]> granicus.if.org Git - libjpeg-turbo/commitdiff
Eliminate backward incompatibility that required empty_output_buffer() to handle...
authorDRC <dcommander@users.sourceforge.net>
Mon, 16 Mar 2009 23:58:30 +0000 (23:58 +0000)
committerDRC <dcommander@users.sourceforge.net>
Mon, 16 Mar 2009 23:58:30 +0000 (23:58 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@32 632fc199-4ca6-4c93-a231-07263d6284db

1  2 
jchuff.c

diff --cc jchuff.c
index 23b29b8bf3e40e832e47732af1325f3f324d986e,f235250548671f2d52cabd12ce366a07db4cbf34..13afab228eec0f80784c75ccab29852c3219e897
+++ b/jchuff.c
  #include "jchuff.h"           /* Declarations shared with jcphuff.c */
  
  
 +static unsigned char jpeg_first_bit_table[65536];
 +int jpeg_first_bit_table_init=0;
 +
 +#define CALC_FIRST_BIT(nbits, t)                       \
 +  nbits = jpeg_first_bit_table[t&255];                 \
 +  if (t > 255) nbits = jpeg_first_bit_table[t>>8] + 8;
 +
++#ifndef min
++ #define min(a,b) ((a)<(b)?(a):(b))
++#endif
++
  /* Expanded entropy encoder object for Huffman encoding.
   *
   * The savable_state subrecord contains fields that change within an MCU,
@@@ -330,74 -297,52 +334,101 @@@ dump_buffer (working_state * state
   * between calls, so 24 bits are sufficient.
   */
  
 -INLINE
 +/***************************************************************/
 +
 +#define DUMP_BITS_(code, size) {                                \
 +  put_bits += size;                                             \
 +  put_buffer = (put_buffer << size) | code;                     \
 +  if (put_bits > 7)                                             \
 +    while(put_bits > 7)                                         \
 +      if (0xFF == (*buffer++ =  put_buffer >> (put_bits -= 8))) \
 +        *buffer++ = 0;                                          \
 + }
 +
 +/***************************************************************/
 +
 +#define DUMP_BITS(code, size) {                                 \
 +  put_bits += size;                                             \
 +  put_buffer = (put_buffer << size) | code;                     \
 +  if (put_bits > 15) {                                          \
 +    if (0xFF == (*buffer++ =  put_buffer >> (put_bits -= 8)))   \
 +      *buffer++ = 0;                                            \
 +    if (0xFF == (*buffer++ =  put_buffer >> (put_bits -= 8)))   \
 +      *buffer++ = 0;                                            \
 +  }                                                             \
 + }
 +
 +/***************************************************************/
 +
 +#define DUMP_SINGLE_VALUE(ht, codevalue) { \
 +  size = ht->ehufsi[codevalue];            \
 +  code = ht->ehufco[codevalue];            \
 +                                           \
 +  DUMP_BITS(code, size)                    \
 + }
 +
 +/***************************************************************/
 +
 +#define DUMP_VALUE(ht, codevalue, t, nbits) { \
 +  size = ht->ehufsi[codevalue];               \
 +  code = ht->ehufco[codevalue];               \
 +  t &= ~(-1 << nbits);                        \
 +  DUMP_BITS(code, size)                       \
 +  DUMP_BITS(t, nbits)                         \
 + }
 +
 +/***************************************************************/
 +
