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

📄 minijpegenc.cpp

📁 About JPEG, executable on Visual C++
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		z3 = MULTIPLY(tmp11, FIX_0_707106781);			/* c4 */
		
		z11 = tmp7 + z3;		/* phase 5 */
		z13 = tmp7 - z3;
		
		coefptr[5] = z13 + z2;	/* phase 6 */
		coefptr[3] = z13 - z2;
		coefptr[1] = z11 + z4;
		coefptr[7] = z11 - z4;
		
		dataptr += 8;		/* advance pointer to next row */
		coefptr += 8;
	}
	
	/* Pass 2: process columns. */	

	coefptr = coef;		//both input and output
	for ( x = 0; x < 8; x++ ) 
	{
		tmp0 = coefptr[DCTSIZE*0] + coefptr[DCTSIZE*7];
		tmp7 = coefptr[DCTSIZE*0] - coefptr[DCTSIZE*7];
		tmp1 = coefptr[DCTSIZE*1] + coefptr[DCTSIZE*6];
		tmp6 = coefptr[DCTSIZE*1] - coefptr[DCTSIZE*6];
		tmp2 = coefptr[DCTSIZE*2] + coefptr[DCTSIZE*5];
		tmp5 = coefptr[DCTSIZE*2] - coefptr[DCTSIZE*5];
		tmp3 = coefptr[DCTSIZE*3] + coefptr[DCTSIZE*4];
		tmp4 = coefptr[DCTSIZE*3] - coefptr[DCTSIZE*4];
		
		/* Even part */
		
		tmp10 = tmp0 + tmp3;	/* phase 2 */
		tmp13 = tmp0 - tmp3;
		tmp11 = tmp1 + tmp2;
		tmp12 = tmp1 - tmp2;
		
		coefptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
		coefptr[DCTSIZE*4] = tmp10 - tmp11;
		
		z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
		coefptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
		coefptr[DCTSIZE*6] = tmp13 - z1;
		
		/* Odd part */
		
		tmp10 = tmp4 + tmp5;	/* phase 2 */
		tmp11 = tmp5 + tmp6;
		tmp12 = tmp6 + tmp7;
		
		/* The rotator is modified from fig 4-8 to avoid extra negations. */
		z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
		z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
		z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
		z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
		
		z11 = tmp7 + z3;		/* phase 5 */
		z13 = tmp7 - z3;
		
		coefptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
		coefptr[DCTSIZE*3] = z13 - z2;
		coefptr[DCTSIZE*1] = z11 + z4;
		coefptr[DCTSIZE*7] = z11 - z4;
		
		coefptr++;			/* advance pointer to next column */
	}
}


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

void CMiniJpegEncoder::Quantize( 
		int* coef,	//coef is both in and out
		int iBlock	//block id; Y: 0,1,2,3; Cb: 4; Cr: 5
		)
{
	int temp;
	unsigned short qval, *pQuant;

	if( iBlock < 4 )
		pQuant = m_qtblY;
	else
		pQuant = m_qtblCbCr;

	for (int i = 0; i < 64; i++) 
	{
		qval = pQuant[i];
		temp = coef[i];
		
		/* Divide the coefficient value by qval, ensuring proper rounding.
		* Since C does not specify the direction of rounding for negative
		* quotients, we have to force the dividend positive for portability.
		*
		* In most files, at least half of the output values will be zero
		* (at default quantization settings, more like three-quarters...)
		* so we should ensure that this case is fast.  On many machines,
		* a comparison is enough cheaper than a divide to make a special test
		* a win.  Since both inputs will be nonnegative, we need only test
		* for a < b to discover whether a/b is 0.
		* If your machine's division is fast enough, define FAST_DIVIDE.
		*/

		// Notes: Actually we use the second expression !!
/*
#ifdef FAST_DIVIDE
#define DIVIDE_BY(a,b)	a /= b
#else
*/
#define DIVIDE_BY(a,b)	if (a >= b) a /= b; else a = 0
//#endif		
		
		if ( temp < 0) 
		{
			temp = -temp;
			temp += qval>>1;	/* for rounding */
			DIVIDE_BY(temp, qval);
			temp = -temp;
		} 
		else 
		{
			temp += qval>>1;	/* for rounding */
			DIVIDE_BY(temp, qval);
		}
		
		coef[i] = temp;		
    }
}



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

