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

📄 minijpegdec.cpp

📁 About JPEG, executable on Visual C++
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
	0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
	0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
	0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
	0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
	0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
	0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
	0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
	0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
	0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
	0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
	0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
	0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
	0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
	0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
	0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
	0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
	0xf9, 0xfa };

	//	Compute four derived Huffman tables

	ComputeHuffmanTable( bitsYDC, valYDC, &m_htblYDC );

	ComputeHuffmanTable( bitsYAC, valYAC, &m_htblYAC );

	ComputeHuffmanTable( bitsCbCrDC, valCbCrDC, &m_htblCbCrDC );

	ComputeHuffmanTable( bitsCbCrAC, valCbCrAC, &m_htblCbCrAC );
}

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

//	Compute the derived values for a Huffman table.	

void CMiniJpegDecoder::ComputeHuffmanTable(
		unsigned char *	pBits, 
		unsigned char * pVal,
		HUFFTABLE * dtbl	
		)
{
	int p, i, l, si;
	int lookbits, ctr;
	char huffsize[257];
	unsigned int huffcode[257];
	unsigned int code;

	memcpy( dtbl->bits, pBits, 17 );
	memcpy( dtbl->huffval, pVal, 256 );
	
	/* Figure C.1: make table of Huffman code length for each symbol */
	/* Note that this is in code-length order. */
	p = 0;
	for (l = 1; l <= 16; l++) {
		for (i = 1; i <= (int) pBits[l]; i++)
			huffsize[p++] = (char) l;
	}
	huffsize[p] = 0;
	
	/* Figure C.2: generate the codes themselves */
	/* Note that this is in code-length order. */
	
	code = 0;
	si = huffsize[0];
	p = 0;
	while (huffsize[p]) {
		while (((int) huffsize[p]) == si) {
			huffcode[p++] = code;
			code++;
		}
		code <<= 1;
		si++;
	}
	
	/* Figure F.15: generate decoding tables for bit-sequential decoding */
	
	p = 0;
	for (l = 1; l <= 16; l++) {
		if (pBits[l]) {
			dtbl->valptr[l] = p; /* huffval[] index of 1st symbol of code length l */
			dtbl->mincode[l] = huffcode[p]; /* minimum code of length l */
			p += pBits[l];
			dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
		} else {
			dtbl->maxcode[l] = -1;	/* -1 if no codes of this length */
		}
	}
	dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */
	
	/* Compute lookahead tables to speed up decoding.
	 * First we set all the table entries to 0, indicating "too long";
	 * then we iterate through the Huffman codes that are short enough and
	 * fill in all the entries that correspond to bit sequences starting
	 * with that code.	 */
	
	memset( dtbl->look_nbits, 0, sizeof(int)*256 );
	
	int HUFF_LOOKAHEAD = 8;
	p = 0;
	for (l = 1; l <= HUFF_LOOKAHEAD; l++) 
	{
		for (i = 1; i <= (int) pBits[l]; i++, p++) 
		{
			/* l = current code's length, 
			p = its index in huffcode[] & huffval[]. Generate left-justified
			code followed by all possible bit sequences */
			lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
			for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) 
			{
				dtbl->look_nbits[lookbits] = l;
				dtbl->look_sym[lookbits] = pVal[p];
				lookbits++;
			}
		}
	}
}


////////////////////////////////////////////////////////////////////////////////
//	CMiniJpegDecoder::DecompressImage(), the main function in this class !!
//	IMPORTANT: You should call GetImageInfo() to get image width and height,
//				Then allocate (m_nWidth * m_nHeight * 3) bytes for pOutBuf

bool CMiniJpegDecoder::DecompressImage(	
	unsigned char *pInBuf,	//in, source data, in jpg format
	unsigned char *pOutBuf	//out, bgr format, (m_nWidth * m_nHeight * 3) bytes
	)
{
	//	Error handling
	if(( pInBuf == 0 )||( pOutBuf == 0 ))
		return false;

	//	declares
	int xPixel, yPixel, xTile, yTile, cxTile, cyTile, cxBlock, cyBlock;
	int y, nTrueRows, nTrueCols, nRowBytes;
	unsigned char byTile[768], *pTileRow;
		
	//	horizontal and vertical count of tile, macroblocks, 
	//	or MCU(Minimum Coded Unit), in 16*16 pixels
	cxTile = (m_nWidth + 15) >> 4;	
	cyTile = (m_nHeight + 15) >> 4;

	//	horizontal and vertical count of block, in 8*8 pixels
	cxBlock = cxTile << 1;
	cyBlock = cyTile << 1;

	//	BMP row width, must be divided by 4
	nRowBytes = (m_nWidth * 3 + 3) / 4 * 4;

	m_pData = pInBuf;
	
	//	Decompress all the tiles, or macroblocks, or MCUs
	for( yTile = 0; yTile < cyTile; yTile++ )
	{
		for( xTile = 0; xTile < cxTile; xTile++ )
		{
			//	Decompress one macroblock started from m_pData;
			//	This function will push m_pData ahead
			//	Result is storing in byTile
			if( ! DecompressOneTile( byTile ))
				return false;

			//	Get tile starting pixel position
			xPixel = xTile << 4;
			yPixel = yTile << 4;

			//	Get the true number of tile columns and rows
			nTrueRows = 16;
			nTrueCols = 16;			
			if( yPixel + nTrueRows > m_nHeight )
				nTrueRows = m_nHeight - yPixel;
			if( xPixel + nTrueCols > m_nWidth )
				nTrueCols = m_nWidth - xPixel;

			//	Write the output bgr data
			pTileRow = pOutBuf + yPixel * nRowBytes + xPixel * 3;
			for( y = 0; y < nTrueRows; y ++ )
			{
				memcpy( pTileRow, byTile + y * 48, nTrueCols * 3 );
				pTileRow += nRowBytes;			
			}		
		}
	}	
	return true;
}

////////////////////////////////////////////////////////////////////////////////
//	function Purpose:	decompress one 16*16 pixels
//	source is m_pData;
//	This function will push m_pData ahead for next tile

bool CMiniJpegDecoder::DecompressOneTile(	
	unsigned char * pBgr	//out, in BGR format, 16*16*3
	)
{
	unsigned char pYCbCr[384];//Three color components, 256 + 64 + 64 bytes 
	short coef[64];	
	
	//	Do Y/Cb/Cr components, Y: 4 blocks; Cb: 1 block; Cr: 1 block
	for( int i=0; i<6; 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 );
	return true;
}


////////////////////////////////////////////////////////////////////////////////
//	Color conversion and up-sampling

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

	pByte = pBgr;
	for( i = 0; i < 4; i++ )
		py[i] = pYCbCr + i * 64;
	pcb	  = pYCbCr + 256;
	pcr   = pYCbCr + 320;
	unsigned char * range_limit = m_tblRange + 256;
	
	for( j=0; j<16; j++ )//vertical axis
	{
		for( i=0; i<16; i++ )	//horizontal axis
		{			
			//	block number is ((j/8) * 2 + i/8): {0, 1, 2, 3}
			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 CMiniJpegDecoder::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;

⌨️ 快捷键说明

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