diff options
Diffstat (limited to 'deflate.c')
-rw-r--r-- | deflate.c | 174 |
1 files changed, 161 insertions, 13 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.2 Copyright 1995-2004 Jean-loup Gailly "; | 55 | " deflate 1.2.2.1 Copyright 1995-2004 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 |
@@ -274,6 +274,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, | |||
274 | s->strm = strm; | 274 | s->strm = strm; |
275 | 275 | ||
276 | s->wrap = wrap; | 276 | s->wrap = wrap; |
277 | s->gzhead = Z_NULL; | ||
277 | s->w_bits = windowBits; | 278 | s->w_bits = windowBits; |
278 | s->w_size = 1 << s->w_bits; | 279 | s->w_size = 1 << s->w_bits; |
279 | s->w_mask = s->w_size - 1; | 280 | s->w_mask = s->w_size - 1; |
@@ -391,6 +392,17 @@ int ZEXPORT deflateReset (strm) | |||
391 | } | 392 | } |
392 | 393 | ||
393 | /* ========================================================================= */ | 394 | /* ========================================================================= */ |
395 | int ZEXPORT deflateSetHeader (strm, head) | ||
396 | z_streamp strm; | ||
397 | gz_headerp head; | ||
398 | { | ||
399 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | ||
400 | if (strm->state->wrap != 2) return Z_STREAM_ERROR; | ||
401 | strm->state->gzhead = head; | ||
402 | return Z_OK; | ||
403 | } | ||
404 | |||
405 | /* ========================================================================= */ | ||
394 | int ZEXPORT deflatePrime (strm, bits, value) | 406 | int ZEXPORT deflatePrime (strm, bits, value) |
395 | z_streamp strm; | 407 | z_streamp strm; |
396 | int bits; | 408 | int bits; |
@@ -548,20 +560,47 @@ int ZEXPORT deflate (strm, flush) | |||
548 | if (s->status == INIT_STATE) { | 560 | if (s->status == INIT_STATE) { |
549 | #ifdef GZIP | 561 | #ifdef GZIP |
550 | if (s->wrap == 2) { | 562 | if (s->wrap == 2) { |
563 | strm->adler = crc32(0L, Z_NULL, 0); | ||
551 | put_byte(s, 31); | 564 | put_byte(s, 31); |
552 | put_byte(s, 139); | 565 | put_byte(s, 139); |
553 | put_byte(s, 8); | 566 | put_byte(s, 8); |
554 | put_byte(s, 0); | 567 | if (s->gzhead == NULL) { |
555 | put_byte(s, 0); | 568 | put_byte(s, 0); |
556 | put_byte(s, 0); | 569 | put_byte(s, 0); |
557 | put_byte(s, 0); | 570 | put_byte(s, 0); |
558 | put_byte(s, 0); | 571 | put_byte(s, 0); |
559 | put_byte(s, s->level == 9 ? 2 : | 572 | put_byte(s, 0); |
560 | (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? | 573 | put_byte(s, s->level == 9 ? 2 : |
561 | 4 : 0)); | 574 | (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? |
562 | put_byte(s, 255); | 575 | 4 : 0)); |
563 | s->status = BUSY_STATE; | 576 | put_byte(s, 255); |
564 | strm->adler = crc32(0L, Z_NULL, 0); | 577 | s->status = BUSY_STATE; |
578 | } | ||
579 | else { | ||
580 | put_byte(s, (s->gzhead->text ? 1 : 0) + | ||
581 | (s->gzhead->hcrc ? 2 : 0) + | ||
582 | (s->gzhead->extra == Z_NULL ? 0 : 4) + | ||
583 | (s->gzhead->name == Z_NULL ? 0 : 8) + | ||
584 | (s->gzhead->comment == Z_NULL ? 0 : 16) | ||
585 | ); | ||
586 | put_byte(s, s->gzhead->time & 0xff); | ||
587 | put_byte(s, (s->gzhead->time >> 8) & 0xff); | ||
588 | put_byte(s, (s->gzhead->time >> 16) & 0xff); | ||
589 | put_byte(s, (s->gzhead->time >> 24) & 0xff); | ||
590 | put_byte(s, s->level == 9 ? 2 : | ||
591 | (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? | ||
592 | 4 : 0)); | ||
593 | put_byte(s, s->gzhead->os & 0xff); | ||
594 | if (s->gzhead->extra != NULL) { | ||
595 | put_byte(s, s->gzhead->extra_len & 0xff); | ||
596 | put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); | ||
597 | } | ||
598 | if (s->gzhead->hcrc) | ||
599 | strm->adler = crc32(strm->adler, s->pending_buf, | ||
600 | s->pending); | ||
601 | s->gzindex = 0; | ||
602 | s->status = EXTRA_STATE; | ||
603 | } | ||
565 | } | 604 | } |
566 | else | 605 | else |
567 | #endif | 606 | #endif |
@@ -592,6 +631,110 @@ int ZEXPORT deflate (strm, flush) | |||
592 | strm->adler = adler32(0L, Z_NULL, 0); | 631 | strm->adler = adler32(0L, Z_NULL, 0); |
593 | } | 632 | } |
594 | } | 633 | } |
634 | #ifdef GZIP | ||
635 | if (s->status == EXTRA_STATE) { | ||
636 | if (s->gzhead->extra != NULL) { | ||
637 | int beg = s->pending; /* start of bytes to update crc */ | ||
638 | |||
639 | while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { | ||
640 | if (s->pending == s->pending_buf_size) { | ||
641 | if (s->gzhead->hcrc && s->pending > beg) | ||
642 | strm->adler = crc32(strm->adler, s->pending_buf + beg, | ||
643 | s->pending - beg); | ||
644 | flush_pending(strm); | ||
645 | beg = s->pending; | ||
646 | if (s->pending == s->pending_buf_size) | ||
647 | break; | ||
648 | } | ||
649 | put_byte(s, s->gzhead->extra[s->gzindex]); | ||
650 | s->gzindex++; | ||
651 | } | ||
652 | if (s->gzhead->hcrc && s->pending > beg) | ||
653 | strm->adler = crc32(strm->adler, s->pending_buf + beg, | ||
654 | s->pending - beg); | ||
655 | if (s->gzindex == s->gzhead->extra_len) { | ||
656 | s->gzindex = 0; | ||
657 | s->status = NAME_STATE; | ||
658 | } | ||
659 | } | ||
660 | else | ||
661 | s->status = NAME_STATE; | ||
662 | } | ||
663 | if (s->status == NAME_STATE) { | ||
664 | if (s->gzhead->name != NULL) { | ||
665 | int beg = s->pending; /* start of bytes to update crc */ | ||
666 | int val; | ||
667 | |||
668 | do { | ||
669 | if (s->pending == s->pending_buf_size) { | ||
670 | if (s->gzhead->hcrc && s->pending > beg) | ||
671 | strm->adler = crc32(strm->adler, s->pending_buf + beg, | ||
672 | s->pending - beg); | ||
673 | flush_pending(strm); | ||
674 | beg = s->pending; | ||
675 | if (s->pending == s->pending_buf_size) { | ||
676 | val = 1; | ||
677 | break; | ||
678 | } | ||
679 | } | ||
680 | val = s->gzhead->name[s->gzindex++]; | ||
681 | put_byte(s, val); | ||
682 | } while (val != 0); | ||
683 | if (s->gzhead->hcrc && s->pending > beg) | ||
684 | strm->adler = crc32(strm->adler, s->pending_buf + beg, | ||
685 | s->pending - beg); | ||
686 | if (val == 0) { | ||
687 | s->gzindex = 0; | ||
688 | s->status = COMMENT_STATE; | ||
689 | } | ||
690 | } | ||
691 | else | ||
692 | s->status = COMMENT_STATE; | ||
693 | } | ||
694 | if (s->status == COMMENT_STATE) { | ||
695 | if (s->gzhead->comment != NULL) { | ||
696 | int beg = s->pending; /* start of bytes to update crc */ | ||
697 | int val; | ||
698 | |||
699 | do { | ||
700 | if (s->pending == s->pending_buf_size) { | ||
701 | if (s->gzhead->hcrc && s->pending > beg) | ||
702 | strm->adler = crc32(strm->adler, s->pending_buf + beg, | ||
703 | s->pending - beg); | ||
704 | flush_pending(strm); | ||
705 | beg = s->pending; | ||
706 | if (s->pending == s->pending_buf_size) { | ||
707 | val = 1; | ||
708 | break; | ||
709 | } | ||
710 | } | ||
711 | val = s->gzhead->comment[s->gzindex++]; | ||
712 | put_byte(s, val); | ||
713 | } while (val != 0); | ||
714 | if (s->gzhead->hcrc && s->pending > beg) | ||
715 | strm->adler = crc32(strm->adler, s->pending_buf + beg, | ||
716 | s->pending - beg); | ||
717 | if (val == 0) | ||
718 | s->status = HCRC_STATE; | ||
719 | } | ||
720 | else | ||
721 | s->status = HCRC_STATE; | ||
722 | } | ||
723 | if (s->status == HCRC_STATE) { | ||
724 | if (s->gzhead->hcrc) { | ||
725 | if (s->pending + 2 > s->pending_buf_size) | ||
726 | flush_pending(strm); | ||
727 | if (s->pending + 2 <= s->pending_buf_size) { | ||
728 | put_byte(s, strm->adler & 0xff); | ||
729 | put_byte(s, (strm->adler >> 8) & 0xff); | ||
730 | strm->adler = crc32(0L, Z_NULL, 0); | ||
731 | s->status = BUSY_STATE; | ||
732 | } | ||
733 | } | ||
734 | else | ||
735 | s->status = BUSY_STATE; | ||
736 | } | ||
737 | #endif | ||
595 | 738 | ||
596 | /* Flush as much pending output as possible */ | 739 | /* Flush as much pending output as possible */ |
597 | if (s->pending != 0) { | 740 | if (s->pending != 0) { |
@@ -704,7 +847,12 @@ int ZEXPORT deflateEnd (strm) | |||
704 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; | 847 | if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; |
705 | 848 | ||
706 | status = strm->state->status; | 849 | status = strm->state->status; |
707 | if (status != INIT_STATE && status != BUSY_STATE && | 850 | if (status != INIT_STATE && |
851 | status != EXTRA_STATE && | ||
852 | status != NAME_STATE && | ||
853 | status != COMMENT_STATE && | ||
854 | status != HCRC_STATE && | ||
855 | status != BUSY_STATE && | ||
708 | status != FINISH_STATE) { | 856 | status != FINISH_STATE) { |
709 | return Z_STREAM_ERROR; | 857 | return Z_STREAM_ERROR; |
710 | } | 858 | } |