Coverage Report

Created: 2026-06-22 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xpdf-4.06/xpdf/JBIG2Stream.cc
Line
Count
Source
1
//========================================================================
2
//
3
// JBIG2Stream.cc
4
//
5
// Copyright 2002-2003 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
#include <aconf.h>
10
11
#include <stdlib.h>
12
#include <limits.h>
13
#include "gmempp.h"
14
#include "GList.h"
15
#include "Error.h"
16
#include "JArithmeticDecoder.h"
17
#include "JBIG2Stream.h"
18
19
//~ share these tables
20
#include "Stream-CCITT.h"
21
22
//------------------------------------------------------------------------
23
24
static int contextSize[4] = { 16, 13, 10, 10 };
25
static int refContextSize[2] = { 13, 10 };
26
27
//------------------------------------------------------------------------
28
// JBIG2HuffmanTable
29
//------------------------------------------------------------------------
30
31
257k
#define jbig2HuffmanLOW 0xfffffffd
32
282k
#define jbig2HuffmanOOB 0xfffffffe
33
967k
#define jbig2HuffmanEOT 0xffffffff
34
35
struct JBIG2HuffmanTable {
36
  int val;
37
  Guint prefixLen;
38
  Guint rangeLen;   // can also be LOW, OOB, or EOT
39
  Guint prefix;
40
};
41
42
JBIG2HuffmanTable huffTableA[] = {
43
  {     0, 1,  4,              0x000 },
44
  {    16, 2,  8,              0x002 },
45
  {   272, 3, 16,              0x006 },
46
  { 65808, 3, 32,              0x007 },
47
  {     0, 0, jbig2HuffmanEOT, 0     }
48
};
49
50
JBIG2HuffmanTable huffTableB[] = {
51
  {     0, 1,  0,              0x000 },
52
  {     1, 2,  0,              0x002 },
53
  {     2, 3,  0,              0x006 },
54
  {     3, 4,  3,              0x00e },
55
  {    11, 5,  6,              0x01e },
56
  {    75, 6, 32,              0x03e },
57
  {     0, 6, jbig2HuffmanOOB, 0x03f },
58
  {     0, 0, jbig2HuffmanEOT, 0     }
59
};
60
61
JBIG2HuffmanTable huffTableC[] = {
62
  {     0, 1,  0,              0x000 },
63
  {     1, 2,  0,              0x002 },
64
  {     2, 3,  0,              0x006 },
65
  {     3, 4,  3,              0x00e },
66
  {    11, 5,  6,              0x01e },
67
  {     0, 6, jbig2HuffmanOOB, 0x03e },
68
  {    75, 7, 32,              0x0fe },
69
  {  -256, 8,  8,              0x0fe },
70
  {  -257, 8, jbig2HuffmanLOW, 0x0ff },
71
  {     0, 0, jbig2HuffmanEOT, 0     }
72
};
73
74
JBIG2HuffmanTable huffTableD[] = {
75
  {     1, 1,  0,              0x000 },
76
  {     2, 2,  0,              0x002 },
77
  {     3, 3,  0,              0x006 },
78
  {     4, 4,  3,              0x00e },
79
  {    12, 5,  6,              0x01e },
80
  {    76, 5, 32,              0x01f },
81
  {     0, 0, jbig2HuffmanEOT, 0     }
82
};
83
84
JBIG2HuffmanTable huffTableE[] = {
85
  {     1, 1,  0,              0x000 },
86
  {     2, 2,  0,              0x002 },
87
  {     3, 3,  0,              0x006 },
88
  {     4, 4,  3,              0x00e },
89
  {    12, 5,  6,              0x01e },
90
  {    76, 6, 32,              0x03e },
91
  {  -255, 7,  8,              0x07e },
92
  {  -256, 7, jbig2HuffmanLOW, 0x07f },
93
  {     0, 0, jbig2HuffmanEOT, 0     }
94
};
95
96
JBIG2HuffmanTable huffTableF[] = {
97
  {     0, 2,  7,              0x000 },
98
  {   128, 3,  7,              0x002 },
99
  {   256, 3,  8,              0x003 },
100
  { -1024, 4,  9,              0x008 },
101
  {  -512, 4,  8,              0x009 },
102
  {  -256, 4,  7,              0x00a },
103
  {   -32, 4,  5,              0x00b },
104
  {   512, 4,  9,              0x00c },
105
  {  1024, 4, 10,              0x00d },
106
  { -2048, 5, 10,              0x01c },
107
  {  -128, 5,  6,              0x01d },
108
  {   -64, 5,  5,              0x01e },
109
  { -2049, 6, jbig2HuffmanLOW, 0x03e },
110
  {  2048, 6, 32,              0x03f },
111
  {     0, 0, jbig2HuffmanEOT, 0     }
112
};
113
114
JBIG2HuffmanTable huffTableG[] = {
115
  {  -512, 3,  8,              0x000 },
116
  {   256, 3,  8,              0x001 },
117
  {   512, 3,  9,              0x002 },
118
  {  1024, 3, 10,              0x003 },
119
  { -1024, 4,  9,              0x008 },
120
  {  -256, 4,  7,              0x009 },
121
  {   -32, 4,  5,              0x00a },
122
  {     0, 4,  5,              0x00b },
123
  {   128, 4,  7,              0x00c },
124
  {  -128, 5,  6,              0x01a },
125
  {   -64, 5,  5,              0x01b },
126
  {    32, 5,  5,              0x01c },
127
  {    64, 5,  6,              0x01d },
128
  { -1025, 5, jbig2HuffmanLOW, 0x01e },
129
  {  2048, 5, 32,              0x01f },
130
  {     0, 0, jbig2HuffmanEOT, 0     }
131
};
132
133
JBIG2HuffmanTable huffTableH[] = {
134
  {     0, 2,  1,              0x000 },
135
  {     0, 2, jbig2HuffmanOOB, 0x001 },
136
  {     4, 3,  4,              0x004 },
137
  {    -1, 4,  0,              0x00a },
138
  {    22, 4,  4,              0x00b },
139
  {    38, 4,  5,              0x00c },
140
  {     2, 5,  0,              0x01a },
141
  {    70, 5,  6,              0x01b },
142
  {   134, 5,  7,              0x01c },
143
  {     3, 6,  0,              0x03a },
144
  {    20, 6,  1,              0x03b },
145
  {   262, 6,  7,              0x03c },
146
  {   646, 6, 10,              0x03d },
147
  {    -2, 7,  0,              0x07c },
148
  {   390, 7,  8,              0x07d },
149
  {   -15, 8,  3,              0x0fc },
150
  {    -5, 8,  1,              0x0fd },
151
  {    -7, 9,  1,              0x1fc },
152
  {    -3, 9,  0,              0x1fd },
153
  {   -16, 9, jbig2HuffmanLOW, 0x1fe },
154
  {  1670, 9, 32,              0x1ff },
155
  {     0, 0, jbig2HuffmanEOT, 0     }
156
};
157
158
JBIG2HuffmanTable huffTableI[] = {
159
  {     0, 2, jbig2HuffmanOOB, 0x000 },
160
  {    -1, 3,  1,              0x002 },
161
  {     1, 3,  1,              0x003 },
162
  {     7, 3,  5,              0x004 },
163
  {    -3, 4,  1,              0x00a },
164
  {    43, 4,  5,              0x00b },
165
  {    75, 4,  6,              0x00c },
166
  {     3, 5,  1,              0x01a },
167
  {   139, 5,  7,              0x01b },
168
  {   267, 5,  8,              0x01c },
169
  {     5, 6,  1,              0x03a },
170
  {    39, 6,  2,              0x03b },
171
  {   523, 6,  8,              0x03c },
172
  {  1291, 6, 11,              0x03d },
173
  {    -5, 7,  1,              0x07c },
174
  {   779, 7,  9,              0x07d },
175
  {   -31, 8,  4,              0x0fc },
176
  {   -11, 8,  2,              0x0fd },
177
  {   -15, 9,  2,              0x1fc },
178
  {    -7, 9,  1,              0x1fd },
179
  {   -32, 9, jbig2HuffmanLOW, 0x1fe },
180
  {  3339, 9, 32,              0x1ff },
181
  {     0, 0, jbig2HuffmanEOT, 0     }
182
};
183
184
JBIG2HuffmanTable huffTableJ[] = {
185
  {    -2, 2,  2,              0x000 },
186
  {     6, 2,  6,              0x001 },
187
  {     0, 2, jbig2HuffmanOOB, 0x002 },
188
  {    -3, 5,  0,              0x018 },
189
  {     2, 5,  0,              0x019 },
190
  {    70, 5,  5,              0x01a },
191
  {     3, 6,  0,              0x036 },
192
  {   102, 6,  5,              0x037 },
193
  {   134, 6,  6,              0x038 },
194
  {   198, 6,  7,              0x039 },
195
  {   326, 6,  8,              0x03a },
196
  {   582, 6,  9,              0x03b },
197
  {  1094, 6, 10,              0x03c },
198
  {   -21, 7,  4,              0x07a },
199
  {    -4, 7,  0,              0x07b },
200
  {     4, 7,  0,              0x07c },
201
  {  2118, 7, 11,              0x07d },
202
  {    -5, 8,  0,              0x0fc },
203
  {     5, 8,  0,              0x0fd },
204
  {   -22, 8, jbig2HuffmanLOW, 0x0fe },
205
  {  4166, 8, 32,              0x0ff },
206
  {     0, 0, jbig2HuffmanEOT, 0     }
207
};
208
209
JBIG2HuffmanTable huffTableK[] = {
210
  {     1, 1,  0,              0x000 },
211
  {     2, 2,  1,              0x002 },
212
  {     4, 4,  0,              0x00c },
213
  {     5, 4,  1,              0x00d },
214
  {     7, 5,  1,              0x01c },
215
  {     9, 5,  2,              0x01d },
216
  {    13, 6,  2,              0x03c },
217
  {    17, 7,  2,              0x07a },
218
  {    21, 7,  3,              0x07b },
219
  {    29, 7,  4,              0x07c },
220
  {    45, 7,  5,              0x07d },
221
  {    77, 7,  6,              0x07e },
222
  {   141, 7, 32,              0x07f },
223
  {     0, 0, jbig2HuffmanEOT, 0     }
224
};
225
226
JBIG2HuffmanTable huffTableL[] = {
227
  {     1, 1,  0,              0x000 },
228
  {     2, 2,  0,              0x002 },
229
  {     3, 3,  1,              0x006 },
230
  {     5, 5,  0,              0x01c },
231
  {     6, 5,  1,              0x01d },
232
  {     8, 6,  1,              0x03c },
233
  {    10, 7,  0,              0x07a },
234
  {    11, 7,  1,              0x07b },
235
  {    13, 7,  2,              0x07c },
236
  {    17, 7,  3,              0x07d },
237
  {    25, 7,  4,              0x07e },
238
  {    41, 8,  5,              0x0fe },
239
  {    73, 8, 32,              0x0ff },
240
  {     0, 0, jbig2HuffmanEOT, 0     }
241
};
242
243
JBIG2HuffmanTable huffTableM[] = {
244
  {     1, 1,  0,              0x000 },
245
  {     2, 3,  0,              0x004 },
246
  {     7, 3,  3,              0x005 },
247
  {     3, 4,  0,              0x00c },
248
  {     5, 4,  1,              0x00d },
249
  {     4, 5,  0,              0x01c },
250
  {    15, 6,  1,              0x03a },
251
  {    17, 6,  2,              0x03b },
252
  {    21, 6,  3,              0x03c },
253
  {    29, 6,  4,              0x03d },
254
  {    45, 6,  5,              0x03e },
255
  {    77, 7,  6,              0x07e },
256
  {   141, 7, 32,              0x07f },
257
  {     0, 0, jbig2HuffmanEOT, 0     }
258
};
259
260
JBIG2HuffmanTable huffTableN[] = {
261
  {     0, 1,  0,              0x000 },
262
  {    -2, 3,  0,              0x004 },
263
  {    -1, 3,  0,              0x005 },
264
  {     1, 3,  0,              0x006 },
265
  {     2, 3,  0,              0x007 },
266
  {     0, 0, jbig2HuffmanEOT, 0     }
267
};
268
269
JBIG2HuffmanTable huffTableO[] = {
270
  {     0, 1,  0,              0x000 },
271
  {    -1, 3,  0,              0x004 },
272
  {     1, 3,  0,              0x005 },
273
  {    -2, 4,  0,              0x00c },
274
  {     2, 4,  0,              0x00d },
275
  {    -4, 5,  1,              0x01c },
276
  {     3, 5,  1,              0x01d },
277
  {    -8, 6,  2,              0x03c },
278
  {     5, 6,  2,              0x03d },
279
  {   -24, 7,  4,              0x07c },
280
  {     9, 7,  4,              0x07d },
281
  {   -25, 7, jbig2HuffmanLOW, 0x07e },
282
  {    25, 7, 32,              0x07f },
283
  {     0, 0, jbig2HuffmanEOT, 0     }
284
};
285
286
//------------------------------------------------------------------------
287
// JBIG2HuffmanDecoder
288
//------------------------------------------------------------------------
289
290
class JBIG2HuffmanDecoder {
291
public:
292
293
  JBIG2HuffmanDecoder();
294
  ~JBIG2HuffmanDecoder();
295
83.9k
  void setStream(Stream *strA) { str = strA; }
296
297
  void reset();
298
299
  // Returns false for OOB, otherwise sets *<x> and returns true.
300
  GBool decodeInt(int *x, JBIG2HuffmanTable *table);
301
302
  Guint readBits(Guint n);
303
  Guint readBit();
304
305
  // Sort the table by prefix length and assign prefix values.
306
  void buildTable(JBIG2HuffmanTable *table, Guint len);
307
308
185k
  void resetByteCounter() { byteCounter = 0; }
309
169k
  Guint getByteCounter() { return byteCounter; }
310
311
private:
312
313
  Stream *str;
314
  Guint buf;
315
  Guint bufLen;
316
  Guint byteCounter;
317
};
318
319
299k
JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
320
299k
  str = NULL;
321
299k
  byteCounter = 0;
322
299k
  reset();
323
299k
}
324
325
299k
JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {
326
299k
}
327
328
314k
void JBIG2HuffmanDecoder::reset() {
329
314k
  buf = 0;
330
314k
  bufLen = 0;
331
314k
}
332
333
//~ optimize this
334
285k
GBool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) {
335
285k
  Guint i, len, prefix;
336
337
285k
  i = 0;
338
285k
  len = 0;
339
285k
  prefix = 0;
340
822k
  while (table[i].rangeLen != jbig2HuffmanEOT) {
341
1.61M
    while (len < table[i].prefixLen) {
342
792k
      prefix = (prefix << 1) | readBit();
343
792k
      ++len;
344
792k
    }
345
818k
    if (prefix == table[i].prefix) {
346
281k
      if (table[i].rangeLen == jbig2HuffmanOOB) {
347
28.0k
  return gFalse;
348
28.0k
      }
349
253k
      if (table[i].rangeLen == jbig2HuffmanLOW) {
350
372
  *x = table[i].val - readBits(32);
351
252k
      } else if (table[i].rangeLen > 0) {
352
138k
  *x = table[i].val + readBits(table[i].rangeLen);
353
138k
      } else {
354
114k
  *x = table[i].val;
355
114k
      }
356
253k
      return gTrue;
357
281k
    }
358
537k
    ++i;
359
537k
  }
360
4.64k
  return gFalse;
361
285k
}
362
363
517k
Guint JBIG2HuffmanDecoder::readBits(Guint n) {
364
517k
  Guint x, mask, nLeft;
365
366
517k
  mask = (n == 32) ? 0xffffffff : ((1 << n) - 1);
367
517k
  if (bufLen >= n) {
368
227k
    x = (buf >> (bufLen - n)) & mask;
369
227k
    bufLen -= n;
370
290k
  } else {
371
290k
    x = buf & ((1 << bufLen) - 1);
372
290k
    nLeft = n - bufLen;
373
290k
    bufLen = 0;
374
333k
    while (nLeft >= 8) {
375
42.6k
      x = (x << 8) | (str->getChar() & 0xff);
376
42.6k
      ++byteCounter;
377
42.6k
      nLeft -= 8;
378
42.6k
    }
379
290k
    if (nLeft > 0) {
380
279k
      buf = str->getChar();
381
279k
      ++byteCounter;
382
279k
      bufLen = 8 - nLeft;
383
279k
      x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1));
384
279k
    }
385
290k
  }
386
517k
  return x;
387
517k
}
388
389
819k
Guint JBIG2HuffmanDecoder::readBit() {
390
819k
  if (bufLen == 0) {
391
112k
    buf = str->getChar();
392
112k
    ++byteCounter;
393
112k
    bufLen = 8;
394
112k
  }
395
819k
  --bufLen;
396
819k
  return (buf >> bufLen) & 1;
397
819k
}
398
399
6.62k
void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {
400
6.62k
  Guint i, j, k, prefix;
401
6.62k
  JBIG2HuffmanTable tab;
402
403
  // stable selection sort:
404
  // - entries with prefixLen > 0, in ascending prefixLen order
405
  // - entry with prefixLen = 0, rangeLen = EOT
406
  // - all other entries with prefixLen = 0
407
  // (on entry, table[len] has prefixLen = 0, rangeLen = EOT)
408
138k
  for (i = 0; i < len; ++i) {
409
9.75M
    for (j = i; j < len && table[j].prefixLen == 0; ++j) ;
410
134k
    if (j == len) {
411
3.05k
      break;
412
3.05k
    }
413
134M
    for (k = j + 1; k < len; ++k) {
414
134M
      if (table[k].prefixLen > 0 &&
415
125M
    table[k].prefixLen < table[j].prefixLen) {
416
185k
  j = k;
417
185k
      }
418
134M
    }
419
131k
    if (j != i) {
420
121k
      tab = table[j];
421
24.1M
      for (k = j; k > i; --k) {
422
24.0M
  table[k] = table[k - 1];
423
24.0M
      }
424
121k
      table[i] = tab;
425
121k
    }
426
131k
  }
427
6.62k
  table[i] = table[len];
428
429
  // assign prefixes
430
6.62k
  if (table[0].rangeLen != jbig2HuffmanEOT) {
431
4.58k
    i = 0;
432
4.58k
    prefix = 0;
433
4.58k
    table[i++].prefix = prefix++;
434
131k
    for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) {
435
126k
      prefix <<= table[i].prefixLen - table[i-1].prefixLen;
436
126k
      table[i].prefix = prefix++;
437
126k
    }
438
4.58k
  }
439
6.62k
}
440
441
//------------------------------------------------------------------------
442
// JBIG2MMRDecoder
443
//------------------------------------------------------------------------
444
445
class JBIG2MMRDecoder {
446
public:
447
448
  JBIG2MMRDecoder();
449
  ~JBIG2MMRDecoder();
450
83.9k
  void setStream(Stream *strA) { str = strA; }
451
  void reset();
452
  int get2DCode();
453
  int getBlackCode();
454
  int getWhiteCode();
455
  Guint get24Bits();
456
185k
  void resetByteCounter() { byteCounter = 0; }
457
169k
  Guint getByteCounter() { return byteCounter; }
458
  void skipTo(Guint length);
459
460
private:
461
462
  Stream *str;
463
  Guint buf;
464
  Guint bufLen;
465
  Guint nBytesRead;
466
  Guint byteCounter;
467
};
468
469
299k
JBIG2MMRDecoder::JBIG2MMRDecoder() {
470
299k
  str = NULL;
471
299k
  byteCounter = 0;
472
299k
  reset();
473
299k
}
474
475
299k
JBIG2MMRDecoder::~JBIG2MMRDecoder() {
476
299k
}
477
478
303k
void JBIG2MMRDecoder::reset() {
479
303k
  buf = 0;
480
303k
  bufLen = 0;
481
303k
  nBytesRead = 0;
482
303k
}
483
484
681k
int JBIG2MMRDecoder::get2DCode() {
485
681k
  CCITTCode *p;
486
487
681k
  if (bufLen == 0) {
488
21.9k
    buf = str->getChar() & 0xff;
489
21.9k
    bufLen = 8;
490
21.9k
    ++nBytesRead;
491
21.9k
    ++byteCounter;
492
21.9k
    p = &twoDimTab1[(buf >> 1) & 0x7f];
493
659k
  } else if (bufLen >= 7) {
494
307k
    p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
495
352k
  } else {
496
352k
    p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f];
497
352k
    if (p->bits < 0 || p->bits > (int)bufLen) {
498
102k
      buf = (buf << 8) | (str->getChar() & 0xff);
499
102k
      bufLen += 8;
500
102k
      ++nBytesRead;
501
102k
      ++byteCounter;
502
102k
      p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
503
102k
    }
504
352k
  }
505
681k
  if (p->bits < 0) {
506
242k
    error(errSyntaxError, str->getPos(),
507
242k
    "Bad two dim code in JBIG2 MMR stream");
508
242k
    return EOF;
509
242k
  }
510
438k
  bufLen -= p->bits;
511
438k
  return p->n;
