bool OpenEXRInput::read_native_tile (int x, int y, int z, void *data) { ASSERT (m_input_tiled != NULL); // Compute where OpenEXR needs to think the full buffers starts. // OpenImageIO requires that 'data' points to where the client wants // to put the pixels being read, but OpenEXR's frameBuffer.insert() // wants where the address of the "virtual framebuffer" for the // whole image. size_t pixelbytes = m_spec.pixel_bytes (true); char *buf = (char *)data - x * pixelbytes - y * pixelbytes * m_spec.tile_width; try { Imf::FrameBuffer frameBuffer; size_t chanoffset = 0; for (int c = 0; c < m_spec.nchannels; ++c) { size_t chanbytes = m_spec.channelformats.size() ? m_spec.channelformats[c].size() : m_spec.format.size(); frameBuffer.insert (m_spec.channelnames[c].c_str(), Imf::Slice (m_pixeltype[c], buf + chanoffset, pixelbytes, pixelbytes*m_spec.tile_width)); chanoffset += chanbytes; } m_input_tiled->setFrameBuffer (frameBuffer); m_input_tiled->readTile ((x - m_spec.x) / m_spec.tile_width, (y - m_spec.y) / m_spec.tile_height, m_miplevel, m_miplevel); } catch (const std::exception &e) { error ("Filed OpenEXR read: %s", e.what()); return false; } return true; }
bool OpenEXRInput::read_native_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, void *data) { chend = clamp (chend, chbegin+1, m_spec.nchannels); #if 0 std::cerr << "openexr rnt " << xbegin << ' ' << xend << ' ' << ybegin << ' ' << yend << ", chans " << chbegin << "-" << (chend-1) << "\n"; #endif if (! (m_input_tiled || m_tiled_input_part) || ! m_spec.valid_tile_range (xbegin, xend, ybegin, yend, zbegin, zend)) { error ("called OpenEXRInput::read_native_tiles without an open file"); return false; } // Compute where OpenEXR needs to think the full buffers starts. // OpenImageIO requires that 'data' points to where the client wants // to put the pixels being read, but OpenEXR's frameBuffer.insert() // wants where the address of the "virtual framebuffer" for the // whole image. const PartInfo &part (m_parts[m_subimage]); size_t pixelbytes = m_spec.pixel_bytes (chbegin, chend, true); int firstxtile = (xbegin-m_spec.x) / m_spec.tile_width; int firstytile = (ybegin-m_spec.y) / m_spec.tile_height; // clamp to the image edge xend = std::min (xend, m_spec.x+m_spec.width); yend = std::min (yend, m_spec.y+m_spec.height); zend = std::min (zend, m_spec.z+m_spec.depth); // figure out how many tiles we need int nxtiles = (xend - xbegin + m_spec.tile_width - 1) / m_spec.tile_width; int nytiles = (yend - ybegin + m_spec.tile_height - 1) / m_spec.tile_height; int whole_width = nxtiles * m_spec.tile_width; int whole_height = nytiles * m_spec.tile_height; boost::scoped_array<char> tmpbuf; void *origdata = data; if (whole_width != (xend-xbegin) || whole_height != (yend-ybegin)) { // Deal with the case of reading not a whole number of tiles -- // OpenEXR will happily overwrite user memory in this case. tmpbuf.reset (new char [nxtiles * nytiles * m_spec.tile_bytes(true)]); data = &tmpbuf[0]; } char *buf = (char *)data - xbegin * pixelbytes - ybegin * pixelbytes * m_spec.tile_width * nxtiles; try { Imf::FrameBuffer frameBuffer; size_t chanoffset = 0; for (int c = chbegin; c < chend; ++c) { size_t chanbytes = m_spec.channelformat(c).size(); frameBuffer.insert (m_spec.channelnames[c].c_str(), Imf::Slice (part.pixeltype[c], buf + chanoffset, pixelbytes, pixelbytes*m_spec.tile_width*nxtiles)); chanoffset += chanbytes; } if (m_input_tiled) { m_input_tiled->setFrameBuffer (frameBuffer); m_input_tiled->readTiles (firstxtile, firstxtile+nxtiles-1, firstytile, firstytile+nytiles-1, m_miplevel, m_miplevel); #ifdef USE_OPENEXR_VERSION2 } else if (m_tiled_input_part) { m_tiled_input_part->setFrameBuffer (frameBuffer); m_tiled_input_part->readTiles (firstxtile, firstxtile+nxtiles-1, firstytile, firstytile+nytiles-1, m_miplevel, m_miplevel); #endif } else { ASSERT (0); } if (data != origdata) { stride_t user_scanline_bytes = (xend-xbegin) * pixelbytes; stride_t scanline_stride = nxtiles*m_spec.tile_width*pixelbytes; for (int y = ybegin; y < yend; ++y) memcpy ((char *)origdata+(y-ybegin)*scanline_stride, (char *)data+(y-ybegin)*scanline_stride, user_scanline_bytes); } } catch (const std::exception &e) { error ("Failed OpenEXR read: %s", e.what()); return false; } return true; }