Coverage Report

Created: 2026-08-22 06:39

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
2.03M
#define jbig2HuffmanLOW 0xfffffffd
32
2.12M
#define jbig2HuffmanOOB 0xfffffffe
33
37.7M
#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
87.7k
  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
186k
  void resetByteCounter() { byteCounter = 0; }
309
167k
  Guint getByteCounter() { return byteCounter; }
310
311
private:
312
313
  Stream *str;
314
  Guint buf;
315
  Guint bufLen;
316
  Guint byteCounter;
317
};
318
319
278k
JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
320
278k
  str = NULL;
321
278k
  byteCounter = 0;
322
278k
  reset();
323
278k
}
324
325
277k
JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {
326
277k
}
327
328
297k
void JBIG2HuffmanDecoder::reset() {
329
297k
  buf = 0;
330
297k
  bufLen = 0;
331
297k
}
332
333
//~ optimize this
334
3.74M
GBool JBIG2HuffmanDecoder::decodeInt(int *x, JBIG2HuffmanTable *table) {
335
3.74M
  Guint i, len, prefix;
336
337
3.74M
  i = 0;
338
3.74M
  len = 0;
339
3.74M
  prefix = 0;
340
37.5M
  while (table[i].rangeLen != jbig2HuffmanEOT) {
341
52.2M
    while (len < table[i].prefixLen) {
342
16.3M
      prefix = (prefix << 1) | readBit();
343
16.3M
      ++len;
344
16.3M
    }
345
35.8M
    if (prefix == table[i].prefix) {
346
2.12M
      if (table[i].rangeLen == jbig2HuffmanOOB) {
347
96.0k
  return gFalse;
348
96.0k
      }
349
2.03M
      if (table[i].rangeLen == jbig2HuffmanLOW) {
350
3.56k
  *x = table[i].val - readBits(32);
351
2.02M
      } else if (table[i].rangeLen > 0) {
352
1.85M
  *x = table[i].val + readBits(table[i].rangeLen);
353
1.85M
      } else {
354
173k
  *x = table[i].val;
355
173k
      }
356
2.03M
      return gTrue;
357
2.12M
    }
358
33.7M
    ++i;
359
33.7M
  }
360
1.62M
  return gFalse;
361
3.74M
}
362
363
138M
Guint JBIG2HuffmanDecoder::readBits(Guint n) {
364
138M
  Guint x, mask, nLeft;
365
366
138M
  mask = (n == 32) ? 0xffffffff : ((1 << n) - 1);
367
138M
  if (bufLen >= n) {
368
93.4M
    x = (buf >> (bufLen - n)) & mask;
369
93.4M
    bufLen -= n;
370
93.4M
  } else {
371
44.7M
    x = buf & ((1 << bufLen) - 1);
372
44.7M
    nLeft = n - bufLen;
373
44.7M
    bufLen = 0;
374
49.8M
    while (nLeft >= 8) {
375
5.11M
      x = (x << 8) | (str->getChar() & 0xff);
376
5.11M
      ++byteCounter;
377
5.11M
      nLeft -= 8;
378
5.11M
    }
379
44.7M
    if (nLeft > 0) {
380
44.6M
      buf = str->getChar();
381
44.6M
      ++byteCounter;
382
44.6M
      bufLen = 8 - nLeft;
383
44.6M
      x = (x << nLeft) | ((buf >> bufLen) & ((1 << nLeft) - 1));
384
44.6M
    }
385
44.7M
  }
386
138M
  return x;
387
138M
}
388
389
16.4M
Guint JBIG2HuffmanDecoder::readBit() {
390
16.4M
  if (bufLen == 0) {
391
1.86M
    buf = str->getChar();
392
1.86M
    ++byteCounter;
393
1.86M
    bufLen = 8;
394
1.86M
  }
395
16.4M
  --bufLen;
396
16.4M
  return (buf >> bufLen) & 1;
397
16.4M
}
398
399
8.76k
void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {
400
8.76k
  Guint i, j, k, prefix;
401
8.76k
  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
181k
  for (i = 0; i < len; ++i) {
409
82.3M
    for (j = i; j < len && table[j].prefixLen == 0; ++j) ;
410
176k
    if (j == len) {
411
3.58k
      break;
412
3.58k
    }
413
250M
    for (k = j + 1; k < len; ++k) {
414
250M
      if (table[k].prefixLen > 0 &&
415
233M
    table[k].prefixLen < table[j].prefixLen) {
416
140k
  j = k;
417
140k
      }
418
250M
    }
419
172k
    if (j != i) {
420
159k
      tab = table[j];
421
91.6M
      for (k = j; k > i; --k) {
422
91.4M
  table[k] = table[k - 1];
423
91.4M
      }
424
159k
      table[i] = tab;
425
159k
    }
426
172k
  }
427
8.76k
  table[i] = table[len];
428
429
  // assign prefixes
430
8.76k
  if (table[0].rangeLen != jbig2HuffmanEOT) {
431
6.41k
    i = 0;
432
6.41k
    prefix = 0;
433
6.41k
    table[i++].prefix = prefix++;
434
172k
    for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) {
435
166k
      prefix <<= table[i].prefixLen - table[i-1].prefixLen;
436
166k
      table[i].prefix = prefix++;
437
166k
    }
438
6.41k
  }
439
8.76k
}
440
441
//------------------------------------------------------------------------
442
// JBIG2MMRDecoder
443
//------------------------------------------------------------------------
444
445
class JBIG2MMRDecoder {
446
public:
447
448
  JBIG2MMRDecoder();
449
  ~JBIG2MMRDecoder();
450
87.7k
  void setStream(Stream *strA) { str = strA; }
451
  void reset();
452
  int get2DCode();
453
  int getBlackCode();
454
  int getWhiteCode();
455
  Guint get24Bits();
456
186k
  void resetByteCounter() { byteCounter = 0; }
457
167k
  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
278k
JBIG2MMRDecoder::JBIG2MMRDecoder() {
470
278k
  str = NULL;
471
278k
  byteCounter = 0;
472
278k
  reset();
473
278k
}
474
475
277k
JBIG2MMRDecoder::~JBIG2MMRDecoder() {
476
277k
}
477
478
283k
void JBIG2MMRDecoder::reset() {
479
283k
  buf = 0;
480
283k
  bufLen = 0;
481
283k
  nBytesRead = 0;
482
283k
}
483
484
1.21M
int JBIG2MMRDecoder::get2DCode() {
485
1.21M
  CCITTCode *p;
486
487
1.21M
  if (bufLen == 0) {
488
91.2k
    buf = str->getChar() & 0xff;
489
91.2k
    bufLen = 8;
490
91.2k
    ++nBytesRead;
491
91.2k
    ++byteCounter;
492
91.2k
    p = &twoDimTab1[(buf >> 1) & 0x7f];
493
1.12M
  } else if (bufLen >= 7) {
494
361k
    p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
495
762k
  } else {
496
762k
    p = &twoDimTab1[(buf << (7 - bufLen)) & 0x7f];
497
762k
    if (p->bits < 0 || p->bits > (int)bufLen) {
498
116k
      buf = (buf << 8) | (str->getChar() & 0xff);
499
116k
      bufLen += 8;
500
116k
      ++nBytesRead;
501
116k
      ++byteCounter;
502
116k
      p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
503
116k
    }
504
762k
  }
505
1.21M
  if (p->bits < 0) {
506
229k
    error(errSyntaxError, str->getPos(),
507
229k
    "Bad two dim code in JBIG2 MMR stream");
508
229k
    return EOF;
509
229k
  }
510
986k
  bufLen -= p->bits;
511
986k
  return p->n;
512
1.21M
}
513
514
71.9k
int JBIG2MMRDecoder::getWhiteCode() {
515
71.9k
  CCITTCode *p;
516
71.9k
  Guint code;
517
518
71.9k
  if (bufLen == 0) {
519
3.26k
    buf = str->getChar() & 0xff;
520
3.26k
    bufLen = 8;
521
3.26k
    ++nBytesRead;
522
3.26k
    ++byteCounter;
523
3.26k
  }
524
117k
  while (1) {
525
117k
    if (bufLen >= 11 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
526
1.03k
      if (bufLen <= 12) {
527
286
  code = buf << (12 - bufLen);
528
749
      } else {
529
749
  code = buf >> (bufLen - 12);
530
749
      }
531
1.03k
      p = &whiteTab1[code & 0x1f];
532
116k
    } else {
533
116k
      if (bufLen <= 9) {
534
93.7k
  code = buf << (9 - bufLen);
535
93.7k
      } else {
536
22.4k
  code = buf >> (bufLen - 9);
537
22.4k
      }
538
116k
      p = &whiteTab2[code & 0x1ff];
539
116k
    }
540
117k
    if (p->bits > 0 && p->bits <= (int)bufLen) {
541
71.5k
      bufLen -= p->bits;
542
71.5k
      return p->n;
543
71.5k
    }
544
45.6k
    if (bufLen >= 12) {
545
438
      break;
546
438
    }
547
45.1k
    buf = (buf << 8) | (str->getChar() & 0xff);
548
45.1k
    bufLen += 8;
549
45.1k
    ++nBytesRead;
550
45.1k
    ++byteCounter;
551
45.1k
  }
552
438
  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
438
  --bufLen;
556
438
  return 1;
557
71.9k
}
558
559
65.9k
int JBIG2MMRDecoder::getBlackCode() {
560
65.9k
  CCITTCode *p;
561
65.9k
  Guint code;
562
563
65.9k
  if (bufLen == 0) {
564
3.14k
    buf = str->getChar() & 0xff;
565
3.14k
    bufLen = 8;
566
3.14k
    ++nBytesRead;
567
3.14k
    ++byteCounter;
568
3.14k
  }
569
100k
  while (1) {
570
100k
    if (bufLen >= 10 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
571
2.32k
      if (bufLen <= 13) {
572
858
  code = buf << (13 - bufLen);
573
1.46k
      } else {
574
1.46k
  code = buf >> (bufLen - 13);
575
1.46k
      }
576
2.32k
      p = &blackTab1[code & 0x7f];
577
98.5k
    } else if (bufLen >= 7 && ((buf >> (bufLen - 4)) & 0x0f) == 0 &&
578
2.41k
         ((buf >> (bufLen - 6)) & 0x03) != 0) {
579
1.68k
      if (bufLen <= 12) {
580
1.22k
  code = buf << (12 - bufLen);
581
1.22k
      } else {
582
457
  code = buf >> (bufLen - 12);
583
457
      }
584
1.68k
      p = &blackTab2[(code & 0xff) - 64];
585
96.9k
    } else {
586
96.9k
      if (bufLen <= 6) {
587
60.6k
  code = buf << (6 - bufLen);
588
60.6k
      } else {
589
36.2k
  code = buf >> (bufLen - 6);
590
36.2k
      }
591
96.9k
      p = &blackTab3[code & 0x3f];
592
96.9k
    }
593
100k
    if (p->bits > 0 && p->bits <= (int)bufLen) {
594
65.2k
      bufLen -= p->bits;
595
65.2k
      return p->n;
596
65.2k
    }
597
35.6k
    if (bufLen >= 13) {
598
628
      break;
599
628
    }
600
35.0k
    buf = (buf << 8) | (str->getChar() & 0xff);
601
35.0k
    bufLen += 8;
602
35.0k
    ++nBytesRead;
603
35.0k
    ++byteCounter;
604
35.0k
  }
605
628
  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
628
  --bufLen;
609
628
  return 1;
610
65.9k
}
611
612
1.25k
Guint JBIG2MMRDecoder::get24Bits() {
613
4.29k
  while (bufLen < 24) {
614
3.03k
    buf = (buf << 8) | (str->getChar() & 0xff);
615
3.03k
    bufLen += 8;
616
3.03k
    ++nBytesRead;
617
3.03k
    ++byteCounter;
618
3.03k
  }
619
1.25k
  return (buf >> (bufLen - 24)) & 0xffffff;
620
1.25k
}
621
622
3.67k
void JBIG2MMRDecoder::skipTo(Guint length) {
623
3.67k
  int n;
624
625
3.67k
  n = str->discardChars(length - nBytesRead);
626
3.67k
  nBytesRead += n;
627
3.67k
  byteCounter += n;
628
3.67k
}
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
379k
  JBIG2Segment(Guint segNumA) { segNum = segNumA; }
645
378k
  virtual ~JBIG2Segment() {}
646
1.39k
  void setSegNum(Guint segNumA) { segNum = segNumA; }
647
43.7k
  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.33k
  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
441k
  int getWidth() { return w; }
677
441k
  int getHeight() { return h; }
678
7.47M
  int getLineSize() { return line; }
679
  int getPixel(int x, int y)
680
935M
    { return (x < 0 || x >= w || y < 0 || y >= h) ? 0 :
681
935M
             (data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; }
682
  void setPixel(int x, int y)
683
380M
    { data[y * line + (x >> 3)] |= (Guchar)(1 << (7 - (x & 7))); }
684
  void clearPixel(int x, int y)
685
159M
    { 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
7.52M
  Guchar *getDataPtr() { return data; }
691
51.3k
  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
365k
  JBIG2Segment(segNumA)
703
365k
{
704
365k
  w = wA;
705
365k
  h = hA;
706
365k
  line = (wA + 7) >> 3;
707
365k
  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
74
    h = -1;
710
74
    line = 2;
711
74
  }
712
  // need to allocate one extra guard byte for use in combine()
713
365k
  data = (Guchar *)gmalloc(h * line + 1);
714
365k
  data[h * line] = 0;
715
365k
}
716
717
JBIG2Bitmap::JBIG2Bitmap(Guint segNumA, JBIG2Bitmap *bitmap):
718
1.33k
  JBIG2Segment(segNumA)
719
1.33k
{
720
1.33k
  w = bitmap->w;
721
1.33k
  h = bitmap->h;
722
1.33k
  line = bitmap->line;
723
1.33k
  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.33k
  data = (Guchar *)gmalloc(h * line + 1);
730
1.33k
  memcpy(data, bitmap->data, h * line);
731
1.33k
  data[h * line] = 0;
732
1.33k
}
733
734
366k
JBIG2Bitmap::~JBIG2Bitmap() {
735
366k
  gfree(data);
736
366k
}
737
738
//~ optimize this
739
136k
JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
740
136k
  JBIG2Bitmap *slice;
741
136k
  Guint xx, yy;
742
743
136k
  slice = new JBIG2Bitmap(0, wA, hA);
744
136k
  slice->clearToZero();
745
18.5M
  for (yy = 0; yy < hA; ++yy) {
746
529M
    for (xx = 0; xx < wA; ++xx) {
747
511M
      if (getPixel(x + xx, y + yy)) {
748
47.6M
  slice->setPixel(xx, yy);
749
47.6M
      }
750
511M
    }
751
18.4M
  }
752
136k
  return slice;
753
136k
}
754
755
1.32k
void JBIG2Bitmap::expand(int newH, Guint pixel) {
756
1.32k
  if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) {
757
735
    return;
758
735
  }
759
  // need to allocate one extra guard byte for use in combine()
760
591
  data = (Guchar *)grealloc(data, newH * line + 1);
761
591
  if (pixel) {
762
240
    memset(data + h * line, 0xff, (newH - h) * line);
763
351
  } else {
764
351
    memset(data + h * line, 0x00, (newH - h) * line);
765
351
  }
766
591
  h = newH;
767
591
  data[h * line] = 0;
768
591
}
769
770
330k
void JBIG2Bitmap::clearToZero() {
771
330k
  memset(data, 0, h * line);
772
330k
}
773
774
35.2k
void JBIG2Bitmap::clearToOne() {
775
35.2k
  memset(data, 0xff, h * line);
776
35.2k
}
777
778
176M
inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) {
779
176M
  if (y < 0 || y >= h || x >= w) {
780
11.4M
    ptr->p = NULL;
781
11.4M
    ptr->shift = 0; // make gcc happy
782
11.4M
    ptr->x = 0; // make gcc happy
783
164M
  } else if (x < 0) {
784
113M
    ptr->p = &data[y * line];
785
113M
    ptr->shift = 7;
786
113M
    ptr->x = x;
787
113M
  } else {
788
51.2M
    ptr->p = &data[y * line + (x >> 3)];
789
51.2M
    ptr->shift = 7 - (x & 7);
790
51.2M
    ptr->x = x;
791
51.2M
  }
792
176M
}
793
794
4.23G
inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr *ptr) {
795
4.23G
  int pix;
796
797
4.23G
  if (!ptr->p) {
798
1.01G
    pix = 0;
799
3.21G
  } else if (ptr->x < 0) {
800
221M
    ++ptr->x;
801
221M
    pix = 0;
802
2.99G
  } else {
803
2.99G
    pix = (*ptr->p >> ptr->shift) & 1;
804
2.99G
    if (++ptr->x == w) {
805
115M
      ptr->p = NULL;
806
2.88G
    } else if (ptr->shift == 0) {
807
338M
      ++ptr->p;
808
338M
      ptr->shift = 7;
809
2.54G
    } else {
810
2.54G
      --ptr->shift;
811
2.54G
    }
812
2.99G
  }
813
4.23G
  return pix;
814
4.23G
}
815
816
524k
void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) {
817
524k
  memcpy(data + yDest * line, data + ySrc * line, line);
818
524k
}
819
820
void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
821
178k
        Guint combOp) {
822
178k
  int x0, x1, y0, y1, xx, yy;
823
178k
  Guchar *srcPtr, *destPtr;
824
178k
  Guchar dest, src0, src1, src, m1, m2, m3;
825
178k
  Guint s1, s2;
826
178k
  GBool oneByte;
827
828
  // check for the pathological case where y = -2^31
829
178k
  if (y < -0x7fffffff) {
830
306
    return;
831
306
  }
832
178k
  if (y < 0) {
833
17.8k
    y0 = -y;
834
160k
  } else {
835
160k
    y0 = 0;
836
160k
  }
837
178k
  if (y > INT_MAX - bitmap->h) {
838
759
    return;
839
759
  }
840
177k
  if (y + bitmap->h > h) {
841
89.2k
    y1 = h - y;
842
89.2k
  } else {
843
88.1k
    y1 = bitmap->h;
844
88.1k
  }
845
177k
  if (y0 >= y1) {
846
41.3k
    return;
847
41.3k
  }
848
849
136k
  if (x >= 0) {
850
86.5k
    x0 = x & ~7;
851
86.5k
  } else {
852
49.4k
    x0 = 0;
853
49.4k
  }
854
136k
  x1 = x + bitmap->w;
855
136k
  if (x1 > w) {
856
84.7k
    x1 = w;
857
84.7k
  }
858
136k
  if (x0 >= x1) {
859
129k
    return;
860
129k
  }
861
862
6.78k
  s1 = x & 7;
863
6.78k
  s2 = 8 - s1;
864
6.78k
  m1 = (Guchar)(0xff >> (x1 & 7));
865
6.78k
  m2 = (Guchar)(0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7)));
866
6.78k
  m3 = (Guchar)((0xff >> s1) & m2);
867
868
6.78k
  oneByte = x0 == ((x1 - 1) & ~7);