512
681k
}
513
514
65.8k
int JBIG2MMRDecoder::getWhiteCode() {
515
65.8k
  CCITTCode *p;
516
65.8k
  Guint code;
517
518
65.8k
  if (bufLen == 0) {
519
2.94k
    buf = str->getChar() & 0xff;
520
2.94k
    bufLen = 8;
521
2.94k
    ++nBytesRead;
522
2.94k
    ++byteCounter;
523
2.94k
  }
524
106k
  while (1) {
525
106k
    if (bufLen >= 11 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
526
569
      if (bufLen <= 12) {
527
241
  code = buf << (12 - bufLen);
528
328
      } else {
529
328
  code = buf >> (bufLen - 12);
530
328
      }
531
569
      p = &whiteTab1[code & 0x1f];
532
105k
    } else {
533
105k
      if (bufLen <= 9) {
534
86.4k
  code = buf << (9 - bufLen);
535
86.4k
      } else {
536
19.2k
  code = buf >> (bufLen - 9);
537
19.2k
      }
538
105k
      p = &whiteTab2[code & 0x1ff];
539
105k
    }
540
106k
    if (p->bits > 0 && p->bits <= (int)bufLen) {
541
65.4k
      bufLen -= p->bits;
542
65.4k
      return p->n;
543
65.4k
    }
544
40.8k
    if (bufLen >= 12) {
545
407
      break;
546
407
    }
547
40.4k
    buf = (buf << 8) | (str->getChar() & 0xff);
548
40.4k
    bufLen += 8;
549
40.4k
    ++nBytesRead;
550
40.4k
    ++byteCounter;
551
40.4k
  }
552
407
  error(errSyntaxError, str->getPos(), "Bad white code in JBIG2 MMR stream");
553
  // eat a bit and return a positive number so that the caller doesn't
554
  // go into an infinite loop
555
407
  --bufLen;
556
407
  return 1;
557
65.8k
}
558
559
60.4k
int JBIG2MMRDecoder::getBlackCode() {
560
60.4k
  CCITTCode *p;
561
60.4k
  Guint code;
562
563
60.4k
  if (bufLen == 0) {
564
1.68k
    buf = str->getChar() & 0xff;
565
1.68k
    bufLen = 8;
566
1.68k
    ++nBytesRead;
567
1.68k
    ++byteCounter;
568
1.68k
  }
569
95.6k
  while (1) {
570
95.6k
    if (bufLen >= 10 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
571
1.68k
      if (bufLen <= 13) {
572
546
  code = buf << (13 - bufLen);
573
1.14k
      } else {
574
1.14k
  code = buf >> (bufLen - 13);
575
1.14k
      }
576
1.68k
      p = &blackTab1[code & 0x7f];
577
93.9k
    } else if (bufLen >= 7 && ((buf >> (bufLen - 4)) & 0x0f) == 0 &&
578
1.92k
         ((buf >> (bufLen - 6)) & 0x03) != 0) {
579
1.31k
      if (bufLen <= 12) {
580
680
  code = buf << (12 - bufLen);
581
680
      } else {
582
636
  code = buf >> (bufLen - 12);
583
636
      }
584
1.31k
      p = &blackTab2[(code & 0xff) - 64];
585
92.6k
    } else {
586
92.6k
      if (bufLen <= 6) {
587
56.7k
  code = buf << (6 - bufLen);
588
56.7k
      } else {
589
35.8k
  code = buf >> (bufLen - 6);
590
35.8k
      }
591
92.6k
      p = &blackTab3[code & 0x3f];
592
92.6k
    }
593
95.6k
    if (p->bits > 0 && p->bits <= (int)bufLen) {
594
59.8k
      bufLen -= p->bits;
595
59.8k
      return p->n;
596
59.8k
    }
597
35.8k
    if (bufLen >= 13) {
598
603
      break;
599
603
    }
600
35.2k
    buf = (buf << 8) | (str->getChar() & 0xff);
601
35.2k
    bufLen += 8;
602
35.2k
    ++nBytesRead;
603
35.2k
    ++byteCounter;
604
35.2k
  }
605
603
  error(errSyntaxError, str->getPos(), "Bad black code in JBIG2 MMR stream");
606
  // eat a bit and return a positive number so that the caller doesn't
607
  // go into an infinite loop
608
603
  --bufLen;
609
603
  return 1;
610
60.4k
}
611
612
1.21k
Guint JBIG2MMRDecoder::get24Bits() {
613
4.21k
  while (bufLen < 24) {
614
3.00k
    buf = (buf << 8) | (str->getChar() & 0xff);
615
3.00k
    bufLen += 8;
616
3.00k
    ++nBytesRead;
617
3.00k
    ++byteCounter;
618
3.00k
  }
619
1.21k
  return (buf >> (bufLen - 24)) & 0xffffff;
620
1.21k
}
621
622
2.02k
void JBIG2MMRDecoder::skipTo(Guint length) {
623
2.02k
  int n;
624
625
2.02k
  n = str->discardChars(length - nBytesRead);
626
2.02k
  nBytesRead += n;
627
2.02k
  byteCounter += n;
628
2.02k
}
629
630
//------------------------------------------------------------------------
631
// JBIG2Segment
632
//------------------------------------------------------------------------
633
634
enum JBIG2SegmentType {
635
  jbig2SegBitmap,
636
  jbig2SegSymbolDict,
637
  jbig2SegPatternDict,
638
  jbig2SegCodeTable
639
};
640
641
class JBIG2Segment {
642
public:
643
644
207k
  JBIG2Segment(Guint segNumA) { segNum = segNumA; }
645
205k
  virtual ~JBIG2Segment() {}
646
551
  void setSegNum(Guint segNumA) { segNum = segNumA; }
647
34.5k
  Guint getSegNum() { return segNum; }
648
  virtual JBIG2SegmentType getType() = 0;
649
650
private:
651
652
  Guint segNum;
653
};
654
655
//------------------------------------------------------------------------
656
// JBIG2Bitmap
657
//------------------------------------------------------------------------
658
659
struct JBIG2BitmapPtr {
660
  Guchar *p;
661
  int shift;
662
  int x;
663
};
664
665
class JBIG2Bitmap: public JBIG2Segment {
666
public:
667
668
  JBIG2Bitmap(Guint segNumA, int wA, int hA);
669
  virtual ~JBIG2Bitmap();
670
0
  virtual JBIG2SegmentType getType() { return jbig2SegBitmap; }
671
1.14k
  JBIG2Bitmap *copy() { return new JBIG2Bitmap(0, this); }
672
  JBIG2Bitmap *getSlice(Guint x, Guint y, Guint wA, Guint hA);
673
  void expand(int newH, Guint pixel);
674
  void clearToZero();
675
  void clearToOne();
676
35.1k
  int getWidth() { return w; }
677
34.9k
  int getHeight() { return h; }
678
2.42M
  int getLineSize() { return line; }
679
  int getPixel(int x, int y)
680
233M
    { return (x < 0 || x >= w || y < 0 || y >= h) ? 0 :
681
233M
             (data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; }
682
  void setPixel(int x, int y)
683
26.8M
    { data[y * line + (x >> 3)] |= (Guchar)(1 << (7 - (x & 7))); }
684
  void clearPixel(int x, int y)
685
3.79M
    { data[y * line + (x >> 3)] &= (Guchar)(0x7f7f >> (x & 7)); }
686
  void getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr);
687
  int nextPixel(JBIG2BitmapPtr *ptr);
688
  void duplicateRow(int yDest, int ySrc);
689
  void combine(JBIG2Bitmap *bitmap, int x, int y, Guint combOp);
690
2.48M
  Guchar *getDataPtr() { return data; }
691
52.6k
  int getDataSize() { return h * line; }
692
693
private:
694
695
  JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap);
696
697
  int w, h, line;
698
  Guchar *data;
699
};
700
701
JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, int wA, int hA):
702
196k
  JBIG2Segment(segNumA)
703
196k
{
704
196k
  w = wA;
705
196k
  h = hA;
706
196k
  line = (wA + 7) >> 3;
707
196k
  if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
708
    // force a call to gmalloc(-1), which will throw an exception
709
13
    h = -1;
710
13
    line = 2;
711
13
  }
712
  // need to allocate one extra guard byte for use in combine()
713
196k
  data = (Guchar *)gmalloc(h * line + 1);
714
196k
  data[h * line] = 0;
715
196k
}
716
717
JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
718
1.14k
  JBIG2Segment(segNumA)
719
1.14k
{
720
1.14k
  w = bitmap->w;
721
1.14k
  h = bitmap->h;
722
1.14k
  line = bitmap->line;
723
1.14k
  if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
724
    // force a call to gmalloc(-1), which will throw an exception
725
0
    h = -1;
726
0
    line = 2;
727
0
  }
728
  // need to allocate one extra guard byte for use in combine()
729
1.14k
  data = (Guchar *)gmalloc(h * line + 1);
730
1.14k
  memcpy(data, bitmap->data, h * line);
731
1.14k
  data[h * line] = 0;
732
1.14k
}
733
734
196k
JBIG2Bitmap::~JBIG2Bitmap() {
735
196k
  gfree(data);
736
196k
}
737
738
//~ optimize this
739
109k
JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
740
109k
  JBIG2Bitmap *slice;
741
109k
  Guint xx, yy;
742
743
109k
  slice = new JBIG2Bitmap(0, wA, hA);
744
109k
  slice->clearToZero();
745
2.16M
  for (yy = 0; yy < hA; ++yy) {
746
70.4M
    for (xx = 0; xx < wA; ++xx) {
747
68.4M
      if (getPixel(x + xx, y + yy)) {
748
12.4M
  slice->setPixel(xx, yy);
749
12.4M
      }
750
68.4M
    }
751
2.05M
  }
752
109k
  return slice;
753
109k
}
754
755
1.16k
void JBIG2Bitmap::expand(int newH, Guint pixel) {
756
1.16k
  if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) {
757
639
    return;
758
639
  }
759
  // need to allocate one extra guard byte for use in combine()
760
523
  data = (Guchar *)grealloc(data, newH * line + 1);
761
523
  if (pixel) {
762
307
    memset(data + h * line, 0xff, (newH - h) * line);
763
307
  } else {
764
216
    memset(data + h * line, 0x00, (newH - h) * line);
765
216
  }
766
523
  h = newH;
767
523
  data[h * line] = 0;
768
523
}
769
770
158k
void JBIG2Bitmap::clearToZero() {
771
158k
  memset(data, 0, h * line);
772
158k
}
773
774
37.7k
void JBIG2Bitmap::clearToOne() {
775
37.7k
  memset(data, 0xff, h * line);
776
37.7k
}
777
778
3.66M
inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) {
779
3.66M
  if (y < 0 || y >= h || x >= w) {
780
521k
    ptr->p = NULL;
781
521k
    ptr->shift = 0; // make gcc happy
782
521k
    ptr->x = 0; // make gcc happy
783
3.13M
  } else if (x < 0) {
784
2.22M
    ptr->p = &data[y * line];
785
2.22M
    ptr->shift = 7;
786
2.22M
    ptr->x = x;
787
2.22M
  } else {
788
914k
    ptr->p = &data[y * line + (x >> 3)];
789
914k
    ptr->shift = 7 - (x & 7);
790
914k
    ptr->x = x;
791
914k
  }
792
3.66M
}
793
794
67.5M
inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr *ptr) {
795
67.5M
  int pix;
796
797
67.5M
  if (!ptr->p) {
798
15.0M
    pix = 0;
799
52.5M
  } else if (ptr->x < 0) {
800
2.77M
    ++ptr->x;
801
2.77M
    pix = 0;
802
49.7M
  } else {
803
49.7M
    pix = (*ptr->p >> ptr->shift) & 1;
804
49.7M
    if (++ptr->x == w) {
805
2.42M
      ptr->p = NULL;
806
47.3M
    } else if (ptr->shift == 0) {
807
4.94M
      ++ptr->p;
808
4.94M
      ptr->shift = 7;
809
42.4M
    } else {
810
42.4M
      --ptr->shift;
811
42.4M
    }
812
49.7M
  }
813
67.5M
  return pix;
814
67.5M
}
815
816
82.9k
void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) {
817
82.9k
  memcpy(data + yDest * line, data + ySrc * line, line);
818
82.9k
}
819
820
void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
821
31.0k
        Guint combOp) {
822
31.0k
  int x0, x1, y0, y1, xx, yy;
823
31.0k
  Guchar *srcPtr, *destPtr;
824
31.0k
  Guchar dest, src0, src1, src, m1, m2, m3;
825
31.0k
  Guint s1, s2;
826
31.0k
  GBool oneByte;
827
828
  // check for the pathological case where y = -2^31
829
31.0k
  if (y < -0x7fffffff) {
830
139
    return;
831
139
  }
832
30.9k
  if (y < 0) {
833
1.54k
    y0 = -y;
834
29.3k
  } else {
835
29.3k
    y0 = 0;
836
29.3k
  }
837
30.9k
  if (y > INT_MAX - bitmap->h) {
838
324
    return;
839
324
  }
840
30.5k
  if (y + bitmap->h > h) {
841
27.9k
    y1 = h - y;
842
27.9k
  } else {
843
2.60k
    y1 = bitmap->h;
844
2.60k
  }
845
30.5k
  if (y0 >= y1) {
846
23.3k
    return;
847
23.3k
  }
848
849
7.24k
  if (x >= 0) {
850
2.53k
    x0 = x & ~7;
851
4.70k
  } else {
852
4.70k
    x0 = 0;
853
4.70k
  }
854
7.24k
  x1 = x + bitmap->w;
855
7.24k
  if (x1 > w) {
856
2.62k
    x1 = w;
857
2.62k
  }
858
7.24k
  if (x0 >= x1) {
859
5.78k
    return;
860
5.78k
  }
861
862
1.46k
  s1 = x & 7;
863
1.46k
  s2 = 8 - s1;
864
1.46k
  m1 = (Guchar)(0xff >> (x1 & 7));
865
1.46k
  m2 = (Guchar)(0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7)));
866
1.46k
  m3 = (Guchar)((0xff >> s1) & m2);
867
868
1.46k
  oneByte = x0 == ((x1 - 1) & ~7);
869
870
333k
  for (yy = y0; yy < y1; ++yy) {
871
872
    // one byte per line -- need to mask both left and right side
873
331k
    if (oneByte) {
874
314k
      if (x >= 0) {
875
32.9k
  destPtr = data + (y + yy) * line + (x >> 3);
876
32.9k
  srcPtr = bitmap->data + yy * bitmap->line;
877
32.9k
  dest = *destPtr;
878
32.9k
  src1 = *srcPtr;
879
32.9k
  switch (combOp) {
880
32.4k
  case 0: // or
881
32.4k
    dest |= (Guchar)((src1 >> s1) & m2);
882
32.4k
    break;
883
0
  case 1: // and
884
0
    dest &= (Guchar)(((0xff00 | src1) >> s1) | m1);
885
0
    break;
886
0
  case 2: // xor
887
0
    dest ^= (Guchar)((src1 >> s1) & m2);
888
0
    break;
889
0
  case 3: // xnor
890
0
    dest ^= (Guchar)(((src1 ^ 0xff) >> s1) & m2);
891
0
    break;
892
490
  case 4: // replace
893
490
    dest = (Guchar)((dest & ~m3) | ((src1 >> s1) & m3));
894
490
    break;
895
32.9k
  }
896
32.9k
  *destPtr = dest;
897
281k
      } else {
898
281k
  destPtr = data + (y + yy) * line;
899
281k
  srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
900
281k
  dest = *destPtr;
901
281k
  src1 = *srcPtr;
902
281k
  switch (combOp) {
903
0
  case 0: // or
904
0
    dest |= src1 & m2;
905
0
    break;
906
280k
  case 1: // and
907
280k
    dest &= src1 | m1;
908
280k
    break;
909
29
  case 2: // xor
910
29
    dest ^= src1 & m2;
911
29
    break;
912
1.04k
  case 3: // xnor
913
1.04k
    dest ^= (src1 ^ 0xff) & m2;
914
1.04k
    break;
915
0
  case 4: // replace
916
0
    dest = (src1 & m2) | (dest & m1);
917
0
    break;
918
281k
  }
919
281k
  *destPtr = dest;
920
281k
      }
921
922
    // multiple bytes per line -- need to mask left side of left-most
923
    // byte and right side of right-most byte
924
314k
    } else {
925
926
      // left-most byte
927
17.6k
      if (x >= 0) {
928
16.4k
  destPtr = data + (y + yy) * line + (x >> 3);
929
16.4k
  srcPtr = bitmap->data + yy * bitmap->line;
930
16.4k
  src1 = *srcPtr++;
931
16.4k
  dest = *destPtr;
932
16.4k
  switch (combOp) {
933
5.64k
  case 0: // or
934
5.64k
    dest |= (Guchar)(src1 >> s1);
935
5.64k
    break;
936
3
  case 1: // and
937
3
    dest &= (Guchar)((0xff00 | src1) >> s1);
938
3
    break;
939
9.58k
  case 2: // xor
940
9.58k
    dest ^= (Guchar)(src1 >> s1);
941
9.58k
    break;
942
5
  case 3: // xnor
943
5
    dest ^= (Guchar)((src1 ^ 0xff) >> s1);
944
5
    break;
945
0
  case 4: // replace
946
0
    dest = (Guchar)((dest & (0xff << s2)) | (src1 >> s1));
947
0
    break;
948
16.4k
  }
949
16.4k
  *destPtr++ = dest;
950
16.4k
  xx = x0 + 8;
951
16.4k
      } else {
952
1.17k
  destPtr = data + (y + yy) * line;
953
1.17k
  srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
954
1.17k
  src1 = *srcPtr++;
955
1.17k
  xx = x0;
956
1.17k
      }
957
958
      // middle bytes
959
912k
      for (; xx < x1 - 8; xx += 8) {
960
894k
  dest = *destPtr;
961
894k
  src0 = src1;
962
894k
  src1 = *srcPtr++;
963
894k
  src = (Guchar)(((src0 << 8) | src1) >> s1);
964
894k
  switch (combOp) {
965
8.13k
  case 0: // or
966
8.13k
    dest |= src;
967
8.13k
    break;
968
6
  case 1: // and
969
6
    dest &= src;
970
6
    break;
971
258k
  case 2: // xor
972
258k
    dest ^= src;
973
258k
    break;
974
5
  case 3: // xnor
975
5
    dest ^= src ^ 0xff;
976
5
    break;
977
25.2k
  case 4: // replace
978
25.2k
    dest = src;
979
25.2k
    break;
980
894k
  }
981
894k
  *destPtr++ = dest;
982
894k
      }
983
984
      // right-most byte
985
      // note: this last byte (src1) may not actually be used, depending
986
      // on the values of s1, m1, and m2 - and in fact, it may be off
987
      // the edge of the source bitmap, which means we need to allocate
988
      // one extra guard byte at the end of each bitmap
989
17.6k
      dest = *destPtr;
990
17.6k
      src0 = src1;
991
17.6k
      src1 = *srcPtr++;
992
17.6k
      src = (Guchar)(((src0 << 8) | src1) >> s1);
993
17.6k
      switch (combOp) {
994
5.66k
      case 0: // or
995
5.66k
  dest |= src & m2;
996
5.66k
  break;
997
3
      case 1: // and
998
3
  dest &= src | m1;
999
3
  break;
1000
9.58k
      case 2: // xor
1001
9.58k
  dest ^= src & m2;
1002
9.58k
  break;
1003
5
      case 3: // xnor
1004
5
  dest ^= (src ^ 0xff) & m2;
1005
5
  break;
1006
900
      case 4: // replace
1007
900
  dest = (src & m2) | (dest & m1);
1008
900
  break;
1009
17.6k
      }
1010
17.6k
      *destPtr = dest;
1011
17.6k
    }
1012
331k
  }
1013
1.46k
}
1014
1015
//------------------------------------------------------------------------
1016
// JBIG2SymbolDict
1017
//------------------------------------------------------------------------
1018
1019
class JBIG2SymbolDict: public JBIG2Segment {
1020
public:
1021
1022
  JBIG2SymbolDict(Guint segNumA, Guint sizeA);
1023
  virtual ~JBIG2SymbolDict();
1024
2.78k
  virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; }
1025
2.78k
  Guint getSize() { return size; }
1026
1.14k
  void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1027
0
  JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1028
  void setGenericRegionStats(JArithmeticDecoderStats *stats)
1029
1.87k
    { genericRegionStats = stats; }
1030
  void setRefinementRegionStats(JArithmeticDecoderStats *stats)
1031
1.52k
    { refinementRegionStats = stats; }
1032
  JArithmeticDecoderStats *getGenericRegionStats()
1033
274
    { return genericRegionStats; }
1034
  JArithmeticDecoderStats *getRefinementRegionStats()
1035
287
    { return refinementRegionStats; }
1036
1037
private:
1038
1039
  Guint size;
1040
  JBIG2Bitmap **bitmaps;
1041
  JArithmeticDecoderStats *genericRegionStats;
1042
  JArithmeticDecoderStats *refinementRegionStats;
1043
};
1044
1045
JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
1046
3.68k
  JBIG2Segment(segNumA)
1047
3.68k
{
1048
3.68k
  Guint i;
1049
1050
3.68k
  size = sizeA;
1051
3.68k
  bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
1052
115M
  for (i = 0; i < size; ++i) {
1053
115M
    bitmaps[i] = NULL;
1054
115M
  }
1055
3.68k
  genericRegionStats = NULL;
1056
3.68k
  refinementRegionStats = NULL;
1057
3.68k
}
1058
1059
3.67k
JBIG2SymbolDict::~JBIG2SymbolDict() {
1060
3.67k
  Guint i;
1061
1062
115M
  for (i = 0; i < size; ++i) {
1063
115M
    if (bitmaps[i]) {
1064
1.14k
      delete bitmaps[i];
1065
1.14k
    }
1066
115M
  }
1067
3.67k
  gfree(bitmaps);
1068
3.67k
  if (genericRegionStats) {
1069
1.86k
    delete genericRegionStats;
1070
1.86k
  }
1071
3.67k
  if (refinementRegionStats) {
1072
1.52k
    delete refinementRegionStats;
1073
1.52k
  }
1074
3.67k
}
1075
1076
//------------------------------------------------------------------------
1077
// JBIG2PatternDict
1078
//------------------------------------------------------------------------
1079
1080
class JBIG2PatternDict: public JBIG2Segment {
1081
public:
1082
1083
  JBIG2PatternDict(Guint segNumA, Guint sizeA);
1084
  virtual ~JBIG2PatternDict();
1085
2.85k
  virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }
1086
0
  Guint getSize() { return size; }
1087
37.2k
  void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1088
0
  JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1089
1090
private:
1091
1092
  Guint size;
1093
  JBIG2Bitmap **bitmaps;
1094
};
1095
1096
JBIG2PatternDict::JBIG2PatternDict(Guint segNumA, Guint sizeA):
1097
1.21k
  JBIG2Segment(segNumA)
1098
1.21k
{
1099
1.21k
  size = sizeA;
1100
1.21k
  bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
1101
1.21k
}
1102
1103
1.21k
JBIG2PatternDict::~JBIG2PatternDict() {
1104
1.21k
  Guint i;
1105
1106
37.4k
  for (i = 0; i < size; ++i) {
1107
36.1k
    delete bitmaps[i];
1108
36.1k
  }
1109
1.21k
  gfree(bitmaps);
1110
1.21k
}
1111
1112
//------------------------------------------------------------------------
1113
// JBIG2CodeTable
1114
//------------------------------------------------------------------------
1115
1116
class JBIG2CodeTable: public JBIG2Segment {
1117
public:
1118
1119
  JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA);
1120
  virtual ~JBIG2CodeTable();
1121
28.3k
  virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; }
1122
4.52k
  JBIG2HuffmanTable *getHuffTable() { return table; }
1123
1124
private:
1125
1126
  JBIG2HuffmanTable *table;
1127
};
1128
1129
JBIG2CodeTable::JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA):
1130
4.61k
  JBIG2Segment(segNumA)
