static std::string compute_sha1 (Oiiotool &ot, ImageInput *input) { SHA1 sha; const ImageSpec &spec (input->spec()); if (spec.deep) { // Special handling of deep data DeepData dd; if (! input->read_native_deep_image (dd)) { ot.error (" SHA-1: unable to compute, could not read image\n"); return std::string(); } // Hash both the sample counts and the data block sha.append (dd.all_samples()); sha.append (dd.all_data()); } else { imagesize_t size = input->spec().image_bytes (true /*native*/); if (size >= std::numeric_limits<size_t>::max()) { ot.error (" SHA-1: unable to compute, image is too big\n"); return std::string(); } else if (size != 0) { boost::scoped_array<char> buf (new char [size]); if (! input->read_image (TypeDesc::UNKNOWN /*native*/, &buf[0])) { ot.error (" SHA-1: unable to compute, could not read image\n"); return std::string(); } sha.append (&buf[0], size); } } return sha.digest().c_str(); }
bool OpenEXRInput::read_native_deep_scanlines (int ybegin, int yend, int z, int firstchan, int nchans, DeepData &deepdata) { if (m_deep_scanline_input_part == NULL) { error ("called OpenEXRInput::read_native_deep_scanlines without an open file"); return false; } #ifdef USE_OPENEXR_VERSION2 try { const PartInfo &part (m_parts[m_subimage]); size_t npixels = (yend - ybegin) * m_spec.width; // Set up the count and pointers arrays and the Imf framebuffer std::vector<TypeDesc> channeltypes; m_spec.get_channelformats (channeltypes); deepdata.init (npixels, nchans, &channeltypes[firstchan], &channeltypes[firstchan+nchans]); Imf::DeepFrameBuffer frameBuffer; Imf::Slice countslice (Imf::UINT, (char *)(&deepdata.nsamples[0] - m_spec.x - ybegin*m_spec.width), sizeof(unsigned int), sizeof(unsigned int) * m_spec.width); frameBuffer.insertSampleCountSlice (countslice); for (int c = 0; c < nchans; ++c) { Imf::DeepSlice slice (part.pixeltype[c+firstchan], (char *)(&deepdata.pointers[c] - m_spec.x * nchans - ybegin*m_spec.width*nchans), sizeof(void*) * nchans, // xstride of pointer array sizeof(void*) * nchans*m_spec.width, // ystride of pointer array part.chanbytes[c+firstchan]); // stride of data sample frameBuffer.insert (m_spec.channelnames[c+firstchan].c_str(), slice); } m_deep_scanline_input_part->setFrameBuffer (frameBuffer); // Get the sample counts for each pixel and compute the total // number of samples and resize the data area appropriately. m_deep_scanline_input_part->readPixelSampleCounts (ybegin, yend-1); deepdata.alloc (); // Read the pixels m_deep_scanline_input_part->readPixels (ybegin, yend-1); } catch (const std::exception &e) { error ("Failed OpenEXR read: %s", e.what()); return false; } return true; #else return false; #endif }
void DeepData_init (DeepData &dd, int npix, int nchan, tuple p) { std::vector<TypeDesc> chantypes; py_to_stdvector (chantypes, p); ScopedGILRelease gil; dd.init (npix, nchan, &(*chantypes.begin()), &(*chantypes.end())); }
bool DeepData::copy_deep_pixel (int pixel, const DeepData &src, int srcpixel) { if (pixel < 0 || pixel >= pixels()) { // std::cout << "dst pixel was " << pixel << "\n"; DASSERT (0 && "Out of range pixel index"); return false; } if (srcpixel < 0 || srcpixel >= src.pixels()) { // Copying empty pixel -- set samples to 0 and we're done // std::cout << "Source pixel was " << srcpixel << "\n"; set_samples (pixel, 0); return true; } int nchans = channels(); if (nchans != src.channels()) { DASSERT (0 && "Number of channels don't match."); return false; } int nsamples = src.samples(srcpixel); set_samples (pixel, nsamples); if (nsamples == 0) return true; bool sametypes = samplesize() == src.samplesize(); if (sametypes) for (int c = 0; c < nchans; ++c) sametypes &= (channeltype(c) == src.channeltype(c)); if (sametypes) memcpy (data_ptr (pixel, 0, 0), src.data_ptr (srcpixel, 0, 0), samplesize()*nsamples); else { for (int c = 0; c < nchans; ++c) { if (channeltype(c) == TypeDesc::UINT32 && src.channeltype(c) == TypeDesc::UINT32) for (int s = 0; s < nsamples; ++s) set_deep_value (pixel, c, s, src.deep_value_uint (srcpixel, c, s)); else for (int s = 0; s < nsamples; ++s) set_deep_value (pixel, c, s, src.deep_value (srcpixel, c, s)); } } return true; }
void DeepData::merge_deep_pixels (int pixel, const DeepData &src, int srcpixel) { int srcsamples = src.samples(srcpixel); if (srcsamples == 0) return; // No samples to merge int dstsamples = samples(pixel); if (dstsamples == 0) { // Nothing in our pixel yet, so just copy src's pixel copy_deep_pixel (pixel, src, srcpixel); return; } // Need to merge the pixels // First, merge all of src's samples into our pixel set_samples (pixel, dstsamples+srcsamples); for (int i = 0; i < srcsamples; ++i) copy_deep_sample (pixel, dstsamples+i, src, srcpixel, i); // Now ALL the samples from both images are in our pixel. // Mutually split the samples against each other. sort (pixel); // sort first so we only loop once int zchan = m_impl->m_z_channel; int zbackchan = m_impl->m_zback_channel; for (int s = 0; s < samples(pixel); ++s) { float z = deep_value (pixel, zchan, s); float zback = deep_value (pixel, zbackchan, s); split (pixel, z); split (pixel, zback); } sort (pixel); // Now merge the overlaps merge_overlaps (pixel); }
bool DeepData::copy_deep_sample (int pixel, int sample, const DeepData &src, int srcpixel, int srcsample) { const void *srcdata = src.data_ptr (srcpixel, 0, srcsample); int nchans = channels(); if (! srcdata || nchans != src.channels()) return false; int nsamples = src.samples(srcpixel); set_samples (pixel, std::max (samples(pixel), nsamples)); for (int c = 0; c < m_nchannels; ++c) { if (channeltype(c) == TypeDesc::UINT32 && src.channeltype(c) == TypeDesc::UINT32) set_deep_value (pixel, c, sample, src.deep_value_uint (srcpixel, c, srcsample)); else set_deep_value (pixel, c, sample, src.deep_value (srcpixel, c, srcsample)); } return true; }
static void dump_data (ImageInput *input, const print_info_options &opt) { const ImageSpec &spec (input->spec()); if (spec.deep) { // Special handling of deep data DeepData dd; if (! input->read_native_deep_image (dd)) { printf (" dump data: could not read image\n"); return; } int nc = spec.nchannels; for (int z = 0, pixel = 0; z < spec.depth; ++z) { for (int y = 0; y < spec.height; ++y) { for (int x = 0; x < spec.width; ++x, ++pixel) { int nsamples = dd.samples(pixel); if (nsamples == 0 && ! opt.dumpdata_showempty) continue; std::cout << " Pixel ("; if (spec.depth > 1 || spec.z != 0) std::cout << Strutil::format("%d, %d, %d", x+spec.x, y+spec.y, z+spec.z); else std::cout << Strutil::format("%d, %d", x+spec.x, y+spec.y); std::cout << "): " << nsamples << " samples" << (nsamples ? ":" : ""); for (int s = 0; s < nsamples; ++s) { if (s) std::cout << " / "; for (int c = 0; c < nc; ++c) { std::cout << " " << spec.channelnames[c] << "="; if (dd.channeltype(c) == TypeDesc::UINT) std::cout << dd.deep_value_uint(pixel, c, s); else std::cout << dd.deep_value (pixel, c, s); } } std::cout << "\n"; } } } } else { std::vector<float> buf(spec.image_pixels() * spec.nchannels); if (! input->read_image (TypeDesc::FLOAT, &buf[0])) { printf (" dump data: could not read image\n"); return; } const float *ptr = &buf[0]; for (int z = 0; z < spec.depth; ++z) { for (int y = 0; y < spec.height; ++y) { for (int x = 0; x < spec.width; ++x) { if (! opt.dumpdata_showempty) { bool allzero = true; for (int c = 0; c < spec.nchannels && allzero; ++c) allzero &= (ptr[c] == 0.0f); if (allzero) { ptr += spec.nchannels; continue; } } if (spec.depth > 1 || spec.z != 0) std::cout << Strutil::format(" Pixel (%d, %d, %d):", x+spec.x, y+spec.y, z+spec.z); else std::cout << Strutil::format(" Pixel (%d, %d):", x+spec.x, y+spec.y); for (int c = 0; c < spec.nchannels; ++c, ++ptr) { std::cout << ' ' << (*ptr); } std::cout << "\n"; } } } } }
bool OpenEXRInput::read_native_deep_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, DeepData &deepdata) { if (m_deep_tiled_input_part == NULL) { error ("called OpenEXRInput::read_native_deep_tiles without an open file"); return false; } #ifdef USE_OPENEXR_VERSION2 try { const PartInfo &part (m_parts[m_subimage]); size_t width = (xend - xbegin); size_t npixels = width * (yend - ybegin) * (zend - zbegin); chend = clamp (chend, chbegin+1, m_spec.nchannels); int nchans = chend - chbegin; // Set up the count and pointers arrays and the Imf framebuffer std::vector<TypeDesc> channeltypes; m_spec.get_channelformats (channeltypes); deepdata.init (npixels, nchans, &channeltypes[chbegin], &channeltypes[chend]); Imf::DeepFrameBuffer frameBuffer; Imf::Slice countslice (Imf::UINT, (char *)(&deepdata.nsamples[0] - xbegin - ybegin*width), sizeof(unsigned int), sizeof(unsigned int) * width); frameBuffer.insertSampleCountSlice (countslice); for (int c = chbegin; c < chend; ++c) { Imf::DeepSlice slice (part.pixeltype[c], (char *)(&deepdata.pointers[c-chbegin] - xbegin*nchans - ybegin*width*nchans), sizeof(void*) * nchans, // xstride of pointer array sizeof(void*) * nchans*width, // ystride of pointer array part.chanbytes[c]); // stride of data sample frameBuffer.insert (m_spec.channelnames[c].c_str(), slice); } m_deep_tiled_input_part->setFrameBuffer (frameBuffer); int xtiles = round_to_multiple (xend-xbegin, m_spec.tile_width) / m_spec.tile_width; int ytiles = round_to_multiple (yend-ybegin, m_spec.tile_height) / m_spec.tile_height; // Get the sample counts for each pixel and compute the total // number of samples and resize the data area appropriately. m_deep_tiled_input_part->readPixelSampleCounts (0, xtiles-1, 0, ytiles-1); deepdata.alloc (); // Read the pixels m_deep_tiled_input_part->readTiles (0, xtiles-1, 0, ytiles-1, m_miplevel, m_miplevel); } catch (const std::exception &e) { error ("Failed OpenEXR read: %s", e.what()); return false; } return true; #else return false; #endif }
bool OpenEXRInput::read_native_deep_tiles (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, int chbegin, int chend, DeepData &deepdata) { if (m_deep_tiled_input_part == NULL) { error ("called OpenEXRInput::read_native_deep_tiles without an open file"); return false; } try { const PartInfo &part (m_parts[m_subimage]); size_t width = (xend - xbegin); size_t npixels = width * (yend - ybegin) * (zend - zbegin); chend = clamp (chend, chbegin+1, m_spec.nchannels); int nchans = chend - chbegin; // Set up the count and pointers arrays and the Imf framebuffer std::vector<TypeDesc> channeltypes; m_spec.get_channelformats (channeltypes); deepdata.init (npixels, nchans, array_view<const TypeDesc>(&channeltypes[chbegin], chend-chbegin), spec().channelnames); std::vector<unsigned int> all_samples (npixels); std::vector<void*> pointerbuf (npixels * nchans); Imf::DeepFrameBuffer frameBuffer; Imf::Slice countslice (Imf::UINT, (char *)(&all_samples[0] - xbegin - ybegin*width), sizeof(unsigned int), sizeof(unsigned int) * width); frameBuffer.insertSampleCountSlice (countslice); for (int c = chbegin; c < chend; ++c) { Imf::DeepSlice slice (part.pixeltype[c], (char *)(&pointerbuf[0]+(c-chbegin) - xbegin*nchans - ybegin*width*nchans), sizeof(void*) * nchans, // xstride of pointer array sizeof(void*) * nchans*width, // ystride of pointer array deepdata.samplesize()); // stride of data sample frameBuffer.insert (m_spec.channelnames[c].c_str(), slice); } m_deep_tiled_input_part->setFrameBuffer (frameBuffer); int xtiles = round_to_multiple (xend-xbegin, m_spec.tile_width) / m_spec.tile_width; int ytiles = round_to_multiple (yend-ybegin, m_spec.tile_height) / m_spec.tile_height; int firstxtile = (xbegin - m_spec.x) / m_spec.tile_width; int firstytile = (ybegin - m_spec.y) / m_spec.tile_height; // Get the sample counts for each pixel and compute the total // number of samples and resize the data area appropriately. m_deep_tiled_input_part->readPixelSampleCounts ( firstxtile, firstxtile+xtiles-1, firstytile, firstytile+ytiles-1); deepdata.set_all_samples (all_samples); deepdata.get_pointers (pointerbuf); // Read the pixels m_deep_tiled_input_part->readTiles ( firstxtile, firstxtile+xtiles-1, firstytile, firstytile+ytiles-1, m_miplevel, m_miplevel); } catch (const std::exception &e) { error ("Failed OpenEXR read: %s", e.what()); return false; } catch (...) { // catch-all for edge cases or compiler bugs error ("Failed OpenEXR read: unknown exception"); return false; } return true; }
bool OpenEXRInput::read_native_deep_scanlines (int ybegin, int yend, int z, int chbegin, int chend, DeepData &deepdata) { if (m_deep_scanline_input_part == NULL) { error ("called OpenEXRInput::read_native_deep_scanlines without an open file"); return false; } #ifdef USE_OPENEXR_VERSION2 try { const PartInfo &part (m_parts[m_subimage]); size_t npixels = (yend - ybegin) * m_spec.width; chend = clamp (chend, chbegin+1, m_spec.nchannels); int nchans = chend - chbegin; // Set up the count and pointers arrays and the Imf framebuffer std::vector<TypeDesc> channeltypes; m_spec.get_channelformats (channeltypes); deepdata.init (npixels, nchans, array_view<const TypeDesc>(&channeltypes[chbegin], chend-chbegin), spec().channelnames); std::vector<unsigned int> all_samples (npixels); std::vector<void*> pointerbuf (npixels*nchans); Imf::DeepFrameBuffer frameBuffer; Imf::Slice countslice (Imf::UINT, (char *)(&all_samples[0] - m_spec.x - ybegin*m_spec.width), sizeof(unsigned int), sizeof(unsigned int) * m_spec.width); frameBuffer.insertSampleCountSlice (countslice); for (int c = chbegin; c < chend; ++c) { Imf::DeepSlice slice (part.pixeltype[c], (char *)(&pointerbuf[0]+(c-chbegin) - m_spec.x * nchans - ybegin*m_spec.width*nchans), sizeof(void*) * nchans, // xstride of pointer array sizeof(void*) * nchans*m_spec.width, // ystride of pointer array deepdata.samplesize()); // stride of data sample frameBuffer.insert (m_spec.channelnames[c].c_str(), slice); } m_deep_scanline_input_part->setFrameBuffer (frameBuffer); // Get the sample counts for each pixel and compute the total // number of samples and resize the data area appropriately. m_deep_scanline_input_part->readPixelSampleCounts (ybegin, yend-1); deepdata.set_all_samples (all_samples); deepdata.get_pointers (pointerbuf); // Read the pixels m_deep_scanline_input_part->readPixels (ybegin, yend-1); // deepdata.import_chansamp (pointerbuf); } catch (const std::exception &e) { error ("Failed OpenEXR read: %s", e.what()); return false; } catch (...) { // catch-all for edge cases or compiler bugs error ("Failed OpenEXR read: unknown exception"); return false; } return true; #else return false; #endif }