openexr-devel
[Top][All Lists]
Advanced

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

[Openexr-devel] Crash when reading sample images


From: Ronny Spiegel
Subject: [Openexr-devel] Crash when reading sample images
Date: Fri, 22 Oct 2010 13:21:47 +0200

Hello,

in my application I have the need to read EXR files and split them up into layers and channels.

I'm currently using OpenExr-1.6.1 on Linux (64 bit).

Therefore I open the file, read the header (dimensions and channels) and iterate over all channels mentioned there. For each channel I create a memory area where the data should be put upon reading the content. This memory area is added to the framebuffer.
This works for all openexr sample images except

   Tiles/Spirals.exr
   ScanLines/Blobbies.exr

These two make the application crash. It seems that memory gets heavily corrupted.

Does anyone of you have an idea of what I'm doing wrong?


----- snip -----

#include "Iex.h"
#include "ImfInputFile.h"
#include "ImfHeader.h"
#include "ImfChannelList.h"
#include "ImfFrameBuffer.h"

#include <stdexcept>
#include <vector>

namespace {

    /*!
     * \brief Determines the number of bytes we need to store a pixel of type \c n_type
     *
     * \return 0 on error, a value > 0 otherwise
     */
    unsigned char getPixelSize(Imf::PixelType n_type) {

        switch (n_type) {
            case Imf::UINT:
                return sizeof(unsigned int);
            case Imf::HALF:
                return 2; // per definition, a Half is a 16 bit float value
            case Imf::FLOAT:
                return sizeof(float);
        }

        return 0;
    }

}

int main(int argc, char** argv) {

Imf::InputFile f(argv[1]);

if (!f.isComplete()) {
throw std::runtime_error("File not complete");
}

const Imf::Header& hdr = f.header();
Imath::Box2i sz = hdr.dataWindow();

size_t width = sz.max.x - sz.min.x + 1;
size_t height = sz.max.y - sz.min.y + 1;

std::vector<char*> buffers; // to free them later
Imf::FrameBuffer frameBuffer;
const Imf::ChannelList& channels(hdr.channels()); // all the channels

    // get all the channels, allocate data for the buffer and create a slice within the FrameBuffer
    for (Imf::ChannelList::ConstIterator channel = channels.begin(); channel != channels.end(); ++channel) {
// XXX: use an auto_ptr here and put it into a Boost Pointer Container
char *tmpBuf = new char[width * height * getPixelSize(channel.channel().type) * 2];
buffers.push_back(tmpBuf);

// calculate the address of pixel (0,0)
char *base = tmpBuf + (getPixelSize(channel.channel().type) * (sz.min.x - sz.min.y * width));

// create a Slice in the Framebuffer
frameBuffer.insert(channel.name(),
Imf::Slice(
channel.channel().type,
base,
getPixelSize(channel.channel().type),
getPixelSize(channel.channel().type) * width, channel.channel().xSampling, channel.channel().ySampling, 0.0));
}

f.setFrameBuffer(frameBuffer);
f.readPixels(sz.min.y, sz.max.y);

for (std::vector<char*>::iterator i = buffers.begin(); i != buffers.end(); ++i) {
std::cerr << "Free buffer at: " << (void*) *i << std::endl;
delete *i;
}

return 0;
}


----- snip -----

Many thanks,

Ronny



reply via email to

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