869
870
547k
  for (yy = y0; yy < y1; ++yy) {
871
872
    // one byte per line -- need to mask both left and right side
873
540k
    if (oneByte) {
874
373k
      if (x >= 0) {
875
128k
  destPtr = data + (y + yy) * line + (x >> 3);
876
128k
  srcPtr = bitmap->data + yy * bitmap->line;
877
128k
  dest = *destPtr;
878
128k
  src1 = *srcPtr;
879
128k
  switch (combOp) {
880
83.8k
  case 0: // or
881
83.8k
    dest |= (Guchar)((src1 >> s1) & m2);
882
83.8k
    break;
883
21.3k
  case 1: // and
884
21.3k
    dest &= (Guchar)(((0xff00 | src1) >> s1) | m1);
885
21.3k
    break;
886
1.58k
  case 2: // xor
887
1.58k
    dest ^= (Guchar)((src1 >> s1) & m2);
888
1.58k
    break;
889
9.21k
  case 3: // xnor
890
9.21k
    dest ^= (Guchar)(((src1 ^ 0xff) >> s1) & m2);
891
9.21k
    break;
892
1.39k
  case 4: // replace
893
1.39k
    dest = (Guchar)((dest & ~m3) | ((src1 >> s1) & m3));
894
1.39k
    break;
895
128k
  }
896
128k
  *destPtr = dest;
897
245k
      } else {
898
245k
  destPtr = data + (y + yy) * line;
899
245k
  srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
900
245k
  dest = *destPtr;
901
245k
  src1 = *srcPtr;
902
245k
  switch (combOp) {
903
2.65k
  case 0: // or
904
2.65k
    dest |= src1 & m2;
905
2.65k
    break;
906
164k
  case 1: // and
907
164k
    dest &= src1 | m1;
908
164k
    break;
909
8.94k
  case 2: // xor
910
8.94k
    dest ^= src1 & m2;
911
8.94k
    break;
912
45.6k
  case 3: // xnor
913
45.6k
    dest ^= (src1 ^ 0xff) & m2;
914
45.6k
    break;
915
22.1k
  case 4: // replace
916
22.1k
    dest = (src1 & m2) | (dest & m1);
917
22.1k
    break;
918
245k
  }
919
245k
  *destPtr = dest;
920
245k
      }
921
922
    // multiple bytes per line -- need to mask left side of left-most
923
    // byte and right side of right-most byte
924
373k
    } else {
925
926
      // left-most byte
927
166k
      if (x >= 0) {
928
107k
  destPtr = data + (y + yy) * line + (x >> 3);
929
107k
  srcPtr = bitmap->data + yy * bitmap->line;
930
107k
  src1 = *srcPtr++;
931
107k
  dest = *destPtr;
932
107k
  switch (combOp) {
933
88.7k
  case 0: // or
934
88.7k
    dest |= (Guchar)(src1 >> s1);
935
88.7k
    break;
936
899
  case 1: // and
937
899
    dest &= (Guchar)((0xff00 | src1) >> s1);
938
899
    break;
939
13.6k
  case 2: // xor
940
13.6k
    dest ^= (Guchar)(src1 >> s1);
941
13.6k
    break;
942
1.78k
  case 3: // xnor
943
1.78k
    dest ^= (Guchar)((src1 ^ 0xff) >> s1);
944
1.78k
    break;
945
653
  case 4: // replace
946
653
    dest = (Guchar)((dest & (0xff << s2)) | (src1 >> s1));
947
653
    break;
948
107k
  }
949
107k
  *destPtr++ = dest;
950
107k
  xx = x0 + 8;
951
107k
      } else {
952
59.6k
  destPtr = data + (y + yy) * line;
953
59.6k
  srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
954
59.6k
  src1 = *srcPtr++;
955
59.6k
  xx = x0;
956
59.6k
      }
957
958
      // middle bytes
959
5.15M
      for (; xx < x1 - 8; xx += 8) {
960
4.98M
  dest = *destPtr;
961
4.98M
  src0 = src1;
962
4.98M
  src1 = *srcPtr++;
963
4.98M
  src = (Guchar)(((src0 << 8) | src1) >> s1);
964
4.98M
  switch (combOp) {
965
3.88M
  case 0: // or
966
3.88M
    dest |= src;
967
3.88M
    break;
968
32.0k
  case 1: // and
969
32.0k
    dest &= src;
970
32.0k
    break;
971
342k
  case 2: // xor
972
342k
    dest ^= src;
973
342k
    break;
974
9.43k
  case 3: // xnor
975
9.43k
    dest ^= src ^ 0xff;
976
9.43k
    break;
977
77.0k
  case 4: // replace
978
77.0k
    dest = src;
979
77.0k
    break;
980
4.98M
  }
981
4.98M
  *destPtr++ = dest;
982
4.98M
      }
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
166k
      dest = *destPtr;
990
166k
      src0 = src1;
991
166k
      src1 = *srcPtr++;
992
166k
      src = (Guchar)(((src0 << 8) | src1) >> s1);
993
166k
      switch (combOp) {
994
138k
      case 0: // or
995
138k
  dest |= src & m2;
996
138k
  break;
997
905
      case 1: // and
998
905
  dest &= src | m1;
999
905
  break;
1000
22.3k
      case 2: // xor
1001
22.3k
  dest ^= src & m2;
1002
22.3k
  break;
1003
1.79k
      case 3: // xnor
1004
1.79k
  dest ^= (src ^ 0xff) & m2;
1005
1.79k
  break;
1006
1.57k
      case 4: // replace
1007
1.57k
  dest = (src & m2) | (dest & m1);
1008
1.57k
  break;
1009
166k
      }
1010
166k
      *destPtr = dest;
1011
166k
    }
1012
540k
  }
1013
6.78k
}
1014
1015
//------------------------------------------------------------------------
1016
// JBIG2SymbolDict
1017
//------------------------------------------------------------------------
1018
1019
class JBIG2SymbolDict: public JBIG2Segment {
1020
public:
1021
1022
  JBIG2SymbolDict(Guint segNumA, Guint sizeA);
1023
  virtual ~JBIG2SymbolDict();
1024
4.46k
  virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; }
1025
4.46k
  Guint getSize() { return size; }
1026
1.33k
  void setBitmap(Guint idx, JBIG2Bitmap *bitmap) { bitmaps[idx] = bitmap; }
1027
0
  JBIG2Bitmap *getBitmap(Guint idx) { return bitmaps[idx]; }
1028
  void setGenericRegionStats(JArithmeticDecoderStats *stats)
1029
2.24k
    { genericRegionStats = stats; }
1030
  void setRefinementRegionStats(JArithmeticDecoderStats *stats)
1031
1.71k
    { refinementRegionStats = stats; }
1032
  JArithmeticDecoderStats *getGenericRegionStats()
1033
384
    { return genericRegionStats; }
1034
  JArithmeticDecoderStats *getRefinementRegionStats()
1035
386
    { 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
4.56k
  JBIG2Segment(segNumA)
1047
4.56k
{
1048
4.56k
  Guint i;
1049
1050
4.56k
  size = sizeA;
1051
4.56k
  bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
1052
1.21G
  for (i = 0; i < size; ++i) {
1053
1.21G
    bitmaps[i] = NULL;
1054
1.21G
  }
1055
4.56k
  genericRegionStats = NULL;
1056
4.56k
  refinementRegionStats = NULL;
1057
4.56k
}
1058
1059
4.54k
JBIG2SymbolDict::~JBIG2SymbolDict() {
1060
4.54k
  Guint i;
1061
1062
1.21G
  for (i = 0; i < size; ++i) {
1063
1.21G
    if (bitmaps[i]) {
1064
1.33k
      delete bitmaps[i];
1065
1.33k
    }
1066
1.21G
  }
1067
4.54k
  gfree(bitmaps);
1068
4.54k
  if (genericRegionStats) {
1069
2.23k
    delete genericRegionStats;
1070
2.23k
  }
1071
4.54k
  if (refinementRegionStats) {
1072
1.71k
    delete refinementRegionStats;
1073
1.71k
  }
1074
4.54k
}
1075
1076
//------------------------------------------------------------------------
1077
// JBIG2PatternDict
1078
//------------------------------------------------------------------------
1079
1080
class JBIG2PatternDict: public JBIG2Segment {
1081
public:
1082
1083
  JBIG2PatternDict(Guint segNumA, Guint sizeA);
1084
  virtual ~JBIG2PatternDict();
1085
4.87k
  virtual JBIG2SegmentType getType() { return jbig2SegPatternDict; }
1086
0
  Guint getSize() { return size; }
1087
4.68k
  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.71k
  JBIG2Segment(segNumA)
1098
1.71k
{
1099
1.71k
  size = sizeA;
1100
1.71k
  bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
1101
1.71k
}
1102
1103
1.71k
JBIG2PatternDict::~JBIG2PatternDict() {
1104
1.71k
  Guint i;
1105
1106
6.39k
  for (i = 0; i < size; ++i) {
1107
4.67k
    delete bitmaps[i];
1108
4.67k
  }
1109
1.71k
  gfree(bitmaps);
1110
1.71k
}
1111
1112
//------------------------------------------------------------------------
1113
// JBIG2CodeTable
1114
//------------------------------------------------------------------------
1115
1116
class JBIG2CodeTable: public JBIG2Segment {
1117
public:
1118
1119
  JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA);
1120
  virtual ~JBIG2CodeTable();
1121
38.5k
  virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; }
1122
6.82k
  JBIG2HuffmanTable *getHuffTable() { return table; }
1123
1124
private:
1125
1126
  JBIG2HuffmanTable *table;
1127
};
1128
1129
JBIG2CodeTable::JBIG2CodeTable(Guint segNumA, JBIG2HuffmanTable *tableA):
1130
6.06k
  JBIG2Segment(segNumA)
1131
6.06k
{
1132
6.06k
  table = tableA;
1133
6.06k
}
1134
1135
6.05k
JBIG2CodeTable::~JBIG2CodeTable() {
1136
6.05k
  gfree(table);
1137
6.05k
}
1138
1139
//------------------------------------------------------------------------
1140
// JBIG2Stream
1141
//------------------------------------------------------------------------
1142
1143
JBIG2Stream::JBIG2Stream(Stream *strA, Object *globalsStreamA):
1144
278k
  FilterStream(strA)
1145
278k
{
1146
278k
  decoded = gFalse;
1147
278k
  pageBitmap = NULL;
1148
1149
278k
  arithDecoder = new JArithmeticDecoder();
1150
278k
  genericRegionStats = new JArithmeticDecoderStats(1 << 1);
1151
278k
  refinementRegionStats = new JArithmeticDecoderStats(1 << 1);
1152
278k
  iadhStats = new JArithmeticDecoderStats(1 << 9);
1153
278k
  iadwStats = new JArithmeticDecoderStats(1 << 9);
1154
278k
  iaexStats = new JArithmeticDecoderStats(1 << 9);
1155
278k
  iaaiStats = new JArithmeticDecoderStats(1 << 9);
1156
278k
  iadtStats = new JArithmeticDecoderStats(1 << 9);
1157
278k
  iaitStats = new JArithmeticDecoderStats(1 << 9);
1158
278k
  iafsStats = new JArithmeticDecoderStats(1 << 9);
1159
278k
  iadsStats = new JArithmeticDecoderStats(1 << 9);
1160
278k
  iardxStats = new JArithmeticDecoderStats(1 << 9);
1161
278k
  iardyStats = new JArithmeticDecoderStats(1 << 9);
1162
278k
  iardwStats = new JArithmeticDecoderStats(1 << 9);
1163
278k
  iardhStats = new JArithmeticDecoderStats(1 << 9);
1164
278k
  iariStats = new JArithmeticDecoderStats(1 << 9);
1165
278k
  iaidStats = new JArithmeticDecoderStats(1 << 1);
1166
278k
  huffDecoder = new JBIG2HuffmanDecoder();
1167
278k
  mmrDecoder = new JBIG2MMRDecoder();
1168
1169
278k
  globalsStreamA->copy(&globalsStream);
1170
278k
  segments = globalSegments = NULL;
1171
278k
  curStr = NULL;
1172
278k
  dataPtr = dataEnd = NULL;
1173
278k
}
1174
1175
277k
JBIG2Stream::~JBIG2Stream() {
1176
277k
  close();
1177
277k
  globalsStream.free();
1178
277k
  delete arithDecoder;
1179
277k
  delete genericRegionStats;
1180
277k
  delete refinementRegionStats;
1181
277k
  delete iadhStats;
1182
277k
  delete iadwStats;
1183
277k
  delete iaexStats;
1184
277k
  delete iaaiStats;
1185
277k
  delete iadtStats;
1186
277k
  delete iaitStats;
1187
277k
  delete iafsStats;
1188
277k
  delete iadsStats;
1189
277k
  delete iardxStats;
1190
277k
  delete iardyStats;
1191
277k
  delete iardwStats;
1192
277k
  delete iardhStats;
1193
277k
  delete iariStats;
1194
277k
  delete iaidStats;
1195
277k
  delete huffDecoder;
1196
277k
  delete mmrDecoder;
1197
277k
  delete str;
1198
277k
}
1199
1200
270k
Stream *JBIG2Stream::copy() {
1201
270k
  return new JBIG2Stream(str->copy(), &globalsStream);
1202
270k
}
1203
1204
78.7k
void JBIG2Stream::reset() {
1205
78.7k
  segments = new GList();
1206
78.7k
  globalSegments = new GList();
1207
78.7k
  decoded = gFalse;
1208
78.7k
}
1209
1210
358k
void JBIG2Stream::close() {
1211
358k
  if (pageBitmap) {
1212
51.3k
    delete pageBitmap;
1213
51.3k
    pageBitmap = NULL;
1214
51.3k
  }
1215
358k
  if (segments) {
1216
78.6k
    deleteGList(segments, JBIG2Segment);
1217
78.6k
    segments = NULL;
1218
78.6k
  }
1219
358k
  if (globalSegments) {
1220
78.6k
    deleteGList(globalSegments, JBIG2Segment);
1221
78.6k
    globalSegments = NULL;
1222
78.6k
  }
1223
358k
  dataPtr = dataEnd = NULL;
1224
358k
  FilterStream::close();
1225
358k
}
1226
1227
774M
int JBIG2Stream::getChar() {
1228
774M
  if (!decoded) {
1229
78.5k
    decodeImage();
1230
78.5k
  }
1231
774M
  if (dataPtr && dataPtr < dataEnd) {
1232
773M
    return (*dataPtr++ ^ 0xff) & 0xff;
1233
773M
  }
1234
1.37M
  return EOF;
1235
774M
}
1236
1237
80.0M
int JBIG2Stream::lookChar() {
1238
80.0M
  if (!decoded) {
1239
0
    decodeImage();
1240
0
  }
1241
80.0M
  if (dataPtr && dataPtr < dataEnd) {
1242
79.9M
    return (*dataPtr ^ 0xff) & 0xff;
1243
79.9M
  }
1244
12.4k
  return EOF;
1245
80.0M
}
1246
1247
3.71k
int JBIG2Stream::getBlock(char *blk, int size) {
1248
3.71k
  int n, i;
1249
1250
3.71k
  if (!decoded) {
1251
113
    decodeImage();
1252
113
  }
1253
3.71k
  if (size <= 0) {
1254
0
    return 0;
1255
0
  }
1256
3.71k
  if (dataEnd - dataPtr < size) {
1257
235
    n = (int)(dataEnd - dataPtr);
1258
3.48k
  } else {
1259
3.48k
    n = size;
1260
3.48k
  }
1261
14.4M
  for (i = 0; i < n; ++i) {
1262
14.4M
    blk[i] = *dataPtr++ ^ 0xff;
1263
14.4M
  }
1264
3.71k
  return n;
1265
3.71k
}
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
78.6k
void JBIG2Stream::decodeImage() {
1277
78.6k
  GList *t;
1278
1279
  // read the globals stream
1280
78.6k
  if (globalsStream.isStream()) {
1281
9.13k
    curStr = globalsStream.getStream();
1282
9.13k
    curStr->reset();
1283
9.13k
    arithDecoder->setStream(curStr);
1284
9.13k
    huffDecoder->setStream(curStr);
1285
9.13k
    mmrDecoder->setStream(curStr);
1286
9.13k
    readSegments();
1287
9.13k
    curStr->close();
1288
    // swap the newly read segments list into globalSegments
1289
9.13k
    t = segments;
1290
9.13k
    segments = globalSegments;
1291
9.13k
    globalSegments = t;
1292
9.13k
  }
1293
1294
  // read the main stream
1295
78.6k
  curStr = str;
1296
78.6k
  curStr->reset();
1297
78.6k
  arithDecoder->setStream(curStr);
1298
78.6k
  huffDecoder->setStream(curStr);
1299
78.6k
  mmrDecoder->setStream(curStr);
1300
78.6k
  readSegments();
1301
1302
78.6k
  if (pageBitmap) {
1303
51.3k
    dataPtr = pageBitmap->getDataPtr();
1304
51.3k
    dataEnd = dataPtr + pageBitmap->getDataSize();
1305
51.3k
  } else {
1306
27.3k
    dataPtr = dataEnd = NULL;
1307
27.3k
  }
1308
1309
78.6k
  decoded = gTrue;
1310
78.6k
}
1311
1312
87.7k
void JBIG2Stream::readSegments() {
1313
87.7k
  Guint segNum, segFlags, segType, page, segLength;
1314
87.7k
  Guint refFlags, nRefSegs;
1315
87.7k
  Guint *refSegs;
1316
87.7k
  int c1, c2, c3;
1317
87.7k
  Guint i;
1318
1319
87.7k
  done = gFalse;
1320
204k
  while (!done && readULong(&segNum)) {
1321
1322
    // segment header flags
1323
194k
    if (!readUByte(&segFlags)) {
1324
261
      goto eofError1;
1325
261
    }
1326
194k
    segType = segFlags & 0x3f;
1327
1328
    // referred-to segment count and retention flags
1329
194k
    if (!readUByte(&refFlags)) {
1330
196
      goto eofError1;
1331
196
    }
1332
194k
    nRefSegs = refFlags >> 5;
1333
194k
    if (nRefSegs == 7) {
1334
9.76k
      if ((c1 = curStr->getChar()) == EOF ||
1335
9.55k
    (c2 = curStr->getChar()) == EOF ||
1336
9.34k
    (c3 = curStr->getChar()) == EOF) {
1337
649
  goto eofError1;
1338
649
      }
1339
9.11k
      refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3;
1340
9.11k
      nRefSegs = refFlags & 0x1fffffff;
1341
9.11k
      i = (nRefSegs + 9) >> 3;
1342
9.11k
      if (curStr->discardChars(i) != i) {
1343
952
  goto eofError1;
1344
952
      }
1345
9.11k
    }
1346
1347
    // referred-to segment numbers
1348
192k
    refSegs = (Guint *)gmallocn(nRefSegs, sizeof(Guint));
1349
192k
    if (segNum <= 256) {
1350
170k
      for (i = 0; i < nRefSegs; ++i) {
1351
156k
  if (!readUByte(&refSegs[i])) {
1352
214
    goto eofError2;
1353
214
  }
1354
156k
      }
1355
178k
    } else if (segNum <= 65536) {
1356
7.07M
      for (i = 0; i < nRefSegs; ++i) {
1357
7.05M
  if (!readUWord(&refSegs[i])) {
1358
657
    goto eofError2;
1359
657
  }
1360
7.05M
      }
1361
164k
    } else {
1362
544k
      for (i = 0; i < nRefSegs; ++i) {
1363
380k
  if (!readULong(&refSegs[i])) {
1364
802
    goto eofError2;
1365
802
  }
1366
380k
      }
1367
164k
    }
1368
1369
    // segment page association
1370
191k
    if (segFlags & 0x40) {
1371
36.6k
      if (!readULong(&page)) {
1372
721
  goto eofError2;
1373
721
      }
1374
154k
    } else {
1375
154k
      if (!readUByte(&page)) {
1376
188
  goto eofError2;
1377
188
      }
1378
154k
    }
1379
1380
    // segment data length
1381
190k
    if (!readULong(&segLength)) {
1382
801
      goto eofError2;
1383
801
    }
1384
1385
    // check for missing page information segment
1386
189k
    if (!pageBitmap && ((segType >= 4 && segType <= 7) ||
1387
92.8k
      (segType >= 20 && segType <= 43))) {
1388
2.78k
      error(errSyntaxError, getPos(),
1389
2.78k
      "First JBIG2 segment associated with a page must be a page information segment");
1390
2.78k
      goto syntaxError;
1391
2.78k
    }
1392
1393
    // read the segment data
1394
186k
    arithDecoder->resetByteCounter();
1395
186k
    huffDecoder->resetByteCounter();
1396
186k
    mmrDecoder->resetByteCounter();
1397
186k
    byteCounter = 0;
1398
186k
    switch (segType) {
1399
19.4k
    case 0:
1400
19.4k
      if (!readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs)) {
1401
15.7k
  goto syntaxError;
1402
15.7k
      }
1403
3.69k
      break;
1404
3.69k
    case 4:
1405
853
      readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
1406
853
      break;
1407
7.59k
    case 6:
1408
7.59k
      readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs);
1409
7.59k
      break;
1410
3.47k
    case 7:
1411
3.47k
      readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs);