1131
4.61k
{
1132
4.61k
  table = tableA;
1133
4.61k
}
1134
1135
4.59k
JBIG2CodeTable::~JBIG2CodeTable() {
1136
4.59k
  gfree(table);
1137
4.59k
}
1138
1139
//------------------------------------------------------------------------
1140
// JBIG2Stream
1141
//------------------------------------------------------------------------
1142
1143
JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStreamA):
1144
299k
  FilterStream(strA)
1145
299k
{
1146
299k
  decoded = gFalse;
1147
299k
  pageBitmap = NULL;
1148
1149
299k
  arithDecoder = new JArithmeticDecoder();
1150
299k
  genericRegionStats = new JArithmeticDecoderStats(1 << 1);
1151
299k
  refinementRegionStats = new JArithmeticDecoderStats(1 << 1);
1152
299k
  iadhStats = new JArithmeticDecoderStats(1 << 9);
1153
299k
  iadwStats = new JArithmeticDecoderStats(1 << 9);
1154
299k
  iaexStats = new JArithmeticDecoderStats(1 << 9);
1155
299k
  iaaiStats = new JArithmeticDecoderStats(1 << 9);
1156
299k
  iadtStats = new JArithmeticDecoderStats(1 << 9);
1157
299k
  iaitStats = new JArithmeticDecoderStats(1 << 9);
1158
299k
  iafsStats = new JArithmeticDecoderStats(1 << 9);
1159
299k
  iadsStats = new JArithmeticDecoderStats(1 << 9);
1160
299k
  iardxStats = new JArithmeticDecoderStats(1 << 9);
1161
299k
  iardyStats = new JArithmeticDecoderStats(1 << 9);
1162
299k
  iardwStats = new JArithmeticDecoderStats(1 << 9);
1163
299k
  iardhStats = new JArithmeticDecoderStats(1 << 9);
1164
299k
  iariStats = new JArithmeticDecoderStats(1 << 9);
1165
299k
  iaidStats = new JArithmeticDecoderStats(1 << 1);
1166
299k
  huffDecoder = new JBIG2HuffmanDecoder();
1167
299k
  mmrDecoder = new JBIG2MMRDecoder();
1168
1169
299k
  globalsStreamA->copy(&globalsStream);
1170
299k
  segments = globalSegments = NULL;
1171
299k
  curStr = NULL;
1172
299k
  dataPtr = dataEnd = NULL;
1173
299k
}
1174
1175
299k
JBIG2Stream::~JBIG2Stream() {
1176
299k
  close();
1177
299k
  globalsStream.free();
1178
299k
  delete arithDecoder;
1179
299k
  delete genericRegionStats;
1180
299k
  delete refinementRegionStats;
1181
299k
  delete iadhStats;
1182
299k
  delete iadwStats;
1183
299k
  delete iaexStats;
1184
299k
  delete iaaiStats;
1185
299k
  delete iadtStats;
1186
299k
  delete iaitStats;
1187
299k
  delete iafsStats;
1188
299k
  delete iadsStats;
1189
299k
  delete iardxStats;
1190
299k
  delete iardyStats;
1191
299k
  delete iardwStats;
1192
299k
  delete iardhStats;
1193
299k
  delete iariStats;
1194
299k
  delete iaidStats;
1195
299k
  delete huffDecoder;
1196
299k
  delete mmrDecoder;
1197
299k
  delete str;
1198
299k
}
1199
1200
294k
Stream *JBIG2Stream::copy() {
1201
294k
  return new JBIG2Stream(str->copy(), &globalsStream);
1202
294k
}
1203
1204
75.8k
void JBIG2Stream::reset() {
1205
75.8k
  segments = new GList();
1206
75.8k
  globalSegments = new GList();
1207
75.8k
  decoded = gFalse;
1208
75.8k
}
1209
1210
376k
void JBIG2Stream::close() {
1211
376k
  if (pageBitmap) {
1212
52.6k
    delete pageBitmap;
1213
52.6k
    pageBitmap = NULL;
1214
52.6k
  }
1215
376k
  if (segments) {
1216
75.6k
    deleteGList(segments, JBIG2Segment);
1217
75.6k
    segments = NULL;
1218
75.6k
  }
1219
376k
  if (globalSegments) {
1220
75.6k
    deleteGList(globalSegments, JBIG2Segment);
1221
75.6k
    globalSegments = NULL;
1222
75.6k
  }
1223
376k
  dataPtr = dataEnd = NULL;
1224
376k
  FilterStream::close();
1225
376k
}
1226
1227
421M
int JBIG2Stream::getChar() {
1228
421M
  if (!decoded) {
1229
75.4k
    decodeImage();
1230
75.4k
  }
1231
421M
  if (dataPtr && dataPtr < dataEnd) {
1232
420M
    return (*dataPtr++ ^ 0xff) & 0xff;
1233
420M
  }
1234
895k
  return EOF;
1235
421M
}
1236
1237
73.1M
int JBIG2Stream::lookChar() {
1238
73.1M
  if (!decoded) {
1239
0
    decodeImage();
1240
0
  }
1241
73.1M
  if (dataPtr && dataPtr < dataEnd) {
1242
73.0M
    return (*dataPtr ^ 0xff) & 0xff;
1243
73.0M
  }
1244
11.8k
  return EOF;
1245
73.1M
}
1246
1247
7.76k
int JBIG2Stream::getBlock(char *blk, int size) {
1248
7.76k
  int n, i;
1249
1250
7.76k
  if (!decoded) {
1251
259
    decodeImage();
1252
259
  }
1253
7.76k
  if (size <= 0) {
1254
0
    return 0;
1255
0
  }
1256
7.76k
  if (dataEnd - dataPtr < size) {
1257
590
    n = (int)(dataEnd - dataPtr);
1258
7.17k
  } else {
1259
7.17k
    n = size;
1260
7.17k
  }
1261
29.8M
  for (i = 0; i < n; ++i) {
1262
29.8M
    blk[i] = *dataPtr++ ^ 0xff;
1263
29.8M
  }
1264
7.76k
  return n;
1265
7.76k
}
1266
1267
GString *JBIG2Stream::getPSFilter(int psLevel, const char *indent,
1268
0
          GBool okToReadStream) {
1269
0
  return NULL;
1270
0
}
1271
1272
0
GBool JBIG2Stream::isBinary(GBool last) {
1273
0
  return str->isBinary(gTrue);
1274
0
}
1275
1276
75.6k
void JBIG2Stream::decodeImage() {
1277
75.6k
  GList *t;
1278
1279
  // read the globals stream
1280
75.6k
  if (globalsStream.isStream()) {
1281
8.28k
    curStr = globalsStream.getStream();
1282
8.28k
    curStr->reset();
1283
8.28k
    arithDecoder->setStream(curStr);
1284
8.28k
    huffDecoder->setStream(curStr);
1285
8.28k
    mmrDecoder->setStream(curStr);
1286
8.28k
    readSegments();
1287
8.28k
    curStr->close();
1288
    // swap the newly read segments list into globalSegments
1289
8.28k
    t = segments;
1290
8.28k
    segments = globalSegments;
1291
8.28k
    globalSegments = t;
1292
8.28k
  }
1293
1294
  // read the main stream
1295
75.6k
  curStr = str;
1296
75.6k
  curStr->reset();
1297
75.6k
  arithDecoder->setStream(curStr);
1298
75.6k
  huffDecoder->setStream(curStr);
1299
75.6k
  mmrDecoder->setStream(curStr);
1300
75.6k
  readSegments();
1301
1302
75.6k
  if (pageBitmap) {
1303
52.6k
    dataPtr = pageBitmap->getDataPtr();
1304
52.6k
    dataEnd = dataPtr + pageBitmap->getDataSize();
1305
52.6k
  } else {
1306
23.0k
    dataPtr = dataEnd = NULL;
1307
23.0k
  }
1308
1309
75.6k
  decoded = gTrue;
1310
75.6k
}
1311
1312
83.9k
void JBIG2Stream::readSegments() {
1313
83.9k
  Guint segNum, segFlags, segType, page, segLength;
1314
83.9k
  Guint refFlags, nRefSegs;
1315
83.9k
  Guint *refSegs;
1316
83.9k
  int c1, c2, c3;
1317
83.9k
  Guint i;
1318
1319
83.9k
  done = gFalse;
1320
202k
  while (!done && readULong(&segNum)) {
1321
1322
    // segment header flags
1323
193k
    if (!readUByte(&segFlags)) {
1324
294
      goto eofError1;
1325
294
    }
1326
193k
    segType = segFlags & 0x3f;
1327
1328
    // referred-to segment count and retention flags
1329
193k
    if (!readUByte(&refFlags)) {
1330
180
      goto eofError1;
1331
180
    }
1332
193k
    nRefSegs = refFlags >> 5;
1333
193k
    if (nRefSegs == 7) {
1334
9.18k
      if ((c1 = curStr->getChar()) == EOF ||
1335
8.98k
    (c2 = curStr->getChar()) == EOF ||
1336
8.88k
    (c3 = curStr->getChar()) == EOF) {
1337
616
  goto eofError1;
1338
616
      }
1339
8.57k
      refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3;
1340
8.57k
      nRefSegs = refFlags & 0x1fffffff;
1341
8.57k
      i = (nRefSegs + 9) >> 3;
1342
8.57k
      if (curStr->discardChars(i) != i) {
1343
1.36k
  goto eofError1;
1344
1.36k
      }
1345
8.57k
    }
1346
1347
    // referred-to segment numbers
1348
191k
    refSegs = (Guint *)gmallocn(nRefSegs, sizeof(Guint));
1349
191k
    if (segNum <= 256) {
1350
97.6k
      for (i = 0; i < nRefSegs; ++i) {
1351
86.2k
  if (!readUByte(&refSegs[i])) {
1352
129
    goto eofError2;
1353
129
  }
1354
86.2k
      }
1355
179k
    } else if (segNum <= 65536) {
1356
6.46M
      for (i = 0; i < nRefSegs; ++i) {
1357
6.45M
  if (!readUWord(&refSegs[i])) {
1358
323
    goto eofError2;
1359
323
  }
1360
6.45M
      }
1361
168k
    } else {
1362
566k
      for (i = 0; i < nRefSegs; ++i) {
1363
399k
  if (!readULong(&refSegs[i])) {
1364
811
    goto eofError2;
1365
811
  }
1366
399k
      }
1367
168k
    }
1368
1369
    // segment page association
1370
190k
    if (segFlags & 0x40) {
1371
41.1k
      if (!readULong(&page)) {
1372
619
  goto eofError2;
1373
619
      }
1374
148k
    } else {
1375
148k
      if (!readUByte(&page)) {
1376
172
  goto eofError2;
1377
172
      }
1378
148k
    }
1379
1380
    // segment data length
1381
189k
    if (!readULong(&segLength)) {
1382
952
      goto eofError2;
1383
952
    }
1384
1385
    // check for missing page information segment
1386
188k
    if (!pageBitmap && ((segType >= 4 && segType <= 7) ||
1387
87.4k
      (segType >= 20 && segType <= 43))) {
1388
2.92k
      error(errSyntaxError, getPos(),
1389
2.92k
      "First JBIG2 segment associated with a page must be a page information segment");
1390
2.92k
      goto syntaxError;
1391
2.92k
    }
1392
1393
    // read the segment data
1394
185k
    arithDecoder->resetByteCounter();
1395
185k
    huffDecoder->resetByteCounter();
1396
185k
    mmrDecoder->resetByteCounter();
1397
185k
    byteCounter = 0;
1398
185k
    switch (segType) {
1399
16.3k
    case 0:
1400
16.3k
      if (!readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs)) {
1401
13.3k
  goto syntaxError;
1402
13.3k
      }
1403
3.06k
      break;
1404
3.06k
    case 4:
1405
966
      readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
1406
966
      break;
1407
6.77k
    case 6:
1408
6.77k
      readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs);
1409
6.77k
      break;
1410
12.3k
    case 7:
1411
12.3k
      readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs);
1412
12.3k
      break;
1413
2.53k
    case 16:
1414
2.53k
      readPatternDictSeg(segNum, segLength);
1415
2.53k
      break;
1416
6.81k
    case 20:
1417
6.81k
      readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength,
1418
6.81k
          refSegs, nRefSegs);
1419
6.81k
      break;
1420
1.24k
    case 22:
1421
1.24k
      readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength,
1422
1.24k
          refSegs, nRefSegs);
1423
1.24k
      break;
1424
302
    case 23:
1425
302
      readHalftoneRegionSeg(segNum, gTrue, gTrue, segLength,
1426
302
          refSegs, nRefSegs);
1427
302
      break;
1428
1.31k
    case 36:
1429
1.31k
      readGenericRegionSeg(segNum, gFalse, gFalse, segLength);
1430
1.31k
      break;
1431
7.36k
    case 38:
1432
7.36k
      readGenericRegionSeg(segNum, gTrue, gFalse, segLength);
1433
7.36k
      break;
1434
946
    case 39:
1435
946
      readGenericRegionSeg(segNum, gTrue, gTrue, segLength);
1436
946
      break;
1437
1.08k
    case 40:
1438
1.08k
      readGenericRefinementRegionSeg(segNum, gFalse, gFalse, segLength,
1439
1.08k
             refSegs, nRefSegs);
1440
1.08k
      break;
1441
728
    case 42:
1442
728
      readGenericRefinementRegionSeg(segNum, gTrue, gFalse, segLength,
1443
728
             refSegs, nRefSegs);
1444
728
      break;
1445
5.34k
    case 43:
1446
5.34k
      readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength,
1447
5.34k
             refSegs, nRefSegs);
1448
5.34k
      break;
1449
109k
    case 48:
1450
109k
      readPageInfoSeg(segLength);
1451
109k
      break;
1452
498
    case 50:
1453
498
      readEndOfStripeSeg(segLength);
1454
498
      break;
1455
248
    case 51:
1456
      // end of file segment
1457
248
      done = gTrue;
1458
248
      break;
1459
242
    case 52:
1460
242
      readProfilesSeg(segLength);
1461
242
      break;
1462
6.57k
    case 53:
1463
6.57k
      readCodeTableSeg(segNum, segLength);
1464
6.57k
      break;
1465
386
    case 62:
1466
386
      readExtensionSeg(segLength);
1467
386
      break;
1468
3.86k
    default:
1469
3.86k
      error(errSyntaxError, getPos(), "Unknown segment type in JBIG2 stream");
1470
3.86k
      if (curStr->discardChars(segLength) != segLength) {
1471
1.98k
  goto eofError2;
1472
1.98k
      }
1473
1.87k
      break;
1474
185k
    }
1475
1476
    // skip any unused data at the end of the segment
1477
    // (except for immediate generic region segments which have
1478
    // 0xffffffff = unspecified length)
1479
170k
    if (!(segType == 38 && segLength == 0xffffffff)) {
1480
169k
      byteCounter += arithDecoder->getByteCounter();
1481
169k
      byteCounter += huffDecoder->getByteCounter();
1482
169k
      byteCounter += mmrDecoder->getByteCounter();
1483
      // do a sanity check on byteCounter vs segLength -- if there is
1484
      // a problem, abort the decode
1485
169k
      if (byteCounter > segLength ||
1486
166k
    segLength - byteCounter > 65536) {
1487
51.1k
  error(errSyntaxError, getPos(),
1488
51.1k
        "Invalid segment length in JBIG2 stream");
1489
51.1k
  gfree(refSegs);
1490
51.1k
  break;
1491
51.1k
      }
1492
118k
      byteCounter += curStr->discardChars(segLength - byteCounter);
1493
118k
    }
1494
1495
119k
    gfree(refSegs);
1496
119k
  }
1497
1498
60.2k
  return;
1499
1500
60.2k
 syntaxError:
1501
16.2k
  gfree(refSegs);
1502
16.2k
  return;
1503
1504
4.99k
 eofError2:
1505
4.99k
  gfree(refSegs);
1506
7.44k
 eofError1:
1507
7.44k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
1508
7.44k
}
1509
1510
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
1511
16.3k
             Guint *refSegs, Guint nRefSegs) {
1512
16.3k
  JBIG2SymbolDict *symbolDict;
1513
16.3k
  JBIG2HuffmanTable *huffDHTable, *huffDWTable;
1514
16.3k
  JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
1515
16.3k
  JBIG2Segment *seg;
1516
16.3k
  GList *codeTables;
1517
16.3k
  JBIG2SymbolDict *inputSymbolDict;
1518
16.3k
  Guint flags, sdTemplate, sdrTemplate, huff, refAgg;
1519
16.3k
  Guint huffDH, huffDW, huffBMSize, huffAggInst;
1520
16.3k
  Guint contextUsed, contextRetained;
1521
16.3k
  int sdATX[4], sdATY[4], sdrATX[2], sdrATY[2];
1522
16.3k
  Guint numExSyms, numNewSyms, numInputSyms, symCodeLen;
1523
16.3k
  JBIG2Bitmap **bitmaps;
1524
16.3k
  JBIG2Bitmap *collBitmap, *refBitmap;
1525
16.3k
  Guint *symWidths;
1526
16.3k
  Guint symHeight, symWidth, totalWidth, x, symID;
1527
16.3k
  int dh, dw, refAggNum, refDX, refDY, bmSize;
1528
16.3k
  GBool ex;
1529
16.3k
  int run, prevRun, cnt;
1530
16.3k
  Guint i, j, k;
1531
1532
16.3k
  symWidths = NULL;
1533
1534
  // symbol dictionary flags
1535
16.3k
  if (!readUWord(&flags)) {
1536
382
    goto eofError;
1537
382
  }
1538
15.9k
  sdTemplate = (flags >> 10) & 3;
1539
15.9k
  sdrTemplate = (flags >> 12) & 1;
1540
15.9k
  huff = flags & 1;
1541
15.9k
  refAgg = (flags >> 1) & 1;
1542
15.9k
  huffDH = (flags >> 2) & 3;
1543
15.9k
  huffDW = (flags >> 4) & 3;
1544
15.9k
  huffBMSize = (flags >> 6) & 1;
1545
15.9k
  huffAggInst = (flags >> 7) & 1;
1546
15.9k
  contextUsed = (flags >> 8) & 1;
1547
15.9k
  contextRetained = (flags >> 9) & 1;
1548
1549
  // symbol dictionary AT flags
1550
15.9k
  if (!huff) {
1551
9.87k
    if (sdTemplate == 0) {
1552
6.01k
      if (!readByte(&sdATX[0]) ||
1553
5.73k
    !readByte(&sdATY[0]) ||
1554
5.48k
    !readByte(&sdATX[1]) ||
1555
5.29k
    !readByte(&sdATY[1]) ||
1556
5.12k
    !readByte(&sdATX[2]) ||
1557
4.86k
    !readByte(&sdATY[2]) ||
1558
4.74k
    !readByte(&sdATX[3]) ||
1559
4.52k
    !readByte(&sdATY[3])) {
1560
1.73k
  goto eofError;
1561
1.73k
      }
1562
6.01k
    } else {
1563
3.85k
      if (!readByte(&sdATX[0]) ||
1564
3.60k
    !readByte(&sdATY[0])) {
1565
540
  goto eofError;
1566
540
      }
1567
3.85k
    }
1568
9.87k
  }
1569
1570
  // symbol dictionary refinement AT flags
1571
13.7k
  if (refAgg && !sdrTemplate) {
1572
3.26k
    if (!readByte(&sdrATX[0]) ||
1573
3.09k
  !readByte(&sdrATY[0]) ||
1574
2.93k
  !readByte(&sdrATX[1]) ||
1575
2.73k
  !readByte(&sdrATY[1])) {
1576
716
      goto eofError;
1577
716
    }
1578
3.26k
  }
1579
1580
  // SDNUMEXSYMS and SDNUMNEWSYMS
1581
12.9k
  if (!readULong(&numExSyms) || !readULong(&numNewSyms)) {
1582
1.84k
    goto eofError;
1583
1.84k
  }
1584
1585
  // get referenced segments: input symbol dictionaries and code tables
1586
11.1k
  codeTables = new GList();
1587
11.1k
  numInputSyms = 0;
1588
1.23M
  for (i = 0; i < nRefSegs; ++i) {
1589
1.22M
    if ((seg = findSegment(refSegs[i]))) {
1590
5.48k
      if (seg->getType() == jbig2SegSymbolDict) {
1591
1.24k
  j = ((JBIG2SymbolDict *)seg)->getSize();
1592
1.24k
  if (j > INT_MAX || numInputSyms > INT_MAX - j) {
1593
0
    error(errSyntaxError, getPos(),
1594
0
    "Too many input symbols in JBIG2 symbol dictionary");
1595
0
    delete codeTables;
1596
0
    goto eofError;
1597
0
  }
1598
1.24k
  numInputSyms += j;
1599
4.23k
      } else if (seg->getType() == jbig2SegCodeTable) {
1600
3.43k
  codeTables->append(seg);
1601
3.43k
      }
1602
5.48k
    }
1603
1.22M
  }
1604
11.1k
  if (numNewSyms > INT_MAX || numInputSyms > INT_MAX - numNewSyms) {
1605
1.65k
    error(errSyntaxError, getPos(),
1606
1.65k
    "Too many input symbols in JBIG2 symbol dictionary");
1607
1.65k
    delete codeTables;
1608
1.65k
    goto eofError;
1609
1.65k
  }
1610
1611
  // compute symbol code length
1612
9.49k
  i = numInputSyms + numNewSyms;
1613
9.49k
  if (i <= 1) {
1614
3.57k
    symCodeLen = huff ? 1 : 0;
1615
5.92k
  } else {
1616
5.92k
    --i;
1617
5.92k
    symCodeLen = 0;
1618
    // i = floor((numSyms-1) / 2^symCodeLen)
1619
63.6k
    while (i > 0) {
1620
57.7k
      ++symCodeLen;
1621
57.7k
      i >>= 1;
1622
57.7k
    }
1623
5.92k
  }
1624
1625
  // get the input symbol bitmaps
1626
9.49k
  bitmaps = (JBIG2Bitmap **)gmallocn(numInputSyms + numNewSyms,
1627
9.49k
             sizeof(JBIG2Bitmap *));
1628
294M
  for (i = 0; i < numInputSyms + numNewSyms; ++i) {
1629
294M
    bitmaps[i] = NULL;
1630
294M
  }
1631
9.49k
  k = 0;
1632
9.49k
  inputSymbolDict = NULL;
1633
1.22M
  for (i = 0; i < nRefSegs; ++i) {
1634
1.21M
    if ((seg = findSegment(refSegs[i]))) {
1635
4.13k
      if (seg->getType() == jbig2SegSymbolDict) {
1636
635
  inputSymbolDict = (JBIG2SymbolDict *)seg;
1637
635
  for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1638
0
    bitmaps[k++] = inputSymbolDict->getBitmap(j);
1639
0
  }
1640
635
      }
1641
4.13k
    }
1642
1.21M
  }
