openexr-devel
[Top][All Lists]
Advanced

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

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


From: Jeremy Selan
Subject: [Openexr-devel] Efficient read of a single image channel, in a multi-channel image
Date: Wed, 24 Jan 2007 15:12:43 -0800
User-agent: Thunderbird 1.5.0.5 (X11/20060719)

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]);
}





reply via email to

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