1412
3.47k
      break;
1413
4.21k
    case 16:
1414
4.21k
      readPatternDictSeg(segNum, segLength);
1415
4.21k
      break;
1416
7.35k
    case 20:
1417
7.35k
      readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength,
1418
7.35k
          refSegs, nRefSegs);
1419
7.35k
      break;
1420
1.99k
    case 22:
1421
1.99k
      readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength,
1422
1.99k
          refSegs, nRefSegs);
1423
1.99k
      break;
1424
341
    case 23:
1425
341
      readHalftoneRegionSeg(segNum, gTrue, gTrue, segLength,
1426
341
          refSegs, nRefSegs);
1427
341
      break;
1428
1.64k
    case 36:
1429
1.64k
      readGenericRegionSeg(segNum, gFalse, gFalse, segLength);
1430
1.64k
      break;
1431
7.55k
    case 38:
1432
7.55k
      readGenericRegionSeg(segNum, gTrue, gFalse, segLength);
1433
7.55k
      break;
1434
877
    case 39:
1435
877
      readGenericRegionSeg(segNum, gTrue, gTrue, segLength);
1436
877
      break;
1437
1.92k
    case 40:
1438
1.92k
      readGenericRefinementRegionSeg(segNum, gFalse, gFalse, segLength,
1439
1.92k
             refSegs, nRefSegs);
1440
1.92k
      break;
1441
1.13k
    case 42:
1442
1.13k
      readGenericRefinementRegionSeg(segNum, gTrue, gFalse, segLength,
1443
1.13k
             refSegs, nRefSegs);
1444
1.13k
      break;
1445
6.65k
    case 43:
1446
6.65k
      readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength,
1447
6.65k
             refSegs, nRefSegs);
1448
6.65k
      break;
1449
105k
    case 48:
1450
105k
      readPageInfoSeg(segLength);
1451
105k
      break;
1452
347
    case 50:
1453
347
      readEndOfStripeSeg(segLength);
1454
347
      break;
1455
244
    case 51:
1456
      // end of file segment
1457
244
      done = gTrue;
1458
244
      break;
1459
359
    case 52:
1460
359
      readProfilesSeg(segLength);
1461
359
      break;
1462
8.19k
    case 53:
1463
8.19k
      readCodeTableSeg(segNum, segLength);
1464
8.19k
      break;
1465
663
    case 62:
1466
663
      readExtensionSeg(segLength);
1467
663
      break;
1468
6.08k
    default:
1469
6.08k
      error(errSyntaxError, getPos(), "Unknown segment type in JBIG2 stream");
1470
6.08k
      if (curStr->discardChars(segLength) != segLength) {
1471
3.07k
  goto eofError2;
1472
3.07k
      }
1473
3.01k
      break;
1474
186k
    }
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
167k
    if (!(segType == 38 && segLength == 0xffffffff)) {
1480
167k
      byteCounter += arithDecoder->getByteCounter();
1481
167k
      byteCounter += huffDecoder->getByteCounter();
1482
167k
      byteCounter += mmrDecoder->getByteCounter();
1483
      // do a sanity check on byteCounter vs segLength -- if there is
1484
      // a problem, abort the decode
1485
167k
      if (byteCounter > segLength ||
1486
162k
    segLength - byteCounter > 65536) {
1487
51.3k
  error(errSyntaxError, getPos(),
1488
51.3k
        "Invalid segment length in JBIG2 stream");
1489
51.3k
  gfree(refSegs);
1490
51.3k
  break;
1491
51.3k
      }
1492
115k
      byteCounter += curStr->discardChars(segLength - byteCounter);
1493
115k
    }
1494
1495
116k
    gfree(refSegs);
1496
116k
  }
1497
1498
60.5k
  return;
1499
1500
60.5k
 syntaxError:
1501
18.5k
  gfree(refSegs);
1502
18.5k
  return;
1503
1504
6.46k
 eofError2:
1505
6.46k
  gfree(refSegs);
1506
8.51k
 eofError1:
1507
8.51k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
1508
8.51k
}
1509
1510
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
1511
19.4k
             Guint *refSegs, Guint nRefSegs) {
1512
19.4k
  JBIG2SymbolDict *symbolDict;
1513
19.4k
  JBIG2HuffmanTable *huffDHTable, *huffDWTable;
1514
19.4k
  JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
1515
19.4k
  JBIG2Segment *seg;
1516
19.4k
  GList *codeTables;
1517
19.4k
  JBIG2SymbolDict *inputSymbolDict;
1518
19.4k
  Guint flags, sdTemplate, sdrTemplate, huff, refAgg;
1519
19.4k
  Guint huffDH, huffDW, huffBMSize, huffAggInst;
1520
19.4k
  Guint contextUsed, contextRetained;
1521
19.4k
  int sdATX[4], sdATY[4], sdrATX[2], sdrATY[2];
1522
19.4k
  Guint numExSyms, numNewSyms, numInputSyms, symCodeLen;
1523
19.4k
  JBIG2Bitmap **bitmaps;
1524
19.4k
  JBIG2Bitmap *collBitmap, *refBitmap;
1525
19.4k
  Guint *symWidths;
1526
19.4k
  Guint symHeight, symWidth, totalWidth, x, symID;
1527
19.4k
  int dh, dw, refAggNum, refDX, refDY, bmSize;
1528
19.4k
  GBool ex;
1529
19.4k
  int run, prevRun, cnt;
1530
19.4k
  Guint i, j, k;
1531
1532
19.4k
  symWidths = NULL;
1533
1534
  // symbol dictionary flags
1535
19.4k
  if (!readUWord(&flags)) {
1536
416
    goto eofError;
1537
416
  }
1538
19.0k
  sdTemplate = (flags >> 10) & 3;
1539
19.0k
  sdrTemplate = (flags >> 12) & 1;
1540
19.0k
  huff = flags & 1;
1541
19.0k
  refAgg = (flags >> 1) & 1;
1542
19.0k
  huffDH = (flags >> 2) & 3;
1543
19.0k
  huffDW = (flags >> 4) & 3;
1544
19.0k
  huffBMSize = (flags >> 6) & 1;
1545
19.0k
  huffAggInst = (flags >> 7) & 1;
1546
19.0k
  contextUsed = (flags >> 8) & 1;
1547
19.0k
  contextRetained = (flags >> 9) & 1;
1548
1549
  // symbol dictionary AT flags
1550
19.0k
  if (!huff) {
1551
11.2k
    if (sdTemplate == 0) {
1552
7.21k
      if (!readByte(&sdATX[0]) ||
1553
6.91k
    !readByte(&sdATY[0]) ||
1554
6.64k
    !readByte(&sdATX[1]) ||
1555
6.34k
    !readByte(&sdATY[1]) ||
1556
6.13k
    !readByte(&sdATX[2]) ||
1557
5.83k
    !readByte(&sdATY[2]) ||
1558
5.56k
    !readByte(&sdATX[3]) ||
1559
5.31k
    !readByte(&sdATY[3])) {
1560
2.18k
  goto eofError;
1561
2.18k
      }
1562
7.21k
    } else {
1563
4.05k
      if (!readByte(&sdATX[0]) ||
1564
3.71k
    !readByte(&sdATY[0])) {
1565
618
  goto eofError;
1566
618
      }
1567
4.05k
    }
1568
11.2k
  }
1569
1570
  // symbol dictionary refinement AT flags
1571
16.2k
  if (refAgg && !sdrTemplate) {
1572
3.95k
    if (!readByte(&sdrATX[0]) ||
1573
3.74k
  !readByte(&sdrATY[0]) ||
1574
3.55k
  !readByte(&sdrATX[1]) ||
1575
3.49k
  !readByte(&sdrATY[1])) {
1576
661
      goto eofError;
1577
661
    }
1578
3.95k
  }
1579
1580
  // SDNUMEXSYMS and SDNUMNEWSYMS
1581
15.6k
  if (!readULong(&numExSyms) || !readULong(&numNewSyms)) {
1582
2.05k
    goto eofError;
1583
2.05k
  }
1584
1585
  // get referenced segments: input symbol dictionaries and code tables
1586
13.5k
  codeTables = new GList();
1587
13.5k
  numInputSyms = 0;
1588
1.46M
  for (i = 0; i < nRefSegs; ++i) {
1589
1.44M
    if ((seg = findSegment(refSegs[i]))) {
1590
6.84k
      if (seg->getType() == jbig2SegSymbolDict) {
1591
1.72k
  j = ((JBIG2SymbolDict *)seg)->getSize();
1592
1.72k
  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.72k
  numInputSyms += j;
1599
5.11k
      } else if (seg->getType() == jbig2SegCodeTable) {
1600
4.15k
  codeTables->append(seg);
1601
4.15k
      }
1602
6.84k
    }
1603
1.44M
  }
1604
13.5k
  if (numNewSyms > INT_MAX || numInputSyms > INT_MAX - numNewSyms) {
1605
1.96k
    error(errSyntaxError, getPos(),
1606
1.96k
    "Too many input symbols in JBIG2 symbol dictionary");
1607
1.96k
    delete codeTables;
1608
1.96k
    goto eofError;
1609
1.96k
  }
1610
1611
  // compute symbol code length
1612
11.5k
  i = numInputSyms + numNewSyms;
1613
11.5k
  if (i <= 1) {
1614
4.14k
    symCodeLen = huff ? 1 : 0;
1615
7.44k
  } else {
1616
7.44k
    --i;
1617
7.44k
    symCodeLen = 0;
1618
    // i = floor((numSyms-1) / 2^symCodeLen)
1619
80.4k
    while (i > 0) {
1620
73.0k
      ++symCodeLen;
1621
73.0k
      i >>= 1;
1622
73.0k
    }
1623
7.44k
  }
1624
1625
  // get the input symbol bitmaps
1626
11.5k
  bitmaps = (JBIG2Bitmap **)gmallocn(numInputSyms + numNewSyms,
1627
11.5k
             sizeof(JBIG2Bitmap *));
1628
1.69G
  for (i = 0; i < numInputSyms + numNewSyms; ++i) {
1629
1.69G
    bitmaps[i] = NULL;
1630
1.69G
  }
1631
11.5k
  k = 0;
1632
11.5k
  inputSymbolDict = NULL;
1633
1.05M
  for (i = 0; i < nRefSegs; ++i) {
1634
1.04M
    if ((seg = findSegment(refSegs[i]))) {
1635
4.92k
      if (seg->getType() == jbig2SegSymbolDict) {
1636
781
  inputSymbolDict = (JBIG2SymbolDict *)seg;
1637
781
  for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1638
0
    bitmaps[k++] = inputSymbolDict->getBitmap(j);
1639
0
  }
1640
781
      }
1641
4.92k
    }
1642
1.04M
  }
1643
1644
  // get the Huffman tables
1645
11.5k
  huffDHTable = huffDWTable = NULL; // make gcc happy
1646
11.5k
  huffBMSizeTable = huffAggInstTable = NULL; // make gcc happy
1647
11.5k
  i = 0;
1648
11.5k
  if (huff) {
1649
5.01k
    if (huffDH == 0) {
1650
2.57k
      huffDHTable = huffTableD;
1651
2.57k
    } else if (huffDH == 1) {
1652
1.78k
      huffDHTable = huffTableE;
1653
1.78k
    } else {
1654
657
      if (i >= (Guint)codeTables->getLength()) {
1655
473
  goto codeTableError;
1656
473
      }
1657
184
      huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1658
184
    }
1659
4.54k
    if (huffDW == 0) {
1660
3.75k
      huffDWTable = huffTableB;
1661
3.75k
    } else if (huffDW == 1) {
1662
300
      huffDWTable = huffTableC;
1663
491
    } else {
1664
491
      if (i >= (Guint)codeTables->getLength()) {
1665
308
  goto codeTableError;
1666
308
      }
1667
183
      huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1668
183
    }
1669
4.23k
    if (huffBMSize == 0) {
1670
3.72k
      huffBMSizeTable = huffTableA;
1671
3.72k
    } else {
1672
505
      if (i >= (Guint)codeTables->getLength()) {
1673
419
  goto codeTableError;
1674
419
      }
1675
86
      huffBMSizeTable =
1676
86
    ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1677
86
    }
1678
3.81k
    if (huffAggInst == 0) {
1679
3.22k
      huffAggInstTable = huffTableA;
1680
3.22k
    } else {
1681
591
      if (i >= (Guint)codeTables->getLength()) {
1682
277
  goto codeTableError;
1683
277
      }
1684
314
      huffAggInstTable =
1685
314
    ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1686
314
    }
1687
3.81k
  }
1688
10.1k
  delete codeTables;
1689
1690
  // set up the Huffman decoder
1691
10.1k
  if (huff) {
1692
3.53k
    huffDecoder->reset();
1693
1694
  // set up the arithmetic decoder
1695
6.57k
  } else {
1696
6.57k
    if (contextUsed && inputSymbolDict) {
1697
384
      resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats());
1698
6.19k
    } else {
1699
6.19k
      resetGenericStats(sdTemplate, NULL);
1700
6.19k
    }
1701
6.57k
    resetIntStats(symCodeLen);
1702
6.57k
    arithDecoder->start();
1703
6.57k
  }
1704
1705
  // set up the arithmetic decoder for refinement/aggregation
1706
10.1k
  if (refAgg) {
1707
4.67k
    if (contextUsed && inputSymbolDict) {
1708
386
      resetRefinementStats(sdrTemplate,
1709
386
         inputSymbolDict->getRefinementRegionStats());
1710
4.28k
    } else {
1711
4.28k
      resetRefinementStats(sdrTemplate, NULL);
1712
4.28k
    }
1713
4.67k
  }
1714
1715
  // allocate symbol widths storage
1716
10.1k
  if (huff && !refAgg) {
1717
2.40k
    symWidths = (Guint *)gmallocn(numNewSyms, sizeof(Guint));
1718
2.40k
  }
1719
1720
10.1k
  symHeight = 0;
1721
10.1k
  i = 0;
1722
1.18M
  while (i < numNewSyms) {
1723
1724
    // read the height class delta height
1725
1.18M
    if (!(huff ? huffDecoder->decodeInt(&dh, huffDHTable) :
1726
1.18M
           arithDecoder->decodeInt(&dh, iadhStats)) ||
1727
1.18M
  (dh <= 0 && (Guint)-dh >= symHeight) ||
1728
1.18M
  (dh > 0 && (Guint)dh > UINT_MAX - symHeight)) {
1729
785
      error(errSyntaxError, getPos(),
1730
785
      "Bad delta-height value in JBIG2 symbol dictionary");
1731
785
      goto syntaxError;
1732
785
    }
1733
1.18M
    symHeight += dh;
1734
1.18M
    symWidth = 0;
1735
1.18M
    totalWidth = 0;
1736
1.18M
    j = i;
1737
1738
    // sanity check to avoid extremely long run-times with damaged streams
1739
1.18M
    if (symHeight > 100000) {
1740
392
      error(errSyntaxError, getPos(),
1741
392
      "Bogus symbol height value in JBIG2 symbol dictionary");
1742
392
      goto syntaxError;
1743
392
    }
1744
1745
    // read the symbols in this height class
1746
1.34M
    while (1) {
1747
1748
      // read the delta width
1749
1.34M
      if (huff) {
1750
210k
  if (!huffDecoder->decodeInt(&dw, huffDWTable)) {
1751
71.9k
    break;
1752
71.9k
  }
1753
1.12M
      } else {
1754
1.12M
  if (!arithDecoder->decodeInt(&dw, iadwStats)) {
1755
993
    break;
1756
993
  }
1757
1.12M
      }
1758
1.26M
      if ((dw <= 0 && (Guint)-dw >= symWidth) ||
1759
1.26M
    (dw > 0 && (Guint)dw > UINT_MAX - symWidth)) {
1760
960
  error(errSyntaxError, getPos(),
1761
960
        "Bad delta-height value in JBIG2 symbol dictionary");
1762
960
  goto syntaxError;
1763
960
      }
1764
1.26M
      symWidth += dw;
1765
1.26M
      if (i >= numNewSyms) {
1766
271
  error(errSyntaxError, getPos(),
1767
271
        "Too many symbols in JBIG2 symbol dictionary");
1768
271
  goto syntaxError;
1769
271
      }
1770
1771
      // sanity check to avoid extremely long run-times with damaged streams
1772
1.26M
      if (symWidth > 100000) {
1773
395
  error(errSyntaxError, getPos(),
1774
395
        "Bogus symbol width value in JBIG2 symbol dictionary");
1775
395
  goto syntaxError;
1776
395
      }
1777
1778
      // using a collective bitmap, so don't read a bitmap here
1779
1.26M
      if (huff && !refAgg) {
1780
130k
  symWidths[i] = symWidth;
1781
130k
  totalWidth += symWidth;
1782
1783
      // refinement/aggregate coding
1784
1.13M
      } else if (refAgg) {
1785
1.11M
  if (huff) {
1786
7.21k
    if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) {
1787
3.88k
      break;
1788
3.88k
    }
1789
1.11M
  } else {
1790
1.11M
    if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) {
1791
1.10M
      break;
1792
1.10M
    }
1793
1.11M
  }
1794
15.3k
  if (refAggNum <= 0 || refAggNum > 10000) {
1795
802
    error(errSyntaxError, getPos(),
1796
802
    "Invalid refinement/aggregation instance count in JBIG2 symbol dictionary");
1797
802
    goto syntaxError;
1798
802
  }
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
14.5k
  if (refAggNum == 1) {
1805
994
#endif
1806
994
    if (huff) {
1807
421
      symID = huffDecoder->readBits(symCodeLen);
1808
421
      huffDecoder->decodeInt(&refDX, huffTableO);
1809
421
      huffDecoder->decodeInt(&refDY, huffTableO);
1810
421
      huffDecoder->decodeInt(&bmSize, huffTableA);
1811
421
      huffDecoder->reset();
1812
421
      arithDecoder->start();
1813
573
    } else {
1814
573
      symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
1815
573
      arithDecoder->decodeInt(&refDX, iardxStats);
1816
573
      arithDecoder->decodeInt(&refDY, iardyStats);
1817
573
    }
1818
994
    if (symID >= numInputSyms + i) {
1819
720
      error(errSyntaxError, getPos(),
1820
720
      "Invalid symbol ID in JBIG2 symbol dictionary");
1821
720
      goto syntaxError;
1822
720
    }
1823
274
    refBitmap = bitmaps[symID];
1824
274
    bitmaps[numInputSyms + i] =
1825
274
        readGenericRefinementRegion(symWidth, symHeight,
1826
274
            sdrTemplate, gFalse,
1827
274
            refBitmap, refDX, refDY,
1828
274
            sdrATX, sdrATY);
1829
    //~ do we need to use the bmSize value here (in Huffman mode)?
1830
13.5k
  } else {
1831
13.5k
    bitmaps[numInputSyms + i] =
1832
13.5k
        readTextRegion(huff, gTrue, symWidth, symHeight,
1833
13.5k
           refAggNum, 0, numInputSyms + i, NULL,
1834
13.5k
           symCodeLen, bitmaps, 0, 0, 0, 1, 0,
1835
13.5k
           huffTableF, huffTableH, huffTableK, huffTableO,
1836
13.5k
           huffTableO, huffTableO, huffTableO, huffTableA,
1837
13.5k
           sdrTemplate, sdrATX, sdrATY);
1838
13.5k
  }
1839
1840
      // non-ref/agg coding
1841
15.5k
      } else {
1842
15.5k
  bitmaps[numInputSyms + i] =
1843
15.5k
      readGenericBitmap(gFalse, symWidth, symHeight,
1844
15.5k
            sdTemplate, gFalse, gFalse, NULL,
1845
15.5k
            sdATX, sdATY, 0);
1846
15.5k
      }