1643
1644
  // get the Huffman tables
1645
9.49k
  huffDHTable = huffDWTable = NULL; // make gcc happy
1646
9.49k
  huffBMSizeTable = huffAggInstTable = NULL; // make gcc happy
1647
9.49k
  i = 0;
1648
9.49k
  if (huff) {
1649
3.98k
    if (huffDH == 0) {
1650
2.06k
      huffDHTable = huffTableD;
1651
2.06k
    } else if (huffDH == 1) {
1652
1.27k
      huffDHTable = huffTableE;
1653
1.27k
    } else {
1654
651
      if (i >= (Guint)codeTables->getLength()) {
1655
353
  goto codeTableError;
1656
353
      }
1657
298
      huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1658
298
    }
1659
3.63k
    if (huffDW == 0) {
1660
2.67k
      huffDWTable = huffTableB;
1661
2.67k
    } else if (huffDW == 1) {
1662
274
      huffDWTable = huffTableC;
1663
688
    } else {
1664
688
      if (i >= (Guint)codeTables->getLength()) {
1665
412
  goto codeTableError;
1666
412
      }
1667
276
      huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1668
276
    }
1669
3.22k
    if (huffBMSize == 0) {
1670
2.69k
      huffBMSizeTable = huffTableA;
1671
2.69k
    } else {
1672
532
      if (i >= (Guint)codeTables->getLength()) {
1673
446
  goto codeTableError;
1674
446
      }
1675
86
      huffBMSizeTable =
1676
86
    ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1677
86
    }
1678
2.77k
    if (huffAggInst == 0) {
1679
2.30k
      huffAggInstTable = huffTableA;
1680
2.30k
    } else {
1681
471
      if (i >= (Guint)codeTables->getLength()) {
1682
277
  goto codeTableError;
1683
277
      }
1684
194
      huffAggInstTable =
1685
194
    ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1686
194
    }
1687
2.77k
  }
1688
8.00k
  delete codeTables;
1689
1690
  // set up the Huffman decoder
1691
8.00k
  if (huff) {
1692
2.49k
    huffDecoder->reset();
1693
1694
  // set up the arithmetic decoder
1695
5.50k
  } else {
1696
5.50k
    if (contextUsed && inputSymbolDict) {
1697
274
      resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats());
1698
5.23k
    } else {
1699
5.23k
      resetGenericStats(sdTemplate, NULL);
1700
5.23k
    }
1701
5.50k
    resetIntStats(symCodeLen);
1702
5.50k
    arithDecoder->start();
1703
5.50k
  }
1704
1705
  // set up the arithmetic decoder for refinement/aggregation
1706
8.00k
  if (refAgg) {
1707
3.29k
    if (contextUsed && inputSymbolDict) {
1708
287
      resetRefinementStats(sdrTemplate,
1709
287
         inputSymbolDict->getRefinementRegionStats());
1710
3.00k
    } else {
1711
3.00k
      resetRefinementStats(sdrTemplate, NULL);
1712
3.00k
    }
1713
3.29k
  }
1714
1715
  // allocate symbol widths storage
1716
8.00k
  if (huff && !refAgg) {
1717
1.73k
    symWidths = (Guint *)gmallocn(numNewSyms, sizeof(Guint));
1718
1.73k
  }
1719
1720
8.00k
  symHeight = 0;
1721
8.00k
  i = 0;
1722
1.11M
  while (i < numNewSyms) {
1723
1724
    // read the height class delta height
1725
1.11M
    if (!(huff ? huffDecoder->decodeInt(&dh, huffDHTable) :
1726
1.11M
           arithDecoder->decodeInt(&dh, iadhStats)) ||
1727
1.11M
  (dh <= 0 && (Guint)-dh >= symHeight) ||
1728
1.11M
  (dh > 0 && (Guint)dh > UINT_MAX - symHeight)) {
1729
892
      error(errSyntaxError, getPos(),
1730
892
      "Bad delta-height value in JBIG2 symbol dictionary");
1731
892
      goto syntaxError;
1732
892
    }
1733
1.11M
    symHeight += dh;
1734
1.11M
    symWidth = 0;
1735
1.11M
    totalWidth = 0;
1736
1.11M
    j = i;
1737
1738
    // sanity check to avoid extremely long run-times with damaged streams
1739
1.11M
    if (symHeight > 100000) {
1740
497
      error(errSyntaxError, getPos(),
1741
497
      "Bogus symbol height value in JBIG2 symbol dictionary");
1742
497
      goto syntaxError;
1743
497
    }
1744
1745
    // read the symbols in this height class
1746
1.20M
    while (1) {
1747
1748
      // read the delta width
1749
1.20M
      if (huff) {
1750
83.2k
  if (!huffDecoder->decodeInt(&dw, huffDWTable)) {
1751
6.99k
    break;
1752
6.99k
  }
1753
1.12M
      } else {
1754
1.12M
  if (!arithDecoder->decodeInt(&dw, iadwStats)) {
1755
1.08k
    break;
1756
1.08k
  }
1757
1.12M
      }
1758
1.19M
      if ((dw <= 0 && (Guint)-dw >= symWidth) ||
1759
1.19M
    (dw > 0 && (Guint)dw > UINT_MAX - symWidth)) {
1760
713
  error(errSyntaxError, getPos(),
1761
713
        "Bad delta-height value in JBIG2 symbol dictionary");
1762
713
  goto syntaxError;
1763
713
      }
1764
1.19M
      symWidth += dw;
1765
1.19M
      if (i >= numNewSyms) {
1766
256
  error(errSyntaxError, getPos(),
1767
256
        "Too many symbols in JBIG2 symbol dictionary");
1768
256
  goto syntaxError;
1769
256
      }
1770
1771
      // sanity check to avoid extremely long run-times with damaged streams
1772
1.19M
      if (symWidth > 100000) {
1773
181
  error(errSyntaxError, getPos(),
1774
181
        "Bogus symbol width value in JBIG2 symbol dictionary");
1775
181
  goto syntaxError;
1776
181
      }
1777
1778
      // using a collective bitmap, so don't read a bitmap here
1779
1.19M
      if (huff && !refAgg) {
1780
71.3k
  symWidths[i] = symWidth;
1781
71.3k
  totalWidth += symWidth;
1782
1783
      // refinement/aggregate coding
1784
1.12M
      } else if (refAgg) {
1785
1.10M
  if (huff) {
1786
4.41k
    if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) {
1787
1.63k
      break;
1788
1.63k
    }
1789
1.10M
  } else {
1790
1.10M
    if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) {
1791
1.10M
      break;
1792
1.10M
    }
1793
1.10M
  }
1794
6.33k
  if (refAggNum <= 0 || refAggNum > 10000) {
1795
439
    error(errSyntaxError, getPos(),
1796
439
    "Invalid refinement/aggregation instance count in JBIG2 symbol dictionary");
1797
439
    goto syntaxError;
1798
439
  }
1799
#if 0 //~ This special case was added about a year before the final draft
1800
      //~ of the JBIG2 spec was released.  I have encountered some old
1801
      //~ JBIG2 images that predate it.
1802
  if (0) {
1803
#else
1804
5.89k
  if (refAggNum == 1) {
1805
581
#endif
1806
581
    if (huff) {
1807
403
      symID = huffDecoder->readBits(symCodeLen);
1808
403
      huffDecoder->decodeInt(&refDX, huffTableO);
1809
403
      huffDecoder->decodeInt(&refDY, huffTableO);
1810
403
      huffDecoder->decodeInt(&bmSize, huffTableA);
1811
403
      huffDecoder->reset();
1812
403
      arithDecoder->start();
1813
403
    } else {
1814
178
      symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
1815
178
      arithDecoder->decodeInt(&refDX, iardxStats);
1816
178
      arithDecoder->decodeInt(&refDY, iardyStats);
1817
178
    }
1818
581
    if (symID >= numInputSyms + i) {
1819
549
      error(errSyntaxError, getPos(),
1820
549
      "Invalid symbol ID in JBIG2 symbol dictionary");
1821
549
      goto syntaxError;
1822
549
    }
1823
32
    refBitmap = bitmaps[symID];
1824
32
    bitmaps[numInputSyms + i] =
1825
32
        readGenericRefinementRegion(symWidth, symHeight,
1826
32
            sdrTemplate, gFalse,
1827
32
            refBitmap, refDX, refDY,
1828
32
            sdrATX, sdrATY);
1829
    //~ do we need to use the bmSize value here (in Huffman mode)?
1830
5.31k
  } else {
1831
5.31k
    bitmaps[numInputSyms + i] =
1832
5.31k
        readTextRegion(huff, gTrue, symWidth, symHeight,
1833
5.31k
           refAggNum, 0, numInputSyms + i, NULL,
1834
5.31k
           symCodeLen, bitmaps, 0, 0, 0, 1, 0,
1835
5.31k
           huffTableF, huffTableH, huffTableK, huffTableO,
1836
5.31k
           huffTableO, huffTableO, huffTableO, huffTableA,
1837
5.31k
           sdrTemplate, sdrATX, sdrATY);
1838
5.31k
  }
1839
1840
      // non-ref/agg coding
1841
15.3k
      } else {
1842
15.3k
  bitmaps[numInputSyms + i] =
1843
15.3k
      readGenericBitmap(gFalse, symWidth, symHeight,
1844
15.3k
            sdTemplate, gFalse, gFalse, NULL,
1845
15.3k
            sdATX, sdATY, 0);
1846
15.3k
      }
1847
1848
92.0k
      ++i;
1849
92.0k
    }
1850
1851
    // read the collective bitmap
1852
1.11M
    if (huff && !refAgg) {
1853
2.65k
      if (totalWidth == 0) {
1854
763
  error(errSyntaxError, getPos(),
1855
763
        "Invalid height class width in JBIG2 symbol dictionary");
1856
763
  goto syntaxError;
1857
763
      }
1858
1.88k
      huffDecoder->decodeInt(&bmSize, huffBMSizeTable);
1859
1.88k
      huffDecoder->reset();
1860
1.88k
      if (bmSize == 0) {
1861
43
  collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight);
1862
43
  bmSize = symHeight * ((totalWidth + 7) >> 3);
1863
43
  byteCounter += curStr->getBlock((char *)collBitmap->getDataPtr(),
1864
43
          bmSize);
1865
1.84k
      } else {
1866
1.84k
  collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
1867
1.84k
               0, gFalse, gFalse, NULL, NULL, NULL,
1868
1.84k
               bmSize);
1869
1.84k
      }
1870
1.88k
      x = 0;
1871
73.2k
      for (; j < i; ++j) {
1872
71.3k
  bitmaps[numInputSyms + j] =
1873
71.3k
      collBitmap->getSlice(x, 0, symWidths[j], symHeight);
1874
71.3k
  x += symWidths[j];
1875
71.3k
      }
1876
1.88k
      delete collBitmap;
1877
1.88k
    }
1878
1.11M
  }
1879
1880
  // create the symbol dict object
1881
3.71k
  symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
1882
1883
  // exported symbol list
1884
3.71k
  i = j = 0;
1885
3.71k
  ex = gFalse;
1886
3.71k
  prevRun = 1;
1887
5.75k
  while (i < numInputSyms + numNewSyms) {
1888
2.42k
    if (huff) {
1889
186
      huffDecoder->decodeInt(&run, huffTableA);
1890
2.23k
    } else {
1891
2.23k
      arithDecoder->decodeInt(&run, iaexStats);
1892
2.23k
    }
1893
2.42k
    if (run == 0 && prevRun == 0) {
1894
      // this avoids infinite loops with damaged files (consecutive
1895
      // zero runs are never useful)
1896
196
      error(errSyntaxError, getPos(),
1897
196
      "Invalid exported symbol list in JBIG2 symbol dictionary");
1898
196
      delete symbolDict;
1899
196
      goto syntaxError;
1900
196
    }
1901
2.22k
    if (i + run > numInputSyms + numNewSyms ||
1902
2.12k
  (ex && j + run > numExSyms)) {
1903
183
      error(errSyntaxError, getPos(),
1904
183
      "Too many exported symbols in JBIG2 symbol dictionary");
1905
183
      delete symbolDict;
1906
183
      goto syntaxError;
1907
183
    }
1908
2.04k
    if (ex) {
1909
1.92k
      for (cnt = 0; cnt < run; ++cnt) {
1910
1.14k
  symbolDict->setBitmap(j++, bitmaps[i++]->copy());
1911
1.14k
      }
1912
1.25k
    } else {
1913
1.25k
      i += run;
1914
1.25k
    }
1915
2.04k
    ex = !ex;
1916
2.04k
    prevRun = run;
1917
2.04k
  }
1918
3.33k
  if (j != numExSyms) {
1919
270
    error(errSyntaxError, getPos(), "Too few symbols in JBIG2 symbol dictionary");
1920
270
    delete symbolDict;
1921
270
    goto syntaxError;
1922
270
  }
1923
1924
4.64k
  for (i = 0; i < numNewSyms; ++i) {
1925
1.57k
    delete bitmaps[numInputSyms + i];
1926
1.57k
  }
1927
3.06k
  gfree(bitmaps);
1928
3.06k
  if (symWidths) {
1929
186
    gfree(symWidths);
1930
186
  }
1931
1932
  // save the arithmetic decoder stats
1933
3.06k
  if (!huff && contextRetained) {
1934
1.87k
    symbolDict->setGenericRegionStats(genericRegionStats->copy());
1935
1.87k
    if (refAgg) {
1936
1.52k
      symbolDict->setRefinementRegionStats(refinementRegionStats->copy());
1937
1.52k
    }
1938
1.87k
  }
1939
1940
  // store the new symbol dict
1941
3.06k
  segments->append(symbolDict);
1942
1943
3.06k
  return gTrue;
1944
1945
1.48k
 codeTableError:
1946
1.48k
  error(errSyntaxError, getPos(), "Missing code table in JBIG2 symbol dictionary");
1947
1.48k
  delete codeTables;
1948
1949
6.42k
 syntaxError:
1950
294M
  for (i = 0; i < numNewSyms; ++i) {
1951
294M
    if (bitmaps[numInputSyms + i]) {
1952
90.4k
      delete bitmaps[numInputSyms + i];
1953
90.4k
    }
1954
294M
  }
1955
6.42k
  gfree(bitmaps);
1956
6.42k
  if (symWidths) {
1957
1.16k
    gfree(symWidths);
1958
1.16k
  }
1959
6.42k
  return gFalse;
1960
1961
6.87k
 eofError:
1962
6.87k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
1963
6.87k
  return gFalse;
1964
1.48k
}
1965
1966
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
1967
            GBool lossless, Guint length,
1968
20.1k
            Guint *refSegs, Guint nRefSegs) {
1969
20.1k
  JBIG2Bitmap *bitmap;
1970
20.1k
  JBIG2HuffmanTable runLengthTab[36];
1971
20.1k
  JBIG2HuffmanTable *symCodeTab;
1972
20.1k
  JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable;
1973
20.1k
  JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
1974
20.1k
  JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
1975
20.1k
  JBIG2Segment *seg;
1976
20.1k
  GList *codeTables;
1977
20.1k
  JBIG2SymbolDict *symbolDict;
1978
20.1k
  JBIG2Bitmap **syms;
1979
20.1k
  Guint w, h, x, y, segInfoFlags, extCombOp;
1980
20.1k
  Guint flags, huff, refine, logStrips, refCorner, transposed;
1981
20.1k
  Guint combOp, defPixel, templ;
1982
20.1k
  int sOffset;
1983
20.1k
  Guint huffFlags, huffFS, huffDS, huffDT;
1984
20.1k
  Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize;
1985
20.1k
  Guint numInstances, numSyms, symCodeLen;
1986
20.1k
  int atx[2], aty[2];
1987
20.1k
  Guint i, k, kk;
1988
20.1k
  int j;
1989
1990
  // region segment info field
1991
20.1k
  if (!readULong(&w) || !readULong(&h) ||
1992
8.93k
      !readULong(&x) || !readULong(&y) ||
1993
13.2k
      !readUByte(&segInfoFlags)) {
1994
13.2k
    goto eofError;
1995
13.2k
  }
1996
6.81k
  if (w == 0 || h == 0) {
1997
415
    error(errSyntaxError, getPos(), "Bad size in JBIG2 text region segment");
1998
415
    return;
1999
415
  }
2000
  // sanity check: if the w/h/x/y values are way out of range, it likely
2001
  // indicates a damaged JBIG2 stream
2002
6.40k
  if (w / 10 > pageW || h / 10 > pageH ||
2003
6.00k
      x / 10 > pageW || y / 10 > pageH) {
2004
671
    error(errSyntaxError, getPos(),
2005
671
    "Bad size or position in JBIG2 text region segment");
2006
671
    done = gTrue;
2007
671
    return;
2008
671
  }
2009
5.73k
  extCombOp = segInfoFlags & 7;
2010
2011
  // rest of the text region header
2012
5.73k
  if (!readUWord(&flags)) {
2013
244
    goto eofError;
2014
244
  }
2015
5.48k
  huff = flags & 1;
2016
5.48k
  refine = (flags >> 1) & 1;
2017
5.48k
  logStrips = (flags >> 2) & 3;
2018
5.48k
  refCorner = (flags >> 4) & 3;
2019
5.48k
  transposed = (flags >> 6) & 1;
2020
5.48k
  combOp = (flags >> 7) & 3;
2021
5.48k
  defPixel = (flags >> 9) & 1;
2022
5.48k
  sOffset = (flags >> 10) & 0x1f;
2023
5.48k
  if (sOffset & 0x10) {
2024
3.26k
    sOffset |= -1 - 0x0f;
2025
3.26k
  }
2026
5.48k
  templ = (flags >> 15) & 1;
2027
5.48k
  huffFS = huffDS = huffDT = 0; // make gcc happy
2028
5.48k
  huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0; // make gcc happy
2029
5.48k
  if (huff) {
2030
4.23k
    if (!readUWord(&huffFlags)) {
2031
197
      goto eofError;
2032
197
    }
2033
4.03k
    huffFS = huffFlags & 3;
2034
4.03k
    huffDS = (huffFlags >> 2) & 3;
2035
4.03k
    huffDT = (huffFlags >> 4) & 3;
2036
4.03k
    huffRDW = (huffFlags >> 6) & 3;
2037
4.03k
    huffRDH = (huffFlags >> 8) & 3;
2038
4.03k
    huffRDX = (huffFlags >> 10) & 3;
2039
4.03k
    huffRDY = (huffFlags >> 12) & 3;
2040
4.03k
    huffRSize = (huffFlags >> 14) & 1;
2041
4.03k
  }
2042
5.29k
  if (refine && templ == 0) {
2043
2.06k
    if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
2044
1.69k
  !readByte(&atx[1]) || !readByte(&aty[1])) {
2045
794
      goto eofError;
2046
794
    }
2047
2.06k
  }
2048
4.49k
  if (!readULong(&numInstances)) {
2049
230
    goto eofError;
2050
230
  }
2051
2052
  // get symbol dictionaries and tables
2053
4.26k
  codeTables = new GList();
2054
4.26k
  numSyms = 0;
2055
11.2k
  for (i = 0; i < nRefSegs; ++i) {
2056
7.85k
    if ((seg = findSegment(refSegs[i]))) {
2057
6.94k
      if (seg->getType() == jbig2SegSymbolDict) {
2058
458
  Guint segSize = ((JBIG2SymbolDict *)seg)->getSize();
2059
458
  if (segSize > INT_MAX || numSyms > INT_MAX - segSize) {
2060
0
    error(errSyntaxError, getPos(),
2061
0
    "Too many symbols in JBIG2 text region");
2062
0
    delete codeTables;
2063
0
    return;
2064
0
  }
2065
458
  numSyms += segSize;
2066
6.49k
      } else if (seg->getType() == jbig2SegCodeTable) {
2067
6.22k
  codeTables->append(seg);
2068
6.22k
      }
2069
6.94k
    } else {
2070
910
      error(errSyntaxError, getPos(),
2071
910
      "Invalid segment reference in JBIG2 text region");
2072
910
      delete codeTables;
2073
910
      return;
2074
910
    }
2075
7.85k
  }
2076
3.35k
  i = numSyms;
2077
3.35k
  if (i <= 1) {
2078
3.35k
    symCodeLen = huff ? 1 : 0;
2079
3.35k
  } else {
2080
0
    --i;
2081
0
    symCodeLen = 0;
2082
    // i = floor((numSyms-1) / 2^symCodeLen)
2083
0
    while (i > 0) {
2084
0
      ++symCodeLen;
2085
0
      i >>= 1;
2086
0
    }
2087
0
  }
2088
2089
  // get the symbol bitmaps
2090
3.35k
  syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *));
2091
3.35k
  kk = 0;
2092
9.93k
  for (i = 0; i < nRefSegs; ++i) {
2093
6.57k
    if ((seg = findSegment(refSegs[i]))) {
2094
6.57k
      if (seg->getType() == jbig2SegSymbolDict) {
2095
444
  symbolDict = (JBIG2SymbolDict *)seg;
2096
444
  for (k = 0; k < symbolDict->getSize(); ++k) {
2097
0
    syms[kk++] = symbolDict->getBitmap(k);
2098
0
  }
2099
444
      }
2100
6.57k
    }
2101
6.57k
  }
2102
2103
  // get the Huffman tables
2104
3.35k
  huffFSTable = huffDSTable = huffDTTable = NULL; // make gcc happy
2105
3.35k
  huffRDWTable = huffRDHTable = NULL; // make gcc happy
2106
3.35k
  huffRDXTable = huffRDYTable = huffRSizeTable = NULL; // make gcc happy
2107
3.35k
  i = 0;
