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 CompositeDeepScanLine::Data::handleDeepFrameBuffer(DeepFrameBuffer& buf, std::vector< unsigned int > & counts, vector< std::vector< float* > > & pointers, const Header& header, int start, int end) { int width=_dataWindow.size().x+1; size_t pixelcount = width * (end-start+1); pointers.resize(_channels.size()); counts.resize(pixelcount); buf.insertSampleCountSlice(Slice(UINT,(char *) (&counts[0]-_dataWindow.min.x-start*width), sizeof(unsigned int), sizeof(unsigned int)*width ) ); pointers[0].resize(pixelcount); buf.insert("Z",DeepSlice(FLOAT,(char *)(&pointers[0][0]-_dataWindow.min.x-start*width), sizeof(float *), sizeof(float *)*width, sizeof(float) ) ) ; if(_zback) { pointers[1].resize(pixelcount); buf.insert("ZBack",DeepSlice(FLOAT,(char *)(&pointers[1][0]-_dataWindow.min.x-start*width), sizeof(float *), sizeof(float *)*width, sizeof(float) ) ); } pointers[2].resize(pixelcount); buf.insert("A",DeepSlice(FLOAT,(char *)(&pointers[2][0]-_dataWindow.min.x-start*width), sizeof(float *), sizeof(float *)*width, sizeof(float) ) ); size_t i =0; for(FrameBuffer::ConstIterator qt = _outputFrameBuffer.begin();qt !=_outputFrameBuffer.end();qt++) { int channel_in_source = _bufferMap[i]; if(channel_in_source>2) { // not dealt with yet (0,1,2 previously inserted) pointers[channel_in_source].resize(pixelcount); buf.insert(qt.name(), DeepSlice(FLOAT,(char *)(&pointers[channel_in_source][0]-_dataWindow.min.x-start*width), sizeof(float *), sizeof(float *)*width, sizeof(float) ) ); } i++; } }
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; }