openexr-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Openexr-devel] Problems reading image data - I'm sure it must be so


From: Florian Kainz
Subject: Re: [Openexr-devel] Problems reading image data - I'm sure it must be something obvious....
Date: Wed, 28 Mar 2007 19:41:19 -0700
User-agent: Mozilla Thunderbird 1.0 (X11/20041207)

Hugh Macdonald wrote:
> Hi all,
>
> I'm kinda new to OpenEXR development - I've been trying a few things
> in the past couple of days, but am a little stuck on one thing at the
> moment...
>
> I need to look at each pixel in an image, so I'm reading the image
> into an Array2D<Rgba> using:
>
> -----------------------------------------------------
> const Box2i dataWindow = inFileHeader.dataWindow();
>
> int dataWidth  = dataWindow.max.x - dataWindow.min.x + 1;
> int dataHeight = dataWindow.max.y - dataWindow.min.y + 1;
>
> Array2D<Rgba> pixels (dataHeight, dataWidth);
> inFile.setFrameBuffer (&pixels[0][0] - dataWindow.min.x -
> dataWindow.min.y * dataWidth, 1, dataWidth);
> inFile.readPixels (dataWindow.min.y, dataWindow.max.y);
> -----------------------------------------------------

As far as I can tell the code above is correct.  It causes the
pixels to be stored in row-major order; each horizontal row of
pixels is contiguous in memory.

>
> I then (and I think that this is where I'm getting confused) look
> through the pixels with:
>
> -----------------------------------------------------
> for(x = 0; x < pixelsWidth; x++)
> {
>     for(y = 0; y < pixelsHeight; y++)
>     {
>         int pixelAddr = y + (x * pixelsHeight);
>         const Rgba *thisPixel = pixels[pixelAddr];
>         cout << "At: " << x << "," << y << " (addr: " << pixelAddr << ")
> : "
> << thisPixel->r << "," << thisPixel->g << "," << thisPixel->b << ","
> << thisPixel->a << endl;
>     }
> }
> -----------------------------------------------------

This part of the code is probably wrong.  Assuming that pixelsWidth
and pixelsHeight are the same as dataWidth and dataHeight above,
the loop should look something like this:

    for(x = 0; x < pixelsWidth; x++)
    {
        for(y = 0; y < pixelsHeight; y++)
        {
            const Rgba &thisPixel = pixels[y][x];
            cout << thisPixel.r << ...
        }
    }

Or, if "pixels" in this loop is not the same Array2D as in the
file reading code above, but instead a pointer to the pixel in the
upper left corner of the dataWindow, then you may want to try this:

    for(x = 0; x < pixelsWidth; x++)
    {
        for(y = 0; y < pixelsHeight; y++)
        {
            const Rgba *thisPixel = pixels + y * pixelsWidth + x;
            cout << thisPixel->r << ...
        }
    }

Your loop traverses the image in column-major order.  If you are
concerned about speed, you may want to switch to traversing in
row-major order by nesting the "for x" loop inside the "for y"
loop.  Row-major order is potentially faster because you get
better cache coherence.

>
> The image I'm testing this on is a grad, and looking at the printout
> of the colour values, I can tell that the addressing is going in y,
> starting from the top left. However, when it gets to the bottom left
> of the image, I get some erroneous pixel values before the whole
> program seg faults.
>
> Any ideas? Please tell me I'm being an idiot somewhere along the line....
>
> Any suggestions more than welcome!
>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]