26 #define GBTUM_COMPRESS_TREE_SIZE 32
29 #define GB_READ_BIT(p, c, bp, result) if (!bp) { c = *(p++); bp = 8; }; result = (c>>7); result &= 1; c <<= 1; bp--
31 #define GB_INIT_WRITE_BITS(p, bp) *p = 0; bp = 8
33 #define GB_WRITE_BITS(p, bp, bitc, bits, i) \
34 if (bp<=0) { bp += 8; p++; *p = 0; } \
35 if ((i=bp-bitc)<0) { \
38 bp += 8; p++; *p = 0; \
43 #define GB_READ_BITS(p, c, bp, bitc, bits) { \
47 for (_i=bitc-1; _i>=0; _i--) { \
48 GB_READ_BIT(p, c, bp, _r); \
49 bits = (bits<<1) + _r; \
68 #if defined(TEST_HUFFMAN_CODE)
75 case GB_CS_END: printf(
" [GB_CS_END]\n");
break;
76 case GB_CS_ID: printf(
" [GB_CS_ID]\n");
break;
79 printf(
": value=%li (='%c')\n", val, (
char)val);
84 printf(
" other command (%li) value=%li (='%c')\n", command, val, (
char)val);
90 int len = strlen(prefix);
91 char *my_prefix = ARB_alloc<char>(len+2);
92 strcpy(my_prefix, prefix);
95 gb_dump_huffmann_tree(t->
son[0], my_prefix);
97 gb_dump_huffmann_tree(t->
son[1], my_prefix);
101 static void gb_dump_huffmann_list(
gb_compress_list *bc,
const char *prefix) {
103 int len = strlen(prefix);
104 char *my_prefix = ARB_alloc<char>(len+2);
105 strcpy(my_prefix, prefix);
106 my_prefix[len+1] = 0;
107 my_prefix[len] =
'0';
108 gb_dump_huffmann_list(bc->
son[0], my_prefix);
109 my_prefix[len] =
'1';
110 gb_dump_huffmann_list(bc->
son[1], my_prefix);
114 printf(
"%s value=%i (='%c') count=%li\n", prefix, bc->
value, (
char)bc->
value, bc->
count);
118 #endif // TEST_HUFFMAN_CODE
123 const unsigned char *p;
127 for (p=data; *p; p+=3+short_flag) {
130 for (i=7; i; i--, mask=mask>>1)
if (mask & bits)
break;
168 if (end) *end = ((
char *)p)+1;
175 #if defined(TEST_HUFFMAN_CODE)
176 printf(
"Huffman tree:\n");
177 gb_dump_huffmann_tree(Main,
"");
178 #endif // TEST_HUFFMAN_CODE
195 int val, bits, mask, value;
196 const unsigned char *p;
201 val = bits = mask = value = bitc = 0;
202 for (p=data; *p; p+=3+short_flag) {
207 if (i>maxi) maxi = i;
216 for (p=data; *p; p+=3+short_flag) {
218 if (short_flag) val = (val<<8)+p[3];
220 for (i=maxi; i<val; i++) {
225 list[i].
value = value;
232 for (bitc=7; bitc; bitc--, mask=mask>>1)
if (mask & bits)
break;
233 mask = 0xff>>(8-bitc);
242 list[i].
value = value;
250 char *
gb_compress_bits(
const char *source,
long size,
const unsigned char *c_0,
long *msize) {
251 const unsigned char *
s = (
const unsigned char *)source;
256 int bitptr, bits, bitc;
262 for (i = 0; i<256; ++i) isNull[i] = 0;
263 for (i = 0; c_0[i]; ++i) isNull[c_0[i]] = 1;
266 for (len = size, i = 0; len; len--) {
267 if (zo_flag == isNull[*(s++)]) {
268 zo_flag = 1 - zo_flag;
289 *msize = dest - buffer + 1;
302 const uint8_t *
s = (
const uint8_t*)(source);
307 for (
long pos = 0; pos<size;) {
311 for (t = Main; !t->
leaf;) {
317 pos += (
long)t->
son[0];
319 for (; lastpos<pos; lastpos++) *(p++) = outc;
320 if (outc==c_0) outc=c_1;
else outc=c_0;
342 while (scount> 0xffff) {
343 *(dest++) = 0x100-122;
346 *(dest++) = lastbyte;
350 *(dest++) = 0x100-122;
351 *(dest++) = scount & 0xff;
352 *(dest++) = (scount >> 8) & 0xff;
353 *(dest++) = lastbyte;
358 *(dest++) = 0x100 - 120;
359 *(dest++) = lastbyte;
365 *(dest++) = lastbyte;
370 #define GB_COPY_NONRUN(dest, source, len) \
371 while (len > 120) { \
376 _p = dest; dest+=_i; \
378 *(_p++) = *(source++); \
386 _p = dest; dest+=_i; \
388 *(_p++) = *(source++); \
397 const char *sourcenequal;
401 sourcenequal = source;
402 rbyte = *(source ++);
407 rbyte = *(source ++); i--;
412 rbyte = *(source ++); i--;
413 if (rbyte!=last)
break;
423 hsize = source - sourcenequal - scount -1;
424 source = sourcenequal;
430 sourcenequal = source++;
434 rbyte = *(source++); i--;
438 hsize = source - sourcenequal;
439 source = sourcenequal;
444 if (*msize >size*9/8) printf(
"ssize %d, dsize %d\n", (
int)size, (
int)*msize);
474 for (search = huffmann_listhead; search; search = search->
next) {
475 if (val<search->val)
break;
478 if (huffmann_listhead) {
481 searchlast->
next = dat;
485 huffmann_listhead = dat;
489 huffmann_listhead = dat;
495 if ((dat = huffmann_listhead)) {
496 huffmann_listhead = dat->
next;
518 *(dest++) = bc->
value;
520 bc->
mask = 0xff>>(8-bitcnt);
527 const int COMPRESS_LIST_SIZE = 257;
530 memset((
char *)(&bitcompress[0]), 0,
sizeof(
gb_compress_list)*COMPRESS_LIST_SIZE);
543 long vali[2] = { 0, 0 };
549 unsigned char *
s = (
unsigned char *)source;
550 for (
long len = size; len; len--) {
551 bitcompress[*(s++)].count++;
555 for (i=0; i<256; i++) {
557 if (bitcompress[i].count>level) {
562 restcount += bitcompress[i].
count;
563 bitcompress[i].
count = 0;
572 while (huffmann_listhead->
next) {
578 bc->
son[0] = element1;
579 bc->
son[1] = element2;
600 #if defined(TEST_HUFFMAN_CODE)
601 printf(
"huffman list:\n");
602 gb_dump_huffmann_list(bc,
"");
603 #endif // TEST_HUFFMAN_CODE
609 unsigned char *
s = (
unsigned char *)source;
611 int bitptr, bits, bitc;
615 for (
long len = size; len; len--) {
617 int command = bitcompress[val].
command;
634 bits = bitcompress[COMPRESS_LIST_SIZE-1].
bits;
635 bitc = bitcompress[COMPRESS_LIST_SIZE-1].
bitcnt;
639 *msize = dest - buffer + 1;
640 #if defined(TEST_HUFFMAN_CODE)
641 printf(
"huffman compression %zu -> %zu (%5.2f %%)\n", size, *msize, (
double)((
double)(*msize)/size*100));
642 #endif // TEST_HUFFMAN_CODE
643 if (*msize >size*2) printf(
"ssize %d, size %d\n", (
int)size, (
int)*msize);
649 const signed char *source = (
signed char*)s;
658 #if defined(DEBUG) && 0
659 printf(
"gb_uncompress_equal_bytes(size=%li):\n", size);
664 #if defined(DEBUG) && 0
665 printf(
"size=%li (code=%i)\n", i, (
int)j);
671 *(dest++) = (
char)(*(source++));
677 j = *(source++) & 0xff;
678 j |= (uint16_t(*(source++)) << 8) & 0xff00;
689 if (((
long)dest) & 1) {
693 if (((
long)dest) &2) {
708 for (; j; j--) *(dest++) = c;
711 for (; j; j++) *(dest++) = c;
732 if (!un_tree)
return NULp;
736 s = (uint8_t*)data[0];
738 for (t = un_tree; !t->
leaf;) {
777 char *p, *s0, *s1, *s2, *s3;
793 for (i = 0; i < mi; i++) {
807 const char *s0, *s1, *s2, *s3;
821 for (i = 0; i < mi; i++) {
835 char *s0, *s1, *s2, *s3;
841 s0 = dest + 0*mi + 1;
842 s1 = dest + 1*mi + 1;
843 s2 = dest + 2*mi + 1;
844 s3 = dest + 3*mi + 1;
845 for (i=0; i<mi; i++) {
872 const char *data = gbe->
data();
879 size_t new_size = -1;
882 int c = *((
unsigned char *)(data++));
886 c &= ~GB_COMPRESSION_LAST;
933 if (pre_compressed) {
957 if ((*msize<=10 && size>10) || *msize < size*7/8) {
968 if (*msize < size-10 && *msize < size*7/8) {
977 if (*msize < size-10 && *msize < size*7/8) {
986 if (last_flag)
return NULp;
987 return (
char *)source;
992 const char *data = (
char *)source;
993 size_t new_size = -1;
997 int c = *((
unsigned char *)(data++));
1000 c &= ~GB_COMPRESSION_LAST;
1022 if (error) last = 1;
1025 if (!error && new_size != size) {
1026 error =
GBS_global_string(
"Wrong decompressed size (expected=%zi, got=%zi)", size, new_size);
#define GB_READ_BIT(p, c, bp, result)
#define GB_READ_BITS(p, c, bp, bitc, bits)
GB_CBUFFER gb_uncompress_data(GBDATA *gbd, GB_CBUFFER source, size_t size)
static char * g_b_write_run(char *dest, int scount, int lastbyte)
void gb_free_compress_tree(gb_compress_tree *tree)
GB_BUFFER gb_compress_data(GBDATA *gbd, int key, GB_CBUFFER source, size_t size, size_t *msize, GB_COMPRESSION_MASK max_compr, bool pre_compressed)
static GB_BUFFER gb_uncompress_equal_bytes(GB_CBUFFER s, size_t size, size_t *new_size)
gb_compress_list_commands command
gb_compress_list * element
GB_MAIN_TYPE * GB_MAIN(GBDATA *gbd)
GB_BUFFER gb_uncompress_longs_old(GB_CBUFFER source, size_t size, size_t *new_size)
bool GB_is_dictionary_compressed(GBDATA *gbd)
gb_compress_tree * bituncompress
#define GB_COPY_NONRUN(dest, source, len)
const unsigned GB_HUFFMAN_MIN_SIZE
void GB_internal_errorf(const char *templat,...)
const char * GBS_global_string(const char *templat,...)
static long gb_compress_huffmann_pop(long *val, gb_compress_list **element)
char * gb_uncompress_by_sequence(GBDATA *gbd, const char *ss, size_t size, GB_ERROR *error, size_t *new_size)
char * gb_compress_bits(const char *source, long size, const unsigned char *c_0, long *msize)
char buffer[MESSAGE_BUFFERSIZE]
GB_BUFFER GB_give_other_buffer(GB_CBUFFER buffer, long size)
GB_BUFFER gb_uncompress_bytes(GB_CBUFFER source, size_t size, size_t *new_size)
GB_ERROR GB_export_error(const char *error)
GB_DICTIONARY * dictionary
GB_ERROR GB_await_error()
static GB_BUFFER gb_compress_longs(GB_CBUFFER source, long size, int last_flag)
GB_CSTR GB_read_key_pntr(GBDATA *gbd)
static __ATTR__USERESULT GB_ERROR gb_check_huffmann_tree(gb_compress_tree *t)
GBCONTAINER * gb_key_data
static void gb_compress_huffmann_add_to_list(long val, gb_compress_list *element)
static GB_BUFFER gb_compress_huffmann(GB_CBUFFER source, size_t size, size_t *msize, int last_flag)
GB_BUFFER gb_uncompress_bits(const char *source, long size, char c_0, char c_1)
static void error(const char *msg)
gb_compress_list * bitcompress
GB_write_int const char GB_write_autoconv_string WRITE_SKELETON(write_pointer, GBDATA *,"%p", GB_write_pointer) char *AW_awa if)(!gb_var) return strdup("")
void * gbm_get_mem(size_t size, long index)
#define GB_WRITE_BITS(p, bp, bitc, bits, i)
#define GB_INIT_WRITE_BITS(p, bp)
gb_compress_tree * son[2]
void gb_compress_equal_bytes_2(const char *source, size_t size, size_t *msize, char *dest)
GB_ERROR GB_export_errorf(const char *templat,...)
void GB_internal_error(const char *message)
GBQUARK GB_KEY_QUARK(GBDATA *gbd)
gb_compress_list * son[2]
static GB_BUFFER gb_uncompress_longs(GB_CBUFFER data, size_t size, size_t *new_size)
static char * gb_compress_huffmann_rek(gb_compress_list *bc, int bits, int bitcnt, char *dest)
#define GB_RUNLENGTH_SIZE
gb_compress_list_commands
size_t uncompressed_size() const
#define __ATTR__USERESULT
char * gb_uncompress_by_dictionary(GBDATA *gbd, GB_CSTR s_source, size_t size, size_t *new_size)
gb_compress_list * gb_build_compress_list(const unsigned char *data, long short_flag, long *size)
static GB_BUFFER gb_compress_equal_bytes(const char *source, size_t size, size_t *msize, int last_flag)
char * gb_compress_by_dictionary(GB_DICTIONARY *dict, GB_CSTR s_source, size_t size, size_t *msize, int last_flag, int search_backward, int search_forward)
#define GB_COMPRESSION_TAGS_SIZE_MAX
gb_compress_tree * gb_build_uncompress_tree(const unsigned char *data, long short_flag, char **end)
GBENTRY * as_entry() const
GB_DICTIONARY * gb_get_dictionary(GB_MAIN_TYPE *Main, GBQUARK key)
static huffmann_list * huffmann_listhead
void gbm_free_mem(void *block, size_t size, long index)
void gb_load_single_key_data(GBDATA *gb_main, GBQUARK q)
#define GBTUM_COMPRESS_TREE_SIZE
static GB_BUFFER gb_uncompress_huffmann(GB_CBUFFER source, size_t maxsize, size_t *new_size)
#define STATIC_ASSERT(const_expression)
const unsigned GB_RUNLENGTH_MIN_SIZE
unsigned int compressed_data
GB_write_int const char s