/src/libwebsockets/lib/misc/upng-gzip.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * LWS PNG -- derived from uPNG -- derived from LodePNG version 20100808 |
3 | | * Stateful, linewise PNG decode requiring ~36KB fixed heap |
4 | | * |
5 | | * Copyright (c) 2005-2010 Lode Vandevenne (LodePNG) |
6 | | * Copyright (c) 2010 Sean Middleditch (uPNG) |
7 | | * Copyright (c) 2021 Andy Green <andy@warmcat.com> (Stateful, incremental) |
8 | | * |
9 | | * This software is provided 'as-is', without any express or implied |
10 | | * warranty. In no event will the authors be held liable for any damages |
11 | | * arising from the use of this software. |
12 | | |
13 | | * Permission is granted to anyone to use this software for any purpose, |
14 | | * including commercial applications, and to alter it and redistribute it |
15 | | * freely, subject to the following restrictions: |
16 | | * |
17 | | * 1. The origin of this software must not be misrepresented; you must not |
18 | | * claim that you wrote the original software. If you use this software |
19 | | * in a product, an acknowledgment in the product documentation would be |
20 | | * appreciated but is not required. |
21 | | * |
22 | | * 2. Altered source versions must be plainly marked as such, and must not be |
23 | | * misrepresented as being the original software. |
24 | | * |
25 | | * 3. This notice may not be removed or altered from any source |
26 | | * distribution. |
27 | | * |
28 | | * AG: The above notice is the ZLIB license, libpng also uses it. |
29 | | * |
30 | | * This version was rewritten from the upng project's fork of lodepng and |
31 | | * adapted to be a stateful stream parser. This rewrite retains the ZLIB |
32 | | * license of the source material for simplicity. |
33 | | * |
34 | | * That allows it to use a fixed 32KB ringbuffer to hold decodes, and |
35 | | * incrementally decode chunks into it as we want output lines that are not yet |
36 | | * present there. The input png nor the output bitmap need to be all in one |
37 | | * place at one time. |
38 | | */ |
39 | | |
40 | | #include <private-lib-core.h> |
41 | | |
42 | | #include <stdio.h> |
43 | | #include <stdlib.h> |
44 | | #include <string.h> |
45 | | #include <limits.h> |
46 | | |
47 | | static const huff_t huff_length_base[] = { |
48 | | /* the base lengths represented by codes 257-285 */ |
49 | | 3, 4, 5, 6, 7, 8, 9, 10, |
50 | | 11, 13, 15, 17, 19, 23, 27, 31, |
51 | | 35, 43, 51, 59, 67, 83, 99, 115, |
52 | | 131, 163, 195, 227, 258, 0 |
53 | | }; |
54 | | |
55 | | static const huff_t huff_length_extra[] = { |
56 | | /* the extra bits used by codes 257-285 (added to base length) */ |
57 | | 0, 0, 0, 0, 0, 0, 0, 0, |
58 | | 1, 1, 1, 1, 2, 2, 2, 2, |
59 | | 3, 3, 3, 3, 4, 4, 4, 4, |
60 | | 5, 5, 5, 5, 0, 127 |
61 | | }; |
62 | | |
63 | | static const huff_t huff_distance_base[] = { |
64 | | /* |
65 | | * The base backwards distances (the bits of distance codes appear |
66 | | * after length codes and use their own huffman tree) |
67 | | */ |
68 | | 1, 2, 3, 4, 5, 7, 9, 13, |
69 | | 17, 25, 33, 49, 65, 97, 129, 193, |
70 | | 257, 385, 513, 769, 1025, 1537, 2049, 3073, |
71 | | 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 |
72 | | }; |
73 | | |
74 | | static const huff_t huff_distance_extra[] = { |
75 | | /* the extra bits of backwards distances (added to base) */ |
76 | | 0, 0, 0, 0, 1, 1, 2, 2, |
77 | | 3, 3, 4, 4, 5, 5, 6, 6, |
78 | | 7, 7, 8, 8, 9, 9, 10, 10, |
79 | | 11, 11, 12, 12, 13, 13, 0, 0 |
80 | | }; |
81 | | |
82 | | static const huff_t huff_cl_cl[] = { |
83 | | /* |
84 | | * The order in which "code length alphabet code lengths" are stored, |
85 | | * out of this the huffman tree of the dynamic huffman tree lengths |
86 | | * is generated |
87 | | */ |
88 | | 16, 17, 18, 0, |
89 | | 8, 7, 9, 6, |
90 | | 10, 5, 11, 4, |
91 | | 12, 3, 13, 2, |
92 | | 14, 1, 15 |
93 | | }; |
94 | | |
95 | | static const huff_t FIXED_DEFLATE_CODE_TREE[NUM_DEFLATE_CODE_SYMBOLS * 2] = { |
96 | | 289, 370, |
97 | | 290, 307, |
98 | | 546, 291, |
99 | | 561, 292, |
100 | | 293, 300, |
101 | | 294, 297, |
102 | | 295, 296, |
103 | | 0, 1, |
104 | | 2, 3, |
105 | | 298, 299, |
106 | | 4, 5, 6, 7, 301, 304, 302, 303, 8, 9, 10, 11, 305, |
107 | | 306, 12, 13, 14, 15, 308, 339, 309, 324, 310, 317, 311, 314, 312, 313, |
108 | | 16, 17, 18, 19, 315, 316, 20, 21, 22, 23, 318, 321, 319, 320, 24, 25, |
109 | | 26, 27, 322, 323, 28, 29, 30, 31, 325, 332, 326, 329, 327, 328, 32, 33, |
110 | | 34, 35, 330, 331, 36, 37, 38, 39, 333, 336, 334, 335, 40, 41, 42, 43, |
111 | | 337, 338, 44, 45, 46, 47, 340, 355, 341, 348, 342, 345, 343, 344, 48, |
112 | | 49, 50, 51, 346, 347, 52, 53, 54, 55, 349, 352, 350, 351, 56, 57, 58, |
113 | | 59, 353, 354, 60, 61, 62, 63, 356, 363, 357, 360, 358, 359, 64, 65, 66, |
114 | | 67, 361, 362, 68, 69, 70, 71, 364, 367, 365, 366, 72, 73, 74, 75, 368, |
115 | | 369, 76, 77, 78, 79, 371, 434, 372, 403, 373, 388, 374, 381, 375, 378, |
116 | | 376, 377, 80, 81, 82, 83, 379, 380, 84, 85, 86, 87, 382, 385, 383, 384, |
117 | | 88, 89, 90, 91, 386, 387, 92, 93, 94, 95, 389, 396, 390, 393, 391, 392, |
118 | | 96, 97, 98, 99, 394, 395, 100, 101, 102, 103, 397, 400, 398, 399, 104, |
119 | | 105, 106, 107, 401, 402, 108, 109, 110, 111, 404, 419, 405, 412, 406, |
120 | | 409, 407, 408, 112, 113, 114, 115, 410, 411, 116, 117, 118, 119, 413, |
121 | | 416, 414, 415, 120, 121, 122, 123, 417, 418, 124, 125, 126, 127, 420, |
122 | | 427, 421, 424, 422, 423, 128, 129, 130, 131, 425, 426, 132, 133, 134, |
123 | | 135, 428, 431, 429, 430, 136, 137, 138, 139, 432, 433, 140, 141, 142, |
124 | | 143, 435, 483, 436, 452, 568, 437, 438, 445, 439, 442, 440, 441, 144, |
125 | | 145, 146, 147, 443, 444, 148, 149, 150, 151, 446, 449, 447, 448, 152, |
126 | | 153, 154, 155, 450, 451, 156, 157, 158, 159, 453, 468, 454, 461, 455, |
127 | | 458, 456, 457, 160, 161, 162, 163, 459, 460, 164, 165, 166, 167, 462, |
128 | | 465, 463, 464, 168, 169, 170, 171, 466, 467, 172, 173, 174, 175, 469, |
129 | | 476, 470, 473, 471, 472, 176, 177, 178, 179, 474, 475, 180, 181, 182, |
130 | | 183, 477, 480, 478, 479, 184, 185, 186, 187, 481, 482, 188, 189, 190, |
131 | | 191, 484, 515, 485, 500, 486, 493, 487, 490, 488, 489, 192, 193, 194, |
132 | | 195, 491, 492, 196, 197, 198, 199, 494, 497, 495, 496, 200, 201, 202, |
133 | | 203, 498, 499, 204, 205, 206, 207, 501, 508, 502, 505, 503, 504, 208, |
134 | | 209, 210, 211, 506, 507, 212, 213, 214, 215, 509, 512, 510, 511, 216, |
135 | | 217, 218, 219, 513, 514, 220, 221, 222, 223, 516, 531, 517, 524, 518, |
136 | | 521, 519, 520, 224, 225, 226, 227, 522, 523, 228, 229, 230, 231, 525, |
137 | | 528, 526, 527, 232, 233, 234, 235, 529, 530, 236, 237, 238, 239, 532, |
138 | | 539, 533, 536, 534, 535, 240, 241, 242, 243, 537, 538, 244, 245, 246, |
139 | | 247, 540, 543, 541, 542, 248, 249, 250, 251, 544, 545, 252, 253, 254, |
140 | | 255, 547, 554, 548, 551, 549, 550, 256, 257, 258, 259, 552, 553, 260, |
141 | | 261, 262, 263, 555, 558, 556, 557, 264, 265, 266, 267, 559, 560, 268, |
142 | | 269, 270, 271, 562, 565, 563, 564, 272, 273, 274, 275, 566, 567, 276, |
143 | | 277, 278, 279, 569, 572, 570, 571, 280, 281, 282, 283, 573, 574, 284, |
144 | | 285, 286, 287, 0, 0 |
145 | | }; |
146 | | |
147 | | static const huff_t FIXED_DISTANCE_TREE[NUM_DISTANCE_SYMBOLS * 2] = { |
148 | | 33, 48, 34, 41, 35, 38, 36, 37, |
149 | | 0, 1, 2, 3, 39, 40, 4, 5, |
150 | | 6, 7, 42, 45, 43, 44, 8, 9, |
151 | | 10, 11, 46, 47, 12, 13, 14, 15, |
152 | | 49, 56, 50, 53, 51, 52, 16, 17, |
153 | | 18, 19, 54, 55, 20, 21, 22, 23, |
154 | | 57, 60, 58, 59, 24, 25, 26, 27, |
155 | | 61, 62, 28, 29, 30, 31, 0, 0 |
156 | | }; |
157 | | |
158 | | static lws_stateful_ret_t |
159 | | read_bit(inflator_ctx_t *inf, uint8_t *bits) |
160 | 1.07M | { |
161 | 1.07M | size_t bo = inf->bp >> 3; |
162 | | |
163 | 1.07M | if (bo + inf->inpos >= inf->inlen) |
164 | 510 | return LWS_SRET_WANT_INPUT; |
165 | | |
166 | 1.07M | *bits = (uint8_t)((*(inf->in + inf->inpos + bo) >> (inf->bp & 7)) & 1); |
167 | | |
168 | 1.07M | inf->bp++; |
169 | | |
170 | 1.07M | return LWS_SRET_OK; |
171 | 1.07M | } |
172 | | |
173 | | /* Stateful, so it can pick up after running out of input partway thru */ |
174 | | |
175 | | static lws_stateful_ret_t |
176 | | read_bits(inflator_ctx_t *inf, unsigned int nbits, unsigned int *bits) |
177 | 57.3k | { |
178 | 57.3k | lws_stateful_ret_t r; |
179 | 57.3k | uint8_t b; |
180 | | |
181 | 57.3k | if (!inf->read_bits_ongoing) { |
182 | 57.3k | inf->read_bits_ongoing = 1; |
183 | 57.3k | inf->read_bits_shifter = 0; |
184 | 57.3k | inf->read_bits_limit = nbits; |
185 | 57.3k | inf->read_bits_i = 0; |
186 | 57.3k | } |
187 | | |
188 | 249k | while (inf->read_bits_i < inf->read_bits_limit) { |
189 | 192k | r =read_bit(inf, &b); |
190 | 192k | if (r) |
191 | 156 | return r; |
192 | | |
193 | 191k | inf->read_bits_shifter = inf->read_bits_shifter | (unsigned int)(b << inf->read_bits_i); |
194 | | |
195 | 191k | inf->read_bits_i++; |
196 | 191k | } |
197 | | |
198 | 57.1k | inf->read_bits_ongoing = 0; |
199 | 57.1k | *bits = inf->read_bits_shifter; |
200 | | |
201 | 57.1k | return LWS_SRET_OK; |
202 | 57.3k | } |
203 | | |
204 | | static lws_stateful_ret_t |
205 | | read_byte(inflator_ctx_t *inf, uint8_t *byte) |
206 | 18.6M | { |
207 | 18.6M | size_t bo; |
208 | | |
209 | 18.6M | while (inf->bp & 7) |
210 | 0 | inf->bp++; |
211 | | |
212 | 18.6M | bo = inf->bp >> 3; |
213 | | |
214 | 18.6M | if (bo + inf->inpos >= inf->inlen) |
215 | 321 | return LWS_SRET_WANT_INPUT; |
216 | | |
217 | 18.6M | *byte = *(inf->in + inf->inpos + bo); |
218 | | |
219 | 18.6M | inf->bp += 8; |
220 | | |
221 | 18.6M | return LWS_SRET_OK; |
222 | 18.6M | } |
223 | | |
224 | | /* buffer must be numcodes*2 in size! */ |
225 | | static void |
226 | | huffman_tree_init(htree_t *tree, huff_t *buffer, uint16_t numcodes, |
227 | | uint16_t maxbitlen) |
228 | 11.4k | { |
229 | 11.4k | tree->tree2d = buffer; |
230 | | |
231 | 11.4k | tree->numcodes = numcodes; |
232 | 11.4k | tree->maxbitlen = maxbitlen; |
233 | 11.4k | } |
234 | | |
235 | 4.71M | #define EMPTY 32767 |
236 | | |
237 | | /* |
238 | | * Given the code lengths (as stored in the PNG file), generate the tree as |
239 | | * defined by Deflate. maxbitlen is the maximum bits that a code in the tree |
240 | | * can have. |
241 | | */ |
242 | | static lws_stateful_ret_t |
243 | | huffman_tree_create_lengths(htree_t *tree, const unsigned *bitlen) |
244 | 8.26k | { |
245 | 8.26k | unsigned int tree1d[NUM_DEFLATE_CODE_SYMBOLS], /* sized to worst */ |
246 | 8.26k | blcount[NUM_DEFLATE_CODE_SYMBOLS], /* sized to worst */ |
247 | 8.26k | nextcode[MAX_BIT_LENGTH + 1], bits, n, i, |
248 | 8.26k | nodefilled = 0, treepos = 0; |
249 | | |
250 | 8.26k | memset(blcount, 0, sizeof(blcount)); |
251 | 8.26k | memset(nextcode, 0, sizeof(nextcode)); |
252 | | |
253 | 8.26k | assert(tree->numcodes <= LWS_ARRAY_SIZE(blcount)); |
254 | | |
255 | 918k | for (bits = 0; bits < tree->numcodes; bits++) { |
256 | | /* any counts exceeding our private buffer length are fatal */ |
257 | 910k | if (bitlen[bits] >= LWS_ARRAY_SIZE(blcount)) |
258 | 0 | return LWS_SRET_FATAL + 1; |
259 | | |
260 | 910k | blcount[bitlen[bits]]++; |
261 | 910k | } |
262 | | |
263 | 8.26k | assert(tree->maxbitlen && tree->maxbitlen - 1u <= LWS_ARRAY_SIZE(blcount)); |
264 | 8.26k | assert(tree->maxbitlen - 1u <= LWS_ARRAY_SIZE(nextcode)); |
265 | | |
266 | 108k | for (bits = 1; bits <= (unsigned int)tree->maxbitlen; bits++) |
267 | 100k | nextcode[bits] = (nextcode[bits - 1] + blcount[bits - 1]) << 1; |
268 | | |
269 | 8.26k | assert(tree->numcodes <= LWS_ARRAY_SIZE(tree1d)); |
270 | | |
271 | 918k | for (n = 0; n < tree->numcodes; n++) |
272 | 910k | if (bitlen[n]) |
273 | 142k | tree1d[n] = nextcode[bitlen[n]]++; |
274 | | |
275 | 1.82M | for (n = 0; n < (unsigned int)tree->numcodes * 2u; n++) |
276 | 1.82M | tree->tree2d[n] = EMPTY; |
277 | | |
278 | 916k | for (n = 0; n < tree->numcodes; n++) { /* the codes */ |
279 | 1.98M | for (i = 0; i < bitlen[n]; i++) { /* the bits for this code */ |
280 | 1.07M | uint8_t bit = (uint8_t)((tree1d[n] >> |
281 | 1.07M | (bitlen[n] - i - 1)) & 1); |
282 | | |
283 | | /* check if oversubscribed */ |
284 | 1.07M | if (treepos > tree->numcodes - 2u) |
285 | 40 | return LWS_SRET_FATAL + 1; |
286 | | |
287 | 1.07M | if (tree->tree2d[2 * treepos + bit] == EMPTY) { |
288 | 303k | if (i + 1 == bitlen[n]) { /* ... last bit */ |
289 | 141k | tree->tree2d[2 * treepos + bit] = (huff_t)n; |
290 | 141k | treepos = 0; |
291 | 162k | } else { |
292 | 162k | nodefilled++; |
293 | 162k | tree->tree2d[2 * treepos + bit] = |
294 | 162k | (huff_t)(nodefilled + tree->numcodes); |
295 | 162k | treepos = nodefilled; |
296 | 162k | } |
297 | 303k | } else |
298 | 769k | treepos = (unsigned int)(tree->tree2d[2 * treepos + bit] - |
299 | 769k | tree->numcodes); |
300 | 1.07M | } |
301 | 908k | } |
302 | | |
303 | 1.82M | for (n = 0; n < tree->numcodes * 2u; n++) |
304 | 1.81M | if (tree->tree2d[n] == EMPTY) |
305 | 1.50M | tree->tree2d[n] = 0; |
306 | | |
307 | 8.22k | return LWS_SRET_OK; |
308 | 8.26k | } |
309 | | |
310 | | |
311 | | |
312 | | static lws_stateful_ret_t |
313 | | huffman_decode_symbol(inflator_ctx_t *inf, const htree_t *ct, unsigned int *uct) |
314 | 288k | { |
315 | 288k | lws_stateful_ret_t r; |
316 | 288k | uint8_t bit; |
317 | | |
318 | 863k | do { |
319 | 863k | r = read_bit(inf, &bit); |
320 | 863k | if (r) |
321 | 321 | return r; |
322 | | |
323 | 863k | *uct = ct->tree2d[(inf->treepos << 1) | bit]; |
324 | 863k | if (*uct < ct->numcodes) |
325 | 288k | return LWS_SRET_OK; |
326 | | |
327 | 574k | inf->treepos = *uct - ct->numcodes; |
328 | 574k | if (inf->treepos >= ct->numcodes) |
329 | 0 | return LWS_SRET_FATAL + 2; |
330 | 574k | } while (1); |
331 | 288k | } |
332 | | |
333 | | lws_stateful_ret_t |
334 | | _lws_upng_inflate_data(inflator_ctx_t *inf) |
335 | 1.15k | { |
336 | 1.15k | unsigned int count, val, tu; |
337 | 1.15k | uint8_t t, done = 0; |
338 | 1.15k | lws_stateful_ret_t r; |
339 | 1.15k | size_t virt; |
340 | | |
341 | 19.3M | while (!done) { |
342 | 19.3M | switch (inf->state) { |
343 | 5.50k | case UPNS_ID_BL_GB_DONE: |
344 | 5.50k | r = read_bit(inf, &inf->done); |
345 | 5.50k | if (r) |
346 | 29 | return r; |
347 | 5.48k | inf->state++; |
348 | | |
349 | | /* fallthru */ |
350 | 5.48k | case UPNS_ID_BL_GB_BTYPEb0: |
351 | 5.48k | r = read_bit(inf, &inf->btype); |
352 | 5.48k | if (r) |
353 | 1 | return r; |
354 | 5.47k | inf->state++; |
355 | | |
356 | | /* fallthru */ |
357 | 5.47k | case UPNS_ID_BL_GB_BTYPEb1: |
358 | 5.47k | r = read_bit(inf, &t); |
359 | 5.47k | if (r) |
360 | 3 | return r; |
361 | | |
362 | 5.47k | inf->btype |= (uint8_t)(t << 1); |
363 | | |
364 | 5.47k | if (inf->btype == 3) |
365 | 13 | return LWS_SRET_FATAL + 3; |
366 | | |
367 | 5.46k | inf->i = 0; |
368 | | |
369 | 5.46k | inf->state = UPNS_ID_BL_GB_BTYPE_0 + inf->btype; |
370 | | |
371 | 5.46k | lwsl_debug("%s: (%lu) block type %d\n", __func__, |
372 | 5.46k | (unsigned long)inf->archive_pos + (inf->bp >> 3), |
373 | 5.46k | inf->btype); |
374 | | |
375 | | /* uncompressed starts on a byte boundary */ |
376 | | |
377 | 5.46k | if (!inf->btype && (inf->bp & 7)) { |
378 | 1.01k | lwsl_debug("%s: skipping %d alignment bits for type 0\n", |
379 | 1.01k | __func__, (int)(8 - (inf->bp & 7)) & 7); |
380 | 1.01k | inf->bp = ((inf->bp >> 3) + 1) << 3; |
381 | 1.01k | } |
382 | 5.46k | continue; |
383 | | |
384 | 1.25k | case UPNS_ID_BL_GB_BTYPE_0: /* no compression */ |
385 | 1.25k | r = read_byte(inf, &t); |
386 | 1.25k | if (r) |
387 | 25 | return r; |
388 | | |
389 | 1.22k | inf->len = t; |
390 | 1.22k | inf->state = UPNS_ID_BL_GB_BTYPE_0a; |
391 | | |
392 | | // lwsl_notice("%s: no compression block\n", __func__); |
393 | | |
394 | | /* fallthru */ |
395 | 1.22k | case UPNS_ID_BL_GB_BTYPE_0a: |
396 | 1.22k | r = read_byte(inf, &t); |
397 | 1.22k | if (r) |
398 | 22 | return r; |
399 | | |
400 | 1.20k | inf->len = inf->len | (unsigned int)(t << 8); |
401 | 1.20k | inf->state++; |
402 | | /* fallthru */ |
403 | | |
404 | 1.20k | case UPNS_ID_BL_GB_BTYPE_0b: |
405 | 1.20k | r = read_byte(inf, &t); |
406 | 1.20k | if (r) |
407 | 23 | return r; |
408 | | |
409 | 1.18k | inf->nlen = t; |
410 | 1.18k | inf->state++; |
411 | | |
412 | | /* fallthru */ |
413 | 1.18k | case UPNS_ID_BL_GB_BTYPE_0c: |
414 | 1.18k | r = read_byte(inf, &t); |
415 | 1.18k | if (r) |
416 | 19 | return r; |
417 | | |
418 | 1.16k | inf->nlen = inf->nlen | (unsigned int)(t << 8); |
419 | | |
420 | 1.16k | if (inf->len + inf->nlen != 65535) |
421 | 94 | return LWS_SRET_FATAL + 4; |
422 | | |
423 | 1.07k | lwsl_debug("%s: type 0 expects len %d\n", __func__, inf->len); |
424 | | |
425 | 1.07k | inf->state++; |
426 | 1.07k | inf->n = 0; |
427 | | |
428 | | /* fallthru */ |
429 | 35.7k | case UPNS_ID_BL_GB_BTYPE_0d: |
430 | | |
431 | 35.7k | if (inf->n < inf->len) { |
432 | | |
433 | 34.7k | r = read_byte(inf, &t); |
434 | 34.7k | if (r) |
435 | 55 | return r; |
436 | | |
437 | 34.7k | inf->out[inf->outpos++] = t; |
438 | 34.7k | if (inf->outpos >= inf->outlen) |
439 | 0 | inf->outpos = 0; |
440 | 34.7k | inf->outpos_linear++; |
441 | 34.7k | inf->n++; |
442 | | |
443 | 34.7k | if (inf->outpos_linear - inf->consumed_linear >= |
444 | 34.7k | inf->bypl + 1) { |
445 | 2 | return LWS_SRET_WANT_OUTPUT; |
446 | 2 | } |
447 | | |
448 | 34.7k | continue; |
449 | 34.7k | } |
450 | | |
451 | 1.01k | inf->treepos = 0; |
452 | 1.01k | inf->state = UPNS_ID_BL_GB_DONE; |
453 | 1.01k | continue; |
454 | | |
455 | 1.20k | case UPNS_ID_BL_GB_BTYPE_1: /* fixed trees */ |
456 | | |
457 | 1.20k | huffman_tree_init(&inf->ct, |
458 | 1.20k | (huff_t *)FIXED_DEFLATE_CODE_TREE, |
459 | 1.20k | NUM_DEFLATE_CODE_SYMBOLS, |
460 | 1.20k | DEFLATE_CODE_BITLEN); |
461 | 1.20k | huffman_tree_init(&inf->ctD, |
462 | 1.20k | (huff_t *)FIXED_DISTANCE_TREE, |
463 | 1.20k | NUM_DISTANCE_SYMBOLS, |
464 | 1.20k | DISTANCE_BITLEN); |
465 | | |
466 | 1.20k | lwsl_debug("%s: fixed tree init\n", __func__); |
467 | 1.20k | inf->treepos = 0; |
468 | 1.20k | inf->state = UPNS_ID_BL_GB_SPIN; |
469 | 1.20k | continue; |
470 | | |
471 | 3.01k | case UPNS_ID_BL_GB_BTYPE_2: /* dynamic trees */ |
472 | 3.01k | huffman_tree_init(&inf->ct, inf->ct_buffer, |
473 | 3.01k | NUM_DEFLATE_CODE_SYMBOLS, |
474 | 3.01k | DEFLATE_CODE_BITLEN); |
475 | 3.01k | huffman_tree_init(&inf->ctD, inf->ctD_buffer, |
476 | 3.01k | NUM_DISTANCE_SYMBOLS, |
477 | 3.01k | DISTANCE_BITLEN); |
478 | 3.01k | huffman_tree_init(&inf->clct, inf->clct_buffer, |
479 | 3.01k | NUM_CODE_LENGTH_CODES, |
480 | 3.01k | CODE_LENGTH_BITLEN); |
481 | | |
482 | | // lwsl_notice("%s: dyn tree init\n", __func__); |
483 | 3.01k | inf->treepos = 0; |
484 | | |
485 | | /* clear bitlen arrays */ |
486 | 3.01k | memset(inf->bitlen, 0, sizeof(inf->bitlen)); |
487 | 3.01k | memset(inf->bitlenD, 0, sizeof(inf->bitlenD)); |
488 | | |
489 | 3.01k | inf->state = UPNS_ID_BL_GB_BTYPE_2a; |
490 | | |
491 | 3.01k | inf->hlit = 0; |
492 | 3.01k | inf->hdist = 0; |
493 | 3.01k | inf->hclen = 0; |
494 | | |
495 | | /* fallthru */ |
496 | | |
497 | 3.01k | case UPNS_ID_BL_GB_BTYPE_2a: |
498 | 3.01k | r = read_bits(inf, 5, &inf->hlit); |
499 | 3.01k | if (r) |
500 | 7 | return r; |
501 | 3.00k | inf->hlit += 257; |
502 | 3.00k | inf->state++; |
503 | | |
504 | | /* fallthru */ |
505 | 3.00k | case UPNS_ID_BL_GB_BTYPE_2b: |
506 | 3.00k | r = read_bits(inf, 5, &inf->hdist); |
507 | 3.00k | if (r) |
508 | 16 | return r; |
509 | 2.98k | inf->hdist++; |
510 | 2.98k | inf->state++; |
511 | | |
512 | | /* fallthru */ |
513 | 2.98k | case UPNS_ID_BL_GB_BTYPE_2c: |
514 | 2.98k | r = read_bits(inf, 4, &inf->hclen); |
515 | 2.98k | if (r) |
516 | 16 | return r; |
517 | 2.97k | inf->hclen += 4; |
518 | 2.97k | inf->state = UPNS_ID_BL_GB_BTYPE_2d; |
519 | 2.97k | inf->i = 0; |
520 | | |
521 | | /* fallthru */ |
522 | 58.8k | case UPNS_ID_BL_GB_BTYPE_2d: |
523 | 58.8k | if (inf->i < NUM_CODE_LENGTH_CODES) { |
524 | 55.9k | if (inf->i < inf->hclen) { |
525 | 17.4k | r = read_bits(inf, 3, |
526 | 17.4k | &inf->clenc[huff_cl_cl[inf->i]]); |
527 | 17.4k | if (r) |
528 | 35 | return r; |
529 | 17.4k | } else |
530 | | /*if not, it must stay 0 */ |
531 | 38.4k | inf->clenc[huff_cl_cl[inf->i]] = 0; |
532 | | |
533 | 55.9k | inf->i++; |
534 | 55.9k | continue; |
535 | 55.9k | } |
536 | | |
537 | 2.93k | r = huffman_tree_create_lengths(&inf->clct, inf->clenc); |
538 | 2.93k | if (r) |
539 | 25 | return r; |
540 | | |
541 | 2.91k | inf->i = 0; |
542 | 2.91k | inf->state = UPNS_ID_BL_GB_BTYPE_2e; |
543 | 2.91k | inf->treepos = 0; |
544 | | |
545 | | /* fallthru */ |
546 | 181k | case UPNS_ID_BL_GB_BTYPE_2e: |
547 | | |
548 | 181k | if (inf->i >= inf->hlit + inf->hdist) { |
549 | 2.69k | if (inf->bitlen[256] == 0) |
550 | 20 | return LWS_SRET_FATAL + 6; |
551 | | |
552 | 2.67k | if (huffman_tree_create_lengths(&inf->ct, |
553 | 2.67k | inf->bitlen)) |
554 | 12 | return LWS_SRET_FATAL + 7; |
555 | | |
556 | 2.65k | if (huffman_tree_create_lengths(&inf->ctD, |
557 | 2.65k | inf->bitlenD)) |
558 | 3 | return LWS_SRET_FATAL + 8; |
559 | | |
560 | 2.65k | inf->treepos = 0; |
561 | 2.65k | inf->state = UPNS_ID_BL_GB_SPIN; |
562 | 2.65k | continue; |
563 | 2.65k | } |
564 | | |
565 | 178k | r = huffman_decode_symbol(inf, &inf->clct, &inf->code); |
566 | 178k | if (r) |
567 | 113 | return r; |
568 | | |
569 | 178k | switch (inf->code) { |
570 | 5.36k | case 16: |
571 | 5.36k | inf->state = UPNS_ID_BL_GB_BTYPE_2_16; |
572 | 5.36k | continue; |
573 | 9.57k | case 17: |
574 | 9.57k | inf->state = UPNS_ID_BL_GB_BTYPE_2_17; |
575 | 9.57k | continue; |
576 | 5.00k | case 18: |
577 | 5.00k | inf->state = UPNS_ID_BL_GB_BTYPE_2_18; |
578 | 5.00k | continue; |
579 | 158k | default: |
580 | 158k | if (inf->code > 15) |
581 | 0 | return LWS_SRET_FATAL + 9; |
582 | | |
583 | 158k | if (inf->i < inf->hlit) |
584 | 119k | inf->bitlen[inf->i] = inf->code; |
585 | 39.5k | else |
586 | 39.5k | inf->bitlenD[inf->i - inf->hlit] = |
587 | 39.5k | inf->code; |
588 | | |
589 | 158k | inf->i++; |
590 | 158k | inf->treepos = 0; |
591 | | |
592 | | /* stay in 2e */ |
593 | 158k | continue; |
594 | 178k | } |
595 | | |
596 | 5.36k | case UPNS_ID_BL_GB_BTYPE_2_16: /* repeat previous */ |
597 | 5.36k | r = read_bits(inf, 2, &tu); |
598 | 5.36k | if (r) |
599 | 13 | return r; |
600 | 5.34k | count = tu + 3; |
601 | | |
602 | 5.34k | if (!inf->i) /* from google fuzzer */ |
603 | 4 | return LWS_SRET_FATAL + 29; |
604 | | |
605 | 5.34k | if (inf->i - 1 < inf->hlit) |
606 | 4.47k | val = inf->bitlen[inf->i - 1]; |
607 | 868 | else |
608 | 868 | val = inf->bitlenD[inf->i - inf->hlit - 1]; |
609 | | |
610 | 5.34k | goto fill; |
611 | | |
612 | 9.57k | case UPNS_ID_BL_GB_BTYPE_2_17: /*repeat "0" 3-10 times */ |
613 | 9.57k | r = read_bits(inf, 3, &tu); |
614 | 9.57k | if (r) |
615 | 20 | return r; |
616 | 9.55k | count = tu + 3; |
617 | | |
618 | 9.55k | val = 0; |
619 | 9.55k | goto fill; |
620 | | |
621 | 5.00k | case UPNS_ID_BL_GB_BTYPE_2_18: /*repeat "0" 11-138 times */ |
622 | 5.00k | r = read_bits(inf, 7, &tu); |
623 | 5.00k | if (r) |
624 | 29 | return r; |
625 | 4.97k | count = tu + 11; |
626 | 4.97k | val = 0; |
627 | 19.8k | fill: |
628 | | |
629 | 19.8k | if (inf->i + count > inf->hlit + inf->hdist) { |
630 | 41 | lwsl_err("%s: inf->i (%d) > %d\n", __func__, |
631 | 41 | inf->i + count, inf->hlit + inf->hdist); |
632 | 41 | return LWS_SRET_FATAL + 10; |
633 | 41 | } |
634 | | |
635 | 19.8k | { |
636 | 19.8k | unsigned int n; |
637 | | |
638 | 649k | for (n = 0; n < count; n++) { |
639 | | |
640 | 629k | if (inf->i < inf->hlit) |
641 | 618k | inf->bitlen[inf->i] = val; |
642 | 10.4k | else |
643 | 10.4k | inf->bitlenD[inf->i - inf->hlit] = val; |
644 | | |
645 | 629k | inf->i++; |
646 | 629k | } |
647 | 19.8k | } |
648 | 19.8k | inf->state = UPNS_ID_BL_GB_BTYPE_2e; |
649 | 19.8k | inf->treepos = 0; |
650 | 19.8k | continue; |
651 | | |
652 | | |
653 | 104k | case UPNS_ID_BL_GB_SPIN: |
654 | | |
655 | 104k | r = huffman_decode_symbol(inf, &inf->ct, &inf->code); |
656 | 104k | if (r) |
657 | 172 | return r; |
658 | | |
659 | 104k | if (inf->code >= FIRST_LENGTH_CODE_INDEX && |
660 | 104k | inf->code - FIRST_LENGTH_CODE_INDEX < |
661 | 7.54k | LWS_ARRAY_SIZE(huff_length_base)) |
662 | 6.50k | inf->length = huff_length_base[inf->code - |
663 | 6.50k | FIRST_LENGTH_CODE_INDEX]; |
664 | 97.7k | else |
665 | 97.7k | inf->length = 0; |
666 | | |
667 | 104k | if (inf->code == 256) { |
668 | | /* |
669 | | * We're finished with this huffman block, we |
670 | | * need to go back up a level |
671 | | */ |
672 | 3.60k | done = inf->done; |
673 | 3.60k | inf->state = UPNS_ID_BL_GB_DONE; |
674 | 3.60k | continue; |
675 | 3.60k | } |
676 | | |
677 | 100k | if (inf->code <= 255) { |
678 | 93.0k | inf->state = UPNS_ID_BL_GB_SPINa; |
679 | 93.0k | continue; |
680 | 93.0k | } |
681 | | |
682 | 7.54k | if (inf->code < FIRST_LENGTH_CODE_INDEX || |
683 | 7.54k | inf->code > LAST_LENGTH_CODE_INDEX) { |
684 | 2.06k | inf->treepos = 0; |
685 | 2.06k | continue; |
686 | 2.06k | } |
687 | | |
688 | 5.47k | inf->exbits = huff_length_extra[inf->code - |
689 | 5.47k | FIRST_LENGTH_CODE_INDEX]; |
690 | 5.47k | inf->state = UPNS_ID_BL_GB_SPINb; |
691 | | |
692 | | /* fallthru */ |
693 | 5.47k | case UPNS_ID_BL_GB_SPINb: |
694 | 5.47k | r = read_bits(inf, (unsigned int)inf->exbits, &tu); |
695 | 5.47k | if (r) |
696 | 5 | return r; |
697 | | |
698 | 5.47k | inf->length += tu; |
699 | 5.47k | inf->state++; |
700 | 5.47k | inf->treepos = 0; |
701 | | |
702 | | /* fallthru */ |
703 | 5.47k | case UPNS_ID_BL_GB_SPINc: |
704 | | |
705 | | /* part 3: get distance code */ |
706 | | |
707 | 5.47k | r = huffman_decode_symbol(inf, &inf->ctD, &inf->codeD); |
708 | 5.47k | if (r) |
709 | 36 | return r; |
710 | | |
711 | | /* invalid distance code (30-31 are never used) */ |
712 | 5.43k | if (inf->codeD > 29) { |
713 | 6 | lwsl_err("%s: invalid dist %d\n", __func__, inf->codeD); |
714 | 6 | return LWS_SRET_FATAL + 11; |
715 | 6 | } |
716 | | |
717 | 5.42k | inf->distance = huff_distance_base[inf->codeD]; |
718 | | |
719 | | /* part 4: get extra bits from distance */ |
720 | | |
721 | 5.42k | inf->exbitsD = huff_distance_extra[inf->codeD]; |
722 | 5.42k | inf->state++; |
723 | | |
724 | | /* fallthru */ |
725 | 5.42k | case UPNS_ID_BL_GB_SPINd: |
726 | | |
727 | 5.42k | r = read_bits(inf, inf->exbitsD, &tu); |
728 | 5.42k | if (r) |
729 | 15 | return r; |
730 | | |
731 | 5.41k | inf->distance += tu; |
732 | | |
733 | 5.41k | if (inf->distance > inf->info_size) { |
734 | 0 | lwsl_err("%s: distance %lu\n", __func__, |
735 | 0 | (unsigned long)inf->distance); |
736 | 0 | assert(0); |
737 | 0 | } |
738 | | |
739 | | /* |
740 | | * Part 5: fill in all the out[n] values based |
741 | | * on the length and dist |
742 | | */ |
743 | 5.41k | inf->start = inf->outpos; |
744 | 5.41k | inf->forward = 0; |
745 | 5.41k | inf->backward = inf->distance; /* from inf->start */ |
746 | | |
747 | 5.41k | inf->state++; |
748 | | |
749 | | /* fallthru */ |
750 | 181k | case UPNS_ID_BL_GB_SPINe: |
751 | | |
752 | 181k | if (inf->forward >= inf->length) { |
753 | 5.39k | inf->treepos = 0; |
754 | 5.39k | inf->state = UPNS_ID_BL_GB_SPIN; |
755 | 5.39k | continue; |
756 | 5.39k | } |
757 | | |
758 | 176k | if (inf->backward <= inf->start) |
759 | 144k | virt = inf->start - inf->backward; |
760 | 31.8k | else /* wrapped... backward >= start */ |
761 | 31.8k | virt = inf->info_size - |
762 | 31.8k | (inf->backward - inf->start); |
763 | | |
764 | 176k | if (virt >= inf->info_size) |
765 | 0 | lwsl_err("virt %d\n", (int)virt); |
766 | | |
767 | 176k | inf->out[inf->outpos++] = inf->out[virt]; |
768 | 176k | if (inf->outpos >= inf->outlen) |
769 | 0 | inf->outpos = 0; |
770 | | |
771 | 176k | inf->outpos_linear++; |
772 | 176k | inf->backward--; |
773 | | |
774 | 176k | if (!inf->backward) |
775 | 77.5k | inf->backward = inf->distance; |
776 | | |
777 | 176k | inf->forward++; |
778 | | |
779 | 176k | if (inf->outpos_linear - inf->consumed_linear >= |
780 | 176k | inf->bypl + 1) |
781 | 15 | return LWS_SRET_WANT_OUTPUT; |
782 | | |
783 | 176k | continue; |
784 | | |
785 | 176k | case UPNS_ID_BL_GB_SPINa: |
786 | | |
787 | 93.0k | inf->out[inf->outpos++] = (uint8_t)inf->code; |
788 | 93.0k | if (inf->outpos >= inf->outlen) |
789 | 0 | inf->outpos = 0; |
790 | | |
791 | 93.0k | inf->outpos_linear++; |
792 | 93.0k | inf->treepos = 0; |
793 | 93.0k | inf->state = UPNS_ID_BL_GB_SPIN; |
794 | | |
795 | 93.0k | if (inf->outpos_linear - inf->consumed_linear >= |
796 | 93.0k | inf->bypl + 1) |
797 | 5 | return LWS_SRET_WANT_OUTPUT; |
798 | | |
799 | 93.0k | continue; |
800 | | |
801 | | |
802 | 93.0k | case UPNS_ID_BL_GB_GZIP_ID1: |
803 | 1.15k | r = read_byte(inf, &t); |
804 | 1.15k | if (r) |
805 | 30 | return r; |
806 | 1.12k | if (t != 0x1f) |
807 | 53 | return LWS_SRET_FATAL + 32; |
808 | 1.07k | inf->state++; |
809 | | |
810 | | /* fallthru */ |
811 | | |
812 | 1.07k | case UPNS_ID_BL_GB_GZIP_ID2: |
813 | 1.07k | r = read_byte(inf, &t); |
814 | 1.07k | if (r) |
815 | 1 | return r; |
816 | 1.07k | if (t != 0x8b) |
817 | 12 | return LWS_SRET_FATAL + 33; |
818 | 1.06k | inf->state++; |
819 | | |
820 | | /* fallthru */ |
821 | | |
822 | 1.06k | case UPNS_ID_BL_GB_GZIP_METHOD: |
823 | 1.06k | r = read_byte(inf, &t); |
824 | 1.06k | if (r) |
825 | 1 | return r; |
826 | 1.06k | if (t != 8) |
827 | 13 | return LWS_SRET_FATAL + 34; |
828 | 1.04k | inf->state++; |
829 | | |
830 | | /* fallthru */ |
831 | | |
832 | 1.04k | case UPNS_ID_BL_GB_GZIP_FLAGS: |
833 | 1.04k | r = read_byte(inf, &t); |
834 | 1.04k | if (r) |
835 | 1 | return r; |
836 | 1.04k | if (t & 0xe0) |
837 | 5 | return LWS_SRET_FATAL + 35; |
838 | 1.04k | inf->gz_flags = t; |
839 | 1.04k | inf->state++; |
840 | 1.04k | inf->ctr = 6; |
841 | | |
842 | | /* fallthru */ |
843 | | |
844 | 7.23k | case UPNS_ID_BL_GB_GZIP_EOH: |
845 | | /* we want skip 6 bytes */ |
846 | 7.23k | if (inf->ctr--) { |
847 | 6.20k | r = read_byte(inf, &t); |
848 | 6.20k | if (r) |
849 | 11 | return r; |
850 | | |
851 | 6.19k | continue; |
852 | 6.20k | } |
853 | | |
854 | 1.03k | if (inf->gz_flags & 4) |
855 | 261 | inf->state = UPNS_ID_BL_GB_GZIP_SKIP_EXTRA_C1; |
856 | 770 | else |
857 | 770 | if (inf->gz_flags & 8) |
858 | 69 | inf->state = UPNS_ID_BL_GB_GZIP_SKIP_FILENAME; |
859 | 701 | else |
860 | 701 | if (inf->gz_flags & 16) |
861 | 39 | inf->state = UPNS_ID_BL_GB_GZIP_SKIP_COMMENT; |
862 | 662 | else |
863 | 662 | if (inf->gz_flags & 2) { |
864 | 4 | inf->state = UPNS_ID_BL_GB_GZIP_SKIP_CRC; |
865 | 4 | inf->ctr = 2; |
866 | 4 | } else |
867 | 658 | inf->state = UPNS_ID_BL_GB_DONE; |
868 | | |
869 | 1.03k | continue; |
870 | | |
871 | 261 | case UPNS_ID_BL_GB_GZIP_SKIP_EXTRA_C1: |
872 | 261 | r = read_byte(inf, &t); |
873 | 261 | if (r) |
874 | 1 | return r; |
875 | | |
876 | 260 | inf->ctr = t; |
877 | | |
878 | 260 | inf->state++; |
879 | | |
880 | | /* fallthru */ |
881 | | |
882 | 260 | case UPNS_ID_BL_GB_GZIP_SKIP_EXTRA_C2: |
883 | 260 | r = read_byte(inf, &t); |
884 | 260 | if (r) |
885 | 1 | return r; |
886 | | |
887 | 259 | inf->ctr = (uint16_t)(inf->ctr | (t << 8)); |
888 | | |
889 | 259 | inf->state++; |
890 | | |
891 | | /* fallthru */ |
892 | | |
893 | 1.68M | case UPNS_ID_BL_GB_GZIP_SKIP_EXTRA: |
894 | 1.68M | if (inf->ctr--) { |
895 | 1.68M | r = read_byte(inf, &t); |
896 | 1.68M | if (r) |
897 | 50 | return r; |
898 | | |
899 | 1.67M | continue; |
900 | 1.68M | } |
901 | | |
902 | 209 | if (inf->gz_flags & 8) |
903 | 186 | inf->state = UPNS_ID_BL_GB_GZIP_SKIP_FILENAME; |
904 | 23 | else |
905 | 23 | if (inf->gz_flags & 16) |
906 | 12 | inf->state = UPNS_ID_BL_GB_GZIP_SKIP_COMMENT; |
907 | 11 | else |
908 | 11 | if (inf->gz_flags & 2) { |
909 | 4 | inf->state = UPNS_ID_BL_GB_GZIP_SKIP_CRC; |
910 | 4 | inf->ctr = 2; |
911 | 4 | } else |
912 | 7 | inf->state = UPNS_ID_BL_GB_DONE; |
913 | | |
914 | 209 | continue; |
915 | | |
916 | 11.6M | case UPNS_ID_BL_GB_GZIP_SKIP_FILENAME: /* zero-terminated */ |
917 | 11.6M | r = read_byte(inf, &t); |
918 | 11.6M | if (r) |
919 | 34 | return r; |
920 | | |
921 | 11.6M | if (t) |
922 | 11.6M | continue; |
923 | | |
924 | 221 | if (inf->gz_flags & 16) |
925 | 182 | inf->state = UPNS_ID_BL_GB_GZIP_SKIP_COMMENT; |
926 | 39 | else |
927 | 39 | if (inf->gz_flags & 2) { |
928 | 10 | inf->state = UPNS_ID_BL_GB_GZIP_SKIP_CRC; |
929 | 10 | inf->ctr = 2; |
930 | 10 | } else |
931 | 29 | inf->state = UPNS_ID_BL_GB_DONE; |
932 | | |
933 | 221 | continue; |
934 | | |
935 | 5.27M | case UPNS_ID_BL_GB_GZIP_SKIP_COMMENT: /* zero-terminated */ |
936 | 5.27M | r = read_byte(inf, &t); |
937 | 5.27M | if (r) |
938 | 40 | return r; |
939 | | |
940 | 5.27M | if (t) |
941 | 5.27M | continue; |
942 | | |
943 | 193 | if (inf->gz_flags & 2) { |
944 | 174 | inf->state = UPNS_ID_BL_GB_GZIP_SKIP_CRC; |
945 | 174 | inf->ctr = 2; |
946 | 174 | } |
947 | 19 | else |
948 | 19 | inf->state = UPNS_ID_BL_GB_DONE; |
949 | | |
950 | 193 | continue; |
951 | | |
952 | 564 | case UPNS_ID_BL_GB_GZIP_SKIP_CRC: |
953 | 564 | if (inf->ctr--) { |
954 | 379 | r = read_byte(inf, &t); |
955 | 379 | if (r) |
956 | 7 | return r; |
957 | | |
958 | 372 | continue; |
959 | 379 | } |
960 | 185 | inf->state = UPNS_ID_BL_GB_DONE; |
961 | 185 | continue; |
962 | 19.3M | } |
963 | 19.3M | } |
964 | | |
965 | 4 | return LWS_SRET_OK; |
966 | 1.15k | } |
967 | | |
968 | | struct inflator_ctx * |
969 | | lws_upng_inflator_create(const uint8_t **outring, size_t *outringlen, |
970 | | size_t **opl, size_t **cl) |
971 | 1.15k | { |
972 | 1.15k | inflator_ctx_t *inf = lws_zalloc(sizeof(*inf), __func__); |
973 | | |
974 | 1.15k | if (!inf) { |
975 | 0 | lwsl_notice("%s: OOM\n", __func__); |
976 | |
|
977 | 0 | return NULL; |
978 | 0 | } |
979 | | |
980 | | /* 32KB gz sliding window */ |
981 | 1.15k | inf->info_size = 32768; |
982 | 1.15k | inf->bypl = 0; |
983 | 1.15k | inf->outlen = inf->info_size; |
984 | 1.15k | inf->outpos = 0; |
985 | 1.15k | inf->state = UPNS_ID_BL_GB_GZIP_ID1; |
986 | | |
987 | 1.15k | inf->out = (uint8_t *)lws_malloc(inf->info_size, __func__); |
988 | 1.15k | if (!inf->out) { |
989 | 0 | lwsl_notice("%s: inf malloc %u OOM\n", |
990 | 0 | __func__, (unsigned int)inf->info_size); |
991 | |
|
992 | 0 | lws_free(inf); |
993 | |
|
994 | 0 | return NULL; |
995 | 0 | } |
996 | | |
997 | 1.15k | *outring = inf->out; |
998 | 1.15k | *outringlen = inf->info_size; |
999 | 1.15k | *opl = &inf->outpos_linear; |
1000 | 1.15k | *cl = &inf->consumed_linear; |
1001 | | |
1002 | 1.15k | return inf; |
1003 | 1.15k | } |
1004 | | |
1005 | | lws_stateful_ret_t |
1006 | | lws_upng_inflate_data(struct inflator_ctx *inf, const void *buf, size_t len) |
1007 | 1.15k | { |
1008 | 1.15k | lws_stateful_ret_t r; |
1009 | | |
1010 | 1.15k | if (buf) { |
1011 | 1.15k | inf->in = buf; |
1012 | 1.15k | inf->inlen = len; |
1013 | 1.15k | inf->inpos = 0; |
1014 | 1.15k | inf->bp = 0; |
1015 | 1.15k | } |
1016 | | |
1017 | 1.15k | if (!inf->bypl) |
1018 | 1.15k | inf->bypl = 4095; |
1019 | | |
1020 | 1.15k | r = _lws_upng_inflate_data(inf); |
1021 | | |
1022 | 1.15k | if ((inf->bp >> 3) == inf->inlen) { |
1023 | 925 | inf->archive_pos += inf->inlen; |
1024 | 925 | inf->inlen = 0; |
1025 | 925 | inf->bp = 0; |
1026 | 925 | } |
1027 | | |
1028 | 1.15k | return r; |
1029 | 1.15k | } |
1030 | | |
1031 | | void |
1032 | | lws_upng_inflator_destroy(struct inflator_ctx **inf) |
1033 | 1.15k | { |
1034 | 1.15k | lws_free_set_NULL((*inf)->out); |
1035 | 1.15k | lws_free_set_NULL(*inf); |
1036 | 1.15k | } |
1037 | | |
1038 | | |