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 }
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 ImageWriterEXR::writeDeepImage(const std::string& filePath, const OutputImage& image, unsigned int channels) { #if USE_OPENEXR2 unsigned int width = image.getWidth(); unsigned int height = image.getHeight(); Imf::Header header(width, height); header.setName("Main"); header.channels().insert("A", Imf::Channel(Imf::HALF)); header.channels().insert("R", Imf::Channel(Imf::HALF)); header.channels().insert("G", Imf::Channel(Imf::HALF)); header.channels().insert("B", Imf::Channel(Imf::HALF)); header.channels().insert("Z", Imf::Channel(Imf::HALF)); Imf::StringAttribute sourceAttribute; sourceAttribute.value() = "Created with Imagine 0.98"; header.insert("comments", sourceAttribute); #if USE_DEEPTILE header.setType(Imf::DEEPTILE); header.setTileDescription(Imf::TileDescription()); #else header.setType(Imf::DEEPSCANLINE); #endif // we need this... header.compression() = Imf::ZIPS_COMPRESSION; // header.compression() = Imf::NO_COMPRESSION; unsigned int* pSampleCount = new unsigned int[width * height]; // work out total number of samples for all pixels unsigned int totalSamples = 0; unsigned int pixelIndex = 0; for (unsigned int y = 0; y < height; y++) { DeepValues* pDeepValues = image.getDeepImage()->colourRowPtr(y); for (unsigned int x = 0; x < width; x++) { totalSamples += pDeepValues->numSamples; pSampleCount[pixelIndex++] = pDeepValues->numSamples; pDeepValues++; } } half* pAlphaFullSamples = new half[totalSamples]; half* pRedFullSamples = new half[totalSamples]; half* pGreenFullSamples = new half[totalSamples]; half* pBlueFullSamples = new half[totalSamples]; half* pZFullSamples = new half[totalSamples]; const DeepValues* pDeepValues = NULL; // accumulate the data for writing... std::vector<half*> aAlphaPointers(width * height); std::vector<half*> aRedPointers(width * height); std::vector<half*> aGreenPointers(width * height); std::vector<half*> aBluePointers(width * height); std::vector<half*> aZPointers(width * height); pixelIndex = 0; unsigned int fullSampleIndex = 0; for (unsigned int y = 0; y < height; y++) { pDeepValues = image.getDeepImage()->colourRowPtr(y); const DeepValues* pDeepPixelValues = pDeepValues; for (unsigned int x = 0; x < width; x++) { unsigned int numSamples = pDeepPixelValues->numSamples; half* pAlphaSampleStart = pAlphaFullSamples + fullSampleIndex; aAlphaPointers[pixelIndex] = pAlphaSampleStart; half* pRedSampleStart = pRedFullSamples + fullSampleIndex; aRedPointers[pixelIndex] = pRedSampleStart; half* pGreenSampleStart = pGreenFullSamples + fullSampleIndex; aGreenPointers[pixelIndex] = pGreenSampleStart; half* pBlueSampleStart = pBlueFullSamples + fullSampleIndex; aBluePointers[pixelIndex] = pBlueSampleStart; half* pZSampleStart = pZFullSamples + fullSampleIndex; aZPointers[pixelIndex] = pZSampleStart; DeepSample* pDeepSample = pDeepPixelValues->samples; // now blit the data over for (unsigned int s = 0; s < numSamples; s++) { *pRedSampleStart++ = pDeepSample->colour.r; *pGreenSampleStart++ = pDeepSample->colour.g; *pBlueSampleStart++ = pDeepSample->colour.b; *pAlphaSampleStart++ = pDeepSample->colour.a; *pZSampleStart++ = pDeepSample->depth; pDeepSample++; } pDeepPixelValues++; fullSampleIndex += numSamples; pixelIndex ++; } } Imf::DeepFrameBuffer frameBuffer; // write the sample count frameBuffer.insertSampleCountSlice(Imf::Slice(Imf::UINT, (char*)pSampleCount, sizeof(unsigned int), width * sizeof(unsigned int))); frameBuffer.insert("A", Imf::DeepSlice(Imf::HALF, (char*)(&aAlphaPointers[0]), sizeof(half*), sizeof(half*) * width, sizeof(half))); frameBuffer.insert("R", Imf::DeepSlice(Imf::HALF, (char*)(&aRedPointers[0]), sizeof(half*), sizeof(half*) * width, sizeof(half))); frameBuffer.insert("G", Imf::DeepSlice(Imf::HALF, (char*)(&aGreenPointers[0]), sizeof(half*), sizeof(half*) * width, sizeof(half))); frameBuffer.insert("B", Imf::DeepSlice(Imf::HALF, (char*)(&aBluePointers[0]), sizeof(half*), sizeof(half*) * width, sizeof(half))); frameBuffer.insert("Z", Imf::DeepSlice(Imf::HALF, (char*)(&aZPointers[0]), sizeof(half*), sizeof(half*) * width, sizeof(half))); const bool useMultipart = true; if (useMultipart) { #if !USE_DEEPTILE Imf::MultiPartOutputFile file(filePath.c_str(), &header, 1); Imf::DeepScanLineOutputPart part(file, 0); try { part.setFrameBuffer(frameBuffer); part.writePixels(height); } catch (...) { int one = 5; } #else Imf::MultiPartOutputFile file(filePath.c_str(), &header, 1); Imf::DeepTiledOutputPart part(file, 0); try { part.setFrameBuffer(frameBuffer); for (int y = 0; y < part.numYTiles(); y++) { for (int x = 0; x < part.numXTiles(); x++) { part.writeTile(x, y, 0); } } } catch (...) { int one = 5; } #endif } else { #if !USE_DEEPTILE Imf::DeepScanLineOutputFile file(filePath.c_str(), header); try { file.setFrameBuffer(frameBuffer); file.writePixels(height); } catch (...) { int one = 5; } #else Imf::DeepTiledOutputFile file(filePath.c_str(), header); try { file.setFrameBuffer(frameBuffer); file.writeTiles(0, file.numXTiles() - 1, 0, file.numYTiles() - 1); /* for (int y = 0; y < file.numYTiles(); y++) { for (int x = 0; x < file.numXTiles(); x++) { file.writeTile(x, y, 0); } } */ } catch (...) { int one = 5; } #endif } delete [] pSampleCount; delete [] pRedFullSamples; delete [] pGreenFullSamples; delete [] pBlueFullSamples; delete [] pAlphaFullSamples; delete [] pZFullSamples; #endif return true; }
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 }