++#define BUFSIZE (DCTSIZE2 * 2)
++
++#define LOAD_BUFFER() {                                           \
++  if (state->free_in_buffer < BUFSIZE) {                          \
++    localbuf = 1;                                                 \
++    buffer = _buffer;                                             \
++  }                                                               \
++  else buffer = state->next_output_byte;                          \
++ }
++
++#define STORE_BUFFER() {                                          \
++  if (localbuf) {                                                 \
++    bytes = buffer - _buffer;                                     \
++    buffer = _buffer;                                             \
++    while (bytes > 0) {                                           \
++      bytestocopy = min(bytes, state->free_in_buffer);            \
++      MEMCOPY(state->next_output_byte, buffer, bytestocopy);      \
++      state->next_output_byte += bytestocopy;                     \
++      buffer += bytestocopy;                                      \
++      state->free_in_buffer -= bytestocopy;                       \
++      if (state->free_in_buffer == 0)                             \
++        if (! dump_buffer(state)) return FALSE;                   \
++      bytes -= bytestocopy;                                       \
++    }                                                             \
++  }                                                               \
++  else {                                                          \
++    state->free_in_buffer -= (buffer - state->next_output_byte);  \
++    state->next_output_byte = buffer;                             \
++  }                                                               \
++ }
++
++/***************************************************************/
 +
  LOCAL(boolean)
 -emit_bits (working_state * state, unsigned int code, int size)
 -/* Emit some bits; return TRUE if successful, FALSE if must suspend */
 +flush_bits (working_state * state)
  {
-   unsigned char *buffer;
 -  /* This routine is heavily used, so it's worth coding tightly. */
 -  register INT32 put_buffer = (INT32) code;
 -  register int put_bits = state->cur.put_bits;
 -
 -  /* if size is 0, caller used an invalid Huffman table entry */
 -  if (size == 0)
 -    ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE);
 -
 -  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 |= state->cur.put_buffer; /* and merge with old buffer contents */
 -  
 -  while (put_bits >= 8) {
 -    int c = (int) ((put_buffer >> 16) & 0xFF);
 -    
 -    emit_byte(state, c, return FALSE);
 -    if (c == 0xFF) {          /* need to stuff a zero byte? */
 -      emit_byte(state, 0, return FALSE);
 -    }
 -    put_buffer <<= 8;
 -    put_bits -= 8;
 -  }
 -
 -  state->cur.put_buffer = put_buffer; /* update state variables */
 -  state->cur.put_bits = put_bits;
++  unsigned char _buffer[BUFSIZE], *buffer;
 +  int put_buffer, put_bits;
++  int bytes, bytestocopy, localbuf = 0;
  
-   if ((state)->free_in_buffer < 1)
-     if (! dump_buffer(state)) return FALSE;
-   if ((state)->free_in_buffer < 1)
-     ERREXIT(state->cinfo, JERR_BUFFER_SIZE);
-   buffer = state->next_output_byte;
 -  return TRUE;
 -}
 +  put_buffer = state->cur.put_buffer;
 +  put_bits = state->cur.put_bits;
++  LOAD_BUFFER()
  
 +  DUMP_BITS_(0x7F, 7)
  
 -LOCAL(boolean)
 -flush_bits (working_state * state)
 -{
 -  if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */
 -    return FALSE;
    state->cur.put_buffer = 0;  /* and reset bit-buffer to empty */
    state->cur.put_bits = 0;
-   state->free_in_buffer -= (buffer - state->next_output_byte);
-   state->next_output_byte = buffer;
++  STORE_BUFFER()
 +
    return TRUE;
  }
  
