⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tonyjpegdecoder.cpp

📁 About JPEG, executable on Visual C++
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		}
	}

	unsigned char pYCbCr[384];//Three color components, 256 + 64 + 64 bytes 
	short coef[64];	
	
	//	Do Y/Cb/Cr components, 
	//	if m_nBlocksInMcu==6,  Y: 4 blocks; Cb: 1 block; Cr: 1 block
	//	if m_nBlocksInMcu==3,  Y: 1 block; Cb: 1 block; Cr: 1 block
	for( int i=0; i<m_nBlocksInMcu; i++ )
	{
		HuffmanDecode( coef, i );	//source is m_pData; coef is result
		InverseDct( coef, pYCbCr + i*64, i );	//De-scale and inverse dct		
	}

	//	Color conversion and up-sampling
	YCbCrToBGREx( pYCbCr, pBgr );

	// Account for restart interval (no-op if not using restarts) 
	restarts_to_go--;

	return true;
}


////////////////////////////////////////////////////////////////////////////////
//	Color conversion and up-sampling
//	if m_nBlocksInMcu==3, no need to up-sampling

void CTonyJpegDecoder::YCbCrToBGREx(	
		unsigned char * pYCbCr,	//in, Y: 256 or 64 bytes; Cb: 64 bytes; Cr: 64 bytes 
		unsigned char * pBgr	//out, BGR format, 16*16*3 = 768 bytes; or 8*8*3=192 bytes
		)
{
	int i, j;
	unsigned char y, cb, cr, *pByte, *py[4], *pcb, *pcr;

	pByte = pBgr;
	for( i = 0; i < m_nBlocksInMcu-2; i++ )
		py[i] = pYCbCr + i * 64;
	pcb	  = pYCbCr + (m_nBlocksInMcu-2) * 64;
	pcr   = pcb + 64;
	unsigned char * range_limit = m_tblRange + 256;
	
	for( j=0; j<m_nMcuSize; j++ )//vertical axis
	{
		for( i=0; i<m_nMcuSize; i++ )	//horizontal axis
		{			
			//	block number is ((j/8) * 2 + i/8)={0, 1, 2, 3}
			//	if m_nMcuSize==8, will use py[0];
			y = *( py[(j>>3) * 2 + (i>>3)] ++ );
		
			cb = pcb[j/2 * 8 + i/2];
			cr = pcr[j/2 * 8 + i/2]; 

			//	Blue
			*(pByte++) = range_limit[ y + m_CbToB[cb] ];

			//	Green
			*(pByte++) = range_limit[ y + ((m_CbToG[cb] + m_CrToG[cr])>>16) ];

			//	Red
			*(pByte++) = range_limit[ y + m_CrToR[cr] ];
		}
	}
}

////////////////////////////////////////////////////////////////////////////////

//	AA&N DCT algorithm implemention

