Coverage Report

Created: 2026-07-04 07:15

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