?? jchuff.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 + -