@@@ -407,22 -353,10 +438,18 @@@ LOCAL(boolean
  encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
                  c_derived_tbl *dctbl, c_derived_tbl *actbl)
  {
 -  register int temp, temp2;
 -  register int nbits;
 -  register int k, r, i;
 -  
 +  int temp, temp2;
 +  int nbits;
 +  int r, sflag, size, code;
-   unsigned char *buffer;
++  unsigned char _buffer[BUFSIZE], *buffer;
 +  int put_buffer, put_bits;
 +  int code_0xf0 = actbl->ehufco[0xf0], size_0xf0 = actbl->ehufsi[0xf0];
++  int bytes, bytestocopy, localbuf = 0;
 +
-   if ((state)->free_in_buffer < DCTSIZE2 * 2)
-     if (! dump_buffer(state)) return FALSE;
-   if ((state)->free_in_buffer < DCTSIZE2 * 2)
-     ERREXIT(state->cinfo, JERR_BUFFER_SIZE);
-   buffer = state->next_output_byte;
 +  put_buffer = state->cur.put_buffer;
 +  put_bits = state->cur.put_bits;
++  LOAD_BUFFER()
 +
    /* Encode the DC coefficient difference per section F.1.2.1 */
    
    temp = temp2 = block[0] - last_dc_val;
    /* 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[jpeg_natural_order[k]]) == 0) {
 -      r++;
 -    } else {
 -      /* if run length > 15, must emit special run-length-16 codes (0xF0) */
 -      while (r > 15) {
 -      if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0]))
 -        return FALSE;
 -      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 */
 -      if (nbits > MAX_COEF_BITS)
 -      ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
 -      
 -      /* Emit Huffman symbol for run length / number of bits */
 -      i = (r << 4) + nbits;
 -      if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i]))
 -      return FALSE;
 -
 -      /* Emit that number of bits of the value, if positive, */
 -      /* or the complement of its magnitude, if negative. */
 -      if (! emit_bits(state, (unsigned int) temp2, nbits))
 -      return FALSE;
 -      
 -      r = 0;
 -    }
 -  }
 +
 +#define innerloop(order) {  \
 +  temp2  = *(JCOEF*)((unsigned char*)block + order);  \
 +  if(temp2 == 0) r++;  \
 +  else {  \
 +    temp = (JCOEF)temp2;  \
 +    sflag = temp >> 31;  \
 +    temp = (temp ^ sflag) - sflag;  \
 +    temp2 += sflag;  \
 +    nbits = jpeg_first_bit_table[temp];  \
 +    for(; r > 15; r -= 16) DUMP_BITS(code_0xf0, size_0xf0)  \
 +    sflag = (r << 4) + nbits;  \
 +    DUMP_VALUE(actbl, sflag, temp2, nbits)  \
 +    r = 0;  \
 +  }}
 +
 +  innerloop(2*1);   innerloop(2*8);   innerloop(2*16);  innerloop(2*9);
 +  innerloop(2*2);   innerloop(2*3);   innerloop(2*10);  innerloop(2*17);
 +  innerloop(2*24);  innerloop(2*32);  innerloop(2*25);  innerloop(2*18);
 +  innerloop(2*11);  innerloop(2*4);   innerloop(2*5);   innerloop(2*12);
 +  innerloop(2*19);  innerloop(2*26);  innerloop(2*33);  innerloop(2*40);
 +  innerloop(2*48);  innerloop(2*41);  innerloop(2*34);  innerloop(2*27);
 +  innerloop(2*20);  innerloop(2*13);  innerloop(2*6);   innerloop(2*7);
 +  innerloop(2*14);  innerloop(2*21);  innerloop(2*28);  innerloop(2*35);
 +  innerloop(2*42);  innerloop(2*49);  innerloop(2*56);  innerloop(2*57);
 +  innerloop(2*50);  innerloop(2*43);  innerloop(2*36);  innerloop(2*29);
 +  innerloop(2*22);  innerloop(2*15);  innerloop(2*23);  innerloop(2*30);
 +  innerloop(2*37);  innerloop(2*44);  innerloop(2*51);  innerloop(2*58);
 +  innerloop(2*59);  innerloop(2*52);  innerloop(2*45);  innerloop(2*38);
 +  innerloop(2*31);  innerloop(2*39);  innerloop(2*46);  innerloop(2*53);
 +  innerloop(2*60);  innerloop(2*61);  innerloop(2*54);  innerloop(2*47);
 +  innerloop(2*55);  innerloop(2*62);  innerloop(2*63);
  
    /* If the last coef(s) were zero, emit an end-of-block code */
 -  if (r > 0)
 -    if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0]))
 -      return FALSE;
 +  if (r > 0) DUMP_SINGLE_VALUE(actbl, 0x0)
 +
 +  state->cur.put_buffer = put_buffer;
 +  state->cur.put_bits = put_bits;
-   state->free_in_buffer -= (buffer - state->next_output_byte);
-   state->next_output_byte = buffer;
++  STORE_BUFFER()
  
    return TRUE;
  }