1847
1848
160k
      ++i;
1849
160k
    }
1850
1851
    // read the collective bitmap
1852
1.17M
    if (huff && !refAgg) {
1853
4.81k
      if (totalWidth == 0) {
1854
1.14k
  error(errSyntaxError, getPos(),
1855
1.14k
        "Invalid height class width in JBIG2 symbol dictionary");
1856
1.14k
  goto syntaxError;
1857
1.14k
      }
1858
3.67k
      huffDecoder->decodeInt(&bmSize, huffBMSizeTable);
1859
3.67k
      huffDecoder->reset();
1860
3.67k
      if (bmSize == 0) {
1861
243
  collBitmap = new JBIG2Bitmap(0, totalWidth, symHeight);
1862
243
  bmSize = symHeight * ((totalWidth + 7) >> 3);
1863
243
  byteCounter += curStr->getBlock((char *)collBitmap->getDataPtr(),
1864
243
          bmSize);
1865
3.43k
      } else {
1866
3.43k
  collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
1867
3.43k
               0, gFalse, gFalse, NULL, NULL, NULL,
1868
3.43k
               bmSize);
1869
3.43k
      }
1870
3.67k
      x = 0;
1871
133k
      for (; j < i; ++j) {
1872
130k
  bitmaps[numInputSyms + j] =
1873
130k
      collBitmap->getSlice(x, 0, symWidths[j], symHeight);
1874
130k
  x += symWidths[j];
1875
130k
      }
1876
3.67k
      delete collBitmap;
1877
3.67k
    }
1878
1.17M
  }
1879
1880
  // create the symbol dict object
1881
4.64k
  symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
1882
1883
  // exported symbol list
1884
4.64k
  i = j = 0;
1885
4.64k
  ex = gFalse;
1886
4.64k
  prevRun = 1;
1887
6.93k
  while (i < numInputSyms + numNewSyms) {
1888
2.87k
    if (huff) {
1889
953
      huffDecoder->decodeInt(&run, huffTableA);
1890
1.92k
    } else {
1891
1.92k
      arithDecoder->decodeInt(&run, iaexStats);
1892
1.92k
    }
1893
2.87k
    if (run == 0 && prevRun == 0) {
1894
      // this avoids infinite loops with damaged files (consecutive
1895
      // zero runs are never useful)
1896
232
      error(errSyntaxError, getPos(),
1897
232
      "Invalid exported symbol list in JBIG2 symbol dictionary");
1898
232
      delete symbolDict;
1899
232
      goto syntaxError;
1900
232
    }
1901
2.64k
    if (i + run > numInputSyms + numNewSyms ||
1902
2.54k
  (ex && j + run > numExSyms)) {
1903
350
      error(errSyntaxError, getPos(),
1904
350
      "Too many exported symbols in JBIG2 symbol dictionary");
1905
350
      delete symbolDict;
1906
350
      goto syntaxError;
1907
350
    }
1908
2.29k
    if (ex) {
1909
2.15k
      for (cnt = 0; cnt < run; ++cnt) {
1910
1.33k
  symbolDict->setBitmap(j++, bitmaps[i++]->copy());
1911
1.33k
      }
1912
1.47k
    } else {
1913
1.47k
      i += run;
1914
1.47k
    }
1915
2.29k
    ex = !ex;
1916
2.29k
    prevRun = run;
1917
2.29k
  }
1918
4.06k
  if (j != numExSyms) {
1919
370
    error(errSyntaxError, getPos(), "Too few symbols in JBIG2 symbol dictionary");
1920
370
    delete symbolDict;
1921
370
    goto syntaxError;
1922
370
  }
1923
1924
5.14k
  for (i = 0; i < numNewSyms; ++i) {
1925
1.44k
    delete bitmaps[numInputSyms + i];
1926
1.44k
  }
1927
3.69k
  gfree(bitmaps);
1928
3.69k
  if (symWidths) {
1929
233
    gfree(symWidths);
1930
233
  }
1931
1932
  // save the arithmetic decoder stats
1933
3.69k
  if (!huff && contextRetained) {
1934
2.24k
    symbolDict->setGenericRegionStats(genericRegionStats->copy());
1935
2.24k
    if (refAgg) {
1936
1.71k
      symbolDict->setRefinementRegionStats(refinementRegionStats->copy());
1937
1.71k
    }
1938
2.24k
  }
1939
1940
  // store the new symbol dict
1941
3.69k
  segments->append(symbolDict);
1942
1943
3.69k
  return gTrue;
1944
1945
1.47k
 codeTableError:
1946
1.47k
  error(errSyntaxError, getPos(), "Missing code table in JBIG2 symbol dictionary");
1947
1.47k
  delete codeTables;
1948
1949
7.89k
 syntaxError:
1950
1.69G
  for (i = 0; i < numNewSyms; ++i) {
1951
1.69G
    if (bitmaps[numInputSyms + i]) {
1952
157k
      delete bitmaps[numInputSyms + i];
1953
157k
    }
1954
1.69G
  }
1955
7.89k
  gfree(bitmaps);
1956
7.89k
  if (symWidths) {
1957
2.01k
    gfree(symWidths);
1958
2.01k
  }
1959
7.89k
  return gFalse;
1960
1961
7.89k
 eofError:
1962
7.89k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
1963
7.89k
  return gFalse;
1964
1.47k
}
1965
1966
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
1967
            GBool lossless, Guint length,
1968
11.9k
            Guint *refSegs, Guint nRefSegs) {
1969
11.9k
  JBIG2Bitmap *bitmap;
1970
11.9k
  JBIG2HuffmanTable runLengthTab[36];
1971
11.9k
  JBIG2HuffmanTable *symCodeTab;
1972
11.9k
  JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable;
1973
11.9k
  JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
1974
11.9k
  JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
1975
11.9k
  JBIG2Segment *seg;
1976
11.9k
  GList *codeTables;
1977
11.9k
  JBIG2SymbolDict *symbolDict;
1978
11.9k
  JBIG2Bitmap **syms;
1979
11.9k
  Guint w, h, x, y, segInfoFlags, extCombOp;
1980
11.9k
  Guint flags, huff, refine, logStrips, refCorner, transposed;
1981
11.9k
  Guint combOp, defPixel, templ;
1982
11.9k
  int sOffset;
1983
11.9k
  Guint huffFlags, huffFS, huffDS, huffDT;
1984
11.9k
  Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize;
1985
11.9k
  Guint numInstances, numSyms, symCodeLen;
1986
11.9k
  int atx[2], aty[2];
1987
11.9k
  Guint i, k, kk;
1988
11.9k
  int j;
1989
1990
  // region segment info field
1991
11.9k
  if (!readULong(&w) || !readULong(&h) ||
1992
10.2k
      !readULong(&x) || !readULong(&y) ||
1993
8.55k
      !readUByte(&segInfoFlags)) {
1994
3.57k
    goto eofError;
1995
3.57k
  }
1996
8.35k
  if (w == 0 || h == 0) {
1997
639
    error(errSyntaxError, getPos(), "Bad size in JBIG2 text region segment");
1998
639
    return;
1999
639
  }
2000
  // sanity check: if the w/h/x/y values are way out of range, it likely
2001
  // indicates a damaged JBIG2 stream
2002
7.71k
  if (w / 10 > pageW || h / 10 > pageH ||
2003
7.24k
      x / 10 > pageW || y / 10 > pageH) {
2004
812
    error(errSyntaxError, getPos(),
2005
812
    "Bad size or position in JBIG2 text region segment");
2006
812
    done = gTrue;
2007
812
    return;
2008
812
  }
2009
6.90k
  extCombOp = segInfoFlags & 7;
2010
2011
  // rest of the text region header
2012
6.90k
  if (!readUWord(&flags)) {
2013
226
    goto eofError;
2014
226
  }
2015
6.67k
  huff = flags & 1;
2016
6.67k
  refine = (flags >> 1) & 1;
2017
6.67k
  logStrips = (flags >> 2) & 3;
2018
6.67k
  refCorner = (flags >> 4) & 3;
2019
6.67k
  transposed = (flags >> 6) & 1;
2020
6.67k
  combOp = (flags >> 7) & 3;
2021
6.67k
  defPixel = (flags >> 9) & 1;
2022
6.67k
  sOffset = (flags >> 10) & 0x1f;
2023
6.67k
  if (sOffset & 0x10) {
2024
3.17k
    sOffset |= -1 - 0x0f;
2025
3.17k
  }
2026
6.67k
  templ = (flags >> 15) & 1;
2027
6.67k
  huffFS = huffDS = huffDT = 0; // make gcc happy
2028
6.67k
  huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0; // make gcc happy
2029
6.67k
  if (huff) {
2030
5.38k
    if (!readUWord(&huffFlags)) {
2031
232
      goto eofError;
2032
232
    }
2033
5.15k
    huffFS = huffFlags & 3;
2034
5.15k
    huffDS = (huffFlags >> 2) & 3;
2035
5.15k
    huffDT = (huffFlags >> 4) & 3;
2036
5.15k
    huffRDW = (huffFlags >> 6) & 3;
2037
5.15k
    huffRDH = (huffFlags >> 8) & 3;
2038
5.15k
    huffRDX = (huffFlags >> 10) & 3;
2039
5.15k
    huffRDY = (huffFlags >> 12) & 3;
2040
5.15k
    huffRSize = (huffFlags >> 14) & 1;
2041
5.15k
  }
2042
6.44k
  if (refine && templ == 0) {
2043
3.02k
    if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
2044
2.60k
  !readByte(&atx[1]) || !readByte(&aty[1])) {
2045
848
      goto eofError;
2046
848
    }
2047
3.02k
  }
2048
5.59k
  if (!readULong(&numInstances)) {
2049
281
    goto eofError;
2050
281
  }
2051
2052
  // get symbol dictionaries and tables
2053
5.31k
  codeTables = new GList();
2054
5.31k
  numSyms = 0;
2055
16.0k
  for (i = 0; i < nRefSegs; ++i) {
2056
12.0k
    if ((seg = findSegment(refSegs[i]))) {
2057
10.7k
      if (seg->getType() == jbig2SegSymbolDict) {
2058
986
  Guint segSize = ((JBIG2SymbolDict *)seg)->getSize();
2059
986
  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
986
  numSyms += segSize;
2066
9.74k
      } else if (seg->getType() == jbig2SegCodeTable) {
2067
8.98k
  codeTables->append(seg);
2068
8.98k
      }
2069
10.7k
    } else {
2070
1.31k
      error(errSyntaxError, getPos(),
2071
1.31k
      "Invalid segment reference in JBIG2 text region");
2072
1.31k
      delete codeTables;
2073
1.31k
      return;
2074
1.31k
    }
2075
12.0k
  }
2076
4.00k
  i = numSyms;
2077
4.00k
  if (i <= 1) {
2078
4.00k
    symCodeLen = huff ? 1 : 0;
2079
4.00k
  } 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
4.00k
  syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *));
2091
4.00k
  kk = 0;
2092
14.3k
  for (i = 0; i < nRefSegs; ++i) {
2093
10.3k
    if ((seg = findSegment(refSegs[i]))) {
2094
10.3k
      if (seg->getType() == jbig2SegSymbolDict) {
2095
969
  symbolDict = (JBIG2SymbolDict *)seg;
2096
969
  for (k = 0; k < symbolDict->getSize(); ++k) {
2097
0
    syms[kk++] = symbolDict->getBitmap(k);
2098
0
  }
2099
969
      }
2100
10.3k
    }
2101
10.3k
  }
2102
2103
  // get the Huffman tables
2104
4.00k
  huffFSTable = huffDSTable = huffDTTable = NULL; // make gcc happy
2105
4.00k
  huffRDWTable = huffRDHTable = NULL; // make gcc happy
2106
4.00k
  huffRDXTable = huffRDYTable = huffRSizeTable = NULL; // make gcc happy
2107
4.00k
  i = 0;
2108
4.00k
  if (huff) {
2109
3.68k
    if (huffFS == 0) {
2110
1.14k
      huffFSTable = huffTableF;
2111
2.54k
    } else if (huffFS == 1) {
2112
1.04k
      huffFSTable = huffTableG;
2113
1.50k
    } else {
2114
1.50k
      if (i >= (Guint)codeTables->getLength()) {
2115
343
  goto codeTableError;
2116
343
      }
2117
1.15k
      huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2118
1.15k
    }
2119
3.34k
    if (huffDS == 0) {
2120
729
      huffDSTable = huffTableH;
2121
2.61k
    } else if (huffDS == 1) {
2122
930
      huffDSTable = huffTableI;
2123
1.68k
    } else if (huffDS == 2) {
2124
786
      huffDSTable = huffTableJ;
2125
899
    } else {
2126
899
      if (i >= (Guint)codeTables->getLength()) {
2127
307
  goto codeTableError;
2128
307
      }
2129
592
      huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2130
592
    }
2131
3.03k
    if (huffDT == 0) {
2132
809
      huffDTTable = huffTableK;
2133
2.22k
    } else if (huffDT == 1) {
2134
670
      huffDTTable = huffTableL;
2135
1.55k
    } else if (huffDT == 2) {
2136
523
      huffDTTable = huffTableM;
2137
1.03k
    } else {
2138
1.03k
      if (i >= (Guint)codeTables->getLength()) {
2139
297
  goto codeTableError;
2140
297
      }
2141
738
      huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2142
738
    }
2143
2.74k
    if (huffRDW == 0) {
2144
617
      huffRDWTable = huffTableN;
2145
2.12k
    } else if (huffRDW == 1) {
2146
806
      huffRDWTable = huffTableO;
2147
1.31k
    } else {
2148
1.31k
      if (i >= (Guint)codeTables->getLength()) {
2149
258
  goto codeTableError;
2150
258
      }
2151
1.05k
      huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2152
1.05k
    }
2153
2.48k
    if (huffRDH == 0) {
2154
911
      huffRDHTable = huffTableN;
2155
1.57k
    } else if (huffRDH == 1) {
2156
742
      huffRDHTable = huffTableO;
2157
829
    } else {
2158
829
      if (i >= (Guint)codeTables->getLength()) {
2159
237
  goto codeTableError;
2160
237
      }
2161
592
      huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2162
592
    }
2163
2.24k
    if (huffRDX == 0) {
2164
769
      huffRDXTable = huffTableN;
2165
1.47k
    } else if (huffRDX == 1) {
2166
1.01k
      huffRDXTable = huffTableO;
2167
1.01k
    } else {
2168
463
      if (i >= (Guint)codeTables->getLength()) {
2169
228
  goto codeTableError;
2170
228
      }
2171
235
      huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2172
235
    }
2173
2.01k
    if (huffRDY == 0) {
2174
482
      huffRDYTable = huffTableN;
2175
1.53k
    } else if (huffRDY == 1) {
2176
416
      huffRDYTable = huffTableO;
2177
1.11k
    } else {
2178
1.11k
      if (i >= (Guint)codeTables->getLength()) {
2179
260
  goto codeTableError;
2180
260
      }
2181
859
      huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2182
859
    }
2183
1.75k
    if (huffRSize == 0) {
2184
525
      huffRSizeTable = huffTableA;
2185
1.23k
    } else {
2186
1.23k
      if (i >= (Guint)codeTables->getLength()) {
2187
409
  goto codeTableError;
2188
409
      }
2189
823
      huffRSizeTable =
2190
823
    ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2191
823
    }
2192
1.75k
  }
2193
1.66k
  delete codeTables;
2194
2195
  // symbol ID Huffman decoding table
