openexr-devel
[Top][All Lists]
Advanced

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

Re: [Openexr-devel] Efficient read of a single image channel, in a multi


From: Florian Kainz
Subject: Re: [Openexr-devel] Efficient read of a single image channel, in a multi-channel image
Date: Wed, 24 Jan 2007 16:30:40 -0800
User-agent: Mozilla Thunderbird 1.0 (X11/20041207)

There is no particularly efficient way to read a single channel.
The channels in the file are interleaved per scan line or per tile.
This allows efficient random access to individual scan lines or tiles,
as well as sequential reading of the entire image with no seek
operations, but it precludes fast extraction of a single image channel.

If you frequently need to access particular subsets of image channels,
you may want to consider storing those subsets in separate files.

Florian


Jeremy Selan wrote:
Hello!

I am wondering what the most efficient mechanism is to read out a single image from a multi-channel exr file. Consider a 12 channel exr file, all 32-bit float, 2Kx2K resolution, no compression. Reading a single channel (code included below), strace reveals:

-- lots of data relating to header access --
_llseek(3, 17289, [17289], SEEK_SET)    = 0
-- BEGIN READ PATTERN --
read(3, "\371\7\0\0\320\177\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 8191) = 8191 read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 90073) = 90073
futex(0x8073afc, FUTEX_WAKE, 1)         = 0
-- END READ PATTERN --

for a total of 201180709 bytes read.

... implying that all 12 channels of data were pulled across the network to read this single channel. Unfortunately, this access pattern limits our ability to store a very large number of data channels in a single file. Is there a more efficient read technique?

All tests were done on Exr 1.4.0.  My apologies if this has changed in 1.5.

Thanks!
-- Jeremy


============================
Imf::InputFile sourceFile(argv[argc-1]);
sourceFile.header().sanityCheck();

Imath::Box2i dw = sourceFile.header().dataWindow();
unsigned int dataWindow_width = dw.max.x - dw.min.x + 1;
int dataWindow_ymin = std::min(dw.min.y, dw.max.y);
int dataWindow_ymax = std::max(dw.min.y, dw.max.y);

std::vector<char> pixelBuffer(dataWindow_width * sizeof(float));

// Read out a single channel
Imf::ChannelList::ConstIterator it = sourceFile.header().channels().begin();

std::string channelName(it.name());
std::cout << "[exrchanneltest]: Processing channel: '" << channelName << "'." << std::endl;

// For all scanlines...
for(int y = dataWindow_ymin; y<=dataWindow_ymax; y++)
{
    // Build a decode structure.
    // This is inefficient to create a new FrameBuffer for each scanline,
    // but shouldnt matter for this simple test.
    Imf::FrameBuffer readBuffer;
    readBuffer.insert(channelName.c_str(), Imf::Slice(Imf::FLOAT,
&pixelBuffer[0] - dw.min.x *sizeof(float), sizeof(float),
                               0, 1, 1, 0.0f));
    sourceFile.setFrameBuffer(readBuffer);
                  // Decode
   sourceFile.readPixels(y);
   float* floatBuffer = reinterpret_cast<float*>(&pixelBuffer[0]);
}



_______________________________________________
Openexr-devel mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/openexr-devel






reply via email to

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