1
//========================================================================
5
// Copyright 2002-2003 Glyph & Cog, LLC
7
//========================================================================
9
//========================================================================
11
// Modified under the Poppler project - http://poppler.freedesktop.org
13
// All changes made under the Poppler project to this file are licensed
14
// under GPL version 2 or later
16
// Copyright (C) 2006 Raj Kumar <rkumar@archive.org>
17
// Copyright (C) 2006 Paul Walmsley <paul@booyaka.com>
18
// Copyright (C) 2006-2010 Albert Astals Cid <aacid@kde.org>
19
// Copyright (C) 2009 David Benjamin <davidben@mit.edu>
20
// Copyright (C) 2011 Edward Jiang <ejiang@google.com>
22
// To see a description of the changes please see the Changelog file that
23
// came with your tarball or type make ChangeLog if you are building from git
25
//========================================================================
29
#ifdef USE_GCC_PRAGMAS
30
#pragma implementation
35
#include "goo/GooList.h"
37
#include "JArithmeticDecoder.h"
38
#include "JBIG2Stream.h"
40
//~ share these tables
41
#include "Stream-CCITT.h"
43
//------------------------------------------------------------------------
45
static const int contextSize[4] = { 16, 13, 10, 10 };
46
static const int refContextSize[2] = { 13, 10 };
48
//------------------------------------------------------------------------
50
//------------------------------------------------------------------------
52
#define jbig2HuffmanLOW 0xfffffffd
53
#define jbig2HuffmanOOB 0xfffffffe
54
#define jbig2HuffmanEOT 0xffffffff
56
struct JBIG2HuffmanTable {
59
Guint rangeLen; // can also be LOW, OOB, or EOT
63
static JBIG2HuffmanTable huffTableA[] = {
66
{ 272, 3, 16, 0x006 },
67
{ 65808, 3, 32, 0x007 },
68
{ 0, 0, jbig2HuffmanEOT, 0 }
71
static JBIG2HuffmanTable huffTableB[] = {
78
{ 0, 6, jbig2HuffmanOOB, 0x03f },
79
{ 0, 0, jbig2HuffmanEOT, 0 }
82
static JBIG2HuffmanTable huffTableC[] = {
88
{ 0, 6, jbig2HuffmanOOB, 0x03e },
90
{ -256, 8, 8, 0x0fe },
91
{ -257, 8, jbig2HuffmanLOW, 0x0ff },
92
{ 0, 0, jbig2HuffmanEOT, 0 }
95
static JBIG2HuffmanTable huffTableD[] = {
101
{ 76, 5, 32, 0x01f },
102
{ 0, 0, jbig2HuffmanEOT, 0 }
105
static JBIG2HuffmanTable huffTableE[] = {
111
{ 76, 6, 32, 0x03e },
112
{ -255, 7, 8, 0x07e },
113
{ -256, 7, jbig2HuffmanLOW, 0x07f },
114
{ 0, 0, jbig2HuffmanEOT, 0 }
117
static JBIG2HuffmanTable huffTableF[] = {
119
{ 128, 3, 7, 0x002 },
120
{ 256, 3, 8, 0x003 },
121
{ -1024, 4, 9, 0x008 },
122
{ -512, 4, 8, 0x009 },
123
{ -256, 4, 7, 0x00a },
124
{ -32, 4, 5, 0x00b },
125
{ 512, 4, 9, 0x00c },
126
{ 1024, 4, 10, 0x00d },
127
{ -2048, 5, 10, 0x01c },
128
{ -128, 5, 6, 0x01d },
129
{ -64, 5, 5, 0x01e },
130
{ -2049, 6, jbig2HuffmanLOW, 0x03e },
131
{ 2048, 6, 32, 0x03f },
132
{ 0, 0, jbig2HuffmanEOT, 0 }
135
static JBIG2HuffmanTable huffTableG[] = {
136
{ -512, 3, 8, 0x000 },
137
{ 256, 3, 8, 0x001 },
138
{ 512, 3, 9, 0x002 },
139
{ 1024, 3, 10, 0x003 },
140
{ -1024, 4, 9, 0x008 },
141
{ -256, 4, 7, 0x009 },
142
{ -32, 4, 5, 0x00a },
144
{ 128, 4, 7, 0x00c },
145
{ -128, 5, 6, 0x01a },
146
{ -64, 5, 5, 0x01b },
149
{ -1025, 5, jbig2HuffmanLOW, 0x01e },
150
{ 2048, 5, 32, 0x01f },
151
{ 0, 0, jbig2HuffmanEOT, 0 }
154
static JBIG2HuffmanTable huffTableH[] = {
156
{ 0, 2, jbig2HuffmanOOB, 0x001 },
163
{ 134, 5, 7, 0x01c },
166
{ 262, 6, 7, 0x03c },
167
{ 646, 6, 10, 0x03d },
169
{ 390, 7, 8, 0x07d },
170
{ -15, 8, 3, 0x0fc },
174
{ -16, 9, jbig2HuffmanLOW, 0x1fe },
175
{ 1670, 9, 32, 0x1ff },
176
{ 0, 0, jbig2HuffmanEOT, 0 }
179
static JBIG2HuffmanTable huffTableI[] = {
180
{ 0, 2, jbig2HuffmanOOB, 0x000 },
188
{ 139, 5, 7, 0x01b },
189
{ 267, 5, 8, 0x01c },
192
{ 523, 6, 8, 0x03c },
193
{ 1291, 6, 11, 0x03d },
195
{ 779, 7, 9, 0x07d },
196
{ -31, 8, 4, 0x0fc },
197
{ -11, 8, 2, 0x0fd },
198
{ -15, 9, 2, 0x1fc },
200
{ -32, 9, jbig2HuffmanLOW, 0x1fe },
201
{ 3339, 9, 32, 0x1ff },
202
{ 0, 0, jbig2HuffmanEOT, 0 }
205
static JBIG2HuffmanTable huffTableJ[] = {
208
{ 0, 2, jbig2HuffmanOOB, 0x002 },
213
{ 102, 6, 5, 0x037 },
214
{ 134, 6, 6, 0x038 },
215
{ 198, 6, 7, 0x039 },
216
{ 326, 6, 8, 0x03a },
217
{ 582, 6, 9, 0x03b },
218
{ 1094, 6, 10, 0x03c },
219
{ -21, 7, 4, 0x07a },
222
{ 2118, 7, 11, 0x07d },
225
{ -22, 8, jbig2HuffmanLOW, 0x0fe },
226
{ 4166, 8, 32, 0x0ff },
227
{ 0, 0, jbig2HuffmanEOT, 0 }
230
static JBIG2HuffmanTable huffTableK[] = {
243
{ 141, 7, 32, 0x07f },
244
{ 0, 0, jbig2HuffmanEOT, 0 }
247
static JBIG2HuffmanTable huffTableL[] = {
260
{ 73, 8, 32, 0x0ff },
261
{ 0, 0, jbig2HuffmanEOT, 0 }
264
static JBIG2HuffmanTable huffTableM[] = {
277
{ 141, 7, 32, 0x07f },
278
{ 0, 0, jbig2HuffmanEOT, 0 }
281
static JBIG2HuffmanTable huffTableN[] = {
287
{ 0, 0, jbig2HuffmanEOT, 0 }
290
static JBIG2HuffmanTable huffTableO[] = {
300
{ -24, 7, 4, 0x07c },
302
{ -25, 7, jbig2HuffmanLOW, 0x07e },
303
{ 25, 7, 32, 0x07f },
304
{ 0, 0, jbig2HuffmanEOT, 0 }
307
//------------------------------------------------------------------------
308
// JBIG2HuffmanDecoder
309
//------------------------------------------------------------------------
311
class JBIG2HuffmanDecoder {
314
JBIG2HuffmanDecoder();
315
~JBIG2HuffmanDecoder();
316
void setStream(Stream *strA) { str = strA; }
320
// Returns false for OOB, otherwise sets *<x> and returns true.
321
GBool decodeInt(int *x, JBIG2HuffmanTable *table);
323
Guint readBits(Guint n);
326
// Sort the table by prefix length and assign prefix values.
327
void buildTable(JBIG2HuffmanTable *table, Guint len);
336
JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
341
JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {
344
void JBIG2HuffmanDecoder::reset() {
350
GBool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) {
351
Guint i, len, prefix;
356
while (table[i].rangeLen != jbig2HuffmanEOT) {
357
while (len < table[i].prefixLen) {
358
prefix = (prefix << 1) | readBit();
361
if (prefix == table[i].prefix) {
362
if (table[i].rangeLen == jbig2HuffmanOOB) {
365
if (table[i].rangeLen == jbig2HuffmanLOW) {
366
*x = table[i].val - readBits(32);
367
} else if (table[i].rangeLen > 0) {
368
*x = table[i].val + readBits(table[i].rangeLen);
379
Guint JBIG2HuffmanDecoder::readBits(Guint n) {
380
Guint x, mask, nLeft;
382
mask = (n == 32) ? 0xffffffff : ((1 << n) - 1);
384
x = (buf >> (bufLen - n)) & mask;
387
x = buf & ((1 << bufLen) - 1);
391
x = (x << 8) | (str->getChar() & 0xff);
395
buf = str->getChar();
397
x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1));
403
Guint JBIG2HuffmanDecoder::readBit() {
405
buf = str->getChar();
409
return (buf >> bufLen) & 1;
412
void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {
413
Guint i, j, k, prefix;
414
JBIG2HuffmanTable tab;
416
// stable selection sort:
417
// - entries with prefixLen > 0, in ascending prefixLen order
418
// - entry with prefixLen = 0, rangeLen = EOT
419
// - all other entries with prefixLen = 0
420
// (on entry, table[len] has prefixLen = 0, rangeLen = EOT)
421
for (i = 0; i < len; ++i) {
422
for (j = i; j < len && table[j].prefixLen == 0; ++j) ;
426
for (k = j + 1; k < len; ++k) {
427
if (table[k].prefixLen > 0 &&
428
table[k].prefixLen < table[j].prefixLen) {
434
for (k = j; k > i; --k) {
435
table[k] = table[k - 1];
440
table[i] = table[len];
443
if (table[0].rangeLen != jbig2HuffmanEOT) {
446
table[i++].prefix = prefix++;
447
for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) {
448
prefix <<= table[i].prefixLen - table[i-1].prefixLen;
449
table[i].prefix = prefix++;
454
//------------------------------------------------------------------------
456
//------------------------------------------------------------------------
458
class JBIG2MMRDecoder {
463
void setStream(Stream *strA) { str = strA; }
469
void skipTo(Guint length);
479
JBIG2MMRDecoder::JBIG2MMRDecoder() {
484
JBIG2MMRDecoder::~JBIG2MMRDecoder() {
487
void JBIG2MMRDecoder::reset() {
493
int JBIG2MMRDecoder::get2DCode() {
497
buf = str->getChar() & 0xff;
500
p = &twoDimTab1[(buf >> 1) & 0x7f];
501
} else if (bufLen == 8) {
502
p = &twoDimTab1[(buf >> 1) & 0x7f];
504
p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f];
505
if (p->bits < 0 || p->bits > (int)bufLen) {
506
buf = (buf << 8) | (str->getChar() & 0xff);
509
p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
513
error(str->getPos(), "Bad two dim code in JBIG2 MMR stream");
520
int JBIG2MMRDecoder::getWhiteCode() {
525
buf = str->getChar() & 0xff;
530
if (bufLen >= 11 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
532
code = buf << (12 - bufLen);
534
code = buf >> (bufLen - 12);
536
p = &whiteTab1[code & 0x1f];
539
code = buf << (9 - bufLen);
541
code = buf >> (bufLen - 9);
543
p = &whiteTab2[code & 0x1ff];
545
if (p->bits > 0 && p->bits <= (int)bufLen) {
552
buf = (buf << 8) | (str->getChar() & 0xff);
556
error(str->getPos(), "Bad white code in JBIG2 MMR stream");
557
// eat a bit and return a positive number so that the caller doesn't
558
// go into an infinite loop
563
int JBIG2MMRDecoder::getBlackCode() {
568
buf = str->getChar() & 0xff;
573
if (bufLen >= 10 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
575
code = buf << (13 - bufLen);
577
code = buf >> (bufLen - 13);
579
p = &blackTab1[code & 0x7f];
580
} else if (bufLen >= 7 && ((buf >> (bufLen - 4)) & 0x0f) == 0 &&
581
((buf >> (bufLen - 6)) & 0x03) != 0) {
583
code = buf << (12 - bufLen);
585
code = buf >> (bufLen - 12);
587
p = &blackTab2[(code & 0xff) - 64];
590
code = buf << (6 - bufLen);
592
code = buf >> (bufLen - 6);
594
p = &blackTab3[code & 0x3f];
596
if (p->bits > 0 && p->bits <= (int)bufLen) {
603
buf = (buf << 8) | (str->getChar() & 0xff);
607
error(str->getPos(), "Bad black code in JBIG2 MMR stream");
608
// eat a bit and return a positive number so that the caller doesn't
609
// go into an infinite loop
614
Guint JBIG2MMRDecoder::get24Bits() {
615
while (bufLen < 24) {
616
buf = (buf << 8) | (str->getChar() & 0xff);
620
return (buf >> (bufLen - 24)) & 0xffffff;
623
void JBIG2MMRDecoder::skipTo(Guint length) {
624
while (nBytesRead < length) {
630
//------------------------------------------------------------------------
632
//------------------------------------------------------------------------
634
enum JBIG2SegmentType {
644
JBIG2Segment(Guint segNumA) { segNum = segNumA; }
645
virtual ~JBIG2Segment() {}
646
void setSegNum(Guint segNumA) { segNum = segNumA; }
647
Guint getSegNum() { return segNum; }
648
virtual JBIG2SegmentType getType() = 0;
655
//------------------------------------------------------------------------
657
//------------------------------------------------------------------------
659
struct JBIG2BitmapPtr {
665
class JBIG2Bitmap: public JBIG2Segment {
668
JBIG2Bitmap(Guint segNumA, int wA, int hA);
669
virtual ~JBIG2Bitmap();
670
virtual JBIG2SegmentType getType() { return jbig2SegBitmap; }
671
JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); }
672
JBIG2Bitmap *getSlice(Guint x, Guint y, Guint wA, Guint hA);
673
void expand(int newH, Guint pixel);
676
int getWidth() { return w; }
677
int getHeight() { return h; }
678
int getPixel(int x, int y)
679
{ return (x < 0 || x >= w || y < 0 || y >= h) ? 0 :
680
(data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; }
681
void setPixel(int x, int y)
682
{ data[y * line + (x >> 3)] |= 1 << (7 - (x & 7)); }
683
void clearPixel(int x, int y)
684
{ data[y * line + (x >> 3)] &= 0x7f7f >> (x & 7); }
685
void getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr);
686
int nextPixel(JBIG2BitmapPtr *ptr);
687
void duplicateRow(int yDest, int ySrc);
688
void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);
689
Guchar *getDataPtr() { return data; }
690
int getDataSize() { return h * line; }
691
GBool isOk() { return data != NULL; }
695
JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap);
701
JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA):
702
JBIG2Segment(segNumA)
706
line = (wA + 7) >> 3;
708
if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
709
error(-1, "invalid width/height");
713
// need to allocate one extra guard byte for use in combine()
714
data = (Guchar *)gmalloc(h * line + 1);
718
JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
719
JBIG2Segment(segNumA)
725
if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
726
error(-1, "invalid width/height");
730
// need to allocate one extra guard byte for use in combine()
731
data = (Guchar *)gmalloc(h * line + 1);
732
memcpy(data, bitmap->data, h * line);
736
JBIG2Bitmap::~JBIG2Bitmap() {
741
JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
745
slice = new JBIG2Bitmap(0, wA, hA);
747
slice->clearToZero();
748
for (yy = 0; yy < hA; ++yy) {
749
for (xx = 0; xx < wA; ++xx) {
750
if (getPixel(x + xx, y + yy)) {
751
slice->setPixel(xx, yy);
762
void JBIG2Bitmap::expand(int newH, Guint pixel) {
763
if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) {
764
error(-1, "invalid width/height");
769
// need to allocate one extra guard byte for use in combine()
770
data = (Guchar *)grealloc(data, newH * line + 1);
772
memset(data + h * line, 0xff, (newH - h) * line);
774
memset(data + h * line, 0x00, (newH - h) * line);
780
void JBIG2Bitmap::clearToZero() {
781
memset(data, 0, h * line);
784
void JBIG2Bitmap::clearToOne() {
785
memset(data, 0xff, h * line);
788
inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) {
789
if (y < 0 || y >= h || x >= w) {
791
ptr->shift = 0; // make gcc happy
792
ptr->x = 0; // make gcc happy
794
ptr->p = &data[y * line];
798
ptr->p = &data[y * line + (x >> 3)];
799
ptr->shift = 7 - (x & 7);
804
inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr *ptr) {
809
} else if (ptr->x < 0) {
813
pix = (*ptr->p >> ptr->shift) & 1;
816
} else if (ptr->shift == 0) {
826
void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) {
827
memcpy(data + yDest * line, data + ySrc * line, line);
830
void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
832
int x0, x1, y0, y1, xx, yy;
833
Guchar *srcPtr, *destPtr;
834
Guint src0, src1, src, dest, s1, s2, m1, m2, m3;
837
// check for the pathological case where y = -2^31
838
if (y < -0x7fffffff) {
846
if (y + bitmap->h > h) {
870
m1 = 0xff >> (x1 & 7);
871
m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7));
872
m3 = (0xff >> s1) & m2;
874
oneByte = x0 == ((x1 - 1) & ~7);
876
for (yy = y0; yy < y1; ++yy) {
878
// one byte per line -- need to mask both left and right side
881
destPtr = data + (y + yy) * line + (x >> 3);
882
srcPtr = bitmap->data + yy * bitmap->line;
887
dest |= (src1 >> s1) & m2;
890
dest &= ((0xff00 | src1) >> s1) | m1;
893
dest ^= (src1 >> s1) & m2;
896
dest ^= ((src1 ^ 0xff) >> s1) & m2;
899
dest = (dest & ~m3) | ((src1 >> s1) & m3);
904
destPtr = data + (y + yy) * line;
905
srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
919
dest ^= (src1 ^ 0xff) & m2;
922
dest = (src1 & m2) | (dest & m1);
928
// multiple bytes per line -- need to mask left side of left-most
929
// byte and right side of right-most byte
934
destPtr = data + (y + yy) * line + (x >> 3);
935
srcPtr = bitmap->data + yy * bitmap->line;
943
dest &= (0xff00 | src1) >> s1;
949
dest ^= (src1 ^ 0xff) >> s1;
952
dest = (dest & (0xff << s2)) | (src1 >> s1);
958
destPtr = data + (y + yy) * line;
959
srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
965
for (; xx < x1 - 8; xx += 8) {
969
src = (((src0 << 8) | src1) >> s1) & 0xff;
991
// note: this last byte (src1) may not actually be used, depending
992
// on the values of s1, m1, and m2 - and in fact, it may be off
993
// the edge of the source bitmap, which means we need to allocate
994
// one extra guard byte at the end of each bitmap
998
src = (((src0 << 8) | src1) >> s1) & 0xff;
1010
dest ^= (src ^ 0xff) & m2;
1013
dest = (src & m2) | (dest & m1);
1021
//------------------------------------------------------------------------
1023
//------------------------------------------------------------------------
1025
class JBIG2SymbolDict: public JBIG2Segment {
1028
JBIG2SymbolDict(Guint segNumA, Guint sizeA);
1029
virtual ~JBIG2SymbolDict();
1030
virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; }
1031
Guint getSize() { return size; }
1032
void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1033
JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1034
GBool isOk() { return bitmaps != NULL; }
1035
void setGenericRegionStats(JArithmeticDecoderStats *stats)
1036
{ genericRegionStats = stats; }
1037
void setRefinementRegionStats(JArithmeticDecoderStats *stats)
1038
{ refinementRegionStats = stats; }
1039
JArithmeticDecoderStats *getGenericRegionStats()
1040
{ return genericRegionStats; }
1041
JArithmeticDecoderStats *getRefinementRegionStats()
1042
{ return refinementRegionStats; }
1047
JBIG2Bitmap **bitmaps;
1048
JArithmeticDecoderStats *genericRegionStats;
1049
JArithmeticDecoderStats *refinementRegionStats;
1052
JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
1053
JBIG2Segment(segNumA)
1056
bitmaps = (JBIG2Bitmap **)gmallocn_checkoverflow(size, sizeof(JBIG2Bitmap *));
1057
if (!bitmaps) size = 0;
1058
genericRegionStats = NULL;
1059
refinementRegionStats = NULL;
1062
JBIG2SymbolDict::~JBIG2SymbolDict() {
1065
for (i = 0; i < size; ++i) {
1069
if (genericRegionStats) {
1070
delete genericRegionStats;
1072
if (refinementRegionStats) {
1073
delete refinementRegionStats;
1077
//------------------------------------------------------------------------
1079
//------------------------------------------------------------------------
1081
class JBIG2PatternDict: public JBIG2Segment {
1084
JBIG2PatternDict(Guint segNumA, Guint sizeA);
1085
virtual ~JBIG2PatternDict();
1086
virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }
1087
Guint getSize() { return size; }
1088
void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1089
JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1094
JBIG2Bitmap **bitmaps;
1097
JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA):
1098
JBIG2Segment(segNumA)
1101
bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
1104
JBIG2PatternDict::~JBIG2PatternDict() {
1107
for (i = 0; i < size; ++i) {
1113
//------------------------------------------------------------------------
1115
//------------------------------------------------------------------------
1117
class JBIG2CodeTable: public JBIG2Segment {
1120
JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA);
1121
virtual ~JBIG2CodeTable();
1122
virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; }
1123
JBIG2HuffmanTable *getHuffTable() { return table; }
1127
JBIG2HuffmanTable *table;
1130
JBIG2CodeTable::JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA):
1131
JBIG2Segment(segNumA)
1136
JBIG2CodeTable::~JBIG2CodeTable() {
1140
//------------------------------------------------------------------------
1142
//------------------------------------------------------------------------
1144
JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStreamA):
1149
arithDecoder = new JArithmeticDecoder();
1150
genericRegionStats = new JArithmeticDecoderStats(1 << 1);
1151
refinementRegionStats = new JArithmeticDecoderStats(1 << 1);
1152
iadhStats = new JArithmeticDecoderStats(1 << 9);
1153
iadwStats = new JArithmeticDecoderStats(1 << 9);
1154
iaexStats = new JArithmeticDecoderStats(1 << 9);
1155
iaaiStats = new JArithmeticDecoderStats(1 << 9);
1156
iadtStats = new JArithmeticDecoderStats(1 << 9);
1157
iaitStats = new JArithmeticDecoderStats(1 << 9);
1158
iafsStats = new JArithmeticDecoderStats(1 << 9);
1159
iadsStats = new JArithmeticDecoderStats(1 << 9);
1160
iardxStats = new JArithmeticDecoderStats(1 << 9);
1161
iardyStats = new JArithmeticDecoderStats(1 << 9);
1162
iardwStats = new JArithmeticDecoderStats(1 << 9);
1163
iardhStats = new JArithmeticDecoderStats(1 << 9);
1164
iariStats = new JArithmeticDecoderStats(1 << 9);
1165
iaidStats = new JArithmeticDecoderStats(1 << 1);
1166
huffDecoder = new JBIG2HuffmanDecoder();
1167
mmrDecoder = new JBIG2MMRDecoder();
1169
globalsStreamA->copy(&globalsStream);
1170
segments = globalSegments = NULL;
1172
dataPtr = dataEnd = NULL;
1175
JBIG2Stream::~JBIG2Stream() {
1177
globalsStream.free();
1178
delete arithDecoder;
1179
delete genericRegionStats;
1180
delete refinementRegionStats;
1200
void JBIG2Stream::reset() {
1201
// read the globals stream
1202
globalSegments = new GooList();
1203
if (globalsStream.isStream()) {
1204
segments = globalSegments;
1205
curStr = globalsStream.getStream();
1207
arithDecoder->setStream(curStr);
1208
huffDecoder->setStream(curStr);
1209
mmrDecoder->setStream(curStr);
1214
// read the main stream
1215
segments = new GooList();
1218
arithDecoder->setStream(curStr);
1219
huffDecoder->setStream(curStr);
1220
mmrDecoder->setStream(curStr);
1224
dataPtr = pageBitmap->getDataPtr();
1225
dataEnd = dataPtr + pageBitmap->getDataSize();
1227
dataPtr = dataEnd = NULL;
1231
void JBIG2Stream::close() {
1237
deleteGooList(segments, JBIG2Segment);
1240
if (globalSegments) {
1241
deleteGooList(globalSegments, JBIG2Segment);
1242
globalSegments = NULL;
1244
dataPtr = dataEnd = NULL;
1245
FilterStream::close();
1248
int JBIG2Stream::getChar() {
1249
if (dataPtr && dataPtr < dataEnd) {
1250
return (*dataPtr++ ^ 0xff) & 0xff;
1255
int JBIG2Stream::lookChar() {
1256
if (dataPtr && dataPtr < dataEnd) {
1257
return (*dataPtr ^ 0xff) & 0xff;
1262
int JBIG2Stream::getPos() {
1263
if (pageBitmap == NULL) {
1266
return dataPtr - pageBitmap->getDataPtr();
1269
GooString *JBIG2Stream::getPSFilter(int psLevel, char *indent) {
1273
GBool JBIG2Stream::isBinary(GBool last) {
1274
return str->isBinary(gTrue);
1277
void JBIG2Stream::readSegments() {
1278
Guint segNum, segFlags, segType, page, segLength;
1279
Guint refFlags, nRefSegs;
1285
while (readULong(&segNum)) {
1287
// segment header flags
1288
if (!readUByte(&segFlags)) {
1291
segType = segFlags & 0x3f;
1293
// referred-to segment count and retention flags
1294
if (!readUByte(&refFlags)) {
1297
nRefSegs = refFlags >> 5;
1298
if (nRefSegs == 7) {
1299
if ((c1 = curStr->getChar()) == EOF ||
1300
(c2 = curStr->getChar()) == EOF ||
1301
(c3 = curStr->getChar()) == EOF) {
1304
refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3;
1305
nRefSegs = refFlags & 0x1fffffff;
1306
for (i = 0; i < (nRefSegs + 9) >> 3; ++i) {
1307
c1 = curStr->getChar();
1311
// referred-to segment numbers
1312
refSegs = (Guint *)gmallocn(nRefSegs, sizeof(Guint));
1313
if (segNum <= 256) {
1314
for (i = 0; i < nRefSegs; ++i) {
1315
if (!readUByte(&refSegs[i])) {
1319
} else if (segNum <= 65536) {
1320
for (i = 0; i < nRefSegs; ++i) {
1321
if (!readUWord(&refSegs[i])) {
1326
for (i = 0; i < nRefSegs; ++i) {
1327
if (!readULong(&refSegs[i])) {
1333
// segment page association
1334
if (segFlags & 0x40) {
1335
if (!readULong(&page)) {
1339
if (!readUByte(&page)) {
1344
// segment data length
1345
if (!readULong(&segLength)) {
1349
// keep track of the start of the segment data
1350
segDataPos = curStr->getPos();
1352
// check for missing page information segment
1353
if (!pageBitmap && ((segType >= 4 && segType <= 7) ||
1354
(segType >= 20 && segType <= 43))) {
1355
error(curStr->getPos(), "First JBIG2 segment associated with a page must be a page information segment");
1359
// read the segment data
1362
if (!readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs)) {
1367
readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
1370
readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs);
1373
readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs);
1376
readPatternDictSeg(segNum, segLength);
1379
readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength,
1383
readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength,
1387
readHalftoneRegionSeg(segNum, gTrue, gTrue, segLength,
1391
readGenericRegionSeg(segNum, gFalse, gFalse, segLength);
1394
readGenericRegionSeg(segNum, gTrue, gFalse, segLength);
1397
readGenericRegionSeg(segNum, gTrue, gTrue, segLength);
1400
readGenericRefinementRegionSeg(segNum, gFalse, gFalse, segLength,
1404
readGenericRefinementRegionSeg(segNum, gTrue, gFalse, segLength,
1408
readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength,
1412
readPageInfoSeg(segLength);
1415
readEndOfStripeSeg(segLength);
1418
readProfilesSeg(segLength);
1421
readCodeTableSeg(segNum, segLength);
1424
readExtensionSeg(segLength);
1427
error(curStr->getPos(), "Unknown segment type in JBIG2 stream");
1428
for (i = 0; i < segLength; ++i) {
1429
if ((c1 = curStr->getChar()) == EOF) {
1436
// Make sure the segment handler read all of the bytes in the
1437
// segment data, unless this segment is marked as having an
1438
// unknown length (section 7.2.7 of the JBIG2 Final Committee Draft)
1440
if (segLength != 0xffffffff) {
1442
int segExtraBytes = segDataPos + segLength - curStr->getPos();
1443
if (segExtraBytes > 0) {
1445
// If we didn't read all of the bytes in the segment data,
1446
// indicate an error, and throw away the rest of the data.
1448
// v.3.1.01.13 of the LuraTech PDF Compressor Server will
1449
// sometimes generate an extraneous NULL byte at the end of
1450
// arithmetic-coded symbol dictionary segments when numNewSyms
1451
// == 0. Segments like this often occur for blank pages.
1453
error(curStr->getPos(), "%d extraneous byte%s after segment",
1454
segExtraBytes, (segExtraBytes > 1) ? "s" : "");
1456
// Burn through the remaining bytes -- inefficient, but
1457
// hopefully we're not doing this much
1460
for (int i = segExtraBytes; i > 0; i--) {
1464
} else if (segExtraBytes < 0) {
1466
// If we read more bytes than we should have, according to the
1467
// segment length field, note an error.
1469
error(curStr->getPos(), "Previous segment handler read too many bytes");
1487
error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
1490
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
1491
Guint *refSegs, Guint nRefSegs) {
1492
JBIG2SymbolDict *symbolDict;
1493
JBIG2HuffmanTable *huffDHTable, *huffDWTable;
1494
JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
1496
GooList *codeTables;
1497
JBIG2SymbolDict *inputSymbolDict;
1498
Guint flags, sdTemplate, sdrTemplate, huff, refAgg;
1499
Guint huffDH, huffDW, huffBMSize, huffAggInst;
1500
Guint contextUsed, contextRetained;
1501
int sdATX[4], sdATY[4], sdrATX[2], sdrATY[2];
1502
Guint numExSyms, numNewSyms, numInputSyms, symCodeLen;
1503
JBIG2Bitmap **bitmaps;
1504
JBIG2Bitmap *collBitmap, *refBitmap;
1506
Guint symHeight, symWidth, totalWidth, x, symID;
1507
int dh, dw, refAggNum, refDX, refDY, bmSize;
1515
// symbol dictionary flags
1516
if (!readUWord(&flags)) {
1519
sdTemplate = (flags >> 10) & 3;
1520
sdrTemplate = (flags >> 12) & 1;
1522
refAgg = (flags >> 1) & 1;
1523
huffDH = (flags >> 2) & 3;
1524
huffDW = (flags >> 4) & 3;
1525
huffBMSize = (flags >> 6) & 1;
1526
huffAggInst = (flags >> 7) & 1;
1527
contextUsed = (flags >> 8) & 1;
1528
contextRetained = (flags >> 9) & 1;
1530
// symbol dictionary AT flags
1532
if (sdTemplate == 0) {
1533
if (!readByte(&sdATX[0]) ||
1534
!readByte(&sdATY[0]) ||
1535
!readByte(&sdATX[1]) ||
1536
!readByte(&sdATY[1]) ||
1537
!readByte(&sdATX[2]) ||
1538
!readByte(&sdATY[2]) ||
1539
!readByte(&sdATX[3]) ||
1540
!readByte(&sdATY[3])) {
1544
if (!readByte(&sdATX[0]) ||
1545
!readByte(&sdATY[0])) {
1551
// symbol dictionary refinement AT flags
1552
if (refAgg && !sdrTemplate) {
1553
if (!readByte(&sdrATX[0]) ||
1554
!readByte(&sdrATY[0]) ||
1555
!readByte(&sdrATX[1]) ||
1556
!readByte(&sdrATY[1])) {
1561
// SDNUMEXSYMS and SDNUMNEWSYMS
1562
if (!readULong(&numExSyms) || !readULong(&numNewSyms)) {
1566
// get referenced segments: input symbol dictionaries and code tables
1567
codeTables = new GooList();
1569
for (i = 0; i < nRefSegs; ++i) {
1570
// This is need by bug 12014, returning gFalse makes it not crash
1571
// but we end up with a empty page while acroread is able to render
1573
if ((seg = findSegment(refSegs[i]))) {
1574
if (seg->getType() == jbig2SegSymbolDict) {
1575
j = ((JBIG2SymbolDict *)seg)->getSize();
1576
if (numInputSyms > UINT_MAX - j) {
1577
error(curStr->getPos(), "Too many input symbols in JBIG2 symbol dictionary");
1582
} else if (seg->getType() == jbig2SegCodeTable) {
1583
codeTables->append(seg);
1590
if (numInputSyms > UINT_MAX - numNewSyms) {
1591
error(curStr->getPos(), "Too many input symbols in JBIG2 symbol dictionary");
1596
// compute symbol code length, per 6.5.8.2.3
1597
// symCodeLen = ceil( log2( numInputSyms + numNewSyms ) )
1599
if (likely(numInputSyms + numNewSyms > 0)) { // don't fail too badly if the sum is 0
1600
i = (numInputSyms + numNewSyms - 1) >> 1;
1607
// get the input symbol bitmaps
1608
bitmaps = (JBIG2Bitmap **)gmallocn(numInputSyms + numNewSyms,
1609
sizeof(JBIG2Bitmap *));
1610
for (i = 0; i < numInputSyms + numNewSyms; ++i) {
1614
inputSymbolDict = NULL;
1615
for (i = 0; i < nRefSegs; ++i) {
1616
seg = findSegment(refSegs[i]);
1617
if (seg != NULL && seg->getType() == jbig2SegSymbolDict) {
1618
inputSymbolDict = (JBIG2SymbolDict *)seg;
1619
for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1620
bitmaps[k++] = inputSymbolDict->getBitmap(j);
1625
// get the Huffman tables
1626
huffDHTable = huffDWTable = NULL; // make gcc happy
1627
huffBMSizeTable = huffAggInstTable = NULL; // make gcc happy
1631
huffDHTable = huffTableD;
1632
} else if (huffDH == 1) {
1633
huffDHTable = huffTableE;
1635
if (i >= (Guint)codeTables->getLength()) {
1636
goto codeTableError;
1638
huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1641
huffDWTable = huffTableB;
1642
} else if (huffDW == 1) {
1643
huffDWTable = huffTableC;
1645
if (i >= (Guint)codeTables->getLength()) {
1646
goto codeTableError;
1648
huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1650
if (huffBMSize == 0) {
1651
huffBMSizeTable = huffTableA;
1653
if (i >= (Guint)codeTables->getLength()) {
1654
goto codeTableError;
1657
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1659
if (huffAggInst == 0) {
1660
huffAggInstTable = huffTableA;
1662
if (i >= (Guint)codeTables->getLength()) {
1663
goto codeTableError;
1666
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1671
// set up the Huffman decoder
1673
huffDecoder->reset();
1675
// set up the arithmetic decoder
1677
if (contextUsed && inputSymbolDict) {
1678
resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats());
1680
resetGenericStats(sdTemplate, NULL);
1682
resetIntStats(symCodeLen);
1683
arithDecoder->start();
1686
// set up the arithmetic decoder for refinement/aggregation
1688
if (contextUsed && inputSymbolDict) {
1689
resetRefinementStats(sdrTemplate,
1690
inputSymbolDict->getRefinementRegionStats());
1692
resetRefinementStats(sdrTemplate, NULL);
1696
// allocate symbol widths storage
1697
if (huff && !refAgg) {
1698
symWidths = (Guint *)gmallocn(numNewSyms, sizeof(Guint));
1703
while (i < numNewSyms) {
1705
// read the height class delta height
1707
huffDecoder->decodeInt(&dh, huffDHTable);
1709
arithDecoder->decodeInt(&dh, iadhStats);
1711
if (dh < 0 && (Guint)-dh >= symHeight) {
1712
error(curStr->getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
1720
// read the symbols in this height class
1723
// read the delta width
1725
if (!huffDecoder->decodeInt(&dw, huffDWTable)) {
1729
if (!arithDecoder->decodeInt(&dw, iadwStats)) {
1733
if (dw < 0 && (Guint)-dw >= symWidth) {
1734
error(curStr->getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
1738
if (i >= numNewSyms) {
1739
error(curStr->getPos(), "Too many symbols in JBIG2 symbol dictionary");
1743
// using a collective bitmap, so don't read a bitmap here
1744
if (huff && !refAgg) {
1745
symWidths[i] = symWidth;
1746
totalWidth += symWidth;
1748
// refinement/aggregate coding
1749
} else if (refAgg) {
1751
if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) {
1755
if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) {
1759
#if 0 //~ This special case was added about a year before the final draft
1760
//~ of the JBIG2 spec was released. I have encountered some old
1761
//~ JBIG2 images that predate it.
1764
if (refAggNum == 1) {
1767
symID = huffDecoder->readBits(symCodeLen);
1768
huffDecoder->decodeInt(&refDX, huffTableO);
1769
huffDecoder->decodeInt(&refDY, huffTableO);
1770
huffDecoder->decodeInt(&bmSize, huffTableA);
1771
huffDecoder->reset();
1772
arithDecoder->start();
1774
symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
1775
arithDecoder->decodeInt(&refDX, iardxStats);
1776
arithDecoder->decodeInt(&refDY, iardyStats);
1778
if (symID >= numInputSyms + i) {
1779
error(curStr->getPos(), "Invalid symbol ID in JBIG2 symbol dictionary");
1782
refBitmap = bitmaps[symID];
1783
bitmaps[numInputSyms + i] =
1784
readGenericRefinementRegion(symWidth, symHeight,
1785
sdrTemplate, gFalse,
1786
refBitmap, refDX, refDY,
1788
//~ do we need to use the bmSize value here (in Huffman mode)?
1790
bitmaps[numInputSyms + i] =
1791
readTextRegion(huff, gTrue, symWidth, symHeight,
1792
refAggNum, 0, numInputSyms + i, NULL,
1793
symCodeLen, bitmaps, 0, 0, 0, 1, 0,
1794
huffTableF, huffTableH, huffTableK, huffTableO,
1795
huffTableO, huffTableO, huffTableO, huffTableA,
1796
sdrTemplate, sdrATX, sdrATY);
1799
// non-ref/agg coding
1801
bitmaps[numInputSyms + i] =
1802
readGenericBitmap(gFalse, symWidth, symHeight,
1803
sdTemplate, gFalse, gFalse, NULL,
1810
// read the collective bitmap
1811
if (huff && !refAgg) {
1812
huffDecoder->decodeInt(&bmSize, huffBMSizeTable);
1813
huffDecoder->reset();
1815
collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight);
1816
bmSize = symHeight * ((totalWidth + 7) >> 3);
1817
p = collBitmap->getDataPtr();
1818
for (k = 0; k < (Guint)bmSize; ++k) {
1819
*p++ = curStr->getChar();
1822
collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
1823
0, gFalse, gFalse, NULL, NULL, NULL,
1827
for (; j < i; ++j) {
1828
bitmaps[numInputSyms + j] =
1829
collBitmap->getSlice(x, 0, symWidths[j], symHeight);
1836
// create the symbol dict object
1837
symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
1838
if (!symbolDict->isOk()) {
1843
// exported symbol list
1846
while (i < numInputSyms + numNewSyms) {
1848
huffDecoder->decodeInt(&run, huffTableA);
1850
arithDecoder->decodeInt(&run, iaexStats);
1852
if (i + run > numInputSyms + numNewSyms ||
1853
(ex && j + run > numExSyms)) {
1854
error(curStr->getPos(), "Too many exported symbols in JBIG2 symbol dictionary");
1855
for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
1860
for (cnt = 0; cnt < run; ++cnt) {
1861
symbolDict->setBitmap(j++, bitmaps[i++]->copy());
1868
if (j != numExSyms) {
1869
error(curStr->getPos(), "Too few symbols in JBIG2 symbol dictionary");
1870
for ( ; j < numExSyms; ++j) symbolDict->setBitmap(j, NULL);
1875
for (i = 0; i < numNewSyms; ++i) {
1876
delete bitmaps[numInputSyms + i];
1883
// save the arithmetic decoder stats
1884
if (!huff && contextRetained) {
1885
symbolDict->setGenericRegionStats(genericRegionStats->copy());
1887
symbolDict->setRefinementRegionStats(refinementRegionStats->copy());
1891
// store the new symbol dict
1892
segments->append(symbolDict);
1897
error(curStr->getPos(), "Missing code table in JBIG2 symbol dictionary");
1901
for (i = 0; i < numNewSyms; ++i) {
1902
if (bitmaps[numInputSyms + i]) {
1903
delete bitmaps[numInputSyms + i];
1913
error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
1917
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
1918
GBool lossless, Guint length,
1919
Guint *refSegs, Guint nRefSegs) {
1920
JBIG2Bitmap *bitmap;
1921
JBIG2HuffmanTable runLengthTab[36];
1922
JBIG2HuffmanTable *symCodeTab;
1923
JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable;
1924
JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
1925
JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
1927
GooList *codeTables;
1928
JBIG2SymbolDict *symbolDict;
1930
Guint w, h, x, y, segInfoFlags, extCombOp;
1931
Guint flags, huff, refine, logStrips, refCorner, transposed;
1932
Guint combOp, defPixel, templ;
1934
Guint huffFlags, huffFS, huffDS, huffDT;
1935
Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize;
1936
Guint numInstances, numSyms, symCodeLen;
1941
// region segment info field
1942
if (!readULong(&w) || !readULong(&h) ||
1943
!readULong(&x) || !readULong(&y) ||
1944
!readUByte(&segInfoFlags)) {
1947
extCombOp = segInfoFlags & 7;
1949
// rest of the text region header
1950
if (!readUWord(&flags)) {
1954
refine = (flags >> 1) & 1;
1955
logStrips = (flags >> 2) & 3;
1956
refCorner = (flags >> 4) & 3;
1957
transposed = (flags >> 6) & 1;
1958
combOp = (flags >> 7) & 3;
1959
defPixel = (flags >> 9) & 1;
1960
sOffset = (flags >> 10) & 0x1f;
1961
if (sOffset & 0x10) {
1962
sOffset |= -1 - 0x0f;
1964
templ = (flags >> 15) & 1;
1965
huffFS = huffDS = huffDT = 0; // make gcc happy
1966
huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0; // make gcc happy
1968
if (!readUWord(&huffFlags)) {
1971
huffFS = huffFlags & 3;
1972
huffDS = (huffFlags >> 2) & 3;
1973
huffDT = (huffFlags >> 4) & 3;
1974
huffRDW = (huffFlags >> 6) & 3;
1975
huffRDH = (huffFlags >> 8) & 3;
1976
huffRDX = (huffFlags >> 10) & 3;
1977
huffRDY = (huffFlags >> 12) & 3;
1978
huffRSize = (huffFlags >> 14) & 1;
1980
if (refine && templ == 0) {
1981
if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
1982
!readByte(&atx[1]) || !readByte(&aty[1])) {
1986
if (!readULong(&numInstances)) {
1990
// get symbol dictionaries and tables
1991
codeTables = new GooList();
1993
for (i = 0; i < nRefSegs; ++i) {
1994
if ((seg = findSegment(refSegs[i]))) {
1995
if (seg->getType() == jbig2SegSymbolDict) {
1996
numSyms += ((JBIG2SymbolDict *)seg)->getSize();
1997
} else if (seg->getType() == jbig2SegCodeTable) {
1998
codeTables->append(seg);
2001
error(curStr->getPos(), "Invalid segment reference in JBIG2 text region");
2008
while (i < numSyms) {
2013
// get the symbol bitmaps
2014
syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *));
2016
for (i = 0; i < nRefSegs; ++i) {
2017
if ((seg = findSegment(refSegs[i]))) {
2018
if (seg->getType() == jbig2SegSymbolDict) {
2019
symbolDict = (JBIG2SymbolDict *)seg;
2020
for (k = 0; k < symbolDict->getSize(); ++k) {
2021
syms[kk++] = symbolDict->getBitmap(k);
2027
// get the Huffman tables
2028
huffFSTable = huffDSTable = huffDTTable = NULL; // make gcc happy
2029
huffRDWTable = huffRDHTable = NULL; // make gcc happy
2030
huffRDXTable = huffRDYTable = huffRSizeTable = NULL; // make gcc happy
2034
huffFSTable = huffTableF;
2035
} else if (huffFS == 1) {
2036
huffFSTable = huffTableG;
2038
if (i >= (Guint)codeTables->getLength()) {
2039
goto codeTableError;
2041
huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2044
huffDSTable = huffTableH;
2045
} else if (huffDS == 1) {
2046
huffDSTable = huffTableI;
2047
} else if (huffDS == 2) {
2048
huffDSTable = huffTableJ;
2050
if (i >= (Guint)codeTables->getLength()) {
2051
goto codeTableError;
2053
huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2056
huffDTTable = huffTableK;
2057
} else if (huffDT == 1) {
2058
huffDTTable = huffTableL;
2059
} else if (huffDT == 2) {
2060
huffDTTable = huffTableM;
2062
if (i >= (Guint)codeTables->getLength()) {
2063
goto codeTableError;
2065
huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2068
huffRDWTable = huffTableN;
2069
} else if (huffRDW == 1) {
2070
huffRDWTable = huffTableO;
2072
if (i >= (Guint)codeTables->getLength()) {
2073
goto codeTableError;
2075
huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2078
huffRDHTable = huffTableN;
2079
} else if (huffRDH == 1) {
2080
huffRDHTable = huffTableO;
2082
if (i >= (Guint)codeTables->getLength()) {
2083
goto codeTableError;
2085
huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2088
huffRDXTable = huffTableN;
2089
} else if (huffRDX == 1) {
2090
huffRDXTable = huffTableO;
2092
if (i >= (Guint)codeTables->getLength()) {
2093
goto codeTableError;
2095
huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2098
huffRDYTable = huffTableN;
2099
} else if (huffRDY == 1) {
2100
huffRDYTable = huffTableO;
2102
if (i >= (Guint)codeTables->getLength()) {
2103
goto codeTableError;
2105
huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2107
if (huffRSize == 0) {
2108
huffRSizeTable = huffTableA;
2110
if (i >= (Guint)codeTables->getLength()) {
2111
goto codeTableError;
2114
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2119
// symbol ID Huffman decoding table
2121
huffDecoder->reset();
2122
for (i = 0; i < 32; ++i) {
2123
runLengthTab[i].val = i;
2124
runLengthTab[i].prefixLen = huffDecoder->readBits(4);
2125
runLengthTab[i].rangeLen = 0;
2127
runLengthTab[32].val = 0x103;
2128
runLengthTab[32].prefixLen = huffDecoder->readBits(4);
2129
runLengthTab[32].rangeLen = 2;
2130
runLengthTab[33].val = 0x203;
2131
runLengthTab[33].prefixLen = huffDecoder->readBits(4);
2132
runLengthTab[33].rangeLen = 3;
2133
runLengthTab[34].val = 0x20b;
2134
runLengthTab[34].prefixLen = huffDecoder->readBits(4);
2135
runLengthTab[34].rangeLen = 7;
2136
runLengthTab[35].prefixLen = 0;
2137
runLengthTab[35].rangeLen = jbig2HuffmanEOT;
2138
huffDecoder->buildTable(runLengthTab, 35);
2139
symCodeTab = (JBIG2HuffmanTable *)gmallocn(numSyms + 1,
2140
sizeof(JBIG2HuffmanTable));
2141
for (i = 0; i < numSyms; ++i) {
2142
symCodeTab[i].val = i;
2143
symCodeTab[i].rangeLen = 0;
2146
while (i < numSyms) {
2147
huffDecoder->decodeInt(&j, runLengthTab);
2149
for (j -= 0x200; j && i < numSyms; --j) {
2150
symCodeTab[i++].prefixLen = 0;
2152
} else if (j > 0x100) {
2153
for (j -= 0x100; j && i < numSyms; --j) {
2154
symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
2158
symCodeTab[i++].prefixLen = j;
2161
symCodeTab[numSyms].prefixLen = 0;
2162
symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT;
2163
huffDecoder->buildTable(symCodeTab, numSyms);
2164
huffDecoder->reset();
2166
// set up the arithmetic decoder
2169
resetIntStats(symCodeLen);
2170
arithDecoder->start();
2173
resetRefinementStats(templ, NULL);
2176
bitmap = readTextRegion(huff, refine, w, h, numInstances,
2177
logStrips, numSyms, symCodeTab, symCodeLen, syms,
2178
defPixel, combOp, transposed, refCorner, sOffset,
2179
huffFSTable, huffDSTable, huffDTTable,
2180
huffRDWTable, huffRDHTable,
2181
huffRDXTable, huffRDYTable, huffRSizeTable,
2187
// combine the region bitmap into the page bitmap
2189
if (pageH == 0xffffffff && y + h > curPageH) {
2190
pageBitmap->expand(y + h, pageDefPixel);
2192
pageBitmap->combine(bitmap, x, y, extCombOp);
2195
// store the region bitmap
2197
bitmap->setSegNum(segNum);
2198
segments->append(bitmap);
2202
// clean up the Huffman decoder
2210
error(curStr->getPos(), "Missing code table in JBIG2 text region");
2216
error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
2220
JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
2225
JBIG2HuffmanTable *symCodeTab,
2228
Guint defPixel, Guint combOp,
2229
Guint transposed, Guint refCorner,
2231
JBIG2HuffmanTable *huffFSTable,
2232
JBIG2HuffmanTable *huffDSTable,
2233
JBIG2HuffmanTable *huffDTTable,
2234
JBIG2HuffmanTable *huffRDWTable,
2235
JBIG2HuffmanTable *huffRDHTable,
2236
JBIG2HuffmanTable *huffRDXTable,
2237
JBIG2HuffmanTable *huffRDYTable,
2238
JBIG2HuffmanTable *huffRSizeTable,
2240
int *atx, int *aty) {
2241
JBIG2Bitmap *bitmap;
2242
JBIG2Bitmap *symbolBitmap;
2244
int t, dt, tt, s, ds, sFirst, j;
2245
int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize;
2246
Guint symID, inst, bw, bh;
2248
strips = 1 << logStrips;
2250
// allocate the bitmap
2251
bitmap = new JBIG2Bitmap(0, w, h);
2252
if (!bitmap->isOk()) {
2257
bitmap->clearToOne();
2259
bitmap->clearToZero();
2262
// decode initial T value
2264
huffDecoder->decodeInt(&t, huffDTTable);
2266
arithDecoder->decodeInt(&t, iadtStats);
2272
while (inst < numInstances) {
2276
huffDecoder->decodeInt(&dt, huffDTTable);
2278
arithDecoder->decodeInt(&dt, iadtStats);
2284
huffDecoder->decodeInt(&ds, huffFSTable);
2286
arithDecoder->decodeInt(&ds, iafsStats);
2291
// read the instances
2292
while (inst < numInstances) {
2298
dt = huffDecoder->readBits(logStrips);
2300
arithDecoder->decodeInt(&dt, iaitStats);
2307
huffDecoder->decodeInt(&j, symCodeTab);
2310
symID = huffDecoder->readBits(symCodeLen);
2313
symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
2316
if (symID >= (Guint)numSyms) {
2317
error(curStr->getPos(), "Invalid symbol number in JBIG2 text region");
2320
// get the symbol bitmap
2321
symbolBitmap = NULL;
2324
ri = (int)huffDecoder->readBit();
2326
arithDecoder->decodeInt(&ri, iariStats);
2332
GBool decodeSuccess;
2334
decodeSuccess = huffDecoder->decodeInt(&rdw, huffRDWTable);
2335
decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdh, huffRDHTable);
2336
decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdx, huffRDXTable);
2337
decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&rdy, huffRDYTable);
2338
decodeSuccess = decodeSuccess && huffDecoder->decodeInt(&bmSize, huffRSizeTable);
2339
huffDecoder->reset();
2340
arithDecoder->start();
2342
decodeSuccess = arithDecoder->decodeInt(&rdw, iardwStats);
2343
decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdh, iardhStats);
2344
decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdx, iardxStats);
2345
decodeSuccess = decodeSuccess && arithDecoder->decodeInt(&rdy, iardyStats);
2348
if (decodeSuccess && syms[symID])
2350
refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
2351
refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
2354
readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
2355
rdh + syms[symID]->getHeight(),
2356
templ, gFalse, syms[symID],
2357
refDX, refDY, atx, aty);
2359
//~ do we need to use the bmSize value here (in Huffman mode)?
2361
symbolBitmap = syms[symID];
2365
// combine the symbol bitmap into the region bitmap
2366
//~ something is wrong here - refCorner shouldn't degenerate into
2368
bw = symbolBitmap->getWidth() - 1;
2369
bh = symbolBitmap->getHeight() - 1;
2371
switch (refCorner) {
2372
case 0: // bottom left
2373
bitmap->combine(symbolBitmap, tt, s, combOp);
2376
bitmap->combine(symbolBitmap, tt, s, combOp);
2378
case 2: // bottom right
2379
bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2381
case 3: // top right
2382
bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2387
switch (refCorner) {
2388
case 0: // bottom left
2389
bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2392
bitmap->combine(symbolBitmap, s, tt, combOp);
2394
case 2: // bottom right
2395
bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2397
case 3: // top right
2398
bitmap->combine(symbolBitmap, s, tt, combOp);
2404
delete symbolBitmap;
2407
// NULL symbolBitmap only happens on error
2418
if (!huffDecoder->decodeInt(&ds, huffDSTable)) {
2422
if (!arithDecoder->decodeInt(&ds, iadsStats)) {
2433
void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
2434
JBIG2PatternDict *patternDict;
2435
JBIG2Bitmap *bitmap;
2436
Guint flags, patternW, patternH, grayMax, templ, mmr;
2440
// halftone dictionary flags, pattern width and height, max gray value
2441
if (!readUByte(&flags) ||
2442
!readUByte(&patternW) ||
2443
!readUByte(&patternH) ||
2444
!readULong(&grayMax)) {
2447
templ = (flags >> 1) & 3;
2450
// set up the arithmetic decoder
2452
resetGenericStats(templ, NULL);
2453
arithDecoder->start();
2457
atx[0] = -(int)patternW; aty[0] = 0;
2458
atx[1] = -3; aty[1] = -1;
2459
atx[2] = 2; aty[2] = -2;
2460
atx[3] = -2; aty[3] = -2;
2461
bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
2462
templ, gFalse, gFalse, NULL,
2463
atx, aty, length - 7);
2468
// create the pattern dict object
2469
patternDict = new JBIG2PatternDict(segNum, grayMax + 1);
2471
// split up the bitmap
2473
for (i = 0; i <= grayMax; ++i) {
2474
patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
2481
// store the new pattern dict
2482
segments->append(patternDict);
2487
error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
2490
void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
2491
GBool lossless, Guint length,
2492
Guint *refSegs, Guint nRefSegs) {
2493
JBIG2Bitmap *bitmap;
2495
JBIG2PatternDict *patternDict;
2496
JBIG2Bitmap *skipBitmap;
2498
JBIG2Bitmap *grayBitmap;
2499
JBIG2Bitmap *patternBitmap;
2500
Guint w, h, x, y, segInfoFlags, extCombOp;
2501
Guint flags, mmr, templ, enableSkip, combOp;
2502
Guint gridW, gridH, stepX, stepY, patW, patH;
2504
int gridX, gridY, xx, yy, bit, j;
2507
// region segment info field
2508
if (!readULong(&w) || !readULong(&h) ||
2509
!readULong(&x) || !readULong(&y) ||
2510
!readUByte(&segInfoFlags)) {
2513
extCombOp = segInfoFlags & 7;
2515
// rest of the halftone region header
2516
if (!readUByte(&flags)) {
2520
templ = (flags >> 1) & 3;
2521
enableSkip = (flags >> 3) & 1;
2522
combOp = (flags >> 4) & 7;
2523
if (!readULong(&gridW) || !readULong(&gridH) ||
2524
!readLong(&gridX) || !readLong(&gridY) ||
2525
!readUWord(&stepX) || !readUWord(&stepY)) {
2528
if (w == 0 || h == 0 || w >= INT_MAX / h) {
2529
error(curStr->getPos(), "Bad bitmap size in JBIG2 halftone segment");
2532
if (gridH == 0 || gridW >= INT_MAX / gridH) {
2533
error(curStr->getPos(), "Bad grid size in JBIG2 halftone segment");
2537
// get pattern dictionary
2538
if (nRefSegs != 1) {
2539
error(curStr->getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2542
seg = findSegment(refSegs[0]);
2543
if (seg == NULL || seg->getType() != jbig2SegPatternDict) {
2544
error(curStr->getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2548
patternDict = (JBIG2PatternDict *)seg;
2551
while (i < patternDict->getSize()) {
2555
patW = patternDict->getBitmap(0)->getWidth();
2556
patH = patternDict->getBitmap(0)->getHeight();
2558
// set up the arithmetic decoder
2560
resetGenericStats(templ, NULL);
2561
arithDecoder->start();
2564
// allocate the bitmap
2565
bitmap = new JBIG2Bitmap(segNum, w, h);
2566
if (flags & 0x80) { // HDEFPIXEL
2567
bitmap->clearToOne();
2569
bitmap->clearToZero();
2572
// compute the skip bitmap
2575
skipBitmap = new JBIG2Bitmap(0, gridW, gridH);
2576
skipBitmap->clearToZero();
2577
for (m = 0; m < gridH; ++m) {
2578
for (n = 0; n < gridW; ++n) {
2579
xx = gridX + m * stepY + n * stepX;
2580
yy = gridY + m * stepX - n * stepY;
2581
if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w ||
2582
((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) {
2583
skipBitmap->setPixel(n, m);
2589
// read the gray-scale image
2590
grayImg = (Guint *)gmallocn(gridW * gridH, sizeof(Guint));
2591
memset(grayImg, 0, gridW * gridH * sizeof(Guint));
2592
atx[0] = templ <= 1 ? 3 : 2; aty[0] = -1;
2593
atx[1] = -3; aty[1] = -1;
2594
atx[2] = 2; aty[2] = -2;
2595
atx[3] = -2; aty[3] = -2;
2596
for (j = bpp - 1; j >= 0; --j) {
2597
grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse,
2598
enableSkip, skipBitmap, atx, aty, -1);
2600
for (m = 0; m < gridH; ++m) {
2601
for (n = 0; n < gridW; ++n) {
2602
bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1);
2603
grayImg[i] = (grayImg[i] << 1) | bit;
2612
for (m = 0; m < gridH; ++m) {
2613
xx = gridX + m * stepY;
2614
yy = gridY + m * stepX;
2615
for (n = 0; n < gridW; ++n) {
2616
if (!(enableSkip && skipBitmap->getPixel(n, m))) {
2617
patternBitmap = patternDict->getBitmap(grayImg[i]);
2618
bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp);
2631
// combine the region bitmap into the page bitmap
2633
if (pageH == 0xffffffff && y + h > curPageH) {
2634
pageBitmap->expand(y + h, pageDefPixel);
2636
pageBitmap->combine(bitmap, x, y, extCombOp);
2639
// store the region bitmap
2641
segments->append(bitmap);
2647
error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
2650
void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
2651
GBool lossless, Guint length) {
2652
JBIG2Bitmap *bitmap;
2653
Guint w, h, x, y, segInfoFlags, extCombOp;
2654
Guint flags, mmr, templ, tpgdOn;
2657
// region segment info field
2658
if (!readULong(&w) || !readULong(&h) ||
2659
!readULong(&x) || !readULong(&y) ||
2660
!readUByte(&segInfoFlags)) {
2663
extCombOp = segInfoFlags & 7;
2665
// rest of the generic region segment header
2666
if (!readUByte(&flags)) {
2670
templ = (flags >> 1) & 3;
2671
tpgdOn = (flags >> 3) & 1;
2676
if (!readByte(&atx[0]) ||
2677
!readByte(&aty[0]) ||
2678
!readByte(&atx[1]) ||
2679
!readByte(&aty[1]) ||
2680
!readByte(&atx[2]) ||
2681
!readByte(&aty[2]) ||
2682
!readByte(&atx[3]) ||
2683
!readByte(&aty[3])) {
2687
if (!readByte(&atx[0]) ||
2688
!readByte(&aty[0])) {
2694
// set up the arithmetic decoder
2696
resetGenericStats(templ, NULL);
2697
arithDecoder->start();
2701
bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
2702
NULL, atx, aty, mmr ? length - 18 : 0);
2706
// combine the region bitmap into the page bitmap
2708
if (pageH == 0xffffffff && y + h > curPageH) {
2709
pageBitmap->expand(y + h, pageDefPixel);
2711
pageBitmap->combine(bitmap, x, y, extCombOp);
2714
// store the region bitmap
2716
bitmap->setSegNum(segNum);
2717
segments->append(bitmap);
2723
error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
2726
inline void JBIG2Stream::mmrAddPixels(int a1, int blackPixels,
2727
int *codingLine, int *a0i, int w) {
2728
if (a1 > codingLine[*a0i]) {
2730
error(curStr->getPos(), "JBIG2 MMR row is wrong length (%d)", a1);
2733
if ((*a0i & 1) ^ blackPixels) {
2736
codingLine[*a0i] = a1;
2740
inline void JBIG2Stream::mmrAddPixelsNeg(int a1, int blackPixels,
2741
int *codingLine, int *a0i, int w) {
2742
if (a1 > codingLine[*a0i]) {
2744
error(curStr->getPos(), "JBIG2 MMR row is wrong length (%d)", a1);
2747
if ((*a0i & 1) ^ blackPixels) {
2750
codingLine[*a0i] = a1;
2751
} else if (a1 < codingLine[*a0i]) {
2753
error(curStr->getPos(), "Invalid JBIG2 MMR code");
2756
while (*a0i > 0 && a1 <= codingLine[*a0i - 1]) {
2759
codingLine[*a0i] = a1;
2763
JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
2764
int templ, GBool tpgdOn,
2765
GBool useSkip, JBIG2Bitmap *skip,
2767
int mmrDataLength) {
2768
JBIG2Bitmap *bitmap;
2770
Guint ltpCX, cx, cx0, cx1, cx2;
2771
JBIG2BitmapPtr cxPtr0 = {0}, cxPtr1 = {0};
2772
JBIG2BitmapPtr atPtr0 = {0}, atPtr1 = {0}, atPtr2 = {0}, atPtr3 = {0};
2773
int *refLine, *codingLine;
2774
int code1, code2, code3;
2775
int x, y, a0i, b1i, blackPixels, pix, i;
2777
bitmap = new JBIG2Bitmap(0, w, h);
2778
if (!bitmap->isOk()) {
2782
bitmap->clearToZero();
2788
mmrDecoder->reset();
2789
if (w > INT_MAX - 2) {
2790
error(curStr->getPos(), "Bad width in JBIG2 generic bitmap");
2791
// force a call to gmalloc(-1), which will throw an exception
2794
// 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = w
2795
// ---> max codingLine size = w + 1
2796
// refLine has one extra guard entry at the end
2797
// ---> max refLine size = w + 2
2798
codingLine = (int *)gmallocn(w + 1, sizeof(int));
2799
refLine = (int *)gmallocn(w + 2, sizeof(int));
2800
for (i = 0; i < w + 1; ++i) codingLine[i] = w;
2802
for (y = 0; y < h; ++y) {
2804
// copy coding line to ref line
2805
for (i = 0; codingLine[i] < w; ++i) {
2806
refLine[i] = codingLine[i];
2817
// refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1] <= w
2818
// exception at left edge:
2819
// codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
2820
// exception at right edge:
2821
// refLine[b1i] = refLine[b1i+1] = w is possible
2822
while (codingLine[a0i] < w) {
2823
code1 = mmrDecoder->get2DCode();
2826
mmrAddPixels(refLine[b1i + 1], blackPixels, codingLine, &a0i, w);
2827
if (refLine[b1i + 1] < w) {
2835
code1 += code3 = mmrDecoder->getBlackCode();
2836
} while (code3 >= 64);
2838
code2 += code3 = mmrDecoder->getWhiteCode();
2839
} while (code3 >= 64);
2842
code1 += code3 = mmrDecoder->getWhiteCode();
2843
} while (code3 >= 64);
2845
code2 += code3 = mmrDecoder->getBlackCode();
2846
} while (code3 >= 64);
2848
mmrAddPixels(codingLine[a0i] + code1, blackPixels,
2849
codingLine, &a0i, w);
2850
if (codingLine[a0i] < w) {
2851
mmrAddPixels(codingLine[a0i] + code2, blackPixels ^ 1,
2852
codingLine, &a0i, w);
2854
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2859
mmrAddPixels(refLine[b1i] + 3, blackPixels, codingLine, &a0i, w);
2861
if (codingLine[a0i] < w) {
2863
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2869
mmrAddPixels(refLine[b1i] + 2, blackPixels, codingLine, &a0i, w);
2871
if (codingLine[a0i] < w) {
2873
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2879
mmrAddPixels(refLine[b1i] + 1, blackPixels, codingLine, &a0i, w);
2881
if (codingLine[a0i] < w) {
2883
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2889
mmrAddPixels(refLine[b1i], blackPixels, codingLine, &a0i, w);
2891
if (codingLine[a0i] < w) {
2893
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2899
mmrAddPixelsNeg(refLine[b1i] - 3, blackPixels, codingLine, &a0i, w);
2901
if (codingLine[a0i] < w) {
2907
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2913
mmrAddPixelsNeg(refLine[b1i] - 2, blackPixels, codingLine, &a0i, w);
2915
if (codingLine[a0i] < w) {
2921
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2927
mmrAddPixelsNeg(refLine[b1i] - 1, blackPixels, codingLine, &a0i, w);
2929
if (codingLine[a0i] < w) {
2935
while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
2941
mmrAddPixels(w, 0, codingLine, &a0i, w);
2944
error(curStr->getPos(), "Illegal code in JBIG2 MMR bitmap data");
2945
mmrAddPixels(w, 0, codingLine, &a0i, w);
2950
// convert the run lengths to a bitmap line
2953
for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
2954
bitmap->setPixel(x, y);
2956
if (codingLine[i+1] >= w || codingLine[i+2] >= w) {
2963
if (mmrDataLength >= 0) {
2964
mmrDecoder->skipTo(mmrDataLength);
2966
if (mmrDecoder->get24Bits() != 0x001001) {
2967
error(curStr->getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
2974
//----- arithmetic decode
2977
// set up the typical row context
2978
ltpCX = 0; // make gcc happy
2982
ltpCX = 0x3953; // 001 11001 0101 0011
2985
ltpCX = 0x079a; // 0011 11001 101 0
2988
ltpCX = 0x0e3; // 001 1100 01 1
2991
ltpCX = 0x18a; // 01100 0101 1
2997
cx = cx0 = cx1 = cx2 = 0; // make gcc happy
2998
for (y = 0; y < h; ++y) {
3000
// check for a "typical" (duplicate) row
3002
if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
3007
bitmap->duplicateRow(y, y-1);
3016
// set up the context
3017
bitmap->getPixelPtr(0, y-2, &cxPtr0);
3018
cx0 = bitmap->nextPixel(&cxPtr0);
3019
cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
3020
bitmap->getPixelPtr(0, y-1, &cxPtr1);
3021
cx1 = bitmap->nextPixel(&cxPtr1);
3022
cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3023
cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3025
bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
3026
bitmap->getPixelPtr(atx[1], y + aty[1], &atPtr1);
3027
bitmap->getPixelPtr(atx[2], y + aty[2], &atPtr2);
3028
bitmap->getPixelPtr(atx[3], y + aty[3], &atPtr3);
3031
for (x = 0; x < w; ++x) {
3033
// build the context
3034
cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
3035
(bitmap->nextPixel(&atPtr0) << 3) |
3036
(bitmap->nextPixel(&atPtr1) << 2) |
3037
(bitmap->nextPixel(&atPtr2) << 1) |
3038
bitmap->nextPixel(&atPtr3);
3040
// check for a skipped pixel
3041
if (useSkip && skip->getPixel(x, y)) {
3045
} else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3046
bitmap->setPixel(x, y);
3049
// update the context
3050
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
3051
cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
3052
cx2 = ((cx2 << 1) | pix) & 0x0f;
3058
// set up the context
3059
bitmap->getPixelPtr(0, y-2, &cxPtr0);
3060
cx0 = bitmap->nextPixel(&cxPtr0);
3061
cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
3062
cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
3063
bitmap->getPixelPtr(0, y-1, &cxPtr1);
3064
cx1 = bitmap->nextPixel(&cxPtr1);
3065
cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3066
cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3068
bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
3071
for (x = 0; x < w; ++x) {
3073
// build the context
3074
cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
3075
bitmap->nextPixel(&atPtr0);
3077
// check for a skipped pixel
3078
if (useSkip && skip->getPixel(x, y)) {
3082
} else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3083
bitmap->setPixel(x, y);
3086
// update the context
3087
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x0f;
3088
cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
3089
cx2 = ((cx2 << 1) | pix) & 0x07;
3095
// set up the context
3096
bitmap->getPixelPtr(0, y-2, &cxPtr0);
3097
cx0 = bitmap->nextPixel(&cxPtr0);
3098
cx0 = (cx0 << 1) | bitmap->nextPixel(&cxPtr0);
3099
bitmap->getPixelPtr(0, y-1, &cxPtr1);
3100
cx1 = bitmap->nextPixel(&cxPtr1);
3101
cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3103
bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
3106
for (x = 0; x < w; ++x) {
3108
// build the context
3109
cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
3110
bitmap->nextPixel(&atPtr0);
3112
// check for a skipped pixel
3113
if (useSkip && skip->getPixel(x, y)) {
3117
} else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3118
bitmap->setPixel(x, y);
3121
// update the context
3122
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 0x07;
3123
cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x0f;
3124
cx2 = ((cx2 << 1) | pix) & 0x03;
3130
// set up the context
3131
bitmap->getPixelPtr(0, y-1, &cxPtr1);
3132
cx1 = bitmap->nextPixel(&cxPtr1);
3133
cx1 = (cx1 << 1) | bitmap->nextPixel(&cxPtr1);
3135
bitmap->getPixelPtr(atx[0], y + aty[0], &atPtr0);
3138
for (x = 0; x < w; ++x) {
3140
// build the context
3141
cx = (cx1 << 5) | (cx2 << 1) |
3142
bitmap->nextPixel(&atPtr0);
3144
// check for a skipped pixel
3145
if (useSkip && skip->getPixel(x, y)) {
3149
} else if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3150
bitmap->setPixel(x, y);
3153
// update the context
3154
cx1 = ((cx1 << 1) | bitmap->nextPixel(&cxPtr1)) & 0x1f;
3155
cx2 = ((cx2 << 1) | pix) & 0x0f;
3165
void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
3166
GBool lossless, Guint length,
3169
JBIG2Bitmap *bitmap, *refBitmap;
3170
Guint w, h, x, y, segInfoFlags, extCombOp;
3171
Guint flags, templ, tpgrOn;
3175
// region segment info field
3176
if (!readULong(&w) || !readULong(&h) ||
3177
!readULong(&x) || !readULong(&y) ||
3178
!readUByte(&segInfoFlags)) {
3181
extCombOp = segInfoFlags & 7;
3183
// rest of the generic refinement region segment header
3184
if (!readUByte(&flags)) {
3188
tpgrOn = (flags >> 1) & 1;
3192
if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
3193
!readByte(&atx[1]) || !readByte(&aty[1])) {
3198
// resize the page bitmap if needed
3199
if (nRefSegs == 0 || imm) {
3200
if (pageH == 0xffffffff && y + h > curPageH) {
3201
pageBitmap->expand(y + h, pageDefPixel);
3205
// get referenced bitmap
3207
error(curStr->getPos(), "Bad reference in JBIG2 generic refinement segment");
3210
if (nRefSegs == 1) {
3211
seg = findSegment(refSegs[0]);
3212
if (seg == NULL || seg->getType() != jbig2SegBitmap) {
3213
error(curStr->getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
3216
refBitmap = (JBIG2Bitmap *)seg;
3218
refBitmap = pageBitmap->getSlice(x, y, w, h);
3221
// set up the arithmetic decoder
3222
resetRefinementStats(templ, NULL);
3223
arithDecoder->start();
3226
bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
3227
refBitmap, 0, 0, atx, aty);
3229
// combine the region bitmap into the page bitmap
3231
pageBitmap->combine(bitmap, x, y, extCombOp);
3234
// store the region bitmap
3237
bitmap->setSegNum(segNum);
3238
segments->append(bitmap);
3240
error(curStr->getPos(), "readGenericRefinementRegionSeg with null bitmap");
3244
// delete the referenced bitmap
3245
if (nRefSegs == 1) {
3246
discardSegment(refSegs[0]);
3254
error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
3257
JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
3258
int templ, GBool tpgrOn,
3259
JBIG2Bitmap *refBitmap,
3260
int refDX, int refDY,
3261
int *atx, int *aty) {
3262
JBIG2Bitmap *bitmap;
3264
Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
3265
JBIG2BitmapPtr cxPtr0 = {0};
3266
JBIG2BitmapPtr cxPtr1 = {0};
3267
JBIG2BitmapPtr cxPtr2 = {0};
3268
JBIG2BitmapPtr cxPtr3 = {0};
3269
JBIG2BitmapPtr cxPtr4 = {0};
3270
JBIG2BitmapPtr cxPtr5 = {0};
3271
JBIG2BitmapPtr cxPtr6 = {0};
3272
JBIG2BitmapPtr tpgrCXPtr0 = {0};
3273
JBIG2BitmapPtr tpgrCXPtr1 = {0};
3274
JBIG2BitmapPtr tpgrCXPtr2 = {0};
3277
bitmap = new JBIG2Bitmap(0, w, h);
3278
if (!bitmap->isOk())
3283
bitmap->clearToZero();
3285
// set up the typical row context
3293
for (y = 0; y < h; ++y) {
3297
// set up the context
3298
bitmap->getPixelPtr(0, y-1, &cxPtr0);
3299
cx0 = bitmap->nextPixel(&cxPtr0);
3300
bitmap->getPixelPtr(-1, y, &cxPtr1);
3301
refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
3302
refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
3303
cx3 = refBitmap->nextPixel(&cxPtr3);
3304
cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
3305
refBitmap->getPixelPtr(-refDX, y+1-refDY, &cxPtr4);
3306
cx4 = refBitmap->nextPixel(&cxPtr4);
3308
// set up the typical prediction context
3309
tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3311
refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
3312
tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
3313
tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3314
tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3315
refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
3316
tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
3317
tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3318
tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3319
refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
3320
tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3321
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3322
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3324
tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy
3325
tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
3326
tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
3329
for (x = 0; x < w; ++x) {
3331
// update the context
3332
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 7;
3333
cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3334
cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 3;
3337
// update the typical predictor context
3338
tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3339
tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3340
tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3342
// check for a "typical" pixel
3343
if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3346
if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3347
bitmap->clearPixel(x, y);
3349
} else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3350
bitmap->setPixel(x, y);
3355
// build the context
3356
cx = (cx0 << 7) | (bitmap->nextPixel(&cxPtr1) << 6) |
3357
(refBitmap->nextPixel(&cxPtr2) << 5) |
3361
if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3362
bitmap->setPixel(x, y);
3368
// set up the context
3369
bitmap->getPixelPtr(0, y-1, &cxPtr0);
3370
cx0 = bitmap->nextPixel(&cxPtr0);
3371
bitmap->getPixelPtr(-1, y, &cxPtr1);
3372
refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
3373
cx2 = refBitmap->nextPixel(&cxPtr2);
3374
refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
3375
cx3 = refBitmap->nextPixel(&cxPtr3);
3376
cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
3377
refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &cxPtr4);
3378
cx4 = refBitmap->nextPixel(&cxPtr4);
3379
cx4 = (cx4 << 1) | refBitmap->nextPixel(&cxPtr4);
3380
bitmap->getPixelPtr(atx[0], y+aty[0], &cxPtr5);
3381
refBitmap->getPixelPtr(atx[1]-refDX, y+aty[1]-refDY, &cxPtr6);
3383
// set up the typical prediction context
3384
tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3386
refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
3387
tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
3388
tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3389
tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3390
refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
3391
tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
3392
tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3393
tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3394
refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
3395
tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3396
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3397
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3399
tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy
3400
tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
3401
tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
3404
for (x = 0; x < w; ++x) {
3406
// update the context
3407
cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 3;
3408
cx2 = ((cx2 << 1) | refBitmap->nextPixel(&cxPtr2)) & 3;
3409
cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3410
cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 7;
3413
// update the typical predictor context
3414
tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3415
tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3416
tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3418
// check for a "typical" pixel
3419
if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3422
if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3423
bitmap->clearPixel(x, y);
3425
} else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3426
bitmap->setPixel(x, y);
3431
// build the context
3432
cx = (cx0 << 11) | (bitmap->nextPixel(&cxPtr1) << 10) |
3433
(cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
3434
(bitmap->nextPixel(&cxPtr5) << 1) |
3435
refBitmap->nextPixel(&cxPtr6);
3438
if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3439
bitmap->setPixel(x, y);
3448
void JBIG2Stream::readPageInfoSeg(Guint length) {
3449
Guint xRes, yRes, flags, striping;
3451
if (!readULong(&pageW) || !readULong(&pageH) ||
3452
!readULong(&xRes) || !readULong(&yRes) ||
3453
!readUByte(&flags) || !readUWord(&striping)) {
3456
pageDefPixel = (flags >> 2) & 1;
3457
defCombOp = (flags >> 3) & 3;
3459
// allocate the page bitmap
3460
if (pageH == 0xffffffff) {
3461
curPageH = striping & 0x7fff;
3465
pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
3467
if (!pageBitmap->isOk()) {
3473
// default pixel value
3475
pageBitmap->clearToOne();
3477
pageBitmap->clearToZero();
3483
error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
3486
void JBIG2Stream::readEndOfStripeSeg(Guint length) {
3490
for (i = 0; i < length; ++i) {
3495
void JBIG2Stream::readProfilesSeg(Guint length) {
3499
for (i = 0; i < length; ++i) {
3504
void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) {
3505
JBIG2HuffmanTable *huffTab;
3506
Guint flags, oob, prefixBits, rangeBits;
3507
int lowVal, highVal, val;
3508
Guint huffTabSize, i;
3510
if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
3514
prefixBits = ((flags >> 1) & 7) + 1;
3515
rangeBits = ((flags >> 4) & 7) + 1;
3517
huffDecoder->reset();
3519
huffTab = (JBIG2HuffmanTable *)
3520
gmallocn(huffTabSize, sizeof(JBIG2HuffmanTable));
3523
while (val < highVal) {
3524
if (i == huffTabSize) {
3526
huffTab = (JBIG2HuffmanTable *)
3527
greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
3529
huffTab[i].val = val;
3530
huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3531
huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
3532
val += 1 << huffTab[i].rangeLen;
3535
if (i + oob + 3 > huffTabSize) {
3536
huffTabSize = i + oob + 3;
3537
huffTab = (JBIG2HuffmanTable *)
3538
greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
3540
huffTab[i].val = lowVal - 1;
3541
huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3542
huffTab[i].rangeLen = jbig2HuffmanLOW;
3544
huffTab[i].val = highVal;
3545
huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3546
huffTab[i].rangeLen = 32;
3550
huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
3551
huffTab[i].rangeLen = jbig2HuffmanOOB;
3555
huffTab[i].prefixLen = 0;
3556
huffTab[i].rangeLen = jbig2HuffmanEOT;
3557
huffDecoder->buildTable(huffTab, i);
3559
// create and store the new table segment
3560
segments->append(new JBIG2CodeTable(segNum, huffTab));
3565
error(curStr->getPos(), "Unexpected EOF in JBIG2 stream");
3568
void JBIG2Stream::readExtensionSeg(Guint length) {
3572
for (i = 0; i < length; ++i) {
3577
JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
3581
for (i = 0; i < globalSegments->getLength(); ++i) {
3582
seg = (JBIG2Segment *)globalSegments->get(i);
3583
if (seg->getSegNum() == segNum) {
3587
for (i = 0; i < segments->getLength(); ++i) {
3588
seg = (JBIG2Segment *)segments->get(i);
3589
if (seg->getSegNum() == segNum) {
3596
void JBIG2Stream::discardSegment(Guint segNum) {
3600
for (i = 0; i < globalSegments->getLength(); ++i) {
3601
seg = (JBIG2Segment *)globalSegments->get(i);
3602
if (seg->getSegNum() == segNum) {
3603
globalSegments->del(i);
3607
for (i = 0; i < segments->getLength(); ++i) {
3608
seg = (JBIG2Segment *)segments->get(i);
3609
if (seg->getSegNum() == segNum) {
3616
void JBIG2Stream::resetGenericStats(Guint templ,
3617
JArithmeticDecoderStats *prevStats) {
3620
size = contextSize[templ];
3621
if (prevStats && prevStats->getContextSize() == size) {
3622
if (genericRegionStats->getContextSize() == size) {
3623
genericRegionStats->copyFrom(prevStats);
3625
delete genericRegionStats;
3626
genericRegionStats = prevStats->copy();
3629
if (genericRegionStats->getContextSize() == size) {
3630
genericRegionStats->reset();
3632
delete genericRegionStats;
3633
genericRegionStats = new JArithmeticDecoderStats(1 << size);
3638
void JBIG2Stream::resetRefinementStats(Guint templ,
3639
JArithmeticDecoderStats *prevStats) {
3642
size = refContextSize[templ];
3643
if (prevStats && prevStats->getContextSize() == size) {
3644
if (refinementRegionStats->getContextSize() == size) {
3645
refinementRegionStats->copyFrom(prevStats);
3647
delete refinementRegionStats;
3648
refinementRegionStats = prevStats->copy();
3651
if (refinementRegionStats->getContextSize() == size) {
3652
refinementRegionStats->reset();
3654
delete refinementRegionStats;
3655
refinementRegionStats = new JArithmeticDecoderStats(1 << size);
3660
void JBIG2Stream::resetIntStats(int symCodeLen) {
3669
iardxStats->reset();
3670
iardyStats->reset();
3671
iardwStats->reset();
3672
iardhStats->reset();
3674
if (iaidStats->getContextSize() == 1 << (symCodeLen + 1)) {
3678
iaidStats = new JArithmeticDecoderStats(1 << (symCodeLen + 1));
3682
GBool JBIG2Stream::readUByte(Guint *x) {
3685
if ((c0 = curStr->getChar()) == EOF) {
3692
GBool JBIG2Stream::readByte(int *x) {
3695
if ((c0 = curStr->getChar()) == EOF) {
3705
GBool JBIG2Stream::readUWord(Guint *x) {
3708
if ((c0 = curStr->getChar()) == EOF ||
3709
(c1 = curStr->getChar()) == EOF) {
3712
*x = (Guint)((c0 << 8) | c1);
3716
GBool JBIG2Stream::readULong(Guint *x) {
3719
if ((c0 = curStr->getChar()) == EOF ||
3720
(c1 = curStr->getChar()) == EOF ||
3721
(c2 = curStr->getChar()) == EOF ||
3722
(c3 = curStr->getChar()) == EOF) {
3725
*x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3729
GBool JBIG2Stream::readLong(int *x) {
3732
if ((c0 = curStr->getChar()) == EOF ||
3733
(c1 = curStr->getChar()) == EOF ||
3734
(c2 = curStr->getChar()) == EOF ||
3735
(c3 = curStr->getChar()) == EOF) {
3738
*x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3740
*x |= -1 - (int)0xffffffff;