2196
1.66k
  if (huff) {
2197
1.34k
    huffDecoder->reset();
2198
44.4k
    for (i = 0; i < 32; ++i) {
2199
43.1k
      runLengthTab[i].val = i;
2200
43.1k
      runLengthTab[i].prefixLen = huffDecoder->readBits(4);
2201
43.1k
      runLengthTab[i].rangeLen = 0;
2202
43.1k
      runLengthTab[i].prefix = 0;
2203
43.1k
    }
2204
1.34k
    runLengthTab[32].val = 0x103;
2205
1.34k
    runLengthTab[32].prefixLen = huffDecoder->readBits(4);
2206
1.34k
    runLengthTab[32].rangeLen = 2;
2207
1.34k
    runLengthTab[32].prefix = 0;
2208
1.34k
    runLengthTab[33].val = 0x203;
2209
1.34k
    runLengthTab[33].prefixLen = huffDecoder->readBits(4);
2210
1.34k
    runLengthTab[33].rangeLen = 3;
2211
1.34k
    runLengthTab[33].prefix = 0;
2212
1.34k
    runLengthTab[34].val = 0x20b;
2213
1.34k
    runLengthTab[34].prefixLen = huffDecoder->readBits(4);
2214
1.34k
    runLengthTab[34].rangeLen = 7;
2215
1.34k
    runLengthTab[34].prefix = 0;
2216
1.34k
    runLengthTab[35].prefixLen = 0;
2217
1.34k
    runLengthTab[35].rangeLen = jbig2HuffmanEOT;
2218
1.34k
    runLengthTab[35].prefix = 0;
2219
1.34k
    huffDecoder->buildTable(runLengthTab, 35);
2220
1.34k
    symCodeTab = (JBIG2HuffmanTable *)gmallocn(numSyms + 1,
2221
1.34k
                 sizeof(JBIG2HuffmanTable));
2222
1.34k
    for (i = 0; i < numSyms; ++i) {
2223
0
      symCodeTab[i].val = i;
2224
0
      symCodeTab[i].rangeLen = 0;
2225
0
    }
2226
1.34k
    i = 0;
2227
1.34k
    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.34k
    symCodeTab[numSyms].prefixLen = 0;
2249
1.34k
    symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT;
2250
1.34k
    huffDecoder->buildTable(symCodeTab, numSyms);
2251
1.34k
    huffDecoder->reset();
2252
2253
  // set up the arithmetic decoder
2254
1.34k
  } else {
2255
320
    symCodeTab = NULL;
2256
320
    resetIntStats(symCodeLen);
2257
320
    arithDecoder->start();
2258
320
  }
2259
1.66k
  if (refine) {
2260
973
    resetRefinementStats(templ, NULL);
2261
973
  }
2262
2263
1.66k
  bitmap = readTextRegion(huff, refine, w, h, numInstances,
2264
1.66k
        logStrips, numSyms, symCodeTab, symCodeLen, syms,
2265
1.66k
        defPixel, combOp, transposed, refCorner, sOffset,
2266
1.66k
        huffFSTable, huffDSTable, huffDTTable,
2267
1.66k
        huffRDWTable, huffRDHTable,
2268
1.66k
        huffRDXTable, huffRDYTable, huffRSizeTable,
2269
1.66k
        templ, atx, aty);
2270
2271
1.66k
  gfree(syms);
2272
2273
  // combine the region bitmap into the page bitmap
2274
1.66k
  if (imm) {
2275
1.50k
    if (pageH == 0xffffffff && y + h > curPageH) {
2276
41
      pageBitmap->expand(y + h, pageDefPixel);
2277
41
    }
2278
1.50k
    pageBitmap->combine(bitmap, x, y, extCombOp);
2279
1.50k
    delete bitmap;
2280
2281
  // store the region bitmap
2282
1.50k
  } else {
2283
168
    bitmap->setSegNum(segNum);
2284
168
    segments->append(bitmap);
2285
168
  }
2286
2287
  // clean up the Huffman decoder
2288
1.66k
  if (huff) {
2289
1.34k
    gfree(symCodeTab);
2290
1.34k
  }
2291
2292
1.66k
  return;
2293
2294
2.33k
 codeTableError:
2295
2.33k
  error(errSyntaxError, getPos(), "Missing code table in JBIG2 text region");
2296
2.33k
  delete codeTables;
2297
2.33k
  gfree(syms);
2298
2.33k
  return;
2299
2300
5.16k
 eofError:
2301
5.16k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
2302
5.16k
  return;
2303
1.66k
}
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
15.2k
           int *atx, int *aty) {
2326
15.2k
  JBIG2Bitmap *bitmap;
2327
15.2k
  JBIG2Bitmap *symbolBitmap;
2328
15.2k
  Guint strips;
2329
15.2k
  int t, dt, tt, s, ds, sFirst, j;
2330
15.2k
  int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize;
2331
15.2k
  Guint symID, inst, bw, bh;
2332
2333
15.2k
  strips = 1 << logStrips;
2334
2335
  // allocate the bitmap
2336
15.2k
  bitmap = new JBIG2Bitmap(0, w, h);
2337
15.2k
  if (defPixel) {
2338
468
    bitmap->clearToOne();
2339
14.7k
  } else {
2340
14.7k
    bitmap->clearToZero();
2341
14.7k
  }
2342
2343
  // decode initial T value
2344
15.2k
  if (huff) {
2345
3.94k
    huffDecoder->decodeInt(&t, huffDTTable);
2346
11.2k
  } else {
2347
11.2k
    arithDecoder->decodeInt(&t, iadtStats);
2348
11.2k
  }
2349
15.2k
  t *= -(int)strips;
2350
2351
15.2k
  inst = 0;
2352
15.2k
  sFirst = 0;
2353
69.2k
  while (inst < numInstances) {
2354
2355
    // decode delta-T
2356
59.1k
    if (huff) {
2357
27.2k
      if (!huffDecoder->decodeInt(&dt, huffDTTable)) {
2358
348
  break;
2359
348
      }
2360
31.8k
    } else {
2361
31.8k
      if (!arithDecoder->decodeInt(&dt, iadtStats)) {
2362
1.06k
  break;
2363
1.06k
      }
2364
31.8k
    }
2365
57.7k
    t += dt * strips;
2366
2367
    // first S value
2368
57.7k
    if (huff) {
2369
26.9k
      if (!huffDecoder->decodeInt(&ds, huffFSTable)) {
2370
807
  break;
2371
807
      }
2372
30.7k
    } else {
2373
30.7k
      if (!arithDecoder->decodeInt(&ds, iafsStats)) {
2374
2.83k
  break;
2375
2.83k
      }
2376
30.7k
    }
2377
54.0k
    sFirst += ds;
2378
54.0k
    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
2.67M
    while (inst < numInstances) {
2384
2385
      // T value
2386
2.67M
      if (strips == 1) {
2387
1.12M
  dt = 0;
2388
1.54M
      } else if (huff) {
2389
1.53M
  dt = huffDecoder->readBits(logStrips);
2390
1.53M
      } else {
2391
5.37k
  arithDecoder->decodeInt(&dt, iaitStats);
2392
5.37k
      }
2393
2.67M
      tt = t + dt;
2394
2395
      // symbol ID
2396
2.67M
      if (huff) {
2397
1.76M
  if (symCodeTab) {
2398
1.61M
    huffDecoder->decodeInt(&j, symCodeTab);
2399
1.61M
    symID = (Guint)j;
2400
1.61M
  } else {
2401
146k
    symID = huffDecoder->readBits(symCodeLen);
2402
146k
  }
2403
1.76M
      } else {
2404
908k
  symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
2405
908k
      }
2406
2407
2.67M
      if (symID >= (Guint)numSyms) {
2408
2.49M
  error(errSyntaxError, getPos(),
2409
2.49M
        "Invalid symbol number in JBIG2 text region");
2410
2.49M
      } else {
2411
2412
  // get the symbol bitmap
2413
175k
  symbolBitmap = NULL;
2414
175k
  if (refine) {
2415
175k
    if (huff) {
2416
36.7k
      ri = (int)huffDecoder->readBit();
2417
138k
    } else {
2418
138k
      arithDecoder->decodeInt(&ri, iariStats);
2419
138k
    }
2420
175k
  } else {
2421
0
    ri = 0;
2422
0
  }
2423
175k
  if (ri) {
2424
134k
    if (huff) {
2425
2.55k
      huffDecoder->decodeInt(&rdw, huffRDWTable);
2426
2.55k
      huffDecoder->decodeInt(&rdh, huffRDHTable);
2427
2.55k
      huffDecoder->decodeInt(&rdx, huffRDXTable);
2428
2.55k
      huffDecoder->decodeInt(&rdy, huffRDYTable);
2429
2.55k
      huffDecoder->decodeInt(&bmSize, huffRSizeTable);
2430
2.55k
      huffDecoder->reset();
2431
2.55k
      arithDecoder->start();
2432
132k
    } else {
2433
132k
      arithDecoder->decodeInt(&rdw, iardwStats);
2434
132k
      arithDecoder->decodeInt(&rdh, iardhStats);
2435
132k
      arithDecoder->decodeInt(&rdx, iardxStats);
2436
132k
      arithDecoder->decodeInt(&rdy, iardyStats);
2437
132k
    }
2438
134k
    refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
2439
134k
    refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
2440
2441
134k
    if (rdw > INT_MAX - syms[symID]->getWidth() ||
2442
134k
        rdh > INT_MAX - syms[symID]->getHeight()) {
2443
375
      error(errSyntaxError, getPos(),
2444
375
      "Invalid refinement size in JBIG2 text region");
2445
375
      continue;
2446
375
    }
2447
    // sanity check
2448
134k
    if (rdw > 1000 || rdh > 1000) {
2449
1.20k
      error(errSyntaxError, getPos(),
2450
1.20k
      "Invalid refinement size in JBIG2 text region");
2451
1.20k
      continue;
2452
1.20k
    }
2453
133k
    symbolBitmap =
2454
133k
      readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
2455
133k
          rdh + syms[symID]->getHeight(),
2456
133k
          templ, gFalse, syms[symID],
2457
133k
          refDX, refDY, atx, aty);
2458
    //~ do we need to use the bmSize value here (in Huffman mode)?
2459
133k
  } else {
2460
40.2k
    symbolBitmap = syms[symID];
2461
40.2k
  }
2462
2463
  // combine the symbol bitmap into the region bitmap
2464
  //~ something is wrong here - refCorner shouldn't degenerate into
2465
  //~   two cases
2466
173k
  bw = symbolBitmap->getWidth() - 1;
2467
173k
  bh = symbolBitmap->getHeight() - 1;
2468
173k
  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
173k
  } else {
2485
173k
    switch (refCorner) {
2486
0
    case 0: // bottom left
2487
0
      bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2488
0
      break;
2489
173k
    case 1: // top left
2490
173k
      bitmap->combine(symbolBitmap, s, tt, combOp);
2491
173k
      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
173k
    }
2499
173k
    s += bw;
2500
173k
  }
2501
173k
  if (ri) {
2502
133k
    delete symbolBitmap;
2503
133k
  }
2504
173k
      }
2505
2506
      // next instance
2507
2.66M
      ++inst;
2508
2509
      // next S value
2510
2.66M
      if (huff) {
2511
1.76M
  if (!huffDecoder->decodeInt(&ds, huffDSTable)) {
2512
24.0k
    break;
2513
24.0k
  }
2514
1.76M
      } else {
2515
907k
  if (!arithDecoder->decodeInt(&ds, iadsStats)) {
2516
21.1k
    break;
2517
21.1k
  }
2518
907k
      }
2519
2.62M
      s += sOffset + ds;
2520
2.62M
    }
2521
54.0k
  }
2522
2523
15.1k
  return bitmap;
2524
15.2k
}
2525
2526
4.21k
void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
2527
4.21k
  JBIG2PatternDict *patternDict;
2528
4.21k
  JBIG2Bitmap *bitmap;
2529
4.21k
  Guint flags, patternW, patternH, grayMax, templ, mmr;
2530
4.21k
  int atx[4], aty[4];
2531
4.21k
  Guint i, x;
2532
2533
  // halftone dictionary flags, pattern width and height, max gray value
2534
4.21k
  if (!readUByte(&flags) ||
2535
4.00k
      !readUByte(&patternW) ||
2536
3.81k
      !readUByte(&patternH) ||
2537
3.60k
      !readULong(&grayMax)) {
2538
1.40k
    goto eofError;
2539
1.40k
  }
2540
2.80k
  if (patternW == 0 || patternH == 0 ||
2541
2.38k
      grayMax > UINT_MAX / patternW - 1) {
2542
1.09k
    error(errSyntaxError, getPos(),
2543
1.09k
    "Bad size in JBIG2 pattern dictionary segment");
2544
1.09k
    return;
2545
1.09k
  }
2546
1.71k
  templ = (flags >> 1) & 3;
2547
1.71k
  mmr = flags & 1;
2548
2549
  // set up the arithmetic decoder
2550
1.71k
  if (!mmr) {
2551
739
    resetGenericStats(templ, NULL);
2552
739
    arithDecoder->start();
2553
739
  }
2554
2555
  // read the bitmap
2556
1.71k
  atx[0] = -(int)patternW; aty[0] =  0;
2557
1.71k
  atx[1] = -3;             aty[1] = -1;
2558
1.71k
  atx[2] =  2;             aty[2] = -2;
2559
1.71k
  atx[3] = -2;             aty[3] = -2;
2560
1.71k
  bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
2561
1.71k
           templ, gFalse, gFalse, NULL,
2562
1.71k
           atx, aty, length - 7);
2563
2564
  // create the pattern dict object
2565
1.71k
  patternDict = new JBIG2PatternDict(segNum, grayMax + 1);
2566
2567
  // split up the bitmap
2568
1.71k
  x = 0;
2569
6.40k
  for (i = 0; i <= grayMax; ++i) {
2570
4.68k
    patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
2571
4.68k
    x += patternW;
2572
4.68k
  }
2573
2574
  // free memory
2575
1.71k
  delete bitmap;
2576
2577
  // store the new pattern dict
2578
1.71k
  segments->append(patternDict);
2579
2580
1.71k
  return;
2581
2582
1.40k
 eofError:
2583
1.40k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
2584
1.40k
}
2585
2586
void JBIG2Stream::readHalftoneRegionSeg(Guint segNum, GBool imm,
2587
          GBool lossless, Guint length,
2588
9.68k
          Guint *refSegs, Guint nRefSegs) {
2589
9.68k
  JBIG2Bitmap *bitmap;
2590
9.68k
  JBIG2Segment *seg;
2591
9.68k
  JBIG2PatternDict *patternDict;
2592
9.68k
  JBIG2Bitmap *skipBitmap;
2593
9.68k
  Guint *grayImg;
2594
9.68k
  JBIG2Bitmap *grayBitmap;
2595
9.68k
  JBIG2Bitmap *patternBitmap;
2596
9.68k
  Guint w, h, x, y, segInfoFlags, extCombOp;
2597
9.68k
  Guint flags, mmr, templ, enableSkip, combOp;
2598
9.68k
  Guint gridW, gridH, stepX, stepY, patW, patH;
2599
9.68k
  int atx[4], aty[4];
2600
9.68k
  int gridX, gridY, xx, yy, bit, j;
2601
9.68k
  Guint bpp, m, n, i;
2602
2603
  // region segment info field
2604
9.68k
  if (!readULong(&w) || !readULong(&h) ||
2605
7.40k
      !readULong(&x) || !readULong(&y) ||
2606
5.91k
      !readUByte(&segInfoFlags)) {
2607
4.02k
    goto eofError;
2608
4.02k
  }
2609
  // sanity check: if the w/h/x/y values are way out of range, it likely
2610
  // indicates a damaged JBIG2 stream
2611
5.66k
  if (w / 10 > pageW || h / 10 > pageH ||
2612
4.53k
      x / 10 > pageW || y / 10 > pageH) {
2613
1.58k
    error(errSyntaxError, getPos(),
2614
1.58k
    "Bad size or position in JBIG2 halftone region segment");
2615
1.58k
    done = gTrue;
2616
1.58k
    return;
2617
1.58k
  }
2618
4.08k
  extCombOp = segInfoFlags & 7;
2619
2620
  // rest of the halftone region header
2621
4.08k
  if (!readUByte(&flags)) {
2622
69
    goto eofError;
2623
69
  }
2624
4.01k
  mmr = flags & 1;
2625
4.01k
  templ = (flags >> 1) & 3;
2626
4.01k
  enableSkip = (flags >> 3) & 1;
2627
4.01k
  combOp = (flags >> 4) & 7;
2628
4.01k
  if (!readULong(&gridW) || !readULong(&gridH) ||
2629
3.27k
      !readLong(&gridX) || !readLong(&gridY) ||
2630
2.35k
      !readUWord(&stepX) || !readUWord(&stepY)) {
2631
2.35k
    goto eofError;
2632
2.35k
  }
2633
1.65k
  if (w == 0 || h == 0 || w >= INT_MAX / h) {
2634
586
    error(errSyntaxError, getPos(),
2635
586
    "Bad bitmap size in JBIG2 halftone segment");
2636
586
    return;
2637
586
  }
2638
1.06k
  if (gridW == 0 || gridH == 0 || gridW >= INT_MAX / gridH) {
2639
768
    error(errSyntaxError, getPos(), "Bad grid size in JBIG2 halftone segment");
2640
768
    return;
2641
768
  }
2642
2643
  // get pattern dictionary
2644
301
  if (nRefSegs != 1) {
2645
214
    error(errSyntaxError, getPos(),
2646
214
    "Bad symbol dictionary reference in JBIG2 halftone segment");
2647
214
    return;
2648
214
  }
2649
87
  if (!(seg = findSegment(refSegs[0])) ||
2650
87
      seg->getType() != jbig2SegPatternDict) {
2651
87
    error(errSyntaxError, getPos(),
2652
87
    "Bad symbol dictionary reference in JBIG2 halftone segment");
2653
87
    return;
2654
87
  }
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
6.44k
 eofError:
2771
6.44k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
2772
6.44k
}
2773
2774
void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
2775
10.0k
               GBool lossless, Guint length) {
2776
10.0k
  JBIG2Bitmap *bitmap;
2777
10.0k
  Guint w, h, x, y, segInfoFlags, extCombOp, rowCount;
2778
10.0k
  Guint flags, mmr, templ, tpgdOn;
2779
10.0k
  int atx[4], aty[4];
2780
2781
  // region segment info field
2782
10.0k
  if (!readULong(&w) || !readULong(&h) ||
2783
8.22k
      !readULong(&x) || !readULong(&y) ||
2784
6.90k
      !readUByte(&segInfoFlags)) {
2785
3.26k
    goto eofError;
2786
3.26k
  }
2787
6.81k
  if (w == 0 || h == 0) {
2788
306
    error(errSyntaxError, getPos(),
2789
306
    "Bad bitmap size in JBIG2 generic region segment");
2790
306
    return;
2791
306
  }
2792
  // sanity check: if the w/h/x/y values are way out of range, it likely
2793
  // indicates a damaged JBIG2 stream
2794
6.50k
  if (w / 10 > pageW || h / 10 > pageH ||
2795
5.93k
      x / 10 > pageW || y / 10 > pageH) {
2796
796
    error(errSyntaxError, getPos(),
2797
796
    "Bad size or position in JBIG2 generic region segment");
2798
796
    done = gTrue;
2799
796
    return;
2800
796
  }
2801
5.70k
  extCombOp = segInfoFlags & 7;
2802
2803
  // rest of the generic region segment header
2804
5.70k
  if (!readUByte(&flags)) {
2805
245
    goto eofError;
2806
245
  }
2807
5.46k
  mmr = flags & 1;
2808
5.46k
  templ = (flags >> 1) & 3;
2809
5.46k
  tpgdOn = (flags >> 3) & 1;
2810
2811
  // AT flags
2812
5.46k
  if (!mmr) {
2813
4.92k
    if (templ == 0) {
2814
2.95k
      if (!readByte(&atx[0]) ||
2815
2.67k
    !readByte(&aty[0]) ||
2816
2.41k
    !readByte(&atx[1]) ||
2817
2.12k
    !readByte(&aty[1]) ||
2818
1.88k
    !readByte(&atx[2]) ||
2819
1.67k
    !readByte(&aty[2]) ||
2820
1.46k
    !readByte(&atx[3]) ||
2821
2.05k
    !readByte(&aty[3])) {
2822
2.05k
  goto eofError;
2823
2.05k
      }
2824
2.95k
    } else {
2825
1.97k
      if (!readByte(&atx[0]) ||
2826
1.74k
    !readByte(&aty[0])) {
2827
453
  goto eofError;
2828
453
      }
2829
1.97k
    }
2830
4.92k
  }
2831
2832
  // set up the arithmetic decoder
2833
2.95k
  if (!mmr) {
2834
2.41k
    resetGenericStats(templ, NULL);
2835
2.41k
    arithDecoder->start();
2836
2.41k
  }
2837
2838
  // read the bitmap
2839
2.95k
  bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
2840
2.95k
           NULL, atx, aty, mmr ? length - 18 : 0);