bool CMiniJpegEncoder::HuffmanEncode( 
		int* pCoef,				//	DCT coefficients
		unsigned char* pOut,	//	Output byte stream
		int iBlock,				//	0,1,2,3:Y; 4:Cb; 5:Cr;
		int& nBytes				//	Out, Byte number of Output stream
		)
{	
	/*
	* jpeg_natural_order[i] is the natural-order position of the i'th element
	* of zigzag order.
	*
	* When reading corrupted data, the Huffman decoders could attempt
	* to reference an entry beyond the end of this array (if the decoded
	* zero run length reaches past the end of the block).  To prevent
	* wild stores without adding an inner-loop test, we put some extra
	* "63"s after the real entries.  This will cause the extra coefficient
	* to be stored in location 63 of the block, not somewhere random.
	* The worst case would be a run-length of 15, which means we need 16
	* fake entries.
	*/
	static const int jpeg_natural_order[64+16] = {
			 0,  1,  8, 16,  9,  2,  3, 10,
			17, 24, 32, 25, 18, 11,  4,  5,
			12, 19, 26, 33, 40, 48, 41, 34,
			27, 20, 13,  6,  7, 14, 21, 28,
			35, 42, 49, 56, 57, 50, 43, 36,
			29, 22, 15, 23, 30, 37, 44, 51,
			58, 59, 52, 45, 38, 31, 39, 46,
			53, 60, 61, 54, 47, 55, 62, 63,
			63, 63, 63, 63, 63, 63, 63, 63,//extra entries for safety
			63, 63, 63, 63, 63, 63, 63, 63
	};
	
	int temp, temp2, nbits, k, r, i, nWrite;
	int *block = pCoef;
	int *pLastDc = &m_dcY;
	HUFFMAN_TABLE *dctbl, *actbl;

	nBytes = 0;

	if( iBlock < 4 )
	{
		dctbl = & m_htblYDC;
		actbl = & m_htblYAC;
//		pLastDc = &m_dcY;	
	}
	else
	{
		dctbl = & m_htblCbCrDC;
		actbl = & m_htblCbCrAC;

		if( iBlock == 4 )
			pLastDc = &m_dcCb;
		else
			pLastDc = &m_dcCr;
	}
	
	/* Encode the DC coefficient difference per section F.1.2.1 */
	
	temp = temp2 = block[0] - (*pLastDc);
	*pLastDc = block[0];
	
	if (temp < 0) {
		temp = -temp;		/* temp is abs value of input */
		/* For a negative input, want temp2 = bitwise complement of abs(input) */
		/* This code assumes we are on a two's complement machine */
		temp2 --;
	}
	
	/* Find the number of bits needed for the magnitude of the coefficient */
	nbits = 0;
	while (temp) {
		nbits ++;
		temp >>= 1;
	}
	
	//	Write category number
	if (! EmitBits( pOut + nBytes, dctbl->code[nbits], dctbl->size[nbits], nWrite ))
		return FALSE;
	nBytes += nWrite;

	//	Write category offset
	if (nbits)			/* EmitBits rejects calls with size 0 */
	{
		if (! EmitBits( pOut + nBytes, (unsigned int) temp2, nbits, nWrite ))
			return FALSE;
		nBytes += nWrite;
	}
	
	////////////////////////////////////////////////////////////////////////////
	/* Encode the AC coefficients per section F.1.2.2 */
	
	r = 0;			/* r = run length of zeros */
	
	for (k = 1; k < 64; k++) 
	{
		if ((temp = block[jpeg_natural_order[k]]) == 0) 
		{
			r++;
		} 
		else 
		{
			/* if run length > 15, must emit special run-length-16 codes (0xF0) */
			while (r > 15) {
				if (! EmitBits( pOut + nBytes, actbl->code[0xF0], 
								actbl->size[0xF0], nWrite ))
					return FALSE;
				nBytes += nWrite;
				r -= 16;
			}
			
			temp2 = temp;
			if (temp < 0) {
				temp = -temp;		/* temp is abs value of input */
				/* This code assumes we are on a two's complement machine */
				temp2--;
			}
			
			/* Find the number of bits needed for the magnitude of the coefficient */
			nbits = 1;		/* there must be at least one 1 bit */
			while ((temp >>= 1))
				nbits++;
			
			/* Emit Huffman symbol for run length / number of bits */
			i = (r << 4) + nbits;
			if (! EmitBits( pOut + nBytes, actbl->code[i], 
							actbl->size[i], nWrite ))
				return FALSE;
			nBytes += nWrite;
			
			//	Write Category offset
			if (! EmitBits( pOut + nBytes, (unsigned int) temp2, 
							nbits, nWrite ))
				return FALSE;
			nBytes += nWrite;
			
			r = 0;
		}
	}
	
	//If all the left coefs were zero, emit an end-of-block code
	if (r > 0)
	{
		if (! EmitBits( pOut + nBytes, actbl->code[0], 
						actbl->size[0], nWrite ))
			return FALSE;
		nBytes += nWrite;
	}		
	
	return TRUE;
}


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

