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