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

📄 jchuff.c

📁 jpeg压缩C代码,包括库的源代码和一个测试程序的源代码
💻 C
字号:
/*
* jchuff.c
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains Huffman entropy encoding routines.
*
* Much of the complexity here has to do with supporting output suspension.
* If the data destination module demands suspension, we want to be able to
* back up to the start of the current MCU.  To do this, we copy state
* variables into local working storage, and update them back to the
* permanent JPEG objects only upon successful completion of an MCU.
*/

#include "jpeg.h"


#define JPEG_RST0	0xD0	/* RST0 marker code */
//#define JPEG_EOI	0xD9	/* EOI marker code */
//#define JPEG_APP0	0xE0	/* APP0 marker code */
//#define JPEG_COM	0xFE	/* COM marker code */

#define MAX_COEF_BITS 10

/*!
 ************************************************************************
 * \brief
 *    writes UVLC code to the appropriate buffer
 ************************************************************************
 */
__inline void  emit_bits(Bitstream * bs, int code, int len)
{
	BYTE c;
	code &= (1<<len) - 1;
	// Add the new bits to the bitstream.
	bs->cnt += len;
	bs->byte_buf |= code << (32 - bs->cnt);

	// Write out a byte if it is full
	while(bs->cnt >= 8)
	{
		c = (BYTE)(bs->byte_buf >> 24);
		*bs->ptr++ = c;
		if(c == 0xFF)
			*bs->ptr ++ = 0;
		bs->byte_buf <<= 8;
		bs->cnt -= 8;
	}
}

/* Encode a single block's worth of coefficients */
void encode_one_block (Bitstream *bs, short* block, int last_dc_val, 
					   unsigned short* dctbl, unsigned short* actbl)
{
	int temp, temp2;
	int nbits;
	int k, r, i;
	
	/* Encode the DC coefficient difference per section F.1.2.1 */
	temp = temp2 = block[0] - last_dc_val;
	
	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;
	}

	/* Check for out-of-range coefficient values.
	* Since we're encoding a difference, the range limit is twice as much.
	*/
	assert(nbits <= MAX_COEF_BITS+1);
	
	/* Emit the Huffman-coded symbol for the number of bits */
	emit_bits(bs, dctbl[nbits*2], dctbl[nbits*2+1]);
	
	/* Emit that number of bits of the value, if positive, */
	/* or the complement of its magnitude, if negative. */
	if (nbits)			/* emit_bits rejects calls with size 0 */
	{
		emit_bits(bs, (unsigned int) temp2, nbits);
	}
	
	/* Encode the AC coefficients per section F.1.2.2 */
	r = 0;			/* r = run length of zeros */
	for (k = 1; k < DCTSIZE2; k++) 
	{
		if ((temp = block[k]) == 0) 
		{
			r++;
		}
		else
		{
			/* if run length > 15, must emit special run-length-16 codes (0xF0) */
			while (r > 15) 
			{
				emit_bits(bs, actbl[0xF0*2], actbl[0xF0*2+1]);
				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++;
			/* Check for out-of-range coefficient values */
			assert(nbits <= MAX_COEF_BITS);
			
			/* Emit Huffman symbol for run length / number of bits */
			i = (r << 4) + nbits;
			emit_bits(bs, actbl[i*2], actbl[i*2+1]);
			
			/* Emit that number of bits of the value, if positive, */
			/* or the complement of its magnitude, if negative. */
			emit_bits(bs, (unsigned int) temp2, nbits);

			
			r = 0;
		}
	}
	
	/* If the last coef(s) were zero, emit an end-of-block code */
	if (r > 0)
	{
		emit_bits(bs, actbl[0], actbl[1]);
	}
}


/*
* Encode and output one MCU's worth of Huffman-compressed coefficients.
*/
void encode_mcu_huff (j_compress_ptr cinfo, Bitstream *bs, short MCU_data[6][64], int last_dc_val[3])
{
	int blkn, ci;
	
	// Y
	for (blkn = 0; blkn < 4; blkn++)
	{
		encode_one_block(bs, MCU_data[blkn], last_dc_val[0], 
			cinfo->dc_derived_tbls,cinfo->ac_derived_tbls);

		last_dc_val[0] = MCU_data[blkn][0]; // Update last_dc_val
	}

	// UV
	ci = 1;
	for (blkn = 4; blkn < 6; blkn++)
	{
		encode_one_block(bs, MCU_data[blkn], last_dc_val[ci], 
			cinfo->dc_derived_tbls+2*256, cinfo->ac_derived_tbls+2*256);
		
		last_dc_val[ci] = MCU_data[blkn][0];// Update last_dc_val
		ci ++;
	}
}

/*
* Finish up at the end of a Huffman-compressed scan.
*/
void finish_pass_huff (Bitstream *bs)
{
	/* Flush out the last data */
	emit_bits(bs, 0x7F, 7); /* fill any partial byte with ones */

	while(bs->cnt >= 8)
	{
		*bs->ptr++ = (BYTE)(bs->byte_buf >> 24);
		bs->byte_buf <<= 8;
		bs->cnt -= 8;
	}

	// and reset bit-buffer to empty 
	bs->byte_buf = 0;	
	bs->cnt = 0;
}

⌨️ 快捷键说明

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