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

📄 jcphuff.c

📁 GIS系统支持库Geospatial Data Abstraction Library代码.GDAL is a translator library for raster geospatial dat
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * jcphuff.c * * Copyright (C) 1995-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 for progressive JPEG. * * We do not support output suspension in this module, since the library * currently does not allow multiple-scan files to be written with output * suspension. */#define JPEG_INTERNALS#include "jinclude.h"#include "jpeglib.h"#include "jchuff.h"		/* Declarations shared with jchuff.c */#ifdef C_PROGRESSIVE_SUPPORTED/* Expanded entropy encoder object for progressive Huffman encoding. */typedef struct {  struct jpeg_entropy_encoder pub; /* public fields */  /* Mode flag: TRUE for optimization, FALSE for actual data output */  boolean gather_statistics;  /* Bit-level coding status.   * next_output_byte/free_in_buffer are local copies of cinfo->dest fields.   */  JOCTET * next_output_byte;	/* => next byte to write in buffer */  size_t free_in_buffer;	/* # of byte spaces remaining in buffer */  INT32 put_buffer;		/* current bit-accumulation buffer */  int put_bits;			/* # of bits now in it */  j_compress_ptr cinfo;		/* link to cinfo (needed for dump_buffer) */  /* Coding status for DC components */  int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */  /* Coding status for AC components */  int ac_tbl_no;		/* the table number of the single component */  unsigned int EOBRUN;		/* run length of EOBs */  unsigned int BE;		/* # of buffered correction bits before MCU */  char * bit_buffer;		/* buffer for correction bits (1 per char) */  /* packing correction bits tightly would save some space but cost time... */  unsigned int restarts_to_go;	/* MCUs left in this restart interval */  int next_restart_num;		/* next restart number to write (0-7) */  /* Pointers to derived tables (these workspaces have image lifespan).   * Since any one scan codes only DC or only AC, we only need one set   * of tables, not one for DC and one for AC.   */  c_derived_tbl * derived_tbls[NUM_HUFF_TBLS];  /* Statistics tables for optimization; again, one set is enough */  long * count_ptrs[NUM_HUFF_TBLS];} phuff_entropy_encoder;typedef phuff_entropy_encoder * phuff_entropy_ptr;/* MAX_CORR_BITS is the number of bits the AC refinement correction-bit * buffer can hold.  Larger sizes may slightly improve compression, but * 1000 is already well into the realm of overkill. * The minimum safe size is 64 bits. */#define MAX_CORR_BITS  1000	/* Max # of correction bits I can buffer *//* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32. * We assume that int right shift is unsigned if INT32 right shift is, * which should be safe. */#ifdef RIGHT_SHIFT_IS_UNSIGNED#define ISHIFT_TEMPS	int ishift_temp;#define IRIGHT_SHIFT(x,shft)  \	((ishift_temp = (x)) < 0 ? \	 (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \	 (ishift_temp >> (shft)))#else#define ISHIFT_TEMPS#define IRIGHT_SHIFT(x,shft)	((x) >> (shft))#endif/* Forward declarations */METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo,					    JBLOCKROW *MCU_data));METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo,					    JBLOCKROW *MCU_data));METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo,					     JBLOCKROW *MCU_data));METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo,					     JBLOCKROW *MCU_data));METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo));METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo));/* * Initialize for a Huffman-compressed scan using progressive JPEG. */METHODDEF(void)start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics){    phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;  boolean is_DC_band;  int ci, tbl;  jpeg_component_info * compptr;  entropy->cinfo = cinfo;  entropy->gather_statistics = gather_statistics;  is_DC_band = (cinfo->Ss == 0);  /* We assume jcmaster.c already validated the scan parameters. */  /* Select execution routines */  if (cinfo->Ah == 0) {    if (is_DC_band)      entropy->pub.encode_mcu = encode_mcu_DC_first;    else      entropy->pub.encode_mcu = encode_mcu_AC_first;  } else {    if (is_DC_band)      entropy->pub.encode_mcu = encode_mcu_DC_refine;    else {      entropy->pub.encode_mcu = encode_mcu_AC_refine;      /* AC refinement needs a correction bit buffer */      if (entropy->bit_buffer == NULL)	entropy->bit_buffer = (char *)	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,				      MAX_CORR_BITS * SIZEOF(char));    }  }  if (gather_statistics)    entropy->pub.finish_pass = finish_pass_gather_phuff;  else    entropy->pub.finish_pass = finish_pass_phuff;  /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1   * for AC coefficients.   */  for (ci = 0; ci < cinfo->comps_in_scan; ci++) {    compptr = cinfo->cur_comp_info[ci];    /* Initialize DC predictions to 0 */    entropy->last_dc_val[ci] = 0;    /* Get table index */    if (is_DC_band) {      if (cinfo->Ah != 0)	/* DC refinement needs no table */	continue;      tbl = compptr->dc_tbl_no;    } else {      entropy->ac_tbl_no = tbl = compptr->ac_tbl_no;    }    if (gather_statistics) {      /* Check for invalid table index */      /* (make_c_derived_tbl does this in the other path) */      if (tbl < 0 || tbl >= NUM_HUFF_TBLS)        ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);      /* Allocate and zero the statistics tables */      /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */      if (entropy->count_ptrs[tbl] == NULL)	entropy->count_ptrs[tbl] = (long *)	  (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,				      257 * SIZEOF(long));      MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));    } else {      /* Compute derived values for Huffman table */      /* We may do this more than once for a table, but it's not expensive */      jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl,			      & entropy->derived_tbls[tbl]);    }  }  /* Initialize AC stuff */  entropy->EOBRUN = 0;  entropy->BE = 0;  /* Initialize bit buffer to empty */  entropy->put_buffer = 0;  entropy->put_bits = 0;  /* Initialize restart stuff */  entropy->restarts_to_go = cinfo->restart_interval;  entropy->next_restart_num = 0;}/* Outputting bytes to the file. * NB: these must be called only when actually outputting, * that is, entropy->gather_statistics == FALSE. *//* Emit a byte */#define emit_byte(entropy,val)  \	{ *(entropy)->next_output_byte++ = (JOCTET) (val);  \	  if (--(entropy)->free_in_buffer == 0)  \	    dump_buffer(entropy); }LOCAL(void)dump_buffer (phuff_entropy_ptr entropy)/* Empty the output buffer; we do not support suspension in this module. */{  struct jpeg_destination_mgr * dest = entropy->cinfo->dest;  if (! (*dest->empty_output_buffer) (entropy->cinfo))    ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND);  /* After a successful buffer dump, must reset buffer pointers */  entropy->next_output_byte = dest->next_output_byte;  entropy->free_in_buffer = dest->free_in_buffer;}/* 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 emit_bits * in one call, and we never retain more than 7 bits in put_buffer * between calls, so 24 bits are sufficient. */INLINELOCAL(void)emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)/* Emit some bits, unless we are in gather mode */{  /* This routine is heavily used, so it's worth coding tightly. */  register INT32 put_buffer = (INT32) code;  register int put_bits = entropy->put_bits;  /* if size is 0, caller used an invalid Huffman table entry */  if (size == 0)    ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);  if (entropy->gather_statistics)    return;			/* do nothing if we're only getting stats */  put_buffer &= (((INT32) 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 |= entropy->put_buffer; /* and merge with old buffer contents */  while (put_bits >= 8) {    int c = (int) ((put_buffer >> 16) & 0xFF);        emit_byte(entropy, c);    if (c == 0xFF) {		/* need to stuff a zero byte? */      emit_byte(entropy, 0);    }    put_buffer <<= 8;    put_bits -= 8;  }  entropy->put_buffer = put_buffer; /* update variables */  entropy->put_bits = put_bits;}LOCAL(void)flush_bits (phuff_entropy_ptr entropy){  emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */  entropy->put_buffer = 0;     /* and reset bit-buffer to empty */  entropy->put_bits = 0;}/* * Emit (or just count) a Huffman symbol. */INLINELOCAL(void)emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol){  if (entropy->gather_statistics)    entropy->count_ptrs[tbl_no][symbol]++;  else {    c_derived_tbl * tbl = entropy->derived_tbls[tbl_no];    emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);  }}/* * Emit bits from a correction bit buffer. */LOCAL(void)emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart,		    unsigned int nbits){  if (entropy->gather_statistics)    return;			/* no real work */  while (nbits > 0) {    emit_bits(entropy, (unsigned int) (*bufstart), 1);    bufstart++;    nbits--;  }}/* * Emit any pending EOBRUN symbol. */LOCAL(void)emit_eobrun (phuff_entropy_ptr entropy){  register int temp, nbits;  if (entropy->EOBRUN > 0) {	/* if there is any pending EOBRUN */    temp = entropy->EOBRUN;    nbits = 0;    while ((temp >>= 1))      nbits++;    /* safety check: shouldn't happen given limited correction-bit buffer */    if (nbits > 14)      ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);    emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4);    if (nbits)      emit_bits(entropy, entropy->EOBRUN, nbits);    entropy->EOBRUN = 0;    /* Emit any buffered correction bits */    emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE);    entropy->BE = 0;  }}/* * Emit a restart marker & resynchronize predictions. */LOCAL(void)emit_restart (phuff_entropy_ptr entropy, int restart_num){  int ci;  emit_eobrun(entropy);  if (! entropy->gather_statistics) {    flush_bits(entropy);    emit_byte(entropy, 0xFF);    emit_byte(entropy, JPEG_RST0 + restart_num);  }  if (entropy->cinfo->Ss == 0) {    /* Re-initialize DC predictions to 0 */    for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++)      entropy->last_dc_val[ci] = 0;  } else {    /* Re-initialize all AC-related fields to 0 */    entropy->EOBRUN = 0;    entropy->BE = 0;  }}/* * MCU encoding for DC initial scan (either spectral selection, * or first pass of successive approximation). */METHODDEF(boolean)encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data){  phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;  register int temp, temp2;  register int nbits;  int blkn, ci;  int Al = cinfo->Al;  JBLOCKROW block;  jpeg_component_info * compptr;  ISHIFT_TEMPS  entropy->next_output_byte = cinfo->dest->next_output_byte;  entropy->free_in_buffer = cinfo->dest->free_in_buffer;  /* Emit restart marker if needed */  if (cinfo->restart_interval)    if (entropy->restarts_to_go == 0)      emit_restart(entropy, entropy->next_restart_num);  /* Encode the MCU data blocks */  for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {    block = MCU_data[blkn];    ci = cinfo->MCU_membership[blkn];    compptr = cinfo->cur_comp_info[ci];    /* Compute the DC value after the required point transform by Al.     * This is simply an arithmetic right shift.     */    temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al);    /* DC differences are figured on the point-transformed values. */    temp = temp2 - entropy->last_dc_val[ci];    entropy->last_dc_val[ci] = temp2;    /* Encode the DC coefficient difference per section G.1.2.1 */    temp2 = temp;    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--;

⌨️ 快捷键说明

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