Coverage Report

Created: 2025-08-29 07:16

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