Coverage Report

Created: 2026-05-30 06:30

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