| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282 |
- /* Copyright (C) 2001-2023 Artifex Software, Inc.
- All Rights Reserved.
- This software is provided AS-IS with no warranty, either express or
- implied.
- This software is distributed under license and may not be copied,
- modified or distributed except as expressly authorized under the terms
- of the license contained in the file LICENSE in this distribution.
- Refer to licensing information at http://www.artifex.com or contact
- Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
- CA 94129, USA, for further information.
- */
- /*
- jbig2dec
- */
- /* An implementation of MMR decoding. This is based on the
- implementation in Fitz, which in turn is based on the one
- in Ghostscript.
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "os_types.h"
- #include <assert.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <string.h>
- #include "jbig2.h"
- #include "jbig2_priv.h"
- #include "jbig2_arith.h"
- #include "jbig2_generic.h"
- #include "jbig2_image.h"
- #include "jbig2_mmr.h"
- #include "jbig2_segment.h"
- typedef struct {
- uint32_t width;
- uint32_t height;
- const byte *data;
- size_t size;
- size_t consumed_bits;
- uint32_t data_index;
- uint32_t bit_index;
- uint32_t word;
- } Jbig2MmrCtx;
- #define MINUS1 UINT32_MAX
- #define ERROR -1
- #define ZEROES -2
- #define UNCOMPRESSED -3
- static void
- jbig2_decode_mmr_init(Jbig2MmrCtx *mmr, int width, int height, const byte *data, size_t size)
- {
- mmr->width = width;
- mmr->height = height;
- mmr->data = data;
- mmr->size = size;
- mmr->data_index = 0;
- mmr->bit_index = 32;
- mmr->word = 0;
- mmr->consumed_bits = 0;
- while (mmr->bit_index >= 8 && mmr->data_index < mmr->size) {
- mmr->bit_index -= 8;
- mmr->word |= (mmr->data[mmr->data_index] << mmr->bit_index);
- mmr->data_index++;
- }
- }
- static void
- jbig2_decode_mmr_consume(Jbig2MmrCtx *mmr, int n_bits)
- {
- mmr->consumed_bits += n_bits;
- if (mmr->consumed_bits > mmr->size * 8)
- mmr->consumed_bits = mmr->size * 8;
- mmr->word <<= n_bits;
- mmr->bit_index += n_bits;
- while (mmr->bit_index >= 8 && mmr->data_index < mmr->size) {
- mmr->bit_index -= 8;
- mmr->word |= (mmr->data[mmr->data_index] << mmr->bit_index);
- mmr->data_index++;
- }
- }
- /*
- <raph> the first 2^(initialbits) entries map bit patterns to decodes
- <raph> let's say initial_bits is 8 for the sake of example
- <raph> and that the code is 1001
- <raph> that means that entries 0x90 .. 0x9f have the entry { val, 4 }
- <raph> because those are all the bytes that start with the code
- <raph> and the 4 is the length of the code
- ... if (n_bits > initial_bits) ...
- <raph> anyway, in that case, it basically points to a mini table
- <raph> the n_bits is the maximum length of all codes beginning with that byte
- <raph> so 2^(n_bits - initial_bits) is the size of the mini-table
- <raph> peter came up with this, and it makes sense
- */
- typedef struct {
- short val;
- short n_bits;
- } mmr_table_node;
- /* white decode table (runlength huffman codes) */
- const mmr_table_node jbig2_mmr_white_decode[] = {
- {256, 12},
- {272, 12},
- {29, 8},
- {30, 8},
- {45, 8},
- {46, 8},
- {22, 7},
- {22, 7},
- {23, 7},
- {23, 7},
- {47, 8},
- {48, 8},
- {13, 6},
- {13, 6},
- {13, 6},
- {13, 6},
- {20, 7},
- {20, 7},
- {33, 8},
- {34, 8},
- {35, 8},
- {36, 8},
- {37, 8},
- {38, 8},
- {19, 7},
- {19, 7},
- {31, 8},
- {32, 8},
- {1, 6},
- {1, 6},
- {1, 6},
- {1, 6},
- {12, 6},
- {12, 6},
- {12, 6},
- {12, 6},
- {53, 8},
- {54, 8},
- {26, 7},
- {26, 7},
- {39, 8},
- {40, 8},
- {41, 8},
- {42, 8},
- {43, 8},
- {44, 8},
- {21, 7},
- {21, 7},
- {28, 7},
- {28, 7},
- {61, 8},
- {62, 8},
- {63, 8},
- {0, 8},
- {320, 8},
- {384, 8},
- {10, 5},
- {10, 5},
- {10, 5},
- {10, 5},
- {10, 5},
- {10, 5},
- {10, 5},
- {10, 5},
- {11, 5},
- {11, 5},
- {11, 5},
- {11, 5},
- {11, 5},
- {11, 5},
- {11, 5},
- {11, 5},
- {27, 7},
- {27, 7},
- {59, 8},
- {60, 8},
- {288, 9},
- {290, 9},
- {18, 7},
- {18, 7},
- {24, 7},
- {24, 7},
- {49, 8},
- {50, 8},
- {51, 8},
- {52, 8},
- {25, 7},
- {25, 7},
- {55, 8},
- {56, 8},
- {57, 8},
- {58, 8},
- {192, 6},
- {192, 6},
- {192, 6},
- {192, 6},
- {1664, 6},
- {1664, 6},
- {1664, 6},
- {1664, 6},
- {448, 8},
- {512, 8},
- {292, 9},
- {640, 8},
- {576, 8},
- {294, 9},
- {296, 9},
- {298, 9},
- {300, 9},
- {302, 9},
- {256, 7},
- {256, 7},
- {2, 4},
- {2, 4},
- {2, 4},
- {2, 4},
- {2, 4},
- {2, 4},
- {2, 4},
- {2, 4},
- {2, 4},
- {2, 4},
- {2, 4},
- {2, 4},
- {2, 4},
- {2, 4},
- {2, 4},
- {2, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {3, 4},
- {128, 5},
- {128, 5},
- {128, 5},
- {128, 5},
- {128, 5},
- {128, 5},
- {128, 5},
- {128, 5},
- {8, 5},
- {8, 5},
- {8, 5},
- {8, 5},
- {8, 5},
- {8, 5},
- {8, 5},
- {8, 5},
- {9, 5},
- {9, 5},
- {9, 5},
- {9, 5},
- {9, 5},
- {9, 5},
- {9, 5},
- {9, 5},
- {16, 6},
- {16, 6},
- {16, 6},
- {16, 6},
- {17, 6},
- {17, 6},
- {17, 6},
- {17, 6},
- {4, 4},
- {4, 4},
- {4, 4},
- {4, 4},
- {4, 4},
- {4, 4},
- {4, 4},
- {4, 4},
- {4, 4},
- {4, 4},
- {4, 4},
- {4, 4},
- {4, 4},
- {4, 4},
- {4, 4},
- {4, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {14, 6},
- {14, 6},
- {14, 6},
- {14, 6},
- {15, 6},
- {15, 6},
- {15, 6},
- {15, 6},
- {64, 5},
- {64, 5},
- {64, 5},
- {64, 5},
- {64, 5},
- {64, 5},
- {64, 5},
- {64, 5},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {7, 4},
- {-2, 3},
- {-2, 3},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-3, 4},
- {1792, 3},
- {1792, 3},
- {1984, 4},
- {2048, 4},
- {2112, 4},
- {2176, 4},
- {2240, 4},
- {2304, 4},
- {1856, 3},
- {1856, 3},
- {1920, 3},
- {1920, 3},
- {2368, 4},
- {2432, 4},
- {2496, 4},
- {2560, 4},
- {1472, 1},
- {1536, 1},
- {1600, 1},
- {1728, 1},
- {704, 1},
- {768, 1},
- {832, 1},
- {896, 1},
- {960, 1},
- {1024, 1},
- {1088, 1},
- {1152, 1},
- {1216, 1},
- {1280, 1},
- {1344, 1},
- {1408, 1}
- };
- /* black decode table (runlength huffman codes) */
- const mmr_table_node jbig2_mmr_black_decode[] = {
- {128, 12},
- {160, 13},
- {224, 12},
- {256, 12},
- {10, 7},
- {11, 7},
- {288, 12},
- {12, 7},
- {9, 6},
- {9, 6},
- {8, 6},
- {8, 6},
- {7, 5},
- {7, 5},
- {7, 5},
- {7, 5},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {6, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {5, 4},
- {1, 3},
- {1, 3},
- {1, 3},
- {1, 3},
- {1, 3},
- {1, 3},
- {1, 3},
- {1, 3},
- {1, 3},
- {1, 3},
- {1, 3},
- {1, 3},
- {1, 3},
- {1, 3},
- {1, 3},
- {1, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {4, 3},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {3, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {2, 2},
- {-2, 4},
- {-2, 4},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-1, 0},
- {-3, 5},
- {1792, 4},
- {1792, 4},
- {1984, 5},
- {2048, 5},
- {2112, 5},
- {2176, 5},
- {2240, 5},
- {2304, 5},
- {1856, 4},
- {1856, 4},
- {1920, 4},
- {1920, 4},
- {2368, 5},
- {2432, 5},
- {2496, 5},
- {2560, 5},
- {18, 3},
- {18, 3},
- {18, 3},
- {18, 3},
- {18, 3},
- {18, 3},
- {18, 3},
- {18, 3},
- {52, 5},
- {52, 5},
- {640, 6},
- {704, 6},
- {768, 6},
- {832, 6},
- {55, 5},
- {55, 5},
- {56, 5},
- {56, 5},
- {1280, 6},
- {1344, 6},
- {1408, 6},
- {1472, 6},
- {59, 5},
- {59, 5},
- {60, 5},
- {60, 5},
- {1536, 6},
- {1600, 6},
- {24, 4},
- {24, 4},
- {24, 4},
- {24, 4},
- {25, 4},
- {25, 4},
- {25, 4},
- {25, 4},
- {1664, 6},
- {1728, 6},
- {320, 5},
- {320, 5},
- {384, 5},
- {384, 5},
- {448, 5},
- {448, 5},
- {512, 6},
- {576, 6},
- {53, 5},
- {53, 5},
- {54, 5},
- {54, 5},
- {896, 6},
- {960, 6},
- {1024, 6},
- {1088, 6},
- {1152, 6},
- {1216, 6},
- {64, 3},
- {64, 3},
- {64, 3},
- {64, 3},
- {64, 3},
- {64, 3},
- {64, 3},
- {64, 3},
- {13, 1},
- {13, 1},
- {13, 1},
- {13, 1},
- {13, 1},
- {13, 1},
- {13, 1},
- {13, 1},
- {13, 1},
- {13, 1},
- {13, 1},
- {13, 1},
- {13, 1},
- {13, 1},
- {13, 1},
- {13, 1},
- {23, 4},
- {23, 4},
- {50, 5},
- {51, 5},
- {44, 5},
- {45, 5},
- {46, 5},
- {47, 5},
- {57, 5},
- {58, 5},
- {61, 5},
- {256, 5},
- {16, 3},
- {16, 3},
- {16, 3},
- {16, 3},
- {17, 3},
- {17, 3},
- {17, 3},
- {17, 3},
- {48, 5},
- {49, 5},
- {62, 5},
- {63, 5},
- {30, 5},
- {31, 5},
- {32, 5},
- {33, 5},
- {40, 5},
- {41, 5},
- {22, 4},
- {22, 4},
- {14, 1},
- {14, 1},
- {14, 1},
- {14, 1},
- {14, 1},
- {14, 1},
- {14, 1},
- {14, 1},
- {14, 1},
- {14, 1},
- {14, 1},
- {14, 1},
- {14, 1},
- {14, 1},
- {14, 1},
- {14, 1},
- {15, 2},
- {15, 2},
- {15, 2},
- {15, 2},
- {15, 2},
- {15, 2},
- {15, 2},
- {15, 2},
- {128, 5},
- {192, 5},
- {26, 5},
- {27, 5},
- {28, 5},
- {29, 5},
- {19, 4},
- {19, 4},
- {20, 4},
- {20, 4},
- {34, 5},
- {35, 5},
- {36, 5},
- {37, 5},
- {38, 5},
- {39, 5},
- {21, 4},
- {21, 4},
- {42, 5},
- {43, 5},
- {0, 3},
- {0, 3},
- {0, 3},
- {0, 3}
- };
- #define getbit(buf, x) ( ( buf[x >> 3] >> ( 7 - (x & 7) ) ) & 1 )
- /* On platforms that enforce aligned memory accesses, we can't just
- * cast the byte * to the type of object we are accessing, we have
- * unpack the requisite number of bytes, and deal with it that way.
- * Note that the comments below about being 16/32 bit boundaries
- * is referring to offsets into the byte stream, *not* memory
- * addresses.
- */
- #define getword16(b) ((uint16_t)(b[0] | (b[1] << 8)))
- #define getword32(b) ((uint32_t)(getword16(b) | (getword16((b + 2)) << 16)))
- static uint32_t
- jbig2_find_changing_element(const byte *line, uint32_t x, uint32_t w)
- {
- int a;
- uint8_t all8;
- uint16_t all16;
- uint32_t all32;
- if (line == NULL)
- return w;
- if (x == MINUS1) {
- a = 0;
- x = 0;
- } else if (x < w) {
- a = getbit(line, x);
- x++;
- } else {
- return x;
- }
- /* We will be looking for a uint8 or uint16 or uint32 that has at least one
- bit different from <a>, so prepare some useful values for comparison. */
- all8 = (a) ? 0xff : 0;
- all16 = (a) ? 0xffff : 0;
- all32 = (a) ? 0xffffffff : 0;
- /* Check individual bits up to next 8-bit boundary.
- [Would it be worth looking at top 4 bits, then at 2 bits then at 1 bit,
- instead of iterating over all 8 bits? */
- if ( ((uint8_t*) line)[ x / 8] == all8) {
- /* Don't bother checking individual bits if the enclosing uint8 equals
- all8 - just move to the next byte. */
- x = x / 8 * 8 + 8;
- if (x >= w) {
- x = w;
- goto end;
- }
- } else {
- for(;;) {
- if (x == w) {
- goto end;
- }
- if (x % 8 == 0) {
- break;
- }
- if (getbit(line, x) != a) {
- goto end;
- }
- x += 1;
- }
- }
- assert(x % 8 == 0);
- /* Check next uint8 if we are not on 16-bit boundary. */
- if (x % 16) {
- if (w - x < 8) {
- goto check1;
- }
- if ( ((uint8_t*) line)[ x / 8] != all8) {
- goto check1;
- }
- x += 8; /* This will make x a multiple of 16. */
- }
- assert(x % 16 == 0);
- /* Check next uint16 if we are not on 32-bit boundary. */
- if (x % 32) {
- if (w - x < 16) {
- goto check8;
- }
- if ( getword16((line + (x / 8))) != all16) {
- goto check8_no_eof;
- }
- x += 16; /* This will make x a multiple of 32. */
- }
- /* We are now on a 32-bit boundary. Check uint32's until we reach last
- sub-32-bit region. */
- assert(x % 32 == 0);
- for(;;) {
- if (w - x < 32) {
- /* We could still look at the uint32 here - if it equals all32, we
- know there is no match before <w> so could do {x = w; goto end;}.
- But for now we simply fall into the epilogue checking, which will
- look at the next uint16, then uint8, then last 8 bits. */
- goto check16;
- }
- if ( getword32((line + (x / 8))) != all32) {
- goto check16_no_eof;
- }
- x += 32;
- }
- /* Check next uint16. */
- check16:
- assert(x % 16 == 0);
- if (w - x < 16) {
- goto check8;
- }
- check16_no_eof:
- assert(w - x >= 16);
- if ( getword16((line + (x / 8))) != all16) {
- goto check8_no_eof;
- }
- x += 16;
- /* Check next uint8. */
- check8:
- assert(x % 8 == 0);
- if (w - x < 8) {
- goto check1;
- }
- check8_no_eof:
- assert(w - x >= 8);
- if ( ((uint8_t*) line)[x/8] != all8) {
- goto check1;
- }
- x += 8;
- /* Check up to the next 8 bits. */
- check1:
- assert(x % 8 == 0);
- if ( ((uint8_t*) line)[ x / 8] == all8) {
- x = w;
- goto end;
- }
- {
- for(;;) {
- if (x == w) {
- goto end;
- }
- if (getbit(line, x) != a) {
- goto end;
- }
- x += 1;
- }
- }
- end:
- return x;
- }
- #undef getword16
- #undef getword32
- static uint32_t
- jbig2_find_changing_element_of_color(const byte *line, uint32_t x, uint32_t w, int color)
- {
- if (line == NULL)
- return w;
- x = jbig2_find_changing_element(line, x, w);
- if (x < w && getbit(line, x) != color)
- x = jbig2_find_changing_element(line, x, w);
- return x;
- }
- static const byte lm[8] = { 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01 };
- static const byte rm[8] = { 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE };
- static void
- jbig2_set_bits(byte *line, uint32_t x0, uint32_t x1)
- {
- uint32_t a0, a1, b0, b1, a;
- a0 = x0 >> 3;
- a1 = x1 >> 3;
- b0 = x0 & 7;
- b1 = x1 & 7;
- if (a0 == a1) {
- line[a0] |= lm[b0] & rm[b1];
- } else {
- line[a0] |= lm[b0];
- for (a = a0 + 1; a < a1; a++)
- line[a] = 0xFF;
- if (b1)
- line[a1] |= rm[b1];
- }
- }
- static int
- jbig2_decode_get_code(Jbig2MmrCtx *mmr, const mmr_table_node *table, int initial_bits)
- {
- uint32_t word = mmr->word;
- int table_ix = word >> (32 - initial_bits);
- int val = table[table_ix].val;
- int n_bits = table[table_ix].n_bits;
- if (n_bits > initial_bits) {
- int mask = (1 << (32 - initial_bits)) - 1;
- table_ix = val + ((word & mask) >> (32 - n_bits));
- val = table[table_ix].val;
- n_bits = initial_bits + table[table_ix].n_bits;
- }
- jbig2_decode_mmr_consume(mmr, n_bits);
- return val;
- }
- static int
- jbig2_decode_get_run(Jbig2Ctx *ctx, Jbig2MmrCtx *mmr, const mmr_table_node *table, int initial_bits)
- {
- int result = 0;
- int val;
- do {
- val = jbig2_decode_get_code(mmr, table, initial_bits);
- if (val == ERROR)
- return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "invalid code detected in MMR-coded data");
- else if (val == UNCOMPRESSED)
- return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "uncompressed code in MMR-coded data");
- else if (val == ZEROES)
- return jbig2_error(ctx, JBIG2_SEVERITY_FATAL, JBIG2_UNKNOWN_SEGMENT_NUMBER, "zeroes code in MMR-coded data");
- result += val;
- } while (val >= 64);
- return result;
- }
- static int
- jbig2_decode_mmr_line(Jbig2Ctx *ctx, Jbig2MmrCtx *mmr, const byte *ref, byte *dst, int *eofb)
- {
- uint32_t a0 = MINUS1;
- uint32_t a1, a2, b1, b2;
- int c = 0; /* 0 is white, black is 1 */
- while (1) {
- uint32_t word = mmr->word;
- /* printf ("%08x\n", word); */
- if (a0 != MINUS1 && a0 >= mmr->width)
- break;
- if ((word >> (32 - 3)) == 1) {
- int white_run, black_run;
- jbig2_decode_mmr_consume(mmr, 3);
- if (a0 == MINUS1)
- a0 = 0;
- if (c == 0) {
- white_run = jbig2_decode_get_run(ctx, mmr, jbig2_mmr_white_decode, 8);
- if (white_run < 0)
- return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to decode white H run");
- black_run = jbig2_decode_get_run(ctx, mmr, jbig2_mmr_black_decode, 7);
- if (black_run < 0)
- return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to decode black H run");
- /* printf ("H %d %d\n", white_run, black_run); */
- a1 = a0 + white_run;
- a2 = a1 + black_run;
- if (a1 > mmr->width)
- a1 = mmr->width;
- if (a2 > mmr->width)
- a2 = mmr->width;
- if (a2 < a1) {
- jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative black H run");
- a2 = a1;
- }
- if (a1 < mmr->width)
- jbig2_set_bits(dst, a1, a2);
- a0 = a2;
- } else {
- black_run = jbig2_decode_get_run(ctx, mmr, jbig2_mmr_black_decode, 7);
- if (black_run < 0)
- return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to decode black H run");
- white_run = jbig2_decode_get_run(ctx, mmr, jbig2_mmr_white_decode, 8);
- if (white_run < 0)
- return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to decode white H run");
- /* printf ("H %d %d\n", black_run, white_run); */
- a1 = a0 + black_run;
- a2 = a1 + white_run;
- if (a1 > mmr->width)
- a1 = mmr->width;
- if (a2 > mmr->width)
- a2 = mmr->width;
- if (a1 < a0) {
- jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative white H run");
- a1 = a0;
- }
- if (a0 < mmr->width)
- jbig2_set_bits(dst, a0, a1);
- a0 = a2;
- }
- }
- else if ((word >> (32 - 4)) == 1) {
- /* printf ("P\n"); */
- jbig2_decode_mmr_consume(mmr, 4);
- b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
- b2 = jbig2_find_changing_element(ref, b1, mmr->width);
- if (c) {
- if (b2 < a0) {
- jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative P run");
- b2 = a0;
- }
- if (a0 < mmr->width)
- jbig2_set_bits(dst, a0, b2);
- }
- a0 = b2;
- }
- else if ((word >> (32 - 1)) == 1) {
- /* printf ("V(0)\n"); */
- jbig2_decode_mmr_consume(mmr, 1);
- b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
- if (c) {
- if (b1 < a0) {
- jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative V(0) run");
- b1 = a0;
- }
- if (a0 < mmr->width)
- jbig2_set_bits(dst, a0, b1);
- }
- a0 = b1;
- c = !c;
- }
- else if ((word >> (32 - 3)) == 3) {
- /* printf ("VR(1)\n"); */
- jbig2_decode_mmr_consume(mmr, 3);
- b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
- if (b1 + 1 <= mmr->width)
- b1 += 1;
- if (c) {
- if (b1 < a0) {
- jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative VR(1) run");
- b1 = a0;
- }
- if (a0 < mmr->width)
- jbig2_set_bits(dst, a0, b1);
- }
- a0 = b1;
- c = !c;
- }
- else if ((word >> (32 - 6)) == 3) {
- /* printf ("VR(2)\n"); */
- jbig2_decode_mmr_consume(mmr, 6);
- b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
- if (b1 + 2 <= mmr->width)
- b1 += 2;
- if (c) {
- if (b1 < a0) {
- jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative VR(2) run");
- b1 = a0;
- }
- if (a0 < mmr->width)
- jbig2_set_bits(dst, a0, b1);
- }
- a0 = b1;
- c = !c;
- }
- else if ((word >> (32 - 7)) == 3) {
- /* printf ("VR(3)\n"); */
- jbig2_decode_mmr_consume(mmr, 7);
- b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
- if (b1 + 3 <= mmr->width)
- b1 += 3;
- if (c) {
- if (b1 < a0) {
- jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative VR(3) run");
- b1 = a0;
- }
- if (a0 < mmr->width)
- jbig2_set_bits(dst, a0, b1);
- }
- a0 = b1;
- c = !c;
- }
- else if ((word >> (32 - 3)) == 2) {
- /* printf ("VL(1)\n"); */
- jbig2_decode_mmr_consume(mmr, 3);
- b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
- if (b1 >= 1)
- b1 -= 1;
- if (c) {
- if (b1 < a0) {
- jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative VL(1) run");
- b1 = a0;
- }
- if (a0 < mmr->width)
- jbig2_set_bits(dst, a0, b1);
- }
- a0 = b1;
- c = !c;
- }
- else if ((word >> (32 - 6)) == 2) {
- /* printf ("VL(2)\n"); */
- jbig2_decode_mmr_consume(mmr, 6);
- b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
- if (b1 >= 2)
- b1 -= 2;
- if (c) {
- if (b1 < a0) {
- jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative VL(2) run");
- b1 = a0;
- }
- if (a0 < mmr->width)
- jbig2_set_bits(dst, a0, b1);
- }
- a0 = b1;
- c = !c;
- }
- else if ((word >> (32 - 7)) == 2) {
- /* printf ("VL(3)\n"); */
- jbig2_decode_mmr_consume(mmr, 7);
- b1 = jbig2_find_changing_element_of_color(ref, a0, mmr->width, !c);
- if (b1 >= 3)
- b1 -= 3;
- if (c) {
- if (b1 < a0) {
- jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "ignoring negative VL(3) run");
- b1 = a0;
- }
- if (a0 < mmr->width)
- jbig2_set_bits(dst, a0, b1);
- }
- a0 = b1;
- c = !c;
- }
- else if ((word >> (32 - 24)) == 0x1001) {
- /* printf ("EOFB\n"); */
- jbig2_decode_mmr_consume(mmr, 24);
- *eofb = 1;
- break;
- }
- else
- break;
- }
- return 0;
- }
- int
- jbig2_decode_generic_mmr(Jbig2Ctx *ctx, Jbig2Segment *segment, const Jbig2GenericRegionParams *params, const byte *data, size_t size, Jbig2Image *image)
- {
- Jbig2MmrCtx mmr;
- const uint32_t rowstride = image->stride;
- byte *dst = image->data;
- byte *ref = NULL;
- uint32_t y;
- int code = 0;
- int eofb = 0;
- jbig2_decode_mmr_init(&mmr, image->width, image->height, data, size);
- for (y = 0; !eofb && y < image->height; y++) {
- memset(dst, 0, rowstride);
- code = jbig2_decode_mmr_line(ctx, &mmr, ref, dst, &eofb);
- if (code < 0)
- return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, segment->number, "failed to decode mmr line");
- ref = dst;
- dst += rowstride;
- }
- if (eofb && y < image->height) {
- memset(dst, 0, rowstride * (image->height - y));
- }
- return code;
- }
- /**
- * jbig2_decode_halftone_mmr: decode mmr region inside of halftones
- *
- * @ctx: jbig2 decoder context
- * @params: parameters for decoding
- * @data: pointer to text region data to be decoded
- * @size: length of text region data
- * @image: return of decoded image
- * @consumed_bytes: return of consumed bytes from @data
- *
- * MMR decoding that consumes EOFB and returns consumed bytes (@consumed_bytes)
- *
- * returns: 0
- **/
- int
- jbig2_decode_halftone_mmr(Jbig2Ctx *ctx, const Jbig2GenericRegionParams *params, const byte *data, size_t size, Jbig2Image *image, size_t *consumed_bytes)
- {
- Jbig2MmrCtx mmr;
- const uint32_t rowstride = image->stride;
- byte *dst = image->data;
- byte *ref = NULL;
- uint32_t y;
- int code = 0;
- const uint32_t EOFB = 0x001001;
- int eofb = 0;
- jbig2_decode_mmr_init(&mmr, image->width, image->height, data, size);
- for (y = 0; !eofb && y < image->height; y++) {
- memset(dst, 0, rowstride);
- code = jbig2_decode_mmr_line(ctx, &mmr, ref, dst, &eofb);
- if (code < 0)
- return jbig2_error(ctx, JBIG2_SEVERITY_WARNING, JBIG2_UNKNOWN_SEGMENT_NUMBER, "failed to decode halftone mmr line");
- ref = dst;
- dst += rowstride;
- }
- if (eofb && y < image->height) {
- memset(dst, 0, rowstride * (image->height - y));
- }
- /* test for EOFB (see section 6.2.6) */
- if (mmr.word >> 8 == EOFB) {
- jbig2_decode_mmr_consume(&mmr, 24);
- }
- *consumed_bytes += (mmr.consumed_bits + 7) / 8;
- return code;
- }
|