void CTonyJpegDecoder::InverseDct( 
		short* coef, 			//in, dct coefficients, length = 64
		unsigned char* data, 	//out, 64 bytes		
		int nBlock				//block index: 0~3:Y; 4:Cb; 5:Cr
		)
{

#define FIX_1_082392200  ((int)277)		/* FIX(1.082392200) */
#define FIX_1_414213562  ((int)362)		/* FIX(1.414213562) */
#define FIX_1_847759065  ((int)473)		/* FIX(1.847759065) */
#define FIX_2_613125930  ((int)669)		/* FIX(2.613125930) */
	
#define MULTIPLY(var,cons)  ((int) ((var)*(cons))>>8 )

	int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
	int tmp10, tmp11, tmp12, tmp13;
	int z5, z10, z11, z12, z13;
	int workspace[64];		/* buffers data between passes */

	short* inptr = coef;
	unsigned short* quantptr;	
	int* wsptr = workspace;
	unsigned char* outptr;
	unsigned char* range_limit = &(m_tblRange[256+128]);
	int ctr, dcval, DCTSIZE = 8;

	if( nBlock < 4 )
		quantptr = m_qtblY;
	else
		quantptr = m_qtblCbCr;
	
	//Pass 1: process columns from input (inptr), store into work array(wsptr)
	
	for (ctr = 8; ctr > 0; ctr--) {
    /* Due to quantization, we will usually find that many of the input
	* coefficients are zero, especially the AC terms.  We can exploit this
	* by short-circuiting the IDCT calculation for any column in which all
	* the AC terms are zero.  In that case each output is equal to the
	* DC coefficient (with scale factor as needed).
	* With typical images and quantization tables, half or more of the
	* column DCT calculations can be simplified this way.
	*/
		
		if ((inptr[DCTSIZE*1] | inptr[DCTSIZE*2] | inptr[DCTSIZE*3] |
			inptr[DCTSIZE*4] | inptr[DCTSIZE*5] | inptr[DCTSIZE*6] |
			inptr[DCTSIZE*7]) == 0) 
		{
			/* AC terms all zero */
			dcval = (int)( inptr[DCTSIZE*0] * quantptr[DCTSIZE*0] );
			
			wsptr[DCTSIZE*0] = dcval;
			wsptr[DCTSIZE*1] = dcval;
			wsptr[DCTSIZE*2] = dcval;
			wsptr[DCTSIZE*3] = dcval;
			wsptr[DCTSIZE*4] = dcval;
			wsptr[DCTSIZE*5] = dcval;
			wsptr[DCTSIZE*6] = dcval;
			wsptr[DCTSIZE*7] = dcval;
			
			inptr++;			/* advance pointers to next column */
			quantptr++;
			wsptr++;
			continue;
		}
		
		/* Even part */
		
		tmp0 = inptr[DCTSIZE*0] * quantptr[DCTSIZE*0];
		tmp1 = inptr[DCTSIZE*2] * quantptr[DCTSIZE*2];
		tmp2 = inptr[DCTSIZE*4] * quantptr[DCTSIZE*4];
		tmp3 = inptr[DCTSIZE*6] * quantptr[DCTSIZE*6];
		
		tmp10 = tmp0 + tmp2;	/* phase 3 */
		tmp11 = tmp0 - tmp2;
		
		tmp13 = tmp1 + tmp3;	/* phases 5-3 */
		tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
		
		tmp0 = tmp10 + tmp13;	/* phase 2 */
		tmp3 = tmp10 - tmp13;
		tmp1 = tmp11 + tmp12;
		tmp2 = tmp11 - tmp12;
		
		/* Odd part */
		
		tmp4 = inptr[DCTSIZE*1] * quantptr[DCTSIZE*1];
		tmp5 = inptr[DCTSIZE*3] * quantptr[DCTSIZE*3];
		tmp6 = inptr[DCTSIZE*5] * quantptr[DCTSIZE*5];
		tmp7 = inptr[DCTSIZE*7] * quantptr[DCTSIZE*7];
		
		z13 = tmp6 + tmp5;		/* phase 6 */
		z10 = tmp6 - tmp5;
		z11 = tmp4 + tmp7;
		z12 = tmp4 - tmp7;
		
		tmp7  = z11 + z13;		/* phase 5 */
		tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
		
		z5	  = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
		tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
		tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
		
		tmp6 = tmp12 - tmp7;	/* phase 2 */
		tmp5 = tmp11 - tmp6;
		tmp4 = tmp10 + tmp5;
		
		wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
		wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
		wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
		wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
		wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
		wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
		wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
		wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
		
		inptr++;			/* advance pointers to next column */
		quantptr++;
		wsptr++;
	}
	
	/* Pass 2: process rows from work array, store into output array. */
	/* Note that we must descale the results by a factor of 8 == 2**3, */
	/* and also undo the PASS1_BITS scaling. */

int RANGE_MASK = 1023; //2 bits wider than legal samples
#define PASS1_BITS  2
#define IDESCALE(x,n)  ((int) ((x)>>n) )
	
	wsptr = workspace;
	for (ctr = 0; ctr < DCTSIZE; ctr++) {
		outptr = data + ctr * 8;
	
		/* Rows of zeroes can be exploited in the same way as we did with columns.
		* However, the column calculation has created many nonzero AC terms, so
		* the simplification applies less often (typically 5% to 10% of the time).
		* On machines with very fast multiplication, it's possible that the
		* test takes more time than it's worth.  In that case this section
		* may be commented out.
		*/
		
		if ((wsptr[1] | wsptr[2] | wsptr[3] | wsptr[4] | wsptr[5] | wsptr[6] |
			wsptr[7]) == 0) {
			/* AC terms all zero */
			dcval = (int) range_limit[ (wsptr[0] >> 5) & RANGE_MASK];		
			outptr[0] = dcval;
			outptr[1] = dcval;
			outptr[2] = dcval;
			outptr[3] = dcval;
			outptr[4] = dcval;
			outptr[5] = dcval;
			outptr[6] = dcval;
			outptr[7] = dcval;
			
			wsptr += DCTSIZE;		/* advance pointer to next row */
			continue;
		}
		
		/* Even part */
		
		tmp10 = ((int) wsptr[0] + (int) wsptr[4]);
		tmp11 = ((int) wsptr[0] - (int) wsptr[4]);
		
		tmp13 = ((int) wsptr[2] + (int) wsptr[6]);
		tmp12 = MULTIPLY((int) wsptr[2] - (int) wsptr[6], FIX_1_414213562)
			- tmp13;
		
		tmp0 = tmp10 + tmp13;
		tmp3 = tmp10 - tmp13;
		tmp1 = tmp11 + tmp12;
		tmp2 = tmp11 - tmp12;
		
		/* Odd part */
		
		z13 = (int) wsptr[5] + (int) wsptr[3];
		z10 = (int) wsptr[5] - (int) wsptr[3];
		z11 = (int) wsptr[1] + (int) wsptr[7];
		z12 = (int) wsptr[1] - (int) wsptr[7];
		
		tmp7 = z11 + z13;		/* phase 5 */
		tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
		
		z5    = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
		tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
		tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
		
		tmp6 = tmp12 - tmp7;	/* phase 2 */
		tmp5 = tmp11 - tmp6;
		tmp4 = tmp10 + tmp5;
		
		/* Final output stage: scale down by a factor of 8 and range-limit */
		
		outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
			& RANGE_MASK];
		outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
			& RANGE_MASK];
		outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
			& RANGE_MASK];
		outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
			& RANGE_MASK];
		outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
			& RANGE_MASK];
		outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
			& RANGE_MASK];
		outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
			& RANGE_MASK];
		outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
			& RANGE_MASK];
		
		wsptr += DCTSIZE;		/* advance pointer to next row */
	}
}