2108
3.35k
  if (huff) {
2109
3.03k
    if (huffFS == 0) {
2110
779
      huffFSTable = huffTableF;
2111
2.25k
    } else if (huffFS == 1) {
2112
1.26k
      huffFSTable = huffTableG;
2113
1.26k
    } else {
2114
982
      if (i >= (Guint)codeTables->getLength()) {
2115
320
  goto codeTableError;
2116
320
      }
2117
662
      huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2118
662
    }
2119
2.71k
    if (huffDS == 0) {
2120
527
      huffDSTable = huffTableH;
2121
2.18k
    } else if (huffDS == 1) {
2122
959
      huffDSTable = huffTableI;
2123
1.22k
    } else if (huffDS == 2) {
2124
572
      huffDSTable = huffTableJ;
2125
652
    } else {
2126
652
      if (i >= (Guint)codeTables->getLength()) {
2127
169
  goto codeTableError;
2128
169
      }
2129
483
      huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2130
483
    }
2131
2.54k
    if (huffDT == 0) {
2132
328
      huffDTTable = huffTableK;
2133
2.21k
    } else if (huffDT == 1) {
2134
619
      huffDTTable = huffTableL;
2135
1.59k
    } else if (huffDT == 2) {
2136
822
      huffDTTable = huffTableM;
2137
822
    } else {
2138
772
      if (i >= (Guint)codeTables->getLength()) {
2139
367
  goto codeTableError;
2140
367
      }
2141
405
      huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2142
405
    }
2143
2.17k
    if (huffRDW == 0) {
2144
577
      huffRDWTable = huffTableN;
2145
1.59k
    } else if (huffRDW == 1) {
2146
716
      huffRDWTable = huffTableO;
2147
881
    } else {
2148
881
      if (i >= (Guint)codeTables->getLength()) {
2149
248
  goto codeTableError;
2150
248
      }
2151
633
      huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2152
633
    }
2153
1.92k
    if (huffRDH == 0) {
2154
591
      huffRDHTable = huffTableN;
2155
1.33k
    } else if (huffRDH == 1) {
2156
908
      huffRDHTable = huffTableO;
2157
908
    } else {
2158
427
      if (i >= (Guint)codeTables->getLength()) {
2159
239
  goto codeTableError;
2160
239
      }
2161
188
      huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2162
188
    }
2163
1.68k
    if (huffRDX == 0) {
2164
279
      huffRDXTable = huffTableN;
2165
1.40k
    } else if (huffRDX == 1) {
2166
795
      huffRDXTable = huffTableO;
2167
795
    } else {
2168
613
      if (i >= (Guint)codeTables->getLength()) {
2169
88
  goto codeTableError;
2170
88
      }
2171
525
      huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2172
525
    }
2173
1.59k
    if (huffRDY == 0) {
2174
609
      huffRDYTable = huffTableN;
2175
990
    } else if (huffRDY == 1) {
2176
407
      huffRDYTable = huffTableO;
2177
583
    } else {
2178
583
      if (i >= (Guint)codeTables->getLength()) {
2179
234
  goto codeTableError;
2180
234
      }
2181
349
      huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2182
349
    }
2183
1.36k
    if (huffRSize == 0) {
2184
581
      huffRSizeTable = huffTableA;
2185
784
    } else {
2186
784
      if (i >= (Guint)codeTables->getLength()) {
2187
360
  goto codeTableError;
2188
360
      }
2189
424
      huffRSizeTable =
2190
424
    ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2191
424
    }
2192
1.36k
  }
2193
1.33k
  delete codeTables;
2194
2195
  // symbol ID Huffman decoding table
2196
1.33k
  if (huff) {
2197
1.00k
    huffDecoder->reset();
2198
33.1k
    for (i = 0; i < 32; ++i) {
2199
32.1k
      runLengthTab[i].val = i;
2200
32.1k
      runLengthTab[i].prefixLen = huffDecoder->readBits(4);
2201
32.1k
      runLengthTab[i].rangeLen = 0;
2202
32.1k
      runLengthTab[i].prefix = 0;
2203
32.1k
    }
2204
1.00k
    runLengthTab[32].val = 0x103;
2205
1.00k
    runLengthTab[32].prefixLen = huffDecoder->readBits(4);
2206
1.00k
    runLengthTab[32].rangeLen = 2;
2207
1.00k
    runLengthTab[32].prefix = 0;
2208
1.00k
    runLengthTab[33].val = 0x203;
2209
1.00k
    runLengthTab[33].prefixLen = huffDecoder->readBits(4);
2210
1.00k
    runLengthTab[33].rangeLen = 3;
2211
1.00k
    runLengthTab[33].prefix = 0;
2212
1.00k
    runLengthTab[34].val = 0x20b;
2213
1.00k
    runLengthTab[34].prefixLen = huffDecoder->readBits(4);
2214
1.00k
    runLengthTab[34].rangeLen = 7;
2215
1.00k
    runLengthTab[34].prefix = 0;
2216
1.00k
    runLengthTab[35].prefixLen = 0;
2217
1.00k
    runLengthTab[35].rangeLen = jbig2HuffmanEOT;
2218
1.00k
    runLengthTab[35].prefix = 0;
2219
1.00k
    huffDecoder->buildTable(runLengthTab, 35);
2220
1.00k
    symCodeTab = (JBIG2HuffmanTable *)gmallocn(numSyms + 1,
2221
1.00k
                 sizeof(JBIG2HuffmanTable));
2222
1.00k
    for (i = 0; i < numSyms; ++i) {
2223
0
      symCodeTab[i].val = i;
2224
0
      symCodeTab[i].rangeLen = 0;
2225
0
    }
2226
1.00k
    i = 0;
2227
1.00k
    while (i < numSyms) {
2228
0
      huffDecoder->decodeInt(&j, runLengthTab);
2229
0
      if (j > 0x200) {
2230
0
  for (j -= 0x200; j && i < numSyms; --j) {
2231
0
    symCodeTab[i++].prefixLen = 0;
2232
0
  }
2233
0
      } else if (j > 0x100) {
2234
0
  if (i == 0) {
2235
0
    error(errSyntaxError, getPos(), "Invalid code in JBIG2 text region");
2236
0
    gfree(syms);
2237
0
    gfree(symCodeTab);
2238
0
    return;
2239
0
  }
2240
0
  for (j -= 0x100; j && i < numSyms; --j) {
2241
0
    symCodeTab[i].prefixLen = symCodeTab[i-1].prefixLen;
2242
0
    ++i;
2243
0
  }
2244
0
      } else {
2245
0
  symCodeTab[i++].prefixLen = j;
2246
0
      }
2247
0
    }
2248
1.00k
    symCodeTab[numSyms].prefixLen = 0;
2249
1.00k
    symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT;
2250
1.00k
    huffDecoder->buildTable(symCodeTab, numSyms);
2251
1.00k
    huffDecoder->reset();
2252
2253
  // set up the arithmetic decoder
2254
1.00k
  } else {
2255
326
    symCodeTab = NULL;
2256
326
    resetIntStats(symCodeLen);
2257
326
    arithDecoder->start();
2258
326
  }
2259
1.33k
  if (refine) {
2260
539
    resetRefinementStats(templ, NULL);
2261
539
  }
2262
2263
1.33k
  bitmap = readTextRegion(huff, refine, w, h, numInstances,
2264
1.33k
        logStrips, numSyms, symCodeTab, symCodeLen, syms,
2265
1.33k
        defPixel, combOp, transposed, refCorner, sOffset,
2266
1.33k
        huffFSTable, huffDSTable, huffDTTable,
2267
1.33k
        huffRDWTable, huffRDHTable,
2268
1.33k
        huffRDXTable, huffRDYTable, huffRSizeTable,
2269
1.33k
        templ, atx, aty);
2270
2271
1.33k
  gfree(syms);
2272
2273
  // combine the region bitmap into the page bitmap
2274
1.33k
  if (imm) {
2275
1.13k
    if (pageH == 0xffffffff && y + h > curPageH) {
2276
83
      pageBitmap->expand(y + h, pageDefPixel);
2277
83
    }
2278
1.13k
    pageBitmap->combine(bitmap, x, y, extCombOp);
2279
1.13k
    delete bitmap;
2280
2281
  // store the region bitmap
2282
1.13k
  } else {
2283
199
    bitmap->setSegNum(segNum);
2284
199
    segments->append(bitmap);
2285
199
  }
2286
2287
  // clean up the Huffman decoder
2288
1.33k
  if (huff) {
2289
1.00k
    gfree(symCodeTab);
2290
1.00k
  }
2291
2292
1.33k
  return;
2293
2294
2.02k
 codeTableError:
2295
2.02k
  error(errSyntaxError, getPos(), "Missing code table in JBIG2 text region");
2296
2.02k
  delete codeTables;
2297
2.02k
  gfree(syms);
2298
2.02k
  return;
2299
2300
14.7k
 eofError:
2301
14.7k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
2302
14.7k
  return;
2303
1.33k
}
2304
2305
JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
2306
           int w, int h,
2307
           Guint numInstances,
2308
           Guint logStrips,
2309
           int numSyms,
2310
           JBIG2HuffmanTable *symCodeTab,
2311
           Guint symCodeLen,
2312
           JBIG2Bitmap **syms,
2313
           Guint defPixel, Guint combOp,
2314
           Guint transposed, Guint refCorner,
2315
           int sOffset,
2316
           JBIG2HuffmanTable *huffFSTable,
2317
           JBIG2HuffmanTable *huffDSTable,
2318
           JBIG2HuffmanTable *huffDTTable,
2319
           JBIG2HuffmanTable *huffRDWTable,
2320
           JBIG2HuffmanTable *huffRDHTable,
2321
           JBIG2HuffmanTable *huffRDXTable,
2322
           JBIG2HuffmanTable *huffRDYTable,
2323
           JBIG2HuffmanTable *huffRSizeTable,
2324
           Guint templ,
2325
6.64k
           int *atx, int *aty) {
2326
6.64k
  JBIG2Bitmap *bitmap;
2327
6.64k
  JBIG2Bitmap *symbolBitmap;
2328
6.64k
  Guint strips;
2329
6.64k
  int t, dt, tt, s, ds, sFirst, j;
2330
6.64k
  int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize;
2331
6.64k
  Guint symID, inst, bw, bh;
2332
2333
6.64k
  strips = 1 << logStrips;
2334
2335
  // allocate the bitmap
2336
6.64k
  bitmap = new JBIG2Bitmap(0, w, h);
2337
6.64k
  if (defPixel) {
2338
282
    bitmap->clearToOne();
2339
6.36k
  } else {
2340
6.36k
    bitmap->clearToZero();
2341
6.36k
  }
2342
2343
  // decode initial T value
2344
6.64k
  if (huff) {
2345
3.21k
    huffDecoder->decodeInt(&t, huffDTTable);
2346
3.43k
  } else {
2347
3.43k
    arithDecoder->decodeInt(&t, iadtStats);
2348
3.43k
  }
2349
6.64k
  t *= -(int)strips;
2350
2351
6.64k
  inst = 0;
2352
6.64k
  sFirst = 0;
2353
38.1k
  while (inst < numInstances) {
2354
2355
    // decode delta-T
2356
32.8k
    if (huff) {
2357
23.5k
      if (!huffDecoder->decodeInt(&dt, huffDTTable)) {
2358
368
  break;
2359
368
      }
2360
23.5k
    } else {
2361
9.28k
      if (!arithDecoder->decodeInt(&dt, iadtStats)) {
2362
160
  break;
2363
160
      }
2364
9.28k
    }
2365
32.3k
    t += dt * strips;
2366
2367
    // first S value
2368
32.3k
    if (huff) {
2369
23.2k
      if (!huffDecoder->decodeInt(&ds, huffFSTable)) {
2370
242
  break;
2371
242
      }
2372
23.2k
    } else {
2373
9.12k
      if (!arithDecoder->decodeInt(&ds, iafsStats)) {
2374
595
  break;
2375
595
      }
2376
9.12k
    }
2377
31.5k
    sFirst += ds;
2378
31.5k
    s = sFirst;
2379
2380
    // read the instances
2381
    // (this loop test is here to avoid an infinite loop with damaged
2382
    // JBIG2 streams where the normal loop exit doesn't get triggered)
2383
505k
    while (inst < numInstances) {
2384
2385
      // T value
2386
500k
      if (strips == 1) {
2387
498k
  dt = 0;
2388
498k
      } else if (huff) {
2389
1.95k
  dt = huffDecoder->readBits(logStrips);
2390
1.95k
      } else {
2391
413
  arithDecoder->decodeInt(&dt, iaitStats);
2392
413
      }
2393
500k
      tt = t + dt;
2394
2395
      // symbol ID
2396
500k
      if (huff) {
2397
119k
  if (symCodeTab) {
2398
1.99k
    huffDecoder->decodeInt(&j, symCodeTab);
2399
1.99k
    symID = (Guint)j;
2400
117k
  } else {
2401
117k
    symID = huffDecoder->readBits(symCodeLen);
2402
117k
  }
2403
381k
      } else {
2404
381k
  symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
2405
381k
      }
2406
2407
500k
      if (symID >= (Guint)numSyms) {
2408
472k
  error(errSyntaxError, getPos(),
2409
472k
        "Invalid symbol number in JBIG2 text region");
2410
472k
      } else {
2411
2412
  // get the symbol bitmap
2413
28.5k
  symbolBitmap = NULL;
2414
28.5k
  if (refine) {
2415
28.5k
    if (huff) {
2416
27.1k
      ri = (int)huffDecoder->readBit();
2417
27.1k
    } else {
2418
1.37k
      arithDecoder->decodeInt(&ri, iariStats);
2419
1.37k
    }
2420
28.5k
  } else {
2421
0
    ri = 0;
2422
0
  }
2423
28.5k
  if (ri) {
2424
4.25k
    if (huff) {
2425
2.88k
      huffDecoder->decodeInt(&rdw, huffRDWTable);
2426
2.88k
      huffDecoder->decodeInt(&rdh, huffRDHTable);
2427
2.88k
      huffDecoder->decodeInt(&rdx, huffRDXTable);
2428
2.88k
      huffDecoder->decodeInt(&rdy, huffRDYTable);
2429
2.88k
      huffDecoder->decodeInt(&bmSize, huffRSizeTable);
2430
2.88k
      huffDecoder->reset();
2431
2.88k
      arithDecoder->start();
2432
2.88k
    } else {
2433
1.37k
      arithDecoder->decodeInt(&rdw, iardwStats);
2434
1.37k
      arithDecoder->decodeInt(&rdh, iardhStats);
2435
1.37k
      arithDecoder->decodeInt(&rdx, iardxStats);
2436
1.37k
      arithDecoder->decodeInt(&rdy, iardyStats);
2437
1.37k
    }
2438
4.25k
    refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
2439
4.25k
    refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
2440
2441
4.25k
    if (rdw > INT_MAX - syms[symID]->getWidth() ||
2442
4.03k
        rdh > INT_MAX - syms[symID]->getHeight()) {
2443
279
      error(errSyntaxError, getPos(),
2444
279
      "Invalid refinement size in JBIG2 text region");
2445
279
      continue;
2446
279
    }
2447
    // sanity check
2448
3.97k
    if (rdw > 1000 || rdh > 1000) {
2449
662
      error(errSyntaxError, getPos(),
2450
662
      "Invalid refinement size in JBIG2 text region");
2451
662
      continue;
2452
662
    }
2453
3.31k
    symbolBitmap =
2454
3.31k
      readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
2455
3.31k
          rdh + syms[symID]->getHeight(),
2456
3.31k
          templ, gFalse, syms[symID],
2457
3.31k
          refDX, refDY, atx, aty);
2458
    //~ do we need to use the bmSize value here (in Huffman mode)?
2459
24.3k
  } else {
2460
24.3k
    symbolBitmap = syms[symID];
2461
24.3k
  }
2462
2463
  // combine the symbol bitmap into the region bitmap
2464
  //~ something is wrong here - refCorner shouldn't degenerate into
2465
  //~   two cases
2466
27.6k
  bw = symbolBitmap->getWidth() - 1;
2467
27.6k
  bh = symbolBitmap->getHeight() - 1;
2468
27.6k
  if (transposed) {
2469
0
    switch (refCorner) {
2470
0
    case 0: // bottom left
2471
0
      bitmap->combine(symbolBitmap, tt, s, combOp);
2472
0
      break;
2473
0
    case 1: // top left
2474
0
      bitmap->combine(symbolBitmap, tt, s, combOp);
2475
0
      break;
2476
0
    case 2: // bottom right
2477
0
      bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2478
0
      break;
2479
0
    case 3: // top right
2480
0
      bitmap->combine(symbolBitmap, tt - bw, s, combOp);
2481
0
      break;
2482
0
    }
2483
0
    s += bh;
2484
27.6k
  } else {
2485
27.6k
    switch (refCorner) {
2486
0
    case 0: // bottom left
2487
0
      bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2488
0
      break;
2489
27.6k
    case 1: // top left
2490
27.6k
      bitmap->combine(symbolBitmap, s, tt, combOp);
2491
27.6k
      break;
2492
0
    case 2: // bottom right
2493
0
      bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2494
0
      break;
2495
0
    case 3: // top right
2496
0
      bitmap->combine(symbolBitmap, s, tt, combOp);
2497
0
      break;
2498
27.6k
    }
2499
27.6k
    s += bw;
2500
27.6k
  }
2501
27.6k
  if (ri) {
2502
3.31k
    delete symbolBitmap;
2503
3.31k
  }
2504
27.6k
      }
2505
2506
      // next instance
2507
499k
      ++inst;
2508
2509
      // next S value
2510
499k
      if (huff) {
2511
118k
  if (!huffDecoder->decodeInt(&ds, huffDSTable)) {
2512
21.0k
    break;
2513
21.0k
  }
2514
381k
      } else {
2515
381k
  if (!arithDecoder->decodeInt(&ds, iadsStats)) {
2516
5.90k
    break;
2517
5.90k
  }
2518
381k
      }
2519
472k
      s += sOffset + ds;
2520
472k
    }
2521
31.5k
  }
2522
2523
6.64k
  return bitmap;
2524
6.64k
}
2525
2526
2.53k
void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
2527
2.53k
  JBIG2PatternDict *patternDict;
2528
2.53k
  JBIG2Bitmap *bitmap;
2529
2.53k
  Guint flags, patternW, patternH, grayMax, templ, mmr;
2530
2.53k
  int atx[4], aty[4];
2531
2.53k
  Guint i, x;
2532
2533
  // halftone dictionary flags, pattern width and height, max gray value
2534
2.53k
  if (!readUByte(&flags) ||
2535
2.33k
      !readUByte(&patternW) ||
2536
2.26k
      !readUByte(&patternH) ||
2537
2.23k
      !readULong(&grayMax)) {
2538
937
    goto eofError;
2539
937
  }
2540
1.59k
  if (patternW == 0 || patternH == 0 ||
2541
1.32k
      grayMax > UINT_MAX / patternW - 1) {
2542
377
    error(errSyntaxError, getPos(),
2543
377
    "Bad size in JBIG2 pattern dictionary segment");
2544
377
    return;
2545
377
  }
2546
1.21k
  templ = (flags >> 1) & 3;
2547
1.21k
  mmr = flags & 1;
2548
2549
  // set up the arithmetic decoder
2550
1.21k
  if (!mmr) {
2551
272
    resetGenericStats(templ, NULL);
2552
272
    arithDecoder->start();
2553
272
  }
2554
2555
  // read the bitmap
2556
1.21k
  atx[0] = -(int)patternW; aty[0] =  0;
2557
1.21k
  atx[1] = -3;             aty[1] = -1;
2558
1.21k
  atx[2] =  2;             aty[2] = -2;
2559
1.21k
  atx[3] = -2;             aty[3] = -2;
2560
1.21k
  bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
2561
1.21k
           templ, gFalse, gFalse, NULL,
2562
1.21k
           atx, aty, length - 7);
2563
2564
  // create the pattern dict object
2565
1.21k
  patternDict = new JBIG2PatternDict(segNum, grayMax + 1);
2566
2567
  // split up the bitmap
2568
1.21k
  x = 0;
2569
38.4k
  for (i = 0; i <= grayMax; ++i) {
2570
37.2k
    patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
2571
37.2k
    x += patternW;
2572
37.2k
  }
2573
2574
  // free memory
2575
1.21k
  delete bitmap;
2576
2577
  // store the new pattern dict
2578
1.21k
  segments->append(patternDict);
2579
2580
1.21k
  return;
2581
2582
937
 eofError:
2583
937
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
2584
937
}
2585
2586
void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
2587
          GBool lossless, Guint length,
