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
02525 if (nRefSegs != 1) {
02526 error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
02527 return;
02528 }
02529 seg = findSegment(refSegs[0]);
02530 if (seg->getType() != jbig2SegPatternDict) {
02531 error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
02532 return;
02533 }
02534 if (gridH == 0 || gridW >= INT_MAX / gridH) {
02535 error(getPos(), "Bad size in JBIG2 halftone segment");
02536 return;
02537 }
02538 if (w == 0 || h >= INT_MAX / w) {
02539 error(getPos(), "Bad size in JBIG2 bitmap segment");
02540 return;
02541 }
02542
02543 patternDict = (JBIG2PatternDict *)seg;
02544 bpp = 0;
02545 i = 1;
02546 while (i < patternDict->getSize()) {
02547 ++bpp;
02548 i <<= 1;
02549 }
02550 patW = patternDict->getBitmap(0)->getWidth();
02551 patH = patternDict->getBitmap(0)->getHeight();
02552
02553
02554 if (!mmr) {
02555 resetGenericStats(templ, NULL);
02556 arithDecoder->start();
02557 }
02558
02559
02560 bitmap = new JBIG2Bitmap(segNum, w, h);
02561 if (flags & 0x80) {
02562 bitmap->clearToOne();
02563 } else {
02564 bitmap->clearToZero();
02565 }
02566
02567
02568 skipBitmap = NULL;
02569 if (enableSkip) {
02570 skipBitmap = new JBIG2Bitmap(0, gridW, gridH);
02571 skipBitmap->clearToZero();
02572 for (m = 0; m < gridH; ++m) {
02573 xx = gridX + m * stepY;
02574 yy = gridY + m * stepX;
02575 for (n = 0; n < gridW; ++n) {
02576 if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w ||
02577 ((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) {
02578 skipBitmap->setPixel(n, m);
02579 }
02580 }
02581 }
02582 }
02583
02584
02585 grayImg = (Guint *)gmalloc(gridW * gridH * sizeof(Guint));
02586 memset(grayImg, 0, gridW * gridH * sizeof(Guint));
02587 atx[0] = templ <= 1 ? 3 : 2; aty[0] = -1;
02588 atx[1] = -3; aty[1] = -1;
02589 atx[2] = 2; aty[2] = -2;
02590 atx[3] = -2; aty[3] = -2;
02591 for (j = bpp - 1; j >= 0; --j) {
02592 grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse,
02593 enableSkip, skipBitmap, atx, aty, -1);
02594 i = 0;
02595 for (m = 0; m < gridH; ++m) {
02596 for (n = 0; n < gridW; ++n) {
02597 bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1);
02598 grayImg[i] = (grayImg[i] << 1) | bit;
02599 ++i;
02600 }
02601 }
02602 delete grayBitmap;
02603 }
02604
02605
02606 i = 0;
02607 for (m = 0; m < gridH; ++m) {
02608 xx = gridX + m * stepY;
02609 yy = gridY + m * stepX;
02610 for (n = 0; n < gridW; ++n) {
02611 if (!(enableSkip && skipBitmap->getPixel(n, m))) {
02612 patternBitmap = patternDict->getBitmap(grayImg[i]);
02613 bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp);
02614 }
02615 xx += stepX;
02616 yy -= stepY;
02617 ++i;
02618 }
02619 }
02620
02621 gfree(grayImg);
02622
02623
02624 if (imm) {
02625 if (pageH == 0xffffffff && y + h > curPageH) {
02626 pageBitmap->expand(y + h, pageDefPixel);
02627 }
02628 pageBitmap->combine(bitmap, x, y, extCombOp);
02629 delete bitmap;
02630
02631
02632 } else {
02633 segments->append(bitmap);
02634 }
02635
02636 return;
02637
02638 eofError:
02639 error(getPos(), "Unexpected EOF in JBIG2 stream");
02640 }
02641
02642 void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
02643 GBool , Guint length) {
02644 JBIG2Bitmap *bitmap;
02645 Guint w, h, x, y, segInfoFlags, extCombOp;
02646 Guint flags, mmr, templ, tpgdOn;
02647 int atx[4], aty[4];
02648
02649
02650 if (!readULong(&w) || !readULong(&h) ||
02651 !readULong(&x) || !readULong(&y) ||
02652 !readUByte(&segInfoFlags)) {
02653 goto eofError;
02654 }
02655 extCombOp = segInfoFlags & 7;
02656
02657
02658 if (!readUByte(&flags)) {
02659 goto eofError;
02660 }
02661 mmr = flags & 1;
02662 templ = (flags >> 1) & 3;
02663 tpgdOn = (flags >> 3) & 1;
02664
02665
02666 if (!mmr) {
02667 if (templ == 0) {
02668 if (!readByte(&atx[0]) ||
02669 !readByte(&aty[0]) ||
02670 !readByte(&atx[1]) ||
02671 !readByte(&aty[1]) ||
02672 !readByte(&atx[2]) ||
02673 !readByte(&aty[2]) ||
02674 !readByte(&atx[3]) ||
02675 !readByte(&aty[3])) {
02676 goto eofError;
02677 }
02678 } else {
02679 if (!readByte(&atx[0]) ||
02680 !readByte(&aty[0])) {
02681 goto eofError;
02682 }
02683 }
02684 }
02685
02686
02687 if (!mmr) {
02688 resetGenericStats(templ, NULL);
02689 arithDecoder->start();
02690 }
02691
02692
02693 bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
02694 NULL, atx, aty, mmr ? 0 : length - 18);
02695
02696
02697 if (imm) {
02698 if (pageH == 0xffffffff && y + h > curPageH) {
02699 pageBitmap->expand(y + h, pageDefPixel);
02700 }
02701 pageBitmap->combine(bitmap, x, y, extCombOp);
02702 delete bitmap;
02703
02704
02705 } else {
02706 bitmap->setSegNum(segNum);
02707 segments->append(bitmap);
02708 }
02709
02710 return;
02711
02712 eofError:
02713 error(getPos(), "Unexpected EOF in JBIG2 stream");
02714 }
02715
02716 JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
02717 int templ, GBool tpgdOn,
02718 GBool useSkip, JBIG2Bitmap *skip,
02719 int *atx, int *aty,
02720 int mmrDataLength) {
02721 JBIG2Bitmap *bitmap;
02722 GBool ltp;
02723 Guint ltpCX, cx, cx0, cx1, cx2;
02724 int *refLine, *codingLine;
02725 int code1, code2, code3;
02726 int x, y, a0, pix, i, refI, codingI;
02727
02728 bitmap = new JBIG2Bitmap(0, w, h);
02729 bitmap->clearToZero();
02730
02731
02732
02733 if (mmr) {
02734
02735 mmrDecoder->reset();
02736 refLine = (int *)gmalloc((w + 2) * sizeof(int));
02737 codingLine = (int *)gmalloc((w + 2) * sizeof(int));
02738 codingLine[0] = codingLine[1] = w;
02739
02740 for (y = 0; y < h; ++y) {
02741
02742
02743 for (i = 0; codingLine[i] < w; ++i) {
02744 refLine[i] = codingLine[i];
02745 }
02746 refLine[i] = refLine[i + 1] = w;
02747
02748
02749 refI = 0;
02750 codingI = 0;
02751 a0 = 0;
02752 do {
02753 code1 = mmrDecoder->get2DCode();
02754 switch (code1) {
02755 case twoDimPass:
02756 if (refLine[refI] < w) {
02757 a0 = refLine[refI + 1];
02758 refI += 2;
02759 }
02760 break;
02761 case twoDimHoriz:
02762 if (codingI & 1) {
02763 code1 = 0;
02764 do {
02765 code1 += code3 = mmrDecoder->getBlackCode();
02766 } while (code3 >= 64);
02767 code2 = 0;
02768 do {
02769 code2 += code3 = mmrDecoder->getWhiteCode();
02770 } while (code3 >= 64);
02771 } else {
02772 code1 = 0;
02773 do {
02774 code1 += code3 = mmrDecoder->getWhiteCode();
02775 } while (code3 >= 64);
02776 code2 = 0;
02777 do {
02778 code2 += code3 = mmrDecoder->getBlackCode();
02779 } while (code3 >= 64);
02780 }
02781 a0 = codingLine[codingI++] = a0 + code1;
02782 a0 = codingLine[codingI++] = a0 + code2;
02783 while (refLine[refI] <= a0 && refLine[refI] < w) {
02784 refI += 2;
02785 }
02786 break;
02787 case twoDimVert0:
02788 a0 = codingLine[codingI++] = refLine[refI];
02789 if (refLine[refI] < w) {
02790 ++refI;
02791 }
02792 break;
02793 case twoDimVertR1:
02794 a0 = codingLine[codingI++] = refLine[refI] + 1;
02795 if (refLine[refI] < w) {
02796 ++refI;
02797 while (refLine[refI] <= a0 && refLine[refI] < w) {
02798 refI += 2;
02799 }
02800 }
02801 break;
02802 case twoDimVertR2:
02803 a0 = codingLine[codingI++] = refLine[refI] + 2;
02804 if (refLine[refI] < w) {
02805 ++refI;
02806 while (refLine[refI] <= a0 && refLine[refI] < w) {
02807 refI += 2;
02808 }
02809 }
02810 break;
02811 case twoDimVertR3:
02812 a0 = codingLine[codingI++] = refLine[refI] + 3;
02813 if (refLine[refI] < w) {
02814 ++refI;
02815 while (refLine[refI] <= a0 && refLine[refI] < w) {
02816 refI += 2;
02817 }
02818 }
02819 break;
02820 case twoDimVertL1:
02821 a0 = codingLine[codingI++] = refLine[refI] - 1;
02822 if (refI > 0) {
02823 --refI;
02824 } else {
02825 ++refI;
02826 }
02827 while (refLine[refI] <= a0 && refLine[refI] < w) {
02828 refI += 2;
02829 }
02830 break;
02831 case twoDimVertL2:
02832 a0 = codingLine[codingI++] = refLine[refI] - 2;
02833 if (refI > 0) {
02834 --refI;
02835 } else {
02836 ++refI;
02837 }
02838 while (refLine[refI] <= a0 && refLine[refI] < w) {
02839 refI += 2;
02840 }
02841 break;
02842 case twoDimVertL3:
02843 a0 = codingLine[codingI++] = refLine[refI] - 3;
02844 if (refI > 0) {
02845 --refI;
02846 } else {
02847 ++refI;
02848 }
02849 while (refLine[refI] <= a0 && refLine[refI] < w) {
02850 refI += 2;
02851 }
02852 break;
02853 default:
02854 error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
02855 break;
02856 }
02857 } while (a0 < w);
02858 codingLine[codingI++] = w;
02859
02860
02861 i = 0;
02862 while (codingLine[i] < w) {
02863 for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
02864 bitmap->setPixel(x, y);
02865 }
02866 i += 2;
02867 }
02868 }
02869
02870 if (mmrDataLength >= 0) {
02871 mmrDecoder->skipTo(mmrDataLength);
02872 } else {
02873 if (mmrDecoder->get24Bits() != 0x001001) {
02874 error(getPos(), "Missing EOFB in JBIG2 MMR bitmap data");
02875 }
02876 }
02877
02878 gfree(refLine);
02879 gfree(codingLine);
02880
02881
02882
02883 } else {
02884
02885 ltpCX = 0;
02886 if (tpgdOn) {
02887 switch (templ) {
02888 case 0:
02889 ltpCX = 0x3953;
02890 break;
02891 case 1:
02892 ltpCX = 0x079a;
02893 break;
02894 case 2:
02895 ltpCX = 0x0e3;
02896 break;
02897 case 3:
02898 ltpCX = 0x18a;
02899 break;
02900 }
02901 }
02902
02903 ltp = 0;
02904 cx = cx0 = cx1 = cx2 = 0;
02905 for (y = 0; y < h; ++y) {
02906
02907
02908 if (tpgdOn) {
02909 if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
02910 ltp = !ltp;
02911 }
02912 if (ltp) {
02913 bitmap->duplicateRow(y, y-1);
02914 continue;
02915 }
02916 }
02917
02918
02919 switch (templ) {
02920 case 0:
02921 cx0 = (bitmap->getPixel(0, y-2) << 1) |
02922 bitmap->getPixel(1, y-2);
02923 cx1 = (bitmap->getPixel(0, y-1) << 2) |
02924 (bitmap->getPixel(1, y-1) << 1) |
02925 bitmap->getPixel(2, y-1);
02926 cx2 = 0;
02927 break;
02928 case 1:
02929 cx0 = (bitmap->getPixel(0, y-2) << 2) |
02930 (bitmap->getPixel(1, y-2) << 1) |
02931 bitmap->getPixel(2, 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 2:
02938 cx0 = (bitmap->getPixel(0, y-2) << 1) |
02939 bitmap->getPixel(1, y-2);
02940 cx1 = (bitmap->getPixel(0, y-1) << 1) |
02941 bitmap->getPixel(1, y-1);
02942 cx2 = 0;
02943 break;
02944 case 3:
02945 cx1 = (bitmap->getPixel(0, y-1) << 1) |
02946 bitmap->getPixel(1, y-1);
02947 cx2 = 0;
02948 break;
02949 }
02950
02951
02952 for (x = 0; x < w; ++x) {
02953
02954
02955 if (useSkip && skip->getPixel(x, y)) {
02956 pix = 0;
02957
02958 } else {
02959
02960
02961 switch (templ) {
02962 case 0:
02963 cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
02964 (bitmap->getPixel(x + atx[0], y + aty[0]) << 3) |
02965 (bitmap->getPixel(x + atx[1], y + aty[1]) << 2) |
02966 (bitmap->getPixel(x + atx[2], y + aty[2]) << 1) |
02967 bitmap->getPixel(x + atx[3], y + aty[3]);
02968 break;
02969 case 1:
02970 cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
02971 bitmap->getPixel(x + atx[0], y + aty[0]);
02972 break;
02973 case 2:
02974 cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
02975 bitmap->getPixel(x + atx[0], y + aty[0]);
02976 break;
02977 case 3:
02978 cx = (cx1 << 5) | (cx2 << 1) |
02979 bitmap->getPixel(x + atx[0], y + aty[0]);
02980 break;
02981 }
02982
02983
02984 if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
02985 bitmap->setPixel(x, y);
02986 }
02987 }
02988
02989
02990 switch (templ) {
02991 case 0:
02992 cx0 = ((cx0 << 1) | bitmap->getPixel(x+2, y-2)) & 0x07;
02993 cx1 = ((cx1 << 1) | bitmap->getPixel(x+3, y-1)) & 0x1f;
02994 cx2 = ((cx2 << 1) | pix) & 0x0f;
02995 break;
02996 case 1:
02997 cx0 = ((cx0 << 1) | bitmap->getPixel(x+3, y-2)) & 0x0f;
02998 cx1 = ((cx1 << 1) | bitmap->getPixel(x+3, y-1)) & 0x1f;
02999 cx2 = ((cx2 << 1) | pix) & 0x07;
03000 break;
03001 case 2:
03002 cx0 = ((cx0 << 1) | bitmap->getPixel(x+2, y-2)) & 0x07;
03003 cx1 = ((cx1 << 1) | bitmap->getPixel(x+2, y-1)) & 0x0f;
03004 cx2 = ((cx2 << 1) | pix) & 0x03;
03005 break;
03006 case 3:
03007 cx1 = ((cx1 << 1) | bitmap->getPixel(x+2, y-1)) & 0x1f;
03008 cx2 = ((cx2 << 1) | pix) & 0x0f;
03009 break;
03010 }
03011 }
03012 }
03013 }
03014
03015 return bitmap;
03016 }
03017
03018 void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
03019 GBool , Guint ,
03020 Guint *refSegs,
03021 Guint nRefSegs) {
03022 JBIG2Bitmap *bitmap, *refBitmap;
03023 Guint w, h, x, y, segInfoFlags, extCombOp;
03024 Guint flags, templ, tpgrOn;
03025 int atx[2], aty[2];
03026 JBIG2Segment *seg;
03027
03028
03029 if (!readULong(&w) || !readULong(&h) ||
03030 !readULong(&x) || !readULong(&y) ||
03031 !readUByte(&segInfoFlags)) {
03032 goto eofError;
03033 }
03034 extCombOp = segInfoFlags & 7;
03035
03036
03037 if (!readUByte(&flags)) {
03038 goto eofError;
03039 }
03040 templ = flags & 1;
03041 tpgrOn = (flags >> 1) & 1;
03042
03043
03044 if (!templ) {
03045 if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
03046 !readByte(&atx[1]) || !readByte(&aty[1])) {
03047 goto eofError;
03048 }
03049 }
03050
03051
03052 if (nRefSegs == 0 || imm) {
03053 if (pageH == 0xffffffff && y + h > curPageH) {
03054 pageBitmap->expand(y + h, pageDefPixel);
03055 }
03056 }
03057
03058
03059 if (nRefSegs > 1) {
03060 error(getPos(), "Bad reference in JBIG2 generic refinement segment");
03061 return;
03062 }
03063 if (nRefSegs == 1) {
03064 seg = findSegment(refSegs[0]);
03065 if (seg->getType() != jbig2SegBitmap) {
03066 error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
03067 return;
03068 }
03069 refBitmap = (JBIG2Bitmap *)seg;
03070 } else {
03071 refBitmap = pageBitmap->getSlice(x, y, w, h);
03072 }
03073
03074
03075 resetRefinementStats(templ, NULL);
03076 arithDecoder->start();
03077
03078
03079 bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
03080 refBitmap, 0, 0, atx, aty);
03081
03082
03083 if (imm) {
03084 pageBitmap->combine(bitmap, x, y, extCombOp);
03085 delete bitmap;
03086
03087
03088 } else {
03089 bitmap->setSegNum(segNum);
03090 segments->append(bitmap);
03091 }
03092
03093
03094 if (nRefSegs == 1) {
03095 discardSegment(refSegs[0]);
03096 } else {
03097 delete refBitmap;
03098 }
03099
03100 return;
03101
03102 eofError:
03103 error(getPos(), "Unexpected EOF in JBIG2 stream");
03104 }
03105
03106 JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
03107 int templ, GBool tpgrOn,
03108 JBIG2Bitmap *refBitmap,
03109 int refDX, int refDY,
03110 int *atx, int *aty) {
03111 JBIG2Bitmap *bitmap;
03112 GBool ltp;
03113 Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
03114 int x, y, pix;
03115
03116 if (w < 0 || h <= 0 || w >= INT_MAX / h) {
03117 error(-1, "invalid width/height");
03118 return NULL;
03119 }
03120
03121 bitmap = new JBIG2Bitmap(0, w, h);
03122 bitmap->clearToZero();
03123
03124
03125 if (templ) {
03126 ltpCX = 0x008;
03127 } else {
03128 ltpCX = 0x0010;
03129 }
03130
03131 ltp = 0;
03132 for (y = 0; y < h; ++y) {
03133
03134
03135 if (templ) {
03136 cx0 = bitmap->getPixel(0, y-1);
03137 cx2 = 0;
03138 cx3 = (refBitmap->getPixel(-1-refDX, y-refDY) << 1) |
03139 refBitmap->getPixel(-refDX, y-refDY);
03140 cx4 = refBitmap->getPixel(-refDX, y+1-refDY);
03141 } else {
03142 cx0 = bitmap->getPixel(0, y-1);
03143 cx2 = refBitmap->getPixel(-refDX, y-1-refDY);
03144 cx3 = (refBitmap->getPixel(-1-refDX, y-refDY) << 1) |
03145 refBitmap->getPixel(-refDX, y-refDY);
03146 cx4 = (refBitmap->getPixel(-1-refDX, y+1-refDY) << 1) |
03147 refBitmap->getPixel(-refDX, y+1-refDY);
03148 }
03149
03150
03151 tpgrCX0 = tpgrCX1 = tpgrCX2 = 0;
03152 if (tpgrOn) {
03153 tpgrCX0 = (refBitmap->getPixel(-1-refDX, y-1-refDY) << 2) |
03154 (refBitmap->getPixel(-refDX, y-1-refDY) << 1) |
03155 refBitmap->getPixel(1-refDX, y-1-refDY);
03156 tpgrCX1 = (refBitmap->getPixel(-1-refDX, y-refDY) << 2) |
03157 (refBitmap->getPixel(-refDX, y-refDY) << 1) |
03158 refBitmap->getPixel(1-refDX, y-refDY);
03159 tpgrCX2 = (refBitmap->getPixel(-1-refDX, y+1-refDY) << 2) |
03160 (refBitmap->getPixel(-refDX, y+1-refDY) << 1) |
03161 refBitmap->getPixel(1-refDX, y+1-refDY);
03162 }
03163
03164 for (x = 0; x < w; ++x) {
03165
03166
03167 if (templ) {
03168 cx0 = ((cx0 << 1) | bitmap->getPixel(x+1, y-1)) & 7;
03169 cx3 = ((cx3 << 1) | refBitmap->getPixel(x+1-refDX, y-refDY)) & 7;
03170 cx4 = ((cx4 << 1) | refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 3;
03171 } else {
03172 cx0 = ((cx0 << 1) | bitmap->getPixel(x+1, y-1)) & 3;
03173 cx2 = ((cx2 << 1) | refBitmap->getPixel(x+1-refDX, y-1-refDY)) & 3;
03174 cx3 = ((cx3 << 1) | refBitmap->getPixel(x+1-refDX, y-refDY)) & 7;
03175 cx4 = ((cx4 << 1) | refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 7;
03176 }
03177
03178 if (tpgrOn) {
03179
03180 tpgrCX0 = ((tpgrCX0 << 1) |
03181 refBitmap->getPixel(x+1-refDX, y-1-refDY)) & 7;
03182 tpgrCX1 = ((tpgrCX1 << 1) |
03183 refBitmap->getPixel(x+1-refDX, y-refDY)) & 7;
03184 tpgrCX2 = ((tpgrCX2 << 1) |
03185 refBitmap->getPixel(x+1-refDX, y+1-refDY)) & 7;
03186
03187
03188 if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
03189 ltp = !ltp;
03190 }
03191 if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
03192 bitmap->clearPixel(x, y);
03193 continue;
03194 } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
03195 bitmap->setPixel(x, y);
03196 continue;
03197 }
03198 }
03199
03200
03201 if (templ) {
03202 cx = (cx0 << 7) | (bitmap->getPixel(x-1, y) << 6) |
03203 (refBitmap->getPixel(x-refDX, y-1-refDY) << 5) |
03204 (cx3 << 2) | cx4;
03205 } else {
03206 cx = (cx0 << 11) | (bitmap->getPixel(x-1, y) << 10) |
03207 (cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
03208 (bitmap->getPixel(x+atx[0], y+aty[0]) << 1) |
03209 refBitmap->getPixel(x+atx[1]-refDX, y+aty[1]-refDY);
03210 }
03211
03212
03213 if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
03214 bitmap->setPixel(x, y);
03215 }
03216 }
03217 }
03218
03219 return bitmap;
03220 }
03221
03222 void JBIG2Stream::readPageInfoSeg(Guint ) {
03223 Guint xRes, yRes, flags, striping;
03224
03225 if (!readULong(&pageW) || !readULong(&pageH) ||
03226 !readULong(&xRes) || !readULong(&yRes) ||
03227 !readUByte(&flags) || !readUWord(&striping)) {
03228 goto eofError;
03229 }
03230 pageDefPixel = (flags >> 2) & 1;
03231 defCombOp = (flags >> 3) & 3;
03232
03233
03234 if (pageH == 0xffffffff) {
03235 curPageH = striping & 0x7fff;
03236 } else {
03237 curPageH = pageH;
03238 }
03239 pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
03240
03241
03242 if (pageDefPixel) {
03243 pageBitmap->clearToOne();
03244 } else {
03245 pageBitmap->clearToZero();
03246 }
03247
03248 return;
03249
03250 eofError:
03251 error(getPos(), "Unexpected EOF in JBIG2 stream");
03252 }
03253
03254 void JBIG2Stream::readEndOfStripeSeg(Guint length) {
03255 Guint i;
03256
03257
03258 for (i = 0; i < length; ++i) {
03259 curStr->getChar();
03260 }
03261 }
03262
03263 void JBIG2Stream::readProfilesSeg(Guint length) {
03264 Guint i;
03265
03266
03267 for (i = 0; i < length; ++i) {
03268 curStr->getChar();
03269 }
03270 }
03271
03272 void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint ) {
03273 JBIG2HuffmanTable *huffTab;
03274 Guint flags, oob, prefixBits, rangeBits;
03275 int lowVal, highVal, val;
03276 Guint huffTabSize, i;
03277
03278 if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
03279 goto eofError;
03280 }
03281 oob = flags & 1;
03282 prefixBits = (flags >> 1) & 7;
03283 rangeBits = (flags >> 4) & 7;
03284
03285 huffDecoder->reset();
03286 huffTabSize = 8;
03287 huffTab = (JBIG2HuffmanTable *)
03288 gmalloc(huffTabSize * sizeof(JBIG2HuffmanTable));
03289 i = 0;
03290 val = lowVal;
03291 while (val < highVal) {
03292 if (i == huffTabSize) {
03293 huffTabSize *= 2;
03294 huffTab = (JBIG2HuffmanTable *)
03295 grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
03296 }
03297 huffTab[i].val = val;
03298 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
03299 huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
03300 val += 1 << huffTab[i].rangeLen;
03301 ++i;
03302 }
03303 if (i + oob + 3 > huffTabSize) {
03304 huffTabSize = i + oob + 3;
03305 huffTab = (JBIG2HuffmanTable *)
03306 grealloc(huffTab, huffTabSize * sizeof(JBIG2HuffmanTable));
03307 }
03308 huffTab[i].val = lowVal - 1;
03309 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
03310 huffTab[i].rangeLen = jbig2HuffmanLOW;
03311 ++i;
03312 huffTab[i].val = highVal;
03313 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
03314 huffTab[i].rangeLen = 32;
03315 ++i;
03316 if (oob) {
03317 huffTab[i].val = 0;
03318 huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
03319 huffTab[i].rangeLen = jbig2HuffmanOOB;
03320 ++i;
03321 }
03322 huffTab[i].val = 0;
03323 huffTab[i].prefixLen = 0;
03324 huffTab[i].rangeLen = jbig2HuffmanEOT;
03325 ++i;
03326 huffDecoder->buildTable(huffTab, i);
03327
03328
03329 segments->append(new JBIG2CodeTable(segNum, huffTab));
03330
03331 return;
03332
03333 eofError:
03334 error(getPos(), "Unexpected EOF in JBIG2 stream");
03335 }
03336
03337 void JBIG2Stream::readExtensionSeg(Guint length) {
03338 Guint i;
03339
03340
03341 for (i = 0; i < length; ++i) {
03342 curStr->getChar();
03343 }
03344 }
03345
03346 JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
03347 JBIG2Segment *seg;
03348 int i;
03349
03350 for (i = 0; i < globalSegments->getLength(); ++i) {
03351 seg = (JBIG2Segment *)globalSegments->get(i);
03352 if (seg->getSegNum() == segNum) {
03353 return seg;
03354 }
03355 }
03356 for (i = 0; i < segments->getLength(); ++i) {
03357 seg = (JBIG2Segment *)segments->get(i);
03358 if (seg->getSegNum() == segNum) {
03359 return seg;
03360 }
03361 }
03362 return NULL;
03363 }
03364
03365 void JBIG2Stream::discardSegment(Guint segNum) {
03366 JBIG2Segment *seg;
03367 int i;
03368
03369 for (i = 0; i < globalSegments->getLength(); ++i) {
03370 seg = (JBIG2Segment *)globalSegments->get(i);
03371 if (seg->getSegNum() == segNum) {
03372 globalSegments->del(i);
03373 return;
03374 }
03375 }
03376 for (i = 0; i < segments->getLength(); ++i) {
03377 seg = (JBIG2Segment *)segments->get(i);
03378 if (seg->getSegNum() == segNum) {
03379 globalSegments->del(i);
03380 return;
03381 }
03382 }
03383 }
03384
03385 void JBIG2Stream::resetGenericStats(Guint templ,
03386 JBIG2ArithmeticDecoderStats *prevStats) {
03387 int size;
03388
03389 size = contextSize[templ];
03390 if (prevStats && prevStats->getContextSize() == size) {
03391 if (genericRegionStats->getContextSize() == size) {
03392 genericRegionStats->copyFrom(prevStats);
03393 } else {
03394 delete genericRegionStats;
03395 genericRegionStats = prevStats->copy();
03396 }
03397 } else {
03398 if (genericRegionStats->getContextSize() == size) {
03399 genericRegionStats->reset();
03400 } else {
03401 delete genericRegionStats;
03402 genericRegionStats = new JBIG2ArithmeticDecoderStats(size);
03403 }
03404 }
03405 }
03406
03407 void JBIG2Stream::resetRefinementStats(
03408 Guint templ,
03409 JBIG2ArithmeticDecoderStats *prevStats) {
03410 int size;
03411
03412 size = refContextSize[templ];
03413 if (prevStats && prevStats->getContextSize() == size) {
03414 if (refinementRegionStats->getContextSize() == size) {
03415 refinementRegionStats->copyFrom(prevStats);
03416 } else {
03417 delete refinementRegionStats;
03418 refinementRegionStats = prevStats->copy();
03419 }
03420 } else {
03421 if (refinementRegionStats->getContextSize() == size) {
03422 refinementRegionStats->reset();
03423 } else {
03424 delete refinementRegionStats;
03425 refinementRegionStats = new JBIG2ArithmeticDecoderStats(size);
03426 }
03427 }
03428 }
03429
03430 void JBIG2Stream::resetIntStats(int symCodeLen) {
03431 iadhStats->reset();
03432 iadwStats->reset();
03433 iaexStats->reset();
03434 iaaiStats->reset();
03435 iadtStats->reset();
03436 iaitStats->reset();
03437 iafsStats->reset();
03438 iadsStats->reset();
03439 iardxStats->reset();
03440 iardyStats->reset();
03441 iardwStats->reset();
03442 iardhStats->reset();
03443 iariStats->reset();
03444 if (iaidStats->getContextSize() == symCodeLen + 1) {
03445 iaidStats->reset();
03446 } else {
03447 delete iaidStats;
03448 iaidStats = new JBIG2ArithmeticDecoderStats(symCodeLen + 1);
03449 }
03450 }
03451
03452 GBool JBIG2Stream::readUByte(Guint *x) {
03453 int c0;
03454
03455 if ((c0 = curStr->getChar()) == EOF) {
03456 return gFalse;
03457 }
03458 *x = (Guint)c0;
03459 return gTrue;
03460 }
03461
03462 GBool JBIG2Stream::readByte(int *x) {
03463 int c0;
03464
03465 if ((c0 = curStr->getChar()) == EOF) {
03466 return gFalse;
03467 }
03468 *x = c0;
03469 if (c0 & 0x80) {
03470 *x |= -1 - 0xff;
03471 }
03472 return gTrue;
03473 }
03474
03475 GBool JBIG2Stream::readUWord(Guint *x) {
03476 int c0, c1;
03477
03478 if ((c0 = curStr->getChar()) == EOF ||
03479 (c1 = curStr->getChar()) == EOF) {
03480 return gFalse;
03481 }
03482 *x = (Guint)((c0 << 8) | c1);
03483 return gTrue;
03484 }
03485
03486 GBool JBIG2Stream::readULong(Guint *x) {
03487 int c0, c1, c2, c3;
03488
03489 if ((c0 = curStr->getChar()) == EOF ||
03490 (c1 = curStr->getChar()) == EOF ||
03491 (c2 = curStr->getChar()) == EOF ||
03492 (c3 = curStr->getChar()) == EOF) {
03493 return gFalse;
03494 }
03495 *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
03496 return gTrue;
03497 }
03498
03499 GBool JBIG2Stream::readLong(int *x) {
03500 int c0, c1, c2, c3;
03501
03502 if ((c0 = curStr->getChar()) == EOF ||
03503 (c1 = curStr->getChar()) == EOF ||
03504 (c2 = curStr->getChar()) == EOF ||
03505 (c3 = curStr->getChar()) == EOF) {
03506 return gFalse;
03507 }
03508 *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
03509 if (c0 & 0x80) {
03510 *x |= -1 - 0xffffffff;
03511 }
03512 return gTrue;
03513 }