diff options
Diffstat (limited to 'trees.c')
-rw-r--r-- | trees.c | 140 |
1 files changed, 98 insertions, 42 deletions
@@ -143,9 +143,9 @@ local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, | |||
143 | local void compress_block OF((deflate_state *s, ct_data *ltree, | 143 | local void compress_block OF((deflate_state *s, ct_data *ltree, |
144 | ct_data *dtree)); | 144 | ct_data *dtree)); |
145 | local void set_data_type OF((deflate_state *s)); | 145 | local void set_data_type OF((deflate_state *s)); |
146 | local void send_bits OF((deflate_state *s, int value, int length)); | ||
147 | local unsigned bi_reverse OF((unsigned value, int length)); | 146 | local unsigned bi_reverse OF((unsigned value, int length)); |
148 | local void bi_windup OF((deflate_state *s)); | 147 | local void bi_windup OF((deflate_state *s)); |
148 | local void bi_flush OF((deflate_state *s)); | ||
149 | local void copy_block OF((deflate_state *s, charf *buf, unsigned len, | 149 | local void copy_block OF((deflate_state *s, charf *buf, unsigned len, |
150 | int header)); | 150 | int header)); |
151 | 151 | ||
@@ -166,6 +166,63 @@ local void copy_block OF((deflate_state *s, charf *buf, unsigned len, | |||
166 | * used. | 166 | * used. |
167 | */ | 167 | */ |
168 | 168 | ||
169 | /* =========================================================================== | ||
170 | * Output a short LSB first on the stream. | ||
171 | * IN assertion: there is enough room in pendingBuf. | ||
172 | */ | ||
173 | #define put_short(s, w) { \ | ||
174 | put_byte(s, (uch)((w) & 0xff)); \ | ||
175 | put_byte(s, (uch)((ush)(w) >> 8)); \ | ||
176 | } | ||
177 | |||
178 | /* =========================================================================== | ||
179 | * Send a value on a given number of bits. | ||
180 | * IN assertion: length <= 16 and value fits in length bits. | ||
181 | */ | ||
182 | #ifdef DEBUG | ||
183 | local void send_bits OF((deflate_state *s, int value, int length)); | ||
184 | |||
185 | local void send_bits(s, value, length) | ||
186 | deflate_state *s; | ||
187 | int value; /* value to send */ | ||
188 | int length; /* number of bits */ | ||
189 | { | ||
190 | Tracev((stderr," l %2d v %4x ", length, value)); | ||
191 | Assert(length > 0 && length <= 15, "invalid length"); | ||
192 | s->bits_sent += (ulg)length; | ||
193 | |||
194 | /* If not enough room in bi_buf, use (valid) bits from bi_buf and | ||
195 | * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) | ||
196 | * unused bits in value. | ||
197 | */ | ||
198 | if (s->bi_valid > (int)Buf_size - length) { | ||
199 | s->bi_buf |= (value << s->bi_valid); | ||
200 | put_short(s, s->bi_buf); | ||
201 | s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); | ||
202 | s->bi_valid += length - Buf_size; | ||
203 | } else { | ||
204 | s->bi_buf |= value << s->bi_valid; | ||
205 | s->bi_valid += length; | ||
206 | } | ||
207 | } | ||
208 | #else /* !DEBUG */ | ||
209 | |||
210 | #define send_bits(s, value, length) \ | ||
211 | { int len = length;\ | ||
212 | if (s->bi_valid > (int)Buf_size - len) {\ | ||
213 | int val = value;\ | ||
214 | s->bi_buf |= (val << s->bi_valid);\ | ||
215 | put_short(s, s->bi_buf);\ | ||
216 | s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ | ||
217 | s->bi_valid += len - Buf_size;\ | ||
218 | } else {\ | ||
219 | s->bi_buf |= (value) << s->bi_valid;\ | ||
220 | s->bi_valid += len;\ | ||
221 | }\ | ||
222 | } | ||
223 | #endif /* DEBUG */ | ||
224 | |||
225 | |||
169 | #define MAX(a,b) (a >= b ? a : b) | 226 | #define MAX(a,b) (a >= b ? a : b) |
170 | /* the arguments must not have side effects */ | 227 | /* the arguments must not have side effects */ |
171 | 228 | ||
@@ -259,6 +316,7 @@ void ct_init(s) | |||
259 | 316 | ||
260 | s->bi_buf = 0; | 317 | s->bi_buf = 0; |
261 | s->bi_valid = 0; | 318 | s->bi_valid = 0; |
319 | s->last_eob_len = 8; /* enough lookahead for inflate */ | ||
262 | #ifdef DEBUG | 320 | #ifdef DEBUG |
263 | s->bits_sent = 0L; | 321 | s->bits_sent = 0L; |
264 | #endif | 322 | #endif |
@@ -739,7 +797,12 @@ void ct_stored_block(s, buf, stored_len, eof) | |||
739 | } | 797 | } |
740 | 798 | ||
741 | /* =========================================================================== | 799 | /* =========================================================================== |
742 | * Send one empty static block to give enough lookahead for inflate | 800 | * Send one empty static block to give enough lookahead for inflate. |
801 | * This takes 10 bits, of which 7 may remain in the bit buffer. | ||
802 | * The current inflate code requires 9 bits of lookahead. If the EOB | ||
803 | * code for the previous block was coded on 5 bits or less, inflate | ||
804 | * may have only 5+3 bits of lookahead to decode this EOB. | ||
805 | * (There are no problems if the previous block is stored or fixed.) | ||
743 | */ | 806 | */ |
744 | void ct_align(s) | 807 | void ct_align(s) |
745 | deflate_state *s; | 808 | deflate_state *s; |
@@ -747,6 +810,18 @@ void ct_align(s) | |||
747 | send_bits(s, STATIC_TREES<<1, 3); | 810 | send_bits(s, STATIC_TREES<<1, 3); |
748 | send_code(s, END_BLOCK, static_ltree); | 811 | send_code(s, END_BLOCK, static_ltree); |
749 | s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ | 812 | s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ |
813 | bi_flush(s); | ||
814 | /* Of the 10 bits for the empty block, we have already sent | ||
815 | * (10 - bi_valid) bits. The lookahead for the EOB of the previous | ||
816 | * block was thus its length plus what we have just sent. | ||
817 | */ | ||
818 | if (s->last_eob_len + 10 - s->bi_valid < 9) { | ||
819 | send_bits(s, STATIC_TREES<<1, 3); | ||
820 | send_code(s, END_BLOCK, static_ltree); | ||
821 | s->compressed_len += 10L; | ||
822 | bi_flush(s); | ||
823 | } | ||
824 | s->last_eob_len = 7; | ||
750 | } | 825 | } |
751 | 826 | ||
752 | /* =========================================================================== | 827 | /* =========================================================================== |
@@ -950,6 +1025,7 @@ local void compress_block(s, ltree, dtree) | |||
950 | } while (lx < s->last_lit); | 1025 | } while (lx < s->last_lit); |
951 | 1026 | ||
952 | send_code(s, END_BLOCK, ltree); | 1027 | send_code(s, END_BLOCK, ltree); |
1028 | s->last_eob_len = ltree[END_BLOCK].Len; | ||
953 | } | 1029 | } |
954 | 1030 | ||
955 | /* =========================================================================== | 1031 | /* =========================================================================== |
@@ -971,44 +1047,6 @@ local void set_data_type(s) | |||
971 | } | 1047 | } |
972 | 1048 | ||
973 | /* =========================================================================== | 1049 | /* =========================================================================== |
974 | * Output a short LSB first on the stream. | ||
975 | * IN assertion: there is enough room in pendingBuf. | ||
976 | */ | ||
977 | #define put_short(s, w) { \ | ||
978 | put_byte(s, (uch)((w) & 0xff)); \ | ||
979 | put_byte(s, (uch)((ush)(w) >> 8)); \ | ||
980 | } | ||
981 | |||
982 | /* =========================================================================== | ||
983 | * Send a value on a given number of bits. | ||
984 | * IN assertion: length <= 16 and value fits in length bits. | ||
985 | */ | ||
986 | local void send_bits(s, value, length) | ||
987 | deflate_state *s; | ||
988 | int value; /* value to send */ | ||
989 | int length; /* number of bits */ | ||
990 | { | ||
991 | #ifdef DEBUG | ||
992 | Tracev((stderr," l %2d v %4x ", length, value)); | ||
993 | Assert(length > 0 && length <= 15, "invalid length"); | ||
994 | s->bits_sent += (ulg)length; | ||
995 | #endif | ||
996 | /* If not enough room in bi_buf, use (valid) bits from bi_buf and | ||
997 | * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) | ||
998 | * unused bits in value. | ||
999 | */ | ||
1000 | if (s->bi_valid > (int)Buf_size - length) { | ||
1001 | s->bi_buf |= (value << s->bi_valid); | ||
1002 | put_short(s, s->bi_buf); | ||
1003 | s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); | ||
1004 | s->bi_valid += length - Buf_size; | ||
1005 | } else { | ||
1006 | s->bi_buf |= value << s->bi_valid; | ||
1007 | s->bi_valid += length; | ||
1008 | } | ||
1009 | } | ||
1010 | |||
1011 | /* =========================================================================== | ||
1012 | * Reverse the first len bits of a code, using straightforward code (a faster | 1050 | * Reverse the first len bits of a code, using straightforward code (a faster |
1013 | * method would use a table) | 1051 | * method would use a table) |
1014 | * IN assertion: 1 <= len <= 15 | 1052 | * IN assertion: 1 <= len <= 15 |
@@ -1026,7 +1064,24 @@ local unsigned bi_reverse(code, len) | |||
1026 | } | 1064 | } |
1027 | 1065 | ||
1028 | /* =========================================================================== | 1066 | /* =========================================================================== |
1029 | * Write out any remaining bits in an incomplete byte. | 1067 | * Flush the bit buffer, keeping at most 7 bits in it. |
1068 | */ | ||
1069 | local void bi_flush(s) | ||
1070 | deflate_state *s; | ||
1071 | { | ||
1072 | if (s->bi_valid == 16) { | ||
1073 | put_short(s, s->bi_buf); | ||
1074 | s->bi_buf = 0; | ||
1075 | s->bi_valid = 0; | ||
1076 | } else if (s->bi_valid >= 8) { | ||
1077 | put_byte(s, (Byte)s->bi_buf); | ||
1078 | s->bi_buf >>= 8; | ||
1079 | s->bi_valid -= 8; | ||
1080 | } | ||
1081 | } | ||
1082 | |||
1083 | /* =========================================================================== | ||
1084 | * Flush the bit buffer and align the output on a byte boundary | ||
1030 | */ | 1085 | */ |
1031 | local void bi_windup(s) | 1086 | local void bi_windup(s) |
1032 | deflate_state *s; | 1087 | deflate_state *s; |
@@ -1053,7 +1108,8 @@ local void copy_block(s, buf, len, header) | |||
1053 | unsigned len; /* its length */ | 1108 | unsigned len; /* its length */ |
1054 | int header; /* true if block header must be written */ | 1109 | int header; /* true if block header must be written */ |
1055 | { | 1110 | { |
1056 | bi_windup(s); /* align on byte boundary */ | 1111 | bi_windup(s); /* align on byte boundary */ |
1112 | s->last_eob_len = 8; /* enough lookahead for inflate */ | ||
1057 | 1113 | ||
1058 | if (header) { | 1114 | if (header) { |
1059 | put_short(s, (ush)len); | 1115 | put_short(s, (ush)len); |