2841
2842
  // combine the region bitmap into the page bitmap
2843
2.95k
  if (imm) {
2844
2.03k
    if (pageH == 0xffffffff && y + h > curPageH) {
2845
817
      pageBitmap->expand(y + h, pageDefPixel);
2846
817
    }
2847
2.03k
    pageBitmap->combine(bitmap, x, y, extCombOp);
2848
2.03k
    delete bitmap;
2849
2850
  // store the region bitmap
2851
2.03k
  } else {
2852
920
    bitmap->setSegNum(segNum);
2853
920
    segments->append(bitmap);
2854
920
  }
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
2.95k
  if (imm && length == 0xffffffff) {
2859
487
    readULong(&rowCount);
2860
487
  }
2861
2862
2.95k
  return;
2863
2864
6.01k
 eofError:
2865
6.01k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
2866
6.01k
}
2867
2868
inline void JBIG2Stream::mmrAddPixels(int a1, int blackPixels,
2869
1.18M
              int *codingLine, int *a0i, int w) {
2870
1.18M
  if (a1 > codingLine[*a0i]) {
2871
1.18M
    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
1.18M
    if ((*a0i & 1) ^ blackPixels) {
2877
694k
      ++*a0i;
2878
694k
    }
2879
1.18M
    codingLine[*a0i] = a1;
2880
1.18M
  }
2881
1.18M
}
2882
2883
inline void JBIG2Stream::mmrAddPixelsNeg(int a1, int blackPixels,
2884
81.6k
           int *codingLine, int *a0i, int w) {
2885
81.6k
  if (a1 > codingLine[*a0i]) {
2886
60.3k
    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
60.3k
    if ((*a0i & 1) ^ blackPixels) {
2892
43.3k
      ++*a0i;
2893
43.3k
    }
2894
60.3k
    codingLine[*a0i] = a1;
2895
60.3k
  } else if (a1 < codingLine[*a0i]) {
2896
14.4k
    if (a1 < 0) {
2897
3.35k
      error(errSyntaxError, getPos(), "Invalid JBIG2 MMR code");
2898
3.35k
      a1 = 0;
2899
3.35k
    }
2900
20.6k
    while (*a0i > 0 && a1 <= codingLine[*a0i - 1]) {
2901
6.26k
      --*a0i;
2902
6.26k
    }
2903
14.4k
    codingLine[*a0i] = a1;
2904
14.4k
  }
2905
81.6k
}
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
23.6k
              int mmrDataLength) {
2912
23.6k
  JBIG2Bitmap *bitmap;
2913
23.6k
  GBool ltp;
2914
23.6k
  Guint ltpCX, cx, cx0, cx1, cx2;
2915
23.6k
  int *refLine, *codingLine;
2916
23.6k
  int code1, code2, code3;
2917
23.6k
  Guchar *p0, *p1, *p2, *pp;
2918
23.6k
  Guchar *atP0, *atP1, *atP2, *atP3;
2919
23.6k
  Guint buf0, buf1, buf2;
2920
23.6k
  Guint atBuf0, atBuf1, atBuf2, atBuf3;
2921
23.6k
  int atShift0, atShift1, atShift2, atShift3;
2922
23.6k
  Guchar mask;
2923
23.6k
  int x, y, x0, x1, a0i, b1i, blackPixels, pix, i;
2924
2925
23.6k
  bitmap = new JBIG2Bitmap(0, w, h);
2926
23.6k
  bitmap->clearToZero();
2927
2928
  //----- MMR decode
2929
2930
23.6k
  if (mmr) {
2931
2932
4.93k
    mmrDecoder->reset();
2933
4.93k
    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
4.93k
    codingLine = (int *)gmallocn(w + 1, sizeof(int));
2943
4.93k
    refLine = (int *)gmallocn(w + 3, sizeof(int));
2944
4.93k
    codingLine[0] = w;
2945
2946
490k
    for (y = 0; y < h; ++y) {
2947
2948
      // copy coding line to ref line
2949
1.21M
      for (i = 0; codingLine[i] < w; ++i) {
2950
727k
  refLine[i] = codingLine[i];
2951
727k
      }
2952
485k
      refLine[i++] = w;
2953
485k
      refLine[i++] = w;
2954
485k
      refLine[i] = w;
2955
2956
      // decode a line
2957
485k
      codingLine[0] = 0;
2958
485k
      a0i = 0;
2959
485k
      b1i = 0;
2960
485k
      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.70M
      while (codingLine[a0i] < w) {
2968
1.21M
  code1 = mmrDecoder->get2DCode();
2969
1.21M
  switch (code1) {
2970
34.1k
  case twoDimPass:
2971
34.1k
          mmrAddPixels(refLine[b1i + 1], blackPixels, codingLine, &a0i, w);
2972
34.1k
          if (refLine[b1i + 1] < w) {
2973
17.4k
            b1i += 2;
2974
17.4k
          }
2975
34.1k
          break;
2976
64.6k
  case twoDimHoriz:
2977
64.6k
          code1 = code2 = 0;
2978
64.6k
          if (blackPixels) {
2979
26.5k
            do {
2980
26.5k
              code1 += code3 = mmrDecoder->getBlackCode();
2981
26.5k
            } while (code3 >= 64);
2982
30.6k
            do {
2983
30.6k
              code2 += code3 = mmrDecoder->getWhiteCode();
2984
30.6k
            } while (code3 >= 64);
2985
38.8k
          } else {
2986
41.3k
            do {
2987
41.3k
              code1 += code3 = mmrDecoder->getWhiteCode();
2988
41.3k
            } while (code3 >= 64);
2989
39.3k
            do {
2990
39.3k
              code2 += code3 = mmrDecoder->getBlackCode();
2991
39.3k
            } while (code3 >= 64);
2992
38.8k
          }
2993
64.6k
          mmrAddPixels(codingLine[a0i] + code1, blackPixels,
2994
64.6k
           codingLine, &a0i, w);
2995
64.6k
          if (codingLine[a0i] < w) {
2996
54.9k
            mmrAddPixels(codingLine[a0i] + code2, blackPixels ^ 1,
2997
54.9k
       codingLine, &a0i, w);
2998
54.9k
          }
2999
96.3k
          while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3000
31.7k
            b1i += 2;
3001
31.7k
          }
3002
64.6k
          break;
3003
9.57k
  case twoDimVertR3:
3004
9.57k
          mmrAddPixels(refLine[b1i] + 3, blackPixels, codingLine, &a0i, w);
3005
9.57k
          blackPixels ^= 1;
3006
9.57k
          if (codingLine[a0i] < w) {
3007
5.65k
            ++b1i;
3008
5.77k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3009
115
              b1i += 2;
3010
115
            }
3011
5.65k
          }
3012
9.57k
          break;
3013
4.98k
  case twoDimVertR2:
3014
4.98k
          mmrAddPixels(refLine[b1i] + 2, blackPixels, codingLine, &a0i, w);
3015
4.98k
          blackPixels ^= 1;
3016
4.98k
          if (codingLine[a0i] < w) {
3017
3.41k
            ++b1i;
3018
3.68k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3019
268
              b1i += 2;
3020
268
            }
3021
3.41k
          }
3022
4.98k
          break;
3023
34.2k
  case twoDimVertR1:
3024
34.2k
          mmrAddPixels(refLine[b1i] + 1, blackPixels, codingLine, &a0i, w);
3025
34.2k
          blackPixels ^= 1;
3026
34.2k
          if (codingLine[a0i] < w) {
3027
19.5k
            ++b1i;
3028
20.6k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3029
1.11k
              b1i += 2;
3030
1.11k
            }
3031
19.5k
          }
3032
34.2k
          break;
3033
757k
  case twoDimVert0:
3034
757k
          mmrAddPixels(refLine[b1i], blackPixels, codingLine, &a0i, w);
3035
757k
          blackPixels ^= 1;
3036
757k
          if (codingLine[a0i] < w) {
3037
551k
            ++b1i;
3038
551k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3039
0
              b1i += 2;
3040
0
            }
3041
551k
          }
3042
757k
          break;
3043
15.0k
  case twoDimVertL3:
3044
15.0k
          mmrAddPixelsNeg(refLine[b1i] - 3, blackPixels, codingLine, &a0i, w);
3045
15.0k
          blackPixels ^= 1;
3046
15.0k
          if (codingLine[a0i] < w) {
3047
15.0k
            if (b1i > 0) {
3048
10.8k
              --b1i;
3049
10.8k
            } else {
3050
4.16k
              ++b1i;
3051
4.16k
            }
3052
20.8k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3053
5.84k
              b1i += 2;
3054
5.84k
            }
3055
15.0k
          }
3056
15.0k
          break;
3057
35.2k
  case twoDimVertL2:
3058
35.2k
          mmrAddPixelsNeg(refLine[b1i] - 2, blackPixels, codingLine, &a0i, w);
3059
35.2k
          blackPixels ^= 1;
3060
35.2k
          if (codingLine[a0i] < w) {
3061
35.2k
            if (b1i > 0) {
3062
30.5k
              --b1i;
3063
30.5k
            } else {
3064
4.74k
              ++b1i;
3065
4.74k
            }
3066
58.5k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3067
23.2k
              b1i += 2;
3068
23.2k
            }
3069
35.2k
          }
3070
35.2k
          break;
3071
31.3k
  case twoDimVertL1:
3072
31.3k
          mmrAddPixelsNeg(refLine[b1i] - 1, blackPixels, codingLine, &a0i, w);
3073
31.3k
          blackPixels ^= 1;
3074
31.3k
          if (codingLine[a0i] < w) {
3075
31.3k
            if (b1i > 0) {
3076
20.4k
              --b1i;
3077
20.4k
            } else {
3078
10.9k
              ++b1i;
3079
10.9k
            }
3080
50.4k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3081
19.1k
              b1i += 2;
3082
19.1k
            }
3083
31.3k
          }
3084
31.3k
          break;
3085
229k
  case EOF:
3086
229k
          mmrAddPixels(w, 0, codingLine, &a0i, w);
3087
229k
          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
1.21M
  }
3094
1.21M
      }
3095
3096
      // convert the run lengths to a bitmap line
3097
485k
      i = 0;
3098
764k
      while (1) {
3099
764k
  if (codingLine[i] >= w) {
3100
311k
    break;
3101
311k
  }
3102
112M
  for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
3103
111M
    bitmap->setPixel(x, y);
3104
111M
  }
3105
452k
  if (codingLine[i+1] >= w) {
3106
173k
    break;
3107
173k
  }
3108
279k
  i += 2;
3109
279k
      }
3110
485k
    }
3111
3112
4.93k
    if (mmrDataLength >= 0) {
3113
3.67k
      mmrDecoder->skipTo(mmrDataLength);
3114
3.67k
    } else {
3115
1.25k
      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.25k
    }
3120
3121
4.93k
    gfree(refLine);
3122
4.93k
    gfree(codingLine);
3123
3124
  //----- arithmetic decode
3125
3126
18.7k
  } else {
3127
    // set up the typical row context
3128
18.7k
    ltpCX = 0; // make gcc happy
3129
18.7k
    if (tpgdOn) {
3130
1.60k
      switch (templ) {
3131
228
      case 0:
3132
228
  ltpCX = 0x3953; // 001 11001 0101 0011
3133
228
  break;
3134
149
      case 1:
3135
149
  ltpCX = 0x079a; // 0011 11001 101 0
3136
149
  break;
3137
51
      case 2:
3138
51
  ltpCX = 0x0e3; // 001 1100 01 1
3139
51
  break;
3140
1.17k
      case 3:
3141
1.17k
  ltpCX = 0x18b; // 01100 0101 1
3142
1.17k
  break;
3143
1.60k
      }
3144
1.60k
    }
3145
3146
18.7k
    ltp = 0;
3147
18.7k
    cx = cx0 = cx1 = cx2 = 0; // make gcc happy
3148
3.19M
    for (y = 0; y < h; ++y) {
3149
3150
      // check for a "typical" (duplicate) row
3151
3.17M
      if (tpgdOn) {
3152
1.49M
  if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
3153
957k
    ltp = !ltp;
3154
957k
  }
3155
1.49M
  if (ltp) {
3156
525k
    if (y > 0) {
3157
524k
      bitmap->duplicateRow(y, y-1);
3158
524k
    }
3159
525k
    continue;
3160
525k
  }
3161
1.49M
      }
3162
3163
2.64M
      switch (templ) {
3164
1.27M
      case 0:
3165
3166
  // set up the context
3167
1.27M
  p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
3168
1.27M
  buf2 = *p2++ << 8;
3169
1.27M
  if (y >= 1) {
3170
1.25M
    p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
3171
1.25M
    buf1 = *p1++ << 8;
3172
1.25M
    if (y >= 2) {
3173
1.25M
      p0 = bitmap->getDataPtr() + (y - 2) * bitmap->getLineSize();
3174
1.25M
      buf0 = *p0++ << 8;
3175
1.25M
    } else {
3176
4.31k
      p0 = NULL;
3177
4.31k
      buf0 = 0;
3178
4.31k
    }
3179
1.25M
  } else {
3180
15.5k
    p1 = p0 = NULL;
3181
15.5k
    buf1 = buf0 = 0;
3182
15.5k
  }
3183
3184
1.27M
  if (atx[0] >= -8 && atx[0] <= 8 &&
3185
972k
      atx[1] >= -8 && atx[1] <= 8 &&
3186
30.2k
      atx[2] >= -8 && atx[2] <= 8 &&
3187
18.9k
      atx[3] >= -8 && atx[3] <= 8) {
3188
    // set up the adaptive context
3189
5.15k
    if (aty[0] <= 0 && y + aty[0] >= 0) {
3190
4.01k
      atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
3191
4.01k
      atBuf0 = *atP0++ << 8;
3192
4.01k
    } else {
3193
1.13k
      atP0 = NULL;
3194
1.13k
      atBuf0 = 0;
3195
1.13k
    }
3196
5.15k
    atShift0 = 15 - atx[0];
3197
5.15k
    if (aty[1] <= 0 && y + aty[1] >= 0) {
3198
4.23k
      atP1 = bitmap->getDataPtr() + (y + aty[1]) * bitmap->getLineSize();
3199
4.23k
      atBuf1 = *atP1++ << 8;
3200
4.23k
    } else {
3201
926
      atP1 = NULL;
3202
926
      atBuf1 = 0;
3203
926
    }
3204
5.15k
    atShift1 = 15 - atx[1];
3205
5.15k
    if (aty[2] <= 0 && y + aty[2] >= 0) {
3206
3.43k
      atP2 = bitmap->getDataPtr() + (y + aty[2]) * bitmap->getLineSize();
3207
3.43k
      atBuf2 = *atP2++ << 8;
3208
3.43k
    } else {
3209
1.72k
      atP2 = NULL;
3210
1.72k
      atBuf2 = 0;
3211
1.72k
    }
3212
5.15k
    atShift2 = 15 - atx[2];
3213
5.15k
    if (aty[3] <= 0 && y + aty[3] >= 0) {
3214
3.14k
      atP3 = bitmap->getDataPtr() + (y + aty[3]) * bitmap->getLineSize();
3215
3.14k
      atBuf3 = *atP3++ << 8;
3216
3.14k
    } else {
3217
2.00k
      atP3 = NULL;
3218
2.00k
      atBuf3 = 0;
3219
2.00k
    }
3220
5.15k
    atShift3 = 15 - atx[3];
3221
3222
    // decode the row
3223
43.3k
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3224
38.1k
      if (x0 + 8 < w) {
3225
33.0k
        if (p0) {
3226
31.6k
    buf0 |= *p0++;
3227
31.6k
        }
3228
33.0k
        if (p1) {
3229
32.2k
    buf1 |= *p1++;
3230
32.2k
        }
3231
33.0k
        buf2 |= *p2++;
3232
33.0k
        if (atP0) {
3233
31.7k
    atBuf0 |= *atP0++;
3234
31.7k
        }
3235
33.0k
        if (atP1) {
3236
31.5k
    atBuf1 |= *atP1++;
3237
31.5k
        }
3238
33.0k
        if (atP2) {
3239
31.3k
    atBuf2 |= *atP2++;
3240
31.3k
        }
3241
33.0k
        if (atP3) {
3242
2.51k
    atBuf3 |= *atP3++;
3243
2.51k
        }
3244
33.0k
      }
3245
38.1k
      for (x1 = 0, mask = 0x80;
3246
322k
     x1 < 8 && x < w;
3247
283k
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3248
3249
        // build the context
3250
283k
        cx0 = (buf0 >> 14) & 0x07;
3251
283k
        cx1 = (buf1 >> 13) & 0x1f;
3252
283k
        cx2 = (buf2 >> 16) & 0x0f;
3253
283k
        cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
3254
283k
       (((atBuf0 >> atShift0) & 1) << 3) |
3255
283k
       (((atBuf1 >> atShift1) & 1) << 2) |
3256
283k
       (((atBuf2 >> atShift2) & 1) << 1) |
3257
283k
       ((atBuf3 >> atShift3) & 1);
3258
3259
        // check for a skipped pixel
3260
283k
        if (!(useSkip && skip->getPixel(x, y))) {
3261
3262
    // decode the pixel
3263
283k
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3264
139k
      *pp |= mask;
3265
139k
      buf2 |= 0x8000;
3266
139k
      if (aty[0] == 0) {
3267
128k
        atBuf0 |= 0x8000;
3268
128k
      }
3269
139k
      if (aty[1] == 0) {
3270
130k
        atBuf1 |= 0x8000;
3271
130k
      }
3272
139k
      if (aty[2] == 0) {
3273
128k
        atBuf2 |= 0x8000;
3274
128k
      }
3275
139k
      if (aty[3] == 0) {
3276
13.6k
        atBuf3 |= 0x8000;
3277
13.6k
      }
3278
139k
    }
3279
283k
        }
3280
3281
        // update the context
3282
283k
        buf0 <<= 1;
3283
283k
        buf1 <<= 1;
3284
283k
        buf2 <<= 1;
3285
283k
        atBuf0 <<= 1;
3286
283k
        atBuf1 <<= 1;
3287
283k
        atBuf2 <<= 1;
3288
283k
        atBuf3 <<= 1;
3289
283k
      }
3290
38.1k
    }
3291
3292
1.26M
  } else {
3293
    // decode the row
3294
6.44M
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3295
5.17M
      if (x0 + 8 < w) {
3296
3.91M
        if (p0) {
3297
3.21M
    buf0 |= *p0++;
3298
3.21M
        }
3299
3.91M
        if (p1) {
3300
3.27M
    buf1 |= *p1++;
3301
3.27M
        }
3302
3.91M
        buf2 |= *p2++;
3303
3.91M
      }
3304
5.17M
      for (x1 = 0, mask = 0x80;
3305
42.9M
     x1 < 8 && x < w;
3306
37.7M
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3307
3308
        // build the context
3309
37.7M
        cx0 = (buf0 >> 14) & 0x07;
3310
37.7M
        cx1 = (buf1 >> 13) & 0x1f;
3311
37.7M
        cx2 = (buf2 >> 16) & 0x0f;
3312
37.7M
        cx = (cx0 << 13) | (cx1 << 8) | (cx2 << 4) |
3313
37.7M
       (bitmap->getPixel(x + atx[0], y + aty[0]) << 3) |
3314
37.7M
       (bitmap->getPixel(x + atx[1], y + aty[1]) << 2) |
3315
37.7M
       (bitmap->getPixel(x + atx[2], y + aty[2]) << 1) |
3316
37.7M
       bitmap->getPixel(x + atx[3], y + aty[3]);
3317
3318
        // check for a skipped pixel
3319
37.7M
        if (!(useSkip && skip->getPixel(x, y))) {
3320
3321
    // decode the pixel
3322
37.7M
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3323
14.1M
      *pp |= mask;
3324
14.1M
      buf2 |= 0x8000;
3325
14.1M
    }
3326
37.7M
        }
3327
3328
        // update the context
3329
37.7M
        buf0 <<= 1;
3330
37.7M
        buf1 <<= 1;
3331
37.7M
        buf2 <<= 1;
3332
37.7M
      }
