openexr-devel
[Top][All Lists]
Advanced

[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






reply via email to

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