2588
8.36k
          Guint *refSegs, Guint nRefSegs) {
2589
8.36k
  JBIG2Bitmap *bitmap;
2590
8.36k
  JBIG2Segment *seg;
2591
8.36k
  JBIG2PatternDict *patternDict;
2592
8.36k
  JBIG2Bitmap *skipBitmap;
2593
8.36k
  Guint *grayImg;
2594
8.36k
  JBIG2Bitmap *grayBitmap;
2595
8.36k
  JBIG2Bitmap *patternBitmap;
2596
8.36k
  Guint w, h, x, y, segInfoFlags, extCombOp;
2597
8.36k
  Guint flags, mmr, templ, enableSkip, combOp;
2598
8.36k
  Guint gridW, gridH, stepX, stepY, patW, patH;
2599
8.36k
  int atx[4], aty[4];
2600
8.36k
  int gridX, gridY, xx, yy, bit, j;
2601
8.36k
  Guint bpp, m, n, i;
2602
2603
  // region segment info field
2604
8.36k
  if (!readULong(&w) || !readULong(&h) ||
2605
6.64k
      !readULong(&x) || !readULong(&y) ||
2606
5.16k
      !readUByte(&segInfoFlags)) {
2607
3.43k
    goto eofError;
2608
3.43k
  }
2609
  // sanity check: if the w/h/x/y values are way out of range, it likely
2610
  // indicates a damaged JBIG2 stream
2611
4.92k
  if (w / 10 > pageW || h / 10 > pageH ||
2612
4.12k
      x / 10 > pageW || y / 10 > pageH) {
2613
1.24k
    error(errSyntaxError, getPos(),
2614
1.24k
    "Bad size or position in JBIG2 halftone region segment");
2615
1.24k
    done = gTrue;
2616
1.24k
    return;
2617
1.24k
  }
2618
3.68k
  extCombOp = segInfoFlags & 7;
2619
2620
  // rest of the halftone region header
2621
3.68k
  if (!readUByte(&flags)) {
2622
50
    goto eofError;
2623
50
  }
2624
3.63k
  mmr = flags & 1;
2625
3.63k
  templ = (flags >> 1) & 3;
2626
3.63k
  enableSkip = (flags >> 3) & 1;
2627
3.63k
  combOp = (flags >> 4) & 7;
2628
3.63k
  if (!readULong(&gridW) || !readULong(&gridH) ||
2629
3.00k
      !readLong(&gridX) || !readLong(&gridY) ||
2630
2.10k
      !readUWord(&stepX) || !readUWord(&stepY)) {
2631
2.01k
    goto eofError;
2632
2.01k
  }
2633
1.62k
  if (w == 0 || h == 0 || w >= INT_MAX / h) {
2634
554
    error(errSyntaxError, getPos(),
2635
554
    "Bad bitmap size in JBIG2 halftone segment");
2636
554
    return;
2637
554
  }
2638
1.07k
  if (gridW == 0 || gridH == 0 || gridW >= INT_MAX / gridH) {
2639
623
    error(errSyntaxError, getPos(), "Bad grid size in JBIG2 halftone segment");
2640
623
    return;
2641
623
  }
2642
2643
  // get pattern dictionary
2644
447
  if (nRefSegs != 1) {
2645
236
    error(errSyntaxError, getPos(),
2646
236
    "Bad symbol dictionary reference in JBIG2 halftone segment");
2647
236
    return;
2648
236
  }
2649
211
  if (!(seg = findSegment(refSegs[0])) ||
2650
211
      seg->getType() != jbig2SegPatternDict) {
2651
211
    error(errSyntaxError, getPos(),
2652
211
    "Bad symbol dictionary reference in JBIG2 halftone segment");
2653
211
    return;
2654
211
  }
2655
0
  patternDict = (JBIG2PatternDict *)seg;
2656
0
  i = patternDict->getSize();
2657
0
  if (i <= 1) {
2658
0
    bpp = 0;
2659
0
  } else {
2660
0
    --i;
2661
0
    bpp = 0;
2662
    // i = floor((size-1) / 2^bpp)
2663
0
    while (i > 0) {
2664
0
      ++bpp;
2665
0
      i >>= 1;
2666
0
    }
2667
0
  }
2668
0
  patW = patternDict->getBitmap(0)->getWidth();
2669
0
  patH = patternDict->getBitmap(0)->getHeight();
2670
2671
  // set up the arithmetic decoder
2672
0
  if (!mmr) {
2673
0
    resetGenericStats(templ, NULL);
2674
0
    arithDecoder->start();
2675
0
  }
2676
2677
  // allocate the bitmap
2678
0
  bitmap = new JBIG2Bitmap(segNum, w, h);
2679
0
  if (flags & 0x80) { // HDEFPIXEL
2680
0
    bitmap->clearToOne();
2681
0
  } else {
2682
0
    bitmap->clearToZero();
2683
0
  }
2684
2685
  // compute the skip bitmap
2686
0
  skipBitmap = NULL;
2687
0
  if (enableSkip) {
2688
0
    skipBitmap = new JBIG2Bitmap(0, gridW, gridH);
2689
0
    skipBitmap->clearToZero();
2690
0
    for (m = 0; m < gridH; ++m) {
2691
0
      for (n = 0; n < gridW; ++n) {
2692
0
  xx = gridX + m * stepY + n * stepX;
2693
0
  yy = gridY + m * stepX - n * stepY;
2694
0
  if (((xx + (int)patW) >> 8) <= 0 || (xx >> 8) >= (int)w ||
2695
0
      ((yy + (int)patH) >> 8) <= 0 || (yy >> 8) >= (int)h) {
2696
0
    skipBitmap->setPixel(n, m);
2697
0
  }
2698
0
      }
2699
0
    }
2700
0
  }
2701
2702
  // read the gray-scale image
2703
0
  grayImg = (Guint *)gmallocn(gridW * gridH, sizeof(Guint));
2704
0
  memset(grayImg, 0, gridW * gridH * sizeof(Guint));
2705
0
  atx[0] = templ <= 1 ? 3 : 2;  aty[0] = -1;
2706
0
  atx[1] = -3;                  aty[1] = -1;
2707
0
  atx[2] =  2;                  aty[2] = -2;
2708
0
  atx[3] = -2;                  aty[3] = -2;
2709
0
  for (j = bpp - 1; j >= 0; --j) {
2710
0
    grayBitmap = readGenericBitmap(mmr, gridW, gridH, templ, gFalse,
2711
0
           enableSkip, skipBitmap, atx, aty, -1);
2712
0
    i = 0;
2713
0
    for (m = 0; m < gridH; ++m) {
2714
0
      for (n = 0; n < gridW; ++n) {
2715
0
  bit = grayBitmap->getPixel(n, m) ^ (grayImg[i] & 1);
2716
0
  grayImg[i] = (grayImg[i] << 1) | bit;
2717
0
  ++i;
2718
0
      }
2719
0
    }
2720
0
    delete grayBitmap;
2721
0
  }
2722
2723
  // decode the image
2724
0
  i = 0;
2725
0
  for (m = 0; m < gridH; ++m) {
2726
0
    xx = gridX + m * stepY;
2727
0
    yy = gridY + m * stepX;
2728
0
    for (n = 0; n < gridW; ++n) {
2729
0
      if (!(enableSkip && skipBitmap->getPixel(n, m))) {
2730
0
  Guint gray = grayImg[i];
2731
0
  if (gray >= patternDict->getSize()) {
2732
0
    error(errSyntaxError, getPos(),
2733
0
    "Invalid gray value in JBIG2 halftone segment");
2734
0
    gfree(grayImg);
2735
0
    if (skipBitmap) {
2736
0
      delete skipBitmap;
2737
0
    }
2738
0
    delete bitmap;
2739
0
    return;
2740
0
  }
2741
0
  patternBitmap = patternDict->getBitmap(gray);
2742
0
  bitmap->combine(patternBitmap, xx >> 8, yy >> 8, combOp);
2743
0
      }
2744
0
      xx += stepX;
2745
0
      yy -= stepY;
2746
0
      ++i;
2747
0
    }
2748
0
  }
2749
2750
0
  gfree(grayImg);
2751
0
  if (skipBitmap) {
2752
0
    delete skipBitmap;
2753
0
  }
2754
2755
  // combine the region bitmap into the page bitmap
2756
0
  if (imm) {
2757
0
    if (pageH == 0xffffffff && y + h > curPageH) {
2758
0
      pageBitmap->expand(y + h, pageDefPixel);
2759
0
    }
2760
0
    pageBitmap->combine(bitmap, x, y, extCombOp);
2761
0
    delete bitmap;
2762
2763
  // store the region bitmap
2764
0
  } else {
2765
0
    segments->append(bitmap);
2766
0
  }
2767
2768
0
  return;
2769
2770
5.49k
 eofError:
2771
5.49k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
2772
5.49k
}
2773
2774
void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
2775
9.62k
               GBool lossless, Guint length) {
2776
9.62k
  JBIG2Bitmap *bitmap;
2777
9.62k
  Guint w, h, x, y, segInfoFlags, extCombOp, rowCount;
2778
9.62k
  Guint flags, mmr, templ, tpgdOn;
2779
9.62k
  int atx[4], aty[4];
2780
2781
  // region segment info field
2782
9.62k
  if (!readULong(&w) || !readULong(&h) ||
2783
8.08k
      !readULong(&x) || !readULong(&y) ||
2784
6.39k
      !readUByte(&segInfoFlags)) {
2785
3.52k
    goto eofError;
2786
3.52k
  }
2787
6.09k
  if (w == 0 || h == 0) {
2788
491
    error(errSyntaxError, getPos(),
2789
491
    "Bad bitmap size in JBIG2 generic region segment");
2790
491
    return;
2791
491
  }
2792
  // sanity check: if the w/h/x/y values are way out of range, it likely
2793
  // indicates a damaged JBIG2 stream
2794
5.60k
  if (w / 10 > pageW || h / 10 > pageH ||
2795
5.03k
      x / 10 > pageW || y / 10 > pageH) {
2796
983
    error(errSyntaxError, getPos(),
2797
983
    "Bad size or position in JBIG2 generic region segment");
2798
983
    done = gTrue;
2799
983
    return;
2800
983
  }
2801
4.62k
  extCombOp = segInfoFlags & 7;
2802
2803
  // rest of the generic region segment header
2804
4.62k
  if (!readUByte(&flags)) {
2805
270
    goto eofError;
2806
270
  }
2807
4.35k
  mmr = flags & 1;
2808
4.35k
  templ = (flags >> 1) & 3;
2809
4.35k
  tpgdOn = (flags >> 3) & 1;
2810
2811
  // AT flags
2812
4.35k
  if (!mmr) {
2813
3.90k
    if (templ == 0) {
2814
2.58k
      if (!readByte(&atx[0]) ||
2815
2.36k
    !readByte(&aty[0]) ||
2816
2.09k
    !readByte(&atx[1]) ||
2817
1.80k
    !readByte(&aty[1]) ||
2818
1.55k
    !readByte(&atx[2]) ||
2819
1.36k
    !readByte(&aty[2]) ||
2820
1.17k
    !readByte(&atx[3]) ||
2821
1.91k
    !readByte(&aty[3])) {
2822
1.91k
  goto eofError;
2823
1.91k
      }
2824
2.58k
    } else {
2825
1.31k
      if (!readByte(&atx[0]) ||
2826
1.09k
    !readByte(&aty[0])) {
2827
503
  goto eofError;
2828
503
      }
2829
1.31k
    }
2830
3.90k
  }
2831
2832
  // set up the arithmetic decoder
2833
1.94k
  if (!mmr) {
2834
1.48k
    resetGenericStats(templ, NULL);
2835
1.48k
    arithDecoder->start();
2836
1.48k
  }
2837
2838
  // read the bitmap
2839
1.94k
  bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
2840
1.94k
           NULL, atx, aty, mmr ? length - 18 : 0);
2841
2842
  // combine the region bitmap into the page bitmap
2843
1.94k
  if (imm) {
2844
1.60k
    if (pageH == 0xffffffff && y + h > curPageH) {
2845
650
      pageBitmap->expand(y + h, pageDefPixel);
2846
650
    }
2847
1.60k
    pageBitmap->combine(bitmap, x, y, extCombOp);
2848
1.60k
    delete bitmap;
2849
2850
  // store the region bitmap
2851
1.60k
  } else {
2852
334
    bitmap->setSegNum(segNum);
2853
334
    segments->append(bitmap);
2854
334
  }
2855
2856
  // immediate generic segments can have an unspecified length, in
2857
  // which case, a row count is stored at the end of the segment
2858
1.94k
  if (imm && length == 0xffffffff) {
2859
556
    readULong(&rowCount);
2860
556
  }
2861
2862
1.94k
  return;
2863
2864
6.20k
 eofError:
2865
6.20k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
2866
6.20k
}
2867
2868
inline void JBIG2Stream::mmrAddPixels(int a1, int blackPixels,
2869
665k
              int *codingLine, int *a0i, int w) {
2870
665k
  if (a1 > codingLine[*a0i]) {
2871
664k
    if (a1 > w) {
2872
31.1k
      error(errSyntaxError, getPos(),
2873
31.1k
            "JBIG2 MMR row is wrong length ({0:d})", a1);
2874
31.1k
      a1 = w;
2875
31.1k
    }
2876
664k
    if ((*a0i & 1) ^ blackPixels) {
2877
282k
      ++*a0i;
2878
282k
    }
2879
664k
    codingLine[*a0i] = a1;
2880
664k
  }
2881
665k
}
2882
2883
inline void JBIG2Stream::mmrAddPixelsNeg(int a1, int blackPixels,
2884
64.0k
           int *codingLine, int *a0i, int w) {
2885
64.0k
  if (a1 > codingLine[*a0i]) {
2886
48.1k
    if (a1 > w) {
2887
0
      error(errSyntaxError, getPos(),
2888
0
            "JBIG2 MMR row is wrong length ({0:d})", a1);
2889
0
      a1 = w;
2890
0
    }
2891
48.1k
    if ((*a0i & 1) ^ blackPixels) {
2892
35.2k
      ++*a0i;
2893
35.2k
    }
2894
48.1k
    codingLine[*a0i] = a1;
2895
48.1k
  } else if (a1 < codingLine[*a0i]) {
2896
9.91k
    if (a1 < 0) {
2897
983
      error(errSyntaxError, getPos(), "Invalid JBIG2 MMR code");
2898
983
      a1 = 0;
2899
983
    }
2900
12.4k
    while (*a0i > 0 && a1 <= codingLine[*a0i - 1]) {
2901
2.56k
      --*a0i;
2902
2.56k
    }
2903
9.91k
    codingLine[*a0i] = a1;
2904
9.91k
  }
2905
64.0k
}
2906
2907
JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
2908
              int templ, GBool tpgdOn,
2909
              GBool useSkip, JBIG2Bitmap *skip,
2910
              int *atx, int *aty,
2911
20.3k
              int mmrDataLength) {
2912
20.3k
  JBIG2Bitmap *bitmap;
2913
20.3k
  GBool ltp;
2914
20.3k
  Guint ltpCX, cx, cx0, cx1, cx2;
2915
20.3k
  int *refLine, *codingLine;
2916
20.3k
  int code1, code2, code3;
2917
20.3k
  Guchar *p0, *p1, *p2, *pp;
2918
20.3k
  Guchar *atP0, *atP1, *atP2, *atP3;
2919
20.3k
  Guint buf0, buf1, buf2;
2920
20.3k
  Guint atBuf0, atBuf1, atBuf2, atBuf3;
2921
20.3k
  int atShift0, atShift1, atShift2, atShift3;
2922
20.3k
  Guchar mask;
2923
20.3k
  int x, y, x0, x1, a0i, b1i, blackPixels, pix, i;
2924
2925
20.3k
  bitmap = new JBIG2Bitmap(0, w, h);
2926
20.3k
  bitmap->clearToZero();
2927
2928
  //----- MMR decode
2929
2930
20.3k
  if (mmr) {
2931
2932
3.24k
    mmrDecoder->reset();
2933
3.24k
    if (w > INT_MAX - 3) {
2934
0
      error(errSyntaxError, getPos(), "Bad width in JBIG2 generic bitmap");
2935
      // force a call to gmalloc(-1), which will throw an exception
2936
0
      w = -4;
2937
0
    }
2938
    // 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = w
2939
    // ---> max codingLine size = w + 1
2940
    // refLine has two extra guard entries at the end
2941
    // ---> max refLine size = w + 3
2942
3.24k
    codingLine = (int *)gmallocn(w + 1, sizeof(int));
2943
3.24k
    refLine = (int *)gmallocn(w + 3, sizeof(int));
2944
3.24k
    codingLine[0] = w;
2945
2946
369k
    for (y = 0; y < h; ++y) {
2947
2948
      // copy coding line to ref line
2949
679k
      for (i = 0; codingLine[i] < w; ++i) {
2950
312k
  refLine[i] = codingLine[i];
2951
312k
      }
2952
366k
      refLine[i++] = w;
2953
366k
      refLine[i++] = w;
2954
366k
      refLine[i] = w;
2955
2956
      // decode a line
2957
366k
      codingLine[0] = 0;
2958
366k
      a0i = 0;
2959
366k
      b1i = 0;
2960
366k
      blackPixels = 0;
2961
      // invariant:
2962
      // refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1] <= w
2963
      // exception at left edge:
2964
      //   codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
2965
      // exception at right edge:
2966
      //   refLine[b1i] = refLine[b1i+1] = w is possible
2967
1.04M
      while (codingLine[a0i] < w) {
2968
681k
  code1 = mmrDecoder->get2DCode();
2969
681k
  switch (code1) {
2970
32.1k
  case twoDimPass:
2971
32.1k
          mmrAddPixels(refLine[b1i + 1], blackPixels, codingLine, &a0i, w);
2972
32.1k
          if (refLine[b1i + 1] < w) {
2973
17.9k
            b1i += 2;
2974
17.9k
          }
2975
32.1k
          break;
2976
59.6k
  case twoDimHoriz:
2977
59.6k
          code1 = code2 = 0;
2978
59.6k
          if (blackPixels) {
2979
24.0k
            do {
2980
24.0k
              code1 += code3 = mmrDecoder->getBlackCode();
2981
24.0k
            } while (code3 >= 64);
2982
26.7k
            do {
2983
26.7k
              code2 += code3 = mmrDecoder->getWhiteCode();
2984
26.7k
            } while (code3 >= 64);
2985
36.2k
          } else {
2986
39.0k
            do {
2987
39.0k
              code1 += code3 = mmrDecoder->getWhiteCode();
2988
39.0k
            } while (code3 >= 64);
2989
36.3k
            do {
2990
36.3k
              code2 += code3 = mmrDecoder->getBlackCode();
2991
36.3k
            } while (code3 >= 64);
2992
36.2k
          }
2993
59.6k
          mmrAddPixels(codingLine[a0i] + code1, blackPixels,
2994
59.6k
           codingLine, &a0i, w);
2995
59.6k
          if (codingLine[a0i] < w) {
2996
48.0k
            mmrAddPixels(codingLine[a0i] + code2, blackPixels ^ 1,
2997
48.0k
       codingLine, &a0i, w);
2998
48.0k
          }
2999
85.1k
          while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3000
25.4k
            b1i += 2;
3001
25.4k
          }
3002
59.6k
          break;
3003
9.66k
  case twoDimVertR3:
3004
9.66k
          mmrAddPixels(refLine[b1i] + 3, blackPixels, codingLine, &a0i, w);
3005
9.66k
          blackPixels ^= 1;
3006
9.66k
          if (codingLine[a0i] < w) {
3007
5.08k
            ++b1i;
3008
5.56k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3009
480
              b1i += 2;
3010
480
            }
3011
5.08k
          }
3012
9.66k
          break;
3013
4.41k
  case twoDimVertR2:
3014
4.41k
          mmrAddPixels(refLine[b1i] + 2, blackPixels, codingLine, &a0i, w);
3015
4.41k
          blackPixels ^= 1;
3016
4.41k
          if (codingLine[a0i] < w) {
3017
2.81k
            ++b1i;
3018
3.13k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3019
318
              b1i += 2;
3020
318
            }
3021
2.81k
          }
3022
4.41k
          break;
3023
27.3k
  case twoDimVertR1:
3024
27.3k
          mmrAddPixels(refLine[b1i] + 1, blackPixels, codingLine, &a0i, w);
3025
27.3k
          blackPixels ^= 1;
3026
27.3k
          if (codingLine[a0i] < w) {
3027
14.7k
            ++b1i;
3028
15.4k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3029
746
              b1i += 2;
3030
746
            }
3031
14.7k
          }
3032
27.3k
          break;
3033
241k
  case twoDimVert0:
3034
241k
          mmrAddPixels(refLine[b1i], blackPixels, codingLine, &a0i, w);
3035
241k
          blackPixels ^= 1;
3036
241k
          if (codingLine[a0i] < w) {
3037
166k
            ++b1i;
3038
166k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3039
0
              b1i += 2;
3040
0
            }
3041
166k
          }
3042
241k
          break;
3043
7.42k
  case twoDimVertL3:
3044
7.42k
          mmrAddPixelsNeg(refLine[b1i] - 3, blackPixels, codingLine, &a0i, w);
3045
7.42k
          blackPixels ^= 1;
3046
7.42k
          if (codingLine[a0i] < w) {
3047
7.42k
            if (b1i > 0) {
3048
6.14k
              --b1i;
3049
6.14k
            } else {
3050
1.27k
              ++b1i;
3051
1.27k
            }
3052
9.37k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3053
1.95k
              b1i += 2;
3054
1.95k
            }
3055
7.42k
          }
3056
7.42k
          break;
3057
29.8k
  case twoDimVertL2:
3058
29.8k
          mmrAddPixelsNeg(refLine[b1i] - 2, blackPixels, codingLine, &a0i, w);
3059
29.8k
          blackPixels ^= 1;
3060
29.8k
          if (codingLine[a0i] < w) {
3061
29.8k
            if (b1i > 0) {
3062
26.4k
              --b1i;
3063
26.4k
            } else {
3064
3.44k
              ++b1i;
3065
3.44k
            }
3066
50.5k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3067
20.6k
              b1i += 2;
3068
20.6k
            }
3069
29.8k
          }
3070
29.8k
          break;
3071
26.7k
  case twoDimVertL1:
3072
26.7k
          mmrAddPixelsNeg(refLine[b1i] - 1, blackPixels, codingLine, &a0i, w);
3073
26.7k
          blackPixels ^= 1;
3074
26.7k
          if (codingLine[a0i] < w) {
3075
26.7k
            if (b1i > 0) {
3076
17.8k
              --b1i;
3077
17.8k
            } else {
3078
8.88k
              ++b1i;
3079
8.88k
            }
3080
43.5k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3081
16.7k
              b1i += 2;
3082
16.7k
            }
3083
26.7k
          }
3084
26.7k
          break;
3085
242k
  case EOF:
3086
242k
          mmrAddPixels(w, 0, codingLine, &a0i, w);
3087
242k
          break;
3088
0
  default:
3089
0
    error(errSyntaxError, getPos(),
3090
0
    "Illegal code in JBIG2 MMR bitmap data");
3091
0
          mmrAddPixels(w, 0, codingLine, &a0i, w);
3092
0
    break;
3093
681k
  }
3094
681k
      }
3095
3096
      // convert the run lengths to a bitmap line
3097
366k
      i = 0;
3098
501k
      while (1) {
3099
501k
  if (codingLine[i] >= w) {
3100
321k
    break;
3101
321k
  }
3102
11.4M
  for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
3103
11.2M
    bitmap->setPixel(x, y);
3104
11.2M
  }
3105
180k
  if (codingLine[i+1] >= w) {
3106
45.5k
    break;
3107
45.5k
  }
3108
134k
  i += 2;
3109
134k
      }
3110
366k
    }
3111
3112
3.24k
    if (mmrDataLength >= 0) {
3113
2.02k
      mmrDecoder->skipTo(mmrDataLength);
3114
2.02k
    } else {
3115
1.21k
      if (mmrDecoder->get24Bits() != 0x001001) {
3116
1.02k
  error(errSyntaxError, getPos(),
3117
1.02k
        "Missing EOFB in JBIG2 MMR bitmap data");
3118
1.02k
      }
3119
1.21k
    }
3120
3121
3.24k
    gfree(refLine);
3122
3.24k
    gfree(codingLine);
3123
3124
  //----- arithmetic decode
