1 //========================================================================
5 // Copyright 2002-2003 Glyph & Cog, LLC
7 //========================================================================
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
19 #include "JArithmeticDecoder.h"
20 #include "JBIG2Stream.h"
22 //~ share these tables
23 #include "Stream-CCITT.h"
25 //------------------------------------------------------------------------
27 static int contextSize
[4] = { 16, 13, 10, 10 };
28 static int refContextSize
[2] = { 13, 10 };
30 //------------------------------------------------------------------------
32 //------------------------------------------------------------------------
34 #define jbig2HuffmanLOW 0xfffffffd
35 #define jbig2HuffmanOOB 0xfffffffe
36 #define jbig2HuffmanEOT 0xffffffff
38 struct JBIG2HuffmanTable
{
41 Guint rangeLen
; // can also be LOW, OOB, or EOT
45 JBIG2HuffmanTable huffTableA
[] = {
48 { 272, 3, 16, 0x006 },
49 { 65808, 3, 32, 0x007 },
50 { 0, 0, jbig2HuffmanEOT
, 0 }
53 JBIG2HuffmanTable huffTableB
[] = {
60 { 0, 6, jbig2HuffmanOOB
, 0x03f },
61 { 0, 0, jbig2HuffmanEOT
, 0 }
64 JBIG2HuffmanTable huffTableC
[] = {
70 { 0, 6, jbig2HuffmanOOB
, 0x03e },
72 { -256, 8, 8, 0x0fe },
73 { -257, 8, jbig2HuffmanLOW
, 0x0ff },
74 { 0, 0, jbig2HuffmanEOT
, 0 }
77 JBIG2HuffmanTable huffTableD
[] = {
84 { 0, 0, jbig2HuffmanEOT
, 0 }
87 JBIG2HuffmanTable huffTableE
[] = {
94 { -255, 7, 8, 0x07e },
95 { -256, 7, jbig2HuffmanLOW
, 0x07f },
96 { 0, 0, jbig2HuffmanEOT
, 0 }
99 JBIG2HuffmanTable huffTableF
[] = {
101 { 128, 3, 7, 0x002 },
102 { 256, 3, 8, 0x003 },
103 { -1024, 4, 9, 0x008 },
104 { -512, 4, 8, 0x009 },
105 { -256, 4, 7, 0x00a },
106 { -32, 4, 5, 0x00b },
107 { 512, 4, 9, 0x00c },
108 { 1024, 4, 10, 0x00d },
109 { -2048, 5, 10, 0x01c },
110 { -128, 5, 6, 0x01d },
111 { -64, 5, 5, 0x01e },
112 { -2049, 6, jbig2HuffmanLOW
, 0x03e },
113 { 2048, 6, 32, 0x03f },
114 { 0, 0, jbig2HuffmanEOT
, 0 }
117 JBIG2HuffmanTable huffTableG
[] = {
118 { -512, 3, 8, 0x000 },
119 { 256, 3, 8, 0x001 },
120 { 512, 3, 9, 0x002 },
121 { 1024, 3, 10, 0x003 },
122 { -1024, 4, 9, 0x008 },
123 { -256, 4, 7, 0x009 },
124 { -32, 4, 5, 0x00a },
126 { 128, 4, 7, 0x00c },
127 { -128, 5, 6, 0x01a },
128 { -64, 5, 5, 0x01b },
131 { -1025, 5, jbig2HuffmanLOW
, 0x01e },
132 { 2048, 5, 32, 0x01f },
133 { 0, 0, jbig2HuffmanEOT
, 0 }
136 JBIG2HuffmanTable huffTableH
[] = {
138 { 0, 2, jbig2HuffmanOOB
, 0x001 },
145 { 134, 5, 7, 0x01c },
148 { 262, 6, 7, 0x03c },
149 { 646, 6, 10, 0x03d },
151 { 390, 7, 8, 0x07d },
152 { -15, 8, 3, 0x0fc },
156 { -16, 9, jbig2HuffmanLOW
, 0x1fe },
157 { 1670, 9, 32, 0x1ff },
158 { 0, 0, jbig2HuffmanEOT
, 0 }
161 JBIG2HuffmanTable huffTableI
[] = {
162 { 0, 2, jbig2HuffmanOOB
, 0x000 },
170 { 139, 5, 7, 0x01b },
171 { 267, 5, 8, 0x01c },
174 { 523, 6, 8, 0x03c },
175 { 1291, 6, 11, 0x03d },
177 { 779, 7, 9, 0x07d },
178 { -31, 8, 4, 0x0fc },
179 { -11, 8, 2, 0x0fd },
180 { -15, 9, 2, 0x1fc },
182 { -32, 9, jbig2HuffmanLOW
, 0x1fe },
183 { 3339, 9, 32, 0x1ff },
184 { 0, 0, jbig2HuffmanEOT
, 0 }
187 JBIG2HuffmanTable huffTableJ
[] = {
190 { 0, 2, jbig2HuffmanOOB
, 0x002 },
195 { 102, 6, 5, 0x037 },
196 { 134, 6, 6, 0x038 },
197 { 198, 6, 7, 0x039 },
198 { 326, 6, 8, 0x03a },
199 { 582, 6, 9, 0x03b },
200 { 1094, 6, 10, 0x03c },
201 { -21, 7, 4, 0x07a },
204 { 2118, 7, 11, 0x07d },
207 { -22, 8, jbig2HuffmanLOW
, 0x0fe },
208 { 4166, 8, 32, 0x0ff },
209 { 0, 0, jbig2HuffmanEOT
, 0 }
212 JBIG2HuffmanTable huffTableK
[] = {
225 { 141, 7, 32, 0x07f },
226 { 0, 0, jbig2HuffmanEOT
, 0 }
229 JBIG2HuffmanTable huffTableL
[] = {
242 { 73, 8, 32, 0x0ff },
243 { 0, 0, jbig2HuffmanEOT
, 0 }
246 JBIG2HuffmanTable huffTableM
[] = {
259 { 141, 7, 32, 0x07f },
260 { 0, 0, jbig2HuffmanEOT
, 0 }
263 JBIG2HuffmanTable huffTableN
[] = {
269 { 0, 0, jbig2HuffmanEOT
, 0 }
272 JBIG2HuffmanTable huffTableO
[] = {
282 { -24, 7, 4, 0x07c },
284 { -25, 7, jbig2HuffmanLOW
, 0x07e },
285 { 25, 7, 32, 0x07f },
286 { 0, 0, jbig2HuffmanEOT
, 0 }
289 //------------------------------------------------------------------------
290 // JBIG2HuffmanDecoder
291 //------------------------------------------------------------------------
293 class JBIG2HuffmanDecoder
{
296 JBIG2HuffmanDecoder();
297 ~JBIG2HuffmanDecoder();
298 void setStream(Stream
*strA
) { str
= strA
; }
302 // Returns false for OOB, otherwise sets *<x> and returns true.
303 GBool
decodeInt(int *x
, JBIG2HuffmanTable
*table
);
305 Guint
readBits(Guint n
);
308 // Sort the table by prefix length and assign prefix values.
309 void buildTable(JBIG2HuffmanTable
*table
, Guint len
);
318 JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
323 JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {
326 void JBIG2HuffmanDecoder::reset() {
332 GBool
JBIG2HuffmanDecoder::decodeInt(int *x
, JBIG2HuffmanTable
*table
) {
333 Guint i
, len
, prefix
;
338 while (table
[i
].rangeLen
!= jbig2HuffmanEOT
) {
339 while (len
< table
[i
].prefixLen
) {
340 prefix
= (prefix
<< 1) | readBit();
343 if (prefix
== table
[i
].prefix
) {
344 if (table
[i
].rangeLen
== jbig2HuffmanOOB
) {
347 if (table
[i
].rangeLen
== jbig2HuffmanLOW
) {
348 *x
= table
[i
].val
- readBits(32);
349 } else if (table
[i
].rangeLen
> 0) {
350 *x
= table
[i
].val
+ readBits(table
[i
].rangeLen
);
361 Guint
JBIG2HuffmanDecoder::readBits(Guint n
) {
362 Guint x
, mask
, nLeft
;
364 mask
= (n
== 32) ? 0xffffffff : ((1 << n
) - 1);
366 x
= (buf
>> (bufLen
- n
)) & mask
;
369 x
= buf
& ((1 << bufLen
) - 1);
373 x
= (x
<< 8) | (str
->getChar() & 0xff);
377 buf
= str
->getChar();
379 x
= (x
<< nLeft
) | ((buf
>> bufLen
) & ((1 << nLeft
) - 1));
385 Guint
JBIG2HuffmanDecoder::readBit() {
387 buf
= str
->getChar();
391 return (buf
>> bufLen
) & 1;
394 void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable
*table
, Guint len
) {
395 Guint i
, j
, k
, prefix
;
396 JBIG2HuffmanTable tab
;
398 // stable selection sort:
399 // - entries with prefixLen > 0, in ascending prefixLen order
400 // - entry with prefixLen = 0, rangeLen = EOT
401 // - all other entries with prefixLen = 0
402 // (on entry, table[len] has prefixLen = 0, rangeLen = EOT)
403 for (i
= 0; i
< len
; ++i
) {
404 for (j
= i
; j
< len
&& table
[j
].prefixLen
== 0; ++j
) ;
408 for (k
= j
+ 1; k
< len
; ++k
) {
409 if (table
[k
].prefixLen
> 0 &&
410 table
[k
].prefixLen
< table
[j
].prefixLen
) {
416 for (k
= j
; k
> i
; --k
) {
417 table
[k
] = table
[k
- 1];
422 table
[i
] = table
[len
];
427 table
[i
++].prefix
= prefix
++;
428 for (; table
[i
].rangeLen
!= jbig2HuffmanEOT
; ++i
) {
429 prefix
<<= table
[i
].prefixLen
- table
[i
-1].prefixLen
;
430 table
[i
].prefix
= prefix
++;
434 //------------------------------------------------------------------------
436 //------------------------------------------------------------------------
438 class JBIG2MMRDecoder
{
443 void setStream(Stream
*strA
) { str
= strA
; }
449 void skipTo(Guint length
);
459 JBIG2MMRDecoder::JBIG2MMRDecoder() {
464 JBIG2MMRDecoder::~JBIG2MMRDecoder() {
467 void JBIG2MMRDecoder::reset() {
473 int JBIG2MMRDecoder::get2DCode() {
477 buf
= str
->getChar() & 0xff;
480 p
= &twoDimTab1
[(buf
>> 1) & 0x7f];
481 } else if (bufLen
== 8) {
482 p
= &twoDimTab1
[(buf
>> 1) & 0x7f];
484 p
= &twoDimTab1
[(buf
<< (7 - bufLen
)) & 0x7f];
485 if (p
->bits
< 0 || p
->bits
> (int)bufLen
) {
486 buf
= (buf
<< 8) | (str
->getChar() & 0xff);
489 p
= &twoDimTab1
[(buf
>> (bufLen
- 7)) & 0x7f];
493 error(str
->getPos(), "Bad two dim code in JBIG2 MMR stream");
500 int JBIG2MMRDecoder::getWhiteCode() {
505 buf
= str
->getChar() & 0xff;
510 if (bufLen
>= 7 && ((buf
>> (bufLen
- 7)) & 0x7f) == 0) {
512 code
= buf
<< (12 - bufLen
);
514 code
= buf
>> (bufLen
- 12);
516 p
= &whiteTab1
[code
& 0x1f];
519 code
= buf
<< (9 - bufLen
);
521 code
= buf
>> (bufLen
- 9);
523 p
= &whiteTab2
[code
& 0x1ff];
525 if (p
->bits
> 0 && p
->bits
<= (int)bufLen
) {
532 buf
= (buf
<< 8) | (str
->getChar() & 0xff);
536 error(str
->getPos(), "Bad white code in JBIG2 MMR stream");
537 // eat a bit and return a positive number so that the caller doesn't
538 // go into an infinite loop
543 int JBIG2MMRDecoder::getBlackCode() {
548 buf
= str
->getChar() & 0xff;
553 if (bufLen
>= 6 && ((buf
>> (bufLen
- 6)) & 0x3f) == 0) {
555 code
= buf
<< (13 - bufLen
);
557 code
= buf
>> (bufLen
- 13);
559 p
= &blackTab1
[code
& 0x7f];
560 } else if (bufLen
>= 4 && ((buf
>> (bufLen
- 4)) & 0x0f) == 0) {
562 code
= buf
<< (12 - bufLen
);
564 code
= buf
>> (bufLen
- 12);
566 p
= &blackTab2
[(code
& 0xff) - 64];
569 code
= buf
<< (6 - bufLen
);
571 code
= buf
>> (bufLen
- 6);
573 p
= &blackTab3
[code
& 0x3f];
575 if (p
->bits
> 0 && p
->bits
<= (int)bufLen
) {
582 buf
= (buf
<< 8) | (str
->getChar() & 0xff);
586 error(str
->getPos(), "Bad black code in JBIG2 MMR stream");
587 // eat a bit and return a positive number so that the caller doesn't
588 // go into an infinite loop
593 Guint
JBIG2MMRDecoder::get24Bits() {
594 while (bufLen
< 24) {
595 buf
= (buf
<< 8) | (str
->getChar() & 0xff);
599 return (buf
>> (bufLen
- 24)) & 0xffffff;
602 void JBIG2MMRDecoder::skipTo(Guint length
) {
603 while (nBytesRead
< length
) {
609 //------------------------------------------------------------------------
611 //------------------------------------------------------------------------
613 enum JBIG2SegmentType
{
623 JBIG2Segment(Guint segNumA
) { segNum
= segNumA
; }
624 virtual ~JBIG2Segment() {}
625 void setSegNum(Guint segNumA
) { segNum
= segNumA
; }
626 Guint
getSegNum() { return segNum
; }
627 virtual JBIG2SegmentType
getType() = 0;
634 //------------------------------------------------------------------------
636 //------------------------------------------------------------------------
638 struct JBIG2BitmapPtr
{
644 class JBIG2Bitmap
: public JBIG2Segment
{
647 JBIG2Bitmap(Guint segNumA
, int wA
, int hA
);
648 virtual ~JBIG2Bitmap();
649 virtual JBIG2SegmentType
getType() { return jbig2SegBitmap
; }
650 JBIG2Bitmap
*copy() { return new JBIG2Bitmap(0, this); }
651 JBIG2Bitmap
*getSlice(Guint x
, Guint y
, Guint wA
, Guint hA
);
652 void expand(int newH
, Guint pixel
);
655 int getWidth() { return w
; }
656 int getHeight() { return h
; }
657 int getPixel(int x
, int y
)
658 { return (x
< 0 || x
>= w
|| y
< 0 || y
>= h
) ? 0 :
659 (data
[y
* line
+ (x
>> 3)] >> (7 - (x
& 7))) & 1; }
660 void setPixel(int x
, int y
)
661 { data
[y
* line
+ (x
>> 3)] |= 1 << (7 - (x
& 7)); }
662 void clearPixel(int x
, int y
)
663 { data
[y
* line
+ (x
>> 3)] &= 0x7f7f >> (x
& 7); }
664 void getPixelPtr(int x
, int y
, JBIG2BitmapPtr
*ptr
);
665 int nextPixel(JBIG2BitmapPtr
*ptr
);
666 void duplicateRow(int yDest
, int ySrc
);
667 void combine(JBIG2Bitmap
*bitmap
, int x
, int y
, Guint combOp
);
668 Guchar
*getDataPtr() { return data
; }
669 int getDataSize() { return h
* line
; }
673 JBIG2Bitmap(Guint segNumA
, JBIG2Bitmap
*bitmap
);
679 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA
, int wA
, int hA
):
680 JBIG2Segment(segNumA
)
684 line
= (wA
+ 7) >> 3;
685 if (w
<= 0 || h
<= 0 || line
<= 0 || h
>= (INT_MAX
- 1) / line
) {
689 // need to allocate one extra guard byte for use in combine()
690 data
= (Guchar
*)gmalloc(h
* line
+ 1);
694 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA
, JBIG2Bitmap
*bitmap
):
695 JBIG2Segment(segNumA
)
700 if (w
<= 0 || h
<= 0 || line
<= 0 || h
>= (INT_MAX
- 1) / line
) {
704 // need to allocate one extra guard byte for use in combine()
705 data
= (Guchar
*)gmalloc(h
* line
+ 1);
706 memcpy(data
, bitmap
->data
, h
* line
);
710 JBIG2Bitmap::~JBIG2Bitmap() {
715 JBIG2Bitmap
*JBIG2Bitmap::getSlice(Guint x
, Guint y
, Guint wA
, Guint hA
) {
719 slice
= new JBIG2Bitmap(0, wA
, hA
);
720 slice
->clearToZero();
721 for (yy
= 0; yy
< hA
; ++yy
) {
722 for (xx
= 0; xx
< wA
; ++xx
) {
723 if (getPixel(x
+ xx
, y
+ yy
)) {
724 slice
->setPixel(xx
, yy
);
731 void JBIG2Bitmap::expand(int newH
, Guint pixel
) {
732 if (newH
<= h
|| line
<= 0 || newH
>= (INT_MAX
- 1) / line
) {
735 // need to allocate one extra guard byte for use in combine()
736 data
= (Guchar
*)grealloc(data
, newH
* line
+ 1);
738 memset(data
+ h
* line
, 0xff, (newH
- h
) * line
);
740 memset(data
+ h
* line
, 0x00, (newH
- h
) * line
);
746 void JBIG2Bitmap::clearToZero() {
747 memset(data
, 0, h
* line
);
750 void JBIG2Bitmap::clearToOne() {
751 memset(data
, 0xff, h
* line
);
754 inline void JBIG2Bitmap::getPixelPtr(int x
, int y
, JBIG2BitmapPtr
*ptr
) {
755 if (y
< 0 || y
>= h
|| x
>= w
) {
758 ptr
->p
= &data
[y
* line
];
762 ptr
->p
= &data
[y
* line
+ (x
>> 3)];
763 ptr
->shift
= 7 - (x
& 7);
768 inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr
*ptr
) {
773 } else if (ptr
->x
< 0) {
777 pix
= (*ptr
->p
>> ptr
->shift
) & 1;
780 } else if (ptr
->shift
== 0) {
790 void JBIG2Bitmap::duplicateRow(int yDest
, int ySrc
) {
791 memcpy(data
+ yDest
* line
, data
+ ySrc
* line
, line
);
794 void JBIG2Bitmap::combine(JBIG2Bitmap
*bitmap
, int x
, int y
,
796 int x0
, x1
, y0
, y1
, xx
, yy
;
797 Guchar
*srcPtr
, *destPtr
;
798 Guint src0
, src1
, src
, dest
, s1
, s2
, m1
, m2
, m3
;
806 if (y
+ bitmap
->h
> h
) {
830 m1
= 0xff >> (x1
& 7);
831 m2
= 0xff << (((x1
& 7) == 0) ? 0 : 8 - (x1
& 7));
832 m3
= (0xff >> s1
) & m2
;
834 oneByte
= x0
== ((x1
- 1) & ~7);
836 for (yy
= y0
; yy
< y1
; ++yy
) {
838 // one byte per line -- need to mask both left and right side
841 destPtr
= data
+ (y
+ yy
) * line
+ (x
>> 3);
842 srcPtr
= bitmap
->data
+ yy
* bitmap
->line
;
847 dest
|= (src1
>> s1
) & m2
;
850 dest
&= ((0xff00 | src1
) >> s1
) | m1
;
853 dest
^= (src1
>> s1
) & m2
;
856 dest
^= ((src1
^ 0xff) >> s1
) & m2
;
859 dest
= (dest
& ~m3
) | ((src1
>> s1
) & m3
);
864 destPtr
= data
+ (y
+ yy
) * line
;
865 srcPtr
= bitmap
->data
+ yy
* bitmap
->line
+ (-x
>> 3);
879 dest
^= (src1
^ 0xff) & m2
;
882 dest
= (src1
& m2
) | (dest
& m1
);
888 // multiple bytes per line -- need to mask left side of left-most
889 // byte and right side of right-most byte
894 destPtr
= data
+ (y
+ yy
) * line
+ (x
>> 3);
895 srcPtr
= bitmap
->data
+ yy
* bitmap
->line
;
903 dest
&= (0xff00 | src1
) >> s1
;
909 dest
^= (src1
^ 0xff) >> s1
;
912 dest
= (dest
& (0xff << s2
)) | (src1
>> s1
);
918 destPtr
= data
+ (y
+ yy
) * line
;
919 srcPtr
= bitmap
->data
+ yy
* bitmap
->line
+ (-x
>> 3);
925 for (; xx
< x1
- 8; xx
+= 8) {
929 src
= (((src0
<< 8) | src1
) >> s1
) & 0xff;
951 // note: this last byte (src1) may not actually be used, depending
952 // on the values of s1, m1, and m2 - and in fact, it may be off
953 // the edge of the source bitmap, which means we need to allocate
954 // one extra guard byte at the end of each bitmap
958 src
= (((src0
<< 8) | src1
) >> s1
) & 0xff;
970 dest
^= (src
^ 0xff) & m2
;
973 dest
= (src
& m2
) | (dest
& m1
);
981 //------------------------------------------------------------------------
983 //------------------------------------------------------------------------
985 class JBIG2SymbolDict
: public JBIG2Segment
{
988 JBIG2SymbolDict(Guint segNumA
, Guint sizeA
);
989 virtual ~JBIG2SymbolDict();
990 virtual JBIG2SegmentType
getType() { return jbig2SegSymbolDict
; }
991 Guint
getSize() { return size
; }
992 void setBitmap(Guint idx
, JBIG2Bitmap
*bitmap
) { bitmaps
[idx
] = bitmap
; }
993 JBIG2Bitmap
*getBitmap(Guint idx
) { return bitmaps
[idx
]; }
994 void setGenericRegionStats(JArithmeticDecoderStats
*stats
)
995 { genericRegionStats
= stats
; }
996 void setRefinementRegionStats(JArithmeticDecoderStats
*stats
)
997 { refinementRegionStats
= stats
; }
998 JArithmeticDecoderStats
*getGenericRegionStats()
999 { return genericRegionStats
; }
1000 JArithmeticDecoderStats
*getRefinementRegionStats()
1001 { return refinementRegionStats
; }
1006 JBIG2Bitmap
**bitmaps
;
1007 JArithmeticDecoderStats
*genericRegionStats
;
1008 JArithmeticDecoderStats
*refinementRegionStats
;
1011 JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA
, Guint sizeA
):
1012 JBIG2Segment(segNumA
)
1015 bitmaps
= (JBIG2Bitmap
**)gmallocn(size
, sizeof(JBIG2Bitmap
*));
1016 genericRegionStats
= NULL
;
1017 refinementRegionStats
= NULL
;
1020 JBIG2SymbolDict::~JBIG2SymbolDict() {
1023 for (i
= 0; i
< size
; ++i
) {
1027 if (genericRegionStats
) {
1028 delete genericRegionStats
;
1030 if (refinementRegionStats
) {
1031 delete refinementRegionStats
;
1035 //------------------------------------------------------------------------
1037 //------------------------------------------------------------------------
1039 class JBIG2PatternDict
: public JBIG2Segment
{
1042 JBIG2PatternDict(Guint segNumA
, Guint sizeA
);
1043 virtual ~JBIG2PatternDict();
1044 virtual JBIG2SegmentType
getType() { return jbig2SegPatternDict
; }
1045 Guint
getSize() { return size
; }
1046 void setBitmap(Guint idx
, JBIG2Bitmap
*bitmap
) { bitmaps
[idx
] = bitmap
; }
1047 JBIG2Bitmap
*getBitmap(Guint idx
) { return bitmaps
[idx
]; }
1052 JBIG2Bitmap
**bitmaps
;
1055 JBIG2PatternDict::JBIG2PatternDict(Guint segNumA
, Guint sizeA
):
1056 JBIG2Segment(segNumA
)
1059 bitmaps
= (JBIG2Bitmap
**)gmallocn(size
, sizeof(JBIG2Bitmap
*));
1062 JBIG2PatternDict::~JBIG2PatternDict() {
1065 for (i
= 0; i
< size
; ++i
) {
1071 //------------------------------------------------------------------------
1073 //------------------------------------------------------------------------
1075 class JBIG2CodeTable
: public JBIG2Segment
{
1078 JBIG2CodeTable(Guint segNumA
, JBIG2HuffmanTable
*tableA
);
1079 virtual ~JBIG2CodeTable();
1080 virtual JBIG2SegmentType
getType() { return jbig2SegCodeTable
; }
1081 JBIG2HuffmanTable
*getHuffTable() { return table
; }
1085 JBIG2HuffmanTable
*table
;
1088 JBIG2CodeTable::JBIG2CodeTable(Guint segNumA
, JBIG2HuffmanTable
*tableA
):
1089 JBIG2Segment(segNumA
)
1094 JBIG2CodeTable::~JBIG2CodeTable() {
1098 //------------------------------------------------------------------------
1100 //------------------------------------------------------------------------
1102 JBIG2Stream::JBIG2Stream(Stream
*strA
, Object
*globalsStream
):
1107 arithDecoder
= new JArithmeticDecoder();
1108 genericRegionStats
= new JArithmeticDecoderStats(1 << 1);
1109 refinementRegionStats
= new JArithmeticDecoderStats(1 << 1);
1110 iadhStats
= new JArithmeticDecoderStats(1 << 9);
1111 iadwStats
= new JArithmeticDecoderStats(1 << 9);
1112 iaexStats
= new JArithmeticDecoderStats(1 << 9);
1113 iaaiStats
= new JArithmeticDecoderStats(1 << 9);
1114 iadtStats
= new JArithmeticDecoderStats(1 << 9);
1115 iaitStats
= new JArithmeticDecoderStats(1 << 9);
1116 iafsStats
= new JArithmeticDecoderStats(1 << 9);
1117 iadsStats
= new JArithmeticDecoderStats(1 << 9);
1118 iardxStats
= new JArithmeticDecoderStats(1 << 9);
1119 iardyStats
= new JArithmeticDecoderStats(1 << 9);
1120 iardwStats
= new JArithmeticDecoderStats(1 << 9);
1121 iardhStats
= new JArithmeticDecoderStats(1 << 9);
1122 iariStats
= new JArithmeticDecoderStats(1 << 9);
1123 iaidStats
= new JArithmeticDecoderStats(1 << 1);
1124 huffDecoder
= new JBIG2HuffmanDecoder();
1125 mmrDecoder
= new JBIG2MMRDecoder();
1127 segments
= globalSegments
= new GList();
1128 if (globalsStream
->isStream()) {
1129 curStr
= globalsStream
->getStream();
1131 arithDecoder
->setStream(curStr
);
1132 huffDecoder
->setStream(curStr
);
1133 mmrDecoder
->setStream(curStr
);
1139 dataPtr
= dataEnd
= NULL
;
1142 JBIG2Stream::~JBIG2Stream() {
1143 delete arithDecoder
;
1144 delete genericRegionStats
;
1145 delete refinementRegionStats
;
1166 deleteGList(segments
, JBIG2Segment
);
1168 if (globalSegments
) {
1169 deleteGList(globalSegments
, JBIG2Segment
);
1174 void JBIG2Stream::reset() {
1180 deleteGList(segments
, JBIG2Segment
);
1182 segments
= new GList();
1186 arithDecoder
->setStream(curStr
);
1187 huffDecoder
->setStream(curStr
);
1188 mmrDecoder
->setStream(curStr
);
1192 dataPtr
= pageBitmap
->getDataPtr();
1193 dataEnd
= dataPtr
+ pageBitmap
->getDataSize();
1199 int JBIG2Stream::getChar() {
1200 if (dataPtr
&& dataPtr
< dataEnd
) {
1201 return (*dataPtr
++ ^ 0xff) & 0xff;
1206 int JBIG2Stream::lookChar() {
1207 if (dataPtr
&& dataPtr
< dataEnd
) {
1208 return (*dataPtr
^ 0xff) & 0xff;
1213 GString
*JBIG2Stream::getPSFilter(int psLevel
, char *indent
) {
1217 GBool
JBIG2Stream::isBinary(GBool last
) {
1218 return str
->isBinary(gTrue
);
1221 void JBIG2Stream::readSegments() {
1222 Guint segNum
, segFlags
, segType
, page
, segLength
;
1223 Guint refFlags
, nRefSegs
;
1228 while (readULong(&segNum
)) {
1230 // segment header flags
1231 if (!readUByte(&segFlags
)) {
1234 segType
= segFlags
& 0x3f;
1236 // referred-to segment count and retention flags
1237 if (!readUByte(&refFlags
)) {
1240 nRefSegs
= refFlags
>> 5;
1241 if (nRefSegs
== 7) {
1242 if ((c1
= curStr
->getChar()) == EOF
||
1243 (c2
= curStr
->getChar()) == EOF
||
1244 (c3
= curStr
->getChar()) == EOF
) {
1247 refFlags
= (refFlags
<< 24) | (c1
<< 16) | (c2
<< 8) | c3
;
1248 nRefSegs
= refFlags
& 0x1fffffff;
1249 for (i
= 0; i
< (nRefSegs
+ 9) >> 3; ++i
) {
1250 c1
= curStr
->getChar();
1254 // referred-to segment numbers
1255 refSegs
= (Guint
*)gmallocn(nRefSegs
, sizeof(Guint
));
1256 if (segNum
<= 256) {
1257 for (i
= 0; i
< nRefSegs
; ++i
) {
1258 if (!readUByte(&refSegs
[i
])) {
1262 } else if (segNum
<= 65536) {
1263 for (i
= 0; i
< nRefSegs
; ++i
) {
1264 if (!readUWord(&refSegs
[i
])) {
1269 for (i
= 0; i
< nRefSegs
; ++i
) {
1270 if (!readULong(&refSegs
[i
])) {
1276 // segment page association
1277 if (segFlags
& 0x40) {
1278 if (!readULong(&page
)) {
1282 if (!readUByte(&page
)) {
1287 // segment data length
1288 if (!readULong(&segLength
)) {
1292 // read the segment data
1295 if (!readSymbolDictSeg(segNum
, segLength
, refSegs
, nRefSegs
)) {
1300 readTextRegionSeg(segNum
, gFalse
, gFalse
, segLength
, refSegs
, nRefSegs
);
1303 readTextRegionSeg(segNum
, gTrue
, gFalse
, segLength
, refSegs
, nRefSegs
);
1306 readTextRegionSeg(segNum
, gTrue
, gTrue
, segLength
, refSegs
, nRefSegs
);
1309 readPatternDictSeg(segNum
, segLength
);
1312 readHalftoneRegionSeg(segNum
, gFalse
, gFalse
, segLength
,
1316 readHalftoneRegionSeg(segNum
, gTrue
, gFalse
, segLength
,
1320 readHalftoneRegionSeg(segNum
, gTrue
, gTrue
, segLength
,
1324 readGenericRegionSeg(segNum
, gFalse
, gFalse
, segLength
);
1327 readGenericRegionSeg(segNum
, gTrue
, gFalse
, segLength
);
1330 readGenericRegionSeg(segNum
, gTrue
, gTrue
, segLength
);
1333 readGenericRefinementRegionSeg(segNum
, gFalse
, gFalse
, segLength
,
1337 readGenericRefinementRegionSeg(segNum
, gTrue
, gFalse
, segLength
,
1341 readGenericRefinementRegionSeg(segNum
, gTrue
, gTrue
, segLength
,
1345 readPageInfoSeg(segLength
);
1348 readEndOfStripeSeg(segLength
);
1351 readProfilesSeg(segLength
);
1354 readCodeTableSeg(segNum
, segLength
);
1357 readExtensionSeg(segLength
);
1360 error(getPos(), "Unknown segment type in JBIG2 stream");
1361 for (i
= 0; i
< segLength
; ++i
) {
1362 if ((c1
= curStr
->getChar()) == EOF
) {
1381 error(getPos(), "Unexpected EOF in JBIG2 stream");
1384 GBool
JBIG2Stream::readSymbolDictSeg(Guint segNum
, Guint length
,
1385 Guint
*refSegs
, Guint nRefSegs
) {
1386 JBIG2SymbolDict
*symbolDict
;
1387 JBIG2HuffmanTable
*huffDHTable
, *huffDWTable
;
1388 JBIG2HuffmanTable
*huffBMSizeTable
, *huffAggInstTable
;
1391 JBIG2SymbolDict
*inputSymbolDict
;
1392 Guint flags
, sdTemplate
, sdrTemplate
, huff
, refAgg
;
1393 Guint huffDH
, huffDW
, huffBMSize
, huffAggInst
;
1394 Guint contextUsed
, contextRetained
;
1395 int sdATX
[4], sdATY
[4], sdrATX
[2], sdrATY
[2];
1396 Guint numExSyms
, numNewSyms
, numInputSyms
, symCodeLen
;
1397 JBIG2Bitmap
**bitmaps
;
1398 JBIG2Bitmap
*collBitmap
, *refBitmap
;
1400 Guint symHeight
, symWidth
, totalWidth
, x
, symID
;
1401 int dh
, dw
, refAggNum
, refDX
, refDY
, bmSize
;
1407 // symbol dictionary flags
1408 if (!readUWord(&flags
)) {
1411 sdTemplate
= (flags
>> 10) & 3;
1412 sdrTemplate
= (flags
>> 12) & 1;
1414 refAgg
= (flags
>> 1) & 1;
1415 huffDH
= (flags
>> 2) & 3;
1416 huffDW
= (flags
>> 4) & 3;
1417 huffBMSize
= (flags
>> 6) & 1;
1418 huffAggInst
= (flags
>> 7) & 1;
1419 contextUsed
= (flags
>> 8) & 1;
1420 contextRetained
= (flags
>> 9) & 1;
1422 // symbol dictionary AT flags
1424 if (sdTemplate
== 0) {
1425 if (!readByte(&sdATX
[0]) ||
1426 !readByte(&sdATY
[0]) ||
1427 !readByte(&sdATX
[1]) ||
1428 !readByte(&sdATY
[1]) ||
1429 !readByte(&sdATX
[2]) ||
1430 !readByte(&sdATY
[2]) ||
1431 !readByte(&sdATX
[3]) ||
1432 !readByte(&sdATY
[3])) {
1436 if (!readByte(&sdATX
[0]) ||
1437 !readByte(&sdATY
[0])) {
1443 // symbol dictionary refinement AT flags
1444 if (refAgg
&& !sdrTemplate
) {
1445 if (!readByte(&sdrATX
[0]) ||
1446 !readByte(&sdrATY
[0]) ||
1447 !readByte(&sdrATX
[1]) ||
1448 !readByte(&sdrATY
[1])) {
1453 // SDNUMEXSYMS and SDNUMNEWSYMS
1454 if (!readULong(&numExSyms
) || !readULong(&numNewSyms
)) {
1458 // get referenced segments: input symbol dictionaries and code tables
1459 codeTables
= new GList();
1461 for (i
= 0; i
< nRefSegs
; ++i
) {
1462 seg
= findSegment(refSegs
[i
]);
1463 if (seg
->getType() == jbig2SegSymbolDict
) {
1464 numInputSyms
+= ((JBIG2SymbolDict
*)seg
)->getSize();
1465 } else if (seg
->getType() == jbig2SegCodeTable
) {
1466 codeTables
->append(seg
);
1470 // compute symbol code length
1473 while (i
< numInputSyms
+ numNewSyms
) {
1478 // get the input symbol bitmaps
1479 bitmaps
= (JBIG2Bitmap
**)gmallocn(numInputSyms
+ numNewSyms
,
1480 sizeof(JBIG2Bitmap
*));
1481 for (i
= 0; i
< numInputSyms
+ numNewSyms
; ++i
) {
1485 inputSymbolDict
= NULL
;
1486 for (i
= 0; i
< nRefSegs
; ++i
) {
1487 seg
= findSegment(refSegs
[i
]);
1488 if (seg
->getType() == jbig2SegSymbolDict
) {
1489 inputSymbolDict
= (JBIG2SymbolDict
*)seg
;
1490 for (j
= 0; j
< inputSymbolDict
->getSize(); ++j
) {
1491 bitmaps
[k
++] = inputSymbolDict
->getBitmap(j
);
1496 // get the Huffman tables
1497 huffDHTable
= huffDWTable
= NULL
; // make gcc happy
1498 huffBMSizeTable
= huffAggInstTable
= NULL
; // make gcc happy
1502 huffDHTable
= huffTableD
;
1503 } else if (huffDH
== 1) {
1504 huffDHTable
= huffTableE
;
1506 huffDHTable
= ((JBIG2CodeTable
*)codeTables
->get(i
++))->getHuffTable();
1509 huffDWTable
= huffTableB
;
1510 } else if (huffDW
== 1) {
1511 huffDWTable
= huffTableC
;
1513 huffDWTable
= ((JBIG2CodeTable
*)codeTables
->get(i
++))->getHuffTable();
1515 if (huffBMSize
== 0) {
1516 huffBMSizeTable
= huffTableA
;
1519 ((JBIG2CodeTable
*)codeTables
->get(i
++))->getHuffTable();
1521 if (huffAggInst
== 0) {
1522 huffAggInstTable
= huffTableA
;
1525 ((JBIG2CodeTable
*)codeTables
->get(i
++))->getHuffTable();
1530 // set up the Huffman decoder
1532 huffDecoder
->reset();
1534 // set up the arithmetic decoder
1536 if (contextUsed
&& inputSymbolDict
) {
1537 resetGenericStats(sdTemplate
, inputSymbolDict
->getGenericRegionStats());
1539 resetGenericStats(sdTemplate
, NULL
);
1541 resetIntStats(symCodeLen
);
1542 arithDecoder
->start();
1545 // set up the arithmetic decoder for refinement/aggregation
1547 if (contextUsed
&& inputSymbolDict
) {
1548 resetRefinementStats(sdrTemplate
,
1549 inputSymbolDict
->getRefinementRegionStats());
1551 resetRefinementStats(sdrTemplate
, NULL
);
1555 // allocate symbol widths storage
1557 if (huff
&& !refAgg
) {
1558 symWidths
= (Guint
*)gmallocn(numNewSyms
, sizeof(Guint
));
1563 while (i
< numNewSyms
) {
1565 // read the height class delta height
1567 huffDecoder
->decodeInt(&dh
, huffDHTable
);
1569 arithDecoder
->decodeInt(&dh
, iadhStats
);
1571 if (dh
< 0 && (Guint
)-dh
>= symHeight
) {
1572 error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
1580 // read the symbols in this height class
1583 // read the delta width
1585 if (!huffDecoder
->decodeInt(&dw
, huffDWTable
)) {
1589 if (!arithDecoder
->decodeInt(&dw
, iadwStats
)) {
1593 if (dw
< 0 && (Guint
)-dw
>= symWidth
) {
1594 error(getPos(), "Bad delta-height value in JBIG2 symbol dictionary");
1599 // using a collective bitmap, so don't read a bitmap here
1600 if (huff
&& !refAgg
) {
1601 symWidths
[i
] = symWidth
;
1602 totalWidth
+= symWidth
;
1604 // refinement/aggregate coding
1605 } else if (refAgg
) {
1607 if (!huffDecoder
->decodeInt(&refAggNum
, huffAggInstTable
)) {
1611 if (!arithDecoder
->decodeInt(&refAggNum
, iaaiStats
)) {
1615 #if 0 //~ This special case was added about a year before the final draft
1616 //~ of the JBIG2 spec was released. I have encountered some old
1617 //~ JBIG2 images that predate it.
1620 if (refAggNum
== 1) {
1623 symID
= huffDecoder
->readBits(symCodeLen
);
1624 huffDecoder
->decodeInt(&refDX
, huffTableO
);
1625 huffDecoder
->decodeInt(&refDY
, huffTableO
);
1626 huffDecoder
->decodeInt(&bmSize
, huffTableA
);
1627 huffDecoder
->reset();
1628 arithDecoder
->start();
1630 symID
= arithDecoder
->decodeIAID(symCodeLen
, iaidStats
);
1631 arithDecoder
->decodeInt(&refDX
, iardxStats
);
1632 arithDecoder
->decodeInt(&refDY
, iardyStats
);
1634 refBitmap
= bitmaps
[symID
];
1635 bitmaps
[numInputSyms
+ i
] =
1636 readGenericRefinementRegion(symWidth
, symHeight
,
1637 sdrTemplate
, gFalse
,
1638 refBitmap
, refDX
, refDY
,
1640 //~ do we need to use the bmSize value here (in Huffman mode)?
1642 bitmaps
[numInputSyms
+ i
] =
1643 readTextRegion(huff
, gTrue
, symWidth
, symHeight
,
1644 refAggNum
, 0, numInputSyms
+ i
, NULL
,
1645 symCodeLen
, bitmaps
, 0, 0, 0, 1, 0,
1646 huffTableF
, huffTableH
, huffTableK
, huffTableO
,
1647 huffTableO
, huffTableO
, huffTableO
, huffTableA
,
1648 sdrTemplate
, sdrATX
, sdrATY
);
1651 // non-ref/agg coding
1653 bitmaps
[numInputSyms
+ i
] =
1654 readGenericBitmap(gFalse
, symWidth
, symHeight
,
1655 sdTemplate
, gFalse
, gFalse
, NULL
,
1662 // read the collective bitmap
1663 if (huff
&& !refAgg
) {
1664 huffDecoder
->decodeInt(&bmSize
, huffBMSizeTable
);
1665 huffDecoder
->reset();
1667 collBitmap
= new JBIG2Bitmap(0, totalWidth
, symHeight
);
1668 bmSize
= symHeight
* ((totalWidth
+ 7) >> 3);
1669 p
= collBitmap
->getDataPtr();
1670 for (k
= 0; k
< (Guint
)bmSize
; ++k
) {
1671 *p
++ = curStr
->getChar();
1674 collBitmap
= readGenericBitmap(gTrue
, totalWidth
, symHeight
,
1675 0, gFalse
, gFalse
, NULL
, NULL
, NULL
,
1679 for (; j
< i
; ++j
) {
1680 bitmaps
[numInputSyms
+ j
] =
1681 collBitmap
->getSlice(x
, 0, symWidths
[j
], symHeight
);
1688 // create the symbol dict object
1689 symbolDict
= new JBIG2SymbolDict(segNum
, numExSyms
);
1691 // exported symbol list
1694 while (i
< numInputSyms
+ numNewSyms
) {
1696 huffDecoder
->decodeInt(&run
, huffTableA
);
1698 arithDecoder
->decodeInt(&run
, iaexStats
);
1701 for (cnt
= 0; cnt
< run
; ++cnt
) {
1702 symbolDict
->setBitmap(j
++, bitmaps
[i
++]->copy());
1710 for (i
= 0; i
< numNewSyms
; ++i
) {
1711 delete bitmaps
[numInputSyms
+ i
];
1718 // save the arithmetic decoder stats
1719 if (!huff
&& contextRetained
) {
1720 symbolDict
->setGenericRegionStats(genericRegionStats
->copy());
1722 symbolDict
->setRefinementRegionStats(refinementRegionStats
->copy());
1726 // store the new symbol dict
1727 segments
->append(symbolDict
);
1732 for (i
= 0; i
< numNewSyms
; ++i
) {
1733 if (bitmaps
[numInputSyms
+ i
]) {
1734 delete bitmaps
[numInputSyms
+ i
];
1744 error(getPos(), "Unexpected EOF in JBIG2 stream");
1748 void JBIG2Stream::readTextRegionSeg(Guint segNum
, GBool imm
,
1749 GBool lossless
, Guint length
,
1750 Guint
*refSegs
, Guint nRefSegs
) {
1751 JBIG2Bitmap
*bitmap
;
1752 JBIG2HuffmanTable runLengthTab
[36];
1753 JBIG2HuffmanTable
*symCodeTab
;
1754 JBIG2HuffmanTable
*huffFSTable
, *huffDSTable
, *huffDTTable
;
1755 JBIG2HuffmanTable
*huffRDWTable
, *huffRDHTable
;
1756 JBIG2HuffmanTable
*huffRDXTable
, *huffRDYTable
, *huffRSizeTable
;
1759 JBIG2SymbolDict
*symbolDict
;
1761 Guint w
, h
, x
, y
, segInfoFlags
, extCombOp
;
1762 Guint flags
, huff
, refine
, logStrips
, refCorner
, transposed
;
1763 Guint combOp
, defPixel
, templ
;
1765 Guint huffFlags
, huffFS
, huffDS
, huffDT
;
1766 Guint huffRDW
, huffRDH
, huffRDX
, huffRDY
, huffRSize
;
1767 Guint numInstances
, numSyms
, symCodeLen
;
1772 // region segment info field
1773 if (!readULong(&w
) || !readULong(&h
) ||
1774 !readULong(&x
) || !readULong(&y
) ||
1775 !readUByte(&segInfoFlags
)) {
1778 extCombOp
= segInfoFlags
& 7;
1780 // rest of the text region header
1781 if (!readUWord(&flags
)) {
1785 refine
= (flags
>> 1) & 1;
1786 logStrips
= (flags
>> 2) & 3;
1787 refCorner
= (flags
>> 4) & 3;
1788 transposed
= (flags
>> 6) & 1;
1789 combOp
= (flags
>> 7) & 3;
1790 defPixel
= (flags
>> 9) & 1;
1791 sOffset
= (flags
>> 10) & 0x1f;
1792 if (sOffset
& 0x10) {
1793 sOffset
|= -1 - 0x0f;
1795 templ
= (flags
>> 15) & 1;
1796 huffFS
= huffDS
= huffDT
= 0; // make gcc happy
1797 huffRDW
= huffRDH
= huffRDX
= huffRDY
= huffRSize
= 0; // make gcc happy
1799 if (!readUWord(&huffFlags
)) {
1802 huffFS
= huffFlags
& 3;
1803 huffDS
= (huffFlags
>> 2) & 3;
1804 huffDT
= (huffFlags
>> 4) & 3;
1805 huffRDW
= (huffFlags
>> 6) & 3;
1806 huffRDH
= (huffFlags
>> 8) & 3;
1807 huffRDX
= (huffFlags
>> 10) & 3;
1808 huffRDY
= (huffFlags
>> 12) & 3;
1809 huffRSize
= (huffFlags
>> 14) & 1;
1811 if (refine
&& templ
== 0) {
1812 if (!readByte(&atx
[0]) || !readByte(&aty
[0]) ||
1813 !readByte(&atx
[1]) || !readByte(&aty
[1])) {
1817 if (!readULong(&numInstances
)) {
1821 // get symbol dictionaries and tables
1822 codeTables
= new GList();
1824 for (i
= 0; i
< nRefSegs
; ++i
) {
1825 if ((seg
= findSegment(refSegs
[i
]))) {
1826 if (seg
->getType() == jbig2SegSymbolDict
) {
1827 numSyms
+= ((JBIG2SymbolDict
*)seg
)->getSize();
1828 } else if (seg
->getType() == jbig2SegCodeTable
) {
1829 codeTables
->append(seg
);
1832 error(getPos(), "Invalid segment reference in JBIG2 text region");
1837 while (i
< numSyms
) {
1842 // get the symbol bitmaps
1843 syms
= (JBIG2Bitmap
**)gmallocn(numSyms
, sizeof(JBIG2Bitmap
*));
1845 for (i
= 0; i
< nRefSegs
; ++i
) {
1846 if ((seg
= findSegment(refSegs
[i
]))) {
1847 if (seg
->getType() == jbig2SegSymbolDict
) {
1848 symbolDict
= (JBIG2SymbolDict
*)seg
;
1849 for (k
= 0; k
< symbolDict
->getSize(); ++k
) {
1850 syms
[kk
++] = symbolDict
->getBitmap(k
);
1856 // get the Huffman tables
1857 huffFSTable
= huffDSTable
= huffDTTable
= NULL
; // make gcc happy
1858 huffRDWTable
= huffRDHTable
= NULL
; // make gcc happy
1859 huffRDXTable
= huffRDYTable
= huffRSizeTable
= NULL
; // make gcc happy
1863 huffFSTable
= huffTableF
;
1864 } else if (huffFS
== 1) {
1865 huffFSTable
= huffTableG
;
1867 huffFSTable
= ((JBIG2CodeTable
*)codeTables
->get(i
++))->getHuffTable();
1870 huffDSTable
= huffTableH
;
1871 } else if (huffDS
== 1) {
1872 huffDSTable
= huffTableI
;
1873 } else if (huffDS
== 2) {
1874 huffDSTable
= huffTableJ
;
1876 huffDSTable
= ((JBIG2CodeTable
*)codeTables
->get(i
++))->getHuffTable();
1879 huffDTTable
= huffTableK
;
1880 } else if (huffDT
== 1) {
1881 huffDTTable
= huffTableL
;
1882 } else if (huffDT
== 2) {
1883 huffDTTable
= huffTableM
;
1885 huffDTTable
= ((JBIG2CodeTable
*)codeTables
->get(i
++))->getHuffTable();
1888 huffRDWTable
= huffTableN
;
1889 } else if (huffRDW
== 1) {
1890 huffRDWTable
= huffTableO
;
1892 huffRDWTable
= ((JBIG2CodeTable
*)codeTables
->get(i
++))->getHuffTable();
1895 huffRDHTable
= huffTableN
;
1896 } else if (huffRDH
== 1) {
1897 huffRDHTable
= huffTableO
;
1899 huffRDHTable
= ((JBIG2CodeTable
*)codeTables
->get(i
++))->getHuffTable();
1902 huffRDXTable
= huffTableN
;
1903 } else if (huffRDX
== 1) {
1904 huffRDXTable
= huffTableO
;
1906 huffRDXTable
= ((JBIG2CodeTable
*)codeTables
->get(i
++))->getHuffTable();
1909 huffRDYTable
= huffTableN
;
1910 } else if (huffRDY
== 1) {
1911 huffRDYTable
= huffTableO
;
1913 huffRDYTable
= ((JBIG2CodeTable
*)codeTables
->get(i
++))->getHuffTable();
1915 if (huffRSize
== 0) {
1916 huffRSizeTable
= huffTableA
;
1919 ((JBIG2CodeTable
*)codeTables
->get(i
++))->getHuffTable();
1924 // symbol ID Huffman decoding table
1926 huffDecoder
->reset();
1927 for (i
= 0; i
< 32; ++i
) {
1928 runLengthTab
[i
].val
= i
;
1929 runLengthTab
[i
].prefixLen
= huffDecoder
->readBits(4);
1930 runLengthTab
[i
].rangeLen
= 0;
1932 runLengthTab
[32].val
= 0x103;
1933 runLengthTab
[32].prefixLen
= huffDecoder
->readBits(4);
1934 runLengthTab
[32].rangeLen
= 2;
1935 runLengthTab
[33].val
= 0x203;
1936 runLengthTab
[33].prefixLen
= huffDecoder
->readBits(4);
1937 runLengthTab
[33].rangeLen
= 3;
1938 runLengthTab
[34].val
= 0x20b;
1939 runLengthTab
[34].prefixLen
= huffDecoder
->readBits(4);
1940 runLengthTab
[34].rangeLen
= 7;
1941 runLengthTab
[35].prefixLen
= 0;
1942 runLengthTab
[35].rangeLen
= jbig2HuffmanEOT
;
1943 huffDecoder
->buildTable(runLengthTab
, 35);
1944 symCodeTab
= (JBIG2HuffmanTable
*)gmallocn(numSyms
+ 1,
1945 sizeof(JBIG2HuffmanTable
));
1946 for (i
= 0; i
< numSyms
; ++i
) {
1947 symCodeTab
[i
].val
= i
;
1948 symCodeTab
[i
].rangeLen
= 0;
1951 while (i
< numSyms
) {
1952 huffDecoder
->decodeInt(&j
, runLengthTab
);
1954 for (j
-= 0x200; j
&& i
< numSyms
; --j
) {
1955 symCodeTab
[i
++].prefixLen
= 0;
1957 } else if (j
> 0x100) {
1958 for (j
-= 0x100; j
&& i
< numSyms
; --j
) {
1959 symCodeTab
[i
].prefixLen
= symCodeTab
[i
-1].prefixLen
;
1963 symCodeTab
[i
++].prefixLen
= j
;
1966 symCodeTab
[numSyms
].prefixLen
= 0;
1967 symCodeTab
[numSyms
].rangeLen
= jbig2HuffmanEOT
;
1968 huffDecoder
->buildTable(symCodeTab
, numSyms
);
1969 huffDecoder
->reset();
1971 // set up the arithmetic decoder
1974 resetIntStats(symCodeLen
);
1975 arithDecoder
->start();
1978 resetRefinementStats(templ
, NULL
);
1981 bitmap
= readTextRegion(huff
, refine
, w
, h
, numInstances
,
1982 logStrips
, numSyms
, symCodeTab
, symCodeLen
, syms
,
1983 defPixel
, combOp
, transposed
, refCorner
, sOffset
,
1984 huffFSTable
, huffDSTable
, huffDTTable
,
1985 huffRDWTable
, huffRDHTable
,
1986 huffRDXTable
, huffRDYTable
, huffRSizeTable
,
1991 // combine the region bitmap into the page bitmap
1993 if (pageH
== 0xffffffff && y
+ h
> curPageH
) {
1994 pageBitmap
->expand(y
+ h
, pageDefPixel
);
1996 pageBitmap
->combine(bitmap
, x
, y
, extCombOp
);
1999 // store the region bitmap
2001 bitmap
->setSegNum(segNum
);
2002 segments
->append(bitmap
);
2005 // clean up the Huffman decoder
2013 error(getPos(), "Unexpected EOF in JBIG2 stream");
2016 JBIG2Bitmap
*JBIG2Stream::readTextRegion(GBool huff
, GBool refine
,
2021 JBIG2HuffmanTable
*symCodeTab
,
2024 Guint defPixel
, Guint combOp
,
2025 Guint transposed
, Guint refCorner
,
2027 JBIG2HuffmanTable
*huffFSTable
,
2028 JBIG2HuffmanTable
*huffDSTable
,
2029 JBIG2HuffmanTable
*huffDTTable
,
2030 JBIG2HuffmanTable
*huffRDWTable
,
2031 JBIG2HuffmanTable
*huffRDHTable
,
2032 JBIG2HuffmanTable
*huffRDXTable
,
2033 JBIG2HuffmanTable
*huffRDYTable
,
2034 JBIG2HuffmanTable
*huffRSizeTable
,
2036 int *atx
, int *aty
) {
2037 JBIG2Bitmap
*bitmap
;
2038 JBIG2Bitmap
*symbolBitmap
;
2040 int t
, dt
, tt
, s
, ds
, sFirst
, j
;
2041 int rdw
, rdh
, rdx
, rdy
, ri
, refDX
, refDY
, bmSize
;
2042 Guint symID
, inst
, bw
, bh
;
2044 strips
= 1 << logStrips
;
2046 // allocate the bitmap
2047 bitmap
= new JBIG2Bitmap(0, w
, h
);
2049 bitmap
->clearToOne();
2051 bitmap
->clearToZero();
2054 // decode initial T value
2056 huffDecoder
->decodeInt(&t
, huffDTTable
);
2058 arithDecoder
->decodeInt(&t
, iadtStats
);
2064 while (inst
< numInstances
) {
2068 huffDecoder
->decodeInt(&dt
, huffDTTable
);
2070 arithDecoder
->decodeInt(&dt
, iadtStats
);
2076 huffDecoder
->decodeInt(&ds
, huffFSTable
);
2078 arithDecoder
->decodeInt(&ds
, iafsStats
);
2083 // read the instances
2090 dt
= huffDecoder
->readBits(logStrips
);
2092 arithDecoder
->decodeInt(&dt
, iaitStats
);
2099 huffDecoder
->decodeInt(&j
, symCodeTab
);
2102 symID
= huffDecoder
->readBits(symCodeLen
);
2105 symID
= arithDecoder
->decodeIAID(symCodeLen
, iaidStats
);
2108 if (symID
>= (Guint
)numSyms
) {
2109 error(getPos(), "Invalid symbol number in JBIG2 text region");
2112 // get the symbol bitmap
2113 symbolBitmap
= NULL
;
2116 ri
= (int)huffDecoder
->readBit();
2118 arithDecoder
->decodeInt(&ri
, iariStats
);
2125 huffDecoder
->decodeInt(&rdw
, huffRDWTable
);
2126 huffDecoder
->decodeInt(&rdh
, huffRDHTable
);
2127 huffDecoder
->decodeInt(&rdx
, huffRDXTable
);
2128 huffDecoder
->decodeInt(&rdy
, huffRDYTable
);
2129 huffDecoder
->decodeInt(&bmSize
, huffRSizeTable
);
2130 huffDecoder
->reset();
2131 arithDecoder
->start();
2133 arithDecoder
->decodeInt(&rdw
, iardwStats
);
2134 arithDecoder
->decodeInt(&rdh
, iardhStats
);
2135 arithDecoder
->decodeInt(&rdx
, iardxStats
);
2136 arithDecoder
->decodeInt(&rdy
, iardyStats
);
2138 refDX
= ((rdw
>= 0) ? rdw
: rdw
- 1) / 2 + rdx
;
2139 refDY
= ((rdh
>= 0) ? rdh
: rdh
- 1) / 2 + rdy
;
2142 readGenericRefinementRegion(rdw
+ syms
[symID
]->getWidth(),
2143 rdh
+ syms
[symID
]->getHeight(),
2144 templ
, gFalse
, syms
[symID
],
2145 refDX
, refDY
, atx
, aty
);
2146 //~ do we need to use the bmSize value here (in Huffman mode)?
2148 symbolBitmap
= syms
[symID
];
2151 // combine the symbol bitmap into the region bitmap
2152 //~ something is wrong here - refCorner shouldn't degenerate into
2154 bw
= symbolBitmap
->getWidth() - 1;
2155 bh
= symbolBitmap
->getHeight() - 1;
2157 switch (refCorner
) {
2158 case 0: // bottom left
2159 bitmap
->combine(symbolBitmap
, tt
, s
, combOp
);
2162 bitmap
->combine(symbolBitmap
, tt
, s
, combOp
);
2164 case 2: // bottom right
2165 bitmap
->combine(symbolBitmap
, tt
- bw
, s
, combOp
);
2167 case 3: // top right
2168 bitmap
->combine(symbolBitmap
, tt
- bw
, s
, combOp
);
2173 switch (refCorner
) {
2174 case 0: // bottom left
2175 bitmap
->combine(symbolBitmap
, s
, tt
- bh
, combOp
);
2178 bitmap
->combine(symbolBitmap
, s
, tt
, combOp
);
2180 case 2: // bottom right
2181 bitmap
->combine(symbolBitmap
, s
, tt
- bh
, combOp
);
2183 case 3: // top right
2184 bitmap
->combine(symbolBitmap
, s
, tt
, combOp
);
2190 delete symbolBitmap
;
2199 if (!huffDecoder
->decodeInt(&ds
, huffDSTable
)) {
2203 if (!arithDecoder
->decodeInt(&ds
, iadsStats
)) {
2214 void JBIG2Stream::readPatternDictSeg(Guint segNum
, Guint length
) {
2215 JBIG2PatternDict
*patternDict
;
2216 JBIG2Bitmap
*bitmap
;
2217 Guint flags
, patternW
, patternH
, grayMax
, templ
, mmr
;
2221 // halftone dictionary flags, pattern width and height, max gray value
2222 if (!readUByte(&flags
) ||
2223 !readUByte(&patternW
) ||
2224 !readUByte(&patternH
) ||
2225 !readULong(&grayMax
)) {
2228 templ
= (flags
>> 1) & 3;
2231 // set up the arithmetic decoder
2233 resetGenericStats(templ
, NULL
);
2234 arithDecoder
->start();
2238 atx
[0] = -(int)patternW
; aty
[0] = 0;
2239 atx
[1] = -3; aty
[1] = -1;
2240 atx
[2] = 2; aty
[2] = -2;
2241 atx
[3] = -2; aty
[3] = -2;
2242 bitmap
= readGenericBitmap(mmr
, (grayMax
+ 1) * patternW
, patternH
,
2243 templ
, gFalse
, gFalse
, NULL
,
2244 atx
, aty
, length
- 7);
2246 // create the pattern dict object
2247 patternDict
= new JBIG2PatternDict(segNum
, grayMax
+ 1);
2249 // split up the bitmap
2251 for (i
= 0; i
<= grayMax
; ++i
) {
2252 patternDict
->setBitmap(i
, bitmap
->getSlice(x
, 0, patternW
, patternH
));
2259 // store the new pattern dict
2260 segments
->append(patternDict
);
2265 error(getPos(), "Unexpected EOF in JBIG2 stream");
2268 void JBIG2Stream::readHalftoneRegionSeg(Guint segNum
, GBool imm
,
2269 GBool lossless
, Guint length
,
2270 Guint
*refSegs
, Guint nRefSegs
) {
2271 JBIG2Bitmap
*bitmap
;
2273 JBIG2PatternDict
*patternDict
;
2274 JBIG2Bitmap
*skipBitmap
;
2276 JBIG2Bitmap
*grayBitmap
;
2277 JBIG2Bitmap
*patternBitmap
;
2278 Guint w
, h
, x
, y
, segInfoFlags
, extCombOp
;
2279 Guint flags
, mmr
, templ
, enableSkip
, combOp
;
2280 Guint gridW
, gridH
, stepX
, stepY
, patW
, patH
;
2282 int gridX
, gridY
, xx
, yy
, bit
, j
;
2285 // region segment info field
2286 if (!readULong(&w
) || !readULong(&h
) ||
2287 !readULong(&x
) || !readULong(&y
) ||
2288 !readUByte(&segInfoFlags
)) {
2291 extCombOp
= segInfoFlags
& 7;
2293 // rest of the halftone region header
2294 if (!readUByte(&flags
)) {
2298 templ
= (flags
>> 1) & 3;
2299 enableSkip
= (flags
>> 3) & 1;
2300 combOp
= (flags
>> 4) & 7;
2301 if (!readULong(&gridW
) || !readULong(&gridH
) ||
2302 !readLong(&gridX
) || !readLong(&gridY
) ||
2303 !readUWord(&stepX
) || !readUWord(&stepY
)) {
2306 if (w
== 0 || h
== 0 || w
>= INT_MAX
/ h
) {
2307 error(getPos(), "Bad bitmap size in JBIG2 halftone segment");
2310 if (gridH
== 0 || gridW
>= INT_MAX
/ gridH
) {
2311 error(getPos(), "Bad grid size in JBIG2 halftone segment");
2315 // get pattern dictionary
2316 if (nRefSegs
!= 1) {
2317 error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2320 seg
= findSegment(refSegs
[0]);
2321 if (seg
->getType() != jbig2SegPatternDict
) {
2322 error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
2325 patternDict
= (JBIG2PatternDict
*)seg
;
2328 while (i
< patternDict
->getSize()) {
2332 patW
= patternDict
->getBitmap(0)->getWidth();
2333 patH
= patternDict
->getBitmap(0)->getHeight();
2335 // set up the arithmetic decoder
2337 resetGenericStats(templ
, NULL
);
2338 arithDecoder
->start();
2341 // allocate the bitmap
2342 bitmap
= new JBIG2Bitmap(segNum
, w
, h
);
2343 if (flags
& 0x80) { // HDEFPIXEL
2344 bitmap
->clearToOne();
2346 bitmap
->clearToZero();
2349 // compute the skip bitmap
2352 skipBitmap
= new JBIG2Bitmap(0, gridW
, gridH
);
2353 skipBitmap
->clearToZero();
2354 for (m
= 0; m
< gridH
; ++m
) {
2355 xx
= gridX
+ m
* stepY
;
2356 yy
= gridY
+ m
* stepX
;
2357 for (n
= 0; n
< gridW
; ++n
) {
2358 if (((xx
+ (int)patW
) >> 8) <= 0 || (xx
>> 8) >= (int)w
||
2359 ((yy
+ (int)patH
) >> 8) <= 0 || (yy
>> 8) >= (int)h
) {
2360 skipBitmap
->setPixel(n
, m
);
2366 // read the gray-scale image
2367 grayImg
= (Guint
*)gmallocn(gridW
* gridH
, sizeof(Guint
));
2368 memset(grayImg
, 0, gridW
* gridH
* sizeof(Guint
));
2369 atx
[0] = templ
<= 1 ? 3 : 2; aty
[0] = -1;
2370 atx
[1] = -3; aty
[1] = -1;
2371 atx
[2] = 2; aty
[2] = -2;
2372 atx
[3] = -2; aty
[3] = -2;
2373 for (j
= bpp
- 1; j
>= 0; --j
) {
2374 grayBitmap
= readGenericBitmap(mmr
, gridW
, gridH
, templ
, gFalse
,
2375 enableSkip
, skipBitmap
, atx
, aty
, -1);
2377 for (m
= 0; m
< gridH
; ++m
) {
2378 for (n
= 0; n
< gridW
; ++n
) {
2379 bit
= grayBitmap
->getPixel(n
, m
) ^ (grayImg
[i
] & 1);
2380 grayImg
[i
] = (grayImg
[i
] << 1) | bit
;
2389 for (m
= 0; m
< gridH
; ++m
) {
2390 xx
= gridX
+ m
* stepY
;
2391 yy
= gridY
+ m
* stepX
;
2392 for (n
= 0; n
< gridW
; ++n
) {
2393 if (!(enableSkip
&& skipBitmap
->getPixel(n
, m
))) {
2394 patternBitmap
= patternDict
->getBitmap(grayImg
[i
]);
2395 bitmap
->combine(patternBitmap
, xx
>> 8, yy
>> 8, combOp
);
2405 // combine the region bitmap into the page bitmap
2407 if (pageH
== 0xffffffff && y
+ h
> curPageH
) {
2408 pageBitmap
->expand(y
+ h
, pageDefPixel
);
2410 pageBitmap
->combine(bitmap
, x
, y
, extCombOp
);
2413 // store the region bitmap
2415 segments
->append(bitmap
);
2421 error(getPos(), "Unexpected EOF in JBIG2 stream");
2424 void JBIG2Stream::readGenericRegionSeg(Guint segNum
, GBool imm
,
2425 GBool lossless
, Guint length
) {
2426 JBIG2Bitmap
*bitmap
;
2427 Guint w
, h
, x
, y
, segInfoFlags
, extCombOp
;
2428 Guint flags
, mmr
, templ
, tpgdOn
;
2431 // region segment info field
2432 if (!readULong(&w
) || !readULong(&h
) ||
2433 !readULong(&x
) || !readULong(&y
) ||
2434 !readUByte(&segInfoFlags
)) {
2437 extCombOp
= segInfoFlags
& 7;
2439 // rest of the generic region segment header
2440 if (!readUByte(&flags
)) {
2444 templ
= (flags
>> 1) & 3;
2445 tpgdOn
= (flags
>> 3) & 1;
2450 if (!readByte(&atx
[0]) ||
2451 !readByte(&aty
[0]) ||
2452 !readByte(&atx
[1]) ||
2453 !readByte(&aty
[1]) ||
2454 !readByte(&atx
[2]) ||
2455 !readByte(&aty
[2]) ||
2456 !readByte(&atx
[3]) ||
2457 !readByte(&aty
[3])) {
2461 if (!readByte(&atx
[0]) ||
2462 !readByte(&aty
[0])) {
2468 // set up the arithmetic decoder
2470 resetGenericStats(templ
, NULL
);
2471 arithDecoder
->start();
2475 bitmap
= readGenericBitmap(mmr
, w
, h
, templ
, tpgdOn
, gFalse
,
2476 NULL
, atx
, aty
, mmr
? 0 : length
- 18);
2478 // combine the region bitmap into the page bitmap
2480 if (pageH
== 0xffffffff && y
+ h
> curPageH
) {
2481 pageBitmap
->expand(y
+ h
, pageDefPixel
);
2483 pageBitmap
->combine(bitmap
, x
, y
, extCombOp
);
2486 // store the region bitmap
2488 bitmap
->setSegNum(segNum
);
2489 segments
->append(bitmap
);
2495 error(getPos(), "Unexpected EOF in JBIG2 stream");
2498 JBIG2Bitmap
*JBIG2Stream::readGenericBitmap(GBool mmr
, int w
, int h
,
2499 int templ
, GBool tpgdOn
,
2500 GBool useSkip
, JBIG2Bitmap
*skip
,
2502 int mmrDataLength
) {
2503 JBIG2Bitmap
*bitmap
;
2505 Guint ltpCX
, cx
, cx0
, cx1
, cx2
;
2506 JBIG2BitmapPtr cxPtr0
, cxPtr1
;
2507 JBIG2BitmapPtr atPtr0
, atPtr1
, atPtr2
, atPtr3
;
2508 int *refLine
, *codingLine
;
2509 int code1
, code2
, code3
;
2510 int x
, y
, a0
, pix
, i
, refI
, codingI
;
2512 bitmap
= new JBIG2Bitmap(0, w
, h
);
2513 bitmap
->clearToZero();
2519 mmrDecoder
->reset();
2520 refLine
= (int *)gmallocn(w
+ 2, sizeof(int));
2521 codingLine
= (int *)gmallocn(w
+ 2, sizeof(int));
2522 codingLine
[0] = codingLine
[1] = w
;
2524 for (y
= 0; y
< h
; ++y
) {
2526 // copy coding line to ref line
2527 for (i
= 0; codingLine
[i
] < w
; ++i
) {
2528 refLine
[i
] = codingLine
[i
];
2530 refLine
[i
] = refLine
[i
+ 1] = w
;
2533 refI
= 0; // b1 = refLine[refI]
2534 codingI
= 0; // a1 = codingLine[codingI]
2537 code1
= mmrDecoder
->get2DCode();
2540 if (refLine
[refI
] < w
) {
2541 a0
= refLine
[refI
+ 1];
2549 code1
+= code3
= mmrDecoder
->getBlackCode();
2550 } while (code3
>= 64);
2553 code2
+= code3
= mmrDecoder
->getWhiteCode();
2554 } while (code3
>= 64);
2558 code1
+= code3
= mmrDecoder
->getWhiteCode();
2559 } while (code3
>= 64);
2562 code2
+= code3
= mmrDecoder
->getBlackCode();
2563 } while (code3
>= 64);
2565 if (code1
> 0 || code2
> 0) {
2566 a0
= codingLine
[codingI
++] = a0
+ code1
;
2567 a0
= codingLine
[codingI
++] = a0
+ code2
;
2568 while (refLine
[refI
] <= a0
&& refLine
[refI
] < w
) {
2574 a0
= codingLine
[codingI
++] = refLine
[refI
];
2575 if (refLine
[refI
] < w
) {
2580 a0
= codingLine
[codingI
++] = refLine
[refI
] + 1;
2581 if (refLine
[refI
] < w
) {
2583 while (refLine
[refI
] <= a0
&& refLine
[refI
] < w
) {
2589 a0
= codingLine
[codingI
++] = refLine
[refI
] + 2;
2590 if (refLine
[refI
] < w
) {
2592 while (refLine
[refI
] <= a0
&& refLine
[refI
] < w
) {
2598 a0
= codingLine
[codingI
++] = refLine
[refI
] + 3;
2599 if (refLine
[refI
] < w
) {
2601 while (refLine
[refI
] <= a0
&& refLine
[refI
] < w
) {
2607 a0
= codingLine
[codingI
++] = refLine
[refI
] - 1;
2613 while (refLine
[refI
] <= a0
&& refLine
[refI
] < w
) {
2618 a0
= codingLine
[codingI
++] = refLine
[refI
] - 2;
2624 while (refLine
[refI
] <= a0
&& refLine
[refI
] < w
) {
2629 a0
= codingLine
[codingI
++] = refLine
[refI
] - 3;
2635 while (refLine
[refI
] <= a0
&& refLine
[refI
] < w
) {
2640 error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
2644 codingLine
[codingI
++] = w
;
2646 // convert the run lengths to a bitmap line
2648 while (codingLine
[i
] < w
) {
2649 for (x
= codingLine
[i
]; x
< codingLine
[i
+1]; ++x
) {
2650 bitmap
->setPixel(x
, y
);
2656 if (mmrDataLength
>= 0) {
2657 mmrDecoder
->skipTo(mmrDataLength
);
2659 if (mmrDecoder
->get24Bits() != 0x001001) {
2660 error(getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
2667 //----- arithmetic decode
2670 // set up the typical row context
2671 ltpCX
= 0; // make gcc happy
2675 ltpCX
= 0x3953; // 001 11001 0101 0011
2678 ltpCX
= 0x079a; // 0011 11001 101 0
2681 ltpCX
= 0x0e3; // 001 1100 01 1
2684 ltpCX
= 0x18a; // 01100 0101 1
2690 cx
= cx0
= cx1
= cx2
= 0; // make gcc happy
2691 for (y
= 0; y
< h
; ++y
) {
2693 // check for a "typical" (duplicate) row
2695 if (arithDecoder
->decodeBit(ltpCX
, genericRegionStats
)) {
2699 bitmap
->duplicateRow(y
, y
-1);
2707 // set up the context
2708 bitmap
->getPixelPtr(0, y
-2, &cxPtr0
);
2709 cx0
= bitmap
->nextPixel(&cxPtr0
);
2710 cx0
= (cx0
<< 1) | bitmap
->nextPixel(&cxPtr0
);
2711 bitmap
->getPixelPtr(0, y
-1, &cxPtr1
);
2712 cx1
= bitmap
->nextPixel(&cxPtr1
);
2713 cx1
= (cx1
<< 1) | bitmap
->nextPixel(&cxPtr1
);
2714 cx1
= (cx1
<< 1) | bitmap
->nextPixel(&cxPtr1
);
2716 bitmap
->getPixelPtr(atx
[0], y
+ aty
[0], &atPtr0
);
2717 bitmap
->getPixelPtr(atx
[1], y
+ aty
[1], &atPtr1
);
2718 bitmap
->getPixelPtr(atx
[2], y
+ aty
[2], &atPtr2
);
2719 bitmap
->getPixelPtr(atx
[3], y
+ aty
[3], &atPtr3
);
2722 for (x
= 0; x
< w
; ++x
) {
2724 // build the context
2725 cx
= (cx0
<< 13) | (cx1
<< 8) | (cx2
<< 4) |
2726 (bitmap
->nextPixel(&atPtr0
) << 3) |
2727 (bitmap
->nextPixel(&atPtr1
) << 2) |
2728 (bitmap
->nextPixel(&atPtr2
) << 1) |
2729 bitmap
->nextPixel(&atPtr3
);
2731 // check for a skipped pixel
2732 if (useSkip
&& skip
->getPixel(x
, y
)) {
2736 } else if ((pix
= arithDecoder
->decodeBit(cx
, genericRegionStats
))) {
2737 bitmap
->setPixel(x
, y
);
2740 // update the context
2741 cx0
= ((cx0
<< 1) | bitmap
->nextPixel(&cxPtr0
)) & 0x07;
2742 cx1
= ((cx1
<< 1) | bitmap
->nextPixel(&cxPtr1
)) & 0x1f;
2743 cx2
= ((cx2
<< 1) | pix
) & 0x0f;
2749 // set up the context
2750 bitmap
->getPixelPtr(0, y
-2, &cxPtr0
);
2751 cx0
= bitmap
->nextPixel(&cxPtr0
);
2752 cx0
= (cx0
<< 1) | bitmap
->nextPixel(&cxPtr0
);
2753 cx0
= (cx0
<< 1) | bitmap
->nextPixel(&cxPtr0
);
2754 bitmap
->getPixelPtr(0, y
-1, &cxPtr1
);
2755 cx1
= bitmap
->nextPixel(&cxPtr1
);
2756 cx1
= (cx1
<< 1) | bitmap
->nextPixel(&cxPtr1
);
2757 cx1
= (cx1
<< 1) | bitmap
->nextPixel(&cxPtr1
);
2759 bitmap
->getPixelPtr(atx
[0], y
+ aty
[0], &atPtr0
);
2762 for (x
= 0; x
< w
; ++x
) {
2764 // build the context
2765 cx
= (cx0
<< 9) | (cx1
<< 4) | (cx2
<< 1) |
2766 bitmap
->nextPixel(&atPtr0
);
2768 // check for a skipped pixel
2769 if (useSkip
&& skip
->getPixel(x
, y
)) {
2773 } else if ((pix
= arithDecoder
->decodeBit(cx
, genericRegionStats
))) {
2774 bitmap
->setPixel(x
, y
);
2777 // update the context
2778 cx0
= ((cx0
<< 1) | bitmap
->nextPixel(&cxPtr0
)) & 0x0f;
2779 cx1
= ((cx1
<< 1) | bitmap
->nextPixel(&cxPtr1
)) & 0x1f;
2780 cx2
= ((cx2
<< 1) | pix
) & 0x07;
2786 // set up the context
2787 bitmap
->getPixelPtr(0, y
-2, &cxPtr0
);
2788 cx0
= bitmap
->nextPixel(&cxPtr0
);
2789 cx0
= (cx0
<< 1) | bitmap
->nextPixel(&cxPtr0
);
2790 bitmap
->getPixelPtr(0, y
-1, &cxPtr1
);
2791 cx1
= bitmap
->nextPixel(&cxPtr1
);
2792 cx1
= (cx1
<< 1) | bitmap
->nextPixel(&cxPtr1
);
2794 bitmap
->getPixelPtr(atx
[0], y
+ aty
[0], &atPtr0
);
2797 for (x
= 0; x
< w
; ++x
) {
2799 // build the context
2800 cx
= (cx0
<< 7) | (cx1
<< 3) | (cx2
<< 1) |
2801 bitmap
->nextPixel(&atPtr0
);
2803 // check for a skipped pixel
2804 if (useSkip
&& skip
->getPixel(x
, y
)) {
2808 } else if ((pix
= arithDecoder
->decodeBit(cx
, genericRegionStats
))) {
2809 bitmap
->setPixel(x
, y
);
2812 // update the context
2813 cx0
= ((cx0
<< 1) | bitmap
->nextPixel(&cxPtr0
)) & 0x07;
2814 cx1
= ((cx1
<< 1) | bitmap
->nextPixel(&cxPtr1
)) & 0x0f;
2815 cx2
= ((cx2
<< 1) | pix
) & 0x03;
2821 // set up the context
2822 bitmap
->getPixelPtr(0, y
-1, &cxPtr1
);
2823 cx1
= bitmap
->nextPixel(&cxPtr1
);
2824 cx1
= (cx1
<< 1) | bitmap
->nextPixel(&cxPtr1
);
2826 bitmap
->getPixelPtr(atx
[0], y
+ aty
[0], &atPtr0
);
2829 for (x
= 0; x
< w
; ++x
) {
2831 // build the context
2832 cx
= (cx1
<< 5) | (cx2
<< 1) |
2833 bitmap
->nextPixel(&atPtr0
);
2835 // check for a skipped pixel
2836 if (useSkip
&& skip
->getPixel(x
, y
)) {
2840 } else if ((pix
= arithDecoder
->decodeBit(cx
, genericRegionStats
))) {
2841 bitmap
->setPixel(x
, y
);
2844 // update the context
2845 cx1
= ((cx1
<< 1) | bitmap
->nextPixel(&cxPtr1
)) & 0x1f;
2846 cx2
= ((cx2
<< 1) | pix
) & 0x0f;
2856 void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum
, GBool imm
,
2857 GBool lossless
, Guint length
,
2860 JBIG2Bitmap
*bitmap
, *refBitmap
;
2861 Guint w
, h
, x
, y
, segInfoFlags
, extCombOp
;
2862 Guint flags
, templ
, tpgrOn
;
2866 // region segment info field
2867 if (!readULong(&w
) || !readULong(&h
) ||
2868 !readULong(&x
) || !readULong(&y
) ||
2869 !readUByte(&segInfoFlags
)) {
2872 extCombOp
= segInfoFlags
& 7;
2874 // rest of the generic refinement region segment header
2875 if (!readUByte(&flags
)) {
2879 tpgrOn
= (flags
>> 1) & 1;
2883 if (!readByte(&atx
[0]) || !readByte(&aty
[0]) ||
2884 !readByte(&atx
[1]) || !readByte(&aty
[1])) {
2889 // resize the page bitmap if needed
2890 if (nRefSegs
== 0 || imm
) {
2891 if (pageH
== 0xffffffff && y
+ h
> curPageH
) {
2892 pageBitmap
->expand(y
+ h
, pageDefPixel
);
2896 // get referenced bitmap
2898 error(getPos(), "Bad reference in JBIG2 generic refinement segment");
2901 if (nRefSegs
== 1) {
2902 seg
= findSegment(refSegs
[0]);
2903 if (seg
->getType() != jbig2SegBitmap
) {
2904 error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
2907 refBitmap
= (JBIG2Bitmap
*)seg
;
2909 refBitmap
= pageBitmap
->getSlice(x
, y
, w
, h
);
2912 // set up the arithmetic decoder
2913 resetRefinementStats(templ
, NULL
);
2914 arithDecoder
->start();
2917 bitmap
= readGenericRefinementRegion(w
, h
, templ
, tpgrOn
,
2918 refBitmap
, 0, 0, atx
, aty
);
2920 // combine the region bitmap into the page bitmap
2922 pageBitmap
->combine(bitmap
, x
, y
, extCombOp
);
2925 // store the region bitmap
2927 bitmap
->setSegNum(segNum
);
2928 segments
->append(bitmap
);
2931 // delete the referenced bitmap
2932 if (nRefSegs
== 1) {
2933 discardSegment(refSegs
[0]);
2941 error(getPos(), "Unexpected EOF in JBIG2 stream");
2944 JBIG2Bitmap
*JBIG2Stream::readGenericRefinementRegion(int w
, int h
,
2945 int templ
, GBool tpgrOn
,
2946 JBIG2Bitmap
*refBitmap
,
2947 int refDX
, int refDY
,
2948 int *atx
, int *aty
) {
2949 JBIG2Bitmap
*bitmap
;
2951 Guint ltpCX
, cx
, cx0
, cx2
, cx3
, cx4
, tpgrCX0
, tpgrCX1
, tpgrCX2
;
2952 JBIG2BitmapPtr cxPtr0
, cxPtr1
, cxPtr2
, cxPtr3
, cxPtr4
, cxPtr5
, cxPtr6
;
2953 JBIG2BitmapPtr tpgrCXPtr0
, tpgrCXPtr1
, tpgrCXPtr2
;
2956 bitmap
= new JBIG2Bitmap(0, w
, h
);
2957 bitmap
->clearToZero();
2959 // set up the typical row context
2967 for (y
= 0; y
< h
; ++y
) {
2971 // set up the context
2972 bitmap
->getPixelPtr(0, y
-1, &cxPtr0
);
2973 cx0
= bitmap
->nextPixel(&cxPtr0
);
2974 bitmap
->getPixelPtr(-1, y
, &cxPtr1
);
2975 refBitmap
->getPixelPtr(-refDX
, y
-1-refDY
, &cxPtr2
);
2976 refBitmap
->getPixelPtr(-1-refDX
, y
-refDY
, &cxPtr3
);
2977 cx3
= refBitmap
->nextPixel(&cxPtr3
);
2978 cx3
= (cx3
<< 1) | refBitmap
->nextPixel(&cxPtr3
);
2979 refBitmap
->getPixelPtr(-refDX
, y
+1-refDY
, &cxPtr4
);
2980 cx4
= refBitmap
->nextPixel(&cxPtr4
);
2982 // set up the typical prediction context
2983 tpgrCX0
= tpgrCX1
= tpgrCX2
= 0; // make gcc happy
2985 refBitmap
->getPixelPtr(-1-refDX
, y
-1-refDY
, &tpgrCXPtr0
);
2986 tpgrCX0
= refBitmap
->nextPixel(&tpgrCXPtr0
);
2987 tpgrCX0
= (tpgrCX0
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr0
);
2988 tpgrCX0
= (tpgrCX0
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr0
);
2989 refBitmap
->getPixelPtr(-1-refDX
, y
-refDY
, &tpgrCXPtr1
);
2990 tpgrCX1
= refBitmap
->nextPixel(&tpgrCXPtr1
);
2991 tpgrCX1
= (tpgrCX1
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr1
);
2992 tpgrCX1
= (tpgrCX1
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr1
);
2993 refBitmap
->getPixelPtr(-1-refDX
, y
+1-refDY
, &tpgrCXPtr2
);
2994 tpgrCX2
= refBitmap
->nextPixel(&tpgrCXPtr2
);
2995 tpgrCX2
= (tpgrCX2
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr2
);
2996 tpgrCX2
= (tpgrCX2
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr2
);
2999 for (x
= 0; x
< w
; ++x
) {
3001 // update the context
3002 cx0
= ((cx0
<< 1) | bitmap
->nextPixel(&cxPtr0
)) & 7;
3003 cx3
= ((cx3
<< 1) | refBitmap
->nextPixel(&cxPtr3
)) & 7;
3004 cx4
= ((cx4
<< 1) | refBitmap
->nextPixel(&cxPtr4
)) & 3;
3007 // update the typical predictor context
3008 tpgrCX0
= ((tpgrCX0
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr0
)) & 7;
3009 tpgrCX1
= ((tpgrCX1
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr1
)) & 7;
3010 tpgrCX2
= ((tpgrCX2
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr2
)) & 7;
3012 // check for a "typical" pixel
3013 if (arithDecoder
->decodeBit(ltpCX
, refinementRegionStats
)) {
3016 if (tpgrCX0
== 0 && tpgrCX1
== 0 && tpgrCX2
== 0) {
3017 bitmap
->clearPixel(x
, y
);
3019 } else if (tpgrCX0
== 7 && tpgrCX1
== 7 && tpgrCX2
== 7) {
3020 bitmap
->setPixel(x
, y
);
3025 // build the context
3026 cx
= (cx0
<< 7) | (bitmap
->nextPixel(&cxPtr1
) << 6) |
3027 (refBitmap
->nextPixel(&cxPtr2
) << 5) |
3031 if ((pix
= arithDecoder
->decodeBit(cx
, refinementRegionStats
))) {
3032 bitmap
->setPixel(x
, y
);
3038 // set up the context
3039 bitmap
->getPixelPtr(0, y
-1, &cxPtr0
);
3040 cx0
= bitmap
->nextPixel(&cxPtr0
);
3041 bitmap
->getPixelPtr(-1, y
, &cxPtr1
);
3042 refBitmap
->getPixelPtr(-refDX
, y
-1-refDY
, &cxPtr2
);
3043 cx2
= refBitmap
->nextPixel(&cxPtr2
);
3044 refBitmap
->getPixelPtr(-1-refDX
, y
-refDY
, &cxPtr3
);
3045 cx3
= refBitmap
->nextPixel(&cxPtr3
);
3046 cx3
= (cx3
<< 1) | refBitmap
->nextPixel(&cxPtr3
);
3047 refBitmap
->getPixelPtr(-1-refDX
, y
+1-refDY
, &cxPtr4
);
3048 cx4
= refBitmap
->nextPixel(&cxPtr4
);
3049 cx4
= (cx4
<< 1) | refBitmap
->nextPixel(&cxPtr4
);
3050 bitmap
->getPixelPtr(atx
[0], y
+aty
[0], &cxPtr5
);
3051 refBitmap
->getPixelPtr(atx
[1]-refDX
, y
+aty
[1]-refDY
, &cxPtr6
);
3053 // set up the typical prediction context
3054 tpgrCX0
= tpgrCX1
= tpgrCX2
= 0; // make gcc happy
3056 refBitmap
->getPixelPtr(-1-refDX
, y
-1-refDY
, &tpgrCXPtr0
);
3057 tpgrCX0
= refBitmap
->nextPixel(&tpgrCXPtr0
);
3058 tpgrCX0
= (tpgrCX0
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr0
);
3059 tpgrCX0
= (tpgrCX0
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr0
);
3060 refBitmap
->getPixelPtr(-1-refDX
, y
-refDY
, &tpgrCXPtr1
);
3061 tpgrCX1
= refBitmap
->nextPixel(&tpgrCXPtr1
);
3062 tpgrCX1
= (tpgrCX1
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr1
);
3063 tpgrCX1
= (tpgrCX1
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr1
);
3064 refBitmap
->getPixelPtr(-1-refDX
, y
+1-refDY
, &tpgrCXPtr2
);
3065 tpgrCX2
= refBitmap
->nextPixel(&tpgrCXPtr2
);
3066 tpgrCX2
= (tpgrCX2
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr2
);
3067 tpgrCX2
= (tpgrCX2
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr2
);
3070 for (x
= 0; x
< w
; ++x
) {
3072 // update the context
3073 cx0
= ((cx0
<< 1) | bitmap
->nextPixel(&cxPtr0
)) & 3;
3074 cx2
= ((cx2
<< 1) | refBitmap
->nextPixel(&cxPtr2
)) & 3;
3075 cx3
= ((cx3
<< 1) | refBitmap
->nextPixel(&cxPtr3
)) & 7;
3076 cx4
= ((cx4
<< 1) | refBitmap
->nextPixel(&cxPtr4
)) & 7;
3079 // update the typical predictor context
3080 tpgrCX0
= ((tpgrCX0
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr0
)) & 7;
3081 tpgrCX1
= ((tpgrCX1
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr1
)) & 7;
3082 tpgrCX2
= ((tpgrCX2
<< 1) | refBitmap
->nextPixel(&tpgrCXPtr2
)) & 7;
3084 // check for a "typical" pixel
3085 if (arithDecoder
->decodeBit(ltpCX
, refinementRegionStats
)) {
3088 if (tpgrCX0
== 0 && tpgrCX1
== 0 && tpgrCX2
== 0) {
3089 bitmap
->clearPixel(x
, y
);
3091 } else if (tpgrCX0
== 7 && tpgrCX1
== 7 && tpgrCX2
== 7) {
3092 bitmap
->setPixel(x
, y
);
3097 // build the context
3098 cx
= (cx0
<< 11) | (bitmap
->nextPixel(&cxPtr1
) << 10) |
3099 (cx2
<< 8) | (cx3
<< 5) | (cx4
<< 2) |
3100 (bitmap
->nextPixel(&cxPtr5
) << 1) |
3101 refBitmap
->nextPixel(&cxPtr6
);
3104 if ((pix
= arithDecoder
->decodeBit(cx
, refinementRegionStats
))) {
3105 bitmap
->setPixel(x
, y
);
3114 void JBIG2Stream::readPageInfoSeg(Guint length
) {
3115 Guint xRes
, yRes
, flags
, striping
;
3117 if (!readULong(&pageW
) || !readULong(&pageH
) ||
3118 !readULong(&xRes
) || !readULong(&yRes
) ||
3119 !readUByte(&flags
) || !readUWord(&striping
)) {
3122 pageDefPixel
= (flags
>> 2) & 1;
3123 defCombOp
= (flags
>> 3) & 3;
3125 // allocate the page bitmap
3126 if (pageH
== 0xffffffff) {
3127 curPageH
= striping
& 0x7fff;
3131 pageBitmap
= new JBIG2Bitmap(0, pageW
, curPageH
);
3133 // default pixel value
3135 pageBitmap
->clearToOne();
3137 pageBitmap
->clearToZero();
3143 error(getPos(), "Unexpected EOF in JBIG2 stream");
3146 void JBIG2Stream::readEndOfStripeSeg(Guint length
) {
3150 for (i
= 0; i
< length
; ++i
) {
3155 void JBIG2Stream::readProfilesSeg(Guint length
) {
3159 for (i
= 0; i
< length
; ++i
) {
3164 void JBIG2Stream::readCodeTableSeg(Guint segNum
, Guint length
) {
3165 JBIG2HuffmanTable
*huffTab
;
3166 Guint flags
, oob
, prefixBits
, rangeBits
;
3167 int lowVal
, highVal
, val
;
3168 Guint huffTabSize
, i
;
3170 if (!readUByte(&flags
) || !readLong(&lowVal
) || !readLong(&highVal
)) {
3174 prefixBits
= ((flags
>> 1) & 7) + 1;
3175 rangeBits
= ((flags
>> 4) & 7) + 1;
3177 huffDecoder
->reset();
3179 huffTab
= (JBIG2HuffmanTable
*)
3180 gmallocn(huffTabSize
, sizeof(JBIG2HuffmanTable
));
3183 while (val
< highVal
) {
3184 if (i
== huffTabSize
) {
3186 huffTab
= (JBIG2HuffmanTable
*)
3187 greallocn(huffTab
, huffTabSize
, sizeof(JBIG2HuffmanTable
));
3189 huffTab
[i
].val
= val
;
3190 huffTab
[i
].prefixLen
= huffDecoder
->readBits(prefixBits
);
3191 huffTab
[i
].rangeLen
= huffDecoder
->readBits(rangeBits
);
3192 val
+= 1 << huffTab
[i
].rangeLen
;
3195 if (i
+ oob
+ 3 > huffTabSize
) {
3196 huffTabSize
= i
+ oob
+ 3;
3197 huffTab
= (JBIG2HuffmanTable
*)
3198 greallocn(huffTab
, huffTabSize
, sizeof(JBIG2HuffmanTable
));
3200 huffTab
[i
].val
= lowVal
- 1;
3201 huffTab
[i
].prefixLen
= huffDecoder
->readBits(prefixBits
);
3202 huffTab
[i
].rangeLen
= jbig2HuffmanLOW
;
3204 huffTab
[i
].val
= highVal
;
3205 huffTab
[i
].prefixLen
= huffDecoder
->readBits(prefixBits
);
3206 huffTab
[i
].rangeLen
= 32;
3210 huffTab
[i
].prefixLen
= huffDecoder
->readBits(prefixBits
);
3211 huffTab
[i
].rangeLen
= jbig2HuffmanOOB
;
3215 huffTab
[i
].prefixLen
= 0;
3216 huffTab
[i
].rangeLen
= jbig2HuffmanEOT
;
3217 huffDecoder
->buildTable(huffTab
, i
);
3219 // create and store the new table segment
3220 segments
->append(new JBIG2CodeTable(segNum
, huffTab
));
3225 error(getPos(), "Unexpected EOF in JBIG2 stream");
3228 void JBIG2Stream::readExtensionSeg(Guint length
) {
3232 for (i
= 0; i
< length
; ++i
) {
3237 JBIG2Segment
*JBIG2Stream::findSegment(Guint segNum
) {
3241 for (i
= 0; i
< globalSegments
->getLength(); ++i
) {
3242 seg
= (JBIG2Segment
*)globalSegments
->get(i
);
3243 if (seg
->getSegNum() == segNum
) {
3247 for (i
= 0; i
< segments
->getLength(); ++i
) {
3248 seg
= (JBIG2Segment
*)segments
->get(i
);
3249 if (seg
->getSegNum() == segNum
) {
3256 void JBIG2Stream::discardSegment(Guint segNum
) {
3260 for (i
= 0; i
< globalSegments
->getLength(); ++i
) {
3261 seg
= (JBIG2Segment
*)globalSegments
->get(i
);
3262 if (seg
->getSegNum() == segNum
) {
3263 globalSegments
->del(i
);
3267 for (i
= 0; i
< segments
->getLength(); ++i
) {
3268 seg
= (JBIG2Segment
*)segments
->get(i
);
3269 if (seg
->getSegNum() == segNum
) {
3276 void JBIG2Stream::resetGenericStats(Guint templ
,
3277 JArithmeticDecoderStats
*prevStats
) {
3280 size
= contextSize
[templ
];
3281 if (prevStats
&& prevStats
->getContextSize() == size
) {
3282 if (genericRegionStats
->getContextSize() == size
) {
3283 genericRegionStats
->copyFrom(prevStats
);
3285 delete genericRegionStats
;
3286 genericRegionStats
= prevStats
->copy();
3289 if (genericRegionStats
->getContextSize() == size
) {
3290 genericRegionStats
->reset();
3292 delete genericRegionStats
;
3293 genericRegionStats
= new JArithmeticDecoderStats(1 << size
);
3298 void JBIG2Stream::resetRefinementStats(Guint templ
,
3299 JArithmeticDecoderStats
*prevStats
) {
3302 size
= refContextSize
[templ
];
3303 if (prevStats
&& prevStats
->getContextSize() == size
) {
3304 if (refinementRegionStats
->getContextSize() == size
) {
3305 refinementRegionStats
->copyFrom(prevStats
);
3307 delete refinementRegionStats
;
3308 refinementRegionStats
= prevStats
->copy();
3311 if (refinementRegionStats
->getContextSize() == size
) {
3312 refinementRegionStats
->reset();
3314 delete refinementRegionStats
;
3315 refinementRegionStats
= new JArithmeticDecoderStats(1 << size
);
3320 void JBIG2Stream::resetIntStats(int symCodeLen
) {
3329 iardxStats
->reset();
3330 iardyStats
->reset();
3331 iardwStats
->reset();
3332 iardhStats
->reset();
3334 if (iaidStats
->getContextSize() == symCodeLen
+ 1) {
3338 iaidStats
= new JArithmeticDecoderStats(1 << (symCodeLen
+ 1));
3342 GBool
JBIG2Stream::readUByte(Guint
*x
) {
3345 if ((c0
= curStr
->getChar()) == EOF
) {
3352 GBool
JBIG2Stream::readByte(int *x
) {
3355 if ((c0
= curStr
->getChar()) == EOF
) {
3365 GBool
JBIG2Stream::readUWord(Guint
*x
) {
3368 if ((c0
= curStr
->getChar()) == EOF
||
3369 (c1
= curStr
->getChar()) == EOF
) {
3372 *x
= (Guint
)((c0
<< 8) | c1
);
3376 GBool
JBIG2Stream::readULong(Guint
*x
) {
3379 if ((c0
= curStr
->getChar()) == EOF
||
3380 (c1
= curStr
->getChar()) == EOF
||
3381 (c2
= curStr
->getChar()) == EOF
||
3382 (c3
= curStr
->getChar()) == EOF
) {
3385 *x
= (Guint
)((c0
<< 24) | (c1
<< 16) | (c2
<< 8) | c3
);
3389 GBool
JBIG2Stream::readLong(int *x
) {
3392 if ((c0
= curStr
->getChar()) == EOF
||
3393 (c1
= curStr
->getChar()) == EOF
||
3394 (c2
= curStr
->getChar()) == EOF
||
3395 (c3
= curStr
->getChar()) == EOF
) {
3398 *x
= ((c0
<< 24) | (c1
<< 16) | (c2
<< 8) | c3
);
3400 *x
|= -1 - (int)0xffffffff;