예제 #1
0
static int DecodeACComponent(WinZipJPEGDecompressor *self,int comp,unsigned int k,bool canbezero,
const WinZipJPEGBlock *current,const WinZipJPEGBlock *north,const WinZipJPEGBlock *west,
const WinZipJPEGQuantizationTable *quantization)
{
	if(!north) north=&ZeroBlock;
	if(!west) west=&ZeroBlock;

	int val1;
	if(IsFirstRowOrColumn(k)) val1=Abs(BDR(k,current,north,west,quantization));
	else val1=Average(k,north,west,quantization);

	int val2=Sum(k,current);

	if(canbezero)
	{
		// Decode zero/non-zero bit. (5.6.6.1)
		int zerocontext1=Min(Category(val1),2);
		int zerocontext2=Min(Category(val2),5);

		int nonzero=NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder,
		&self->zerobins[comp][k-1][zerocontext1][zerocontext2]);

		// If this component is zero, there is no need to decode further parameters.
		if(!nonzero) return 0;
	}

	// This component is not zero. Proceed with decoding absolute value.
	int absvalue;

	// Decode pivot (abs>=2). (5.6.6.2)
	int pivotcontext1=Min(Category(val1),4);
	int pivotcontext2=Min(Category(val2),6);

	int pivot=NextBitFromWinZipJPEGArithmeticDecoder(&self->decoder,
	&self->pivotbins[comp][k-1][pivotcontext1][pivotcontext2]);

	if(!pivot)
	{
		// The absolute of this component is not >=2. It must therefore be 1,
		// and there is no need to decode the value.
		absvalue=1;
	}
	else
	{
		// The absolute of this component is >=2. Proceed with decoding
		// the absolute value. (5.6.6.3)
		int val3,n;
		if(IsFirstRow(k)) { val3=Column(k)-1; n=0; }
		else if(IsFirstColumn(k)) { val3=Row(k)-1; n=1; }
		else { val3=Category(k-4); n=2; }

		int magnitudecontext1=Min(Category(val1),8);
		int magnitudecontext2=Min(Category(val2),8);
		int remaindercontext=val3;

		// Decode absolute value.
		absvalue=DecodeBinarization(&self->decoder,
		self->acmagnitudebins[comp][n][magnitudecontext1][magnitudecontext2],
		self->acremainderbins[comp][n][remaindercontext],
		14,9)+2;
	}

	if(DecodeACSign(self,comp,k,absvalue,current,north,west,quantization)) return -absvalue;
	else return absvalue;
}
예제 #2
0
static bool IsFirstRowOrColumn(unsigned int k) { return IsFirstRow(k)||IsFirstColumn(k); }
예제 #3
0
static void CompressACComponent(JPEGCompressor *self,int comp,unsigned int k,bool canbezero,
const JPEGBlock *current,const JPEGBlock *north,const JPEGBlock *west,
const JPEGQuantizationTable *quantization)
{
	int value=current->c[k];

	if(!north) north=&ZeroBlock;
	if(!west) west=&ZeroBlock;

	int val1;
	if(IsFirstRowOrColumn(k)) val1=Abs(BDR(k,current,north,west,quantization));
	else val1=Average(k,north,west,quantization);

	int val2=Sum(k,current);

	if(canbezero)
	{
		// Compress zero/non-zero bit.
		int zerocontext1=Min(Category(val1),2);
		int zerocontext2=Min(Category(val2),5);

		WriteDynamicBit(&self->encoder,value!=0,
		&self->zerobins[comp][k-1][zerocontext1][zerocontext2],
		self->zeroshift);

		// If this component is zero, there is no need to compress further parameters.
		if(value==0) return;
	}

	// This component is not zero. Proceed with compressing absolute value.
	int absvalue=Abs(value);

	// Compress pivot (abs>=2).
	int pivotcontext1=Min(Category(val1),4);
	int pivotcontext2=Min(Category(val2),6);

	WriteDynamicBit(&self->encoder,absvalue>1,
	&self->pivotbins[comp][k-1][pivotcontext1][pivotcontext2],
	self->pivotshift);

	if(absvalue>1)
	{
		// The absolute of this component is >=2. Proceed with compressing
		// the absolute value.
		int val3,n;
		if(IsFirstRow(k)) { val3=Column(k)-1; n=0; }
		else if(IsFirstColumn(k)) { val3=Row(k)-1; n=1; }
		else { val3=Category(k-4); n=2; }

		int magnitudecontext1=Min(Category(val1),8);
		int magnitudecontext2=Min(Category(val2),8);
		int remaindercontext=val3;

		// Compress absolute value.
		WriteUniversalCode(&self->encoder,absvalue-2,
		self->acmagnitudebins[comp][n][magnitudecontext1][magnitudecontext2],
		self->acmagnitudeshift,
		self->acremainderbins[comp][n][remaindercontext],
		self->acremaindershift);
	}

	CompressACSign(self,comp,k,absvalue,current,north,west,quantization);
}