diff options
Diffstat (limited to 'deflate.c')
-rw-r--r-- | deflate.c | 147 |
1 files changed, 99 insertions, 48 deletions
@@ -52,7 +52,7 @@ | |||
52 | #include "deflate.h" | 52 | #include "deflate.h" |
53 | 53 | ||
54 | const char deflate_copyright[] = | 54 | const char deflate_copyright[] = |
55 | " deflate 1.2.0.3 Copyright 1995-2003 Jean-loup Gailly "; | 55 | " deflate 1.2.0.4 Copyright 1995-2003 Jean-loup Gailly "; |
56 | /* | 56 | /* |
57 | If you use the zlib library in a product, an acknowledgment is welcome | 57 | If you use the zlib library in a product, an acknowledgment is welcome |
58 | in the documentation of your product. If for some reason you cannot | 58 | in the documentation of your product. If for some reason you cannot |
@@ -132,12 +132,12 @@ typedef struct config_s { | |||
132 | local const config configuration_table[2] = { | 132 | local const config configuration_table[2] = { |
133 | /* good lazy nice chain */ | 133 | /* good lazy nice chain */ |
134 | /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ | 134 | /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ |
135 | /* 1 */ {4, 4, 8, 4, deflate_fast}}; /* maximum speed, no lazy matches */ | 135 | /* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ |
136 | #else | 136 | #else |
137 | local const config configuration_table[10] = { | 137 | local const config configuration_table[10] = { |
138 | /* good lazy nice chain */ | 138 | /* good lazy nice chain */ |
139 | /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ | 139 | /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ |
140 | /* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ | 140 | /* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ |
141 | /* 2 */ {4, 5, 16, 8, deflate_fast}, | 141 | /* 2 */ {4, 5, 16, 8, deflate_fast}, |
142 | /* 3 */ {4, 6, 32, 32, deflate_fast}, | 142 | /* 3 */ {4, 6, 32, 32, deflate_fast}, |
143 | 143 | ||
@@ -146,7 +146,7 @@ local const config configuration_table[10] = { | |||
146 | /* 6 */ {8, 16, 128, 128, deflate_slow}, | 146 | /* 6 */ {8, 16, 128, 128, deflate_slow}, |
147 | /* 7 */ {8, 32, 128, 256, deflate_slow}, | 147 | /* 7 */ {8, 32, 128, 256, deflate_slow}, |
148 | /* 8 */ {32, 128, 258, 1024, deflate_slow}, | 148 | /* 8 */ {32, 128, 258, 1024, deflate_slow}, |
149 | /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ | 149 | /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ |
150 | #endif | 150 | #endif |
151 | 151 | ||
152 | /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 | 152 | /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 |
@@ -225,7 +225,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, | |||
225 | int stream_size; | 225 | int stream_size; |
226 | { | 226 | { |
227 | deflate_state *s; | 227 | deflate_state *s; |
228 | int noheader = 0; | 228 | int wrap = 1; |
229 | static const char my_version[] = ZLIB_VERSION; | 229 | static const char my_version[] = ZLIB_VERSION; |
230 | 230 | ||
231 | ushf *overlay; | 231 | ushf *overlay; |
@@ -252,10 +252,16 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, | |||
252 | if (level == Z_DEFAULT_COMPRESSION) level = 6; | 252 | if (level == Z_DEFAULT_COMPRESSION) level = 6; |
253 | #endif | 253 | #endif |
254 | 254 | ||
255 | if (windowBits < 0) { /* undocumented feature: suppress zlib header */ | 255 | if (windowBits < 0) { /* suppress zlib wrapper */ |
256 | noheader = 1; | 256 | wrap = 0; |
257 | windowBits = -windowBits; | 257 | windowBits = -windowBits; |
258 | } | 258 | } |
259 | #ifdef GZIP | ||
260 | else if (windowBits > 15) { | ||
261 | wrap = 2; /* write gzip wrapper instead */ | ||
262 | windowBits -= 16; | ||
263 | } | ||
264 | #endif | ||
259 | if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || | 265 | if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || |
260 | windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || | 266 | windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || |
261 | strategy < 0 || strategy > Z_RLE) { | 267 | strategy < 0 || strategy > Z_RLE) { |
@@ -267,7 +273,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, | |||
267 | strm->state = (struct internal_state FAR *)s; | 273 | strm->state = (struct internal_state FAR *)s; |
268 | s->strm = strm; | 274 | s->strm = strm; |
269 | 275 | ||
270 | s->noheader = noheader; | 276 | s->wrap = wrap; |
271 | s->w_bits = windowBits; | 277 | s->w_bits = windowBits; |
272 | s->w_size = 1 << s->w_bits; | 278 | s->w_size = 1 << s->w_bits; |
273 | s->w_mask = s->w_size - 1; | 279 | s->w_mask = s->w_size - 1; |
@@ -316,11 +322,12 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) | |||
316 | IPos hash_head = 0; | 322 | IPos hash_head = 0; |
317 | 323 | ||
318 | if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || | 324 | if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || |
319 | (!strm->state->noheader && strm->state->status != INIT_STATE)) | 325 | strm->state->wrap == 2 || |
326 | (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) | ||
320 | return Z_STREAM_ERROR; | 327 | return Z_STREAM_ERROR; |
321 | 328 | ||
322 | s = strm->state; | 329 | s = strm->state; |
323 | if (!s->noheader) | 330 | if (s->wrap) |
324 | strm->adler = adler32(strm->adler, dictionary, dictLength); | 331 | strm->adler = adler32(strm->adler, dictionary, dictLength); |
325 | 332 | ||
326 | if (length < MIN_MATCH) return Z_OK; | 333 | if (length < MIN_MATCH) return Z_OK; |
@@ -364,11 +371,15 @@ int ZEXPORT deflateReset (strm) | |||
364 | s->pending = 0; | 371 | s->pending = 0; |
365 | s->pending_out = s->pending_buf; | 372 | s->pending_out = s->pending_buf; |
366 | 373 | ||
367 | if (s->noheader < 0) { | 374 | if (s->wrap < 0) { |
368 | s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ | 375 | s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ |
369 | } | 376 | } |
370 | s->status = s->noheader ? BUSY_STATE : INIT_STATE; | 377 | s->status = s->wrap ? INIT_STATE : BUSY_STATE; |
371 | strm->adler = 1; | 378 | strm->adler = |
379 | #ifdef GZIP | ||
380 | s->wrap == 2 ? crc32(0L, Z_NULL, 0) : | ||
381 | #endif | ||
382 | adler32(0L, Z_NULL, 0); | ||
372 | s->last_flush = Z_NO_FLUSH; | 383 | s->last_flush = Z_NO_FLUSH; |
373 | 384 | ||
374 | _tr_init(s); | 385 | _tr_init(s); |
@@ -428,7 +439,7 @@ int ZEXPORT deflateParams(strm, level, strategy) | |||
428 | * can emit on compressed data for some combinations of the parameters. | 439 | * can emit on compressed data for some combinations of the parameters. |
429 | * | 440 | * |
430 | * This function could be more sophisticated to provide closer upper bounds | 441 | * This function could be more sophisticated to provide closer upper bounds |
431 | * for every combination of windowBits and memLevel, as well as noheader. | 442 | * for every combination of windowBits and memLevel, as well as wrap. |
432 | * But even the conservative upper bound of about 14% expansion does not | 443 | * But even the conservative upper bound of about 14% expansion does not |
433 | * seem onerous for output buffer allocation. | 444 | * seem onerous for output buffer allocation. |
434 | */ | 445 | */ |
@@ -519,33 +530,53 @@ int ZEXPORT deflate (strm, flush) | |||
519 | old_flush = s->last_flush; | 530 | old_flush = s->last_flush; |
520 | s->last_flush = flush; | 531 | s->last_flush = flush; |
521 | 532 | ||
522 | /* Write the zlib header */ | 533 | /* Write the header */ |
523 | if (s->status == INIT_STATE) { | 534 | if (s->status == INIT_STATE) { |
524 | 535 | #ifdef GZIP | |
525 | uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; | 536 | if (s->wrap == 2) { |
526 | uInt level_flags; | 537 | put_byte(s, 31); |
527 | 538 | put_byte(s, 139); | |
528 | if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) | 539 | put_byte(s, 8); |
529 | level_flags = 0; | 540 | put_byte(s, 0); |
530 | else if (s->level < 6) | 541 | put_byte(s, 0); |
531 | level_flags = 1; | 542 | put_byte(s, 0); |
532 | else if (s->level == 6) | 543 | put_byte(s, 0); |
533 | level_flags = 2; | 544 | put_byte(s, 0); |
545 | put_byte(s, s->level == 9 ? 2 : | ||
546 | (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? | ||
547 | 4 : 0)); | ||
548 | put_byte(s, 255); | ||
549 | s->status = BUSY_STATE; | ||
550 | strm->adler = crc32(0L, Z_NULL, 0); | ||
551 | } | ||
534 | else | 552 | else |
535 | level_flags = 3; | 553 | #endif |
536 | header |= (level_flags << 6); | 554 | { |
537 | if (s->strstart != 0) header |= PRESET_DICT; | 555 | uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; |
538 | header += 31 - (header % 31); | 556 | uInt level_flags; |
539 | 557 | ||
540 | s->status = BUSY_STATE; | 558 | if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) |
541 | putShortMSB(s, header); | 559 | level_flags = 0; |
542 | 560 | else if (s->level < 6) | |
543 | /* Save the adler32 of the preset dictionary: */ | 561 | level_flags = 1; |
544 | if (s->strstart != 0) { | 562 | else if (s->level == 6) |
545 | putShortMSB(s, (uInt)(strm->adler >> 16)); | 563 | level_flags = 2; |
546 | putShortMSB(s, (uInt)(strm->adler & 0xffff)); | 564 | else |
565 | level_flags = 3; | ||
566 | header |= (level_flags << 6); | ||
567 | if (s->strstart != 0) header |= PRESET_DICT; | ||
568 | header += 31 - (header % 31); | ||
569 | |||
570 | s->status = BUSY_STATE; | ||
571 | putShortMSB(s, header); | ||
572 | |||
573 | /* Save the adler32 of the preset dictionary: */ | ||
574 | if (s->strstart != 0) { | ||
575 | putShortMSB(s, (uInt)(strm->adler >> 16)); | ||
576 | putShortMSB(s, (uInt)(strm->adler & 0xffff)); | ||
577 | } | ||
578 | strm->adler = adler32(0L, Z_NULL, 0); | ||
547 | } | 579 | } |
548 | strm->adler = 1L; | ||
549 | } | 580 | } |
550 | 581 | ||
551 | /* Flush as much pending output as possible */ | 582 | /* Flush as much pending output as possible */ |
@@ -622,16 +653,31 @@ int ZEXPORT deflate (strm, flush) | |||
622 | Assert(strm->avail_out > 0, "bug2"); | 653 | Assert(strm->avail_out > 0, "bug2"); |
623 | 654 | ||
624 | if (flush != Z_FINISH) return Z_OK; | 655 | if (flush != Z_FINISH) return Z_OK; |
625 | if (s->noheader) return Z_STREAM_END; | 656 | if (s->wrap <= 0) return Z_STREAM_END; |
626 | 657 | ||
627 | /* Write the zlib trailer (adler32) */ | 658 | /* Write the trailer */ |
628 | putShortMSB(s, (uInt)(strm->adler >> 16)); | 659 | #ifdef GZIP |
629 | putShortMSB(s, (uInt)(strm->adler & 0xffff)); | 660 | if (s->wrap == 2) { |
661 | put_byte(s, (Byte)(strm->adler & 0xff)); | ||
662 | put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); | ||
663 | put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); | ||
664 | put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); | ||
665 | put_byte(s, (Byte)(strm->total_in & 0xff)); | ||
666 | put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); | ||
667 | put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); | ||
668 | put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); | ||
669 | } | ||
670 | else | ||
671 | #endif | ||
672 | { | ||
673 | putShortMSB(s, (uInt)(strm->adler >> 16)); | ||
674 | putShortMSB(s, (uInt)(strm->adler & 0xffff)); | ||
675 | } | ||
630 | flush_pending(strm); | 676 | flush_pending(strm); |
631 | /* If avail_out is zero, the application will call deflate again | 677 | /* If avail_out is zero, the application will call deflate again |
632 | * to flush the rest. | 678 | * to flush the rest. |
633 | */ | 679 | */ |
634 | s->noheader = -1; /* write the trailer only once! */ | 680 | if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ |
635 | return s->pending != 0 ? Z_OK : Z_STREAM_END; | 681 | return s->pending != 0 ? Z_OK : Z_STREAM_END; |
636 | } | 682 | } |
637 | 683 | ||
@@ -740,9 +786,14 @@ local int read_buf(strm, buf, size) | |||
740 | 786 | ||
741 | strm->avail_in -= len; | 787 | strm->avail_in -= len; |
742 | 788 | ||
743 | if (!strm->state->noheader) { | 789 | if (strm->state->wrap == 1) { |
744 | strm->adler = adler32(strm->adler, strm->next_in, len); | 790 | strm->adler = adler32(strm->adler, strm->next_in, len); |
745 | } | 791 | } |
792 | #ifdef GZIP | ||
793 | else if (strm->state->wrap == 2) { | ||
794 | strm->adler = crc32(strm->adler, strm->next_in, len); | ||
795 | } | ||
796 | #endif | ||
746 | zmemcpy(buf, strm->next_in, len); | 797 | zmemcpy(buf, strm->next_in, len); |
747 | strm->next_in += len; | 798 | strm->next_in += len; |
748 | strm->total_in += len; | 799 | strm->total_in += len; |
@@ -1044,7 +1095,7 @@ local void fill_window(s) | |||
1044 | 1095 | ||
1045 | } else if (more == (unsigned)(-1)) { | 1096 | } else if (more == (unsigned)(-1)) { |
1046 | /* Very unlikely, but possible on 16 bit machine if | 1097 | /* Very unlikely, but possible on 16 bit machine if |
1047 | * strstart == 0 && lookahead == 1 (input done one byte at time) | 1098 | * strstart == 0 && lookahead == 1 (input done a byte at time) |
1048 | */ | 1099 | */ |
1049 | more--; | 1100 | more--; |
1050 | } | 1101 | } |
@@ -1271,7 +1322,7 @@ local block_state deflate_fast(s, flush) | |||
1271 | #ifndef FASTEST | 1322 | #ifndef FASTEST |
1272 | if (s->match_length <= s->max_insert_length && | 1323 | if (s->match_length <= s->max_insert_length && |
1273 | s->lookahead >= MIN_MATCH) { | 1324 | s->lookahead >= MIN_MATCH) { |
1274 | s->match_length--; /* string at strstart already in hash table */ | 1325 | s->match_length--; /* string at strstart already in table */ |
1275 | do { | 1326 | do { |
1276 | s->strstart++; | 1327 | s->strstart++; |
1277 | INSERT_STRING(s, s->strstart, hash_head); | 1328 | INSERT_STRING(s, s->strstart, hash_head); |