Coverage Report

Created: 2023-09-25 06:41

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