////////////////////////////////////////////////////////////////////////////////

//	Below are difficult and complex HUFFMAN decoding !!!!!


////////////////////////////////////////////////////////////////////////////////
//	HuffmanDecode( coef, i ); //source is m_pData; coef is result

void CTonyJpegDecoder::HuffmanDecode( 
		short* coef,//	out, DCT coefficients
		int iBlock	//	0,1,2,3:Y; 4:Cb; 5:Cr; or 0:Y;1:Cb;2:Cr
		)
{	
	int* pLastDC;
	int s, k, r;

	HUFFTABLE *dctbl, *actbl;

	if( iBlock < m_nBlocksInMcu - 2 )
	{
		dctbl = &m_htblYDC;
		actbl = &m_htblYAC;
		pLastDC = &m_dcY;
	}
	else
	{
		dctbl = &m_htblCbCrDC;
		actbl = &m_htblCbCrAC;
		if( iBlock == m_nBlocksInMcu - 2 )
			pLastDC = &m_dcCb;
		else
			pLastDC = &m_dcCr;
	}

	memset( coef, 0, sizeof(short) * 64 );
	
    /* Section F.2.2.1: decode the DC coefficient difference */
	s = GetCategory( dctbl );		//get dc category number, s

	if (s) {
		r = GetBits(s);					//get offset in this dc category
		s = ValueFromCategory(s, r);	//get dc difference value
    }
	
    /* Convert DC difference to actual value, update last_dc_val */
    s += *pLastDC;
    *pLastDC = s;

    /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
    coef[0] = (short) s;	
    
	/* Section F.2.2.2: decode the AC coefficients */
	/* Since zeroes are skipped, output area must be cleared beforehand */
	for (k = 1; k < 64; k++) 
	{
		s = GetCategory( actbl );	//s: (run, category)
		r = s >> 4;			//	r: run length for ac zero, 0 <= r < 16
		s &= 15;			//	s: category for this non-zero ac
		
		if( s ) 
		{
			k += r;					//	k: position for next non-zero ac
			r = GetBits(s);			//	r: offset in this ac category
			s = ValueFromCategory(s, r);	//	s: ac value

			coef[ jpeg_natural_order[ k ] ] = (short) s;
		} 
		else // s = 0, means ac value is 0 ? Only if r = 15.  
		{
			if (r != 15)	//means all the left ac are zero
				break;
			k += 15;
		}
	}		
}



////////////////////////////////////////////////////////////////////////////////
//get category number for dc, or (0 run length, ac category) for ac

//	The max length for Huffman codes is 15 bits; so we use 32 bits buffer	
//	m_nGetBuff, with the validated length is m_nGetBits.
//	Usually, more than 95% of the Huffman codes will be 8 or fewer bits long
//	To speed up, we should pay more attention on the codes whose length <= 8

