Coverage Report

Created: 2026-10-19 06:49

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