Esempio n. 1
0
File: rlc.cpp Progetto: imssbc/irena
void CRLC<T>::doEncode(CImage<T> * pImg, CBitstream * pBstr)
{
	for(int k=0;k<pImg->getComponents(); k++)
	{
		CSize size((*pImg)[k].getHeight(), (*pImg)[k].getWidth());
		for(int y=0; y < (*pImg)[k].getHeight(); y+=8)
		{
			for(int x=0; x < (*pImg)[k].getWidth(); x+=8)
			{
				EncodeBlock(&(*pImg)[k][0][0], CPoint(k, y, x), size, pBstr);
			}
		}
	}
}
Esempio n. 2
0
/// RefinementScan::WriteMCU
// Write a single MCU in this scan. Return true if there are more blocks in this row.
bool RefinementScan::WriteMCU(void)
{ 
  bool more = true;
  int c;

  assert(m_pBlockCtrl);
  
  BeginWriteMCU(m_bMeasure?NULL:m_Stream.ByteStreamOf());

  for(c = 0;c < m_ucCount;c++) {
    class Component *comp           = m_pComponent[c];
    class QuantizedRow *q           = m_pBlockCtrl->CurrentQuantizedRow(comp->IndexOf());
    class HuffmanCoder *ac          = m_pACCoder[c];
    class HuffmanStatistics *acstat = m_pACStatistics[c];
    UWORD &skip                     = m_usSkip[c];
    UBYTE mcux                      = (m_ucCount > 1)?(comp->MCUWidthOf() ):(1);
    UBYTE mcuy                      = (m_ucCount > 1)?(comp->MCUHeightOf()):(1);
    ULONG xmin                      = m_ulX[c];
    ULONG xmax                      = xmin + mcux;
    ULONG x,y; 
    if (xmax >= q->WidthOf()) {
      more     = false;
    }
    for(y = 0;y < mcuy;y++) {
      for(x = xmin;x < xmax;x++) {
        LONG *block,dummy[64];
        if (q && x < q->WidthOf()) {
          block  = q->BlockAt(x)->m_Data;
        } else {
          block  = dummy;
          memset(dummy ,0,sizeof(dummy) );
        }
        if (m_bMeasure) {
          MeasureBlock(block,acstat,skip);
        } else {
          EncodeBlock(block,ac,skip);
        }
      }
      if (q) q = q->NextOf();
    }
    // Done with this component, advance the block.
    m_ulX[c] = xmax;
  }

  return more;
}
Esempio n. 3
0
// Encode a source buffer, adding padding and line breaks
void Encode(const unsigned char *src, size_t len,
            std::vector<unsigned char> &dst) {
  const size_t lineSize = 0;  // Do not insert linefeeds (illegal in JSON)
  size_t blocksOut = 0;
  for (size_t j = 0; j < len; /*EMPTY*/) {
    size_t k = 0;
    unsigned char in[3], out[4];
    for (size_t i = 0; i < 3; ++i) {
      if (j < len) {
        ++k;
        in[i] = src[j++];
      } else {
        in[i] = 0;
      }
    }
    if (k) {
      EncodeBlock(in, out, k);
      ++blocksOut;
      for (size_t i = 0; i < 4; ++i)
        dst.push_back(out[i]);
    }
    if (lineSize > 0 && (blocksOut >= lineSize/4 || j >= len)) {
      if (blocksOut) {
        dst.push_back('\r');
        dst.push_back('\n');
      }
      blocksOut = 0;
    }
  }
  
  // Percent-encode any trailing equals signs
  size_t neq = 0;
  for (size_t i = 0; i < 4; ++i)
    if (dst[dst.size() - 1 - i] == '=')
      neq++;
  if (neq) {
    dst.resize(dst.size() - neq);
    for (size_t i = 0; i < neq; ++i) {
      dst.push_back('%');
      dst.push_back('3');
      dst.push_back('D');
    }
  }
}
Esempio n. 4
0
/// ACRefinementScan::WriteMCU
// Write a single MCU in this scan. Return true if there are more blocks in this row.
bool ACRefinementScan::WriteMCU(void)
{ 
#if ACCUSOFT_CODE
  bool more = true;
  int c;

  assert(m_pBlockCtrl);

  BeginWriteMCU(m_Coder.ByteStreamOf());

  for(c = 0;c < m_ucCount;c++) {
    class Component *comp    = m_pComponent[c];
    class QuantizedRow *q    = m_pBlockCtrl->CurrentQuantizedRow(comp->IndexOf());
    UBYTE mcux               = (m_ucCount > 1)?(comp->MCUWidthOf() ):(1);
    UBYTE mcuy               = (m_ucCount > 1)?(comp->MCUHeightOf()):(1);
    ULONG xmin               = m_ulX[c];
    ULONG xmax               = xmin + mcux;
    ULONG x,y; 
    if (xmax >= q->WidthOf()) {
      more     = false;
    }
    for(y = 0;y < mcuy;y++) {
      for(x = xmin;x < xmax;x++) {
        LONG *block,dummy[64];
        if (q && x < q->WidthOf()) {
          block  = q->BlockAt(x)->m_Data;
        } else {
          block  = dummy;
          memset(dummy ,0,sizeof(dummy) );
        }
        EncodeBlock(block);
      }
      if (q) q = q->NextOf();
    }
    // Done with this component, advance the block.
    m_ulX[c] = xmax;
  }

  return more;
#else
  return false;
#endif
}
Esempio n. 5
0
// blockSize > 0
UInt32 CThreadInfo::EncodeBlockWithHeaders(const Byte *block, UInt32 blockSize)
{
  WriteByte2(kBlockSig0);
  WriteByte2(kBlockSig1);
  WriteByte2(kBlockSig2);
  WriteByte2(kBlockSig3);
  WriteByte2(kBlockSig4);
  WriteByte2(kBlockSig5);

  CBZip2CRC crc;
  int numReps = 0;
  Byte prevByte = block[0];
  UInt32 i = 0;
  do 
  {
    Byte b = block[i];
    if (numReps == kRleModeRepSize)
    {
      for (; b > 0; b--)
        crc.UpdateByte(prevByte);
      numReps = 0;
      continue;
    }
    if (prevByte == b)
      numReps++;
    else
    {
      numReps = 1;
      prevByte = b;
    }
    crc.UpdateByte(b);
  }
  while (++i < blockSize);
  UInt32 crcRes = crc.GetDigest();
  WriteCRC2(crcRes);
  EncodeBlock(block, blockSize);
  return crcRes;
}
void FIndirectLightingCache::UpdateBlock(FScene* Scene, FViewInfo* DebugDrawingView, FBlockUpdateInfo& BlockInfo)
{
	const int32 NumSamplesPerBlock = BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize;
	FSHVectorRGB3 SingleSample;

	float DirectionalShadowing = 1;
	FVector SkyBentNormal(0, 0, 1);

	//always do point interpolation to get valid 3band single sample and directional data.
	InterpolatePoint(Scene, BlockInfo.Block, DirectionalShadowing, SingleSample, SkyBentNormal);

	if (CanIndirectLightingCacheUseVolumeTexture(GetFeatureLevel()) && !BlockInfo.Allocation->bPointSample)
	{
		static TArray<float> AccumulatedWeight;
		AccumulatedWeight.Reset(NumSamplesPerBlock);
		AccumulatedWeight.AddZeroed(NumSamplesPerBlock);

		//volume textures are encoded as two band, so no reason to waste perf interpolating 3 bands.
		static TArray<FSHVectorRGB2> AccumulatedIncidentRadiance;

		AccumulatedIncidentRadiance.Reset(NumSamplesPerBlock);
		AccumulatedIncidentRadiance.AddZeroed(NumSamplesPerBlock);

		// Interpolate SH samples from precomputed lighting samples and accumulate lighting data for an entire block
		InterpolateBlock(Scene, BlockInfo.Block, AccumulatedWeight, AccumulatedIncidentRadiance);

		static TArray<FFloat16Color> Texture0Data;
		static TArray<FFloat16Color> Texture1Data;
		static TArray<FFloat16Color> Texture2Data;
		Texture0Data.Reset(NumSamplesPerBlock);
		Texture1Data.Reset(NumSamplesPerBlock);
		Texture2Data.Reset(NumSamplesPerBlock);
		Texture0Data.AddUninitialized(NumSamplesPerBlock);
		Texture1Data.AddUninitialized(NumSamplesPerBlock);
		Texture2Data.AddUninitialized(NumSamplesPerBlock);

		const int32 FormatSize = GPixelFormats[PF_FloatRGBA].BlockBytes;
		check(FormatSize == sizeof(FFloat16Color));

		// Encode the SH samples into a texture format
		// Note the single sample is updated even if this is a volume allocation, because translucent materials only use the single sample
		EncodeBlock(DebugDrawingView, BlockInfo.Block, AccumulatedWeight, AccumulatedIncidentRadiance, Texture0Data, Texture1Data, Texture2Data);

		// Setup an update region
		const FUpdateTextureRegion3D UpdateRegion(
			BlockInfo.Block.MinTexel.X,
			BlockInfo.Block.MinTexel.Y,
			BlockInfo.Block.MinTexel.Z,
			0,
			0,
			0,
			BlockInfo.Block.TexelSize,
			BlockInfo.Block.TexelSize,
			BlockInfo.Block.TexelSize);

		// Update the volume texture atlas
		RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture0().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture0Data.GetData());
		RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture1().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture1Data.GetData());
		RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture2().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture2Data.GetData());
	}
	else
	{
		if (GCacheDrawInterpolationPoints != 0 && DebugDrawingView)
		{
			FViewElementPDI DebugPDI(DebugDrawingView, NULL);
			const FVector WorldPosition = BlockInfo.Block.Min;
			DebugPDI.DrawPoint(WorldPosition, FLinearColor(0, 0, 1), 10, SDPG_World);
		}
	}

	// Record the position that the sample was taken at
	BlockInfo.Allocation->TargetPosition = BlockInfo.Block.Min + BlockInfo.Block.Size / 2;

	BlockInfo.Allocation->TargetSamplePacked0[0] = FVector4(SingleSample.R.V[0], SingleSample.R.V[1], SingleSample.R.V[2], SingleSample.R.V[3]) / PI;
	BlockInfo.Allocation->TargetSamplePacked0[1] = FVector4(SingleSample.G.V[0], SingleSample.G.V[1], SingleSample.G.V[2], SingleSample.G.V[3]) / PI;
	BlockInfo.Allocation->TargetSamplePacked0[2] = FVector4(SingleSample.B.V[0], SingleSample.B.V[1], SingleSample.B.V[2], SingleSample.B.V[3]) / PI;
	BlockInfo.Allocation->TargetSamplePacked1[0] = FVector4(SingleSample.R.V[4], SingleSample.R.V[5], SingleSample.R.V[6], SingleSample.R.V[7]) / PI;
	BlockInfo.Allocation->TargetSamplePacked1[1] = FVector4(SingleSample.G.V[4], SingleSample.G.V[5], SingleSample.G.V[6], SingleSample.G.V[7]) / PI;
	BlockInfo.Allocation->TargetSamplePacked1[2] = FVector4(SingleSample.B.V[4], SingleSample.B.V[5], SingleSample.B.V[6], SingleSample.B.V[7]) / PI;
	BlockInfo.Allocation->TargetSamplePacked2 = FVector4(SingleSample.R.V[8], SingleSample.G.V[8], SingleSample.B.V[8], 0) / PI;

	BlockInfo.Allocation->TargetDirectionalShadowing = DirectionalShadowing;

	const float BentNormalLength = SkyBentNormal.Size();
	BlockInfo.Allocation->TargetSkyBentNormal = FVector4(SkyBentNormal / FMath::Max(BentNormalLength, .0001f), BentNormalLength);

	if (!BlockInfo.Allocation->bHasEverUpdatedSingleSample)
	{
		// If this is the first update, also set the interpolated state to match the new target
		//@todo - detect and handle teleports in the same way
		BlockInfo.Allocation->SingleSamplePosition = BlockInfo.Allocation->TargetPosition;

		for (int32 VectorIndex = 0; VectorIndex < 3; VectorIndex++) // RGB
		{
			BlockInfo.Allocation->SingleSamplePacked0[VectorIndex] = BlockInfo.Allocation->TargetSamplePacked0[VectorIndex];
			BlockInfo.Allocation->SingleSamplePacked1[VectorIndex] = BlockInfo.Allocation->TargetSamplePacked1[VectorIndex];
		}
		BlockInfo.Allocation->SingleSamplePacked2 = BlockInfo.Allocation->TargetSamplePacked2;
		BlockInfo.Allocation->CurrentDirectionalShadowing = BlockInfo.Allocation->TargetDirectionalShadowing;
		BlockInfo.Allocation->CurrentSkyBentNormal = BlockInfo.Allocation->TargetSkyBentNormal;

		BlockInfo.Allocation->bHasEverUpdatedSingleSample = true;
	}

	BlockInfo.Block.bHasEverBeenUpdated = true;
}
Esempio n. 7
0
bool CDynamicHuffman<T>::EncodeBlock(T * ptr,uint32_t size,CBitstream * bstr)
{
	return EncodeBlock(ptr, size, bstr, true);
}
void FIndirectLightingCache::UpdateBlock(FScene* Scene, FViewInfo* DebugDrawingView, FBlockUpdateInfo& BlockInfo)
{
	const int32 NumSamplesPerBlock = BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize;

	FSHVectorRGB2 SingleSample;
	float DirectionalShadowing = 1;

	if (CanIndirectLightingCacheUseVolumeTexture() && BlockInfo.Allocation->bOpaqueRelevance)
	{
		static TArray<float> AccumulatedWeight;
		AccumulatedWeight.Reset(NumSamplesPerBlock);
		AccumulatedWeight.AddZeroed(NumSamplesPerBlock);

		static TArray<FSHVectorRGB2> AccumulatedIncidentRadiance;
		AccumulatedIncidentRadiance.Reset(NumSamplesPerBlock);
		AccumulatedIncidentRadiance.AddZeroed(NumSamplesPerBlock);

		// Interpolate SH samples from precomputed lighting samples and accumulate lighting data for an entire block
		InterpolateBlock(Scene, BlockInfo.Block, AccumulatedWeight, AccumulatedIncidentRadiance);

		static TArray<FFloat16Color> Texture0Data;
		static TArray<FFloat16Color> Texture1Data;
		static TArray<FFloat16Color> Texture2Data;
		Texture0Data.Reset(NumSamplesPerBlock);
		Texture1Data.Reset(NumSamplesPerBlock);
		Texture2Data.Reset(NumSamplesPerBlock);
		Texture0Data.AddUninitialized(NumSamplesPerBlock);
		Texture1Data.AddUninitialized(NumSamplesPerBlock);
		Texture2Data.AddUninitialized(NumSamplesPerBlock);

		const int32 FormatSize = GPixelFormats[PF_FloatRGBA].BlockBytes;
		check(FormatSize == sizeof(FFloat16Color));

		// Encode the SH samples into a texture format
		EncodeBlock(DebugDrawingView, BlockInfo.Block, AccumulatedWeight, AccumulatedIncidentRadiance, Texture0Data, Texture1Data, Texture2Data, SingleSample);

		// Setup an update region
		const FUpdateTextureRegion3D UpdateRegion(
			BlockInfo.Block.MinTexel.X,
			BlockInfo.Block.MinTexel.Y,
			BlockInfo.Block.MinTexel.Z,
			0,
			0,
			0,
			BlockInfo.Block.TexelSize,
			BlockInfo.Block.TexelSize,
			BlockInfo.Block.TexelSize);

		// Update the volume texture atlas
		RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture0().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture0Data.GetData());
		RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture1().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture1Data.GetData());
		RHIUpdateTexture3D((const FTexture3DRHIRef&)GetTexture2().ShaderResourceTexture, 0, UpdateRegion, BlockInfo.Block.TexelSize * FormatSize, BlockInfo.Block.TexelSize * BlockInfo.Block.TexelSize * FormatSize, (const uint8*)Texture2Data.GetData());
	}
	else
	{
		InterpolatePoint(Scene, BlockInfo.Block, DirectionalShadowing, SingleSample);
	}

	// Record the position that the sample was taken at
	BlockInfo.Allocation->TargetPosition = BlockInfo.Block.Min + BlockInfo.Block.Size / 2;
	BlockInfo.Allocation->TargetSamplePacked[0] = FVector4(SingleSample.R.V[0], SingleSample.R.V[1], SingleSample.R.V[2], SingleSample.R.V[3]) / PI;
	BlockInfo.Allocation->TargetSamplePacked[1] = FVector4(SingleSample.G.V[0], SingleSample.G.V[1], SingleSample.G.V[2], SingleSample.G.V[3]) / PI;
	BlockInfo.Allocation->TargetSamplePacked[2] = FVector4(SingleSample.B.V[0], SingleSample.B.V[1], SingleSample.B.V[2], SingleSample.B.V[3]) / PI;
	BlockInfo.Allocation->TargetDirectionalShadowing = DirectionalShadowing;

	if (!BlockInfo.Allocation->bHasEverUpdatedSingleSample)
	{
		// If this is the first update, also set the interpolated state to match the new target
		//@todo - detect and handle teleports in the same way
		BlockInfo.Allocation->SingleSamplePosition = BlockInfo.Allocation->TargetPosition;

		for (int32 VectorIndex = 0; VectorIndex < ARRAY_COUNT(BlockInfo.Allocation->SingleSamplePacked); VectorIndex++)
		{
			BlockInfo.Allocation->SingleSamplePacked[VectorIndex] = BlockInfo.Allocation->TargetSamplePacked[VectorIndex];
		}

		BlockInfo.Allocation->CurrentDirectionalShadowing = BlockInfo.Allocation->TargetDirectionalShadowing;

		BlockInfo.Allocation->bHasEverUpdatedSingleSample = true;
	}

	BlockInfo.Block.bHasEverBeenUpdated = true;
}
Esempio n. 9
0
/// SequentialScan::WriteMCU
// Write a single MCU in this scan. Return true if there are more blocks in this row.
bool SequentialScan::WriteMCU(void)
{ 
  bool more = true;
  int c;

  assert(m_pBlockCtrl);

  BeginWriteMCU(m_Stream.ByteStreamOf());
  
  for(c = 0;c < m_ucCount;c++) {
    class Component *comp           = m_pComponent[c];
    class QuantizedRow *q           = m_pBlockCtrl->CurrentQuantizedRow(comp->IndexOf());
    class HuffmanCoder *dc          = m_pDCCoder[c];
    class HuffmanCoder *ac          = m_pACCoder[c];
    class HuffmanStatistics *dcstat = m_pDCStatistics[c];
    class HuffmanStatistics *acstat = m_pACStatistics[c];
    LONG &prevdc                    = m_lDC[c];
    UWORD &skip                     = m_usSkip[c];
    UBYTE mcux                      = (m_ucCount > 1)?(comp->MCUWidthOf() ):(1);
    UBYTE mcuy                      = (m_ucCount > 1)?(comp->MCUHeightOf()):(1);
    ULONG xmin                      = m_ulX[c];
    ULONG xmax                      = xmin + mcux;
    ULONG x,y; 
    if (xmax >= q->WidthOf()) {
      more     = false;
    }
    for(y = 0;y < mcuy;y++) {
      for(x = xmin;x < xmax;x++) {
        LONG *block,dummy[64];
        if (q && x < q->WidthOf()) {
          block  = q->BlockAt(x)->m_Data;
        } else {
          block  = dummy;
          memset(dummy ,0,sizeof(dummy) );
          block[0] = prevdc;
        }
#if HIERARCHICAL_HACK
        // A nice hack for the hierarchical scan: If this is not the last frame
        // in the hierarchy, remove all coefficients below the diagonal to allow a
        // fast "EOB", they can be encoded by the level above.
        if (m_pFrame->NextOf()) {
          LONG i,j;
          for(j = 0;j < 8;j++) {
            for(i = 0;i < 8;i++) {
              if (i+j > 4) {
                block[i + (j << 3)] = 0;
              }
            }
          }
        }
#endif
        if (m_bMeasure) {
          MeasureBlock(block,dcstat,acstat,prevdc,skip);
        } else {
          EncodeBlock(block,dc,ac,prevdc,skip);
        }
      }
      if (q) q = q->NextOf();
    }
    // Done with this component, advance the block.
    m_ulX[c] = xmax;
  }

  return more;
}