3125
3126
17.0k
  } else {
3127
    // set up the typical row context
3128
17.0k
    ltpCX = 0; // make gcc happy
3129
17.0k
    if (tpgdOn) {
3130
1.11k
      switch (templ) {
3131
304
      case 0:
3132
304
  ltpCX = 0x3953; // 001 11001 0101 0011
3133
304
  break;
3134
161
      case 1:
3135
161
  ltpCX = 0x079a; // 0011 11001 101 0
3136
161
  break;
3137
196
      case 2:
3138
196
  ltpCX = 0x0e3; // 001 1100 01 1
3139
196
  break;
3140
450
      case 3:
3141
450
  ltpCX = 0x18b; // 01100 0101 1
3142
450
  break;
3143
1.11k
      }
3144
1.11k
    }
3145
3146
17.0k
    ltp = 0;
3147
17.0k
    cx = cx0 = cx1 = cx2 = 0; // make gcc happy
3148
1.03M
    for (y = 0; y < h; ++y) {
3149
3150
      // check for a "typical" (duplicate) row
3151
1.01M
      if (tpgdOn) {
3152
508k
  if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
3153
40.4k
    ltp = !ltp;
3154
40.4k
  }
3155
508k
  if (ltp) {
3156
83.3k
    if (y > 0) {
3157
82.9k
      bitmap->duplicateRow(y, y-1);
3158
82.9k
    }
3159
83.3k
    continue;
3160
83.3k
  }
3161
508k
      }
3162
3163
934k
      switch (templ) {
3164
338k
      case 0:
3165
3166
  // set up the context
3167
338k
  p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
3168
338k
  buf2 = *p2++ << 8;
3169
338k
  if (y >= 1) {
3170
322k
    p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
3171
322k
    buf1 = *p1++ << 8;
3172
322k
    if (y >= 2) {
3173
318k
      p0 = bitmap->getDataPtr() + (y - 2) * bitmap->getLineSize();
3174
318k
      buf0 = *p0++ << 8;
3175
318k
    } else {
3176
4.17k
      p0 = NULL;
3177
4.17k
      buf0 = 0;
3178
4.17k
    }
3179
322k
  } else {
3180
15.5k
    p1 = p0 = NULL;
3181
15.5k
    buf1 = buf0 = 0;
3182
15.5k
  }
3183
3184
338k
  if (atx[0] >= -8 && atx[0] <= 8 &&
3185
98.7k
      atx[1] >= -8 && atx[1] <= 8 &&
3186
54.5k
      atx[2] >= -8 && atx[2] <= 8 &&
3187
45.1k
      atx[3] >= -8 && atx[3] <= 8) {
3188
    // set up the adaptive context
3189
11.0k
    if (aty[0] <= 0 && y + aty[0] >= 0) {
3190
1.50k
      atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
3191
1.50k
      atBuf0 = *atP0++ << 8;
3192
9.51k
    } else {
3193
9.51k
      atP0 = NULL;
3194
9.51k
      atBuf0 = 0;
3195
9.51k
    }
3196
11.0k
    atShift0 = 15 - atx[0];
3197
11.0k
    if (aty[1] <= 0 && y + aty[1] >= 0) {
3198
1.28k
      atP1 = bitmap->getDataPtr() + (y + aty[1]) * bitmap->getLineSize();
3199
1.28k
      atBuf1 = *atP1++ << 8;
3200
9.74k
    } else {
3201
9.74k
      atP1 = NULL;
3202
9.74k
      atBuf1 = 0;
3203
9.74k
    }
3204
11.0k
    atShift1 = 15 - atx[1];
3205
11.0k
    if (aty[2] <= 0 && y + aty[2] >= 0) {
3206
10.8k
      atP2 = bitmap->getDataPtr() + (y + aty[2]) * bitmap->getLineSize();
3207
10.8k
      atBuf2 = *atP2++ << 8;
3208
10.8k
    } else {
3209
190
      atP2 = NULL;
3210
190
      atBuf2 = 0;
3211
190
    }
3212
11.0k
    atShift2 = 15 - atx[2];
3213
11.0k
    if (aty[3] <= 0 && y + aty[3] >= 0) {
3214
10.8k
      atP3 = bitmap->getDataPtr() + (y + aty[3]) * bitmap->getLineSize();
3215
10.8k
      atBuf3 = *atP3++ << 8;
3216
10.8k
    } else {
3217
190
      atP3 = NULL;
3218
190
      atBuf3 = 0;
3219
190
    }
3220
11.0k
    atShift3 = 15 - atx[3];
3221
3222
    // decode the row
3223
590k
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3224
579k
      if (x0 + 8 < w) {
3225
568k
        if (p0) {
3226
411k
    buf0 |= *p0++;
3227
411k
        }
3228
568k
        if (p1) {
3229
415k
    buf1 |= *p1++;
3230
415k
        }
3231
568k
        buf2 |= *p2++;
3232
568k
        if (atP0) {
3233
416k
    atBuf0 |= *atP0++;
3234
416k
        }
3235
568k
        if (atP1) {
3236
408k
    atBuf1 |= *atP1++;
3237
408k
        }
3238
568k
        if (atP2) {
3239
560k
    atBuf2 |= *atP2++;
3240
560k
        }
3241
568k
        if (atP3) {
3242
560k
    atBuf3 |= *atP3++;
3243
560k
        }
3244
568k
      }
3245
579k
      for (x1 = 0, mask = 0x80;
3246
5.17M
     x1 < 8 && x < w;
3247
4.59M
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3248
3249
        // build the context
3250
4.59M
        cx0 = (buf0 >> 14) & 0x07;
3251
4.59M
        cx1 = (buf1 >> 13) & 0x1f;
3252
4.59M
        cx2 = (buf2 >> 16) & 0x0f;
3253
4.59M
        cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
3254
4.59M
       (((atBuf0 >> atShift0) & 1) << 3) |
3255
4.59M
       (((atBuf1 >> atShift1) & 1) << 2) |
3256
4.59M
       (((atBuf2 >> atShift2) & 1) << 1) |
3257
4.59M
       ((atBuf3 >> atShift3) & 1);
3258
3259
        // check for a skipped pixel
3260
4.59M
        if (!(useSkip && skip->getPixel(x, y))) {
3261
3262
    // decode the pixel
3263
4.59M
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3264
2.38M
      *pp |= mask;
3265
2.38M
      buf2 |= 0x8000;
3266
2.38M
      if (aty[0] == 0) {
3267
1.71M
        atBuf0 |= 0x8000;
3268
1.71M
      }
3269
2.38M
      if (aty[1] == 0) {
3270
1.64M
        atBuf1 |= 0x8000;
3271
1.64M
      }
3272
2.38M
      if (aty[2] == 0) {
3273
2.31M
        atBuf2 |= 0x8000;
3274
2.31M
      }
3275
2.38M
      if (aty[3] == 0) {
3276
2.31M
        atBuf3 |= 0x8000;
3277
2.31M
      }
3278
2.38M
    }
3279
4.59M
        }
3280
3281
        // update the context
3282
4.59M
        buf0 <<= 1;
3283
4.59M
        buf1 <<= 1;
3284
4.59M
        buf2 <<= 1;
3285
4.59M
        atBuf0 <<= 1;
3286
4.59M
        atBuf1 <<= 1;
3287
4.59M
        atBuf2 <<= 1;
3288
4.59M
        atBuf3 <<= 1;
3289
4.59M
      }
3290
579k
    }
3291
3292
327k
  } else {
3293
    // decode the row
3294
2.62M
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3295
2.29M
      if (x0 + 8 < w) {
3296
1.96M
        if (p0) {
3297
1.24M
    buf0 |= *p0++;
3298
1.24M
        }
3299
1.96M
        if (p1) {
3300
1.27M
    buf1 |= *p1++;
3301
1.27M
        }
3302
1.96M
        buf2 |= *p2++;
3303
1.96M
      }
3304
2.29M
      for (x1 = 0, mask = 0x80;
3305
19.3M
     x1 < 8 && x < w;
3306
17.0M
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3307
3308
        // build the context
3309
17.0M
        cx0 = (buf0 >> 14) & 0x07;
3310
17.0M
        cx1 = (buf1 >> 13) & 0x1f;
3311
17.0M
        cx2 = (buf2 >> 16) & 0x0f;
3312
17.0M
        cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
3313
17.0M
       (bitmap->getPixel(x + atx[0], y + aty[0]) << 3) |
3314
17.0M
       (bitmap->getPixel(x + atx[1], y + aty[1]) << 2) |
3315
17.0M
       (bitmap->getPixel(x + atx[2], y + aty[2]) << 1) |
3316
17.0M
       bitmap->getPixel(x + atx[3], y + aty[3]);
3317
3318
        // check for a skipped pixel
3319
17.0M
        if (!(useSkip && skip->getPixel(x, y))) {
3320
3321
    // decode the pixel
3322
17.0M
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3323
8.51M
      *pp |= mask;
3324
8.51M
      buf2 |= 0x8000;
3325
8.51M
    }
3326
17.0M
        }
3327
3328
        // update the context
3329
17.0M
        buf0 <<= 1;
3330
17.0M
        buf1 <<= 1;
3331
17.0M
        buf2 <<= 1;
3332
17.0M
      }
3333
2.29M
    }
3334
327k
  }
3335
338k
  break;
3336
3337
9.37k
      case 1:
3338
3339
  // set up the context
3340
9.37k
  p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
3341
9.37k
  buf2 = *p2++ << 8;
3342
9.37k
  if (y >= 1) {
3343
9.17k
    p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
3344
9.17k
    buf1 = *p1++ << 8;
3345
9.17k
    if (y >= 2) {
3346
9.12k
      p0 = bitmap->getDataPtr() + (y - 2) * bitmap->getLineSize();
3347
9.12k
      buf0 = *p0++ << 8;
3348
9.12k
    } else {
3349
49
      p0 = NULL;
3350
49
      buf0 = 0;
3351
49
    }
3352
9.17k
  } else {
3353
198
    p1 = p0 = NULL;
3354
198
    buf1 = buf0 = 0;
3355
198
  }
3356
3357
9.37k
  if (atx[0] >= -8 && atx[0] <= 8) {
3358
    // set up the adaptive context
3359
52
    if (aty[0] <= 0 && y + aty[0] >= 0) {
3360
32
      atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
3361
32
      atBuf0 = *atP0++ << 8;
3362
32
    } else {
3363
20
      atP0 = NULL;
3364
20
      atBuf0 = 0;
3365
20
    }
3366
52
    atShift0 = 15 - atx[0];
3367
3368
    // decode the row
3369
432
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3370
380
      if (x0 + 8 < w) {
3371
328
        if (p0) {
3372
24
    buf0 |= *p0++;
3373
24
        }
3374
328
        if (p1) {
3375
176
    buf1 |= *p1++;
3376
176
        }
3377
328
        buf2 |= *p2++;
3378
328
        if (atP0) {
3379
48
    atBuf0 |= *atP0++;
3380
48
        }
3381
328
      }
3382
380
      for (x1 = 0, mask = 0x80;
3383
3.11k
     x1 < 8 && x < w;
3384
2.73k
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3385
3386
        // build the context
3387
2.73k
        cx0 = (buf0 >> 13) & 0x0f;
3388
2.73k
        cx1 = (buf1 >> 13) & 0x1f;
3389
2.73k
        cx2 = (buf2 >> 16) & 0x07;
3390
2.73k
        cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
3391
2.73k
       ((atBuf0 >> atShift0) & 1);
3392
3393
        // check for a skipped pixel
3394
2.73k
        if (!(useSkip && skip->getPixel(x, y))) {
3395
3396
    // decode the pixel
3397
2.73k
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3398
1.29k
      *pp |= mask;
3399
1.29k
      buf2 |= 0x8000;
3400
1.29k
      if (aty[0] == 0) {
3401
0
        atBuf0 |= 0x8000;
3402
0
      }
3403
1.29k
    }
3404
2.73k
        }
3405
3406
        // update the context
3407
2.73k
        buf0 <<= 1;
3408
2.73k
        buf1 <<= 1;
3409
2.73k
        buf2 <<= 1;
3410
2.73k
        atBuf0 <<= 1;
3411
2.73k
      }
3412
380
    }
3413
3414
9.32k
  } else {
3415
    // decode the row
3416
598k
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3417
589k
      if (x0 + 8 < w) {
3418
580k
        if (p0) {
3419
576k
    buf0 |= *p0++;
3420
576k
        }
3421
580k
        if (p1) {
3422
578k
    buf1 |= *p1++;
3423
578k
        }
3424
580k
        buf2 |= *p2++;
3425
580k
      }
3426
589k
      for (x1 = 0, mask = 0x80;
3427
5.26M
     x1 < 8 && x < w;
3428
4.67M
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3429
3430
        // build the context
3431
4.67M
        cx0 = (buf0 >> 13) & 0x0f;
3432
4.67M
        cx1 = (buf1 >> 13) & 0x1f;
3433
4.67M
        cx2 = (buf2 >> 16) & 0x07;
3434
4.67M
        cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
3435
4.67M
       bitmap->getPixel(x + atx[0], y + aty[0]);
3436
3437
        // check for a skipped pixel
3438
4.67M
        if (!(useSkip && skip->getPixel(x, y))) {
3439
3440
    // decode the pixel
3441
4.67M
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3442
2.15M
      *pp |= mask;
3443
2.15M
      buf2 |= 0x8000;
3444
2.15M
    }
3445
4.67M
        }
3446
3447
        // update the context
3448
4.67M
        buf0 <<= 1;
3449
4.67M
        buf1 <<= 1;
3450
4.67M
        buf2 <<= 1;
3451
4.67M
      }
3452
589k
    }
3453
9.32k
  }
3454
9.37k
  break;
3455
3456
59.4k
      case 2:
3457
3458
  // set up the context
3459
59.4k
  p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
3460
59.4k
  buf2 = *p2++ << 8;
3461
59.4k
  if (y >= 1) {
3462
59.1k
    p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
3463
59.1k
    buf1 = *p1++ << 8;
3464
59.1k
    if (y >= 2) {
3465
59.0k
      p0 = bitmap->getDataPtr() + (y - 2) * bitmap->getLineSize();
3466
59.0k
      buf0 = *p0++ << 8;
3467
59.0k
    } else {
3468
121
      p0 = NULL;
3469
121
      buf0 = 0;
3470
121
    }
3471
59.1k
  } else {
3472
343
    p1 = p0 = NULL;
3473
343
    buf1 = buf0 = 0;
3474
343
  }
3475
3476
59.4k
  if (atx[0] >= -8 && atx[0] <= 8) {
3477
    // set up the adaptive context
3478
1.69k
    if (aty[0] <= 0 && y + aty[0] >= 0) {
3479
673
      atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
3480
673
      atBuf0 = *atP0++ << 8;
3481
1.02k
    } else {
3482
1.02k
      atP0 = NULL;
3483
1.02k
      atBuf0 = 0;
3484
1.02k
    }
3485
1.69k
    atShift0 = 15 - atx[0];
3486
3487
    // decode the row
3488
4.71M
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3489
4.71M
      if (x0 + 8 < w) {
3490
4.71M
        if (p0) {
3491
2.08M
    buf0 |= *p0++;
3492
2.08M
        }
3493
4.71M
        if (p1) {
3494
4.71M
    buf1 |= *p1++;
3495
4.71M
        }
3496
4.71M
        buf2 |= *p2++;
3497
4.71M
        if (atP0) {
3498
2.62M
    atBuf0 |= *atP0++;
3499
2.62M
        }
3500
4.71M
      }
3501
4.71M
      for (x1 = 0, mask = 0x80;
3502
42.4M
     x1 < 8 && x < w;
3503
37.7M
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3504
3505
        // build the context
3506
37.7M
        cx0 = (buf0 >> 14) & 0x07;
3507
37.7M
        cx1 = (buf1 >> 14) & 0x0f;
3508
37.7M
        cx2 = (buf2 >> 16) & 0x03;
3509
37.7M
        cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
3510
37.7M
       ((atBuf0 >> atShift0) & 1);
3511
3512
        // check for a skipped pixel
3513
37.7M
        if (!(useSkip && skip->getPixel(x, y))) {
3514
3515
    // decode the pixel
3516
37.7M
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3517
17.9M
      *pp |= mask;
3518
17.9M
      buf2 |= 0x8000;
3519
17.9M
      if (aty[0] == 0) {
3520
16.5k
        atBuf0 |= 0x8000;
3521
16.5k
      }
3522
17.9M
    }
3523
37.7M
        }
3524
3525
        // update the context
3526
37.7M
        buf0 <<= 1;
3527
37.7M
        buf1 <<= 1;
3528
37.7M
        buf2 <<= 1;
3529
37.7M
        atBuf0 <<= 1;
3530
37.7M
      }
3531
4.71M
    }
3532
3533
57.7k
  } else {
3534
    // decode the row
3535
118k
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3536
60.2k
      if (x0 + 8 < w) {
3537
2.45k
        if (p0) {
3538
10
    buf0 |= *p0++;
3539
10
        }
3540
2.45k
        if (p1) {
3541
56
    buf1 |= *p1++;
3542
56
        }
3543
2.45k
        buf2 |= *p2++;
3544
2.45k
      }
3545
60.2k
      for (x1 = 0, mask = 0x80;
3546
138k
     x1 < 8 && x < w;
3547
78.1k
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3548
3549
        // build the context
3550
78.1k
        cx0 = (buf0 >> 14) & 0x07;
3551
78.1k
        cx1 = (buf1 >> 14) & 0x0f;
3552
78.1k
        cx2 = (buf2 >> 16) & 0x03;
3553
78.1k
        cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
3554
78.1k
       bitmap->getPixel(x + atx[0], y + aty[0]);
3555
3556
        // check for a skipped pixel
3557
78.1k
        if (!(useSkip && skip->getPixel(x, y))) {
3558
3559
    // decode the pixel
3560
78.1k
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3561
58.0k
      *pp |= mask;
3562
58.0k
      buf2 |= 0x8000;
3563
58.0k
    }
3564
78.1k
        }
3565
3566
        // update the context
3567
78.1k
        buf0 <<= 1;
3568
78.1k
        buf1 <<= 1;
3569
78.1k
        buf2 <<= 1;
3570
78.1k
      }
3571
60.2k
    }
3572
57.7k
  }
3573
59.4k
  break;
3574
3575
527k
      case 3:
3576
3577
  // set up the context
3578
527k
  p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
3579
527k
  buf2 = *p2++ << 8;
3580
527k
  if (y >= 1) {
3581
526k
    p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
3582
526k
    buf1 = *p1++ << 8;
3583
526k
  } else {
3584
564
    p1 = NULL;
3585
564
    buf1 = 0;
3586
564
  }
3587
3588
527k
  if (atx[0] >= -8 && atx[0] <= 8) {
3589
    // set up the adaptive context
3590
165k
    if (aty[0] <= 0 && y + aty[0] >= 0) {
3591
163k
      atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
3592
163k
      atBuf0 = *atP0++ << 8;
3593
163k
    } else {
3594
1.96k
      atP0 = NULL;
3595
1.96k
      atBuf0 = 0;
3596
1.96k
    }
3597
165k
    atShift0 = 15 - atx[0];
3598
3599
    // decode the row
3600
2.15M
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3601
1.99M
      if (x0 + 8 < w) {
3602
1.82M
        if (p1) {
3603
1.82M
    buf1 |= *p1++;
3604
1.82M
        }
3605
1.82M
        buf2 |= *p2++;
3606
1.82M
        if (atP0) {
3607
1.81M
    atBuf0 |= *atP0++;
3608
1.81M
        }
3609
1.82M
      }
3610
1.99M
      for (x1 = 0, mask = 0x80;
3611
17.2M
     x1 < 8 && x < w;
3612
15.2M
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3613
3614
        // build the context
3615
15.2M
        cx1 = (buf1 >> 14) & 0x1f;
3616
15.2M
        cx2 = (buf2 >> 16) & 0x0f;
3617
15.2M
        cx = (cx1 << 5) | (cx2 << 1) |
3618
15.2M
       ((atBuf0 >> atShift0) & 1);
3619
3620
        // check for a skipped pixel
3621
15.2M
        if (!(useSkip && skip->getPixel(x, y))) {
3622
3623
    // decode the pixel
3624
15.2M
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3625
8.26M
      *pp |= mask;
3626
8.26M
      buf2 |= 0x8000;
3627
8.26M
      if (aty[0] == 0) {
3628
5.86M
        atBuf0 |= 0x8000;
3629
5.86M
      }
3630
8.26M
    }
3631
15.2M
        }
3632
3633
        // update the context
3634
15.2M
        buf1 <<= 1;
3635
15.2M
        buf2 <<= 1;
3636
15.2M
        atBuf0 <<= 1;
3637
15.2M
      }
3638
1.99M
    }
3639
3640
361k
  } else {
3641
    // decode the row
3642
12.2M
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3643
11.8M
      if (x0 + 8 < w) {
3644
11.4M
        if (p1) {
3645
11.4M
    buf1 |= *p1++;
3646
11.4M
        }
3647
11.4M
        buf2 |= *p2++;
3648
11.4M
      }
3649
11.8M
      for (x1 = 0, mask = 0x80;
3650
104M
     x1 < 8 && x < w;
3651
92.2M
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3652
3653
        // build the context
3654
92.2M
        cx1 = (buf1 >> 14) & 0x1f;
3655
92.2M
        cx2 = (buf2 >> 16) & 0x0f;
3656
92.2M
        cx = (cx1 << 5) | (cx2 << 1) |
3657
92.2M
       bitmap->getPixel(x + atx[0], y + aty[0]);
3658
3659
        // check for a skipped pixel
3660
92.2M
        if (!(useSkip && skip->getPixel(x, y))) {
3661
3662
    // decode the pixel
3663
92.2M
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3664
44.4M
      *pp |= mask;
3665
44.4M
      buf2 |= 0x8000;
3666
44.4M
    }
3667
92.2M
        }
3668
3669
        // update the context
3670
92.2M
        buf1 <<= 1;
3671
92.2M
        buf2 <<= 1;
3672
92.2M
      }
3673
11.8M
    }
3674
361k
  }
3675
527k
  break;
3676
934k
      }
3677
934k
    }
3678
17.0k
  }
3679
3680
20.3k
  return bitmap;
3681
20.3k
}
3682
3683
void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
3684
             GBool lossless, Guint length,
3685
             Guint *refSegs,
