const void * ImageBuf::retile (int x, int y, int z, ImageCache::Tile* &tile, int &tilexbegin, int &tileybegin, int &tilezbegin) const { int tw = spec().tile_width, th = spec().tile_height; int td = std::max (1, spec().tile_depth); if (tile == NULL || x < tilexbegin || x >= (tilexbegin+tw) || y < tileybegin || y >= (tileybegin+th) || z < tilezbegin || z >= (tilezbegin+td)) { // not the same tile as before if (tile) m_imagecache->release_tile (tile); int xtile = (x-spec().x) / tw; int ytile = (y-spec().y) / th; int ztile = (z-spec().z) / td; tilexbegin = spec().x + xtile*tw; tileybegin = spec().y + ytile*th; tilezbegin = spec().z + ztile*td; tile = m_imagecache->get_tile (m_name, subimage(), miplevel(), x, y, z); } size_t offset = ((y - tileybegin) * tw) + (x - tilexbegin); offset += ((z - tilezbegin) * tw * th); offset *= spec().pixel_bytes(); TypeDesc format; return (const char *)m_imagecache->tile_pixels (tile, format) + offset; }
bool ImageBuf::copy (const ImageBuf &src) { if (! m_spec_valid && ! m_pixels_valid) { // uninitialized if (! src.m_spec_valid && ! src.m_pixels_valid) return true; // uninitialized=uninitialized is a nop // uninitialized = initialized : set up *this with local storage reset (src.name(), src.spec()); } bool selfcopy = (&src == this); if (cachedpixels()) { if (selfcopy) { // special case: self copy of ImageCache loads locally return read (subimage(), miplevel(), true /*force*/); } reset (src.name(), src.spec()); // Now it has local pixels } if (selfcopy) return true; if (localpixels()) { if (m_clientpixels) { // app-owned memory if (spec().width != src.spec().width || spec().height != src.spec().height || spec().depth != src.spec().depth || spec().nchannels != src.spec().nchannels) { // size doesn't match, fail return false; } this->copy_metadata (src); } else { // locally owned memory -- we can fully resize it reset (src.name(), src.spec()); } return this->copy_pixels (src); } return false; // all other cases fail }