コード例 #1
0
ファイル: ImfTestFile.cpp プロジェクト: Archeleus/rrender
bool
isTiledOpenExrFile (const char fileName[])
{
    bool exr, tiled;
    exr = isOpenExrFile (fileName, tiled);
    return exr && tiled;
}
コード例 #2
0
ファイル: ImfTestFile.cpp プロジェクト: Archeleus/rrender
bool
isTiledOpenExrFile (IStream &is)
{
    bool exr, tiled;
    exr = isOpenExrFile (is, tiled);
    return exr && tiled;
}
コード例 #3
0
/*!
    Tries to fill the image object with the data read from
    the given input stream. Returns true on success.
*/
bool EXRImageFileType::read(      Image        *image, 
                                  std::istream &is, 
                            const std::string  &mimetype)
{
#ifdef OSG_WITH_IMF
    if (!is.good())
        return false;

    const char *dummy = "";
    StdIStream file(is, dummy);

    Imf::Int64 pos = file.tellg();

    bool check = isOpenExrFile(is);

    file.seekg(pos);

    if (!check)
    {
        FFATAL(( "Wrong format, no %s image given!\n",
                  mimetype.c_str() ));
        return false;
    }

    // just read the header and get the channel count
    int channel_count = 0;
    pos = file.tellg();
    try
    {
        Imf::RgbaInputFile stream(file);
        const Imf::Header &header = stream.header();
        const Imf::ChannelList &channels = header.channels();

        for(Imf::ChannelList::ConstIterator it  = channels.begin();
                                            it != channels.end();
                                          ++it)
        {
            ++channel_count;
        }
    }
    catch(std::exception &e)
    {
        FFATAL(( "Error while trying to read OpenEXR Image from stream: %s\n",
                  e.what() ));
        return false;
    }
    file.seekg(pos);

    if(channel_count <= 4)
    {
        // TODO: check for mipmap levels,
        // look if line order is s.th. else than INCREASING_Y
        try
        {
            Int32 width, height, numImg = 1;
            Imf::RgbaInputFile stream(file);
    
            Imath::Box2i dw = stream.dataWindow();
            Imf::Array2D<Imf::Rgba> pixels;
    
            const Imf::Header &header = stream.header();
//            const Imf::LineOrder &order = header.lineOrder();
    
            const Imf::EnvmapAttribute *envmap =
                header.findTypedAttribute<Imf::EnvmapAttribute>("envmap");
    
            width  = dw.max.x - dw.min.x + 1;
            height = dw.max.y - dw.min.y + 1;
    
            pixels.resizeErase(height, width);
    
            if(envmap && envmap->value() == Imf::ENVMAP_CUBE)
            {
                numImg = 6;
                height /= numImg;
    
                if (width != height)
                {
                    FFATAL(( "Cubemaps must have squared size, "
                             "but w=%d and h=%d!\n", width, height ));
                    return false;
                }
            }
    
            stream.setFrameBuffer(&pixels[0][0] - dw.min.x - dw.min.y * width,
                                  1, 
                                  width);
            stream.readPixels(dw.min.y, dw.max.y);
    
            image->set( Image::OSG_RGBA_PF, width, height, 1, 1, 1, 0, 0,
                        Image::OSG_FLOAT16_IMAGEDATA, true, numImg );
            image->clearHalf();
    
            // now add custom attributes
            for(Imf::Header::ConstIterator it  = header.begin();
                                           it != header.end();
                                         ++it)
            {
                Imf::Attribute *copy = it.attribute().copy();
                Imf::StringAttribute *sa = 
                    dynamic_cast<Imf::StringAttribute *>(copy);
    
                if(sa != NULL)
                    image->setAttachmentField(it.name(), sa->value());
    
                delete copy;
            }
    
            Real16 *data = reinterpret_cast<Real16*>(image->editData());
    
            for (Int32 side=numImg-1; side >=0; side--)
            {
                Int32 i, j, size = side * width * height * 4;
    
                for (Int32 y=side*height; y<(side+1)*height; y++)
                {
                    for (Int32 x=0; x<width; x++)
                    {
                        if (numImg == 1 || side == 2 || side == 3)
                        {
                            i = (2 * side + 1) * height - (y + 1); // new y
                            j = x;
                        }
                        else
                        {
                            i = y;
                            j = width - x - 1; // new x
                        }
    
                        *(data + size++) = Real16(pixels[i][j].r);
                        *(data + size++) = Real16(pixels[i][j].g);
                        *(data + size++) = Real16(pixels[i][j].b);
                        *(data + size++) = Real16(pixels[i][j].a);
                    }
                }
            }
    
            return true;
        }
        catch(std::exception &e)
        {
            FFATAL(( "Error while trying to read OpenEXR Image from stream: "
                     "%s\n", e.what() ));

            return false;
        }
    }
    else
    {
        try
        {
            if(channel_count % 4 != 0)
            {
                FFATAL(( "Error while trying to read OpenEXR Image from "
                         "stream, channel count of %d is not supported!\n", 
                         channel_count));

                return false;
            }

            int num_img = channel_count / 4;

            Imf::InputFile stream(file);
            const Imf::Header &header = stream.header();
            Imath::Box2i dw = header.dataWindow();

            int width  = dw.max.x - dw.min.x + 1;
            int height = dw.max.y - dw.min.y + 1;

            image->set(Image::OSG_RGBA_PF, width, height, 1, 1, 1, 0, 0,
                       Image::OSG_FLOAT16_IMAGEDATA, true, num_img);
            image->clearHalf();

            // now add custom attributes
            for(Imf::Header::ConstIterator it  = header.begin();
                                           it != header.end();
                                         ++it                  )
            {
                Imf::Attribute *copy = it.attribute().copy();
                Imf::StringAttribute *sa = 
                    dynamic_cast<Imf::StringAttribute *>(copy);
    
                if(sa != NULL)
                    image->setAttachmentField(it.name(), sa->value());
    
                delete copy;
            }

            const Imf::ChannelList &channels = header.channels();

            // do some channel name checks
            bool channel_error = false;
            for(Imf::ChannelList::ConstIterator it=channels.begin();it!=channels.end();++it)
            {
                for(int side=0;side>num_img;++side)
                {
                    char cn[20];
                    sprintf(cn, "%d", side);

                    char name[20];
                    sprintf(name, "R%s", side == 0 ? "" : cn);
                    if(channels.findChannel(name) == NULL)
                        channel_error = true;
                    sprintf(name, "G%s", side == 0 ? "" : cn);
                    if(channels.findChannel(name) == NULL)
                        channel_error = true;
                    sprintf(name, "B%s", side == 0 ? "" : cn);
                    if(channels.findChannel(name) == NULL)
                        channel_error = true;
                    sprintf(name, "A%s", side == 0 ? "" : cn);
                    if(channels.findChannel(name) == NULL)
                        channel_error = true;
                }
            }

            if(channel_error)
            {
                FFATAL(( "Error while trying to read OpenEXR Image from "
                         "stream, expected channel names 'R' 'G' 'B' 'A', "
                         "'R1' 'G1', 'B1', 'A1', ...\n"));

                return false;
            }

            Imf::FrameBuffer frame_buffer;

            // we need to do a vertical flip so we read single scan lines in.
            int current_scan_line = 0;
            for(int i=height-1;i>=0;--i)
            {
                for(int side=0;side<num_img;++side)
                {
                    char *data = 
                        (reinterpret_cast<char *>(image->editData(0, 0, side))) + i * (sizeof(Real16) * 4 * width);

                    data -= current_scan_line * (sizeof(Real16) * 4 * width);

                    char cn[20];
                    sprintf(cn, "%d", side);

                    char name[20];
                    sprintf(name, "R%s", side == 0 ? "" : cn);
                    frame_buffer.insert(name, Imf::Slice(Imf::HALF, data, sizeof(Real16) * 4, sizeof(Real16) * 4 * width));
                    sprintf(name, "G%s", side == 0 ? "" : cn);
                    frame_buffer.insert(name, Imf::Slice(Imf::HALF, data + 1 * sizeof(Real16), sizeof(Real16) * 4, sizeof(Real16) * 4 * width));
                    sprintf(name, "B%s", side == 0 ? "" : cn);
                    frame_buffer.insert(name, Imf::Slice(Imf::HALF, data + 2 * sizeof(Real16), sizeof(Real16) * 4, sizeof(Real16) * 4 * width));
                    sprintf(name, "A%s", side == 0 ? "" : cn);
                    frame_buffer.insert(name, Imf::Slice(Imf::HALF, data + 3 * sizeof(Real16), sizeof(Real16) * 4, sizeof(Real16) * 4 * width));
                }
                stream.setFrameBuffer(frame_buffer);
                stream.readPixels(current_scan_line, current_scan_line);
                ++current_scan_line;
            }

            return true;
        }
        catch(std::exception &e)
        {
            FFATAL(( "Error while trying to read OpenEXR Image from stream: %s\n",
                      e.what() ));
            return false;
        }
    }

#else
    SWARNING << getMimeType()
             << " read is not compiled into the current binary "
             << std::endl;
    return false;
#endif
}
コード例 #4
0
ファイル: ImfTestFile.cpp プロジェクト: Archeleus/rrender
bool
isOpenExrFile (const char fileName[])
{
    bool tiled;
    return isOpenExrFile (fileName, tiled);
}
コード例 #5
0
ファイル: ImfTestFile.cpp プロジェクト: Archeleus/rrender
bool
isOpenExrFile (IStream &is)
{
    bool tiled;
    return isOpenExrFile (is, tiled);
}