3686
7.15k
             Guint nRefSegs) {
3687
7.15k
  JBIG2Bitmap *bitmap, *refBitmap;
3688
7.15k
  Guint w, h, x, y, segInfoFlags, extCombOp;
3689
7.15k
  Guint flags, templ, tpgrOn;
3690
7.15k
  int atx[2], aty[2];
3691
7.15k
  JBIG2Segment *seg;
3692
3693
  // region segment info field
3694
7.15k
  if (!readULong(&w) || !readULong(&h) ||
3695
5.62k
      !readULong(&x) || !readULong(&y) ||
3696
3.98k
      !readUByte(&segInfoFlags)) {
3697
3.26k
    goto eofError;
3698
3.26k
  }
3699
3.89k
  if (w == 0 || h == 0) {
3700
400
    error(errSyntaxError, getPos(),
3701
400
    "Bad size in JBIG2 generic refinement region segment");
3702
400
    return;
3703
400
  }
3704
  // sanity check: if the w/h/x/y values are way out of range, it likely
3705
  // indicates a damaged JBIG2 stream
3706
3.49k
  if (w / 10 > pageW || h / 10 > pageH ||
3707
2.85k
      x / 10 > pageW || y / 10 > pageH) {
3708
757
    error(errSyntaxError, getPos(),
3709
757
    "Bad size or position in JBIG2 generic refinement region segment");
3710
757
    done = gTrue;
3711
757
    return;
3712
757
  }
3713
2.73k
  extCombOp = segInfoFlags & 7;
3714
3715
  // rest of the generic refinement region segment header
3716
2.73k
  if (!readUByte(&flags)) {
3717
181
    goto eofError;
3718
181
  }
3719
2.55k
  templ = flags & 1;
3720
2.55k
  tpgrOn = (flags >> 1) & 1;
3721
3722
  // AT flags
3723
2.55k
  if (!templ) {
3724
2.04k
    if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
3725
1.46k
  !readByte(&atx[1]) || !readByte(&aty[1])) {
3726
899
      goto eofError;
3727
899
    }
3728
2.04k
  }
3729
3730
  // resize the page bitmap if needed
3731
1.65k
  if (nRefSegs == 0 || imm) {
3732
1.30k
    if (pageH == 0xffffffff && y + h > curPageH) {
3733
429
      pageBitmap->expand(y + h, pageDefPixel);
3734
429
    }
3735
1.30k
  }
3736
3737
  // get referenced bitmap
3738
1.65k
  if (nRefSegs > 1) {
3739
528
    error(errSyntaxError, getPos(),
3740
528
    "Bad reference in JBIG2 generic refinement segment");
3741
528
    return;
3742
528
  }
3743
1.12k
  if (nRefSegs == 1) {
3744
405
    if (!(seg = findSegment(refSegs[0])) ||
3745
405
  seg->getType() != jbig2SegBitmap) {
3746
405
      error(errSyntaxError, getPos(),
3747
405
      "Bad bitmap reference in JBIG2 generic refinement segment");
3748
405
      return;
3749
405
    }
3750
0
    refBitmap = (JBIG2Bitmap *)seg;
3751
724
  } else {
3752
724
    refBitmap = pageBitmap->getSlice(x, y, w, h);
3753
724
  }
3754
3755
  // set up the arithmetic decoder
3756
724
  resetRefinementStats(templ, NULL);
3757
724
  arithDecoder->start();
3758
3759
  // read
3760
724
  bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
3761
724
               refBitmap, 0, 0, atx, aty);
3762
3763
  // combine the region bitmap into the page bitmap
3764
724
  if (imm) {
3765
697
    pageBitmap->combine(bitmap, x, y, extCombOp);
3766
697
    delete bitmap;
3767
3768
  // store the region bitmap
3769
697
  } else {
3770
27
    bitmap->setSegNum(segNum);
3771
27
    segments->append(bitmap);
3772
27
  }
3773
3774
  // delete the referenced bitmap
3775
724
  if (nRefSegs == 1) {
3776
0
    discardSegment(refSegs[0]);
3777
724
  } else {
3778
724
    delete refBitmap;
3779
724
  }
3780
3781
724
  return;
3782
3783
4.34k
 eofError:
3784
4.34k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
3785
4.34k
}
3786
3787
JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
3788
                  int templ, GBool tpgrOn,
3789
                  JBIG2Bitmap *refBitmap,
3790
                  int refDX, int refDY,
3791
4.07k
                  int *atx, int *aty) {
3792
4.07k
  JBIG2Bitmap *bitmap;
3793
4.07k
  GBool ltp;
3794
4.07k
  Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
3795
4.07k
  JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6;
3796
4.07k
  JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
3797
4.07k
  int x, y, pix;
3798
3799
4.07k
  bitmap = new JBIG2Bitmap(0, w, h);
3800
4.07k
  bitmap->clearToZero();
3801
3802
  // set up the typical row context
3803
4.07k
  if (templ) {
3804
729
    ltpCX = 0x008;
3805
3.34k
  } else {
3806
3.34k
    ltpCX = 0x0010;
3807
3.34k
  }
3808
3809
4.07k
  ltp = 0;
3810
422k
  for (y = 0; y < h; ++y) {
3811
3812
418k
    if (templ) {
3813
3814
      // set up the context
3815
42.2k
      bitmap->getPixelPtr(0, y-1, &cxPtr0);
3816
42.2k
      cx0 = bitmap->nextPixel(&cxPtr0);
3817
42.2k
      bitmap->getPixelPtr(-1, y, &cxPtr1);
3818
42.2k
      refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
3819
42.2k
      refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
3820
42.2k
      cx3 = refBitmap->nextPixel(&cxPtr3);
3821
42.2k
      cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
3822
42.2k
      refBitmap->getPixelPtr(-refDX, y+1-refDY, &cxPtr4);
3823
42.2k
      cx4 = refBitmap->nextPixel(&cxPtr4);
3824
3825
      // set up the typical prediction context
3826
42.2k
      tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3827
42.2k
      if (tpgrOn) {
3828
447
  refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
3829
447
  tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
3830
447
  tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3831
447
  tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3832
447
  refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
3833
447
  tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
3834
447
  tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3835
447
  tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3836
447
  refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
3837
447
  tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3838
447
  tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3839
447
  tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3840
41.7k
      } else {
3841
41.7k
  tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy
3842
41.7k
  tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
3843
41.7k
  tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
3844
41.7k
      }
3845
3846
1.49M
      for (x = 0; x < w; ++x) {
3847
3848
  // update the context
3849
1.45M
  cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 7;
3850
1.45M
  cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3851
1.45M
  cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 3;
3852
3853
1.45M
  if (tpgrOn) {
3854
    // update the typical predictor context
3855
800k
    tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3856
800k
    tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3857
800k
    tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3858
3859
    // check for a "typical" pixel
3860
800k
    if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3861
347k
      ltp = !ltp;
3862
347k
    }
3863
800k
    if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3864
798k
      bitmap->clearPixel(x, y);
3865
798k
      continue;
3866
798k
    } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3867
0
      bitmap->setPixel(x, y);
3868
0
      continue;
3869
0
    }
3870
800k
  }
3871
3872
  // build the context
3873
656k
  cx = (cx0 << 7) | (bitmap->nextPixel(&cxPtr1) << 6) |
3874
656k
       (refBitmap->nextPixel(&cxPtr2) << 5) |
3875
656k
       (cx3 << 2) | cx4;
3876
3877
  // decode the pixel
3878
656k
  if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3879
407k
    bitmap->setPixel(x, y);
3880
407k
  }
3881
656k
      }
3882
3883
375k
    } else {
3884
3885
      // set up the context
3886
375k
      bitmap->getPixelPtr(0, y-1, &cxPtr0);
3887
375k
      cx0 = bitmap->nextPixel(&cxPtr0);
3888
375k
      bitmap->getPixelPtr(-1, y, &cxPtr1);
3889
375k
      refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
3890
375k
      cx2 = refBitmap->nextPixel(&cxPtr2);
3891
375k
      refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
3892
375k
      cx3 = refBitmap->nextPixel(&cxPtr3);
3893
375k
      cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
3894
375k
      refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &cxPtr4);
3895
375k
      cx4 = refBitmap->nextPixel(&cxPtr4);
3896
375k
      cx4 = (cx4 << 1) | refBitmap->nextPixel(&cxPtr4);
3897
375k
      bitmap->getPixelPtr(atx[0], y+aty[0], &cxPtr5);
3898
375k
      refBitmap->getPixelPtr(atx[1]-refDX, y+aty[1]-refDY, &cxPtr6);
3899
3900
      // set up the typical prediction context
3901
375k
      tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3902
375k
      if (tpgrOn) {
3903
272k
  refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
3904
272k
  tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
3905
272k
  tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3906
272k
  tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3907
272k
  refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
3908
272k
  tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
3909
272k
  tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3910
272k
  tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3911
272k
  refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
3912
272k
  tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3913
272k
  tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3914
272k
  tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3915
272k
      } else {
3916
103k
  tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy
3917
103k
  tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
3918
103k
  tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
3919
103k
      }
3920
3921
7.82M
      for (x = 0; x < w; ++x) {
3922
3923
  // update the context
3924
7.44M
  cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 3;
3925
7.44M
  cx2 = ((cx2 << 1) | refBitmap->nextPixel(&cxPtr2)) & 3;
3926
7.44M
  cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3927
7.44M
  cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 7;
3928
3929
7.44M
  if (tpgrOn) {
3930
    // update the typical predictor context
3931
4.35M
    tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3932
4.35M
    tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3933
4.35M
    tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3934
3935
    // check for a "typical" pixel
3936
4.35M
    if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3937
1.70M
      ltp = !ltp;
3938
1.70M
    }
3939
4.35M
    if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3940
2.99M
      bitmap->clearPixel(x, y);
3941
2.99M
      continue;
3942
2.99M
    } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3943
534k
      bitmap->setPixel(x, y);
3944
534k
      continue;
3945
534k
    }
3946
4.35M
  }
3947
3948
  // build the context
3949
3.91M
  cx = (cx0 << 11) | (bitmap->nextPixel(&cxPtr1) << 10) |
3950
3.91M
       (cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
3951
3.91M
       (bitmap->nextPixel(&cxPtr5) << 1) |
3952
3.91M
       refBitmap->nextPixel(&cxPtr6);
3953
3954
  // decode the pixel
3955
3.91M
  if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3956
2.16M
    bitmap->setPixel(x, y);
3957
2.16M
  }
3958
3.91M
      }
3959
375k
    }
3960
418k
  }
3961
3962
4.07k
  return bitmap;
3963
4.07k
}
3964
3965
109k
void JBIG2Stream::readPageInfoSeg(Guint length) {
3966
109k
  Guint xRes, yRes, flags, striping;
3967
3968
109k
  if (!readULong(&pageW) || !readULong(&pageH) ||
3969
107k
      !readULong(&xRes) || !readULong(&yRes) ||
3970
106k
      !readUByte(&flags) || !readUWord(&striping)) {
3971
4.17k
    goto eofError;
3972
4.17k
  }
3973
105k
  if (pageW == 0 || pageH == 0 ||
3974
104k
      pageW > INT_MAX || pageH > INT_MAX ||
3975
86.9k
      pageH > INT_MAX / pageW) {
3976
49.3k
    error(errSyntaxError, getPos(), "Bad page size in JBIG2 stream");
3977
49.3k
    return;
3978
49.3k
  }
3979
55.9k
  pageDefPixel = (flags >> 2) & 1;
3980
55.9k
  defCombOp = (flags >> 3) & 3;
3981
3982
  // this will only happen if there are multiple page info segments
3983
55.9k
  if (pageBitmap) {
3984
3.32k
    delete pageBitmap;
3985
3.32k
  }
3986
3987
  // allocate the page bitmap
3988
55.9k
  if (pageH == 0xffffffff) {
3989
0
    curPageH = striping & 0x7fff;
3990
55.9k
  } else {
3991
55.9k
    curPageH = pageH;
3992
55.9k
  }
3993
55.9k
  pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
3994
3995
  // default pixel value
3996
55.9k
  if (pageDefPixel) {
3997
37.4k
    pageBitmap->clearToOne();
3998
37.4k
  } else {
3999
18.5k
    pageBitmap->clearToZero();
4000
18.5k
  }
4001
4002
55.9k
  return;
4003
4004
4.17k
 eofError:
4005
4.17k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
4006
4.17k
}
4007
4008
498
void JBIG2Stream::readEndOfStripeSeg(Guint length) {
4009
  // skip the segment
4010
498
  byteCounter += curStr->discardChars(length);
4011
498
}
4012
4013
242
void JBIG2Stream::readProfilesSeg(Guint length) {
4014
  // skip the segment
4015
242
  byteCounter += curStr->discardChars(length);
4016
242
}
4017
4018
6.57k
void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) {
4019
6.57k
  JBIG2HuffmanTable *huffTab;
4020
6.57k
  Guint flags, oob, prefixBits, rangeBits;
4021
6.57k
  int lowVal, highVal, val;
4022
6.57k
  Guint huffTabSize, i;
4023
4024
6.57k
  if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
4025
1.95k
    goto eofError;
4026
1.95k
  }
4027
4.61k
  oob = flags & 1;
4028
4.61k
  prefixBits = ((flags >> 1) & 7) + 1;
4029
4.61k
  rangeBits = ((flags >> 4) & 7) + 1;
4030
4031
4.61k
  huffDecoder->reset();
4032
4.61k
  huffTabSize = 8;
4033
4.61k
  huffTab = (JBIG2HuffmanTable *)
4034
4.61k
                gmallocn(huffTabSize, sizeof(JBIG2HuffmanTable));
4035
4.61k
  i = 0;
4036
4.61k
  val = lowVal;
4037
111k
  while (val < highVal) {
4038
106k
    if (i == huffTabSize) {
4039
654
      huffTabSize *= 2;
4040
654
      huffTab = (JBIG2HuffmanTable *)
4041
654
              greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
4042
654
    }
4043
106k
    huffTab[i].val = val;
4044
106k
    huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
4045
106k
    huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
4046
106k
    val += 1 << huffTab[i].rangeLen;
4047
106k
    ++i;
4048
106k
  }
4049
4.61k
  if (i + oob + 3 > huffTabSize) {
4050
308
    huffTabSize = i + oob + 3;
4051
308
    huffTab = (JBIG2HuffmanTable *)
4052
308
                  greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
4053
308
  }
4054
4.61k
  huffTab[i].val = lowVal - 1;
4055
4.61k
  huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
4056
4.61k
  huffTab[i].rangeLen = jbig2HuffmanLOW;
4057
4.61k
  ++i;
4058
4.61k
  huffTab[i].val = highVal;
4059
4.61k
  huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
4060
4.61k
  huffTab[i].rangeLen = 32;
4061
4.61k
  ++i;
4062
4.61k
  if (oob) {
4063
1.32k
    huffTab[i].val = 0;
4064
1.32k
    huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
4065
1.32k
    huffTab[i].rangeLen = jbig2HuffmanOOB;
4066
1.32k
    ++i;
4067
1.32k
  }
4068
4.61k
  huffTab[i].val = 0;
4069
4.61k
  huffTab[i].prefixLen = 0;
4070
4.61k
  huffTab[i].rangeLen = jbig2HuffmanEOT;
4071
4.61k
  huffDecoder->buildTable(huffTab, i);
4072
4073
  // create and store the new table segment
4074
4.61k
  segments->append(new JBIG2CodeTable(segNum, huffTab));
4075
4076
4.61k
  return;
4077
4078
1.95k
 eofError:
4079
1.95k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
4080
1.95k
}
4081
4082
386
void JBIG2Stream::readExtensionSeg(Guint length) {
4083
  // skip the segment
4084
386
  byteCounter += curStr->discardChars(length);
4085
386
}
4086
4087
2.45M
JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
4088
2.45M
  JBIG2Segment *seg;
4089
2.45M
  int i;
4090
4091
2.46M
  for (i = 0; i < globalSegments->getLength(); ++i) {
4092
28.1k
    seg = (JBIG2Segment *)globalSegments->get(i);
4093
28.1k
    if (seg->getSegNum() == segNum) {
4094
19.1k
      return seg;
4095
19.1k
    }
4096
28.1k
  }
4097
2.43M
  for (i = 0; i < segments->getLength(); ++i) {
4098
6.40k
    seg = (JBIG2Segment *)segments->get(i);
4099
6.40k
    if (seg->getSegNum() == segNum) {
4100
4.10k
      return seg;
4101
4.10k
    }
4102
6.40k
  }
4103
2.43M
  return NULL;
4104
2.43M
}
4105
4106
0
void JBIG2Stream::discardSegment(Guint segNum) {
4107
0
  JBIG2Segment *seg;
4108
0
  int i;
4109
4110
0
  for (i = 0; i < globalSegments->getLength(); ++i) {
4111
0
    seg = (JBIG2Segment *)globalSegments->get(i);
4112
0
    if (seg->getSegNum() == segNum) {
4113
0
      globalSegments->del(i);
4114
0
      return;
4115
0
    }
4116
0
  }
4117
0
  for (i = 0; i < segments->getLength(); ++i) {
4118
0
    seg = (JBIG2Segment *)segments->get(i);
4119
0
    if (seg->getSegNum() == segNum) {
4120
0
      segments->del(i);
4121
0
      return;
4122
0
    }
4123
0
  }
4124
0
}
4125
4126
void JBIG2Stream::resetGenericStats(Guint templ,
4127
7.24k
            JArithmeticDecoderStats *prevStats) {
4128
7.24k
  int size;
4129
4130
7.24k
  size = contextSize[templ];
4131
7.24k
  if (prevStats && prevStats->getContextSize() == size) {
4132
0
    if (genericRegionStats->getContextSize() == size) {
4133
0
      genericRegionStats->copyFrom(prevStats);
4134
0
    } else {
4135
0
      delete genericRegionStats;
4136
0
      genericRegionStats = prevStats->copy();
4137
0
    }
4138
7.24k
  } else {
4139
7.24k
    if (genericRegionStats->getContextSize() == size) {
4140
0
      genericRegionStats->reset();
4141
7.24k
    } else {
4142
7.24k
      delete genericRegionStats;
4143
7.24k
      genericRegionStats = new JArithmeticDecoderStats(1 << size);
4144
7.24k
    }
4145
7.24k
  }
4146
7.24k
}
4147
4148
void JBIG2Stream::resetRefinementStats(Guint templ,
4149
4.55k
               JArithmeticDecoderStats *prevStats) {
4150
4.55k
  int size;
4151
4152
4.55k
  size = refContextSize[templ];
4153
4.55k
  if (prevStats && prevStats->getContextSize() == size) {
4154
0
    if (refinementRegionStats->getContextSize() == size) {
4155
0
      refinementRegionStats->copyFrom(prevStats);
4156
0
    } else {
4157
0
      delete refinementRegionStats;
4158
0
      refinementRegionStats = prevStats->copy();
4159
0
    }
4160
4.55k
  } else {
4161
4.55k
    if (refinementRegionStats->getContextSize() == size) {
4162
0
      refinementRegionStats->reset();
4163
4.55k
    } else {
4164
4.55k
      delete refinementRegionStats;
4165
4.55k
      refinementRegionStats = new JArithmeticDecoderStats(1 << size);
4166
4.55k
    }
4167
4.55k
  }
4168
4.55k
}
4169
4170
5.81k
void JBIG2Stream::resetIntStats(int symCodeLen) {
4171
5.81k
  iadhStats->reset();
4172
5.81k
  iadwStats->reset();
4173
5.81k
  iaexStats->reset();
4174
5.81k
  iaaiStats->reset();
4175
5.81k
  iadtStats->reset();
4176
5.81k
  iaitStats->reset();
4177
5.81k
  iafsStats->reset();
4178
5.81k
  iadsStats->reset();
4179
5.81k
  iardxStats->reset();
4180
5.81k
  iardyStats->reset();
4181
5.81k
  iardwStats->reset();
4182
5.81k
  iardhStats->reset();
4183
5.81k
  iariStats->reset();
4184
5.81k
  if (iaidStats->getContextSize() == 1 << (symCodeLen + 1)) {
4185
2.88k
    iaidStats->reset();
4186
2.92k
  } else {
4187
2.92k
    delete iaidStats;
4188
2.92k
    iaidStats = new JArithmeticDecoderStats(1 << (symCodeLen + 1));
4189
2.92k
  }
4190
5.81k
}
4191
4192
776k
GBool JBIG2Stream::readUByte(Guint *x) {
4193
776k
  int c0;
4194
4195
776k
  if ((c0 = curStr->getChar()) == EOF) {
4196
2.86k
    return gFalse;
4197
2.86k
  }
4198
773k
  ++byteCounter;
4199
773k
  *x = (Guint)c0;
4200
773k
  return gTrue;
4201
776k
}
4202
4203
91.3k
GBool JBIG2Stream::readByte(int *x) {
4204
91.3k
 int c0;
4205
4206
91.3k
  if ((c0 = curStr->getChar()) == EOF) {
4207
7.09k
    return gFalse;
4208
7.09k
  }
4209
84.2k
  ++byteCounter;
4210
84.2k
  *x = c0;
4211
84.2k
  if (c0 & 0x80) {
4212
15.9k
    *x |= -1 - 0xff;
4213
15.9k
  }
4214
84.2k
  return gTrue;
4215
91.3k
}
4216
4217
6.59M
GBool JBIG2Stream::readUWord(Guint *x) {
4218
6.59M
  int c0, c1;
4219
4220
6.59M
  if ((c0 = curStr->getChar()) == EOF ||
4221
6.59M
      (c1 = curStr->getChar()) == EOF) {
4222
2.03k
    return gFalse;
4223
2.03k
  }
4224
6.59M
  byteCounter += 2;
4225
6.59M
  *x = (Guint)((c0 << 8) | c1);
4226
6.59M
  return gTrue;
4227
6.59M
}
4228
4229
1.43M
GBool JBIG2Stream::readULong(Guint *x) {
4230
1.43M
  int c0, c1, c2, c3;
4231
4232
1.43M
  if ((c0 = curStr->getChar()) == EOF ||
4233
1.41M
      (c1 = curStr->getChar()) == EOF ||
4234
1.40M
      (c2 = curStr->getChar()) == EOF ||
4235
1.40M
      (c3 = curStr->getChar()) == EOF) {
4236
40.6k
    return gFalse;
4237
40.6k
  }
4238
1.39M
  byteCounter += 4;
4239
1.39M
  *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
4240
1.39M
  return gTrue;
4241
1.43M
}
4242
4243
17.2k
GBool JBIG2Stream::readLong(int *x) {
4244
17.2k
  int c0, c1, c2, c3;
4245
4246
17.2k
  if ((c0 = curStr->getChar()) == EOF ||
4247
16.3k
      (c1 = curStr->getChar()) == EOF ||
4248
15.6k
      (c2 = curStr->getChar()) == EOF ||
4249
15.2k
      (c3 = curStr->getChar()) == EOF) {
4250
2.63k
    return gFalse;
4251
2.63k
  }
4252
14.5k
  byteCounter += 4;
4253
14.5k
  *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
4254
14.5k
  if (c0 & 0x80) {
4255
1.87k
    *x |= -1 - (int)0xffffffff;
4256
1.87k
  }
4257
14.5k
  return gTrue;
4258
17.2k
}