00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <aconf.h>
00010 #include <limits.h>
00011
00012 #ifdef USE_GCC_PRAGMAS
00013 #pragma implementation
00014 #endif
00015
00016 #include <stdlib.h>
00017 #include "GList.h"
00018 #include "Error.h"
00019 #include "JBIG2Stream.h"
00020
00021
00022 #include "Stream-CCITT.h"
00023
00024
00025
00026 static int contextSize[4] = { 16, 13, 10, 10 };
00027 static int refContextSize[2] = { 13, 10 };
00028
00029
00030
00031
00032
00033 class JBIG2ArithmeticDecoderStats {
00034 public:
00035
00036 JBIG2ArithmeticDecoderStats(int contextSizeA);
00037 ~JBIG2ArithmeticDecoderStats();
00038 JBIG2ArithmeticDecoderStats *copy();
00039 void reset();
00040 int getContextSize() { return contextSize; }
00041 void copyFrom(JBIG2ArithmeticDecoderStats *stats);
00042
00043 private:
00044
00045 Guchar *cxTab;
00046 int contextSize;
00047
00048 friend class JBIG2ArithmeticDecoder;
00049 };
00050
00051 JBIG2ArithmeticDecoderStats::JBIG2ArithmeticDecoderStats(int contextSizeA) {
00052 contextSize = contextSizeA;
00053 cxTab = (Guchar *)gmalloc((1 << contextSize) * sizeof(Guchar));
00054 reset();
00055 }
00056
00057 JBIG2ArithmeticDecoderStats::~JBIG2ArithmeticDecoderStats() {
00058 gfree(cxTab);
00059 }
00060
00061 JBIG2ArithmeticDecoderStats *JBIG2ArithmeticDecoderStats::copy() {
00062 JBIG2ArithmeticDecoderStats *stats;
00063
00064 stats = new JBIG2ArithmeticDecoderStats(contextSize);
00065 memcpy(stats->cxTab, cxTab, 1 << contextSize);
00066 return stats;
00067 }
00068
00069 void JBIG2ArithmeticDecoderStats::reset() {
00070 memset(cxTab, 0, 1 << contextSize);
00071 }
00072
00073 void JBIG2ArithmeticDecoderStats::copyFrom(
00074 JBIG2ArithmeticDecoderStats *stats) {
00075 memcpy(cxTab, stats->cxTab, 1 << contextSize);
00076 }
00077
00078
00079
00080
00081
00082 class JBIG2ArithmeticDecoder {
00083 public:
00084
00085 JBIG2ArithmeticDecoder();
00086 ~JBIG2ArithmeticDecoder();
00087 void setStream(Stream *strA) { str = strA; }
00088 void start();
00089 int decodeBit(Guint context, JBIG2ArithmeticDecoderStats *stats);
00090 int decodeByte(Guint context, JBIG2ArithmeticDecoderStats *stats);
00091
00092
00093 GBool decodeInt(int *x, JBIG2ArithmeticDecoderStats *stats);
00094
00095 Guint decodeIAID(Guint codeLen,
00096 JBIG2ArithmeticDecoderStats *stats);
00097
00098 private:
00099
00100 int decodeIntBit(JBIG2ArithmeticDecoderStats *stats);
00101 void byteIn();
00102
00103 static Guint qeTab[47];
00104 static int nmpsTab[47];
00105 static int nlpsTab[47];
00106 static int switchTab[47];
00107
00108 Guint buf0, buf1;
00109 Guint c, a;
00110 int ct;
00111
00112 Guint prev;
00113
00114 Stream *str;
00115 };
00116
00117 Guint JBIG2ArithmeticDecoder::qeTab[47] = {
00118 0x56010000, 0x34010000, 0x18010000, 0x0AC10000,
00119 0x05210000, 0x02210000, 0x56010000, 0x54010000,
00120 0x48010000, 0x38010000, 0x30010000, 0x24010000,
00121 0x1C010000, 0x16010000, 0x56010000, 0x54010000,
00122 0x51010000, 0x48010000, 0x38010000, 0x34010000,
00123 0x30010000, 0x28010000, 0x24010000, 0x22010000,
00124 0x1C010000, 0x18010000, 0x16010000, 0x14010000,
00125 0x12010000, 0x11010000, 0x0AC10000, 0x09C10000,
00126 0x08A10000, 0x05210000, 0x04410000, 0x02A10000,
00127 0x02210000, 0x01410000, 0x01110000, 0x00850000,
00128 0x00490000, 0x00250000, 0x00150000, 0x00090000,
00129 0x00050000, 0x00010000, 0x56010000
00130 };
00131
00132 int JBIG2ArithmeticDecoder::nmpsTab[47] = {
00133 1, 2, 3, 4, 5, 38, 7, 8, 9, 10, 11, 12, 13, 29, 15, 16,
00134 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
00135 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 45, 46
00136 };
00137
00138 int JBIG2ArithmeticDecoder::nlpsTab[47] = {
00139 1, 6, 9, 12, 29, 33, 6, 14, 14, 14, 17, 18, 20, 21, 14, 14,
00140 15, 16, 17, 18, 19, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
00141 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46
00142 };
00143
00144 int JBIG2ArithmeticDecoder::switchTab[47] = {
00145 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
00146 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00147 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00148 };
00149
00150 JBIG2ArithmeticDecoder::JBIG2ArithmeticDecoder() {
00151 str = NULL;
00152 }
00153
00154 JBIG2ArithmeticDecoder::~JBIG2ArithmeticDecoder() {
00155 }
00156
00157 void JBIG2ArithmeticDecoder::start() {
00158 buf0 = (Guint)str->getChar() & 0xff;
00159 buf1 = (Guint)str->getChar() & 0xff;
00160
00161
00162 c = (buf0 ^ 0xff) << 16;
00163 byteIn();
00164 c <<= 7;
00165 ct -= 7;
00166 a = 0x80000000;
00167 }
00168
00169 int JBIG2ArithmeticDecoder::decodeBit(Guint context,
00170 JBIG2ArithmeticDecoderStats *stats) {
00171 int bit;
00172 Guint qe;
00173 int iCX, mpsCX;
00174
00175 iCX = stats->cxTab[context] >> 1;
00176 mpsCX = stats->cxTab[context] & 1;
00177 qe = qeTab[iCX];
00178 a -= qe;
00179 if (c < a) {
00180 if (a & 0x80000000) {
00181 bit = mpsCX;
00182 } else {
00183
00184 if (a < qe) {
00185 bit = 1 - mpsCX;
00186 if (switchTab[iCX]) {
00187 stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
00188 } else {
00189 stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
00190 }
00191 } else {
00192 bit = mpsCX;
00193 stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
00194 }
00195
00196 do {
00197 if (ct == 0) {
00198 byteIn();
00199 }
00200 a <<= 1;
00201 c <<= 1;
00202 --ct;
00203 } while (!(a & 0x80000000));
00204 }
00205 } else {
00206 c -= a;
00207
00208 if (a < qe) {
00209 bit = mpsCX;
00210 stats->cxTab[context] = (nmpsTab[iCX] << 1) | mpsCX;
00211 } else {
00212 bit = 1 - mpsCX;
00213 if (switchTab[iCX]) {
00214 stats->cxTab[context] = (nlpsTab[iCX] << 1) | (1 - mpsCX);
00215 } else {
00216 stats->cxTab[context] = (nlpsTab[iCX] << 1) | mpsCX;
00217 }
00218 }
00219 a = qe;
00220
00221 do {
00222 if (ct == 0) {
00223 byteIn();
00224 }
00225 a <<= 1;
00226 c <<= 1;
00227 --ct;
00228 } while (!(a & 0x80000000));
00229 }
00230 return bit;
00231 }
00232
00233 int JBIG2ArithmeticDecoder::decodeByte(Guint context,
00234 JBIG2ArithmeticDecoderStats *stats) {
00235 int byte;
00236 int i;
00237
00238 byte = 0;
00239 for (i = 0; i < 8; ++i) {
00240 byte = (byte << 1) | decodeBit(context, stats);
00241 }
00242 return byte;
00243 }
00244
00245 GBool JBIG2ArithmeticDecoder::decodeInt(int *x,
00246 JBIG2ArithmeticDecoderStats *stats) {
00247 int s;
00248 Guint v;
00249 int i;
00250
00251 prev = 1;
00252 s = decodeIntBit(stats);
00253 if (decodeIntBit(stats)) {
00254 if (decodeIntBit(stats)) {
00255 if (decodeIntBit(stats)) {
00256 if (decodeIntBit(stats)) {
00257 if (decodeIntBit(stats)) {
00258 v = 0;
00259 for (i = 0; i < 32; ++i) {
00260 v = (v << 1) | decodeIntBit(stats);
00261 }
00262 v += 4436;
00263 } else {
00264 v = 0;
00265 for (i = 0; i < 12; ++i) {
00266 v = (v << 1) | decodeIntBit(stats);
00267 }
00268 v += 340;
00269 }
00270 } else {
00271 v = 0;
00272 for (i = 0; i < 8; ++i) {
00273 v = (v << 1) | decodeIntBit(stats);
00274 }
00275 v += 84;
00276 }
00277 } else {
00278 v = 0;
00279 for (i = 0; i < 6; ++i) {
00280 v = (v << 1) | decodeIntBit(stats);
00281 }
00282 v += 20;
00283 }
00284 } else {
00285 v = decodeIntBit(stats);
00286 v = (v << 1) | decodeIntBit(stats);
00287 v = (v << 1) | decodeIntBit(stats);
00288 v = (v << 1) | decodeIntBit(stats);
00289 v += 4;
00290 }
00291 } else {
00292 v = decodeIntBit(stats);
00293 v = (v << 1) | decodeIntBit(stats);
00294 }
00295
00296 if (s) {
00297 if (v == 0) {
00298 return gFalse;
00299 }
00300 *x = -(int)v;
00301 } else {
00302 *x = (int)v;
00303 }
00304 return gTrue;
00305 }
00306
00307 int JBIG2ArithmeticDecoder::decodeIntBit(JBIG2ArithmeticDecoderStats *stats) {
00308 int bit;
00309
00310 bit = decodeBit(prev, stats);
00311 if (prev < 0x100) {
00312 prev = (prev << 1) | bit;
00313 } else {
00314 prev = (((prev << 1) | bit) & 0x1ff) | 0x100;
00315 }
00316 return bit;
00317 }
00318
00319 Guint JBIG2ArithmeticDecoder::decodeIAID(Guint codeLen,
00320 JBIG2ArithmeticDecoderStats *stats) {
00321 Guint i;
00322 int bit;
00323
00324 prev = 1;
00325 for (i = 0; i < codeLen; ++i) {
00326 bit = decodeBit(prev, stats);
00327 prev = (prev << 1) | bit;
00328 }
00329 return prev - (1 << codeLen);
00330 }
00331
00332 void JBIG2ArithmeticDecoder::byteIn() {
00333 if (buf0 == 0xff) {
00334 if (buf1 > 0x8f) {
00335 ct = 8;
00336 } else {
00337 buf0 = buf1;
00338 buf1 = (Guint)str->getChar() & 0xff;
00339 c = c + 0xfe00 - (buf0 << 9);
00340 ct = 7;
00341 }
00342 } else {
00343 buf0 = buf1;
00344 buf1 = (Guint)str->getChar() & 0xff;
00345 c = c + 0xff00 - (buf0 << 8);
00346 ct = 8;
00347 }
00348 }
00349
00350
00351
00352
00353
00354 #define jbig2HuffmanLOW 0xfffffffd
00355 #define jbig2HuffmanOOB 0xfffffffe
00356 #define jbig2HuffmanEOT 0xffffffff
00357
00358 struct JBIG2HuffmanTable {
00359 int val;
00360 Guint prefixLen;
00361 Guint rangeLen;
00362 Guint prefix;
00363 };
00364
00365 JBIG2HuffmanTable huffTableA[] = {
00366 { 0, 1, 4, 0x000 },
00367 { 16, 2, 8, 0x002 },
00368 { 272, 3, 16, 0x006 },
00369 { 65808, 3, 32, 0x007 },
00370 { 0, 0, jbig2HuffmanEOT, 0 }
00371 };
00372
00373 JBIG2HuffmanTable huffTableB[] = {
00374 { 0, 1, 0, 0x000 },
00375 { 1, 2, 0, 0x002 },
00376 { 2, 3, 0, 0x006 },
00377 { 3, 4, 3, 0x00e },
00378 { 11, 5, 6, 0x01e },
00379 { 75, 6, 32, 0x03e },
00380 { 0, 6, jbig2HuffmanOOB, 0x03f },
00381 { 0, 0, jbig2HuffmanEOT, 0 }
00382 };
00383
00384 JBIG2HuffmanTable huffTableC[] = {
00385 { 0, 1, 0, 0x000 },
00386 { 1, 2, 0, 0x002 },
00387 { 2, 3, 0, 0x006 },
00388 { 3, 4, 3, 0x00e },
00389 { 11, 5, 6, 0x01e },
00390 { 0, 6, jbig2HuffmanOOB, 0x03e },
00391 { 75, 7, 32, 0x0fe },
00392 { -256, 8, 8, 0x0fe },
00393 { -257, 8, jbig2HuffmanLOW, 0x0ff },
00394 { 0, 0, jbig2HuffmanEOT, 0 }
00395 };
00396
00397 JBIG2HuffmanTable huffTableD[] = {
00398 { 1, 1, 0, 0x000 },
00399 { 2, 2, 0, 0x002 },
00400 { 3, 3, 0, 0x006 },
00401 { 4, 4, 3, 0x00e },
00402 { 12, 5, 6, 0x01e },
00403 { 76, 5, 32, 0x01f },
00404 { 0, 0, jbig2HuffmanEOT, 0 }
00405 };
00406
00407 JBIG2HuffmanTable huffTableE[] = {
00408 { 1, 1, 0, 0x000 },
00409 { 2, 2, 0, 0x002 },
00410 { 3, 3, 0, 0x006 },
00411 { 4, 4, 3, 0x00e },
00412 { 12, 5, 6, 0x01e },
00413 { 76, 6, 32, 0x03e },
00414 { -255, 7, 8, 0x07e },
00415 { -256, 7, jbig2HuffmanLOW, 0x07f },
00416 { 0, 0, jbig2HuffmanEOT, 0 }
00417 };
00418
00419 JBIG2HuffmanTable huffTableF[] = {
00420 { 0, 2, 7, 0x000 },
00421 { 128, 3, 7, 0x002 },
00422 { 256, 3, 8, 0x003 },
00423 { -1024, 4, 9, 0x008 },
00424 { -512, 4, 8, 0x009 },
00425 { -256, 4, 7, 0x00a },
00426 { -32, 4, 5, 0x00b },
00427 { 512, 4, 9, 0x00c },
00428 { 1024, 4, 10, 0x00d },
00429 { -2048, 5, 10, 0x01c },
00430 { -128, 5, 6, 0x01d },
00431 { -64, 5, 5, 0x01e },
00432 { -2049, 6, jbig2HuffmanLOW, 0x03e },
00433 { 2048, 6, 32, 0x03f },
00434 { 0, 0, jbig2HuffmanEOT, 0 }
00435 };
00436
00437 JBIG2HuffmanTable huffTableG[] = {
00438 { -512, 3, 8, 0x000 },
00439 { 256, 3, 8, 0x001 },
00440 { 512, 3, 9, 0x002 },
00441 { 1024, 3, 10, 0x003 },
00442 { -1024, 4, 9, 0x008 },
00443 { -256, 4, 7, 0x009 },
00444 { -32, 4, 5, 0x00a },
00445 { 0, 4, 5, 0x00b },
00446 { 128, 4, 7, 0x00c },
00447 { -128, 5, 6, 0x01a },
00448 { -64, 5, 5, 0x01b },
00449 { 32, 5, 5, 0x01c },
00450 { 64, 5, 6, 0x01d },
00451 { -1025, 5, jbig2HuffmanLOW, 0x01e },
00452 { 2048, 5, 32, 0x01f },
00453 { 0, 0, jbig2HuffmanEOT, 0 }
00454 };
00455
00456 JBIG2HuffmanTable huffTableH[] = {
00457 { 0, 2, 1, 0x000 },
00458 { 0, 2, jbig2HuffmanOOB, 0x001 },
00459 { 4, 3, 4, 0x004 },
00460 { -1, 4, 0, 0x00a },
00461 { 22, 4, 4, 0x00b },
00462 { 38, 4, 5, 0x00c },
00463 { 2, 5, 0, 0x01a },
00464 { 70, 5, 6, 0x01b },
00465 { 134, 5, 7, 0x01c },
00466 { 3, 6, 0, 0x03a },
00467 { 20, 6, 1, 0x03b },
00468 { 262, 6, 7, 0x03c },
00469 { 646, 6, 10, 0x03d },
00470 { -2, 7, 0, 0x07c },
00471 { 390, 7, 8, 0x07d },
00472 { -15, 8, 3, 0x0fc },
00473 { -5, 8, 1, 0x0fd },
00474 { -7, 9, 1, 0x1fc },
00475 { -3, 9, 0, 0x1fd },
00476 { -16, 9, jbig2HuffmanLOW, 0x1fe },
00477 { 1670, 9, 32, 0x1ff },
00478 { 0, 0, jbig2HuffmanEOT, 0 }
00479 };
00480
00481 JBIG2HuffmanTable huffTableI[] = {
00482 { 0, 2, jbig2HuffmanOOB, 0x000 },
00483 { -1, 3, 1, 0x002 },
00484 { 1, 3, 1, 0x003 },
00485 { 7, 3, 5, 0x004 },
00486 { -3, 4, 1, 0x00a },
00487 { 43, 4, 5, 0x00b },
00488 { 75, 4, 6, 0x00c },
00489 { 3, 5, 1, 0x01a },
00490 { 139, 5, 7, 0x01b },
00491 { 267, 5, 8, 0x01c },
00492 { 5, 6, 1, 0x03a },
00493 { 39, 6, 2, 0x03b },
00494 { 523, 6, 8, 0x03c },
00495 { 1291, 6, 11, 0x03d },
00496 { -5, 7, 1, 0x07c },
00497 { 779, 7, 9, 0x07d },
00498 { -31, 8, 4, 0x0fc },
00499 { -11, 8, 2, 0x0fd },
00500 { -15, 9, 2, 0x1fc },
00501 { -7, 9, 1, 0x1fd },
00502 { -32, 9, jbig2HuffmanLOW, 0x1fe },
00503 { 3339, 9, 32, 0x1ff },
00504 { 0, 0, jbig2HuffmanEOT, 0 }
00505 };
00506
00507 JBIG2HuffmanTable huffTableJ[] = {
00508 { -2, 2, 2, 0x000 },
00509 { 6, 2, 6, 0x001 },
00510 { 0, 2, jbig2HuffmanOOB, 0x002 },
00511 { -3, 5, 0, 0x018 },
00512 { 2, 5, 0, 0x019 },
00513 { 70, 5, 5, 0x01a },
00514 { 3, 6, 0, 0x036 },
00515 { 102, 6, 5, 0x037 },
00516 { 134, 6, 6, 0x038 },
00517 { 198, 6, 7, 0x039 },
00518 { 326, 6, 8, 0x03a },
00519 { 582, 6, 9, 0x03b },
00520 { 1094, 6, 10, 0x03c },
00521 { -21, 7, 4, 0x07a },
00522 { -4, 7, 0, 0x07b },
00523 { 4, 7, 0, 0x07c },
00524 { 2118, 7, 11, 0x07d },
00525 { -5, 8, 0, 0x0fc },
00526 { 5, 8, 0, 0x0fd },
00527 { -22, 8, jbig2HuffmanLOW, 0x0fe },
00528 { 4166, 8, 32, 0x0ff },
00529 { 0, 0, jbig2HuffmanEOT, 0 }
00530 };
00531
00532 JBIG2HuffmanTable huffTableK[] = {
00533 { 1, 1, 0, 0x000 },
00534 { 2, 2, 1, 0x002 },
00535 { 4, 4, 0, 0x00c },
00536 { 5, 4, 1, 0x00d },
00537 { 7, 5, 1, 0x01c },
00538 { 9, 5, 2, 0x01d },
00539 { 13, 6, 2, 0x03c },
00540 { 17, 7, 2, 0x07a },
00541 { 21, 7, 3, 0x07b },
00542 { 29, 7, 4, 0x07c },
00543 { 45, 7, 5, 0x07d },
00544 { 77, 7, 6, 0x07e },
00545 { 141, 7, 32, 0x07f },
00546 { 0, 0, jbig2HuffmanEOT, 0 }
00547 };
00548
00549 JBIG2HuffmanTable huffTableL[] = {
00550 { 1, 1, 0, 0x000 },
00551 { 2, 2, 0, 0x002 },
00552 { 3, 3, 1, 0x006 },
00553 { 5, 5, 0, 0x01c },
00554 { 6, 5, 1, 0x01d },
00555 { 8, 6, 1, 0x03c },
00556 { 10, 7, 0, 0x07a },
00557 { 11, 7, 1, 0x07b },
00558 { 13, 7, 2, 0x07c },
00559 { 17, 7, 3, 0x07d },
00560 { 25, 7, 4, 0x07e },
00561 { 41, 8, 5, 0x0fe },
00562 { 73, 8, 32, 0x0ff },
00563 { 0, 0, jbig2HuffmanEOT, 0 }
00564 };
00565
00566 JBIG2HuffmanTable huffTableM[] = {
00567 { 1, 1, 0, 0x000 },
00568 { 2, 3, 0, 0x004 },
00569 { 7, 3, 3, 0x005 },
00570 { 3, 4, 0, 0x00c },
00571 { 5, 4, 1, 0x00d },
00572 { 4, 5, 0, 0x01c },
00573 { 15, 6, 1, 0x03a },
00574 { 17, 6, 2, 0x03b },
00575 { 21, 6, 3, 0x03c },
00576 { 29, 6, 4, 0x03d },
00577 { 45, 6, 5, 0x03e },
00578 { 77, 7, 6, 0x07e },
00579 { 141, 7, 32, 0x07f },
00580 { 0, 0, jbig2HuffmanEOT, 0 }
00581 };
00582
00583 JBIG2HuffmanTable huffTableN[] = {
00584 { 0, 1, 0, 0x000 },
00585 { -2, 3, 0, 0x004 },
00586 { -1, 3, 0, 0x005 },
00587 { 1, 3, 0, 0x006 },
00588 { 2, 3, 0, 0x007 },
00589 { 0, 0, jbig2HuffmanEOT, 0 }
00590 };
00591
00592 JBIG2HuffmanTable huffTableO[] = {
00593 { 0, 1, 0, 0x000 },
00594 { -1, 3, 0, 0x004 },
00595 { 1, 3, 0, 0x005 },
00596 { -2, 4, 0, 0x00c },
00597 { 2, 4, 0, 0x00d },
00598 { -4, 5, 1, 0x01c },
00599 { 3, 5, 1, 0x01d },
00600 { -8, 6, 2, 0x03c },
00601 { 5, 6, 2, 0x03d },
00602 { -24, 7, 4, 0x07c },
00603 { 9, 7, 4, 0x07d },
00604 { -25, 7, jbig2HuffmanLOW, 0x07e },
00605 { 25, 7, 32, 0x07f },
00606 { 0, 0, jbig2HuffmanEOT, 0 }
00607 };
00608
00609
00610
00611
00612
00613 class JBIG2HuffmanDecoder {
00614 public:
00615
00616 JBIG2HuffmanDecoder();
00617 ~JBIG2HuffmanDecoder();
00618 void setStream(Stream *strA) { str = strA; }
00619
00620 void reset();
00621
00622
00623 GBool decodeInt(int *x, JBIG2HuffmanTable *table);
00624
00625 Guint readBits(Guint n);
00626 Guint readBit();
00627
00628
00629 void buildTable(JBIG2HuffmanTable *table, Guint len);
00630
00631 private:
00632
00633 Stream *str;
00634 Guint buf;
00635 Guint bufLen;
00636 };
00637
00638 JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
00639 str = NULL;
00640 reset();
00641 }
00642
00643 JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {
00644 }
00645
00646 void JBIG2HuffmanDecoder::reset() {
00647 buf = 0;
00648 bufLen = 0;
00649 }
00650
00651
00652 GBool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) {
00653 Guint i, len, prefix;
00654
00655 i = 0;
00656 len = 0;
00657 prefix = 0;
00658 while (table[i].rangeLen != jbig2HuffmanEOT) {
00659
00660 if (table[i].prefixLen > 0) {
00661 while (len < table[i].prefixLen) {
00662 prefix = (prefix << 1) | readBit();
00663 ++len;
00664 }
00665 if (prefix == table[i].prefix) {
00666 if (table[i].rangeLen == jbig2HuffmanOOB) {
00667 return gFalse;
00668 }
00669 if (table[i].rangeLen == jbig2HuffmanLOW) {
00670 *x = table[i].val - readBits(32);
00671 } else if (table[i].rangeLen > 0) {
00672 *x = table[i].val + readBits(table[i].rangeLen);
00673 } else {
00674 *x = table[i].val;
00675 }
00676 return gTrue;
00677 }
00678 }
00679 ++i;
00680 }
00681 return gFalse;
00682 }
00683
00684 Guint JBIG2HuffmanDecoder::readBits(Guint n) {
00685 Guint x, mask, nLeft;
00686
00687 mask = (n == 32) ? 0xffffffff : ((1 << n) - 1);
00688 if (bufLen >= n) {
00689 x = (buf >> (bufLen - n)) & mask;
00690 bufLen -= n;
00691 } else {
00692 x = buf & ((1 << bufLen) - 1);
00693 nLeft = n - bufLen;
00694 bufLen = 0;
00695 while (nLeft >= 8) {
00696 x = (x << 8) | (str->getChar() & 0xff);
00697 nLeft -= 8;
00698 }
00699 if (nLeft > 0) {
00700 buf = str->getChar();
00701 bufLen = 8 - nLeft;
00702 x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1));
00703 }
00704 }
00705 return x;
00706 }
00707
00708 Guint JBIG2HuffmanDecoder::readBit() {
00709 if (bufLen == 0) {
00710 buf = str->getChar();
00711 bufLen = 8;
00712 }
00713 --bufLen;
00714 return (buf >> bufLen) & 1;
00715 }
00716
00717 static int cmpHuffmanTabEntries(const void *p1, const void *p2) {
00718 return ((JBIG2HuffmanTable *)p1)->prefixLen
00719 - ((JBIG2HuffmanTable *)p2)->prefixLen;
00720 }
00721
00722
00723 void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {
00724 Guint i, prefix;
00725
00726 qsort(table, len, sizeof(JBIG2HuffmanTable), &cmpHuffmanTabEntries);
00727 for (i = 0; i < len && table[i].prefixLen == 0; ++i) {
00728 table[i].prefix = 0;
00729 }
00730 prefix = 0;
00731 table[i++].prefix = prefix++;
00732 for (; i < len; ++i) {
00733 prefix <<= table[i].prefixLen - table[i-1].prefixLen;
00734 table[i].prefix = prefix++;
00735 }
00736 }
00737
00738
00739
00740
00741
00742 class JBIG2MMRDecoder {
00743 public:
00744
00745 JBIG2MMRDecoder();
00746 ~JBIG2MMRDecoder();
00747 void setStream(Stream *strA) { str = strA; }
00748 void reset();
00749 int get2DCode();
00750 int getBlackCode();
00751 int getWhiteCode();
00752 Guint get24Bits();
00753 void skipTo(Guint length);
00754
00755 private:
00756
00757 Stream *str;
00758 Guint buf;
00759 Guint bufLen;
00760 Guint nBytesRead;
00761 };
00762
00763 JBIG2MMRDecoder::JBIG2MMRDecoder() {
00764 str = NULL;
00765 reset();
00766 }
00767
00768 JBIG2MMRDecoder::~JBIG2MMRDecoder() {
00769 }
00770
00771 void JBIG2MMRDecoder::reset() {
00772 buf = 0;
00773 bufLen = 0;
00774 nBytesRead = 0;
00775 }
00776
00777 int JBIG2MMRDecoder::get2DCode() {
00778 CCITTCode *p;
00779
00780 if (bufLen == 0) {
00781 buf = str->getChar() & 0xff;
00782 bufLen = 8;
00783 ++nBytesRead;
00784 p = &twoDimTab1[(buf >> 1) & 0x7f];
00785 } else if (bufLen == 8) {
00786 p = &twoDimTab1[(buf >> 1) & 0x7f];
00787 } else {
00788 p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f];
00789 if (p->bits < 0 || p->bits > (int)bufLen) {
00790 buf = (buf << 8) | (str->getChar() & 0xff);
00791 bufLen += 8;
00792 ++nBytesRead;
00793 p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
00794 }
00795 }
00796 if (p->bits < 0) {
00797 error(str->getPos(), "Bad two dim code in JBIG2 MMR stream");
00798 return 0;
00799 }
00800 bufLen -= p->bits;
00801 return p->n;
00802 }
00803
00804 int JBIG2MMRDecoder::getWhiteCode() {
00805 CCITTCode *p;
00806 Guint code;
00807
00808 if (bufLen == 0) {
00809 buf = str->getChar() & 0xff;
00810 bufLen = 8;
00811 ++nBytesRead;
00812 }
00813 while (1) {
00814 if (bufLen > 7 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
00815 if (bufLen <= 12) {
00816 code = buf << (12 - bufLen);
00817 } else {
00818 code = buf >> (bufLen - 12);
00819 }
00820 p = &whiteTab1[code & 0x1f];
00821 } else {
00822 if (bufLen <= 9) {
00823 code = buf << (9 - bufLen);
00824 } else {
00825 code = buf >> (bufLen - 9);
00826 }
00827 p = &whiteTab2[code & 0x1ff];
00828 }
00829 if (p->bits > 0 && p->bits < (int)bufLen) {
00830 bufLen -= p->bits;
00831 return p->n;
00832 }
00833 if (bufLen >= 12) {
00834 break;
00835 }
00836 buf = (buf << 8) | (str->getChar() & 0xff);
00837 bufLen += 8;
00838 ++nBytesRead;
00839 }
00840 error(str->getPos(), "Bad white code in JBIG2 MMR stream");
00841
00842
00843 --bufLen;
00844 return 1;
00845 }
00846
00847 int JBIG2MMRDecoder::getBlackCode() {
00848 CCITTCode *p;
00849 Guint code;
00850
00851 if (bufLen == 0) {
00852 buf = str->getChar() & 0xff;
00853 bufLen = 8;
00854 ++nBytesRead;
00855 }
00856 while (1) {
00857 if (bufLen > 6 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
00858 if (bufLen <= 13) {
00859 code = buf << (13 - bufLen);
00860 } else {
00861 code = buf >> (bufLen - 13);
00862 }
00863 p = &blackTab1[code & 0x7f];
00864 } else if (bufLen > 4 && ((buf >> (bufLen - 4)) & 0x0f) == 0) {
00865 if (bufLen <= 12) {
00866 code = buf << (12 - bufLen);
00867 } else {
00868 code = buf >> (bufLen - 12);
00869 }
00870 p = &blackTab2[(code & 0xff) - 64];
00871 } else {
00872 if (bufLen <= 6) {
00873 code = buf << (6 - bufLen);
00874 } else {
00875 code = buf >> (bufLen - 6);
00876 }
00877 p = &blackTab3[code & 0x3f];
00878 }
00879 if (p->bits > 0 && p->bits < (int)bufLen) {
00880 bufLen -= p->bits;
00881 return p->n;
00882 }
00883 if (bufLen >= 13) {
00884 break;
00885 }
00886 buf = (buf << 8) | (str->getChar() & 0xff);
00887 bufLen += 8;
00888 ++nBytesRead;
00889 }
00890 error(str->getPos(), "Bad black code in JBIG2 MMR stream");
00891
00892
00893 --bufLen;
00894 return 1;
00895 }
00896
00897 Guint JBIG2MMRDecoder::get24Bits() {
00898 while (bufLen < 24) {
00899 buf = (buf << 8) | (str->getChar() & 0xff);
00900 bufLen += 8;
00901 ++nBytesRead;
00902 }
00903 return (buf >> (bufLen - 24)) & 0xffffff;
00904 }
00905
00906 void JBIG2MMRDecoder::skipTo(Guint length) {
00907 while (nBytesRead < length) {
00908 str->getChar();
00909 ++nBytesRead;
00910 }
00911 }
00912
00913
00914
00915
00916
00917 enum JBIG2SegmentType {
00918 jbig2SegBitmap,
00919 jbig2SegSymbolDict,
00920 jbig2SegPatternDict,
00921 jbig2SegCodeTable
00922 };
00923
00924 class JBIG2Segment {
00925 public:
00926
00927 JBIG2Segment(Guint segNumA) { segNum = segNumA; }
00928 virtual ~JBIG2Segment() {}
00929 void setSegNum(Guint segNumA) { segNum = segNumA; }
00930 Guint getSegNum() { return segNum; }
00931 virtual JBIG2SegmentType getType() = 0;
00932
00933 private:
00934
00935 Guint segNum;
00936 };
00937
00938
00939
00940
00941
00942 class JBIG2Bitmap: public JBIG2Segment {
00943 public:
00944
00945 JBIG2Bitmap(Guint segNumA, int wA, int hA);
00946 virtual ~JBIG2Bitmap();
00947 virtual JBIG2SegmentType getType() { return jbig2SegBitmap; }
00948 JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); }
00949 JBIG2Bitmap *getSlice(Guint x, Guint y, Guint wA, Guint hA);
00950 void expand(int newH, Guint pixel);
00951 void clearToZero();
00952 void clearToOne();
00953 int getWidth() { return w; }
00954 int getHeight() { return h; }
00955 int getPixel(int x, int y)
00956 { return (x < 0 || x >= w || y < 0 || y >= h) ? 0 :
00957 (data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; }
00958 void setPixel(int x, int y)
00959 { data[y * line + (x >> 3)] |= 1 << (7 - (x & 7)); }
00960 void clearPixel(int x, int y)
00961 { data[y * line + (x >> 3)] &= 0x7f7f >> (x & 7); }
00962 void duplicateRow(int yDest, int ySrc);
00963 void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);
00964 Guchar *getDataPtr() { return data; }
00965 int getDataSize() { return h * line; }
00966
00967 private:
00968
00969 JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap);
00970
00971 int w, h, line;
00972 Guchar *data;
00973 };
00974
00975 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA):
00976 JBIG2Segment(segNumA)
00977 {
00978 w = wA;
00979 h = hA;
00980 line = (wA + 7) >> 3;
00981
00982 if (h < 0 || line <= 0 || h >= (INT_MAX - 1)/ line) {
00983 error(-1, "invalid width/height");
00984 data = NULL;
00985 return;
00986 }
00987
00988
00989 data = (Guchar *)gmalloc(h * line + 1);
00990 }
00991
00992 JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
00993 JBIG2Segment(segNumA)
00994 {
00995 w = bitmap->w;
00996 h = bitmap->h;
00997 line = bitmap->line;
00998
00999 if (h < 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
01000 error(-1, "invalid width/height");
01001 data = NULL;
01002 return;
01003 }
01004
01005
01006 data = (Guchar *)gmalloc(h * line + 1);
01007 memcpy(data, bitmap->data, h * line);
01008 }
01009
01010 JBIG2Bitmap::~JBIG2Bitmap() {
01011 gfree(data);
01012 }
01013
01014
01015 JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
01016 JBIG2Bitmap *slice;
01017 Guint xx, yy;
01018
01019 slice = new JBIG2Bitmap(0, wA, hA);
01020 slice->clearToZero();
01021 for (yy = 0; yy < hA; ++yy) {
01022 for (xx = 0; xx < wA; ++xx) {
01023 if (getPixel(x + xx, y + yy)) {
01024 slice->setPixel(xx, yy);
01025 }
01026 }
01027 }
01028 return slice;
01029 }
01030
01031 void JBIG2Bitmap::expand(int newH, Guint pixel) {
01032 if (newH <= h || line <= 0 || newH >= (INT_MAX-1) / line) {
01033 error(-1, "invalid width/height");
01034 gfree(data);
01035 data = NULL;
01036 return;
01037 }
01038
01039 data = (Guchar *)grealloc(data, newH * line + 1);
01040 if (pixel) {
01041 memset(data + h * line, 0xff, (newH - h) * line);
01042 } else {
01043 memset(data + h * line, 0x00, (newH - h) * line);
01044 }
01045 h = newH;
01046 }
01047
01048 void JBIG2Bitmap::clearToZero() {
01049 memset(data, 0, h * line);
01050 }
01051
01052 void JBIG2Bitmap::clearToOne() {
01053 memset(data, 0xff, h * line);
01054 }
01055
01056 void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) {
01057 memcpy(data + yDest * line, data + ySrc * line, line);
01058 }
01059
01060 void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
01061 Guint combOp) {
01062 int x0, x1, y0, y1, xx, yy;
01063 Guchar *srcPtr, *destPtr;
01064 Guint src0, src1, src, dest, s1, s2, m1, m2, m3;
01065 GBool oneByte;
01066
01067 if (y < 0) {
01068 y0 = -y;
01069 } else {
01070 y0 = 0;
01071 }
01072 if (y + bitmap->h > h) {
01073 y1 = h - y;
01074 } else {
01075 y1 = bitmap->h;
01076 }
01077 if (y0 >= y1) {
01078 return;
01079 }
01080
01081 if (x >= 0) {
01082 x0 = x & ~7;
01083 } else {
01084 x0 = 0;
01085 }
01086 x1 = x + bitmap->w;
01087 if (x1 > w) {
01088 x1 = w;
01089 }
01090 if (x0 >= x1) {
01091 return;
01092 }
01093
01094 s1 = x & 7;
01095 s2 = 8 - s1;
01096 m1 = 0xff >> (x1 & 7);
01097 m2 = 0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7));
01098 m3 = (0xff >> s1) & m2;
01099
01100 oneByte = x0 == ((x1 - 1) & ~7);
01101
01102 for (yy = y0; yy < y1; ++yy) {
01103
01104
01105 if (oneByte) {
01106 if (x >= 0) {
01107 destPtr = data + (y + yy) * line + (x >> 3);
01108 srcPtr = bitmap->data + yy * bitmap->line;
01109 dest = *destPtr;
01110 src1 = *srcPtr;
01111 switch (combOp) {
01112 case 0:
01113 dest |= (src1 >> s1) & m2;
01114 break;
01115 case 1:
01116 dest &= ((0xff00 | src1) >> s1) | m1;
01117 break;
01118 case 2:
01119 dest ^= (src1 >> s1) & m2;
01120 break;
01121 case 3:
01122 dest ^= ((src1 ^ 0xff) >> s1) & m2;
01123 break;
01124 case 4:
01125 dest = (dest & ~m3) | ((src1 >> s1) & m3);
01126 break;
01127 }
01128 *destPtr = dest;
01129 } else {
01130 destPtr = data + (y + yy) * line;
01131 srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
01132 dest = *destPtr;
01133 src1 = *srcPtr;
01134 switch (combOp) {
01135 case 0:
01136 dest |= src1 & m2;
01137 break;
01138 case 1:
01139 dest &= src1 | m1;
01140 break;
01141 case 2:
01142 dest ^= src1 & m2;
01143 break;
01144 case 3:
01145 dest ^= (src1 ^ 0xff) & m2;
01146 break;
01147 case 4:
01148 dest = (src1 & m2) | (dest & m1);
01149 break;
01150 }
01151 *destPtr = dest;
01152 }
01153
01154
01155
01156 } else {
01157
01158
01159 if (x >= 0) {
01160 destPtr = data + (y + yy) * line + (x >> 3);
01161 srcPtr = bitmap->data + yy * bitmap->line;
01162 src1 = *srcPtr++;
01163 dest = *destPtr;
01164 switch (combOp) {
01165 case 0:
01166 dest |= src1 >> s1;
01167 break;
01168 case 1:
01169 dest &= (0xff00 | src1) >> s1;
01170 break;
01171 case 2:
01172 dest ^= src1 >> s1;
01173 break;
01174 case 3:
01175 dest ^= (src1 ^ 0xff) >> s1;
01176 break;
01177 case 4:
01178 dest = (dest & (0xff << s2)) | (src1 >> s1);
01179 break;
01180 }
01181 *destPtr++ = dest;
01182 xx = x0 + 8;
01183 } else {
01184 destPtr = data + (y + yy) * line;
01185 srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
01186 src1 = *srcPtr++;
01187 xx = x0;
01188 }
01189
01190
01191 for (; xx < x1 - 8; xx += 8) {
01192 dest = *destPtr;
01193 src0 = src1;
01194 src1 = *srcPtr++;
01195 src = (((src0 << 8) | src1) >> s1) & 0xff;
01196 switch (combOp) {
01197 case 0:
01198 dest |= src;
01199 break;
01200 case 1:
01201 dest &= src;
01202 break;
01203 case 2:
01204 dest ^= src;
01205 break;
01206 case 3:
01207 dest ^= src ^ 0xff;
01208 break;
01209 case 4:
01210 dest = src;
01211 break;
01212 }
01213 *destPtr++ = dest;
01214 }
01215
01216
01217 dest = *destPtr;
01218 src0 = src1;
01219 src1 = *srcPtr++;
01220 src = (((src0 << 8) | src1) >> s1) & 0xff;
01221 switch (combOp) {
01222 case 0:
01223 dest |= src & m2;
01224 break;
01225 case 1:
01226 dest &= src | m1;
01227 break;
01228 case 2:
01229 dest ^= src & m2;
01230 break;
01231 case 3:
01232 dest ^= (src ^ 0xff) & m2;
01233 break;
01234 case 4:
01235 dest = (src & m2) | (dest & m1);
01236 break;
01237 }
01238 *destPtr = dest;
01239 }
01240 }
01241 }
01242
01243
01244
01245
01246
01247 class JBIG2SymbolDict: public JBIG2Segment {
01248 public:
01249
01250 JBIG2SymbolDict(Guint segNumA, Guint sizeA);
01251 virtual ~JBIG2SymbolDict();
01252 virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; }
01253 Guint getSize() { return size; }
01254 void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
01255 JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
01256 void setGenericRegionStats(JBIG2ArithmeticDecoderStats *stats)
01257 { genericRegionStats = stats; }
01258 void setRefinementRegionStats(JBIG2ArithmeticDecoderStats *stats)
01259 { refinementRegionStats = stats; }
01260 JBIG2ArithmeticDecoderStats *getGenericRegionStats()
01261 { return genericRegionStats; }
01262 JBIG2ArithmeticDecoderStats *getRefinementRegionStats()
01263 { return refinementRegionStats; }
01264
01265 private:
01266
01267 Guint size;
01268 JBIG2Bitmap **bitmaps;
01269 JBIG2ArithmeticDecoderStats *genericRegionStats;
01270 JBIG2ArithmeticDecoderStats *refinementRegionStats;
01271 };
01272
01273 JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
01274 JBIG2Segment(segNumA)
01275 {
01276 size = sizeA;
01277 bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
01278 genericRegionStats = NULL;
01279 refinementRegionStats = NULL;
01280 }
01281
01282 JBIG2SymbolDict::~JBIG2SymbolDict() {
01283 Guint i;
01284
01285 for (i = 0; i < size; ++i) {
01286 delete bitmaps[i];
01287 }
01288 gfree(bitmaps);
01289 if (genericRegionStats) {
01290 delete genericRegionStats;
01291 }
01292 if (refinementRegionStats) {
01293 delete refinementRegionStats;
01294 }
01295 }
01296
01297
01298
01299
01300
01301 class JBIG2PatternDict: public JBIG2Segment {
01302 public:
01303
01304 JBIG2PatternDict(Guint segNumA, Guint sizeA);
01305 virtual ~JBIG2PatternDict();
01306 virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }
01307 Guint getSize() { return size; }
01308 void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
01309 JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
01310
01311 private:
01312
01313 Guint size;
01314 JBIG2Bitmap **bitmaps;
01315 };
01316
01317 JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA):
01318 JBIG2Segment(segNumA)
01319 {
01320 size = sizeA;
01321 bitmaps = (JBIG2Bitmap **)gmalloc(size * sizeof(JBIG2Bitmap *));
01322 }
01323
01324 JBIG2PatternDict::~JBIG2PatternDict() {
01325 Guint i;
01326
01327 for (i = 0; i < size; ++i) {
01328 delete bitmaps[i];
01329 }
01330 gfree(bitmaps);
01331 }
01332
01333
01334
01335
01336
01337 class JBIG2CodeTable: public JBIG2Segment {
01338 public:
01339
01340 JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA);
01341 virtual ~JBIG2CodeTable();
01342 virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; }
01343 JBIG2HuffmanTable *getHuffTable() { return table; }
01344
01345 private:
01346
01347 JBIG2HuffmanTable *table;
01348 };
01349
01350 JBIG2CodeTable::JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA):
01351 JBIG2Segment(segNumA)
01352 {
01353 table = tableA;
01354 }
01355
01356 JBIG2CodeTable::~JBIG2CodeTable() {
01357 gfree(table);
01358 }
01359
01360
01361
01362
01363
01364 JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStream):
01365 FilterStream(strA)
01366 {
01367 pageBitmap = NULL;
01368
01369 arithDecoder = new JBIG2ArithmeticDecoder();
01370 genericRegionStats = new JBIG2ArithmeticDecoderStats(1);
01371 refinementRegionStats = new JBIG2ArithmeticDecoderStats(1);
01372 iadhStats = new JBIG2ArithmeticDecoderStats(9);
01373 iadwStats = new JBIG2ArithmeticDecoderStats(9);
01374 iaexStats = new JBIG2ArithmeticDecoderStats(9);
01375 iaaiStats = new JBIG2ArithmeticDecoderStats(9);
01376 iadtStats = new JBIG2ArithmeticDecoderStats(9);
01377 iaitStats = new JBIG2ArithmeticDecoderStats(9);
01378 iafsStats = new JBIG2ArithmeticDecoderStats(9);
01379 iadsStats = new JBIG2ArithmeticDecoderStats(9);
01380 iardxStats = new JBIG2ArithmeticDecoderStats(9);
01381 iardyStats = new JBIG2ArithmeticDecoderStats(9);
01382 iardwStats = new JBIG2ArithmeticDecoderStats(9);
01383 iardhStats = new JBIG2ArithmeticDecoderStats(9);
01384 iariStats = new JBIG2ArithmeticDecoderStats(9);
01385 iaidStats = new JBIG2ArithmeticDecoderStats(1);
01386 huffDecoder = new JBIG2HuffmanDecoder();
01387 mmrDecoder = new JBIG2MMRDecoder();
01388
01389 segments = new GList();
01390 if (globalsStream->isStream()) {
01391 curStr = globalsStream->getStream();
01392 curStr->reset();
01393 arithDecoder->setStream(curStr);
01394 huffDecoder->setStream(curStr);
01395 mmrDecoder->setStream(curStr);
01396 readSegments();
01397 }
01398 globalSegments = segments;
01399
01400 segments = NULL;
01401 curStr = NULL;
01402 dataPtr = dataEnd = NULL;
01403 }
01404
01405 JBIG2Stream::~JBIG2Stream() {
01406 delete arithDecoder;
01407 delete genericRegionStats;
01408 delete refinementRegionStats;
01409 delete iadhStats;
01410 delete iadwStats;
01411 delete iaexStats;
01412 delete iaaiStats;
01413 delete iadtStats;
01414 delete iaitStats;
01415 delete iafsStats;
01416 delete iadsStats;
01417 delete iardxStats;
01418 delete iardyStats;
01419 delete iardwStats;
01420 delete iardhStats;
01421 delete iariStats;
01422 delete iaidStats;
01423 delete huffDecoder;
01424 delete mmrDecoder;
01425 if (pageBitmap) {
01426 delete pageBitmap;
01427 }
01428 if (segments) {
01429 deleteGList(segments, JBIG2Segment);
01430 }
01431 if (globalSegments) {
01432 deleteGList(globalSegments, JBIG2Segment);
01433 }
01434 delete str;
01435 }
01436
01437 void JBIG2Stream::reset() {
01438 if (pageBitmap) {
01439 delete pageBitmap;
01440 pageBitmap = NULL;
01441 }
01442 if (segments) {
01443 deleteGList(segments, JBIG2Segment);
01444 }
01445 segments = new GList();
01446
01447 curStr = str;
01448 curStr->reset();
01449 arithDecoder->setStream(curStr);
01450 huffDecoder->setStream(curStr);
01451 mmrDecoder->setStream(curStr);
01452 readSegments();
01453
01454 if (pageBitmap) {
01455 dataPtr = pageBitmap->getDataPtr();
01456 dataEnd = dataPtr + pageBitmap->getDataSize();
01457 } else {
01458 dataPtr = NULL;
01459 }
01460 }
01461
01462 int JBIG2Stream::getChar() {
01463 if (dataPtr && dataPtr < dataEnd) {
01464 return (*dataPtr++ ^ 0xff) & 0xff;
01465 }
01466 return EOF;
01467 }
01468
01469 int JBIG2Stream::lookChar() {
01470 if (dataPtr && dataPtr < dataEnd) {
01471 return (*dataPtr ^ 0xff) & 0xff;
01472 }
01473 return EOF;
01474 }
01475
01476 GString *JBIG2Stream::getPSFilter(const char *) {
01477 return NULL;
01478 }
01479
01480 GBool JBIG2Stream::isBinary(GBool ) {
01481 return str->isBinary(gTrue);
01482 }
01483
01484 void JBIG2Stream::readSegments() {
01485 Guint segNum, segFlags, segType, page, segLength;
01486 Guint refFlags, nRefSegs;
01487 Guint *refSegs;
01488 int c1, c2, c3;
01489 Guint i;
01490
01491 while (readULong(&segNum)) {
01492
01493
01494 if (!readUByte(&segFlags)) {
01495 goto eofError1;
01496 }
01497 segType = segFlags & 0x3f;
01498
01499
01500 if (!readUByte(&refFlags)) {
01501 goto eofError1;
01502 }
01503 nRefSegs = refFlags >> 5;
01504 if (nRefSegs == 7) {
01505 if ((c1 = curStr->getChar()) == EOF ||
01506 (c2 = curStr->getChar()) == EOF ||
01507 (c3 = curStr->getChar()) == EOF) {
01508 goto eofError1;
01509 }
01510 refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3;
01511 nRefSegs = refFlags & 0x1fffffff;
01512 for (i = 0; i < (nRefSegs + 9) >> 3; ++i) {
01513 c1 = curStr->getChar();
01514 }
01515 }
01516
01517
01518 refSegs = (Guint *)gmalloc(nRefSegs * sizeof(Guint));
01519 if (segNum <= 256) {
01520 for (i = 0; i < nRefSegs; ++i) {
01521 if (!readUByte(&refSegs[i])) {
01522 goto eofError2;
01523 }
01524 }
01525 } else if (segNum <= 65536) {
01526 for (i = 0; i < nRefSegs; ++i) {
01527 if (!readUWord(&refSegs[i])) {
01528 goto eofError2;
01529 }
01530 }
01531 } else {
01532 for (i = 0; i < nRefSegs; ++i) {
01533 if (!readULong(&refSegs[i])) {
01534 goto eofError2;
01535 }
01536 }
01537 }
01538
01539
01540 if (segFlags & 0x40) {
01541 if (!readULong(&page)) {
01542 goto eofError2;
01543 }
01544 } else {
01545 if (!readUByte(&page)) {
01546 goto eofError2;
01547 }
01548 }
01549
01550
01551 if (!readULong(&segLength)) {
01552 goto eofError2;
01553 }
01554
01555
01556 switch (segType) {
01557 case 0:
01558 readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs);
01559 break;
01560 case 4:
01561 readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
01562 break;
01563 case 6:
01564 readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs);
01565 break;
01566 case 7:
01567 readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs);
01568 break;
01569 case 16:
01570 readPatternDictSeg(segNum, segLength);
01571 break;
01572 case 20:
01573 readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength,
01574 refSegs, nRefSegs);
01575 break;
01576 case 22:
01577 readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength,
01578 refSegs, nRefSegs);
01579 break;
01580 case 23:
01581 readHalftoneRegionSeg(segNum, gTrue, gTrue, segLength,
01582 refSegs, nRefSegs);
01583 break;
01584 case 36:
01585 readGenericRegionSeg(segNum, gFalse, gFalse, segLength);
01586 break;
01587 case 38:
01588 readGenericRegionSeg(segNum, gTrue, gFalse, segLength);
01589 break;
01590 case 39:
01591 readGenericRegionSeg(segNum, gTrue, gTrue, segLength);
01592 break;
01593 case 40:
01594 readGenericRefinementRegionSeg(segNum, gFalse, gFalse, segLength,
01595 refSegs, nRefSegs);
01596 break;
01597 case 42:
01598 readGenericRefinementRegionSeg(segNum, gTrue, gFalse, segLength,
01599 refSegs, nRefSegs);
01600 break;
01601 case 43:
01602 readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength,
01603 refSegs, nRefSegs);
01604 break;
01605 case 48:
01606 readPageInfoSeg(segLength);
01607 break;
01608 case 50:
01609 readEndOfStripeSeg(segLength);
01610 break;
01611 case 52:
01612 readProfilesSeg(segLength);
01613 break;
01614 case 53:
01615 readCodeTableSeg(segNum, segLength);
01616 break;
01617 case 62:
01618 readExtensionSeg(segLength);
01619 break;
01620 default:
01621 error(getPos(), "Unknown segment type in JBIG2 stream");
01622 for (i = 0; i < segLength; ++i) {
01623 if ((c1 = curStr->getChar()) == EOF) {
01624 goto eofError2;
01625 }
01626 }
01627 break;
01628 }
01629
01630 gfree(refSegs);
01631 }
01632
01633 return;
01634
01635 eofError2:
01636 gfree(refSegs);
01637 eofError1:
01638 error(getPos(), "Unexpected EOF in JBIG2 stream");
01639 }
01640
01641 void JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint ,
01642 Guint *refSegs, Guint nRefSegs) {
01643 JBIG2SymbolDict *symbolDict;
01644 JBIG2HuffmanTable *huffDHTable, *huffDWTable;
01645 JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
01646 JBIG2Segment *seg;
01647 GList *codeTables;
01648 JBIG2SymbolDict *inputSymbolDict;
01649 Guint flags, sdTemplate, sdrTemplate, huff, refAgg;
01650 Guint huffDH, huffDW, huffBMSize, huffAggInst;
01651 Guint contextUsed, contextRetained;
01652 int sdATX[4], sdATY[4], sdrATX[2], sdrATY[2];
01653 Guint numExSyms, numNewSyms, numInputSyms, symCodeLen;
01654 JBIG2Bitmap **bitmaps;
01655 JBIG2Bitmap *collBitmap, *refBitmap;
01656 Guint *symWidths;
01657 Guint symHeight, symWidth, totalWidth, x, symID;
01658 int dh, dw, refAggNum, refDX, refDY, bmSize;
01659 GBool ex;
01660 int run, cnt;
01661 Guint i, j, k;
01662 Guchar *p;
01663
01664
01665 if (!readUWord(&flags)) {
01666 goto eofError;
01667 }
01668 sdTemplate = (flags >> 10) & 3;
01669 sdrTemplate = (flags >> 12) & 1;
01670 huff = flags & 1;
01671 refAgg = (flags >> 1) & 1;
01672 huffDH = (flags >> 2) & 3;
01673 huffDW = (flags >> 4) & 3;
01674 huffBMSize = (flags >> 6) & 1;
01675 huffAggInst = (flags >> 7) & 1;
01676 contextUsed = (flags >> 8) & 1;
01677 contextRetained = (flags >> 9) & 1;
01678
01679
01680 if (!huff) {
01681 if (sdTemplate == 0) {
01682 if (!readByte(&sdATX[0]) ||
01683 !readByte(&sdATY[0]) ||
01684 !readByte(&sdATX[1]) ||
01685 !readByte(&sdATY[1]) ||
01686 !readByte(&sdATX[2]) ||
01687 !readByte(&sdATY[2]) ||
01688 !readByte(&sdATX[3]) ||
01689 !readByte(&sdATY[3])) {
01690 goto eofError;
01691 }
01692 } else {
01693 if (!readByte(&sdATX[0]) ||
01694 !readByte(&sdATY[0])) {
01695 goto eofError;
01696 }
01697 }
01698 }
01699
01700
01701 if (refAgg && !sdrTemplate) {
01702 if (!readByte(&sdrATX[0]) ||
01703 !readByte(&sdrATY[0]) ||
01704 !readByte(&sdrATX[1]) ||
01705 !readByte(&sdrATY[1])) {
01706 goto eofError;
01707 }
01708 }
01709
01710
01711 if (!readULong(&numExSyms) || !readULong(&numNewSyms)) {
01712 goto eofError;
01713 }
01714
01715
01716 codeTables = new GList();
01717 numInputSyms = 0;
01718 for (i = 0; i < nRefSegs; ++i) {
01719 seg = findSegment(refSegs[i]);
01720 if (seg->getType() == jbig2SegSymbolDict) {
01721 numInputSyms += ((JBIG2SymbolDict *)seg)->getSize();
01722 } else if (seg->getType() == jbig2SegCodeTable) {
01723 codeTables->append(seg);
01724 }
01725 }
01726
01727
01728 symCodeLen = 0;
01729 i = 1;
01730 while (i < numInputSyms + numNewSyms) {
01731 ++symCodeLen;
01732 i <<= 1;
01733 }
01734
01735
01736 bitmaps = (JBIG2Bitmap **)gmalloc((numInputSyms + numNewSyms) *
01737 sizeof(JBIG2Bitmap *));
01738 k = 0;
01739 inputSymbolDict = NULL;
01740 for (i = 0; i < nRefSegs; ++i) {
01741 seg = findSegment(refSegs[i]);
01742 if (seg->getType() == jbig2SegSymbolDict) {
01743 inputSymbolDict = (JBIG2SymbolDict *)seg;
01744 for (j = 0; j < inputSymbolDict->getSize(); ++j) {
01745 bitmaps[k++] = inputSymbolDict->getBitmap(j);
01746 }
01747 }
01748 }
01749
01750
01751 huffDHTable = huffDWTable = NULL;
01752 huffBMSizeTable = huffAggInstTable = NULL;
01753 i = 0;
01754 if (huff) {
01755 if (huffDH == 0) {
01756 huffDHTable = huffTableD;
01757 } else if (huffDH == 1) {
01758 huffDHTable = huffTableE;
01759 } else {
01760 huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
01761 }
01762 if (huffDW == 0) {
01763 huffDWTable = huffTableB;
01764 } else if (huffDW == 1) {
01765 huffDWTable = huffTableC;
01766 } else {
01767 huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
01768 }
01769 if (huffBMSize == 0) {
01770 huffBMSizeTable = huffTableA;
01771 } else {
01772 huffBMSizeTable =
01773 ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
01774 }
01775 if (huffAggInst == 0) {
01776 huffAggInstTable = huffTableA;
01777 } else {
01778 huffAggInstTable =
01779 ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
01780 }
01781 }
01782 delete codeTables;
01783
01784
01785 if (huff) {
01786 huffDecoder->reset();
01787
01788
01789 } else {
01790 if (contextUsed && inputSymbolDict) {
01791 resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats());
01792 if (refAgg) {
01793 resetRefinementStats(sdrTemplate,
01794 inputSymbolDict->getRefinementRegionStats());
01795 }
01796 } else {
01797 resetGenericStats(sdTemplate, NULL);
01798 if (refAgg) {
01799 resetRefinementStats(sdrTemplate, NULL);
01800 }
01801 }
01802 resetIntStats(symCodeLen);
01803 arithDecoder->start();
01804 }
01805
01806
01807 symWidths = NULL;
01808 if (huff && !refAgg) {
01809 symWidths = (Guint *)gmalloc(numNewSyms * sizeof(Guint));
01810 }
01811
01812 symHeight = 0;
01813 i = 0;
01814 while (i < numNewSyms) {
01815
01816
01817 if (huff) {
01818 huffDecoder->decodeInt(&dh, huffDHTable);
01819 } else {
01820 arithDecoder->decodeInt(&dh, iadhStats);
01821 }
01822 symHeight += dh;
01823 symWidth = 0;
01824 totalWidth = 0;
01825 j = i;
01826
01827
01828 while (1) {
01829
01830
01831 if (huff) {
01832 if (!huffDecoder->decodeInt(&dw, huffDWTable)) {
01833 break;
01834 }
01835 } else {
01836 if (!arithDecoder->decodeInt(&dw, iadwStats)) {
01837 break;
01838 }
01839 }
01840 symWidth += dw;
01841
01842
01843 if (huff && !refAgg) {
01844 symWidths[i] = symWidth;
01845 totalWidth += symWidth;
01846
01847
01848 } else if (refAgg) {
01849 if (huff) {
01850 if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) {
01851 break;
01852 }
01853 } else {
01854 if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) {
01855 break;
01856 }
01857 }
01858 if (refAggNum == 1) {
01859 if (huff) {
01860 symID = huffDecoder->readBits(symCodeLen);
01861 huffDecoder->decodeInt(&refDX, huffTableO);
01862 huffDecoder->decodeInt(&refDY, huffTableO);
01863 huffDecoder->decodeInt(&bmSize, huffTableA);
01864 huffDecoder->reset();
01865 arithDecoder->start();
01866 } else {
01867 symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
01868 arithDecoder->decodeInt(&refDX, iardxStats);
01869 arithDecoder->decodeInt(&refDY, iardyStats);
01870 }
01871 refBitmap = bitmaps[symID];
01872 bitmaps[numInputSyms + i] =
01873 readGenericRefinementRegion(symWidth, symHeight,
01874 sdrTemplate, gFalse,
01875 refBitmap, refDX, refDY,
01876 sdrATX, sdrATY);
01877
01878 } else {
01879 bitmaps[numInputSyms + i] =
01880 readTextRegion(huff, gTrue, symWidth, symHeight,
01881 refAggNum, 0, numInputSyms + i, NULL,
01882 symCodeLen, bitmaps, 0, 0, 0, 1, 0,
01883 huffTableF, huffTableH, huffTableK, huffTableO,
01884 huffTableO, huffTableO, huffTableO, huffTableA,
01885 sdrTemplate, sdrATX, sdrATY);
01886 }
01887
01888
01889 } else {
01890 bitmaps[numInputSyms + i] =
01891 readGenericBitmap(gFalse, symWidth, symHeight,
01892 sdTemplate, gFalse, gFalse, NULL,
01893 sdATX, sdATY, 0);
01894 }
01895
01896 ++i;
01897 }
01898
01899
01900 if (huff && !refAgg) {
01901 huffDecoder->decodeInt(&bmSize, huffBMSizeTable);
01902 if (huff) {
01903 huffDecoder->reset();
01904 }
01905 if (bmSize == 0) {
01906 collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight);
01907 bmSize = symHeight * ((totalWidth + 7) >> 3);
01908 p = collBitmap->getDataPtr();
01909 for (k = 0; k < (Guint)bmSize; ++k) {
01910 *p++ = str->getChar();
01911 }
01912 } else {
01913 collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
01914 0, gFalse, gFalse, NULL, NULL, NULL,
01915 bmSize);
01916 }
01917 x = 0;
01918 for (; j < i; ++j) {
01919 bitmaps[numInputSyms + j] =
01920 collBitmap->getSlice(x, 0, symWidths[j], symHeight);
01921 x += symWidths[j];
01922 }
01923 delete collBitmap;
01924 }
01925 }
01926
01927
01928 symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
01929
01930
01931 i = j = 0;
01932 ex = gFalse;
01933 while (i < numInputSyms + numNewSyms) {
01934 if (huff) {
01935 huffDecoder->decodeInt(&run, huffTableA);
01936 } else {
01937 arithDecoder->decodeInt(&run, iaexStats);
01938 }
01939 if (ex) {
01940 for (cnt = 0; cnt < run; ++cnt) {
01941 symbolDict->setBitmap(j++, bitmaps[i++]->copy());
01942 }
01943 } else {
01944 i += run;
01945 }
01946 ex = !ex;
01947 }
01948
01949 for (i = 0; i < numNewSyms; ++i) {
01950 delete bitmaps[numInputSyms + i];
01951 }
01952 gfree(bitmaps);
01953 if (symWidths) {
01954 gfree(symWidths);
01955 }
01956
01957
01958 if (!huff && contextRetained) {
01959 symbolDict->setGenericRegionStats(genericRegionStats->copy());
01960 if (refAgg) {
01961 symbolDict->setRefinementRegionStats(refinementRegionStats->copy());
01962 }
01963 }
01964
01965
01966 segments->append(symbolDict);
01967
01968 return;
01969
01970 eofError:
01971 error(getPos(), "Unexpected EOF in JBIG2 stream");
01972 }
01973
01974 void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
01975 GBool , Guint ,
01976 Guint *refSegs, Guint nRefSegs) {
01977 JBIG2Bitmap *bitmap;
01978 JBIG2HuffmanTable runLengthTab[36];
01979 JBIG2HuffmanTable *symCodeTab;
01980 JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable;
01981 JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
01982 JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
01983 JBIG2Segment *seg;
01984 GList *codeTables;
01985 JBIG2SymbolDict *symbolDict;
01986 JBIG2Bitmap **syms;
01987 Guint w, h, x, y, segInfoFlags, extCombOp;
01988 Guint flags, huff, refine, logStrips, refCorner, transposed;
01989 Guint combOp, defPixel, sOffset, templ;
01990 Guint huffFlags, huffFS, huffDS, huffDT;
01991 Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize;
01992 Guint numInstances, numSyms, symCodeLen;
01993 int atx[2], aty[2];
01994 Guint i, k, kk;
01995 int j;
01996
01997
01998 if (!readULong(&w) || !readULong(&h) ||
01999 !readULong(&x) || !readULong(&y) ||
02000 !readUByte(&segInfoFlags)) {
02001 goto eofError;
02002 }
02003 extCombOp = segInfoFlags & 7;
02004
02005
02006 if (!readUWord(&flags)) {
02007 goto eofError;
02008 }
02009 huff = flags & 1;
02010 refine = (flags >> 1) & 1;
02011 logStrips = (flags >> 2) & 3;
02012 refCorner = (flags >> 4) & 3;
02013 transposed = (flags >> 6) & 1;
02014 combOp = (flags >> 7) & 3;
02015 defPixel = (flags >> 9) & 1;
02016 sOffset = (flags >> 10) & 0x1f;
02017 templ = (flags >> 15) & 1;
02018 huffFS = huffDS = huffDT = 0;
02019 huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0;
02020 if (huff) {
02021 if (!readUWord(&huffFlags)) {
02022 goto eofError;
02023 }
02024 huffFS = huffFlags & 3;
02025 huffDS = (huffFlags >> 2) & 3;
02026 huffDT = (huffFlags >> 4) & 3;
02027 huffRDW = (huffFlags >> 6) & 3;
02028 huffRDH = (huffFlags >> 8) & 3;
02029 huffRDX = (huffFlags >> 10) & 3;
02030 huffRDY = (huffFlags >> 12) & 3;
02031 huffRSize = (huffFlags >> 14) & 1;
02032 }
02033 if (refine && templ == 0) {
02034 if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
02035 !readByte(&atx[1]) || !readByte(&aty[1])) {
02036 goto eofError;
02037 }
02038 }
02039 if (!readULong(&numInstances)) {
02040 goto eofError;
02041 }
02042
02043
02044 codeTables = new GList();
02045 numSyms = 0;
02046 for (i = 0; i < nRefSegs; ++i) {
02047 seg = findSegment(refSegs[i]);
02048 if (seg->getType() == jbig2SegSymbolDict) {
02049 numSyms += ((JBIG2SymbolDict *)seg)->getSize();
02050 } else if (seg->getType() == jbig2SegCodeTable) {
02051 codeTables->append(seg);
02052 }
02053 }
02054 symCodeLen = 0;
02055 i = 1;
02056 while (i < numSyms) {
02057 ++symCodeLen;
02058 i <<= 1;
02059 }
02060
02061
02062 syms = (JBIG2Bitmap **)gmalloc(numSyms * sizeof(JBIG2Bitmap *));
02063 kk = 0;
02064 for (i = 0; i < nRefSegs; ++i) {
02065 seg = findSegment(refSegs[i]);
02066 if (seg->getType() == jbig2SegSymbolDict) {
02067 symbolDict = (JBIG2SymbolDict *)seg;
02068 for (k = 0; k < symbolDict->getSize(); ++k) {
02069 syms[kk++] = symbolDict->getBitmap(k);
02070 }
02071 }
02072 }
02073
02074
02075 huffFSTable = huffDSTable = huffDTTable = NULL;
02076 huffRDWTable = huffRDHTable = NULL;
02077 huffRDXTable = huffRDYTable = huffRSizeTable = NULL;
02078 i = 0;
02079 if (huff) {
02080 if (huffFS == 0) {
02081 huffFSTable = huffTableF;
02082 } else if (huffFS == 1) {
02083 huffFSTable = huffTableG;
02084 } else {
02085 huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
02086 }
02087 if (huffDS == 0) {
02088 huffDSTable = huffTableH;
02089 } else if (huffDS == 1) {
02090 huffDSTable = huffTableI;
02091 } else if (huffDS == 2) {
02092 huffDSTable = huffTableJ;
02093 } else {
02094 huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
02095 }
02096 if (huffDT == 0) {
02097 huffDTTable = huffTableK;
02098 } else if (huffDT == 1) {
02099 huffDTTable = huffTableL;
02100 } else if (huffDT == 2) {
02101 huffDTTable = huffTableM;
02102 } else {
02103 huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
02104 }
02105 if (huffRDW == 0) {
02106 huffRDWTable = huffTableN;
02107 } else if (huffRDW == 1) {
02108 huffRDWTable = huffTableO;
02109 } else {
02110 huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
02111 }
02112 if (huffRDH == 0) {
02113 huffRDHTable = huffTableN;
02114 } else if (huffRDH == 1) {
02115 huffRDHTable = huffTableO;
02116 } else {
02117 huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
02118 }
02119 if (huffRDX == 0) {
02120 huffRDXTable = huffTableN;
02121 } else if (huffRDX == 1) {
02122 huffRDXTable = huffTableO;
02123 } else {
02124 huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
02125 }
02126 if (huffRDY == 0) {
02127 huffRDYTable = huffTableN;
02128 } else if (huffRDY == 1) {
02129 huffRDYTable = huffTableO;
02130 } else {
02131 huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
02132 }
02133 if (huffRSize == 0) {
02134 huffRSizeTable = huffTableA;
02135 } else {
02136 huffRSizeTable =
02137 ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
02138 }
02139 }
02140 delete codeTables;
02141
02142
02143 if (huff) {
02144 huffDecoder->reset();
02145 for (i = 0; i < 32; ++i) {
02146 runLengthTab[i].val = i;
02147 runLengthTab[i].prefixLen = huffDecoder->readBits(4);
02148 runLengthTab[i].rangeLen = 0;
02149 }
02150 runLengthTab[32].val = 0x103;
02151 runLengthTab[32].prefixLen = huffDecoder->readBits(4);
02152 runLengthTab[32].rangeLen = 2;
02153 runLengthTab[33].val = 0x203;
02154 runLengthTab[33].prefixLen = huffDecoder->readBits(4);
02155 runLengthTab[33].rangeLen = 3;
02156 runLengthTab[34].val = 0x20b;
02157 runLengthTab[34].prefixLen = huffDecoder->readBits(4);
02158 runLengthTab[34].rangeLen = 7;
02159 runLengthTab[35].rangeLen = jbig2HuffmanEOT;
02160 huffDecoder->buildTable(runLengthTab, 35);
02161 symCodeTab = (JBIG2HuffmanTable *)gmalloc((numSyms + 1) *
02162 sizeof(JBIG2HuffmanTable));
02163 for (i = 0; i < numSyms; ++i) {
02164 symCodeTab[i].val = i;
02165 symCodeTab[i].rangeLen = 0;
02166 }
02167 i = 0;
02168 while (i < numSyms) {
02169 huffDecoder->decodeInt(&j, runLengthTab);
02170 if (j > 0x200) {
02171 for (j -= 0x200; j && i < numSyms; --j) {
02172 symCodeTab[i++].prefixLen = 0;
02173 }
02174 } else if (j > 0x100) {
02175 for (j -= 0x100; j && i < numSyms; --j) {
02176 symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
02177 ++i;
02178 }
02179 } else {
02180 symCodeTab[i++].prefixLen = j;
02181 }
02182
02183 }
02184 symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT;
02185 huffDecoder->buildTable(symCodeTab, numSyms);
02186 huffDecoder->reset();
02187
02188
02189 } else {
02190 symCodeTab = NULL;
02191 resetIntStats(symCodeLen);
02192 if (refine) {
02193 resetRefinementStats(templ, NULL);
02194 }
02195 arithDecoder->start();
02196 }
02197
02198 bitmap = readTextRegion(huff, refine, w, h, numInstances,
02199 logStrips, numSyms, symCodeTab, symCodeLen, syms,
02200 defPixel, combOp, transposed, refCorner, sOffset,
02201 huffFSTable, huffDSTable, huffDTTable,
02202 huffRDWTable, huffRDHTable,
02203 huffRDXTable, huffRDYTable, huffRSizeTable,
02204 templ, atx, aty);
02205
02206 gfree(syms);
02207
02208
02209 if (imm) {
02210 if (pageH == 0xffffffff && y + h > curPageH) {
02211 pageBitmap->expand(y + h, pageDefPixel);
02212 }
02213 pageBitmap->combine(bitmap, x, y, extCombOp);
02214 delete bitmap;
02215
02216
02217 } else {
02218 bitmap->setSegNum(segNum);
02219 segments->append(bitmap);
02220 }
02221
02222
02223 if (huff) {
02224 gfree(symCodeTab);
02225 }
02226
02227 return;
02228
02229 eofError:
02230 error(getPos(), "Unexpected EOF in JBIG2 stream");
02231 }
02232
02233 JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
02234 int w, int h,
02235 Guint numInstances,
02236 Guint logStrips,
02237 int ,
02238 JBIG2HuffmanTable *symCodeTab,
02239 Guint symCodeLen,
02240 JBIG2Bitmap **syms,
02241 Guint defPixel, Guint combOp,
02242 Guint transposed, Guint refCorner,
02243 Guint sOffset,
02244 JBIG2HuffmanTable *huffFSTable,
02245 JBIG2HuffmanTable *huffDSTable,
02246 JBIG2HuffmanTable *huffDTTable,
02247 JBIG2HuffmanTable *huffRDWTable,
02248 JBIG2HuffmanTable *huffRDHTable,
02249 JBIG2HuffmanTable *huffRDXTable,
02250 JBIG2HuffmanTable *huffRDYTable,
02251 JBIG2HuffmanTable *huffRSizeTable,
02252 Guint templ,
02253 int *atx, int *aty) {
02254 JBIG2Bitmap *bitmap;
02255 JBIG2Bitmap *symbolBitmap;
02256 Guint strips;
02257 int t, dt, tt, s, ds, sFirst, j;
02258 int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize;
02259 Guint symID, inst, bw, bh;
02260
02261 strips = 1 << logStrips;
02262
02263 if (w < 0 || h <= 0 || w >= INT_MAX / h) {
02264 error(-1, "invalid width/height");
02265 return NULL;
02266 }
02267
02268
02269 bitmap = new JBIG2Bitmap(0, w, h);
02270 if (defPixel) {
02271 bitmap->clearToOne();
02272 } else {
02273 bitmap->clearToZero();
02274 }
02275
02276
02277 if (huff) {
02278 huffDecoder->decodeInt(&t, huffDTTable);
02279 } else {
02280 arithDecoder->decodeInt(&t, iadtStats);
02281 }
02282 t *= -strips;
02283
02284 inst = 0;
02285 sFirst = 0;
02286 while (inst < numInstances) {
02287
02288
02289 if (huff) {
02290 huffDecoder->decodeInt(&dt, huffDTTable);
02291 } else {
02292 arithDecoder->decodeInt(&dt, iadtStats);
02293 }
02294 t += dt * strips;
02295
02296
02297 if (huff) {
02298 huffDecoder->decodeInt(&ds, huffFSTable);
02299 } else {
02300 arithDecoder->decodeInt(&ds, iafsStats);
02301 }
02302 sFirst += ds;
02303 s = sFirst;
02304
02305
02306 while (1) {
02307
02308
02309 if (strips == 1) {
02310 dt = 0;
02311 } else if (huff) {
02312 dt = huffDecoder->readBits(logStrips);
02313 } else {
02314 arithDecoder->decodeInt(&dt, iaitStats);
02315 }
02316 tt = t + dt;
02317
02318
02319 if (huff) {
02320 if (symCodeTab) {
02321 huffDecoder->decodeInt(&j, symCodeTab);
02322 symID = (Guint)j;
02323 } else {
02324 symID = huffDecoder->readBits(symCodeLen);
02325 }
02326 } else {
02327 symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
02328 }
02329
02330
02331 symbolBitmap = NULL;
02332 if (refine) {
02333 if (huff) {
02334 ri = (int)huffDecoder->readBit();
02335 } else {
02336 arithDecoder->decodeInt(&ri, iariStats);
02337 }
02338 } else {
02339 ri = 0;
02340 }
02341 if (ri) {
02342 if (huff) {
02343 huffDecoder->decodeInt(&rdw, huffRDWTable);
02344 huffDecoder->decodeInt(&rdh, huffRDHTable);
02345 huffDecoder->decodeInt(&rdx, huffRDXTable);
02346 huffDecoder->decodeInt(&rdy, huffRDYTable);
02347 huffDecoder->decodeInt(&bmSize, huffRSizeTable);
02348 huffDecoder->reset();
02349 arithDecoder->start();
02350 } else {
02351 arithDecoder->decodeInt(&rdw, iardwStats);
02352 arithDecoder->decodeInt(&rdh, iardhStats);
02353 arithDecoder->decodeInt(&rdx, iardxStats);
02354 arithDecoder->decodeInt(&rdy, iardyStats);
02355 }
02356 refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
02357 refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
02358
02359 symbolBitmap =
02360 readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
02361 rdh + syms[symID]->getHeight(),
02362 templ, gFalse, syms[symID],
02363 refDX, refDY, atx, aty);
02364
02365 } else {
02366 symbolBitmap = syms[symID];
02367 }
02368
02369
02370
02371
02372 bw = symbolBitmap->getWidth() - 1;
02373 bh = symbolBitmap->getHeight() - 1;
02374 if (transposed) {
02375 switch (refCorner) {
02376 case 0:
02377 bitmap->combine(symbolBitmap, tt, s, combOp);
02378 break;
02379 case 1:
02380 bitmap->combine(symbolBitmap, tt, s, combOp);
02381 break;
02382 case 2:
02383 bitmap->combine(symbolBitmap, tt - bw, s, combOp);
02384 break;
02385 case 3:
02386 bitmap->combine(symbolBitmap, tt - bw, s, combOp);
02387 break;
02388 }
02389 s += bh;
02390 } else {
02391 switch (refCorner) {
02392 case 0:
02393 bitmap->combine(symbolBitmap, s, tt - bh, combOp);
02394 break;
02395 case 1:
02396 bitmap->combine(symbolBitmap, s, tt, combOp);
02397 break;
02398 case 2:
02399 bitmap->combine(symbolBitmap, s, tt - bh, combOp);
02400 break;
02401 case 3:
02402 bitmap->combine(symbolBitmap, s, tt, combOp);
02403 break;
02404 }
02405 s += bw;
02406 }
02407 if (ri) {
02408 delete symbolBitmap;
02409 }
02410
02411
02412 ++inst;
02413
02414
02415 if (huff) {
02416 if (!huffDecoder->decodeInt(&ds, huffDSTable)) {
02417 break;
02418 }
02419 } else {
02420 if (!arithDecoder->decodeInt(&ds, iadsStats)) {
02421 break;
02422 }
02423 }
02424 s += sOffset + ds;
02425 }
02426 }
02427
02428 return bitmap;
02429 }
02430
02431 void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
02432 JBIG2PatternDict *patternDict;
02433 JBIG2Bitmap *bitmap;
02434 Guint flags, patternW, patternH, grayMax, templ, mmr;
02435 int atx[4], aty[4];
02436 Guint i, x;
02437
02438
02439 if (!readUByte(&flags) ||
02440 !readUByte(&patternW) ||
02441 !readUByte(&patternH) ||
02442 !readULong(&grayMax)) {
02443 goto eofError;
02444 }
02445 templ = (flags >> 1) & 3;
02446 mmr = flags & 1;
02447
02448
02449 if (!mmr) {
02450 resetGenericStats(templ, NULL);
02451 arithDecoder->start();
02452 }
02453
02454
02455 atx[0] = -patternW; aty[0] = 0;
02456 atx[1] = -3; aty[1] = -1;
02457 atx[2] = 2; aty[2] = -2;
02458 atx[3] = -2; aty[3] = -2;
02459 bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
02460 templ, gFalse, gFalse, NULL,
02461 atx, aty, length - 7);
02462
02463
02464 patternDict = new JBIG2PatternDict(segNum, grayMax + 1);
02465
02466
02467 x = 0;
02468 for (i = 0; i <= grayMax; ++i) {
02469 patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
02470 x += patternW;
02471 }
02472
02473
02474 delete bitmap;
02475
02476
02477 segments->append(patternDict);
02478
02479 return;
02480
02481 eofError:
02482 error(getPos(), "Unexpected EOF in JBIG2 stream");
02483 }
02484
02485 void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
02486 GBool , Guint ,
02487 Guint *refSegs, Guint nRefSegs) {
02488 JBIG2Bitmap *bitmap;
02489 JBIG2Segment *seg;
02490 JBIG2PatternDict *patternDict;
02491 JBIG2Bitmap *skipBitmap;
02492 Guint *grayImg;
02493 JBIG2Bitmap *grayBitmap;
02494 JBIG2Bitmap *patternBitmap;
02495 Guint w, h, x, y, segInfoFlags, extCombOp;
02496 Guint flags, mmr, templ, enableSkip, combOp;
02497 Guint gridW, gridH, stepX, stepY, patW, patH;
02498 int atx[4], aty[4];
02499 int gridX, gridY, xx, yy, bit, j;
02500 Guint bpp, m, n, i;
02501
02502
02503 if (!readULong(&w) || !readULong(&h) ||
02504 !readULong(&x) || !readULong(&y) ||
02505 !readUByte(&segInfoFlags)) {
02506 goto eofError;
02507 }
02508 extCombOp = segInfoFlags & 7;
02509
02510
02511 if (!readUByte(&flags)) {
02512 goto eofError;
02513 }
02514 mmr = flags & 1;
02515 templ = (flags >> 1) & 3;
02516 enableSkip = (flags >> 3) & 1;
02517 combOp = (flags >> 4) & 7;
02518 if (!readULong(&gridW) || !readULong(&gridH) ||
02519 !readLong(&gridX) || !readLong(&gridY) ||
02520 !readUWord(&stepX) || !readUWord(&stepY)) {
02521 goto eofError;
02522 }
02523
02524 if (w == 0 || h == 0 || w >= INT_MAX / h) {
02525 error(getPos(), "Bad bitmap size in JBIG2 halftone segment");
02526 return;
02527 }
02528 if (gridH == 0 || gridW >= INT_MAX / gridH) {
02529 error(getPos(), "Bad grid size in JBIG2 halftone segment");
02530 return;
02531 }
02532
02533
02534 if (nRefSegs != 1) {
02535 error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
02536 return;
02537 }
02538 seg = findSegment(refSegs[0]);
02539 if (seg->getType() != jbig2SegPatternDict) {
02540 error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
02541 return;
02542 }
02543 if (gridH == 0 || gridW >= INT_MAX / gridH) {
02544 error(getPos(), "Bad size in JBIG2 halftone segment");
02545 return;
02546 }
02547 if (w == 0 || h >= INT_MAX / w) {
02548 error(getPos(), "Bad size in JBIG2 bitmap segment");
02549 return;
02550 }
02551
02552 patternDict = (JBIG2PatternDict *)seg;
02553 bpp = 0;
02554 i = 1;
02555 while (i < patternDict->getSize()) {
02556 ++bpp;
02557 i <<= 1;
02558 }
02559 patW = patternDict->getBitmap(0)->getWidth();
02560 patH = patternDict->getBitmap(0)->getHeight();
02561
02562
02563 if (!mmr) {
02564 resetGenericStats(templ, NULL);
02565 arithDecoder->start();
02566 }
02567
02568
02569 bitmap = new JBIG2Bitmap(segNum, w, h);
02570 if (flags & 0x80) {
02571 bitmap->clearToOne();
02572 } else {
02573 bitmap->clearToZero();
02574 }
02575
02576
02577 skipBitmap = NULL;
02578 if (enableSkip) {
02579 skipBitmap = new JBIG2Bitmap(0, gridW, gridH);
02580 skipBitmap->clearToZero();
02581 for (m = 0; m < gridH; ++m) {
02582 xx = gridX + m * stepY;
02583 yy = gridY + m * stepX;
02584 for (n = 0; n < gridW; ++n) {
02585 if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w ||
02586 ((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) {
02587 skipBitmap->setPixel(n, m);
02588 }
02589 }
02590 }
02591 }
02592
02593
02594 grayImg = (Guint *)gmalloc(gridW * gridH * sizeof(Guint));
02595 memset(grayImg, 0, gridW * gridH * sizeof(Guint));
02596 atx[0] = templ <= 1 ? 3 : 2; aty[0] = -1;
02597 atx[1] = -3; aty[1] = -1;
02598 atx[2] = 2; aty[2] = -2;
02599 atx[3] = -2; aty[3] = -2;
02600 for (j = bpp - 1; j >= 0; --j) {
02601 grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse,
02602 enableSkip, skipBitmap, atx, aty, -1);
02603 i = 0;
02604 for (m = 0; m < gridH; ++m) {
02605 for (n = 0; n < gridW; ++n) {
02606 bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1);
02607 grayImg[i] = (grayImg[i] << 1) | bit;
02608 ++i;
02609 }
02610 }
02611 delete grayBitmap;
02612 }
02613
02614
02615 i = 0;
02616 for (m = 0; m < gridH; ++m) {
02617 xx = gridX + m * stepY;
02618 yy = gridY + m * stepX;
02619 for (n = 0; n < gridW; ++n) {
02620 if (!(enableSkip && skipBitmap->getPixel(n, m))) {
02621 patternBitmap = patternDict->getBitmap(grayImg[i]);
02622 bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp);
02623 }
02624 xx += stepX;
02625 yy -= stepY;
02626 ++i;
02627 }
02628 }
02629
02630 gfree(grayImg);
02631
02632
02633 if (imm) {
02634 if (pageH == 0xffffffff && y + h > curPageH) {
02635 pageBitmap->expand(y + h, pageDefPixel);
02636 }
02637 pageBitmap->combine(bitmap, x, y, extCombOp);
02638 delete bitmap;
02639
02640
02641 } else {
02642 segments->append(bitmap);
02643 }
02644
02645 return;
02646
02647 eofError:
02648 error(getPos(), "Unexpected EOF in JBIG2 stream");
02649 }
02650
02651 void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
02652 GBool , Guint length) {
02653 JBIG2Bitmap *bitmap;
02654 Guint w, h, x, y, segInfoFlags, extCombOp;
02655 Guint flags, mmr, templ, tpgdOn;
02656 int atx[4], aty[4];
02657
02658
02659 if (!readULong(&w) || !readULong(&h) ||
02660 !readULong(&x) || !readULong(&y) ||
02661 !readUByte(&segInfoFlags)) {
02662 goto eofError;
02663 }
02664 extCombOp = segInfoFlags & 7;
02665
02666
02667 if (!readUByte(&flags)) {
02668 goto eofError;
02669 }
02670 mmr = flags & 1;
02671 templ = (flags >> 1) & 3;
02672 tpgdOn = (flags >> 3) & 1;
02673
02674
02675 if (!mmr) {
02676 if (templ == 0) {
02677 if (!readByte(&atx[0]) ||
02678 !readByte(&aty[0]) ||
02679 !readByte(&atx[1]) ||
02680 !readByte(&aty[1]) ||
02681 !readByte(&atx[2]) ||
02682 !readByte(&aty[2]) ||
02683 !readByte(&atx[3]) ||
02684 !readByte(&aty[3])) {
02685 goto eofError;
02686 }
02687 } else {
02688 if (!readByte(&atx[0]) ||
02689 !readByte(&aty[0])) {
02690 goto eofError;
02691 }
02692 }
02693 }
02694
02695
02696 if (!mmr) {
02697 resetGenericStats(templ, NULL);
02698 arithDecoder->start();
02699 }
02700
02701
02702 bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
02703 NULL, atx, aty, mmr ? 0 : length - 18);
02704
02705
02706 if (imm) {
02707 if (pageH == 0xffffffff && y + h > curPageH) {
02708 pageBitmap->expand(y + h, pageDefPixel);
02709 }
02710 pageBitmap->combine(bitmap, x, y, extCombOp);
02711 delete bitmap;
02712
02713
02714 } else {
02715 bitmap->setSegNum(segNum);
02716 segments->append(bitmap);
02717 }
02718
02719 return;
02720
02721 eofError:
02722 error(getPos(), "Unexpected EOF in JBIG2 stream");
02723 }
02724
02725 JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
02726 int templ, GBool tpgdOn,
02727 GBool useSkip, JBIG2Bitmap *skip,
02728 int *atx, int *aty,
02729 int mmrDataLength) {
02730 JBIG2Bitmap *bitmap;
02731 GBool ltp;
02732 Guint ltpCX, cx, cx0, cx1, cx2;
02733 int *refLine, *codingLine;
02734 int code1, code2, code3;
02735 int x, y, a0, pix, i, refI, codingI;
02736
02737 bitmap = new JBIG2Bitmap(0, w, h);
02738 bitmap->clearToZero();
02739
02740
02741
02742 if (mmr) {
02743
02744 mmrDecoder->reset();
02745 refLine = (int *)gmalloc((w + 2) * sizeof(int));
02746 codingLine = (int *)gmalloc((w + 2) * sizeof(int));
02747 codingLine[0] = codingLine[1] = w;
02748
02749 for (y = 0; y < h; ++y) {
02750
02751
02752 for (i = 0; codingLine[i] < w; ++i) {
02753 refLine[i] = codingLine[i];
02754 }
02755 refLine[i] = refLine[i + 1] = w;
02756
02757
02758 refI = 0;
02759 codingI = 0;
02760 a0 = 0;
02761 do {
02762 code1 = mmrDecoder->get2DCode();
02763 switch (code1) {
02764 case twoDimPass:
02765 if (refLine[refI] < w) {
02766 a0 = refLine[refI + 1];
02767 refI += 2;
02768 }
02769 break;
02770 case twoDimHoriz:
02771 if (codingI & 1) {
02772 code1 = 0;
02773 do {
02774 code1 += code3 = mmrDecoder->getBlackCode();
02775 } while (code3 >= 64);
02776 code2 = 0;
02777 do {
02778 code2 += code3 = mmrDecoder->getWhiteCode();
02779 } while (code3 >= 64);
02780 } else {
02781 code1 = 0;
02782 do {
02783 code1 += code3 = mmrDecoder->getWhiteCode();
02784 } while (code3 >= 64);
02785 code2 = 0;
02786 do {
02787 code2 += code3 = mmrDecoder->getBlackCode();
02788 } while (code3 >= 64);
02789 }
02790 a0 = codingLine[codingI++] = a0 + code1;
02791 a0 = codingLine[codingI++] = a0 + code2;
02792 while (refLine[refI] <= a0 && refLine[refI] < w) {
02793 refI += 2;
02794 }
02795 break;
02796 case twoDimVert0:
02797 a0 = codingLine[codingI++] = refLine[refI];
02798 if (refLine[refI] < w) {
02799 ++refI;
02800 }
02801 break;
02802 case twoDimVertR1:
02803 a0 = codingLine[codingI++] = refLine[refI] + 1;
02804 if (refLine[refI] < w) {
02805 ++refI;
02806 while (refLine[refI] <= a0 && refLine[refI] < w) {
02807 refI += 2;
02808 }
02809 }
02810 break;
02811 case twoDimVertR2:
02812 a0 = codingLine[codingI++] = refLine[refI] + 2;
02813 if (refLine[refI] < w) {
02814 ++refI;
02815 while (refLine[refI] <= a0 && refLine[refI] < w) {
02816 refI += 2;
02817 }
02818 }
02819 break;
02820 case twoDimVertR3:
02821 a0 = codingLine[codingI++] = refLine[refI] + 3;
02822 if (refLine[refI] < w) {
02823 ++refI;
02824 while (refLine[refI] <= a0 && refLine[refI] < w) {
02825 refI += 2;
02826 }
02827 }
02828 break;
02829 case twoDimVertL1:
02830 a0 = codingLine[codingI++] = refLine[refI] - 1;
02831 if (refI > 0) {
02832 --refI;
02833 } else {
02834 ++refI;
02835 }
02836 while (refLine[refI] <= a0 && refLine[refI] < w) {
02837 refI += 2;
02838 }
02839 break;
02840 case twoDimVertL2:
02841 a0 = codingLine[codingI++] = refLine[refI] - 2;
02842 if (refI > 0) {
02843 --refI;
02844 } else {
02845 ++refI;
02846 }
02847 while (refLine[refI] <= a0 && refLine[refI] < w) {
02848 refI += 2;
02849 }
02850 break;
02851 case twoDimVertL3:
02852 a0 = codingLine[codingI++] = refLine[refI] - 3;
02853 if (refI > 0) {
02854 --refI;
02855 } else {
02856 ++refI;
02857 }
02858 while (refLine[refI] <= a0 && refLine[refI] < w) {
02859 refI += 2;
02860 }
02861 break;
02862 default:
02863 error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
02864 break;
02865 }
02866 } while (a0 < w);
02867 codingLine[codingI++] = w;
02868
02869
02870 i = 0;
02871 while (codingLine[i] < w) {
02872 for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
02873 bitmap->setPixel(x, y);
02874 }
02875 i += 2;
02876 }
02877 }
02878
02879 if (mmrDataLength >= 0) {
02880 mmrDecoder->skipTo(mmrDataLength);
02881 } else {
02882 if (mmrDecoder->get24Bits() != 0x001001) {
02883 error(getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
02884 }
02885 }
02886
02887 gfree(refLine);
02888 gfree(codingLine);
02889
02890
02891
02892 } else {
02893
02894 ltpCX = 0;
02895 if (tpgdOn) {
02896 switch (templ) {
02897 case 0:
02898 ltpCX = 0x3953;
02899 break;
02900 case 1:
02901 ltpCX = 0x079a;
02902 break;
02903 case 2:
02904 ltpCX = 0x0e3;
02905 break;
02906 case 3:
02907 ltpCX = 0x18a;
02908 break;
02909 }
02910 }
02911
02912 ltp = 0;
02913 cx = cx0 = cx1 = cx2 = 0;
02914 for (y = 0; y < h; ++y) {
02915
02916
02917 if (tpgdOn) {
02918 if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
02919 ltp = !ltp;
02920 }
02921 if (ltp) {
02922 bitmap->duplicateRow(y, y-1);
02923 continue;
02924 }
02925 }
02926
02927
02928 switch (templ) {
02929 case 0:
02930 cx0 = (bitmap->getPixel(0, y-2) << 1) |
02931 bitmap->getPixel(1, y-2);
02932 cx1 = (bitmap->getPixel(0, y-1) << 2) |
02933 (bitmap->getPixel(1, y-1) << 1) |
02934 bitmap->getPixel(2, y-1);
02935 cx2 = 0;
02936 break;
02937 case 1:
02938 cx0 = (bitmap->getPixel(0, y-2) << 2) |
02939 (bitmap->getPixel(1, y-2) << 1) |
02940 bitmap->getPixel(2, y-2);
02941 cx1 = (bitmap->getPixel(0, y-1) << 2) |
02942 (bitmap->getPixel(1, y-1) << 1) |
02943 bitmap->getPixel(2, y-1);
02944 cx2 = 0;
02945 break;
02946 case 2:
02947 cx0 = (bitmap->getPixel(0, y-2) << 1) |
02948 bitmap->getPixel(1, y-2);
02949 cx1 = (bitmap->getPixel(0, y-1) << 1) |
02950 bitmap->getPixel(1, y-1);
02951 cx2 = 0;
02952 break;
02953 case 3:
02954 cx1 = (bitmap->getPixel(0, y-1) << 1) |
02955 bitmap->getPixel(1, y-1);
02956 cx2 = 0;
02957 break;
02958 }
02959
02960
02961 for (x = 0; x < w; ++x) {
02962
02963
02964 if (useSkip && skip->getPixel(x, y)) {
02965 pix = 0;
02966
02967 } else {
02968
02969
02970 switch (templ) {
02971 case 0:
02972 cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
02973 (bitmap->getPixel(x + atx[0], y + aty[0]) << 3) |
02974 (bitmap->getPixel(x + atx[1], y + aty[1]) << 2) |
02975 (bitmap->getPixel(x + atx[2], y + aty[2]) << 1) |
02976 bitmap->getPixel(x + atx[3], y + aty[3]);
02977 break;
02978 case 1:
02979 cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
02980 bitmap->getPixel(x + atx[0], y + aty[0]);
02981 break;
02982 case 2:
02983 cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
02984 bitmap->getPixel(x + atx[0], y + aty[0]);
02985 break;
02986 case 3:
02987 cx = (cx1 << 5) | (cx2 << 1) |
02988 bitmap->getPixel(x + atx[0], y + aty[0]);
02989 break;
02990 }
02991
02992
02993 if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
02994 bitmap->setPixel(x, y);
02995 }
02996 }
02997
02998
02999 switch (templ) {
03000 case 0:
03001 cx0 = ((cx0 << 1) | bitmap->getPixel(x+2, y-2)) & 0x07;
03002 cx1 = ((cx1 << 1) | bitmap->getPixel(x+3, y-1)) & 0x1f;
03003 cx2 = ((cx2 << 1) | pix) & 0x0f;
03004 break;
03005 case 1:
03006 cx0 = ((cx0 << 1) | bitmap->getPixel(x+3, y-2)) & 0x0f;
03007 cx1 = ((cx1 << 1) | bitmap->getPixel(x+3, y-1)) & 0x1f;
03008 cx2 = ((cx2 << 1) | pix) & 0x07;
03009 break;
03010 case 2:
03011 cx0 = ((cx0 << 1) | bitmap->getPixel(x+2, y-2)) & 0x07;
03012 cx1 = ((cx1 << 1) | bitmap->getPixel(x+2, y-1)) & 0x0f;
03013 cx2 = ((cx2 << 1) | pix) & 0x03;
03014 break;
03015 case 3:
03016 cx1 = ((cx1 << 1) | bitmap->getPixel(x+2, y-1)) & 0x1f;
03017 cx2 = ((cx2 << 1) | pix) & 0x0f;
03018 break;
03019 }
03020 }
03021 }
03022 }
03023
03024 return bitmap;
03025 }
03026
03027 void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
03028 GBool , Guint ,
03029 Guint *refSegs,
03030 Guint nRefSegs) {
03031 JBIG2Bitmap *bitmap, *refBitmap;
03032 Guint w, h, x, y, segInfoFlags, extCombOp;
03033 Guint flags, templ, tpgrOn;
03034 int atx[2], aty[2];
03035 JBIG2Segment *seg;
03036
03037
03038 if (!readULong(&w) || !readULong(&h) ||
03039 !readULong(&x) || !readULong(&y) ||
03040 !readUByte(&segInfoFlags)) {
03041 goto eofError;
03042 }
03043 extCombOp = segInfoFlags & 7;
03044
03045
03046 if (!readUByte(&flags)) {
03047 goto eofError;
03048 }
03049 templ = flags & 1;
03050 tpgrOn = (flags >> 1) & 1;
03051
03052
03053 if (!templ) {
03054 if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
03055 !readByte(&atx[1]) || !readByte(&aty[1])) {
03056 goto eofError;
03057 }
03058 }
03059
03060
03061 if (nRefSegs == 0 || imm) {
03062 if (pageH == 0xffffffff && y + h > curPageH) {
03063 pageBitmap->expand(y + h, pageDefPixel);
03064 }
03065 }
03066
03067
03068 if (nRefSegs > 1) {
03069 error(getPos(), "Bad reference in JBIG2 generic refinement segment");
03070 return;
03071 }
03072 if (nRefSegs == 1) {
03073 seg = findSegment(refSegs[0]);
03074 if (seg->getType() != jbig2SegBitmap) {
03075 error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
03076 return;
03077 }
03078 refBitmap = (JBIG2Bitmap *)seg;
03079 } else {
03080 refBitmap = pageBitmap->getSlice(x, y, w, h);
03081 }
03082
03083
03084 resetRefinementStats(templ, NULL);
03085 arithDecoder->start();
03086
03087
03088 bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
03089 refBitmap, 0, 0, atx, aty);
03090
03091
03092 if (imm) {
03093 pageBitmap->combine(bitmap, x, y, extCombOp);
03094 delete bitmap;
03095
03096
03097 } else {
03098 bitmap->setSegNum(segNum);
03099 segments->append(bitmap);
03100 }
03101
03102
03103 if (nRefSegs == 1) {
03104 discardSegment(refSegs[0]);
03105 } else {
03106 delete refBitmap;
03107 }
03108
03109 return;
03110
03111 eofError:
03112 error(getPos(), "Unexpected EOF in JBIG2 stream");
03113 }
03114
03115 JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
03116 int templ, GBool tpgrOn,
03117 JBIG2Bitmap *refBitmap,
03118 int refDX, int refDY,
03119 int *atx, int *aty) {
03120 JBIG2Bitmap *bitmap;
03121 GBool ltp;
03122 Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
03123 int x, y, pix;
03124
03125 if (w < 0 || h <= 0 || w >= INT_MAX / h) {
03126 error(-1, "invalid width/height");
03127 return NULL;
03128 }
03129
03130 bitmap = new JBIG2Bitmap(0, w, h);
03131 bitmap->clearToZero();
03132
03133
03134 if (templ) {
03135 ltpCX = 0x008;
03136 } else {
03137 ltpCX = 0x0010;
03138 }
03139
03140 ltp = 0;
03141 for (y = 0; y < h; ++y) {
03142
03143
03144 if (templ) {
03145 cx0 = bitmap->getPixel(0, y-1);
03146 cx2 = 0;
03147 cx3 = (refBitmap->getPixel(-1-refDX, y-refDY) << 1) |
03148 refBitmap->getPixel(-refDX, y-refDY);
03149 cx4 = refBitmap->getPixel(-refDX, y+1-refDY);
03150 } else {
03151 cx0 = bitmap->getPixel(0, y-1);
03152 cx2 = refBitmap->getPixel(-refDX, y-1-refDY);
03153 cx3 = (refBitmap->getPixel(-1-refDX, y-refDY) << 1) |
03154 refBitmap->getPixel(-refDX, y-refDY);
03155 cx4 = (refBitmap->getPixel(-1-refDX, y+1-refDY) << 1) |
03156 refBitmap->getPixel(-refDX, y+1-refDY);
03157 }
03158
03159
03160 tpgrCX0 = tpgrCX1 = tpgrCX2 = 0;
03161 if (tpgrOn) {
03162 tpgrCX0 = (refBitmap->getPixel(-1-refDX, y-1-refDY) << 2) |
03163 (refBitmap->getPixel(-refDX, y-1-refDY) << 1) |
03164 refBitmap->getPixel(1-refDX, y-1-refDY);
03165 tpgrCX1 = (refBitmap->getPixel(-1-refDX, y-refDY) << 2) |
03166 (refBitmap->getPixel(-refDX, y-refDY) << 1) |
03167 refBitmap->getPixel(1-refDX, y-refDY);
03168 tpgrCX2 = (refBitmap->getPixel(-1-refDX, y+1-refDY) << 2) |
03169 (refBitmap->getPixel(-refDX, y+1-refDY) << 1) |
03170 refBitmap->getPixel(1-refDX, y+1-refDY);
03171 }
03172
03173 for (x = 0; x < w; ++x) {
03174
03175
03176 if (templ) {
03177 cx0 = ((cx0 << 1) | bitmap->getPixel(x+1, y-1)) & 7;
03178 cx3 = ((cx3 << 1) | refBitmap->getPixel(x+1-refDX, y-refDY)) & 7;
03179 cx4 = ((cx4 << 1) | refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 3;
03180 } else {
03181 cx0 = ((cx0 << 1) | bitmap->getPixel(x+1, y-1)) & 3;
03182 cx2 = ((cx2 << 1) | refBitmap->getPixel(x+1-refDX, y-1-refDY)) & 3;
03183 cx3 = ((cx3 << 1) | refBitmap->getPixel(x+1-refDX, y-refDY)) & 7;
03184 cx4 = ((cx4 << 1) | refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 7;
03185 }
03186
03187 if (tpgrOn) {
03188
03189 tpgrCX0 = ((tpgrCX0 << 1) |
03190 refBitmap->getPixel(x+1-refDX, y-1-refDY)) & 7;
03191 tpgrCX1 = ((tpgrCX1 << 1) |
03192 refBitmap->getPixel(x+1-refDX, y-refDY)) & 7;
03193 tpgrCX2 = ((tpgrCX2 << 1) |
03194 refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 7;
03195
03196
03197 if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
03198 ltp = !ltp;
03199 }
03200 if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
03201 bitmap->clearPixel(x, y);
03202 continue;
03203 } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
03204 bitmap->setPixel(x, y);
03205 continue;
03206 }
03207 }
03208
03209
03210 if (templ) {
03211 cx = (cx0 << 7) | (bitmap->getPixel(x-1, y) << 6) |
03212 (refBitmap->getPixel(x-refDX, y-1-refDY) << 5) |
03213 (cx3 << 2) | cx4;
03214 } else {
03215 cx = (cx0 << 11) | (bitmap->getPixel(x-1, y) << 10) |
03216 (cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
03217 (bitmap->getPixel(x+atx[0], y+aty[0]) << 1) |
03218 refBitmap->getPixel(x+atx[1]-refDX, y+aty[1]-refDY);
03219 }
03220
03221
03222 if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
03223 bitmap->setPixel(x, y);
03224 }
03225 }
03226 }
03227
03228 return bitmap;
03229 }
03230
03231 void JBIG2Stream::readPageInfoSeg(Guint ) {
03232 Guint xRes, yRes, flags, striping;
03233
03234 if (!readULong(&pageW) || !readULong(&pageH) ||
03235 !readULong(&xRes) || !readULong(&yRes) ||
03236 !readUByte(&flags) || !readUWord(&striping)) {
03237 goto eofError;
03238 }
03239 pageDefPixel = (flags >> 2) & 1;
03240 defCombOp = (flags >> 3) & 3;
03241
03242
03243 if (pageH == 0xffffffff) {
03244 curPageH = striping & 0x7fff;
03245 } else {
03246 curPageH = pageH;
03247 }
03248 pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
03249
03250
03251 if (pageDefPixel) {
03252 pageBitmap->clearToOne();
03253 } else {
03254 pageBitmap->clearToZero();
03255 }
03256
03257 return;
03258
03259 eofError:
03260 error(getPos(), "Unexpected EOF in JBIG2 stream");
03261 }
03262
03263 void JBIG2Stream::readEndOfStripeSeg(Guint length) {
03264 Guint i;
03265
03266
03267 for (i = 0; i < length; ++i) {
03268 curStr->getChar();
03269 }
03270 }
03271
03272 void JBIG2Stream::readProfilesSeg(Guint length) {
03273 Guint i;
03274
03275
03276 for (i = 0; i < length; ++i) {
03277 curStr->getChar();
03278 }
03279 }
03280
03281 void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint ) {
03282 JBIG2HuffmanTable *huffTab;
03283 Guint flags, oob, prefixBits, rangeBits;
03284 int lowVal, highVal, val;
03285 Guint huffTabSize, i;
03286
03287 if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
03288 goto eofError;
03289 }
03290 oob = flags & 1;
03291 prefixBits = (flags >> 1) & 7;
03292 rangeBits = (flags >> 4) & 7;
03293
03294 huffDecoder->reset();
03295 huffTabSize = 8;
03296 huffTab = (JBIG2HuffmanTable *)
03297 gmalloc(huffTabSize * sizeof(JBIG2HuffmanTable));
03298 i = 0;
03299 val = lowVal;
03300 while (val < highVal) {
03301 if (i == huffTabSize) {
03302 huffTabSize *= 2;
03303 huffTab = (JBIG2HuffmanTable *)
03304 grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
03305 }
03306 huffTab[i].val = val;
03307 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
03308 huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
03309 val += 1 << huffTab[i].rangeLen;
03310 ++i;
03311 }
03312 if (i + oob + 3 > huffTabSize) {
03313 huffTabSize = i + oob + 3;
03314 huffTab = (JBIG2HuffmanTable *)
03315 grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
03316 }
03317 huffTab[i].val = lowVal - 1;
03318 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
03319 huffTab[i].rangeLen = jbig2HuffmanLOW;
03320 ++i;
03321 huffTab[i].val = highVal;
03322 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
03323 huffTab[i].rangeLen = 32;
03324 ++i;
03325 if (oob) {
03326 huffTab[i].val = 0;
03327 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
03328 huffTab[i].rangeLen = jbig2HuffmanOOB;
03329 ++i;
03330 }
03331 huffTab[i].val = 0;
03332 huffTab[i].prefixLen = 0;
03333 huffTab[i].rangeLen = jbig2HuffmanEOT;
03334 ++i;
03335 huffDecoder->buildTable(huffTab, i);
03336
03337
03338 segments->append(new JBIG2CodeTable(segNum, huffTab));
03339
03340 return;
03341
03342 eofError:
03343 error(getPos(), "Unexpected EOF in JBIG2 stream");
03344 }
03345
03346 void JBIG2Stream::readExtensionSeg(Guint length) {
03347 Guint i;
03348
03349
03350 for (i = 0; i < length; ++i) {
03351 curStr->getChar();
03352 }
03353 }
03354
03355 JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
03356 JBIG2Segment *seg;
03357 int i;
03358
03359 for (i = 0; i < globalSegments->getLength(); ++i) {
03360 seg = (JBIG2Segment *)globalSegments->get(i);
03361 if (seg->getSegNum() == segNum) {
03362 return seg;
03363 }
03364 }
03365 for (i = 0; i < segments->getLength(); ++i) {
03366 seg = (JBIG2Segment *)segments->get(i);
03367 if (seg->getSegNum() == segNum) {
03368 return seg;
03369 }
03370 }
03371 return NULL;
03372 }
03373
03374 void JBIG2Stream::discardSegment(Guint segNum) {
03375 JBIG2Segment *seg;
03376 int i;
03377
03378 for (i = 0; i < globalSegments->getLength(); ++i) {
03379 seg = (JBIG2Segment *)globalSegments->get(i);
03380 if (seg->getSegNum() == segNum) {
03381 globalSegments->del(i);
03382 return;
03383 }
03384 }
03385 for (i = 0; i < segments->getLength(); ++i) {
03386 seg = (JBIG2Segment *)segments->get(i);
03387 if (seg->getSegNum() == segNum) {
03388 globalSegments->del(i);
03389 return;
03390 }
03391 }
03392 }
03393
03394 void JBIG2Stream::resetGenericStats(Guint templ,
03395 JBIG2ArithmeticDecoderStats *prevStats) {
03396 int size;
03397
03398 size = contextSize[templ];
03399 if (prevStats && prevStats->getContextSize() == size) {
03400 if (genericRegionStats->getContextSize() == size) {
03401 genericRegionStats->copyFrom(prevStats);
03402 } else {
03403 delete genericRegionStats;
03404 genericRegionStats = prevStats->copy();
03405 }
03406 } else {
03407 if (genericRegionStats->getContextSize() == size) {
03408 genericRegionStats->reset();
03409 } else {
03410 delete genericRegionStats;
03411 genericRegionStats = new JBIG2ArithmeticDecoderStats(size);
03412 }
03413 }
03414 }
03415
03416 void JBIG2Stream::resetRefinementStats(
03417 Guint templ,
03418 JBIG2ArithmeticDecoderStats *prevStats) {
03419 int size;
03420
03421 size = refContextSize[templ];
03422 if (prevStats && prevStats->getContextSize() == size) {
03423 if (refinementRegionStats->getContextSize() == size) {
03424 refinementRegionStats->copyFrom(prevStats);
03425 } else {
03426 delete refinementRegionStats;
03427 refinementRegionStats = prevStats->copy();
03428 }
03429 } else {
03430 if (refinementRegionStats->getContextSize() == size) {
03431 refinementRegionStats->reset();
03432 } else {
03433 delete refinementRegionStats;
03434 refinementRegionStats = new JBIG2ArithmeticDecoderStats(size);
03435 }
03436 }
03437 }
03438
03439 void JBIG2Stream::resetIntStats(int symCodeLen) {
03440 iadhStats->reset();
03441 iadwStats->reset();
03442 iaexStats->reset();
03443 iaaiStats->reset();
03444 iadtStats->reset();
03445 iaitStats->reset();
03446 iafsStats->reset();
03447 iadsStats->reset();
03448 iardxStats->reset();
03449 iardyStats->reset();
03450 iardwStats->reset();
03451 iardhStats->reset();
03452 iariStats->reset();
03453 if (iaidStats->getContextSize() == symCodeLen + 1) {
03454 iaidStats->reset();
03455 } else {
03456 delete iaidStats;
03457 iaidStats = new JBIG2ArithmeticDecoderStats(symCodeLen + 1);
03458 }
03459 }
03460
03461 GBool JBIG2Stream::readUByte(Guint *x) {
03462 int c0;
03463
03464 if ((c0 = curStr->getChar()) == EOF) {
03465 return gFalse;
03466 }
03467 *x = (Guint)c0;
03468 return gTrue;
03469 }
03470
03471 GBool JBIG2Stream::readByte(int *x) {
03472 int c0;
03473
03474 if ((c0 = curStr->getChar()) == EOF) {
03475 return gFalse;
03476 }
03477 *x = c0;
03478 if (c0 & 0x80) {
03479 *x |= -1 - 0xff;
03480 }
03481 return gTrue;
03482 }
03483
03484 GBool JBIG2Stream::readUWord(Guint *x) {
03485 int c0, c1;
03486
03487 if ((c0 = curStr->getChar()) == EOF ||
03488 (c1 = curStr->getChar()) == EOF) {
03489 return gFalse;
03490 }
03491 *x = (Guint)((c0 << 8) | c1);
03492 return gTrue;
03493 }
03494
03495 GBool JBIG2Stream::readULong(Guint *x) {
03496 int c0, c1, c2, c3;
03497
03498 if ((c0 = curStr->getChar()) == EOF ||
03499 (c1 = curStr->getChar()) == EOF ||
03500 (c2 = curStr->getChar()) == EOF ||
03501 (c3 = curStr->getChar()) == EOF) {
03502 return gFalse;
03503 }
03504 *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
03505 return gTrue;
03506 }
03507
03508 GBool JBIG2Stream::readLong(int *x) {
03509 int c0, c1, c2, c3;
03510
03511 if ((c0 = curStr->getChar()) == EOF ||
03512 (c1 = curStr->getChar()) == EOF ||
03513 (c2 = curStr->getChar()) == EOF ||
03514 (c3 = curStr->getChar()) == EOF) {
03515 return gFalse;
03516 }
03517 *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
03518 if (c0 & 0x80) {
03519 *x |= -1 - 0xffffffff;
03520 }
03521 return gTrue;
03522 }