Beispiel #1
0
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;
}