/src/ghostpdl/jbig2dec/jbig2_mmr.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2023 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | /* |
17 | | jbig2dec |
18 | | */ |
19 | | |
20 | | /* An implementation of MMR decoding. This is based on the |
21 | | implementation in Fitz, which in turn is based on the one |
22 | | in Ghostscript. |
23 | | */ |
24 | | |
25 | | #ifdef HAVE_CONFIG_H |
26 | | #include "config.h" |
27 | | #endif |
28 | | #include "os_types.h" |
29 | | |
30 | | #include <assert.h> |
31 | | #include <stddef.h> |
32 | | #include <stdio.h> |
33 | | #include <string.h> |
34 | | |
35 | | #include "jbig2.h" |
36 | | #include "jbig2_priv.h" |
37 | | #include "jbig2_arith.h" |
38 | | #include "jbig2_generic.h" |
39 | | #include "jbig2_image.h" |
40 | | #include "jbig2_mmr.h" |
41 | | #include "jbig2_segment.h" |
42 | | |
43 | | typedef struct { |
44 | | uint32_t width; |
45 | | uint32_t height; |
46 | | const byte *data; |
47 | | size_t size; |
48 | | size_t consumed_bits; |
49 | | uint32_t data_index; |
50 | | uint32_t bit_index; |
51 | | uint32_t word; |
52 | | } Jbig2MmrCtx; |
53 | | |
54 | 223k | #define MINUS1 UINT32_MAX |
55 | 12.6k | #define ERROR -1 |
56 | 12.6k | #define ZEROES -2 |
57 | 12.6k | #define UNCOMPRESSED -3 |
58 | | |
59 | | static void |
60 | | jbig2_decode_mmr_init(Jbig2MmrCtx *mmr, int width, int height, const byte *data, size_t size) |
61 | 135 | { |
62 | 135 | mmr->width = width; |
63 | 135 | mmr->height = height; |
64 | 135 | mmr->data = data; |
65 | 135 | mmr->size = size; |
66 | 135 | mmr->data_index = 0; |
67 | 135 | mmr->bit_index = 32; |
68 | 135 | mmr->word = 0; |
69 | 135 | mmr->consumed_bits = 0; |
70 | | |
71 | 675 | while (mmr->bit_index >= 8 && mmr->data_index < mmr->size) { |
72 | 540 | mmr->bit_index -= 8; |
73 | 540 | mmr->word |= (mmr->data[mmr->data_index] << mmr->bit_index); |
74 | 540 | mmr->data_index++; |
75 | 540 | } |
76 | 135 | } |
77 | | |
78 | | static void |
79 | | jbig2_decode_mmr_consume(Jbig2MmrCtx *mmr, int n_bits) |
80 | 56.6k | { |
81 | 56.6k | mmr->consumed_bits += n_bits; |
82 | 56.6k | if (mmr->consumed_bits > mmr->size * 8) |
83 | 27 | mmr->consumed_bits = mmr->size * 8; |
84 | | |
85 | 56.6k | mmr->word <<= n_bits; |
86 | 56.6k | mmr->bit_index += n_bits; |
87 | 74.1k | while (mmr->bit_index >= 8 && mmr->data_index < mmr->size) { |
88 | 17.4k | mmr->bit_index -= 8; |
89 | 17.4k | mmr->word |= (mmr->data[mmr->data_index] << mmr->bit_index); |
90 | 17.4k | mmr->data_index++; |
91 | 17.4k | } |
92 | 56.6k | } |
93 | | |
94 | | /* |
95 | | <raph> the first 2^(initialbits) entries map bit patterns to decodes |
96 | | <raph> let's say initial_bits is 8 for the sake of example |
97 | | <raph> and that the code is 1001 |
98 | | <raph> that means that entries 0x90 .. 0x9f have the entry { val, 4 } |
99 | | <raph> because those are all the bytes that start with the code |
100 | | <raph> and the 4 is the length of the code |
101 | | ... if (n_bits > initial_bits) ... |
102 | | <raph> anyway, in that case, it basically points to a mini table |
103 | | <raph> the n_bits is the maximum length of all codes beginning with that byte |
104 | | <raph> so 2^(n_bits - initial_bits) is the size of the mini-table |
105 | | <raph> peter came up with this, and it makes sense |
106 | | */ |
107 | | |
108 | | typedef struct { |
109 | | short val; |
110 | | short n_bits; |
111 | | } mmr_table_node; |
112 | | |
113 | | /* white decode table (runlength huffman codes) */ |
114 | | const mmr_table_node jbig2_mmr_white_decode[] = { |
115 | | {256, 12}, |
116 | | {272, 12}, |
117 | | {29, 8}, |
118 | | {30, 8}, |
119 | | {45, 8}, |
120 | | {46, 8}, |
121 | | {22, 7}, |
122 | | {22, 7}, |
123 | | {23, 7}, |
124 | | {23, 7}, |
125 | | {47, 8}, |
126 | | {48, 8}, |
127 | | {13, 6}, |
128 | | {13, 6}, |
129 | | {13, 6}, |
130 | | {13, 6}, |
131 | | {20, 7}, |
132 | | {20, 7}, |
133 | | {33, 8}, |
134 | | {34, 8}, |
135 | | {35, 8}, |
136 | | {36, 8}, |
137 | | {37, 8}, |
138 | | {38, 8}, |
139 | | {19, 7}, |
140 | | {19, 7}, |
141 | | {31, 8}, |
142 | | {32, 8}, |
143 | | {1, 6}, |
144 | | {1, 6}, |
145 | | {1, 6}, |
146 | | {1, 6}, |
147 | | {12, 6}, |
148 | | {12, 6}, |
149 | | {12, 6}, |
150 | | {12, 6}, |
151 | | {53, 8}, |
152 | | {54, 8}, |
153 | | {26, 7}, |
154 | | {26, 7}, |
155 | | {39, 8}, |
156 | | {40, 8}, |
157 | | {41, 8}, |
158 | | {42, 8}, |
159 | | {43, 8}, |
160 | | {44, 8}, |
161 | | {21, 7}, |
162 | | {21, 7}, |
163 | | {28, 7}, |
164 | | {28, 7}, |
165 | | {61, 8}, |
166 | | {62, 8}, |
167 | | {63, 8}, |
168 | | {0, 8}, |
169 | | {320, 8}, |
170 | | {384, 8}, |
171 | | {10, 5}, |
172 | | {10, 5}, |
173 | | {10, 5}, |
174 | | {10, 5}, |
175 | | {10, 5}, |
176 | | {10, 5}, |
177 | | {10, 5}, |
178 | | {10, 5}, |
179 | | {11, 5}, |
180 | | {11, 5}, |
181 | | {11, 5}, |
182 | | {11, 5}, |
183 | | {11, 5}, |
184 | | {11, 5}, |
185 | | {11, 5}, |
186 | | {11, 5}, |
187 | | {27, 7}, |
188 | | {27, 7}, |
189 | | {59, 8}, |
190 | | {60, 8}, |
191 | | {288, 9}, |
192 | | {290, 9}, |
193 | | {18, 7}, |
194 | | {18, 7}, |
195 | | {24, 7}, |
196 | | {24, 7}, |
197 | | {49, 8}, |
198 | | {50, 8}, |
199 | | {51, 8}, |
200 | | {52, 8}, |
201 | | {25, 7}, |
202 | | {25, 7}, |
203 | | {55, 8}, |
204 | | {56, 8}, |
205 | | {57, 8}, |
206 | | {58, 8}, |
207 | | {192, 6}, |
208 | | {192, 6}, |
209 | | {192, 6}, |
210 | | {192, 6}, |
211 | | {1664, 6}, |
212 | | {1664, 6}, |
213 | | {1664, 6}, |
214 | | {1664, 6}, |
215 | | {448, 8}, |
216 | | {512, 8}, |
217 | | {292, 9}, |
218 | | {640, 8}, |
219 | | {576, 8}, |
220 | | {294, 9}, |
221 | | {296, 9}, |
222 | | {298, 9}, |
223 | | {300, 9}, |
224 | | {302, 9}, |
225 | | {256, 7}, |
226 | | {256, 7}, |
227 | | {2, 4}, |
228 | | {2, 4}, |
229 | | {2, 4}, |
230 | | {2, 4}, |
231 | | {2, 4}, |
232 | | {2, 4}, |
233 | | {2, 4}, |
234 | | {2, 4}, |
235 | | {2, 4}, |
236 | | {2, 4}, |
237 | | {2, 4}, |
238 | | {2, 4}, |
239 | | {2, 4}, |
240 | | {2, 4}, |
241 | | {2, 4}, |
242 | | {2, 4}, |
243 | | {3, 4}, |
244 | | {3, 4}, |
245 | | {3, 4}, |
246 | | {3, 4}, |
247 | | {3, 4}, |
248 | | {3, 4}, |
249 | | {3, 4}, |
250 | | {3, 4}, |
251 | | {3, 4}, |
252 | | {3, 4}, |
253 | | {3, 4}, |
254 | | {3, 4}, |
255 | | {3, 4}, |
256 | | {3, 4}, |
257 | | {3, 4}, |
258 | | {3, 4}, |
259 | | {128, 5}, |
260 | | {128, 5}, |
261 | | {128, 5}, |
262 | | {128, 5}, |
263 | | {128, 5}, |
264 | | {128, 5}, |
265 | | {128, 5}, |
266 | | {128, 5}, |
267 | | {8, 5}, |
268 | | {8, 5}, |
269 | | {8, 5}, |
270 | | {8, 5}, |
271 | | {8, 5}, |
272 | | {8, 5}, |
273 | | {8, 5}, |
274 | | {8, 5}, |
275 | | {9, 5}, |
276 | | {9, 5}, |
277 | | {9, 5}, |
278 | | {9, 5}, |
279 | | {9, 5}, |
280 | | {9, 5}, |
281 | | {9, 5}, |
282 | | {9, 5}, |
283 | | {16, 6}, |
284 | | {16, 6}, |
285 | | {16, 6}, |
286 | | {16, 6}, |
287 | | {17, 6}, |
288 | | {17, 6}, |
289 | | {17, 6}, |
290 | | {17, 6}, |
291 | | {4, 4}, |
292 | | {4, 4}, |
293 | | {4, 4}, |
294 | | {4, 4}, |
295 | | {4, 4}, |
296 | | {4, 4}, |
297 | | {4, 4}, |
298 | | {4, 4}, |
299 | | {4, 4}, |
300 | | {4, 4}, |
301 | | {4, 4}, |
302 | | {4, 4}, |
303 | | {4, 4}, |
304 | | {4, 4}, |
305 | | {4, 4}, |
306 | | {4, 4}, |
307 | | {5, 4}, |
308 | | {5, 4}, |
309 | | {5, 4}, |
310 | | {5, 4}, |
311 | | {5, 4}, |
312 | | {5, 4}, |
313 | | {5, 4}, |
314 | | {5, 4}, |
315 | | {5, 4}, |
316 | | {5, 4}, |
317 | | {5, 4}, |
318 | | {5, 4}, |
319 | | {5, 4}, |
320 | | {5, 4}, |
321 | | {5, 4}, |
322 | | {5, 4}, |
323 | | {14, 6}, |
324 | | {14, 6}, |
325 | | {14, 6}, |
326 | | {14, 6}, |
327 | | {15, 6}, |
328 | | {15, 6}, |
329 | | {15, 6}, |
330 | | {15, 6}, |
331 | | {64, 5}, |
332 | | {64, 5}, |
333 | | {64, 5}, |
334 | | {64, 5}, |
335 | | {64, 5}, |
336 | | {64, 5}, |
337 | | {64, 5}, |
338 | | {64, 5}, |
339 | | {6, 4}, |
340 | | {6, 4}, |
341 | | {6, 4}, |
342 | | {6, 4}, |
343 | | {6, 4}, |
344 | | {6, 4}, |
345 | | {6, 4}, |
346 | | {6, 4}, |
347 | | {6, 4}, |
348 | | {6, 4}, |
349 | | {6, 4}, |
350 | | {6, 4}, |
351 | | {6, 4}, |
352 | | {6, 4}, |
353 | | {6, 4}, |
354 | | {6, 4}, |
355 | | {7, 4}, |
356 | | {7, 4}, |
357 | | {7, 4}, |
358 | | {7, 4}, |
359 | | {7, 4}, |
360 | | {7, 4}, |
361 | | {7, 4}, |
362 | | {7, 4}, |
363 | | {7, 4}, |
364 | | {7, 4}, |
365 | | {7, 4}, |
366 | | {7, 4}, |
367 | | {7, 4}, |
368 | | {7, 4}, |
369 | | {7, 4}, |
370 | | {7, 4}, |
371 | | {-2, 3}, |
372 | | {-2, 3}, |
373 | | {-1, 0}, |
374 | | {-1, 0}, |
375 | | {-1, 0}, |
376 | | {-1, 0}, |
377 | | {-1, 0}, |
378 | | {-1, 0}, |
379 | | {-1, 0}, |
380 | | {-1, 0}, |
381 | | {-1, 0}, |
382 | | {-1, 0}, |
383 | | {-1, 0}, |
384 | | {-1, 0}, |
385 | | {-1, 0}, |
386 | | {-3, 4}, |
387 | | {1792, 3}, |
388 | | {1792, 3}, |
389 | | {1984, 4}, |
390 | | {2048, 4}, |
391 | | {2112, 4}, |
392 | | {2176, 4}, |
393 | | {2240, 4}, |
394 | | {2304, 4}, |
395 | | {1856, 3}, |
396 | | {1856, 3}, |
397 | | {1920, 3}, |
398 | | {1920, 3}, |
399 | | {2368, 4}, |
400 | | {2432, 4}, |
401 | | {2496, 4}, |
402 | | {2560, 4}, |
403 | | {1472, 1}, |
404 | | {1536, 1}, |
405 | | {1600, 1}, |
406 | | {1728, 1}, |
407 | | {704, 1}, |
408 | | {768, 1}, |
409 | | {832, 1}, |
410 | | {896, 1}, |
411 | | {960, 1}, |
412 | | {1024, 1}, |
413 | | {1088, 1}, |
414 | | {1152, 1}, |
415 | | {1216, 1}, |
416 | | {1280, 1}, |
417 | | {1344, 1}, |
418 | | {1408, 1} |
419 | | }; |
420 | | |
421 | | /* black decode table (runlength huffman codes) */ |
422 | | const mmr_table_node jbig2_mmr_black_decode[] = { |
423 | | {128, 12}, |
424 | | {160, 13}, |
425 | | {224, 12}, |
426 | | {256, 12}, |
427 | | {10, 7}, |
428 | | {11, 7}, |
429 | | {288, 12}, |
430 | | {12, 7}, |
431 | | {9, 6}, |
432 | | {9, 6}, |
433 | | {8, 6}, |
434 | | {8, 6}, |
435 | | {7, 5}, |
436 | | {7, 5}, |
437 | | {7, 5}, |
438 | | {7, 5}, |
439 | | {6, 4}, |
440 | | {6, 4}, |
441 | | {6, 4}, |
442 | | {6, 4}, |
443 | | {6, 4}, |
444 | | {6, 4}, |
445 | | {6, 4}, |
446 | | {6, 4}, |
447 | | {5, 4}, |
448 | | {5, 4}, |
449 | | {5, 4}, |
450 | | {5, 4}, |
451 | | {5, 4}, |
452 | | {5, 4}, |
453 | | {5, 4}, |
454 | | {5, 4}, |
455 | | {1, 3}, |
456 | | {1, 3}, |
457 | | {1, 3}, |
458 | | {1, 3}, |
459 | | {1, 3}, |
460 | | {1, 3}, |
461 | | {1, 3}, |
462 | | {1, 3}, |
463 | | {1, 3}, |
464 | | {1, 3}, |
465 | | {1, 3}, |
466 | | {1, 3}, |
467 | | {1, 3}, |
468 | | {1, 3}, |
469 | | {1, 3}, |
470 | | {1, 3}, |
471 | | {4, 3}, |
472 | | {4, 3}, |
473 | | {4, 3}, |
474 | | {4, 3}, |
475 | | {4, 3}, |
476 | | {4, 3}, |
477 | | {4, 3}, |
478 | | {4, 3}, |
479 | | {4, 3}, |
480 | | {4, 3}, |
481 | | {4, 3}, |
482 | | {4, 3}, |
483 | | {4, 3}, |
484 | | {4, 3}, |
485 | | {4, 3}, |
486 | | {4, 3}, |
487 | | {3, 2}, |
488 | | {3, 2}, |
489 | | {3, 2}, |
490 | | {3, 2}, |
491 | | {3, 2}, |
492 | | {3, 2}, |
493 | | {3, 2}, |
494 | | {3, 2}, |
495 | | {3, 2}, |
496 | | {3, 2}, |
497 | | {3, 2}, |
498 | | {3, 2}, |
499 | | {3, 2}, |
500 | | {3, 2}, |
501 | | {3, 2}, |
502 | | {3, 2}, |
503 | | {3, 2}, |
504 | | {3, 2}, |
505 | | {3, 2}, |
506 | | {3, 2}, |
507 | | {3, 2}, |
508 | | {3, 2}, |
509 | | {3, 2}, |
510 | | {3, 2}, |
511 | | {3, 2}, |
512 | | {3, 2}, |
513 | | {3, 2}, |
514 | | {3, 2}, |
515 | | {3, 2}, |
516 | | {3, 2}, |
517 | | {3, 2}, |
518 | | {3, 2}, |
519 | | {2, 2}, |
520 | | {2, 2}, |
521 | | {2, 2}, |
522 | | {2, 2}, |
523 | | {2, 2}, |
524 | | {2, 2}, |
525 | | {2, 2}, |
526 | | {2, 2}, |
527 | | {2, 2}, |
528 | | {2, 2}, |
529 | | {2, 2}, |
530 | | {2, 2}, |
531 | | {2, 2}, |
532 | | {2, 2}, |
533 | | {2, 2}, |
534 | | {2, 2}, |
535 | | {2, 2}, |
536 | | {2, 2}, |
537 | | {2, 2}, |
538 | | {2, 2}, |
539 | | {2, 2}, |
540 | | {2, 2}, |
541 | | {2, 2}, |
542 | | {2, 2}, |
543 | | {2, 2}, |
544 | | {2, 2}, |
545 | | {2, 2}, |
546 | | {2, 2}, |
547 | | {2, 2}, |
548 | | {2, 2}, |
549 | | {2, 2}, |
550 | | {2, 2}, |
551 | | {-2, 4}, |
552 | | {-2, 4}, |
553 | | {-1, 0}, |
554 | | {-1, 0}, |
555 | | {-1, 0}, |
556 | | {-1, 0}, |
557 | | {-1, 0}, |
558 | | {-1, 0}, |
559 | | {-1, 0}, |
560 | | {-1, 0}, |
561 | | {-1, 0}, |
562 | | {-1, 0}, |
563 | | {-1, 0}, |
564 | | {-1, 0}, |
565 | | {-1, 0}, |
566 | | {-3, 5}, |
567 | | {1792, 4}, |
568 | | {1792, 4}, |
569 | | {1984, 5}, |
570 | | {2048, 5}, |
571 | | {2112, 5}, |
572 | | {2176, 5}, |
573 | | {2240, 5}, |
574 | | {2304, 5}, |
575 | | {1856, 4}, |
576 | | {1856, 4}, |
577 | | {1920, 4}, |
578 | | {1920, 4}, |
579 | | {2368, 5}, |
580 | | {2432, 5}, |
581 | | {2496, 5}, |
582 | | {2560, 5}, |
583 | | {18, 3}, |
584 | | {18, 3}, |
585 | | {18, 3}, |
586 | | {18, 3}, |
587 | | {18, 3}, |
588 | | {18, 3}, |
589 | | {18, 3}, |
590 | | {18, 3}, |
591 | | {52, 5}, |
592 | | {52, 5}, |
593 | | {640, 6}, |
594 | | {704, 6}, |
595 | | {768, 6}, |
596 | | {832, 6}, |
597 | | {55, 5}, |
598 | | {55, 5}, |
599 | | {56, 5}, |
600 | | {56, 5}, |
601 | | {1280, 6}, |
602 | | {1344, 6}, |
603 | | {1408, 6}, |
604 | | {1472, 6}, |
605 | | {59, 5}, |
606 | | {59, 5}, |
607 | | {60, 5}, |
608 | | {60, 5}, |
609 | | {1536, 6}, |
610 | | {1600, 6}, |
611 | | {24, 4}, |
612 | | {24, 4}, |
613 | | {24, 4}, |
614 | | {24, 4}, |
615 | | {25, 4}, |
616 | | {25, 4}, |
617 | | {25, 4}, |
618 | | {25, 4}, |
619 | | {1664, 6}, |
620 | | {1728, 6}, |
621 | | {320, 5}, |
622 | | {320, 5}, |
623 | | {384, 5}, |
624 | | {384, 5}, |
625 | | {448, 5}, |
626 | | {448, 5}, |
627 | | {512, 6}, |
628 | | {576, 6}, |
629 | | {53, 5}, |
630 | | {53, 5}, |
631 | | {54, 5}, |
632 | | {54, 5}, |
633 | | {896, 6}, |
634 | | {960, 6}, |
635 | | {1024, 6}, |
636 | | {1088, 6}, |
637 | | {1152, 6}, |
638 | | {1216, 6}, |
639 | | {64, 3}, |
640 | | {64, 3}, |
641 | | {64, 3}, |
642 | | {64, 3}, |
643 | | {64, 3}, |
644 | | {64, 3}, |
645 | | {64, 3}, |
646 | | {64, 3}, |
647 | | {13, 1}, |
648 | | {13, 1}, |
649 | | {13, 1}, |
650 | | {13, 1}, |
651 | | {13, 1}, |
652 | | {13, 1}, |
653 | | {13, 1}, |
654 | | {13, 1}, |
655 | | {13, 1}, |
656 | | {13, 1}, |
657 | | {13, 1}, |
658 | | {13, 1}, |
659 | | {13, 1}, |
660 | | {13, 1}, |
661 | | {13, 1}, |
662 | | {13, 1}, |
663 | | {23, 4}, |
664 | | {23, 4}, |
665 | | {50, 5}, |
666 | | {51, 5}, |
667 | | {44, 5}, |
668 | | {45, 5}, |
669 | | {46, 5}, |
670 | | {47, 5}, |
671 | | {57, 5}, |
672 | | {58, 5}, |
673 | | {61, 5}, |
674 | | {256, 5}, |
675 | | {16, 3}, |
676 | | {16, 3}, |
677 | | {16, 3}, |
678 | | {16, 3}, |
679 | | {17, 3}, |
680 | | {17, 3}, |
681 | | {17, 3}, |
682 | | {17, 3}, |
683 | | {48, 5}, |
684 | | {49, 5}, |
685 | | {62, 5}, |
686 | | {63, 5}, |
687 | | {30, 5}, |
688 | | {31, 5}, |
689 | | {32, 5}, |
690 | | {33, 5}, |
691 | | {40, 5}, |
692 | | {41, 5}, |
693 | | {22, 4}, |
694 | | {22, 4}, |
695 | | {14, 1}, |
696 | | {14, 1}, |
697 | | {14, 1}, |
698 | | {14, 1}, |
699 | | {14, 1}, |
700 | | {14, 1}, |
701 | | {14, 1}, |
702 | | {14, 1}, |
703 | | {14, 1}, |
704 | | {14, 1}, |
705 | | {14, 1}, |
706 | | {14, 1}, |
707 | | {14, 1}, |
708 | | {14, 1}, |
709 | | {14, 1}, |
710 | | {14, 1}, |
711 | | {15, 2}, |
712 | | {15, 2}, |
713 | | {15, 2}, |
714 | | {15, 2}, |
715 | | {15, 2}, |
716 | | {15, 2}, |
717 | | {15, 2}, |
718 | | {15, 2}, |
719 | | {128, 5}, |
720 | | {192, 5}, |
721 | | {26, 5}, |
722 | | {27, 5}, |
723 | | {28, 5}, |
724 | | {29, 5}, |
725 | | {19, 4}, |
726 | | {19, 4}, |
727 | | {20, 4}, |
728 | | {20, 4}, |
729 | | {34, 5}, |
730 | | {35, 5}, |
731 | | {36, 5}, |
732 | | {37, 5}, |
733 | | {38, 5}, |
734 | | {39, 5}, |
735 | | {21, 4}, |
736 | | {21, 4}, |
737 | | {42, 5}, |
738 | | {43, 5}, |
739 | | {0, 3}, |
740 | | {0, 3}, |
741 | | {0, 3}, |
742 | | {0, 3} |
743 | | }; |
744 | | |
745 | 256k | #define getbit(buf, x) ( ( buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1 ) |
746 | | |
747 | | /* On platforms that enforce aligned memory accesses, we can't just |
748 | | * cast the byte * to the type of object we are accessing, we have |
749 | | * unpack the requisite number of bytes, and deal with it that way. |
750 | | * Note that the comments below about being 16/32 bit boundaries |
751 | | * is referring to offsets into the byte stream, *not* memory |
752 | | * addresses. |
753 | | */ |
754 | 1.27G | #define getword16(b) ((uint16_t)(b[0] | (b[1] << 8))) |
755 | 639M | #define getword32(b) ((uint32_t)(getword16(b) | (getword16((b + 2)) << 16))) |
756 | | |
757 | | static uint32_t |
758 | | jbig2_find_changing_element(const byte *line, uint32_t x, uint32_t w) |
759 | 43.9k | { |
760 | 43.9k | int a; |
761 | 43.9k | uint8_t all8; |
762 | 43.9k | uint16_t all16; |
763 | 43.9k | uint32_t all32; |
764 | | |
765 | 43.9k | if (line == NULL) |
766 | 0 | return w; |
767 | | |
768 | 43.9k | if (x == MINUS1) { |
769 | 6.71k | a = 0; |
770 | 6.71k | x = 0; |
771 | 37.2k | } else if (x < w) { |
772 | 36.8k | a = getbit(line, x); |
773 | 36.8k | x++; |
774 | 36.8k | } else { |
775 | 429 | return x; |
776 | 429 | } |
777 | | |
778 | | /* We will be looking for a uint8 or uint16 or uint32 that has at least one |
779 | | bit different from <a>, so prepare some useful values for comparison. */ |
780 | 43.5k | all8 = (a) ? 0xff : 0; |
781 | 43.5k | all16 = (a) ? 0xffff : 0; |
782 | 43.5k | all32 = (a) ? 0xffffffff : 0; |
783 | | |
784 | | /* Check individual bits up to next 8-bit boundary. |
785 | | |
786 | | [Would it be worth looking at top 4 bits, then at 2 bits then at 1 bit, |
787 | | instead of iterating over all 8 bits? */ |
788 | | |
789 | 43.5k | if ( ((uint8_t*) line)[ x / 8] == all8) { |
790 | | /* Don't bother checking individual bits if the enclosing uint8 equals |
791 | | all8 - just move to the next byte. */ |
792 | 13.4k | x = x / 8 * 8 + 8; |
793 | 13.4k | if (x >= w) { |
794 | 317 | x = w; |
795 | 317 | goto end; |
796 | 317 | } |
797 | 30.0k | } else { |
798 | 96.1k | for(;;) { |
799 | 96.1k | if (x == w) { |
800 | 2.13k | goto end; |
801 | 2.13k | } |
802 | 93.9k | if (x % 8 == 0) { |
803 | 18.6k | break; |
804 | 18.6k | } |
805 | 75.3k | if (getbit(line, x) != a) { |
806 | 9.26k | goto end; |
807 | 9.26k | } |
808 | 66.0k | x += 1; |
809 | 66.0k | } |
810 | 30.0k | } |
811 | | |
812 | 31.8k | assert(x % 8 == 0); |
813 | | /* Check next uint8 if we are not on 16-bit boundary. */ |
814 | 31.8k | if (x % 16) { |
815 | 17.9k | if (w - x < 8) { |
816 | 534 | goto check1; |
817 | 534 | } |
818 | 17.3k | if ( ((uint8_t*) line)[ x / 8] != all8) { |
819 | 4.23k | goto check1; |
820 | 4.23k | } |
821 | 13.1k | x += 8; /* This will make x a multiple of 16. */ |
822 | 13.1k | } |
823 | | |
824 | 27.0k | assert(x % 16 == 0); |
825 | | /* Check next uint16 if we are not on 32-bit boundary. */ |
826 | 27.0k | if (x % 32) { |
827 | 15.8k | if (w - x < 16) { |
828 | 0 | goto check8; |
829 | 0 | } |
830 | 15.8k | if ( getword16((line + (x / 8))) != all16) { |
831 | 3.42k | goto check8_no_eof; |
832 | 3.42k | } |
833 | 12.4k | x += 16; /* This will make x a multiple of 32. */ |
834 | 12.4k | } |
835 | | |
836 | | /* We are now on a 32-bit boundary. Check uint32's until we reach last |
837 | | sub-32-bit region. */ |
838 | 23.6k | assert(x % 32 == 0); |
839 | 639M | for(;;) { |
840 | 639M | if (w - x < 32) { |
841 | | /* We could still look at the uint32 here - if it equals all32, we |
842 | | know there is no match before <w> so could do {x = w; goto end;}. |
843 | | |
844 | | But for now we simply fall into the epilogue checking, which will |
845 | | look at the next uint16, then uint8, then last 8 bits. */ |
846 | 7.49k | goto check16; |
847 | 7.49k | } |
848 | 639M | if ( getword32((line + (x / 8))) != all32) { |
849 | 16.1k | goto check16_no_eof; |
850 | 16.1k | } |
851 | 639M | x += 32; |
852 | 639M | } |
853 | | |
854 | | /* Check next uint16. */ |
855 | 7.49k | check16: |
856 | 7.49k | assert(x % 16 == 0); |
857 | 7.49k | if (w - x < 16) { |
858 | 3.97k | goto check8; |
859 | 3.97k | } |
860 | 19.6k | check16_no_eof: |
861 | 19.6k | assert(w - x >= 16); |
862 | 19.6k | if ( getword16((line + (x / 8))) != all16) { |
863 | 10.5k | goto check8_no_eof; |
864 | 10.5k | } |
865 | 9.07k | x += 16; |
866 | | |
867 | | /* Check next uint8. */ |
868 | 13.0k | check8: |
869 | 13.0k | assert(x % 8 == 0); |
870 | 13.0k | if (w - x < 8) { |
871 | 772 | goto check1; |
872 | 772 | } |
873 | 26.2k | check8_no_eof: |
874 | 26.2k | assert(w - x >= 8); |
875 | 26.2k | if ( ((uint8_t*) line)[x/8] != all8) { |
876 | 12.4k | goto check1; |
877 | 12.4k | } |
878 | 13.8k | x += 8; |
879 | | |
880 | | /* Check up to the next 8 bits. */ |
881 | 31.8k | check1: |
882 | 31.8k | assert(x % 8 == 0); |
883 | 31.8k | if ( ((uint8_t*) line)[ x / 8] == all8) { |
884 | 2.76k | x = w; |
885 | 2.76k | goto end; |
886 | 2.76k | } |
887 | 29.0k | { |
888 | 115k | for(;;) { |
889 | 115k | if (x == w) { |
890 | 2.78k | goto end; |
891 | 2.78k | } |
892 | 112k | if (getbit(line, x) != a) { |
893 | 26.2k | goto end; |
894 | 26.2k | } |
895 | 86.5k | x += 1; |
896 | 86.5k | } |
897 | 29.0k | } |
898 | | |
899 | 43.5k | end: |
900 | 43.5k | return x; |
901 | 29.0k | } |
902 | | |
903 | | #undef getword16 |
904 | | #undef getword32 |
905 | | |
906 | | static uint32_t |
907 | | jbig2_find_changing_element_of_color(const byte *line, uint32_t x, uint32_t w, int color) |
908 | 38.5k | { |
909 | 38.5k | if (line == NULL) |
910 | 150 | return w; |
911 | 38.4k | x = jbig2_find_changing_element(line, x, w); |
912 | 38.4k | if (x < w && getbit(line, x) != color) |
913 | 3.85k | x = jbig2_find_changing_element(line, x, w); |
914 | 38.4k | return x; |
915 | 38.5k | } |
916 | | |
917 | | static const byte lm[8] = { 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01 }; |
918 | | static const byte rm[8] = { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE }; |
919 | | |
920 | | static void |
921 | | jbig2_set_bits(byte *line, uint32_t x0, uint32_t x1) |
922 | 22.3k | { |
923 | 22.3k | uint32_t a0, a1, b0, b1, a; |
924 | | |
925 | 22.3k | a0 = x0 >> 3; |
926 | 22.3k | a1 = x1 >> 3; |
927 | | |
928 | 22.3k | b0 = x0 & 7; |
929 | 22.3k | b1 = x1 & 7; |
930 | | |
931 | 22.3k | if (a0 == a1) { |
932 | 9.27k | line[a0] |= lm[b0] & rm[b1]; |
933 | 13.0k | } else { |
934 | 13.0k | line[a0] |= lm[b0]; |
935 | 1.29G | for (a = a0 + 1; a < a1; a++) |
936 | 1.29G | line[a] = 0xFF; |
937 | 13.0k | if (b1) |
938 | 10.6k | line[a1] |= rm[b1]; |
939 | 13.0k | } |
940 | 22.3k | } |
941 | | |
942 | | static int |
943 | | jbig2_decode_get_code(Jbig2MmrCtx *mmr, const mmr_table_node *table, int initial_bits) |
944 | 12.6k | { |
945 | 12.6k | uint32_t word = mmr->word; |
946 | 12.6k | int table_ix = word >> (32 - initial_bits); |
947 | 12.6k | int val = table[table_ix].val; |
948 | 12.6k | int n_bits = table[table_ix].n_bits; |
949 | | |
950 | 12.6k | if (n_bits > initial_bits) { |
951 | 307 | int mask = (1 << (32 - initial_bits)) - 1; |
952 | | |
953 | 307 | table_ix = val + ((word & mask) >> (32 - n_bits)); |
954 | 307 | val = table[table_ix].val; |
955 | 307 | n_bits = initial_bits + table[table_ix].n_bits; |
956 | 307 | } |
957 | | |
958 | 12.6k | jbig2_decode_mmr_consume(mmr, n_bits); |
959 | | |
960 | 12.6k | return val; |
961 | 12.6k | } |
962 | | |
963 | | static int |
964 | | jbig2_decode_get_run(Jbig2Ctx *ctx, Jbig2MmrCtx *mmr, const mmr_table_node *table, int initial_bits) |
965 | 10.8k | { |
966 | 10.8k | int result = 0; |
967 | 10.8k | int val; |
968 | | |
969 | 12.6k | do { |
970 | 12.6k | val = jbig2_decode_get_code(mmr, table, initial_bits); |
971 | 12.6k | if (val == ERROR) |
972 | 10 | return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "invalid code detected in MMR-coded data"); |
973 | 12.6k | else if (val == UNCOMPRESSED) |
974 | 0 | return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "uncompressed code in MMR-coded data"); |
975 | 12.6k | else if (val == ZEROES) |
976 | 17 | return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "zeroes code in MMR-coded data"); |
977 | 12.6k | result += val; |
978 | 12.6k | } while (val >= 64); |
979 | | |
980 | 10.8k | return result; |
981 | 10.8k | } |
982 | | |
983 | | static int |
984 | | jbig2_decode_mmr_line(Jbig2Ctx *ctx, Jbig2MmrCtx *mmr, const byte *ref, byte *dst, int *eofb) |
985 | 28.7k | { |
986 | 28.7k | uint32_t a0 = MINUS1; |
987 | 28.7k | uint32_t a1, a2, b1, b2; |
988 | 28.7k | int c = 0; /* 0 is white, black is 1 */ |
989 | | |
990 | 72.7k | while (1) { |
991 | 72.7k | uint32_t word = mmr->word; |
992 | | |
993 | | /* printf ("%08x\n", word); */ |
994 | | |
995 | 72.7k | if (a0 != MINUS1 && a0 >= mmr->width) |
996 | 7.75k | break; |
997 | | |
998 | 65.0k | if ((word >> (32 - 3)) == 1) { |
999 | 5.45k | int white_run, black_run; |
1000 | | |
1001 | 5.45k | jbig2_decode_mmr_consume(mmr, 3); |
1002 | | |
1003 | 5.45k | if (a0 == MINUS1) |
1004 | 1.07k | a0 = 0; |
1005 | | |
1006 | 5.45k | if (c == 0) { |
1007 | 3.11k | white_run = jbig2_decode_get_run(ctx, mmr, jbig2_mmr_white_decode, 8); |
1008 | 3.11k | if (white_run < 0) |
1009 | 15 | return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to decode white H run"); |
1010 | 3.10k | black_run = jbig2_decode_get_run(ctx, mmr, jbig2_mmr_black_decode, 7); |
1011 | 3.10k | if (black_run < 0) |
1012 | 9 | return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to decode black H run"); |
1013 | | /* printf ("H %d %d\n", white_run, black_run); */ |
1014 | 3.09k | a1 = a0 + white_run; |
1015 | 3.09k | a2 = a1 + black_run; |
1016 | 3.09k | if (a1 > mmr->width) |
1017 | 221 | a1 = mmr->width; |
1018 | 3.09k | if (a2 > mmr->width) |
1019 | 237 | a2 = mmr->width; |
1020 | 3.09k | if (a2 < a1) { |
1021 | 0 | jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative black H run"); |
1022 | 0 | a2 = a1; |
1023 | 0 | } |
1024 | 3.09k | if (a1 < mmr->width) |
1025 | 2.85k | jbig2_set_bits(dst, a1, a2); |
1026 | 3.09k | a0 = a2; |
1027 | 3.09k | } else { |
1028 | 2.33k | black_run = jbig2_decode_get_run(ctx, mmr, jbig2_mmr_black_decode, 7); |
1029 | 2.33k | if (black_run < 0) |
1030 | 1 | return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to decode black H run"); |
1031 | 2.33k | white_run = jbig2_decode_get_run(ctx, mmr, jbig2_mmr_white_decode, 8); |
1032 | 2.33k | if (white_run < 0) |
1033 | 2 | return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to decode white H run"); |
1034 | | /* printf ("H %d %d\n", black_run, white_run); */ |
1035 | 2.33k | a1 = a0 + black_run; |
1036 | 2.33k | a2 = a1 + white_run; |
1037 | 2.33k | if (a1 > mmr->width) |
1038 | 119 | a1 = mmr->width; |
1039 | 2.33k | if (a2 > mmr->width) |
1040 | 249 | a2 = mmr->width; |
1041 | 2.33k | if (a1 < a0) { |
1042 | 0 | jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative white H run"); |
1043 | 0 | a1 = a0; |
1044 | 0 | } |
1045 | 2.33k | if (a0 < mmr->width) |
1046 | 2.33k | jbig2_set_bits(dst, a0, a1); |
1047 | 2.33k | a0 = a2; |
1048 | 2.33k | } |
1049 | 5.45k | } |
1050 | | |
1051 | 59.5k | else if ((word >> (32 - 4)) == 1) { |
1052 | | /* printf ("P\n"); */ |
1053 | 1.72k | jbig2_decode_mmr_consume(mmr, 4); |
1054 | 1.72k | b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c); |
1055 | 1.72k | b2 = jbig2_find_changing_element(ref, b1, mmr->width); |
1056 | 1.72k | if (c) { |
1057 | 507 | if (b2 < a0) { |
1058 | 0 | jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative P run"); |
1059 | 0 | b2 = a0; |
1060 | 0 | } |
1061 | 507 | if (a0 < mmr->width) |
1062 | 507 | jbig2_set_bits(dst, a0, b2); |
1063 | 507 | } |
1064 | 1.72k | a0 = b2; |
1065 | 1.72k | } |
1066 | | |
1067 | 57.8k | else if ((word >> (32 - 1)) == 1) { |
1068 | | /* printf ("V(0)\n"); */ |
1069 | 27.9k | jbig2_decode_mmr_consume(mmr, 1); |
1070 | 27.9k | b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c); |
1071 | 27.9k | if (c) { |
1072 | 13.2k | if (b1 < a0) { |
1073 | 0 | jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative V(0) run"); |
1074 | 0 | b1 = a0; |
1075 | 0 | } |
1076 | 13.2k | if (a0 < mmr->width) |
1077 | 13.2k | jbig2_set_bits(dst, a0, b1); |
1078 | 13.2k | } |
1079 | 27.9k | a0 = b1; |
1080 | 27.9k | c = !c; |
1081 | 27.9k | } |
1082 | | |
1083 | 29.9k | else if ((word >> (32 - 3)) == 3) { |
1084 | | /* printf ("VR(1)\n"); */ |
1085 | 3.92k | jbig2_decode_mmr_consume(mmr, 3); |
1086 | 3.92k | b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c); |
1087 | 3.92k | if (b1 + 1 <= mmr->width) |
1088 | 3.05k | b1 += 1; |
1089 | 3.92k | if (c) { |
1090 | 1.62k | if (b1 < a0) { |
1091 | 0 | jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative VR(1) run"); |
1092 | 0 | b1 = a0; |
1093 | 0 | } |
1094 | 1.62k | if (a0 < mmr->width) |
1095 | 1.62k | jbig2_set_bits(dst, a0, b1); |
1096 | 1.62k | } |
1097 | 3.92k | a0 = b1; |
1098 | 3.92k | c = !c; |
1099 | 3.92k | } |
1100 | | |
1101 | 26.0k | else if ((word >> (32 - 6)) == 3) { |
1102 | | /* printf ("VR(2)\n"); */ |
1103 | 210 | jbig2_decode_mmr_consume(mmr, 6); |
1104 | 210 | b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c); |
1105 | 210 | if (b1 + 2 <= mmr->width) |
1106 | 141 | b1 += 2; |
1107 | 210 | if (c) { |
1108 | 71 | if (b1 < a0) { |
1109 | 0 | jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative VR(2) run"); |
1110 | 0 | b1 = a0; |
1111 | 0 | } |
1112 | 71 | if (a0 < mmr->width) |
1113 | 71 | jbig2_set_bits(dst, a0, b1); |
1114 | 71 | } |
1115 | 210 | a0 = b1; |
1116 | 210 | c = !c; |
1117 | 210 | } |
1118 | | |
1119 | 25.7k | else if ((word >> (32 - 7)) == 3) { |
1120 | | /* printf ("VR(3)\n"); */ |
1121 | 127 | jbig2_decode_mmr_consume(mmr, 7); |
1122 | 127 | b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c); |
1123 | 127 | if (b1 + 3 <= mmr->width) |
1124 | 97 | b1 += 3; |
1125 | 127 | if (c) { |
1126 | 44 | if (b1 < a0) { |
1127 | 0 | jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative VR(3) run"); |
1128 | 0 | b1 = a0; |
1129 | 0 | } |
1130 | 44 | if (a0 < mmr->width) |
1131 | 44 | jbig2_set_bits(dst, a0, b1); |
1132 | 44 | } |
1133 | 127 | a0 = b1; |
1134 | 127 | c = !c; |
1135 | 127 | } |
1136 | | |
1137 | 25.6k | else if ((word >> (32 - 3)) == 2) { |
1138 | | /* printf ("VL(1)\n"); */ |
1139 | 3.39k | jbig2_decode_mmr_consume(mmr, 3); |
1140 | 3.39k | b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c); |
1141 | 3.39k | if (b1 >= 1) |
1142 | 3.34k | b1 -= 1; |
1143 | 3.39k | if (c) { |
1144 | 1.30k | if (b1 < a0) { |
1145 | 0 | jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative VL(1) run"); |
1146 | 0 | b1 = a0; |
1147 | 0 | } |
1148 | 1.30k | if (a0 < mmr->width) |
1149 | 1.30k | jbig2_set_bits(dst, a0, b1); |
1150 | 1.30k | } |
1151 | 3.39k | a0 = b1; |
1152 | 3.39k | c = !c; |
1153 | 3.39k | } |
1154 | | |
1155 | 22.2k | else if ((word >> (32 - 6)) == 2) { |
1156 | | /* printf ("VL(2)\n"); */ |
1157 | 528 | jbig2_decode_mmr_consume(mmr, 6); |
1158 | 528 | b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c); |
1159 | 528 | if (b1 >= 2) |
1160 | 528 | b1 -= 2; |
1161 | 528 | if (c) { |
1162 | 211 | if (b1 < a0) { |
1163 | 26 | jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative VL(2) run"); |
1164 | 26 | b1 = a0; |
1165 | 26 | } |
1166 | 211 | if (a0 < mmr->width) |
1167 | 211 | jbig2_set_bits(dst, a0, b1); |
1168 | 211 | } |
1169 | 528 | a0 = b1; |
1170 | 528 | c = !c; |
1171 | 528 | } |
1172 | | |
1173 | 21.7k | else if ((word >> (32 - 7)) == 2) { |
1174 | | /* printf ("VL(3)\n"); */ |
1175 | 744 | jbig2_decode_mmr_consume(mmr, 7); |
1176 | 744 | b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c); |
1177 | 744 | if (b1 >= 3) |
1178 | 738 | b1 -= 3; |
1179 | 744 | if (c) { |
1180 | 144 | if (b1 < a0) { |
1181 | 41 | jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative VL(3) run"); |
1182 | 41 | b1 = a0; |
1183 | 41 | } |
1184 | 144 | if (a0 < mmr->width) |
1185 | 144 | jbig2_set_bits(dst, a0, b1); |
1186 | 144 | } |
1187 | 744 | a0 = b1; |
1188 | 744 | c = !c; |
1189 | 744 | } |
1190 | | |
1191 | 21.0k | else if ((word >> (32 - 24)) == 0x1001) { |
1192 | | /* printf ("EOFB\n"); */ |
1193 | 0 | jbig2_decode_mmr_consume(mmr, 24); |
1194 | 0 | *eofb = 1; |
1195 | 0 | break; |
1196 | 0 | } |
1197 | | |
1198 | 21.0k | else |
1199 | 21.0k | break; |
1200 | 65.0k | } |
1201 | | |
1202 | 28.7k | return 0; |
1203 | 28.7k | } |
1204 | | |
1205 | | int |
1206 | | jbig2_decode_generic_mmr(Jbig2Ctx *ctx, Jbig2Segment *segment, const Jbig2GenericRegionParams *params, const byte *data, size_t size, Jbig2Image *image) |
1207 | 135 | { |
1208 | 135 | Jbig2MmrCtx mmr; |
1209 | 135 | const uint32_t rowstride = image->stride; |
1210 | 135 | byte *dst = image->data; |
1211 | 135 | byte *ref = NULL; |
1212 | 135 | uint32_t y; |
1213 | 135 | int code = 0; |
1214 | 135 | int eofb = 0; |
1215 | | |
1216 | 135 | jbig2_decode_mmr_init(&mmr, image->width, image->height, data, size); |
1217 | | |
1218 | 28.8k | for (y = 0; !eofb && y < image->height; y++) { |
1219 | 28.7k | memset(dst, 0, rowstride); |
1220 | 28.7k | code = jbig2_decode_mmr_line(ctx, &mmr, ref, dst, &eofb); |
1221 | 28.7k | if (code < 0) |
1222 | 27 | return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode mmr line"); |
1223 | 28.7k | ref = dst; |
1224 | 28.7k | dst += rowstride; |
1225 | 28.7k | } |
1226 | | |
1227 | 108 | if (eofb && y < image->height) { |
1228 | 0 | memset(dst, 0, rowstride * (image->height - y)); |
1229 | 0 | } |
1230 | | |
1231 | 108 | return code; |
1232 | 135 | } |
1233 | | |
1234 | | /** |
1235 | | * jbig2_decode_halftone_mmr: decode mmr region inside of halftones |
1236 | | * |
1237 | | * @ctx: jbig2 decoder context |
1238 | | * @params: parameters for decoding |
1239 | | * @data: pointer to text region data to be decoded |
1240 | | * @size: length of text region data |
1241 | | * @image: return of decoded image |
1242 | | * @consumed_bytes: return of consumed bytes from @data |
1243 | | * |
1244 | | * MMR decoding that consumes EOFB and returns consumed bytes (@consumed_bytes) |
1245 | | * |
1246 | | * returns: 0 |
1247 | | **/ |
1248 | | int |
1249 | | jbig2_decode_halftone_mmr(Jbig2Ctx *ctx, const Jbig2GenericRegionParams *params, const byte *data, size_t size, Jbig2Image *image, size_t *consumed_bytes) |
1250 | 0 | { |
1251 | 0 | Jbig2MmrCtx mmr; |
1252 | 0 | const uint32_t rowstride = image->stride; |
1253 | 0 | byte *dst = image->data; |
1254 | 0 | byte *ref = NULL; |
1255 | 0 | uint32_t y; |
1256 | 0 | int code = 0; |
1257 | 0 | const uint32_t EOFB = 0x001001; |
1258 | 0 | int eofb = 0; |
1259 | |
|
1260 | 0 | jbig2_decode_mmr_init(&mmr, image->width, image->height, data, size); |
1261 | |
|
1262 | 0 | for (y = 0; !eofb && y < image->height; y++) { |
1263 | 0 | memset(dst, 0, rowstride); |
1264 | 0 | code = jbig2_decode_mmr_line(ctx, &mmr, ref, dst, &eofb); |
1265 | 0 | if (code < 0) |
1266 | 0 | return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to decode halftone mmr line"); |
1267 | 0 | ref = dst; |
1268 | 0 | dst += rowstride; |
1269 | 0 | } |
1270 | | |
1271 | 0 | if (eofb && y < image->height) { |
1272 | 0 | memset(dst, 0, rowstride * (image->height - y)); |
1273 | 0 | } |
1274 | | |
1275 | | /* test for EOFB (see section 6.2.6) */ |
1276 | 0 | if (mmr.word >> 8 == EOFB) { |
1277 | 0 | jbig2_decode_mmr_consume(&mmr, 24); |
1278 | 0 | } |
1279 | |
|
1280 | 0 | *consumed_bytes += (mmr.consumed_bits + 7) / 8; |
1281 | 0 | return code; |
1282 | 0 | } |