3333
5.17M
    }
3334
1.26M
  }
3335
1.27M
  break;
3336
3337
446k
      case 1:
3338
3339
  // set up the context
3340
446k
  p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
3341
446k
  buf2 = *p2++ << 8;
3342
446k
  if (y >= 1) {
3343
446k
    p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
3344
446k
    buf1 = *p1++ << 8;
3345
446k
    if (y >= 2) {
3346
445k
      p0 = bitmap->getDataPtr() + (y - 2) * bitmap->getLineSize();
3347
445k
      buf0 = *p0++ << 8;
3348
445k
    } else {
3349
342
      p0 = NULL;
3350
342
      buf0 = 0;
3351
342
    }
3352
446k
  } else {
3353
579
    p1 = p0 = NULL;
3354
579
    buf1 = buf0 = 0;
3355
579
  }
3356
3357
446k
  if (atx[0] >= -8 && atx[0] <= 8) {
3358
    // set up the adaptive context
3359
308
    if (aty[0] <= 0 && y + aty[0] >= 0) {
3360
281
      atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
3361
281
      atBuf0 = *atP0++ << 8;
3362
281
    } else {
3363
27
      atP0 = NULL;
3364
27
      atBuf0 = 0;
3365
27
    }
3366
308
    atShift0 = 15 - atx[0];
3367
3368
    // decode the row
3369
816
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3370
508
      if (x0 + 8 < w) {
3371
200
        if (p0) {
3372
24
    buf0 |= *p0++;
3373
24
        }
3374
200
        if (p1) {
3375
112
    buf1 |= *p1++;
3376
112
        }
3377
200
        buf2 |= *p2++;
3378
200
        if (atP0) {
3379
48
    atBuf0 |= *atP0++;
3380
48
        }
3381
200
      }
3382
508
      for (x1 = 0, mask = 0x80;
3383
2.71k
     x1 < 8 && x < w;
3384
2.21k
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3385
3386
        // build the context
3387
2.21k
        cx0 = (buf0 >> 13) & 0x0f;
3388
2.21k
        cx1 = (buf1 >> 13) & 0x1f;
3389
2.21k
        cx2 = (buf2 >> 16) & 0x07;
3390
2.21k
        cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
3391
2.21k
       ((atBuf0 >> atShift0) & 1);
3392
3393
        // check for a skipped pixel
3394
2.21k
        if (!(useSkip && skip->getPixel(x, y))) {
3395
3396
    // decode the pixel
3397
2.21k
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3398
1.23k
      *pp |= mask;
3399
1.23k
      buf2 |= 0x8000;
3400
1.23k
      if (aty[0] == 0) {
3401
249
        atBuf0 |= 0x8000;
3402
249
      }
3403
1.23k
    }
3404
2.21k
        }
3405
3406
        // update the context
3407
2.21k
        buf0 <<= 1;
3408
2.21k
        buf1 <<= 1;
3409
2.21k
        buf2 <<= 1;
3410
2.21k
        atBuf0 <<= 1;
3411
2.21k
      }
3412
508
    }
3413
3414
446k
  } else {
3415
    // decode the row
3416
10.4M
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3417
9.98M
      if (x0 + 8 < w) {
3418
9.53M
        if (p0) {
3419
7.41M
    buf0 |= *p0++;
3420
7.41M
        }
3421
9.53M
        if (p1) {
3422
9.52M
    buf1 |= *p1++;
3423
9.52M
        }
3424
9.53M
        buf2 |= *p2++;
3425
9.53M
      }
3426
9.98M
      for (x1 = 0, mask = 0x80;
3427
89.1M
     x1 < 8 && x < w;
3428
79.2M
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3429
3430
        // build the context
3431
79.2M
        cx0 = (buf0 >> 13) & 0x0f;
3432
79.2M
        cx1 = (buf1 >> 13) & 0x1f;
3433
79.2M
        cx2 = (buf2 >> 16) & 0x07;
3434
79.2M
        cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
3435
79.2M
       bitmap->getPixel(x + atx[0], y + aty[0]);
3436
3437
        // check for a skipped pixel
3438
79.2M
        if (!(useSkip && skip->getPixel(x, y))) {
3439
3440
    // decode the pixel
3441
79.2M
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3442
39.1M
      *pp |= mask;
3443
39.1M
      buf2 |= 0x8000;
3444
39.1M
    }
3445
79.2M
        }
3446
3447
        // update the context
3448
79.2M
        buf0 <<= 1;
3449
79.2M
        buf1 <<= 1;
3450
79.2M
        buf2 <<= 1;
3451
79.2M
      }
3452
9.98M
    }
3453
446k
  }
3454
446k
  break;
3455
3456
426k
      case 2:
3457
3458
  // set up the context
3459
426k
  p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
3460
426k
  buf2 = *p2++ << 8;
3461
426k
  if (y >= 1) {
3462
426k
    p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
3463
426k
    buf1 = *p1++ << 8;
3464
426k
    if (y >= 2) {
3465
426k
      p0 = bitmap->getDataPtr() + (y - 2) * bitmap->getLineSize();
3466
426k
      buf0 = *p0++ << 8;
3467
426k
    } else {
3468
217
      p0 = NULL;
3469
217
      buf0 = 0;
3470
217
    }
3471
426k
  } else {
3472
468
    p1 = p0 = NULL;
3473
468
    buf1 = buf0 = 0;
3474
468
  }
3475
3476
426k
  if (atx[0] >= -8 && atx[0] <= 8) {
3477
    // set up the adaptive context
3478
31.6k
    if (aty[0] <= 0 && y + aty[0] >= 0) {
3479
30.5k
      atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
3480
30.5k
      atBuf0 = *atP0++ << 8;
3481
30.5k
    } else {
3482
1.14k
      atP0 = NULL;
3483
1.14k
      atBuf0 = 0;
3484
1.14k
    }
3485
31.6k
    atShift0 = 15 - atx[0];
3486
3487
    // decode the row
3488
3.20M
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3489
3.17M
      if (x0 + 8 < w) {
3490
3.13M
        if (p0) {
3491
2.08M
    buf0 |= *p0++;
3492
2.08M
        }
3493
3.13M
        if (p1) {
3494
3.13M
    buf1 |= *p1++;
3495
3.13M
        }
3496
3.13M
        buf2 |= *p2++;
3497
3.13M
        if (atP0) {
3498
1.05M
    atBuf0 |= *atP0++;
3499
1.05M
        }
3500
3.13M
      }
3501
3.17M
      for (x1 = 0, mask = 0x80;
3502
28.3M
     x1 < 8 && x < w;
3503
25.1M
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3504
3505
        // build the context
3506
25.1M
        cx0 = (buf0 >> 14) & 0x07;
3507
25.1M
        cx1 = (buf1 >> 14) & 0x0f;
3508
25.1M
        cx2 = (buf2 >> 16) & 0x03;
3509
25.1M
        cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
3510
25.1M
       ((atBuf0 >> atShift0) & 1);
3511
3512
        // check for a skipped pixel
3513
25.1M
        if (!(useSkip && skip->getPixel(x, y))) {
3514
3515
    // decode the pixel
3516
25.1M
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3517
11.6M
      *pp |= mask;
3518
11.6M
      buf2 |= 0x8000;
3519
11.6M
      if (aty[0] == 0) {
3520
9.80k
        atBuf0 |= 0x8000;
3521
9.80k
      }
3522
11.6M
    }
3523
25.1M
        }
3524
3525
        // update the context
3526
25.1M
        buf0 <<= 1;
3527
25.1M
        buf1 <<= 1;
3528
25.1M
        buf2 <<= 1;
3529
25.1M
        atBuf0 <<= 1;
3530
25.1M
      }
3531
3.17M
    }
3532
3533
395k
  } else {
3534
    // decode the row
3535
9.72M
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3536
9.33M
      if (x0 + 8 < w) {
3537
8.93M
        if (p0) {
3538
6.76M
    buf0 |= *p0++;
3539
6.76M
        }
3540
8.93M
        if (p1) {
3541
6.80M
    buf1 |= *p1++;
3542
6.80M
        }
3543
8.93M
        buf2 |= *p2++;
3544
8.93M
      }
3545
9.33M
      for (x1 = 0, mask = 0x80;
3546
82.7M
     x1 < 8 && x < w;
3547
73.4M
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3548
3549
        // build the context
3550
73.4M
        cx0 = (buf0 >> 14) & 0x07;
3551
73.4M
        cx1 = (buf1 >> 14) & 0x0f;
3552
73.4M
        cx2 = (buf2 >> 16) & 0x03;
3553
73.4M
        cx = (cx0 << 7) | (cx1 << 3) | (cx2 << 1) |
3554
73.4M
       bitmap->getPixel(x + atx[0], y + aty[0]);
3555
3556
        // check for a skipped pixel
3557
73.4M
        if (!(useSkip && skip->getPixel(x, y))) {
3558
3559
    // decode the pixel
3560
73.4M
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3561
40.9M
      *pp |= mask;
3562
40.9M
      buf2 |= 0x8000;
3563
40.9M
    }
3564
73.4M
        }
3565
3566
        // update the context
3567
73.4M
        buf0 <<= 1;
3568
73.4M
        buf1 <<= 1;
3569
73.4M
        buf2 <<= 1;
3570
73.4M
      }
3571
9.33M
    }
3572
395k
  }
3573
426k
  break;
3574
3575
502k
      case 3:
3576
3577
  // set up the context
3578
502k
  p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
3579
502k
  buf2 = *p2++ << 8;
3580
502k
  if (y >= 1) {
3581
500k
    p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
3582
500k
    buf1 = *p1++ << 8;
3583
500k
  } else {
3584
1.57k
    p1 = NULL;
3585
1.57k
    buf1 = 0;
3586
1.57k
  }
3587
3588
502k
  if (atx[0] >= -8 && atx[0] <= 8) {
3589
    // set up the adaptive context
3590
23.5k
    if (aty[0] <= 0 && y + aty[0] >= 0) {
3591
21.8k
      atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
3592
21.8k
      atBuf0 = *atP0++ << 8;
3593
21.8k
    } else {
3594
1.70k
      atP0 = NULL;
3595
1.70k
      atBuf0 = 0;
3596
1.70k
    }
3597
23.5k
    atShift0 = 15 - atx[0];
3598
3599
    // decode the row
3600
324k
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3601
301k
      if (x0 + 8 < w) {
3602
277k
        if (p1) {
3603
234k
    buf1 |= *p1++;
3604
234k
        }
3605
277k
        buf2 |= *p2++;
3606
277k
        if (atP0) {
3607
151k
    atBuf0 |= *atP0++;
3608
151k
        }
3609
277k
      }
3610
301k
      for (x1 = 0, mask = 0x80;
3611
2.61M
     x1 < 8 && x < w;
3612
2.31M
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3613
3614
        // build the context
3615
2.31M
        cx1 = (buf1 >> 14) & 0x1f;
3616
2.31M
        cx2 = (buf2 >> 16) & 0x0f;
3617
2.31M
        cx = (cx1 << 5) | (cx2 << 1) |
3618
2.31M
       ((atBuf0 >> atShift0) & 1);
3619
3620
        // check for a skipped pixel
3621
2.31M
        if (!(useSkip && skip->getPixel(x, y))) {
3622
3623
    // decode the pixel
3624
2.31M
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3625
1.24M
      *pp |= mask;
3626
1.24M
      buf2 |= 0x8000;
3627
1.24M
      if (aty[0] == 0) {
3628
659k
        atBuf0 |= 0x8000;
3629
659k
      }
3630
1.24M
    }
3631
2.31M
        }
3632
3633
        // update the context
3634
2.31M
        buf1 <<= 1;
3635
2.31M
        buf2 <<= 1;
3636
2.31M
        atBuf0 <<= 1;
3637
2.31M
      }
3638
301k
    }
3639
3640
478k
  } else {
3641
    // decode the row
3642
15.9M
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3643
15.4M
      if (x0 + 8 < w) {
3644
15.0M
        if (p1) {
3645
14.9M
    buf1 |= *p1++;
3646
14.9M
        }
3647
15.0M
        buf2 |= *p2++;
3648
15.0M
      }
3649
15.4M
      for (x1 = 0, mask = 0x80;
3650
136M
     x1 < 8 && x < w;
3651
120M
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3652
3653
        // build the context
3654
120M
        cx1 = (buf1 >> 14) & 0x1f;
3655
120M
        cx2 = (buf2 >> 16) & 0x0f;
3656
120M
        cx = (cx1 << 5) | (cx2 << 1) |
3657
120M
       bitmap->getPixel(x + atx[0], y + aty[0]);
3658
3659
        // check for a skipped pixel
3660
120M
        if (!(useSkip && skip->getPixel(x, y))) {
3661
3662
    // decode the pixel
3663
120M
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3664
59.0M
      *pp |= mask;
3665
59.0M
      buf2 |= 0x8000;
3666
59.0M
    }
3667
120M
        }
3668
3669
        // update the context
3670
120M
        buf1 <<= 1;
3671
120M
        buf2 <<= 1;
3672
120M
      }
3673
15.4M
    }
3674
478k
  }
3675
502k
  break;
3676
2.64M
      }
3677
2.64M
    }
3678
18.7k
  }
3679
3680
23.6k
  return bitmap;
3681
23.6k
}
3682
3683
void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
3684
             GBool lossless, Guint length,
3685
             Guint *refSegs,
