[Top][All Lists]
[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;