diff options
Diffstat (limited to 'deflate.c')
-rw-r--r-- | deflate.c | 169 |
1 files changed, 118 insertions, 51 deletions
@@ -36,8 +36,8 @@ | |||
36 | * | 36 | * |
37 | * REFERENCES | 37 | * REFERENCES |
38 | * | 38 | * |
39 | * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". | 39 | * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". |
40 | * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc | 40 | * Available in ftp://ds.internic.net/rfc/rfc1951.txt |
41 | * | 41 | * |
42 | * A description of the Rabin and Karp algorithm is given in the book | 42 | * A description of the Rabin and Karp algorithm is given in the book |
43 | * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. | 43 | * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. |
@@ -47,10 +47,12 @@ | |||
47 | * | 47 | * |
48 | */ | 48 | */ |
49 | 49 | ||
50 | /* @(#) $Id$ */ | ||
50 | 51 | ||
51 | #include "deflate.h" | 52 | #include "deflate.h" |
52 | 53 | ||
53 | char deflate_copyright[] = " deflate 1.0.5 Copyright 1995-1998 Jean-loup Gailly "; | 54 | const char deflate_copyright[] = |
55 | " deflate 1.0.7 Copyright 1995-1998 Jean-loup Gailly "; | ||
54 | /* | 56 | /* |
55 | 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 |
56 | 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 |
@@ -76,12 +78,14 @@ local block_state deflate_stored OF((deflate_state *s, int flush)); | |||
76 | local block_state deflate_fast OF((deflate_state *s, int flush)); | 78 | local block_state deflate_fast OF((deflate_state *s, int flush)); |
77 | local block_state deflate_slow OF((deflate_state *s, int flush)); | 79 | local block_state deflate_slow OF((deflate_state *s, int flush)); |
78 | local void lm_init OF((deflate_state *s)); | 80 | local void lm_init OF((deflate_state *s)); |
79 | local uInt longest_match OF((deflate_state *s, IPos cur_match)); | ||
80 | local void putShortMSB OF((deflate_state *s, uInt b)); | 81 | local void putShortMSB OF((deflate_state *s, uInt b)); |
81 | local void flush_pending OF((z_streamp strm)); | 82 | local void flush_pending OF((z_streamp strm)); |
82 | local int read_buf OF((z_streamp strm, charf *buf, unsigned size)); | 83 | local int read_buf OF((z_streamp strm, charf *buf, unsigned size)); |
83 | #ifdef ASMV | 84 | #ifdef ASMV |
84 | void match_init OF((void)); /* asm code initialization */ | 85 | void match_init OF((void)); /* asm code initialization */ |
86 | uInt longest_match OF((deflate_state *s, IPos cur_match)); | ||
87 | #else | ||
88 | local uInt longest_match OF((deflate_state *s, IPos cur_match)); | ||
85 | #endif | 89 | #endif |
86 | 90 | ||
87 | #ifdef DEBUG | 91 | #ifdef DEBUG |
@@ -119,7 +123,7 @@ typedef struct config_s { | |||
119 | compress_func func; | 123 | compress_func func; |
120 | } config; | 124 | } config; |
121 | 125 | ||
122 | local config configuration_table[10] = { | 126 | local const config configuration_table[10] = { |
123 | /* good lazy nice chain */ | 127 | /* good lazy nice chain */ |
124 | /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ | 128 | /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ |
125 | /* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ | 129 | /* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ |
@@ -174,7 +178,7 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ | |||
174 | zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); | 178 | zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); |
175 | 179 | ||
176 | /* ========================================================================= */ | 180 | /* ========================================================================= */ |
177 | int deflateInit_(strm, level, version, stream_size) | 181 | int EXPORT deflateInit_(strm, level, version, stream_size) |
178 | z_streamp strm; | 182 | z_streamp strm; |
179 | int level; | 183 | int level; |
180 | const char *version; | 184 | const char *version; |
@@ -186,7 +190,7 @@ int deflateInit_(strm, level, version, stream_size) | |||
186 | } | 190 | } |
187 | 191 | ||
188 | /* ========================================================================= */ | 192 | /* ========================================================================= */ |
189 | int deflateInit2_(strm, level, method, windowBits, memLevel, strategy, | 193 | int EXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, |
190 | version, stream_size) | 194 | version, stream_size) |
191 | z_streamp strm; | 195 | z_streamp strm; |
192 | int level; | 196 | int level; |
@@ -199,13 +203,14 @@ int deflateInit2_(strm, level, method, windowBits, memLevel, strategy, | |||
199 | { | 203 | { |
200 | deflate_state *s; | 204 | deflate_state *s; |
201 | int noheader = 0; | 205 | int noheader = 0; |
206 | static const char* my_version = ZLIB_VERSION; | ||
202 | 207 | ||
203 | ushf *overlay; | 208 | ushf *overlay; |
204 | /* We overlay pending_buf and d_buf+l_buf. This works since the average | 209 | /* We overlay pending_buf and d_buf+l_buf. This works since the average |
205 | * output size for (length,distance) codes is <= 24 bits. | 210 | * output size for (length,distance) codes is <= 24 bits. |
206 | */ | 211 | */ |
207 | 212 | ||
208 | if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || | 213 | if (version == Z_NULL || version[0] != my_version[0] || |
209 | stream_size != sizeof(z_stream)) { | 214 | stream_size != sizeof(z_stream)) { |
210 | return Z_VERSION_ERROR; | 215 | return Z_VERSION_ERROR; |
211 | } | 216 | } |
@@ -252,6 +257,7 @@ int deflateInit2_(strm, level, method, windowBits, memLevel, strategy, | |||
252 | 257 | ||
253 | overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); | 258 | overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); |
254 | s->pending_buf = (uchf *) overlay; | 259 | s->pending_buf = (uchf *) overlay; |
260 | s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); | ||
255 | 261 | ||
256 | if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || | 262 | if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || |
257 | s->pending_buf == Z_NULL) { | 263 | s->pending_buf == Z_NULL) { |
@@ -270,7 +276,7 @@ int deflateInit2_(strm, level, method, windowBits, memLevel, strategy, | |||
270 | } | 276 | } |
271 | 277 | ||
272 | /* ========================================================================= */ | 278 | /* ========================================================================= */ |
273 | int deflateSetDictionary (strm, dictionary, dictLength) | 279 | int EXPORT deflateSetDictionary (strm, dictionary, dictLength) |
274 | z_streamp strm; | 280 | z_streamp strm; |
275 | const Bytef *dictionary; | 281 | const Bytef *dictionary; |
276 | uInt dictLength; | 282 | uInt dictLength; |
@@ -289,7 +295,9 @@ int deflateSetDictionary (strm, dictionary, dictLength) | |||
289 | if (length < MIN_MATCH) return Z_OK; | 295 | if (length < MIN_MATCH) return Z_OK; |
290 | if (length > MAX_DIST(s)) { | 296 | if (length > MAX_DIST(s)) { |
291 | length = MAX_DIST(s); | 297 | length = MAX_DIST(s); |
292 | dictionary += dictLength - length; | 298 | #ifndef USE_DICT_HEAD |
299 | dictionary += dictLength - length; /* use the tail of the dictionary */ | ||
300 | #endif | ||
293 | } | 301 | } |
294 | zmemcpy((charf *)s->window, dictionary, length); | 302 | zmemcpy((charf *)s->window, dictionary, length); |
295 | s->strstart = length; | 303 | s->strstart = length; |
@@ -309,7 +317,7 @@ int deflateSetDictionary (strm, dictionary, dictLength) | |||
309 | } | 317 | } |
310 | 318 | ||
311 | /* ========================================================================= */ | 319 | /* ========================================================================= */ |
312 | int deflateReset (strm) | 320 | int EXPORT deflateReset (strm) |
313 | z_streamp strm; | 321 | z_streamp strm; |
314 | { | 322 | { |
315 | deflate_state *s; | 323 | deflate_state *s; |
@@ -339,7 +347,7 @@ int deflateReset (strm) | |||
339 | } | 347 | } |
340 | 348 | ||
341 | /* ========================================================================= */ | 349 | /* ========================================================================= */ |
342 | int deflateParams(strm, level, strategy) | 350 | int EXPORT deflateParams(strm, level, strategy) |
343 | z_streamp strm; | 351 | z_streamp strm; |
344 | int level; | 352 | int level; |
345 | int strategy; | 353 | int strategy; |
@@ -413,7 +421,7 @@ local void flush_pending(strm) | |||
413 | } | 421 | } |
414 | 422 | ||
415 | /* ========================================================================= */ | 423 | /* ========================================================================= */ |
416 | int deflate (strm, flush) | 424 | int EXPORT deflate (strm, flush) |
417 | z_streamp strm; | 425 | z_streamp strm; |
418 | int flush; | 426 | int flush; |
419 | { | 427 | { |
@@ -547,42 +555,85 @@ int deflate (strm, flush) | |||
547 | } | 555 | } |
548 | 556 | ||
549 | /* ========================================================================= */ | 557 | /* ========================================================================= */ |
550 | int deflateEnd (strm) | 558 | int EXPORT deflateEnd (strm) |
551 | z_streamp strm; | 559 | z_streamp strm; |
552 | { | 560 | { |
553 | int status; | 561 | int status; |
554 | 562 | ||
555 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | 563 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; |
556 | 564 | ||
565 | status = strm->state->status; | ||
566 | if (status != INIT_STATE && status != BUSY_STATE && | ||
567 | status != FINISH_STATE) { | ||
568 | return Z_STREAM_ERROR; | ||
569 | } | ||
570 | |||
557 | /* Deallocate in reverse order of allocations: */ | 571 | /* Deallocate in reverse order of allocations: */ |
558 | TRY_FREE(strm, strm->state->pending_buf); | 572 | TRY_FREE(strm, strm->state->pending_buf); |
559 | TRY_FREE(strm, strm->state->head); | 573 | TRY_FREE(strm, strm->state->head); |
560 | TRY_FREE(strm, strm->state->prev); | 574 | TRY_FREE(strm, strm->state->prev); |
561 | TRY_FREE(strm, strm->state->window); | 575 | TRY_FREE(strm, strm->state->window); |
562 | 576 | ||
563 | status = strm->state->status; | ||
564 | ZFREE(strm, strm->state); | 577 | ZFREE(strm, strm->state); |
565 | strm->state = Z_NULL; | 578 | strm->state = Z_NULL; |
566 | 579 | ||
567 | return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; | 580 | return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; |
568 | } | 581 | } |
569 | 582 | ||
570 | /* ========================================================================= */ | 583 | /* ========================================================================= |
571 | int deflateCopy (dest, source) | 584 | * Copy the source state to the destination state. |
585 | * To simplify the source, this is not supported for 16-bit MSDOS (which | ||
586 | * doesn't have enough memory anyway to duplicate compression states). | ||
587 | */ | ||
588 | int EXPORT deflateCopy (dest, source) | ||
572 | z_streamp dest; | 589 | z_streamp dest; |
573 | z_streamp source; | 590 | z_streamp source; |
574 | { | 591 | { |
575 | if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { | 592 | #ifdef MAXSEG_64K |
593 | return Z_STREAM_ERROR; | ||
594 | #else | ||
595 | deflate_state *ds; | ||
596 | deflate_state *ss; | ||
597 | ushf *overlay; | ||
598 | |||
599 | ss = source->state; | ||
600 | |||
601 | if (source == Z_NULL || dest == Z_NULL || ss == Z_NULL) { | ||
576 | return Z_STREAM_ERROR; | 602 | return Z_STREAM_ERROR; |
577 | } | 603 | } |
578 | *dest = *source; | 604 | *dest = *source; |
579 | return Z_STREAM_ERROR; /* to be implemented */ | ||
580 | #if 0 | ||
581 | dest->state = (struct internal_state FAR *) | ||
582 | (*dest->zalloc)(1, sizeof(deflate_state)); | ||
583 | if (dest->state == Z_NULL) return Z_MEM_ERROR; | ||
584 | 605 | ||
585 | *(dest->state) = *(source->state); | 606 | ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); |
607 | if (ds == Z_NULL) return Z_MEM_ERROR; | ||
608 | dest->state = (struct internal_state FAR *) ds; | ||
609 | *ds = *ss; | ||
610 | ds->strm = dest; | ||
611 | |||
612 | ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); | ||
613 | ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); | ||
614 | ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); | ||
615 | overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); | ||
616 | ds->pending_buf = (uchf *) overlay; | ||
617 | |||
618 | if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || | ||
619 | ds->pending_buf == Z_NULL) { | ||
620 | deflateEnd (dest); | ||
621 | return Z_MEM_ERROR; | ||
622 | } | ||
623 | /* following zmemcpy do not work for 16-bit MSDOS */ | ||
624 | zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); | ||
625 | zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); | ||
626 | zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); | ||
627 | zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); | ||
628 | |||
629 | ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); | ||
630 | ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); | ||
631 | ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; | ||
632 | |||
633 | ds->l_desc.dyn_tree = ds->dyn_ltree; | ||
634 | ds->d_desc.dyn_tree = ds->dyn_dtree; | ||
635 | ds->bl_desc.dyn_tree = ds->bl_tree; | ||
636 | |||
586 | return Z_OK; | 637 | return Z_OK; |
587 | #endif | 638 | #endif |
588 | } | 639 | } |
@@ -815,7 +866,7 @@ local void check_match(s, start, match, length) | |||
815 | } while (--length != 0); | 866 | } while (--length != 0); |
816 | z_error("invalid match"); | 867 | z_error("invalid match"); |
817 | } | 868 | } |
818 | if (verbose > 1) { | 869 | if (z_verbose > 1) { |
819 | fprintf(stderr,"\\[%d,%d]", start-match, length); | 870 | fprintf(stderr,"\\[%d,%d]", start-match, length); |
820 | do { putc(s->window[start++], stderr); } while (--length != 0); | 871 | do { putc(s->window[start++], stderr); } while (--length != 0); |
821 | } | 872 | } |
@@ -864,29 +915,30 @@ local void fill_window(s) | |||
864 | (unsigned)wsize); | 915 | (unsigned)wsize); |
865 | s->match_start -= wsize; | 916 | s->match_start -= wsize; |
866 | s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ | 917 | s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ |
867 | |||
868 | s->block_start -= (long) wsize; | 918 | s->block_start -= (long) wsize; |
869 | 919 | ||
870 | /* Slide the hash table (could be avoided with 32 bit values | 920 | /* Slide the hash table (could be avoided with 32 bit values |
871 | at the expense of memory usage): | 921 | at the expense of memory usage). We slide even when level == 0 |
922 | to keep the hash table consistent if we switch back to level > 0 | ||
923 | later. (Using level 0 permanently is not an optimal usage of | ||
924 | zlib, so we don't care about this pathological case.) | ||
872 | */ | 925 | */ |
873 | n = s->hash_size; | 926 | n = s->hash_size; |
874 | p = &s->head[n]; | 927 | p = &s->head[n]; |
875 | do { | 928 | do { |
876 | m = *--p; | 929 | m = *--p; |
877 | *p = (Pos)(m >= wsize ? m-wsize : NIL); | 930 | *p = (Pos)(m >= wsize ? m-wsize : NIL); |
878 | } while (--n); | 931 | } while (--n); |
879 | 932 | ||
880 | n = wsize; | 933 | n = wsize; |
881 | p = &s->prev[n]; | 934 | p = &s->prev[n]; |
882 | do { | 935 | do { |
883 | m = *--p; | 936 | m = *--p; |
884 | *p = (Pos)(m >= wsize ? m-wsize : NIL); | 937 | *p = (Pos)(m >= wsize ? m-wsize : NIL); |
885 | /* If n is not on any hash chain, prev[n] is garbage but | 938 | /* If n is not on any hash chain, prev[n] is garbage but |
886 | * its value will never be used. | 939 | * its value will never be used. |
887 | */ | 940 | */ |
888 | } while (--n); | 941 | } while (--n); |
889 | |||
890 | more += wsize; | 942 | more += wsize; |
891 | } | 943 | } |
892 | if (s->strm->avail_in == 0) return; | 944 | if (s->strm->avail_in == 0) return; |
@@ -950,12 +1002,24 @@ local void fill_window(s) | |||
950 | * This function does not insert new strings in the dictionary since | 1002 | * This function does not insert new strings in the dictionary since |
951 | * uncompressible data is probably not useful. This function is used | 1003 | * uncompressible data is probably not useful. This function is used |
952 | * only for the level=0 compression option. | 1004 | * only for the level=0 compression option. |
953 | * NOTE: this function should be optimized to avoid extra copying. | 1005 | * NOTE: this function should be optimized to avoid extra copying from |
1006 | * window to pending_buf. | ||
954 | */ | 1007 | */ |
955 | local block_state deflate_stored(s, flush) | 1008 | local block_state deflate_stored(s, flush) |
956 | deflate_state *s; | 1009 | deflate_state *s; |
957 | int flush; | 1010 | int flush; |
958 | { | 1011 | { |
1012 | /* Stored blocks are limited to 0xffff bytes, pending_buf is limited | ||
1013 | * to pending_buf_size, and each stored block has a 5 byte header: | ||
1014 | */ | ||
1015 | ulg max_block_size = 0xffff; | ||
1016 | ulg max_start; | ||
1017 | |||
1018 | if (max_block_size > s->pending_buf_size - 5) { | ||
1019 | max_block_size = s->pending_buf_size - 5; | ||
1020 | } | ||
1021 | |||
1022 | /* Copy as much as possible from input to output: */ | ||
959 | for (;;) { | 1023 | for (;;) { |
960 | /* Fill the window as much as possible: */ | 1024 | /* Fill the window as much as possible: */ |
961 | if (s->lookahead <= 1) { | 1025 | if (s->lookahead <= 1) { |
@@ -973,14 +1037,17 @@ local block_state deflate_stored(s, flush) | |||
973 | s->strstart += s->lookahead; | 1037 | s->strstart += s->lookahead; |
974 | s->lookahead = 0; | 1038 | s->lookahead = 0; |
975 | 1039 | ||
976 | /* Stored blocks are limited to 0xffff bytes: */ | 1040 | /* Emit a stored block if pending_buf will be full: */ |
977 | if (s->strstart == 0 || s->strstart > 0xfffe) { | 1041 | max_start = s->block_start + max_block_size; |
1042 | if (s->strstart == 0 || (ulg)s->strstart >= max_start) { | ||
978 | /* strstart == 0 is possible when wraparound on 16-bit machine */ | 1043 | /* strstart == 0 is possible when wraparound on 16-bit machine */ |
979 | s->lookahead = s->strstart - 0xffff; | 1044 | s->lookahead = (uInt)(s->strstart - max_start); |
980 | s->strstart = 0xffff; | 1045 | s->strstart = (uInt)max_start; |
1046 | FLUSH_BLOCK(s, 0); | ||
981 | } | 1047 | } |
982 | 1048 | /* Flush if we may have to slide, otherwise block_start may become | |
983 | /* Emit a stored block if it is large enough: */ | 1049 | * negative and the data will be gone: |
1050 | */ | ||
984 | if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { | 1051 | if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { |
985 | FLUSH_BLOCK(s, 0); | 1052 | FLUSH_BLOCK(s, 0); |
986 | } | 1053 | } |