/* Outputting bits to the file */

/* Only the right 24 bits of put_buffer are used; the valid bits are
 * left-justified in this part.  At most 16 bits can be passed to EmitBits
 * in one call, and we never retain more than 7 bits in put_buffer
 * between calls, so 24 bits are sufficient.
 */

inline bool CMiniJpegEncoder::EmitBits(
		unsigned char* pOut,	//Output byte stream
		unsigned int code,		//Huffman code
		int size,				//Size in bits of the Huffman code
		int& nBytes				//Out, bytes length 
		)
{
	/* This routine is heavily used, so it's worth coding tightly. */
	int put_buffer = (int) code;
	int put_bits = m_nPutBits;
	
	nBytes = 0;
	
	/* if size is 0, caller used an invalid Huffman table entry */
	if (size == 0)
		return false;
	
	put_buffer &= (((int)1)<<size) - 1; /* mask off any extra bits in code */
	
	put_bits += size;					/* new number of bits in buffer */
	
	put_buffer <<= 24 - put_bits;		/* align incoming bits */
	
	put_buffer |= m_nPutVal;			/* and merge with old buffer contents */
	
	//	If there are more than 8 bits, write it out
	while (put_bits >= 8) 
	{
		//	Write one byte out !!!!
		*(pOut++) = (unsigned char) ((put_buffer >> 16) & 0xFF);
		nBytes ++;
/*	
		if (uc == 0xFF) {		//need to stuff a zero byte?
			*(pOut++) = (unsigned char) 0;	//	Write one byte out !!!!
			nBytes ++;
		}
*/
		put_buffer <<= 8;
		put_bits -= 8;
	}
	
	m_nPutVal	= put_buffer; /* update state variables */
	m_nPutBits	= put_bits;
	
	return TRUE;
}

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

inline void CMiniJpegEncoder::EmitLeftBits(
		unsigned char* pOut,	//Output byte stream
		int& nBytes				//Out, bytes length 
		)
{
	
	unsigned char uc = (unsigned char) ((m_nPutVal >> 16) & 0xFF);
	*(pOut++) = uc;			//	Write one byte out !!!!
	nBytes = 1;

	m_nPutVal  = 0;
	m_nPutBits = 0;
}

⌨️ 快捷键说明

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