@@ -10,6 +10,9 @@ Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
10
10
Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus
11
11
Kuhn, Colin Watson, and CORE SDI S.A.
12
12
13
+ Optimised for MicroPython:
14
+ Copyright (c) 2023 by Jim Mussared
15
+
13
16
Permission is hereby granted, free of charge, to any person
14
17
obtaining a copy of this software and associated documentation files
15
18
(the "Software"), to deal in the Software without restriction,
@@ -55,152 +58,44 @@ static void outbits(struct Outbuf *out, unsigned long bits, int nbits)
55
58
out -> outbits |= bits << out -> noutbits ;
56
59
out -> noutbits += nbits ;
57
60
while (out -> noutbits >= 8 ) {
58
- out -> dest_write_cb (out , out -> outbits & 0xFF );
61
+ out -> dest_write_cb (out -> dest_write_data , out -> outbits & 0xFF );
59
62
out -> outbits >>= 8 ;
60
63
out -> noutbits -= 8 ;
61
64
}
62
65
}
63
66
64
- static const unsigned char mirrorbytes [256 ] = {
65
- 0x00 , 0x80 , 0x40 , 0xc0 , 0x20 , 0xa0 , 0x60 , 0xe0 ,
66
- 0x10 , 0x90 , 0x50 , 0xd0 , 0x30 , 0xb0 , 0x70 , 0xf0 ,
67
- 0x08 , 0x88 , 0x48 , 0xc8 , 0x28 , 0xa8 , 0x68 , 0xe8 ,
68
- 0x18 , 0x98 , 0x58 , 0xd8 , 0x38 , 0xb8 , 0x78 , 0xf8 ,
69
- 0x04 , 0x84 , 0x44 , 0xc4 , 0x24 , 0xa4 , 0x64 , 0xe4 ,
70
- 0x14 , 0x94 , 0x54 , 0xd4 , 0x34 , 0xb4 , 0x74 , 0xf4 ,
71
- 0x0c , 0x8c , 0x4c , 0xcc , 0x2c , 0xac , 0x6c , 0xec ,
72
- 0x1c , 0x9c , 0x5c , 0xdc , 0x3c , 0xbc , 0x7c , 0xfc ,
73
- 0x02 , 0x82 , 0x42 , 0xc2 , 0x22 , 0xa2 , 0x62 , 0xe2 ,
74
- 0x12 , 0x92 , 0x52 , 0xd2 , 0x32 , 0xb2 , 0x72 , 0xf2 ,
75
- 0x0a , 0x8a , 0x4a , 0xca , 0x2a , 0xaa , 0x6a , 0xea ,
76
- 0x1a , 0x9a , 0x5a , 0xda , 0x3a , 0xba , 0x7a , 0xfa ,
77
- 0x06 , 0x86 , 0x46 , 0xc6 , 0x26 , 0xa6 , 0x66 , 0xe6 ,
78
- 0x16 , 0x96 , 0x56 , 0xd6 , 0x36 , 0xb6 , 0x76 , 0xf6 ,
79
- 0x0e , 0x8e , 0x4e , 0xce , 0x2e , 0xae , 0x6e , 0xee ,
80
- 0x1e , 0x9e , 0x5e , 0xde , 0x3e , 0xbe , 0x7e , 0xfe ,
81
- 0x01 , 0x81 , 0x41 , 0xc1 , 0x21 , 0xa1 , 0x61 , 0xe1 ,
82
- 0x11 , 0x91 , 0x51 , 0xd1 , 0x31 , 0xb1 , 0x71 , 0xf1 ,
83
- 0x09 , 0x89 , 0x49 , 0xc9 , 0x29 , 0xa9 , 0x69 , 0xe9 ,
84
- 0x19 , 0x99 , 0x59 , 0xd9 , 0x39 , 0xb9 , 0x79 , 0xf9 ,
85
- 0x05 , 0x85 , 0x45 , 0xc5 , 0x25 , 0xa5 , 0x65 , 0xe5 ,
86
- 0x15 , 0x95 , 0x55 , 0xd5 , 0x35 , 0xb5 , 0x75 , 0xf5 ,
87
- 0x0d , 0x8d , 0x4d , 0xcd , 0x2d , 0xad , 0x6d , 0xed ,
88
- 0x1d , 0x9d , 0x5d , 0xdd , 0x3d , 0xbd , 0x7d , 0xfd ,
89
- 0x03 , 0x83 , 0x43 , 0xc3 , 0x23 , 0xa3 , 0x63 , 0xe3 ,
90
- 0x13 , 0x93 , 0x53 , 0xd3 , 0x33 , 0xb3 , 0x73 , 0xf3 ,
91
- 0x0b , 0x8b , 0x4b , 0xcb , 0x2b , 0xab , 0x6b , 0xeb ,
92
- 0x1b , 0x9b , 0x5b , 0xdb , 0x3b , 0xbb , 0x7b , 0xfb ,
93
- 0x07 , 0x87 , 0x47 , 0xc7 , 0x27 , 0xa7 , 0x67 , 0xe7 ,
94
- 0x17 , 0x97 , 0x57 , 0xd7 , 0x37 , 0xb7 , 0x77 , 0xf7 ,
95
- 0x0f , 0x8f , 0x4f , 0xcf , 0x2f , 0xaf , 0x6f , 0xef ,
96
- 0x1f , 0x9f , 0x5f , 0xdf , 0x3f , 0xbf , 0x7f , 0xff ,
67
+ static const unsigned char mirrornibbles [16 ] = {
68
+ 0x0 , 0x8 , 0x4 , 0xc , 0x2 , 0xa , 0x6 , 0xe ,
69
+ 0x1 , 0x9 , 0x5 , 0xd , 0x3 , 0xb , 0x7 , 0xf ,
97
70
};
98
71
99
- typedef struct {
100
- uint8_t extrabits ;
101
- uint8_t min , max ;
102
- } len_coderecord ;
103
-
104
- typedef struct {
105
- uint8_t code , extrabits ;
106
- uint16_t min , max ;
107
- } dist_coderecord ;
108
-
109
- #define TO_LCODE (x , y ) x - 3, y - 3
110
- #define FROM_LCODE (x ) (x + 3)
111
-
112
- static const len_coderecord lencodes [] = {
113
- {0 , TO_LCODE (3 , 3 )},
114
- {0 , TO_LCODE (4 , 4 )},
115
- {0 , TO_LCODE (5 , 5 )},
116
- {0 , TO_LCODE (6 , 6 )},
117
- {0 , TO_LCODE (7 , 7 )},
118
- {0 , TO_LCODE (8 , 8 )},
119
- {0 , TO_LCODE (9 , 9 )},
120
- {0 , TO_LCODE (10 , 10 )},
121
- {1 , TO_LCODE (11 , 12 )},
122
- {1 , TO_LCODE (13 , 14 )},
123
- {1 , TO_LCODE (15 , 16 )},
124
- {1 , TO_LCODE (17 , 18 )},
125
- {2 , TO_LCODE (19 , 22 )},
126
- {2 , TO_LCODE (23 , 26 )},
127
- {2 , TO_LCODE (27 , 30 )},
128
- {2 , TO_LCODE (31 , 34 )},
129
- {3 , TO_LCODE (35 , 42 )},
130
- {3 , TO_LCODE (43 , 50 )},
131
- {3 , TO_LCODE (51 , 58 )},
132
- {3 , TO_LCODE (59 , 66 )},
133
- {4 , TO_LCODE (67 , 82 )},
134
- {4 , TO_LCODE (83 , 98 )},
135
- {4 , TO_LCODE (99 , 114 )},
136
- {4 , TO_LCODE (115 , 130 )},
137
- {5 , TO_LCODE (131 , 162 )},
138
- {5 , TO_LCODE (163 , 194 )},
139
- {5 , TO_LCODE (195 , 226 )},
140
- {5 , TO_LCODE (227 , 257 )},
141
- {0 , TO_LCODE (258 , 258 )},
142
- };
72
+ static unsigned int mirrorbyte (unsigned int b ) {
73
+ return mirrornibbles [b & 0xf ] << 4 | mirrornibbles [b >> 4 ];
74
+ }
143
75
144
- static const dist_coderecord distcodes [] = {
145
- {0 , 0 , 1 , 1 },
146
- {1 , 0 , 2 , 2 },
147
- {2 , 0 , 3 , 3 },
148
- {3 , 0 , 4 , 4 },
149
- {4 , 1 , 5 , 6 },
150
- {5 , 1 , 7 , 8 },
151
- {6 , 2 , 9 , 12 },
152
- {7 , 2 , 13 , 16 },
153
- {8 , 3 , 17 , 24 },
154
- {9 , 3 , 25 , 32 },
155
- {10 , 4 , 33 , 48 },
156
- {11 , 4 , 49 , 64 },
157
- {12 , 5 , 65 , 96 },
158
- {13 , 5 , 97 , 128 },
159
- {14 , 6 , 129 , 192 },
160
- {15 , 6 , 193 , 256 },
161
- {16 , 7 , 257 , 384 },
162
- {17 , 7 , 385 , 512 },
163
- {18 , 8 , 513 , 768 },
164
- {19 , 8 , 769 , 1024 },
165
- {20 , 9 , 1025 , 1536 },
166
- {21 , 9 , 1537 , 2048 },
167
- {22 , 10 , 2049 , 3072 },
168
- {23 , 10 , 3073 , 4096 },
169
- {24 , 11 , 4097 , 6144 },
170
- {25 , 11 , 6145 , 8192 },
171
- {26 , 12 , 8193 , 12288 },
172
- {27 , 12 , 12289 , 16384 },
173
- {28 , 13 , 16385 , 24576 },
174
- {29 , 13 , 24577 , 32768 },
175
- };
76
+ static int int_log2 (int x ) {
77
+ int r = 0 ;
78
+ while (x >>= 1 ) {
79
+ ++ r ;
80
+ }
81
+ return r ;
82
+ }
176
83
177
84
void zlib_literal (struct Outbuf * out , unsigned char c )
178
85
{
179
- if (out -> comp_disabled ) {
180
- /*
181
- * We're in an uncompressed block, so just output the byte.
182
- */
183
- outbits (out , c , 8 );
184
- return ;
185
- }
186
-
187
86
if (c <= 143 ) {
188
87
/* 0 through 143 are 8 bits long starting at 00110000. */
189
- outbits (out , mirrorbytes [ 0x30 + c ] , 8 );
88
+ outbits (out , mirrorbyte ( 0x30 + c ) , 8 );
190
89
} else {
191
90
/* 144 through 255 are 9 bits long starting at 110010000. */
192
- outbits (out , 1 + 2 * mirrorbytes [ 0x90 - 144 + c ] , 9 );
91
+ outbits (out , 1 + 2 * mirrorbyte ( 0x90 - 144 + c ) , 9 );
193
92
}
194
93
}
195
94
196
95
void zlib_match (struct Outbuf * out , int distance , int len )
197
96
{
198
- const dist_coderecord * d ;
199
- const len_coderecord * l ;
200
- int i , j , k ;
201
- int lcode ;
202
-
203
- assert (!out -> comp_disabled );
97
+ assert (distance >= 1 && distance <= 32768 );
98
+ distance -= 1 ;
204
99
205
100
while (len > 0 ) {
206
101
int thislen ;
@@ -218,73 +113,56 @@ void zlib_match(struct Outbuf *out, int distance, int len)
218
113
thislen = (len > 260 ? 258 : len <= 258 ? len : len - 3 );
219
114
len -= thislen ;
220
115
221
- /*
222
- * Binary-search to find which length code we're
223
- * transmitting.
224
- */
225
- i = -1 ;
226
- j = sizeof (lencodes ) / sizeof (* lencodes );
227
- while (1 ) {
228
- assert (j - i >= 2 );
229
- k = (j + i ) / 2 ;
230
- if (thislen < FROM_LCODE (lencodes [k ].min ))
231
- j = k ;
232
- else if (thislen > FROM_LCODE (lencodes [k ].max ))
233
- i = k ;
234
- else {
235
- l = & lencodes [k ];
236
- break ; /* found it! */
116
+ assert (thislen >= 3 && thislen <= 258 );
117
+
118
+ thislen -= 3 ;
119
+ int lcode = 28 ;
120
+ int x = int_log2 (thislen );
121
+ int y ;
122
+ if (thislen < 255 ) {
123
+ if (x ) {
124
+ -- x ;
237
125
}
126
+ y = (thislen >> (x ? x - 1 : 0 )) & 3 ;
127
+ lcode = x * 4 + y ;
238
128
}
239
129
240
- lcode = l - lencodes + 257 ;
241
-
242
130
/*
243
131
* Transmit the length code. 256-279 are seven bits
244
132
* starting at 0000000; 280-287 are eight bits starting at
245
133
* 11000000.
246
134
*/
247
- if (lcode <= 279 ) {
248
- outbits (out , mirrorbytes [( lcode - 256 ) * 2 ] , 7 );
135
+ if (lcode <= 22 ) {
136
+ outbits (out , mirrorbyte (( lcode + 1 ) * 2 ) , 7 );
249
137
} else {
250
- outbits (out , mirrorbytes [ 0xc0 - 280 + lcode ] , 8 );
138
+ outbits (out , mirrorbyte ( lcode + 169 ) , 8 );
251
139
}
252
140
253
141
/*
254
142
* Transmit the extra bits.
255
143
*/
256
- if (l -> extrabits )
257
- outbits (out , thislen - FROM_LCODE (l -> min ), l -> extrabits );
258
-
259
- /*
260
- * Binary-search to find which distance code we're
261
- * transmitting.
262
- */
263
- i = -1 ;
264
- j = sizeof (distcodes ) / sizeof (* distcodes );
265
- while (1 ) {
266
- assert (j - i >= 2 );
267
- k = (j + i ) / 2 ;
268
- if (distance < distcodes [k ].min )
269
- j = k ;
270
- else if (distance > distcodes [k ].max )
271
- i = k ;
272
- else {
273
- d = & distcodes [k ];
274
- break ; /* found it! */
275
- }
144
+ if (thislen < 255 && x > 1 ) {
145
+ int extrabits = x - 1 ;
146
+ int lmin = (thislen >> extrabits ) << extrabits ;
147
+ outbits (out , thislen - lmin , extrabits );
276
148
}
277
149
150
+ x = int_log2 (distance );
151
+ y = (distance >> (x ? x - 1 : 0 )) & 1 ;
152
+
278
153
/*
279
154
* Transmit the distance code. Five bits starting at 00000.
280
155
*/
281
- outbits (out , mirrorbytes [ d -> code * 8 ] , 5 );
156
+ outbits (out , mirrorbyte (( x * 2 + y ) * 8 ) , 5 );
282
157
283
158
/*
284
159
* Transmit the extra bits.
285
160
*/
286
- if (d -> extrabits )
287
- outbits (out , distance - d -> min , d -> extrabits );
161
+ if (x > 1 ) {
162
+ int dextrabits = x - 1 ;
163
+ int dmin = (distance >> dextrabits ) << dextrabits ;
164
+ outbits (out , distance - dmin , dextrabits );
165
+ }
288
166
}
289
167
}
290
168
0 commit comments