openexr-devel
[Top][All Lists]
Advanced

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

Re: [Openexr-devel] Computing "base" Address When Setting up the FrameBu


From: Florian Kainz
Subject: Re: [Openexr-devel] Computing "base" Address When Setting up the FrameBuffer
Date: Fri, 19 Nov 2004 17:58:53 -0800
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.3) Gecko/20030314

Angus Taggart wrote:
OK, I think that my lack of sleep (due to a 5-month-old baby) is starting to catch up me because I can't wrap my head around this!

I'm having problems setting the y-offset component for the base address for the FrameBuffer correctly when reading a rgba scanline file (in chunks) for the case when the data window and the display window are not aligned. Specifically, I'm not getting the correct result for the example image t13.exr that has the following data window and display window values:

Display Window: min (399, 299), max (499, 399)
Data Window: min (0, 0), max(399, 299)

How should the yOffset component of the base address be calculated? Here's how I'm setting up the FrameBuffer:

int exrBufWidth = _fileHeader->dataWindow().max.y-_fileHeader->dataWindow().min.y+1;
int exrBufHeight = myOutputBuf->nLines;
int exrBufXOffset = _fileHeader->dataWindow().min.x;
int exrBufYOffset = myOutputBuf->lineNum + ?????; // NOTE: myOutputBuf->lineNum is relative to the bottom of the display window.

_rgbaExrDataBuf.resizeErase(exrBufWidth, exrBufHeight);
_rgbaScanlineFile->setFrameBuffer (&_rgbaExrDataBuf[0][0] - exrBufXOffset - exrBufYOffset * exrBufWidth,
1, exrBufWidth);

Thanks for any help.

Angus


Hi Angus,

the size and location of the display window should have no effect on your
frame buffer address calculations.  While reading from the file, the IlmImf
library computes the memory address of pixel (x,y) as

    address = base + x * xStride + y * yStride,

where xStride and yStride are the differences between the memory addresses
of horizontally and vertically adjacent pixels.

When you read the next chunk of nLines scan lines, say from y to y+nLines-1,
you want pixel (dataWindow().min.x, y) to be at address &_rgbaExrDataBuf[0][0].
Assuming that you want scan lines to be contiguous in memory, pixels
(dataWindow().min.x+1,y) and (dataWindow().min.x,y+1) should be at
&_rgbaExrDataBuf[0][1] and &_rgbaExrDataBuf[1][0] respectively.
This means xStride and yStride can be computed like this:

    int xStride = &_rgbaExrDataBuf[0][1] - &_rgbaExrDataBuf[0][0];
    int yStride = &_rgbaExrDataBuf[1][0] - &_rgbaExrDataBuf[0][0];

In order to make the library store pixel (dataWindow().min.x,y), that
is, the leftmost pixel of the first scan line in your chunk, at address
&_rgbaExrDataBuf[0][0], the following must be true:

    base + dataWindow().min.x * xStride + y * yStride == &_rgbaExrDataBuf[0][0]

Therefore

    base == &_rgbaExrDataBuf[0][0] - dataWindow().min.x * xStride - y * yStride

The following code fragment should do what you want:

    Box2i dw = _fileHeader.dataWindow();

    _rgbaExrDataBuf.resizeErase (nLines, dw.max.x - dw.min.x + 1);

    int xStride = &_rgbaExrDataBuf[0][1] - &_rgbaExrDataBuf[0][0];
    int yStride = &_rgbaExrDataBuf[1][0] - &_rgbaExrDataBuf[0][0];

    for (int y = dataWindow().min.y; y <= dataWindow().max.y; y += nLines)
    {
        setFrameBuffer (&_rgbaExrDataBuf[0][0] -
                            dw.min.x * xStride - y * yStride,
                        xStride, yStride);

        _rgbaScanLinefile->readPixels (y, min (dw.max.y, y + nLines - 1));
    }

Hope this helps,

Florian



P.S.: I think in your code the line that reads

int exrBufWidth =_fileHeader->dataWindow().max.y-_fileHeader->dataWindow().min.y+1;

should look like this:

int exrBufWidth = _fileHeader->dataWindow().max.x-_fileHeader->dataWindow().min.x+1;






reply via email to

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