void OutputFile::setFrameBuffer (const FrameBuffer &frameBuffer) { Lock lock (*_data); // // Check if the new frame buffer descriptor // is compatible with the image file header. // const ChannelList &channels = _data->header.channels(); for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) { FrameBuffer::ConstIterator j = frameBuffer.find (i.name()); if (j == frameBuffer.end()) continue; if (i.channel().type != j.slice().type) { THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" channel " "of output file \"" << fileName() << "\" is " "not compatible with the frame buffer's " "pixel type."); } if (i.channel().xSampling != j.slice().xSampling || i.channel().ySampling != j.slice().ySampling) { THROW (Iex::ArgExc, "X and/or y subsampling factors " "of \"" << i.name() << "\" channel " "of output file \"" << fileName() << "\" are " "not compatible with the frame buffer's " "subsampling factors."); } } // // Initialize slice table for writePixels(). // vector<OutSliceInfo> slices; for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) { FrameBuffer::ConstIterator j = frameBuffer.find (i.name()); if (j == frameBuffer.end()) { // // Channel i is not present in the frame buffer. // In the file, channel i will contain only zeroes. // slices.push_back (OutSliceInfo (i.channel().type, 0, // base 0, // xStride, 0, // yStride, i.channel().xSampling, i.channel().ySampling, true)); // zero } else { // // Channel i is present in the frame buffer. // slices.push_back (OutSliceInfo (j.slice().type, j.slice().base, j.slice().xStride, j.slice().yStride, j.slice().xSampling, j.slice().ySampling, false)); // zero } } // // Store the new frame buffer. // _data->frameBuffer = frameBuffer; _data->slices = slices; }
void ScanLineInputFile::setFrameBuffer (const FrameBuffer &frameBuffer) { Lock lock (*_data); // // Check if the new frame buffer descriptor is // compatible with the image file header. // const ChannelList &channels = _data->header.channels(); for (FrameBuffer::ConstIterator j = frameBuffer.begin(); j != frameBuffer.end(); ++j) { ChannelList::ConstIterator i = channels.find (j.name()); if (i == channels.end()) continue; if (i.channel().xSampling != j.slice().xSampling || i.channel().ySampling != j.slice().ySampling) THROW (Iex::ArgExc, "X and/or y subsampling factors " "of \"" << i.name() << "\" channel " "of input file \"" << fileName() << "\" are " "not compatible with the frame buffer's " "subsampling factors."); } // // Initialize the slice table for readPixels(). // vector<InSliceInfo> slices; ChannelList::ConstIterator i = channels.begin(); for (FrameBuffer::ConstIterator j = frameBuffer.begin(); j != frameBuffer.end(); ++j) { while (i != channels.end() && strcmp (i.name(), j.name()) < 0) { // // Channel i is present in the file but not // in the frame buffer; data for channel i // will be skipped during readPixels(). // slices.push_back (InSliceInfo (i.channel().type, i.channel().type, 0, // base 0, // xStride 0, // yStride i.channel().xSampling, i.channel().ySampling, false, // fill true, // skip 0.0)); // fillValue ++i; } bool fill = false; if (i == channels.end() || strcmp (i.name(), j.name()) > 0) { // // Channel i is present in the frame buffer, but not in the file. // In the frame buffer, slice j will be filled with a default value. // fill = true; } slices.push_back (InSliceInfo (j.slice().type, fill? j.slice().type: i.channel().type, j.slice().base, j.slice().xStride, j.slice().yStride, j.slice().xSampling, j.slice().ySampling, fill, false, // skip j.slice().fillValue)); if (i != channels.end() && !fill) ++i; } // // Store the new frame buffer. // _data->frameBuffer = frameBuffer; _data->slices = slices; }
void InputFile::setFrameBuffer (const FrameBuffer &frameBuffer) { if (isTiled (_data->version)) { Lock lock (*_data); // // We must invalidate the cached buffer if the new frame // buffer has a different set of channels than the old // frame buffer, or if the type of a channel has changed. // const FrameBuffer &oldFrameBuffer = _data->tFileBuffer; FrameBuffer::ConstIterator i = oldFrameBuffer.begin(); FrameBuffer::ConstIterator j = frameBuffer.begin(); while (i != oldFrameBuffer.end() && j != frameBuffer.end()) { if (strcmp (i.name(), j.name()) || i.slice().type != j.slice().type) break; ++i; ++j; } if (i != oldFrameBuffer.end() || j != frameBuffer.end()) { // // Invalidate the cached buffer. // _data->deleteCachedBuffer (); _data->cachedTileY = -1; // // Create new a cached frame buffer. It can hold a single // row of tiles. The cached buffer can be reused for each // row of tiles because we set the yTileCoords parameter of // each Slice to true. // const Box2i &dataWindow = _data->header.dataWindow(); _data->cachedBuffer = new FrameBuffer(); _data->offset = dataWindow.min.x; int tileRowSize = (dataWindow.max.x - dataWindow.min.x + 1) * _data->tFile->tileYSize(); for (FrameBuffer::ConstIterator k = frameBuffer.begin(); k != frameBuffer.end(); ++k) { Slice s = k.slice(); switch (s.type) { case UINT: _data->cachedBuffer->insert (k.name(), Slice (UINT, (char *)(new unsigned int[tileRowSize] - _data->offset), sizeof (unsigned int), sizeof (unsigned int) * _data->tFile->levelWidth(0), 1, 1, s.fillValue, false, true)); break; case HALF: _data->cachedBuffer->insert (k.name(), Slice (HALF, (char *)(new half[tileRowSize] - _data->offset), sizeof (half), sizeof (half) * _data->tFile->levelWidth(0), 1, 1, s.fillValue, false, true)); break; case FLOAT: _data->cachedBuffer->insert (k.name(), Slice (FLOAT, (char *)(new float[tileRowSize] - _data->offset), sizeof(float), sizeof(float) * _data->tFile->levelWidth(0), 1, 1, s.fillValue, false, true)); break; default: throw Iex::ArgExc ("Unknown pixel data type."); } } _data->tFile->setFrameBuffer (*_data->cachedBuffer); } _data->tFileBuffer = frameBuffer; } else { _data->sFile->setFrameBuffer (frameBuffer); } }
void TiledOutputFile::setFrameBuffer (const FrameBuffer &frameBuffer) { Lock lock (*_streamData); // // Check if the new frame buffer descriptor // is compatible with the image file header. // const ChannelList &channels = _data->header.channels(); for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) { FrameBuffer::ConstIterator j = frameBuffer.find (i.name()); if (j == frameBuffer.end()) continue; if (i.channel().type != j.slice().type) THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" channel " "of output file \"" << fileName() << "\" is " "not compatible with the frame buffer's " "pixel type."); if (j.slice().xSampling != 1 || j.slice().ySampling != 1) THROW (IEX_NAMESPACE::ArgExc, "All channels in a tiled file must have" "sampling (1,1)."); } // // Initialize slice table for writePixels(). // vector<TOutSliceInfo> slices; for (ChannelList::ConstIterator i = channels.begin(); i != channels.end(); ++i) { FrameBuffer::ConstIterator j = frameBuffer.find (i.name()); if (j == frameBuffer.end()) { // // Channel i is not present in the frame buffer. // In the file, channel i will contain only zeroes. // slices.push_back (TOutSliceInfo (i.channel().type, 0, // base 0, // xStride, 0, // yStride, true)); // zero } else { // // Channel i is present in the frame buffer. // slices.push_back (TOutSliceInfo (j.slice().type, j.slice().base, j.slice().xStride, j.slice().yStride, false, // zero (j.slice().xTileCoords)? 1: 0, (j.slice().yTileCoords)? 1: 0)); } } // // Store the new frame buffer. // _data->frameBuffer = frameBuffer; _data->slices = slices; }
void ScanLineInputFile::setFrameBuffer (const FrameBuffer &frameBuffer) { Lock lock (*_streamData); const ChannelList &channels = _data->header.channels(); for (FrameBuffer::ConstIterator j = frameBuffer.begin(); j != frameBuffer.end(); ++j) { ChannelList::ConstIterator i = channels.find (j.name()); if (i == channels.end()) continue; if (i.channel().xSampling != j.slice().xSampling || i.channel().ySampling != j.slice().ySampling) THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors " "of \"" << i.name() << "\" channel " "of input file \"" << fileName() << "\" are " "not compatible with the frame buffer's " "subsampling factors."); } // // Check if the new frame buffer descriptor is // compatible with the image file header. // if (!GLOBAL_SYSTEM_LITTLE_ENDIAN) { _data->optimizationMode._destination._format = OptimizationMode::PIXELFORMAT_OTHER; _data->optimizationMode._source._format = OptimizationMode::PIXELFORMAT_OTHER; } else { StringVector * v=NULL; if(hasMultiView(_data->header)) { v = &multiView(_data->header); } _data->optimizationMode = detectOptimizationMode(frameBuffer, channels,v); } // TODO-pk this disables optimization // _data->optimizationMode._destination._format = Imf::OptimizationMode::PIXELFORMAT_OTHER; // // Initialize the slice table for readPixels(). // vector<InSliceInfo> slices; ChannelList::ConstIterator i = channels.begin(); for (FrameBuffer::ConstIterator j = frameBuffer.begin(); j != frameBuffer.end(); ++j) { while (i != channels.end() && strcmp (i.name(), j.name()) < 0) { // // Channel i is present in the file but not // in the frame buffer; data for channel i // will be skipped during readPixels(). // slices.push_back (InSliceInfo (i.channel().type, i.channel().type, 0, // base 0, // xStride 0, // yStride i.channel().xSampling, i.channel().ySampling, false, // fill true, // skip 0.0)); // fillValue ++i; } bool fill = false; if (i == channels.end() || strcmp (i.name(), j.name()) > 0) { // // Channel i is present in the frame buffer, but not in the file. // In the frame buffer, slice j will be filled with a default value. // fill = true; } slices.push_back (InSliceInfo (j.slice().type, fill? j.slice().type: i.channel().type, j.slice().base, j.slice().xStride, j.slice().yStride, j.slice().xSampling, j.slice().ySampling, fill, false, // skip j.slice().fillValue)); if (i != channels.end() && !fill) ++i; } // // Store the new frame buffer. // _data->frameBuffer = frameBuffer; _data->slices = slices; }
void ScanLineInputFile::setFrameBuffer (const FrameBuffer &frameBuffer) { Lock lock (*_streamData); const ChannelList &channels = _data->header.channels(); for (FrameBuffer::ConstIterator j = frameBuffer.begin(); j != frameBuffer.end(); ++j) { ChannelList::ConstIterator i = channels.find (j.name()); if (i == channels.end()) continue; if (i.channel().xSampling != j.slice().xSampling || i.channel().ySampling != j.slice().ySampling) THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors " "of \"" << i.name() << "\" channel " "of input file \"" << fileName() << "\" are " "not compatible with the frame buffer's " "subsampling factors."); } // optimization is possible if this is a little endian system // and both inputs and outputs are half floats // bool optimizationPossible = true; if (!GLOBAL_SYSTEM_LITTLE_ENDIAN) { optimizationPossible =false; } vector<sliceOptimizationData> optData; // // Initialize the slice table for readPixels(). // vector<InSliceInfo> slices; ChannelList::ConstIterator i = channels.begin(); // current offset of channel: pixel data starts at offset*width into the // decompressed scanline buffer size_t offset = 0; for (FrameBuffer::ConstIterator j = frameBuffer.begin(); j != frameBuffer.end(); ++j) { while (i != channels.end() && strcmp (i.name(), j.name()) < 0) { // // Channel i is present in the file but not // in the frame buffer; data for channel i // will be skipped during readPixels(). // slices.push_back (InSliceInfo (i.channel().type, i.channel().type, 0, // base 0, // xStride 0, // yStride i.channel().xSampling, i.channel().ySampling, false, // fill true, // skip 0.0)); // fillValue switch(i.channel().type) { case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF : offset++; break; case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT : offset+=2; break; case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT : offset+=2; break; } ++i; } bool fill = false; if (i == channels.end() || strcmp (i.name(), j.name()) > 0) { // // Channel i is present in the frame buffer, but not in the file. // In the frame buffer, slice j will be filled with a default value. // fill = true; } slices.push_back (InSliceInfo (j.slice().type, fill? j.slice().type: i.channel().type, j.slice().base, j.slice().xStride, j.slice().yStride, j.slice().xSampling, j.slice().ySampling, fill, false, // skip j.slice().fillValue)); if(!fill && i.channel().type!=OPENEXR_IMF_INTERNAL_NAMESPACE::HALF) { optimizationPossible = false; } if(j.slice().type != OPENEXR_IMF_INTERNAL_NAMESPACE::HALF) { optimizationPossible = false; } if(j.slice().xSampling!=1 || j.slice().ySampling!=1) { optimizationPossible = false; } if(optimizationPossible) { sliceOptimizationData dat; dat.base = j.slice().base; dat.fill = fill; dat.fillValue = j.slice().fillValue; dat.offset = offset; dat.xStride = j.slice().xStride; dat.yStride = j.slice().yStride; dat.xSampling = j.slice().xSampling; dat.ySampling = j.slice().ySampling; optData.push_back(dat); } if(!fill) { switch(i.channel().type) { case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF : offset++; break; case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT : offset+=2; break; case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT : offset+=2; break; } } if (i != channels.end() && !fill) ++i; } if(optimizationPossible) { // // check optimisibility // based on channel ordering and fill channel positions // sort(optData.begin(),optData.end()); _data->optimizationMode = detectOptimizationMode(optData); } if(!optimizationPossible || _data->optimizationMode._optimizable==false) { optData = vector<sliceOptimizationData>(); _data->optimizationMode._optimizable=false; } // // Store the new frame buffer. // _data->frameBuffer = frameBuffer; _data->slices = slices; _data->optimizationData = optData; }