[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Openexr-devel] Y RY BY images
From: |
Jim Hourihan |
Subject: |
Re: [Openexr-devel] Y RY BY images |
Date: |
Wed, 14 Mar 2007 22:21:56 -0700 |
On Mar 14, 2007, at 6:37 PM, Florian Kainz wrote:
Imf::RgbaOutputFile does the filtering and sampling for you.
With Imf::OutputFile you have to do it yourself.
You should be able to hand sub-sampled data to OutputFile;
after all that's what RgbaOutputFile does internally.
Thanks for the help...
One thing that struck me in the RgbaOutputFile code: it writes
scanlines one at a time out of a temporary buffer for Y/C output.
I'm calling writePixels(numScanlinesInMyYimage). Perhaps
that's my problem. I could set the yStride to 0 and adjust the
slice base pointer between each call to get similar behavior.
Alternately I could do exactly what RgbaOutputFile is doing
and copy the pixels to a temp buffer.
I looked at testCompression.cpp, but I didn't see an example
exactly analogous what I'm describing (but I could be misunderstanding
that code).
When you are using Imf::OutputFile to write the file, you must specify
the sub-sampling rates in the header's channel list and in the frame
buffer slices.
I certainly could have messed that up. I have:
Header display and data windows: 0,0 -> 609,406
in memory:
Y half image (610 x 406) contiguous
RY half image (305 x 203) contiguous
BY half image (305 x 203) contiguous
I have the Y Channel sample rate at 1,1 (x,y).
The RY Channel sample rate at 2,2 with plinear=true
The BY Channel sample rate at 2,2 with plinear=true
For the slices I have Y slice sampling at 1,1
RY slice sampling at 2,2
BY slice sampling at 2,2
A call to Header::sanityCheck() succeeds.
Using this setup, I get a core dump in ImfMisc.cpp at 676 when writing.
(gcc 4.0.2/IA32/DARWIN)
Here's the literal code I'm using, the FrameBuffer class has pointers
to subsequent
image planes, each of which can be unique. In this case the dataType
is the same (HALF).
the outfb contains the Y data which has the logical image resolution.
Imf::FrameBuffer frameBuffer;
Imath::Box2i window(Imath::V2i(0,0),
Imath::V2i(outfb->width()-1, outfb->height
()-1));
Imf::Header header(window, window,
1.0f, // pixelAspectRatio = 1
Imath::V2f(0,0), // screenWindowCenter
1.0f, // screenWindowWidth
order, // lineOrder
Imf::PIZ_COMPRESSION);
for (const FrameBuffer* fb = outfb; fb; fb = fb->nextPlane())
{
int xsamp = outfb->width() / fb->width();
int ysamp = outfb->height() / fb->height();
string chname = fb->channelName(0);
header.channels().insert(chname.c_str(),
Imf::Channel(pixelType,
xsamp, ysamp,
chname == "RY" ||
chname == "BY"));
frameBuffer.insert(chname.c_str(), //
name
Imf::Slice(pixelType, //
type
(char*)fb->pixels<char>(), //
base
fb->pixelSize(), //
xStride
fb->scanlineSize(), //
yStride
xsamp, //
xSamples
ysamp)); //
ySamples
}
header.sanityCheck();
Imf::OutputFile file(filename.c_str(), header);
file.setFrameBuffer(frameBuffer);
file.writePixels(outfb->height()); // The Y height
-Jim