diff options
author | DRC <dcommander@users.sourceforge.net> | 2009-07-30 08:35:06 +0000 |
---|---|---|
committer | DRC <dcommander@users.sourceforge.net> | 2009-07-30 08:35:06 +0000 |
commit | bac441e5dd3a47a5d5f1c94b0c3b820a44c15647 (patch) | |
tree | ec4fa4e0664418a00a1cebbe0a631cc97b50608f /common/jpeg | |
parent | ee3933ce582d21f6add90ca1d921de38ddf7e87f (diff) | |
download | tigervnc-bac441e5dd3a47a5d5f1c94b0c3b820a44c15647.tar.gz tigervnc-bac441e5dd3a47a5d5f1c94b0c3b820a44c15647.zip |
Improve compression performance by 15-20%
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3868 3789f03b-4d11-0410-bbf8-ca57d06f2519
Diffstat (limited to 'common/jpeg')
-rw-r--r-- | common/jpeg/jchuff.c | 122 |
1 files changed, 101 insertions, 21 deletions
diff --git a/common/jpeg/jchuff.c b/common/jpeg/jchuff.c index 13afab22..e9abb42c 100644 --- a/common/jpeg/jchuff.c +++ b/common/jpeg/jchuff.c @@ -33,15 +33,11 @@ #include "jinclude.h" #include "jpeglib.h" #include "jchuff.h" /* Declarations shared with jcphuff.c */ - +#include <limits.h> 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 @@ -53,7 +49,7 @@ int jpeg_first_bit_table_init=0; */ typedef struct { - INT32 put_buffer; /* current bit-accumulation buffer */ + long put_buffer; /* current bit-accumulation buffer */ int put_bits; /* # of bits now in it */ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ } savable_state; @@ -185,6 +181,7 @@ start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) } /* Initialize bit buffer to empty */ + entropy->saved.put_buffer = 0; entropy->saved.put_bits = 0; @@ -336,28 +333,85 @@ dump_buffer (working_state * state) /***************************************************************/ +#define EMIT_BYTE() { \ + 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 > 7) \ while(put_bits > 7) \ - if (0xFF == (*buffer++ = put_buffer >> (put_bits -= 8))) \ - *buffer++ = 0; \ + EMIT_BYTE() \ } /***************************************************************/ +#define CHECKBUF15() { \ + if (put_bits > 15) { \ + EMIT_BYTE() \ + EMIT_BYTE() \ + } \ +} + +#define CHECKBUF15() { \ + if (put_bits > 15) { \ + EMIT_BYTE() \ + EMIT_BYTE() \ + } \ +} + +#define CHECKBUF47() { \ + if (put_bits > 47) { \ + EMIT_BYTE() \ + EMIT_BYTE() \ + EMIT_BYTE() \ + EMIT_BYTE() \ + EMIT_BYTE() \ + EMIT_BYTE() \ + } \ +} + +#define CHECKBUF55() { \ + if (put_bits > 55) { \ + EMIT_BYTE() \ + EMIT_BYTE() \ + EMIT_BYTE() \ + EMIT_BYTE() \ + EMIT_BYTE() \ + EMIT_BYTE() \ + EMIT_BYTE() \ + } \ +} + +/***************************************************************/ + +#define DUMP_BITS_NOCHECK(code, size) { \ + put_bits += size; \ + put_buffer = (put_buffer << size) | code; \ + } + +#if __WORDSIZE==64 + #define DUMP_BITS(code, size) { \ + CHECKBUF55() \ 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; \ - } \ } +#else + +#define DUMP_BITS(code, size) { \ + put_bits += size; \ + put_buffer = (put_buffer << size) | code; \ + CHECKBUF15() \ + } + +#endif + /***************************************************************/ #define DUMP_SINGLE_VALUE(ht, codevalue) { \ @@ -369,14 +423,40 @@ dump_buffer (working_state * state) /***************************************************************/ +#define DUMP_VALUE_SLOW(ht, codevalue, t, nbits) { \ + size = ht->ehufsi[codevalue]; \ + code = ht->ehufco[codevalue]; \ + t &= ~(-1 << nbits); \ + DUMP_BITS_NOCHECK(code, size) \ + CHECKBUF15() \ + DUMP_BITS_NOCHECK(t, nbits) \ + CHECKBUF15() \ + } + +#if __WORDSIZE==64 + +#define DUMP_VALUE(ht, codevalue, t, nbits) { \ + size = ht->ehufsi[codevalue]; \ + code = ht->ehufco[codevalue]; \ + t &= ~(-1 << nbits); \ + CHECKBUF47() \ + DUMP_BITS_NOCHECK(code, size) \ + DUMP_BITS_NOCHECK(t, nbits) \ + } + +#else + #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) \ + DUMP_BITS_NOCHECK(code, size) \ + DUMP_BITS_NOCHECK(t, nbits) \ + CHECKBUF15() \ } +#endif + /***************************************************************/ #define BUFSIZE (DCTSIZE2 * 2) @@ -416,7 +496,7 @@ LOCAL(boolean) flush_bits (working_state * state) { unsigned char _buffer[BUFSIZE], *buffer; - int put_buffer, put_bits; + long put_buffer; int put_bits; int bytes, bytestocopy, localbuf = 0; put_buffer = state->cur.put_buffer; @@ -442,7 +522,7 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, int nbits; int r, sflag, size, code; unsigned char _buffer[BUFSIZE], *buffer; - int put_buffer, put_bits; + long put_buffer; int put_bits; int code_0xf0 = actbl->ehufco[0xf0], size_0xf0 = actbl->ehufsi[0xf0]; int bytes, bytestocopy, localbuf = 0; @@ -457,8 +537,8 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, sflag = temp >> 31; temp -= ((temp + temp) & sflag); temp2 += sflag; - CALC_FIRST_BIT(nbits, temp) - DUMP_VALUE(dctbl, nbits, temp2, nbits) + nbits = jpeg_first_bit_table[temp]; + DUMP_VALUE_SLOW(dctbl, nbits, temp2, nbits) /* Encode the AC coefficients per section F.1.2.2 */ @@ -472,8 +552,8 @@ encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, 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) \ + nbits = jpeg_first_bit_table[temp]; \ sflag = (r << 4) + nbits; \ DUMP_VALUE(actbl, sflag, temp2, nbits) \ r = 0; \ |