示例#1
0
文件: exrinput.cpp 项目: AheadIO/oiio
bool
OpenEXRInput::open (const std::string &name, ImageSpec &newspec)
{
    // Quick check to reject non-exr files
    if (! Filesystem::is_regular (name)) {
        error ("Could not open file \"%s\"", name.c_str());
        return false;
    }
    bool tiled;
    if (! Imf::isOpenExrFile (name.c_str(), tiled)) {
        error ("\"%s\" is not an OpenEXR file", name.c_str());
        return false;
    }

    pvt::set_exr_threads ();

    m_spec = ImageSpec(); // Clear everything with default constructor
    
    try {
        m_input_stream = new OpenEXRInputStream (name.c_str());
    } catch (const std::exception &e) {
        m_input_stream = NULL;
        error ("OpenEXR exception: %s", e.what());
        return false;
    } catch (...) {   // catch-all for edge cases or compiler bugs
        m_input_stream = NULL;
        error ("OpenEXR exception: unknown");
        return false;
    }

    try {
        m_input_multipart = new Imf::MultiPartInputFile (*m_input_stream);
    } catch (const std::exception &e) {
        delete m_input_stream;
        m_input_stream = NULL;
        error ("OpenEXR exception: %s", e.what());
        return false;
    } catch (...) {   // catch-all for edge cases or compiler bugs
        m_input_stream = NULL;
        error ("OpenEXR exception: unknown");
        return false;
    }

    m_nsubimages = m_input_multipart->parts();
    m_parts.resize (m_nsubimages);
    m_subimage = -1;
    m_miplevel = -1;
    bool ok = seek_subimage (0, 0, newspec);
    if (! ok)
        close ();
    return ok;
}
示例#2
0
bool
OpenEXRInput::seek_subimage (int subimage, int miplevel, ImageSpec &newspec)
{
    if (subimage < 0 || subimage >= m_nsubimages)   // out of range
        return false;

    if (subimage == m_subimage && miplevel == m_miplevel) {  // no change
        newspec = m_spec;
        return true;
    }

    PartInfo &part (m_parts[subimage]);
    if (! part.initialized) {
        const Imf::Header *header = NULL;
#ifdef USE_OPENEXR_VERSION2
        if (m_input_multipart)
            header = &(m_input_multipart->header(subimage));
#else
        if (m_input_tiled)
            header = &(m_input_tiled->header());
        if (m_input_scanline)
            header = &(m_input_scanline->header());
#endif
        part.parse_header (header);
        part.initialized = true;
    }

#ifdef USE_OPENEXR_VERSION2
    if (subimage != m_subimage) {
        delete m_scanline_input_part;  m_scanline_input_part = NULL;
        delete m_tiled_input_part;  m_tiled_input_part = NULL;
        delete m_deep_scanline_input_part;  m_deep_scanline_input_part = NULL;
        delete m_deep_tiled_input_part;  m_deep_tiled_input_part = NULL;
        try {
            if (part.spec.deep) {
                if (part.spec.tile_width)
                    m_deep_tiled_input_part = new Imf::DeepTiledInputPart (*m_input_multipart, subimage);
                else
                    m_deep_scanline_input_part = new Imf::DeepScanLineInputPart (*m_input_multipart, subimage);
            } else {
                if (part.spec.tile_width)
                    m_tiled_input_part = new Imf::TiledInputPart (*m_input_multipart, subimage);
                else
                    m_scanline_input_part = new Imf::InputPart (*m_input_multipart, subimage);
            }
        }
        catch (const std::exception &e) {
            error ("OpenEXR exception: %s", e.what());
            m_scanline_input_part = NULL;
            m_tiled_input_part = NULL;
            m_deep_scanline_input_part = NULL;
            m_deep_tiled_input_part = NULL;
            ASSERT(0);
            return false;
        }
    }
#endif

    m_subimage = subimage;

    if (miplevel < 0 || miplevel >= part.nmiplevels)   // out of range
        return false;

    m_miplevel = miplevel;
    m_spec = part.spec;

    if (miplevel == 0 && part.levelmode == Imf::ONE_LEVEL) {
        newspec = m_spec;
        return true;
    }

    // Compute the resolution of the requested mip level.
    int w = part.topwidth, h = part.topheight;
    if (part.levelmode == Imf::MIPMAP_LEVELS) {
        while (miplevel--) {
            if (part.roundingmode == Imf::ROUND_DOWN) {
                w = w / 2;
                h = h / 2;
            } else {
                w = (w + 1) / 2;
                h = (h + 1) / 2;
            }
            w = std::max (1, w);
            h = std::max (1, h);
        }
    } else if (part.levelmode == Imf::RIPMAP_LEVELS) {
        // FIXME
    } else {
        ASSERT(0);
    }

    m_spec.width = w;
    m_spec.height = h;
    // N.B. OpenEXR doesn't support data and display windows per MIPmap
    // level.  So always take from the top level.
    Imath::Box2i datawindow = part.top_datawindow;
    Imath::Box2i displaywindow = part.top_displaywindow;
    m_spec.x = datawindow.min.x;
    m_spec.y = datawindow.min.y;
    if (m_miplevel == 0) {
        m_spec.full_x = displaywindow.min.x;
        m_spec.full_y = displaywindow.min.y;
        m_spec.full_width = displaywindow.max.x - displaywindow.min.x + 1;
        m_spec.full_height = displaywindow.max.y - displaywindow.min.y + 1;
    } else {
        m_spec.full_x = m_spec.x;
        m_spec.full_y = m_spec.y;
        m_spec.full_width = m_spec.width;
        m_spec.full_height = m_spec.height;
    }
    if (part.cubeface) {
        m_spec.full_width = w;
        m_spec.full_height = w;
    }
    newspec = m_spec;

    return true;
}
示例#3
0
bool
OpenEXRInput::open (const std::string &name, ImageSpec &newspec)
{
    // Quick check to reject non-exr files
    if (! Filesystem::is_regular (name)) {
        error ("Could not open file \"%s\"", name.c_str());
        return false;
    }
    bool tiled;
    if (! Imf::isOpenExrFile (name.c_str(), tiled)) {
        error ("\"%s\" is not an OpenEXR file", name.c_str());
        return false;
    }

    pvt::set_exr_threads ();

    m_spec = ImageSpec(); // Clear everything with default constructor
    
    try {
        m_input_stream = new OpenEXRInputStream (name.c_str());
    }
    catch (const std::exception &e) {
        m_input_stream = NULL;
        error ("OpenEXR exception: %s", e.what());
        return false;
    }

#ifdef USE_OPENEXR_VERSION2
    try {
        m_input_multipart = new Imf::MultiPartInputFile (*m_input_stream);
    }
    catch (const std::exception &e) {
        delete m_input_stream;
        m_input_stream = NULL;
        error ("OpenEXR exception: %s", e.what());
        return false;
    }

    m_nsubimages = m_input_multipart->parts();

#else
    try {
        if (tiled) {
            m_input_tiled = new Imf::TiledInputFile (*m_input_stream);
        } else {
            m_input_scanline = new Imf::InputFile (*m_input_stream);
        }
    }
    catch (const std::exception &e) {
        delete m_input_stream;
        m_input_stream = NULL;
        error ("OpenEXR exception: %s", e.what());
        return false;
    }

    if (! m_input_scanline && ! m_input_tiled) {
        error ("Unknown error opening EXR file");
        return false;
    }

    m_nsubimages = 1;  // OpenEXR 1.x did not have multipart
#endif

    m_parts.resize (m_nsubimages);
    m_subimage = -1;
    m_miplevel = -1;
    bool ok = seek_subimage (0, 0, newspec);
    if (! ok)
        close ();
    return ok;
}