3686
9.71k
             Guint nRefSegs) {
3687
9.71k
  JBIG2Bitmap *bitmap, *refBitmap;
3688
9.71k
  Guint w, h, x, y, segInfoFlags, extCombOp;
3689
9.71k
  Guint flags, templ, tpgrOn;
3690
9.71k
  int atx[2], aty[2];
3691
9.71k
  JBIG2Segment *seg;
3692
3693
  // region segment info field
3694
9.71k
  if (!readULong(&w) || !readULong(&h) ||
3695
7.63k
      !readULong(&x) || !readULong(&y) ||
3696
5.79k
      !readUByte(&segInfoFlags)) {
3697
4.21k
    goto eofError;
3698
4.21k
  }
3699
5.49k
  if (w == 0 || h == 0) {
3700
505
    error(errSyntaxError, getPos(),
3701
505
    "Bad size in JBIG2 generic refinement region segment");
3702
505
    return;
3703
505
  }
3704
  // sanity check: if the w/h/x/y values are way out of range, it likely
3705
  // indicates a damaged JBIG2 stream
3706
4.99k
  if (w / 10 > pageW || h / 10 > pageH ||
3707
4.38k
      x / 10 > pageW || y / 10 > pageH) {
3708
771
    error(errSyntaxError, getPos(),
3709
771
    "Bad size or position in JBIG2 generic refinement region segment");
3710
771
    done = gTrue;
3711
771
    return;
3712
771
  }
3713
4.22k
  extCombOp = segInfoFlags & 7;
3714
3715
  // rest of the generic refinement region segment header
3716
4.22k
  if (!readUByte(&flags)) {
3717
227
    goto eofError;
3718
227
  }
3719
3.99k
  templ = flags & 1;
3720
3.99k
  tpgrOn = (flags >> 1) & 1;
3721
3722
  // AT flags
3723
3.99k
  if (!templ) {
3724
2.94k
    if (!readByte(&atx[0]) || !readByte(&aty[0]) ||
3725
2.42k
  !readByte(&atx[1]) || !readByte(&aty[1])) {
3726
1.04k
      goto eofError;
3727
1.04k
    }
3728
2.94k
  }
3729
3730
  // resize the page bitmap if needed
3731
2.94k
  if (nRefSegs == 0 || imm) {
3732
2.36k
    if (pageH == 0xffffffff && y + h > curPageH) {
3733
468
      pageBitmap->expand(y + h, pageDefPixel);
3734
468
    }
3735
2.36k
  }
3736
3737
  // get referenced bitmap
3738
2.94k
  if (nRefSegs > 1) {
3739
493
    error(errSyntaxError, getPos(),
3740
493
    "Bad reference in JBIG2 generic refinement segment");
3741
493
    return;
3742
493
  }
3743
2.45k
  if (nRefSegs == 1) {
3744
709
    if (!(seg = findSegment(refSegs[0])) ||
3745
709
  seg->getType() != jbig2SegBitmap) {
3746
709
      error(errSyntaxError, getPos(),
3747
709
      "Bad bitmap reference in JBIG2 generic refinement segment");
3748
709
      return;
3749
709
    }
3750
0
    refBitmap = (JBIG2Bitmap *)seg;
3751
1.74k
  } else {
3752
1.74k
    refBitmap = pageBitmap->getSlice(x, y, w, h);
3753
1.74k
  }
3754
3755
  // set up the arithmetic decoder
3756
1.74k
  resetRefinementStats(templ, NULL);
3757
1.74k
  arithDecoder->start();
3758
3759
  // read
3760
1.74k
  bitmap = readGenericRefinementRegion(w, h, templ, tpgrOn,
3761
1.74k
               refBitmap, 0, 0, atx, aty);
3762
3763
  // combine the region bitmap into the page bitmap
3764
1.74k
  if (imm) {
3765
1.42k
    pageBitmap->combine(bitmap, x, y, extCombOp);
3766
1.42k
    delete bitmap;
3767
3768
  // store the region bitmap
3769
1.42k
  } else {
3770
326
    bitmap->setSegNum(segNum);
3771
326
    segments->append(bitmap);
3772
326
  }
3773
3774
  // delete the referenced bitmap
3775
1.74k
  if (nRefSegs == 1) {
3776
0
    discardSegment(refSegs[0]);
3777
1.74k
  } else {
3778
1.74k
    delete refBitmap;
3779
1.74k
  }
3780
3781
1.74k
  return;
3782
3783
5.48k
 eofError:
3784
5.48k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
3785
5.48k
}
3786
3787
JBIG2Bitmap *JBIG2Stream::readGenericRefinementRegion(int w, int h,
3788
                  int templ, GBool tpgrOn,
3789
                  JBIG2Bitmap *refBitmap,
3790
                  int refDX, int refDY,
3791
135k
                  int *atx, int *aty) {
3792
135k
  JBIG2Bitmap *bitmap;
3793
135k
  GBool ltp;
3794
135k
  Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
3795
135k
  JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6;
3796
135k
  JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
3797
135k
  int x, y, pix;
3798
3799
135k
  bitmap = new JBIG2Bitmap(0, w, h);
3800
135k
  bitmap->clearToZero();
3801
3802
  // set up the typical row context
3803
135k
  if (templ) {
3804
70.2k
    ltpCX = 0x008;
3805
70.2k
  } else {
3806
65.0k
    ltpCX = 0x0010;
3807
65.0k
  }
3808
3809
135k
  ltp = 0;
3810
21.1M
  for (y = 0; y < h; ++y) {
3811
3812
21.0M
    if (templ) {
3813
3814
      // set up the context
3815
9.29M
      bitmap->getPixelPtr(0, y-1, &cxPtr0);
3816
9.29M
      cx0 = bitmap->nextPixel(&cxPtr0);
3817
9.29M
      bitmap->getPixelPtr(-1, y, &cxPtr1);
3818
9.29M
      refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
3819
9.29M
      refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
3820
9.29M
      cx3 = refBitmap->nextPixel(&cxPtr3);
3821
9.29M
      cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
3822
9.29M
      refBitmap->getPixelPtr(-refDX, y+1-refDY, &cxPtr4);
3823
9.29M
      cx4 = refBitmap->nextPixel(&cxPtr4);
3824
3825
      // set up the typical prediction context
3826
9.29M
      tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3827
9.29M
      if (tpgrOn) {
3828
5.55M
  refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
3829
5.55M
  tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
3830
5.55M
  tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3831
5.55M
  tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3832
5.55M
  refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
3833
5.55M
  tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
3834
5.55M
  tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3835
5.55M
  tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3836
5.55M
  refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
3837
5.55M
  tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3838
5.55M
  tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3839
5.55M
  tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3840
5.55M
      } else {
3841
3.73M
  tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy
3842
3.73M
  tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
3843
3.73M
  tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
3844
3.73M
      }
3845
3846
552M
      for (x = 0; x < w; ++x) {
3847
3848
  // update the context
3849
543M
  cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 7;
3850
543M
  cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3851
543M
  cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 3;
3852
3853
543M
  if (tpgrOn) {
3854
    // update the typical predictor context
3855
76.2M
    tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3856
76.2M
    tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3857
76.2M
    tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3858
3859
    // check for a "typical" pixel
3860
76.2M
    if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3861
51.2M
      ltp = !ltp;
3862
51.2M
    }
3863
76.2M
    if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3864
75.9M
      bitmap->clearPixel(x, y);
3865
75.9M
      continue;
3866
75.9M
    } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3867
165k
      bitmap->setPixel(x, y);
3868
165k
      continue;
3869
165k
    }
3870
76.2M
  }
3871
3872
  // build the context
3873
467M
  cx = (cx0 << 7) | (bitmap->nextPixel(&cxPtr1) << 6) |
3874
467M
       (refBitmap->nextPixel(&cxPtr2) << 5) |
3875
467M
       (cx3 << 2) | cx4;
3876
3877
  // decode the pixel
3878
467M
  if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3879
197M
    bitmap->setPixel(x, y);
3880
197M
  }
3881
467M
      }
3882
3883
11.7M
    } else {
3884
3885
      // set up the context
3886
11.7M
      bitmap->getPixelPtr(0, y-1, &cxPtr0);
3887
11.7M
      cx0 = bitmap->nextPixel(&cxPtr0);
3888
11.7M
      bitmap->getPixelPtr(-1, y, &cxPtr1);
3889
11.7M
      refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
3890
11.7M
      cx2 = refBitmap->nextPixel(&cxPtr2);
3891
11.7M
      refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
3892
11.7M
      cx3 = refBitmap->nextPixel(&cxPtr3);
3893
11.7M
      cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
3894
11.7M
      refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &cxPtr4);
3895
11.7M
      cx4 = refBitmap->nextPixel(&cxPtr4);
3896
11.7M
      cx4 = (cx4 << 1) | refBitmap->nextPixel(&cxPtr4);
3897
11.7M
      bitmap->getPixelPtr(atx[0], y+aty[0], &cxPtr5);
3898
11.7M
      refBitmap->getPixelPtr(atx[1]-refDX, y+aty[1]-refDY, &cxPtr6);
3899
3900
      // set up the typical prediction context
3901
11.7M
      tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3902
11.7M
      if (tpgrOn) {
3903
10.2M
  refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
3904
10.2M
  tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
3905
10.2M
  tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3906
10.2M
  tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3907
10.2M
  refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
3908
10.2M
  tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
3909
10.2M
  tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3910
10.2M
  tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3911
10.2M
  refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
3912
10.2M
  tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3913
10.2M
  tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3914
10.2M
  tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3915
10.2M
      } else {
3916
1.46M
  tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy
3917
1.46M
  tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
3918
1.46M
  tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
3919
1.46M
      }
3920
3921
181M
      for (x = 0; x < w; ++x) {
3922
3923
  // update the context
3924
169M
  cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 3;
3925
169M
  cx2 = ((cx2 << 1) | refBitmap->nextPixel(&cxPtr2)) & 3;
3926
169M
  cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3927
169M
  cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 7;
3928
3929
169M
  if (tpgrOn) {
3930
    // update the typical predictor context
3931
84.4M
    tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3932
84.4M
    tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3933
84.4M
    tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3934
3935
    // check for a "typical" pixel
3936
84.4M
    if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3937
70.8M
      ltp = !ltp;
3938
70.8M
    }
3939
84.4M
    if (tpgrCX0 == 0 && tpgrCX1 == 0 && tpgrCX2 == 0) {
3940
83.6M
      bitmap->clearPixel(x, y);
3941
83.6M
      continue;
3942
83.6M
    } else if (tpgrCX0 == 7 && tpgrCX1 == 7 && tpgrCX2 == 7) {
3943
489k
      bitmap->setPixel(x, y);
3944
489k
      continue;
3945
489k
    }
3946
84.4M
  }
3947
3948
  // build the context
3949
85.3M
  cx = (cx0 << 11) | (bitmap->nextPixel(&cxPtr1) << 10) |
3950
85.3M
       (cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
3951
85.3M
       (bitmap->nextPixel(&cxPtr5) << 1) |
3952
85.3M
       refBitmap->nextPixel(&cxPtr6);
3953
3954
  // decode the pixel
3955
85.3M
  if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3956
23.6M
    bitmap->setPixel(x, y);
3957
23.6M
  }
3958
85.3M
      }
3959
11.7M
    }
3960
21.0M
  }
3961
3962
135k
  return bitmap;
3963
135k
}
3964
3965
105k
void JBIG2Stream::readPageInfoSeg(Guint length) {
3966
105k
  Guint xRes, yRes, flags, striping;
3967
3968
105k
  if (!readULong(&pageW) || !readULong(&pageH) ||
3969
103k
      !readULong(&xRes) || !readULong(&yRes) ||
3970
102k
      !readUByte(&flags) || !readUWord(&striping)) {
3971
4.35k
    goto eofError;
3972
4.35k
  }
3973
101k
  if (pageW == 0 || pageH == 0 ||
3974
100k
      pageW > INT_MAX || pageH > INT_MAX ||
3975
81.8k
      pageH > INT_MAX / pageW) {
3976
46.6k
    error(errSyntaxError, getPos(), "Bad page size in JBIG2 stream");
3977
46.6k
    return;
3978
46.6k
  }
3979
54.6k
  pageDefPixel = (flags >> 2) & 1;
3980
54.6k
  defCombOp = (flags >> 3) & 3;
3981
3982
  // this will only happen if there are multiple page info segments
3983
54.6k
  if (pageBitmap) {
3984
3.27k
    delete pageBitmap;
3985
3.27k
  }
3986
3987
  // allocate the page bitmap
3988
54.6k
  if (pageH == 0xffffffff) {
3989
0
    curPageH = striping & 0x7fff;
3990
54.6k
  } else {
3991
54.6k
    curPageH = pageH;
3992
54.6k
  }
3993
54.6k
  pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
3994
3995
  // default pixel value
3996
54.6k
  if (pageDefPixel) {
3997
34.8k
    pageBitmap->clearToOne();
3998
34.8k
  } else {
3999
19.8k
    pageBitmap->clearToZero();
4000
19.8k
  }
4001
4002
54.6k
  return;
4003
4004
4.35k
 eofError:
4005
4.35k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
4006
4.35k
}
4007
4008
347
void JBIG2Stream::readEndOfStripeSeg(Guint length) {
4009
  // skip the segment
4010
347
  byteCounter += curStr->discardChars(length);
4011
347
}
4012
4013
359
void JBIG2Stream::readProfilesSeg(Guint length) {
4014
  // skip the segment
4015
359
  byteCounter += curStr->discardChars(length);
4016
359
}
4017
4018
8.19k
void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) {
4019
8.19k
  JBIG2HuffmanTable *huffTab;
4020
8.19k
  Guint flags, oob, prefixBits, rangeBits;
4021
8.19k
  int lowVal, highVal, val;
4022
8.19k
  Guint huffTabSize, i;
4023
4024
8.19k
  if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
4025
2.12k
    goto eofError;
4026
2.12k
  }
4027
6.07k
  oob = flags & 1;
4028
6.07k
  prefixBits = ((flags >> 1) & 7) + 1;
4029
6.07k
  rangeBits = ((flags >> 4) & 7) + 1;
4030
4031
6.07k
  huffDecoder->reset();
4032
6.07k
  huffTabSize = 8;
4033
6.07k
  huffTab = (JBIG2HuffmanTable *)
4034
6.07k
                gmallocn(huffTabSize, sizeof(JBIG2HuffmanTable));
4035
6.07k
  i = 0;
4036
6.07k
  val = lowVal;
4037
67.2M
  while (val < highVal) {
4038
67.2M
    if (i == huffTabSize) {
4039
750
      huffTabSize *= 2;
4040
750
      huffTab = (JBIG2HuffmanTable *)
4041
750
              greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
4042
750
    }
4043
67.2M
    huffTab[i].val = val;
4044
67.2M
    huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
4045
67.2M
    huffTab[i].rangeLen = huffDecoder->readBits(rangeBits);
4046
67.2M
    val += 1 << huffTab[i].rangeLen;
4047
67.2M
    ++i;
4048
67.2M
  }
4049
6.07k
  if (i + oob + 3 > huffTabSize) {
4050
374
    huffTabSize = i + oob + 3;
4051
374
    huffTab = (JBIG2HuffmanTable *)
4052
374
                  greallocn(huffTab, huffTabSize, sizeof(JBIG2HuffmanTable));
4053
374
  }
4054
6.07k
  huffTab[i].val = lowVal - 1;
4055
6.07k
  huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
4056
6.07k
  huffTab[i].rangeLen = jbig2HuffmanLOW;
4057
6.07k
  ++i;
4058
6.07k
  huffTab[i].val = highVal;
4059
6.07k
  huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
4060
6.07k
  huffTab[i].rangeLen = 32;
4061
6.07k
  ++i;
4062
6.07k
  if (oob) {
4063
1.68k
    huffTab[i].val = 0;
4064
1.68k
    huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
4065
1.68k
    huffTab[i].rangeLen = jbig2HuffmanOOB;
4066
1.68k
    ++i;
4067
1.68k
  }
4068
6.07k
  huffTab[i].val = 0;
4069
6.07k
  huffTab[i].prefixLen = 0;
4070
6.07k
  huffTab[i].rangeLen = jbig2HuffmanEOT;
4071
6.07k
  huffDecoder->buildTable(huffTab, i);
4072
4073
  // create and store the new table segment
4074
6.07k
  segments->append(new JBIG2CodeTable(segNum, huffTab));
4075
4076
6.07k
  return;
4077
4078
2.12k
 eofError:
4079
2.12k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
4080
2.12k
}
4081
4082
663
void JBIG2Stream::readExtensionSeg(Guint length) {
4083
  // skip the segment
4084
663
  byteCounter += curStr->discardChars(length);
4085
663
}
4086
4087
2.51M
JBIG2Segment *JBIG2Stream::findSegment(Guint segNum) {
4088
2.51M
  JBIG2Segment *seg;
4089
2.51M
  int i;
4090
4091
2.52M
  for (i = 0; i < globalSegments->getLength(); ++i) {
4092
35.8k
    seg = (JBIG2Segment *)globalSegments->get(i);
4093
35.8k
    if (seg->getSegNum() == segNum) {
4094
27.7k
      return seg;
4095
27.7k
    }
4096
35.8k
  }
4097
2.48M
  for (i = 0; i < segments->getLength(); ++i) {
4098
7.87k
    seg = (JBIG2Segment *)segments->get(i);
4099
7.87k
    if (seg->getSegNum() == segNum) {
4100
5.27k
      return seg;
4101
5.27k
    }
4102
7.87k
  }
4103
2.48M
  return NULL;
4104
2.48M
}
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
9.70k
            JArithmeticDecoderStats *prevStats) {
4128
9.70k
  int size;
4129
4130
9.70k
  size = contextSize[templ];
4131
9.70k
  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
9.70k
  } else {
4139
9.70k
    if (genericRegionStats->getContextSize() == size) {
4140
0
      genericRegionStats->reset();
4141
9.70k
    } else {
4142
9.70k
      delete genericRegionStats;
4143
9.70k
      genericRegionStats = new JArithmeticDecoderStats(1 << size);
4144
9.70k
    }
4145
9.70k
  }
4146
9.70k
}
4147
4148
void JBIG2Stream::resetRefinementStats(Guint templ,
4149
7.39k
               JArithmeticDecoderStats *prevStats) {
4150
7.39k
  int size;
4151
4152
7.39k
  size = refContextSize[templ];
4153
7.39k
  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
7.39k
  } else {
4161
7.39k
    if (refinementRegionStats->getContextSize() == size) {
4162
0
      refinementRegionStats->reset();
4163
7.39k
    } else {
4164
7.39k
      delete refinementRegionStats;
4165
7.39k
      refinementRegionStats = new JArithmeticDecoderStats(1 << size);
4166
7.39k
    }
4167
7.39k
  }
4168
7.39k
}
4169
4170
6.86k
void JBIG2Stream::resetIntStats(int symCodeLen) {
4171
6.86k
  iadhStats->reset();
4172
6.86k
  iadwStats->reset();
4173
6.86k
  iaexStats->reset();
4174
6.86k
  iaaiStats->reset();
4175
6.86k
  iadtStats->reset();
4176
6.86k
  iaitStats->reset();
4177
6.86k
  iafsStats->reset();
4178
6.86k
  iadsStats->reset();
4179
6.86k
  iardxStats->reset();
4180
6.86k
  iardyStats->reset();
4181
6.86k
  iardwStats->reset();
4182
6.86k
  iardhStats->reset();
4183
6.86k
  iariStats->reset();
4184
6.86k
  if (iaidStats->getContextSize() == 1 << (symCodeLen + 1)) {
4185
3.65k
    iaidStats->reset();
4186
3.65k
  } else {
4187
3.21k
    delete iaidStats;
4188
3.21k
    iaidStats = new JArithmeticDecoderStats(1 << (symCodeLen + 1));
4189
3.21k
  }
4190
6.86k
}
4191
4192
863k
GBool JBIG2Stream::readUByte(Guint *x) {
4193
863k
  int c0;
4194
4195
863k
  if ((c0 = curStr->getChar()) == EOF) {
4196
3.39k
    return gFalse;
4197
3.39k
  }
4198
860k
  ++byteCounter;
4199
860k
  *x = (Guint)c0;
4200
860k
  return gTrue;
4201
863k
}
4202
4203
113k
GBool JBIG2Stream::readByte(int *x) {
4204
113k
 int c0;
4205
4206
113k
  if ((c0 = curStr->getChar()) == EOF) {
4207
7.86k
    return gFalse;
4208
7.86k
  }
4209
105k
  ++byteCounter;
4210
105k
  *x = c0;
4211
105k
  if (c0 & 0x80) {
4212
20.3k
    *x |= -1 - 0xff;
4213
20.3k
  }
4214
105k
  return gTrue;
4215
113k
}
4216
4217
7.19M
GBool JBIG2Stream::readUWord(Guint *x) {
4218
7.19M
  int c0, c1;
4219
4220
7.19M
  if ((c0 = curStr->getChar()) == EOF ||
4221
7.19M
      (c1 = curStr->getChar()) == EOF) {
4222
2.58k
    return gFalse;
4223
2.58k
  }
4224
7.19M
  byteCounter += 2;
4225
7.19M
  *x = (Guint)((c0 << 8) | c1);
4226
7.19M
  return gTrue;
4227
7.19M
}
4228
4229
1.41M
GBool JBIG2Stream::readULong(Guint *x) {
4230
1.41M
  int c0, c1, c2, c3;
4231
4232
1.41M
  if ((c0 = curStr->getChar()) == EOF ||
4233
1.40M
      (c1 = curStr->getChar()) == EOF ||
4234
1.39M
      (c2 = curStr->getChar()) == EOF ||
4235
1.39M
      (c3 = curStr->getChar()) == EOF) {
4236
32.8k
    return gFalse;
4237
32.8k
  }
4238
1.38M
  byteCounter += 4;
4239
1.38M
  *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
4240
1.38M
  return gTrue;
4241
1.41M
}
4242
4243
20.7k
GBool JBIG2Stream::readLong(int *x) {
4244
20.7k
  int c0, c1, c2, c3;
4245
4246
20.7k
  if ((c0 = curStr->getChar()) == EOF ||
4247
19.9k
      (c1 = curStr->getChar()) == EOF ||
4248
19.2k
      (c2 = curStr->getChar()) == EOF ||
4249
18.4k
      (c3 = curStr->getChar()) == EOF) {
4250
2.99k
    return gFalse;
4251
2.99k
  }
4252
17.7k
  byteCounter += 4;
4253
17.7k
  *x = ((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
4254
17.7k
  if (c0 & 0x80) {
4255
2.91k
    *x |= -1 - (int)0xffffffff;
4256
2.91k
  }
4257
17.7k
  return gTrue;
4258
20.7k
}