inline int CTonyJpegDecoder::GetCategory( HUFFTABLE* htbl )
{
	//	If left bits < 8, we should get more data
	if( m_nGetBits < 8 )
		FillBitBuffer( );

	//	Call special process if data finished; min bits is 1
	if( m_nGetBits < 8 )
		return SpecialDecode( htbl, 1 );

	//	Peek the first valid byte	
	int look = ((m_nGetBuff>>(m_nGetBits - 8))& 0xFF);
	int nb = htbl->look_nbits[look];

	if( nb ) 
	{ 
		m_nGetBits -= nb;
		return htbl->look_sym[look]; 
	} 
	else	//Decode long codes with length >= 9
		return SpecialDecode( htbl, 9 );
}

////////////////////////////////////////////////////////////////////////////////

void CTonyJpegDecoder::FillBitBuffer( void )
{
	unsigned char uc;
	while( m_nGetBits < 25 )	//#define MIN_GET_BITS  (32-7)
	{
		if( m_nDataBytesLeft > 0 )//Are there some data?
		{ 
			/* Attempt to read a byte */
			if (unread_marker != 0)
				goto no_more_data;	/* can't advance past a marker */

			uc = *m_pData++;
			m_nDataBytesLeft --;			
			
			// If it's 0xFF, check and discard stuffed zero byte
			if (uc == 0xFF) 
			{
				do 
				{
					uc = *m_pData++;
					m_nDataBytesLeft --;
				}while (uc == 0xFF);
				
				if (uc == 0) 
				{
					// Found FF/00, which represents an FF data byte
					uc = 0xFF;
				} 
				else 
				{
					// Oops, it's actually a marker indicating end of compressed data.
					// Better put it back for use later 
					
					unread_marker = uc;

no_more_data:					
					// There should be enough bits still left in the data segment;
					// if so, just break out of the outer while loop.
					//if (m_nGetBits >= nbits)
					if (m_nGetBits >= 0)
						break;
				}
			}

			m_nGetBuff = (m_nGetBuff << 8) | ((int) uc);
			m_nGetBits += 8;			
		}
		else
			break;
	}
}

////////////////////////////////////////////////////////////////////////////////

inline int CTonyJpegDecoder::GetBits(int nbits) 
{
	if( m_nGetBits < nbits )//we should read nbits bits to get next data
		FillBitBuffer();
	m_nGetBits -= nbits;
	return (int) (m_nGetBuff >> m_nGetBits) & ((1<<nbits)-1);
}

////////////////////////////////////////////////////////////////////////////////
//	Special Huffman decode:
//	(1) For codes with length > 8
//	(2) For codes with length < 8 while data is finished

int CTonyJpegDecoder::SpecialDecode( HUFFTABLE* htbl, int nMinBits )
{
	
	int l = nMinBits;
	int code;
	
	/* HUFF_DECODE has determined that the code is at least min_bits */
	/* bits long, so fetch that many bits in one swoop. */

	code = GetBits(l);
	
	/* Collect the rest of the Huffman code one bit at a time. */
	/* This is per Figure F.16 in the JPEG spec. */
	while (code > htbl->maxcode[l]) {
		code <<= 1;
		code |= GetBits(1);
		l++;
	}
	
	/* With garbage input we may reach the sentinel value l = 17. */
	if (l > 16) {
		return 0;			/* fake a zero as the safest result */
	}
	
	return htbl->huffval[ htbl->valptr[l] +	(int)(code - htbl->mincode[l]) ];
}

////////////////////////////////////////////////////////////////////////////////
//	To find dc or ac value according to category and category offset

inline int CTonyJpegDecoder::ValueFromCategory(int nCate, int nOffset)
{
/*	//Method 1: 
	//On some machines, a shift and add will be faster than a table lookup.
	#define HUFF_EXTEND(x,s) \
	((x)< (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) 
*/
	//Method 2: Table lookup
	
	//If (nOffset < half[nCate]), then value is below zero
	//Otherwise, value is above zero, and just the nOffset
	static const int half[16] =		/* entry n is 2**(n-1) */
	{ 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
    0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
	
	//start[i] is the starting value in this category; surely it is below zero
	static const int start[16] =	/* entry n is (-1 << n) + 1 */
	{ 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
    ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
    ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
    ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };	

	return ( nOffset < half[nCate] ? nOffset + start[nCate] : nOffset);	
}

////////////////////////////////////////////////////////////////////////////////
// end //

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -