Solved

Read a raster

Posted on 1998-10-30
12
456 Views
Last Modified: 2013-11-20
I have a function named TIFFReadRGBAImage that reads a TIFF image into memory, storing the result in a supplied raster.
Raster pixels are 8-bit packed red,green,blue alpha samples.

What must i do now to acces individual samples??

(The raster is assumed tobe organizated such thet the pixel at localitation (x,y) is raster [y*image.width+x] with the raster origin in the lower-left hand cornar)
0
Comment
Question by:Sol
  • 6
  • 6
12 Comments
 
LVL 12

Accepted Solution

by:
rwilson032697 earned 160 total points
Comment Utility
Each sample occupies 32 bits or 4 bytes. So you can cast the memory containing the raster image to an array of structures with each structure containing 4 fields, each of one byte in size called red, green, blue and alpha.

When you access this pizel array in the manner you describe you then get a structure with the individual samples all nicely separated out for you.

eg (excuse the rusty syntax - you get the picture (sic))

 struct APixel { tByte red, green, blue, alpha }; // tByte is whatever you use for a byte

typedef PixelArray APixel[];

Then ((PixelArray)RasterMemoryBlock)[y*image.width+x].red is the red sample for the pixel at [x, y]

Cheers,

Raymond.
0
 

Author Comment

by:Sol
Comment Utility
Hi, Cheers!!

I’m a begginer in Visual C++, i suppose you have noticed that.. ;-D. Would you explain me writing the “needed” lines that you are talking about??? PLEASE!!!

This is the code done (less or more) :

.

in = TIFFOpen(m_ovl+".tif", "r");
   
TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &imageWidth);
if (in) {
      
            TIFFRGBAImage img;
            char emsg[1024];
            uint32* buf;

            if(TIFFRGBAImageBegin(&img,in,0,emsg)) {
                  
            buf = (uint32*)_TIFFmalloc(imageWidth*imageLength*SamplePerPixel);  //THE RASTER

            if (!buf)
                    goto OutOfDIBMemory;

            if (buf != NULL) {

                  if (TIFFRGBAImageGet(&img,buf,img.width,img.height)) {

                        // PROCESS RASTER DATA
                        // ¿¿WHAT MUST I DO HERE???

                  }
                  free (buf);
            }

            TIFFRGBAImageEnd(&img);
            
            }
      }


Thanks!!!

0
 

Author Comment

by:Sol
Comment Utility
Adjusted points to 160
0
 
LVL 12

Expert Comment

by:rwilson032697
Comment Utility
// PROCESS RASTER DATA

// Assuming buf now points to the memory containing the pixels and the declarations in my answer then

// To get the RedValue and to something with it do this
 RedValue = ((PixelArray *)Buf)[y*imageWidth+x].red;

This could be optimised by extracting the entire pixel structure to reduce the calculations and pointer dereferences...

Cheers,

Raymond.
 
0
 

Author Comment

by:Sol
Comment Utility
Hi Raymond!!

I’ve done:

struct APixel              
{
BYTE red,green,blue,alpha;  
};

On the other hand,

Typedef PixelArray Apixel();

Doesn’t work...Why?? What must i write??? PixelArray isn’t a type declaration....

Then, when i wrote :

RedValue = ((PixelArray *)Buf)[y*imageWidth+x].red;

in the process raster data...but:

1- What kind of data is RedValue?? BYTE??

Would you explain me the typedef and the redvalue errors??

THANKS!!!

0
 
LVL 12

Expert Comment

by:rwilson032697
Comment Utility
Hi,

RedValue is a BYTE (the same as the samples in the Pixel struct.

Try Typdef APixel PixelArray[]; // What I'm saying is PixelArray is an unsized array of APixel structures. I'm sorry but my C declaration syntax is a little rusty.

You may also need to change

RedValue = ((PixelArray *)Buf)[y*imageWidth+x].red;

to

RedValue = (* (PixelArray *)Buf)[y*imageWidth+x].red;

if the compiler still gives you trouble with it.

Raymond.

0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:Sol
Comment Utility
The last question rwilson ;-D

I've tried Typdef APixel PixelArray[]; but, unfortunatelly, it doen't work... :-((

I know that you want to define PixelArray as an unsized array of APixel structures. How can i do that!! I've tried a lot of things...

I think it's the last step to resolve the problem...

You have helped me very much. Thanks...
0
 
LVL 12

Expert Comment

by:rwilson032697
Comment Utility
Sorry for the delay Sol - E-E went off-line for me for 2-3 days...

I assume when you say it does not work that it does not compile...

Try

Typdef Struct APixel PixelArray[];

That should do it.

Raymond.
0
 

Author Comment

by:Sol
Comment Utility
Hi Raymond!!

Oh my God....I’ve tried your solution but this message appear:

First-chance exception in X_Sheet.exe: 0xC0000005: Access Violation.

at the first time that i was reading the buffer!!! (a=0,b=0) ......

Do you know what’s happening???

Look at the code done...

struct APixel              
{
BYTE red,green,blue,alpha;  
};
                        
buf = (uint32*)_TIFFmalloc(imageWidth*imageLength*SamplePerPixel);

if (buf != NULL) {
      
      if (TIFFReadRGBAImage(in,imageWidth,imageLength,buf,0)) {
                                    
            int Alpha,Red,Green,Blue,Offset;
            BYTE RedValue,GreenValue,BlueValue,AlphaValue;
            typedef struct APixel PixelArray[];

            for (a=0;a<=imageWidth;a++) {
                                    
            for (b=0;b<=imageLength;b++) {

                        RedValue = (*(PixelArray *)buf[b*imageWidth+a])->red;
                           GreenValue = (*(PixelArray *)buf[b*imageWidth+a])->green;
                        BlueValue = (*(PixelArray *)buf[b*imageWidth+a])->blue;
                        AlphaValue = (*(PixelArray *)buf[b*imageWidth+a])->alpha;

                  }
            }
      }
                  
      _TIFFfree (buf);

I don't understand it, because the image is 2138x889....
0
 
LVL 12

Expert Comment

by:rwilson032697
Comment Utility
Do it like this...


RedValue = (*(PixelArray *)buf)[b*imageWidth+a].red;
GreenValue = (*(PixelArray *)buf)[b*imageWidth+a].green;
BlueValue = (*(PixelArray *)buf)[b*imageWidth+a].lue;
AlphaValue = (*(PixelArray *)buf)[b*imageWidth+a].alpha;

I may be getting the pointers a bit messed up, if this doesn't work try:

RedValue = (PixelArray)buf[b*imageWidth+a].red;
GreenValue = (PixelArray)buf[b*imageWidth+a].green;
BlueValue = (PixelArray)buf[b*imageWidth+a].lue;
AlphaValue = (PixelArray)buf[b*imageWidth+a].alpha;

(C may be treating PixelArray as a pointer already...)

Raymond
0
 

Author Comment

by:Sol
Comment Utility
I’ve tried this:

RedValue = (*(PixelArray *)buf)[b*imageWidth+a].red;
GreenValue = (*(PixelArray *)buf)[b*imageWidth+a].green;
BlueValue = (*(PixelArray *)buf)[b*imageWidth+a].lue;
AlphaValue = (*(PixelArray *)buf)[b*imageWidth+a].alpha;

(The other doesn’t compile...)

But, unfortunately, look at the answer:

x = 0, y = 0, Alpha = 1598471007, Red = 2, Green = 7009384, Blue = 7009384

That’s imposible!!

Do you know why???

0
 
LVL 12

Expert Comment

by:rwilson032697
Comment Utility
Try changing the (*(PixelArray to just ((PixelArray

Unfortunately I don't have the setup here to test it :-(

Alternatively, declare a variable pf PixelArray type and assign Buf to it, then just just the pizelarray variable instead of buf in a simple array lookup without the casts.

Raymond.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now