Coverage Report

Created: 2025-08-28 06:46

/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
51.3k
  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
112k
  void resetByteCounter() { byteCounter = 0; }
309
95.7k
  Guint getByteCounter() { return byteCounter; }
310
311
private:
312
313
  Stream *str;
314
  Guint buf;
315
  Guint bufLen;
316
  Guint byteCounter;
317
};
318
319
383k
JBIG2HuffmanDecoder::JBIG2HuffmanDecoder() {
320
383k
  str = NULL;
321
383k
  byteCounter = 0;
322
383k
  reset();
323
383k
}
324
325
383k
JBIG2HuffmanDecoder::~JBIG2HuffmanDecoder() {
326
383k
}
327
328
396k
void JBIG2HuffmanDecoder::reset() {
329
396k
  buf = 0;
330
396k
  bufLen = 0;
331
396k
}
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
531k
      if (table[i].rangeLen == jbig2HuffmanLOW) {
350
136
  *x = table[i].val - readBits(32);
351
531k
      } else if (table[i].rangeLen > 0) {
352
441k
  *x = table[i].val + readBits(table[i].rangeLen);
353
441k
      } else {
354
89.3k
  *x = table[i].val;
355
89.3k
      }
356
531k
      return gTrue;
357
845k
    }
358
3.81M
    ++i;
359
3.81M
  }
360
9.42k
  return gFalse;
361
854k
}
362
363
965k
Guint JBIG2HuffmanDecoder::readBits(Guint n) {
364
965k
  Guint x, mask, nLeft;
365
366
965k
  mask = (n == 32) ? 0xffffffff : ((1 << n) - 1);
367
965k
  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
965k
  return x;
387
965k
}
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.50k
void JBIG2HuffmanDecoder::buildTable(JBIG2HuffmanTable *table, Guint len) {
400
4.50k
  Guint i, j, k, prefix;
401
4.50k
  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
172k
  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.76k
      break;
412
2.76k
    }
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
347k
  j = k;
417
347k
      }
418
163M
    }
419
167k
    if (j != i) {
420
161k
      tab = table[j];
421
62.7M
      for (k = j; k > i; --k) {
422
62.6M
  table[k] = table[k - 1];
423
62.6M
      }
424
161k
      table[i] = tab;
425
161k
    }
426
167k
  }
427
4.50k
  table[i] = table[len];
428
429
  // assign prefixes
430
4.50k
  if (table[0].rangeLen != jbig2HuffmanEOT) {
431
2.79k
    i = 0;
432
2.79k
    prefix = 0;
433
2.79k
    table[i++].prefix = prefix++;
434
167k
    for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) {
435
165k
      prefix <<= table[i].prefixLen - table[i-1].prefixLen;
436
165k
      table[i].prefix = prefix++;
437
165k
    }
438
2.79k
  }
439
4.50k
}
440
441
//------------------------------------------------------------------------
442
// JBIG2MMRDecoder
443
//------------------------------------------------------------------------
444
445
class JBIG2MMRDecoder {
446
public:
447
448
  JBIG2MMRDecoder();
449
  ~JBIG2MMRDecoder();
450
51.3k
  void setStream(Stream *strA) { str = strA; }
451
  void reset();
452
  int get2DCode();
453
  int getBlackCode();
454
  int getWhiteCode();
455
  Guint get24Bits();
456
112k
  void resetByteCounter() { byteCounter = 0; }
457
95.7k
  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
383k
JBIG2MMRDecoder::JBIG2MMRDecoder() {
470
383k
  str = NULL;
471
383k
  byteCounter = 0;
472
383k
  reset();
473
383k
}
474
475
383k
JBIG2MMRDecoder::~JBIG2MMRDecoder() {
476
383k
}
477
478
386k
void JBIG2MMRDecoder::reset() {
479
386k
  buf = 0;
480
386k
  bufLen = 0;
481
386k
  nBytesRead = 0;
482
386k
}
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.32M
    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.9k
      buf = (buf << 8) | (str->getChar() & 0xff);
499
29.9k
      bufLen += 8;
500
29.9k
      ++nBytesRead;
501
29.9k
      ++byteCounter;
502
29.9k
      p = &twoDimTab1[(buf >> (bufLen - 7)) & 0x7f];
503
29.9k
    }
504
43.3M
  }
505
57.9M
  if (p->bits < 0) {
506
95.3k
    error(errSyntaxError, str->getPos(),
507
95.3k
    "Bad two dim code in JBIG2 MMR stream");
508
95.3k
    return EOF;
509
95.3k
  }
510
57.8M
  bufLen -= p->bits;
511
57.8M
  return p->n;
512
57.9M
}
513
514
23.4k
int JBIG2MMRDecoder::getWhiteCode() {
515
23.4k
  CCITTCode *p;
516
23.4k
  Guint code;
517
518
23.4k
  if (bufLen == 0) {
519
2.01k
    buf = str->getChar() & 0xff;
520
2.01k
    bufLen = 8;
521
2.01k
    ++nBytesRead;
522
2.01k
    ++byteCounter;
523
2.01k
  }
524
40.1k
  while (1) {
525
40.1k
    if (bufLen >= 11 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
526
1.02k
      if (bufLen <= 12) {
527
132
  code = buf << (12 - bufLen);
528
892
      } else {
529
892
  code = buf >> (bufLen - 12);
530
892
      }
531
1.02k
      p = &whiteTab1[code & 0x1f];
532
39.0k
    } else {
533
39.0k
      if (bufLen <= 9) {
534
31.8k
  code = buf << (9 - bufLen);
535
31.8k
      } else {
536
7.27k
  code = buf >> (bufLen - 9);
537
7.27k
      }
538
39.0k
      p = &whiteTab2[code & 0x1ff];
539
39.0k
    }
540
40.1k
    if (p->bits > 0 && p->bits <= (int)bufLen) {
541
23.0k
      bufLen -= p->bits;
542
23.0k
      return p->n;
543
23.0k
    }
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.4k
}
558
559
20.9k
int JBIG2MMRDecoder::getBlackCode() {
560
20.9k
  CCITTCode *p;
561
20.9k
  Guint code;
562
563
20.9k
  if (bufLen == 0) {
564
903
    buf = str->getChar() & 0xff;
565
903
    bufLen = 8;
566
903
    ++nBytesRead;
567
903
    ++byteCounter;
568
903
  }
569
28.2k
  while (1) {
570
28.2k
    if (bufLen >= 10 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
571
1.15k
      if (bufLen <= 13) {
572
557
  code = buf << (13 - bufLen);
573
601
      } else {
574
601
  code = buf >> (bufLen - 13);
575
601
      }
576
1.15k
      p = &blackTab1[code & 0x7f];
577
27.0k
    } else if (bufLen >= 7 && ((buf >> (bufLen - 4)) & 0x0f) == 0 &&
578
27.0k
         ((buf >> (bufLen - 6)) & 0x03) != 0) {
579
1.41k
      if (bufLen <= 12) {
580
886
  code = buf << (12 - bufLen);
581
886
      } else {
582
533
  code = buf >> (bufLen - 12);
583
533
      }
584
1.41k
      p = &blackTab2[(code & 0xff) - 64];
585
25.6k
    } else {
586
25.6k
      if (bufLen <= 6) {
587
18.8k
  code = buf << (6 - bufLen);
588
18.8k
      } else {
589
6.79k
  code = buf >> (bufLen - 6);
590
6.79k
      }
591
25.6k
      p = &blackTab3[code & 0x3f];
592
25.6k
    }
593
28.2k
    if (p->bits > 0 && p->bits <= (int)bufLen) {
594
20.4k
      bufLen -= p->bits;
595
20.4k
      return p->n;
596
20.4k
    }
597
7.82k
    if (bufLen >= 13) {
598
500
      break;
599
500
    }
600
7.32k
    buf = (buf << 8) | (str->getChar() & 0xff);
601
7.32k
    bufLen += 8;
602
7.32k
    ++nBytesRead;
603
7.32k
    ++byteCounter;
604
7.32k
  }
605
500
  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
500
  --bufLen;
609
500
  return 1;
610
20.9k
}
611
612
316
Guint JBIG2MMRDecoder::get24Bits() {
613
1.13k
  while (bufLen < 24) {
614
819
    buf = (buf << 8) | (str->getChar() & 0xff);
615
819
    bufLen += 8;
616
819
    ++nBytesRead;
617
819
    ++byteCounter;
618
819
  }
619
316
  return (buf >> (bufLen - 24)) & 0xffffff;
620
316
}
621
622
2.23k
void JBIG2MMRDecoder::skipTo(Guint length) {
623
2.23k
  int n;
624
625
2.23k
  n = str->discardChars(length - nBytesRead);
626
2.23k
  nBytesRead += n;
627
2.23k
  byteCounter += n;
628
2.23k
}
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
231k
  JBIG2Segment(Guint segNumA) { segNum = segNumA; }
645
231k
  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
477k
  int getLineSize() { return line; }
679
  int getPixel(int x, int y)
680
87.9M
    { return (x < 0 || x >= w || y < 0 || y >= h) ? 0 :
681
87.9M
             (data[y * line + (x >> 3)] >> (7 - (x & 7))) & 1; }
682
  void setPixel(int x, int y)
683
80.5M
    { 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
504k
  Guchar *getDataPtr() { return data; }
691
27.4k
  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
217k
  JBIG2Segment(segNumA)
703
217k
{
704
217k
  w = wA;
705
217k
  h = hA;
706
217k
  line = (wA + 7) >> 3;
707
217k
  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
10
    h = -1;
710
10
    line = 2;
711
10
  }
712
  // need to allocate one extra guard byte for use in combine()
713
217k
  data = (Guchar *)gmalloc(h * line + 1);
714
217k
  data[h * line] = 0;
715
217k
}
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
222k
JBIG2Bitmap::~JBIG2Bitmap() {
735
222k
  gfree(data);
736
222k
}
737
738
//~ optimize this
739
55.5k
JBIG2Bitmap *JBIG2Bitmap::getSlice(Guint x, Guint y, Guint wA, Guint hA) {
740
55.5k
  JBIG2Bitmap *slice;
741
55.5k
  Guint xx, yy;
742
743
55.5k
  slice = new JBIG2Bitmap(0, wA, hA);
744
55.5k
  slice->clearToZero();
745
2.39M
  for (yy = 0; yy < hA; ++yy) {
746
23.2M
    for (xx = 0; xx < wA; ++xx) {
747
20.9M
      if (getPixel(x + xx, y + yy)) {
748
3.08M
  slice->setPixel(xx, yy);
749
3.08M
      }
750
20.9M
    }
751
2.34M
  }
752
55.5k
  return slice;
753
55.5k
}
754
755
1.22k
void JBIG2Bitmap::expand(int newH, Guint pixel) {
756
1.22k
  if (newH <= h || line <= 0 || newH >= (INT_MAX - 1) / line) {
757
770
    return;
758
770
  }
759
  // need to allocate one extra guard byte for use in combine()
760
458
  data = (Guchar *)grealloc(data, newH * line + 1);
761
458
  if (pixel) {
762
278
    memset(data + h * line, 0xff, (newH - h) * line);
763
278
  } else {
764
180
    memset(data + h * line, 0x00, (newH - h) * line);
765
180
  }
766
458
  h = newH;
767
458
  data[h * line] = 0;
768
458
}
769
770
205k
void JBIG2Bitmap::clearToZero() {
771
205k
  memset(data, 0, h * line);
772
205k
}
773
774
10.9k
void JBIG2Bitmap::clearToOne() {
775
10.9k
  memset(data, 0xff, h * line);
776
10.9k
}
777
778
29.9M
inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) {
779
29.9M
  if (y < 0 || y >= h || x >= w) {
780
3.34M
    ptr->p = NULL;
781
3.34M
    ptr->shift = 0; // make gcc happy
782
3.34M
    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.30M
    ptr->p = &data[y * line + (x >> 3)];
789
8.30M
    ptr->shift = 7 - (x & 7);
790
8.30M
    ptr->x = x;
791
8.30M
  }
792
29.9M
}
793
794
658M
inline int JBIG2Bitmap::nextPixel(JBIG2BitmapPtr *ptr) {
795
658M
  int pix;
796
797
658M
  if (!ptr->p) {
798
193M
    pix = 0;
799
464M
  } else if (ptr->x < 0) {
800
42.4M
    ++ptr->x;
801
42.4M
    pix = 0;
802
421M
  } else {
803
421M
    pix = (*ptr->p >> ptr->shift) & 1;
804
421M
    if (++ptr->x == w) {
805
19.6M
      ptr->p = NULL;
806
402M
    } else if (ptr->shift == 0) {
807
43.6M
      ++ptr->p;
808
43.6M
      ptr->shift = 7;
809
358M
    } else {
810
358M
      --ptr->shift;
811
358M
    }
812
421M
  }
813
658M
  return pix;
814
658M
}
815
816
85.2k
void JBIG2Bitmap::duplicateRow(int yDest, int ySrc) {
817
85.2k
  memcpy(data + yDest * line, data + ySrc * line, line);
818
85.2k
}
819
820
void JBIG2Bitmap::combine(JBIG2Bitmap *bitmap, int x, int y,
821
60.3k
        Guint combOp) {
822
60.3k
  int x0, x1, y0, y1, xx, yy;
823
60.3k
  Guchar *srcPtr, *destPtr;
824
60.3k
  Guchar dest, src0, src1, src, m1, m2, m3;
825
60.3k
  Guint s1, s2;
826
60.3k
  GBool oneByte;
827
828
  // check for the pathological case where y = -2^31
829
60.3k
  if (y < -0x7fffffff) {
830
0
    return;
831
0
  }
832
60.3k
  if (y < 0) {
833
26.2k
    y0 = -y;
834
34.1k
  } else {
835
34.1k
    y0 = 0;
836
34.1k
  }
837
60.3k
  if (y > INT_MAX - bitmap->h) {
838
3.11k
    return;
839
3.11k
  }
840
57.2k
  if (y + bitmap->h > h) {
841
28.6k
    y1 = h - y;
842
28.6k
  } else {
843
28.6k
    y1 = bitmap->h;
844
28.6k
  }
845
57.2k
  if (y0 >= y1) {
846
33.0k
    return;
847
33.0k
  }
848
849
24.2k
  if (x >= 0) {
850
7.86k
    x0 = x & ~7;
851
16.3k
  } else {
852
16.3k
    x0 = 0;
853
16.3k
  }
854
24.2k
  x1 = x + bitmap->w;
855
24.2k
  if (x1 > w) {
856
6.97k
    x1 = w;
857
6.97k
  }
858
24.2k
  if (x0 >= x1) {
859
22.3k
    return;
860
22.3k
  }
861
862
1.83k
  s1 = x & 7;
863
1.83k
  s2 = 8 - s1;
864
1.83k
  m1 = (Guchar)(0xff >> (x1 & 7));
865
1.83k
  m2 = (Guchar)(0xff << (((x1 & 7) == 0) ? 0 : 8 - (x1 & 7)));
866
1.83k
  m3 = (Guchar)((0xff >> s1) & m2);
867
868
1.83k
  oneByte = x0 == ((x1 - 1) & ~7);
869
870
342k
  for (yy = y0; yy < y1; ++yy) {
871
872
    // one byte per line -- need to mask both left and right side
873
340k
    if (oneByte) {
874
329k
      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
98.6k
  destPtr = data + (y + yy) * line;
899
98.6k
  srcPtr = bitmap->data + yy * bitmap->line + (-x >> 3);
900
98.6k
  dest = *destPtr;
901
98.6k
  src1 = *srcPtr;
902
98.6k
  switch (combOp) {
903
46.4k
  case 0: // or
904
46.4k
    dest |= src1 & m2;
905
46.4k
    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
98.6k
  }
919
98.6k
  *destPtr = dest;
920
98.6k
      }
921
922
    // multiple bytes per line -- need to mask left side of left-most
923
    // byte and right side of right-most byte
924
329k
    } else {
925
926
      // left-most byte
927
10.9k
      if (x >= 0) {
928
7.64k
  destPtr = data + (y + yy) * line + (x >> 3);
929
7.64k
  srcPtr = bitmap->data + yy * bitmap->line;
930
7.64k
  src1 = *srcPtr++;
931
7.64k
  dest = *destPtr;
932
7.64k
  switch (combOp) {
933
7.11k
  case 0: // or
934
7.11k
    dest |= (Guchar)(src1 >> s1);
935
7.11k
    break;
936
94
  case 1: // and
937
94
    dest &= (Guchar)((0xff00 | src1) >> s1);
938
94
    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
7.64k
  }
949
7.64k
  *destPtr++ = dest;
950
7.64k
  xx = x0 + 8;
951
7.64k
      } 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
5.29M
      for (; xx < x1 - 8; xx += 8) {
960
5.28M
  dest = *destPtr;
961
5.28M
  src0 = src1;
962
5.28M
  src1 = *srcPtr++;
963
5.28M
  src = (Guchar)(((src0 << 8) | src1) >> s1);
964
5.28M
  switch (combOp) {
965
5.26M
  case 0: // or
966
5.26M
    dest |= src;
967
5.26M
    break;
968
2.43k
  case 1: // and
969
2.43k
    dest &= src;
970
2.43k
    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
5.28M
  }
981
5.28M
  *destPtr++ = dest;
982
5.28M
      }
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
10.9k
      dest = *destPtr;
990
10.9k
      src0 = src1;
991
10.9k
      src1 = *srcPtr++;
992
10.9k
      src = (Guchar)(((src0 << 8) | src1) >> s1);
993
10.9k
      switch (combOp) {
994
10.0k
      case 0: // or
995
10.0k
  dest |= src & m2;
996
10.0k
  break;
997
94
      case 1: // and
998
94
  dest &= src | m1;
999
94
  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
10.9k
      }
1010
10.9k
      *destPtr = dest;
1011
10.9k
    }
1012
340k
  }
1013
1.83k
}
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.44k
  virtual JBIG2SegmentType getType() { return jbig2SegSymbolDict; }
1025
2.44k
  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
572
    { genericRegionStats = stats; }
1030
  void setRefinementRegionStats(JArithmeticDecoderStats *stats)
1031
428
    { refinementRegionStats = stats; }
1032
  JArithmeticDecoderStats *getGenericRegionStats()
1033
256
    { return genericRegionStats; }
1034
  JArithmeticDecoderStats *getRefinementRegionStats()
1035
356
    { 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.39k
  JBIG2Segment(segNumA)
1047
5.39k
{
1048
5.39k
  Guint i;
1049
1050
5.39k
  size = sizeA;
1051
5.39k
  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.39k
  genericRegionStats = NULL;
1056
5.39k
  refinementRegionStats = NULL;
1057
5.39k
}
1058
1059
5.39k
JBIG2SymbolDict::~JBIG2SymbolDict() {
1060
5.39k
  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.39k
  gfree(bitmaps);
1068
5.39k
  if (genericRegionStats) {
1069
572
    delete genericRegionStats;
1070
572
  }
1071
5.39k
  if (refinementRegionStats) {
1072
428
    delete refinementRegionStats;
1073
428
  }
1074
5.39k
}
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
209
  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
130
  JBIG2Segment(segNumA)
1098
130
{
1099
130
  size = sizeA;
1100
130
  bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
1101
130
}
1102
1103
130
JBIG2PatternDict::~JBIG2PatternDict() {
1104
130
  Guint i;
1105
1106
339
  for (i = 0; i < size; ++i) {
1107
209
    delete bitmaps[i];
1108
209
  }
1109
130
  gfree(bitmaps);
1110
130
}
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.6k
  virtual JBIG2SegmentType getType() { return jbig2SegCodeTable; }
1122
3.43k
  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
383k
  FilterStream(strA)
1145
383k
{
1146
383k
  decoded = gFalse;
1147
383k
  pageBitmap = NULL;
1148
1149
383k
  arithDecoder = new JArithmeticDecoder();
1150
383k
  genericRegionStats = new JArithmeticDecoderStats(1 << 1);
1151
383k
  refinementRegionStats = new JArithmeticDecoderStats(1 << 1);
1152
383k
  iadhStats = new JArithmeticDecoderStats(1 << 9);
1153
383k
  iadwStats = new JArithmeticDecoderStats(1 << 9);
1154
383k
  iaexStats = new JArithmeticDecoderStats(1 << 9);
1155
383k
  iaaiStats = new JArithmeticDecoderStats(1 << 9);
1156
383k
  iadtStats = new JArithmeticDecoderStats(1 << 9);
1157
383k
  iaitStats = new JArithmeticDecoderStats(1 << 9);
1158
383k
  iafsStats = new JArithmeticDecoderStats(1 << 9);
1159
383k
  iadsStats = new JArithmeticDecoderStats(1 << 9);
1160
383k
  iardxStats = new JArithmeticDecoderStats(1 << 9);
1161
383k
  iardyStats = new JArithmeticDecoderStats(1 << 9);
1162
383k
  iardwStats = new JArithmeticDecoderStats(1 << 9);
1163
383k
  iardhStats = new JArithmeticDecoderStats(1 << 9);
1164
383k
  iariStats = new JArithmeticDecoderStats(1 << 9);
1165
383k
  iaidStats = new JArithmeticDecoderStats(1 << 1);
1166
383k
  huffDecoder = new JBIG2HuffmanDecoder();
1167
383k
  mmrDecoder = new JBIG2MMRDecoder();
1168
1169
383k
  globalsStreamA->copy(&globalsStream);
1170
383k
  segments = globalSegments = NULL;
1171
383k
  curStr = NULL;
1172
383k
  dataPtr = dataEnd = NULL;
1173
383k
}
1174
1175
383k
JBIG2Stream::~JBIG2Stream() {
1176
383k
  close();
1177
383k
  globalsStream.free();
1178
383k
  delete arithDecoder;
1179
383k
  delete genericRegionStats;
1180
383k
  delete refinementRegionStats;
1181
383k
  delete iadhStats;
1182
383k
  delete iadwStats;
1183
383k
  delete iaexStats;
1184
383k
  delete iaaiStats;
1185
383k
  delete iadtStats;
1186
383k
  delete iaitStats;
1187
383k
  delete iafsStats;
1188
383k
  delete iadsStats;
1189
383k
  delete iardxStats;
1190
383k
  delete iardyStats;
1191
383k
  delete iardwStats;
1192
383k
  delete iardhStats;
1193
383k
  delete iariStats;
1194
383k
  delete iaidStats;
1195
383k
  delete huffDecoder;
1196
383k
  delete mmrDecoder;
1197
383k
  delete str;
1198
383k
}
1199
1200
376k
Stream *JBIG2Stream::copy() {
1201
376k
  return new JBIG2Stream(str->copy(), &globalsStream);
1202
376k
}
1203
1204
42.2k
void JBIG2Stream::reset() {
1205
42.2k
  segments = new GList();
1206
42.2k
  globalSegments = new GList();
1207
42.2k
  decoded = gFalse;
1208
42.2k
}
1209
1210
425k
void JBIG2Stream::close() {
1211
425k
  if (pageBitmap) {
1212
27.4k
    delete pageBitmap;
1213
27.4k
    pageBitmap = NULL;
1214
27.4k
  }
1215
425k
  if (segments) {
1216
42.0k
    deleteGList(segments, JBIG2Segment);
1217
42.0k
    segments = NULL;
1218
42.0k
  }
1219
425k
  if (globalSegments) {
1220
42.0k
    deleteGList(globalSegments, JBIG2Segment);
1221
42.0k
    globalSegments = NULL;
1222
42.0k
  }
1223
425k
  dataPtr = dataEnd = NULL;
1224
425k
  FilterStream::close();
1225
425k
}
1226
1227
246M
int JBIG2Stream::getChar() {
1228
246M
  if (!decoded) {
1229
42.0k
    decodeImage();
1230
42.0k
  }
1231
246M
  if (dataPtr && dataPtr < dataEnd) {
1232
246M
    return (*dataPtr++ ^ 0xff) & 0xff;
1233
246M
  }
1234
53.7k
  return EOF;
1235
246M
}
1236
1237
88.1M
int JBIG2Stream::lookChar() {
1238
88.1M
  if (!decoded) {
1239
0
    decodeImage();
1240
0
  }
1241
88.1M
  if (dataPtr && dataPtr < dataEnd) {
1242
88.0M
    return (*dataPtr ^ 0xff) & 0xff;
1243
88.0M
  }
1244
13.4k
  return EOF;
1245
88.1M
}
1246
1247
16.1k
int JBIG2Stream::getBlock(char *blk, int size) {
1248
16.1k
  int n, i;
1249
1250
16.1k
  if (!decoded) {
1251
13
    decodeImage();
1252
13
  }
1253
16.1k
  if (size <= 0) {
1254
0
    return 0;
1255
0
  }
1256
16.1k
  if (dataEnd - dataPtr < size) {
1257
208
    n = (int)(dataEnd - dataPtr);
1258
15.9k
  } else {
1259
15.9k
    n = size;
1260
15.9k
  }
1261
65.5M
  for (i = 0; i < n; ++i) {
1262
65.5M
    blk[i] = *dataPtr++ ^ 0xff;
1263
65.5M
  }
1264
16.1k
  return n;
1265
16.1k
}
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
42.0k
void JBIG2Stream::decodeImage() {
1277
42.0k
  GList *t;
1278
1279
  // read the globals stream
1280
42.0k
  if (globalsStream.isStream()) {
1281
9.28k
    curStr = globalsStream.getStream();
1282
9.28k
    curStr->reset();
1283
9.28k
    arithDecoder->setStream(curStr);
1284
9.28k
    huffDecoder->setStream(curStr);
1285
9.28k
    mmrDecoder->setStream(curStr);
1286
9.28k
    readSegments();
1287
9.28k
    curStr->close();
1288
    // swap the newly read segments list into globalSegments
1289
9.28k
    t = segments;
1290
9.28k
    segments = globalSegments;
1291
9.28k
    globalSegments = t;
1292
9.28k
  }
1293
1294
  // read the main stream
1295
42.0k
  curStr = str;
1296
42.0k
  curStr->reset();
1297
42.0k
  arithDecoder->setStream(curStr);
1298
42.0k
  huffDecoder->setStream(curStr);
1299
42.0k
  mmrDecoder->setStream(curStr);
1300
42.0k
  readSegments();
1301
1302
42.0k
  if (pageBitmap) {
1303
27.4k
    dataPtr = pageBitmap->getDataPtr();
1304
27.4k
    dataEnd = dataPtr + pageBitmap->getDataSize();
1305
27.4k
  } else {
1306
14.5k
    dataPtr = dataEnd = NULL;
1307
14.5k
  }
1308
1309
42.0k
  decoded = gTrue;
1310
42.0k
}
1311
1312
51.3k
void JBIG2Stream::readSegments() {
1313
51.3k
  Guint segNum, segFlags, segType, page, segLength;
1314
51.3k
  Guint refFlags, nRefSegs;
1315
51.3k
  Guint *refSegs;
1316
51.3k
  int c1, c2, c3;
1317
51.3k
  Guint i;
1318
1319
51.3k
  done = gFalse;
1320
122k
  while (!done && readULong(&segNum)) {
1321
1322
    // segment header flags
1323
115k
    if (!readUByte(&segFlags)) {
1324
47
      goto eofError1;
1325
47
    }
1326
115k
    segType = segFlags & 0x3f;
1327
1328
    // referred-to segment count and retention flags
1329
115k
    if (!readUByte(&refFlags)) {
1330
59
      goto eofError1;
1331
59
    }
1332
115k
    nRefSegs = refFlags >> 5;
1333
115k
    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
793
      refFlags = (refFlags << 24) | (c1 << 16) | (c2 << 8) | c3;
1340
793
      nRefSegs = refFlags & 0x1fffffff;
1341
793
      i = (nRefSegs + 9) >> 3;
1342
793
      if (curStr->discardChars(i) != i) {
1343
302
  goto eofError1;
1344
302
      }
1345
793
    }
1346
1347
    // referred-to segment numbers
1348
114k
    refSegs = (Guint *)gmallocn(nRefSegs, sizeof(Guint));
1349
114k
    if (segNum <= 256) {
1350
21.6k
      for (i = 0; i < nRefSegs; ++i) {
1351
4.50k
  if (!readUByte(&refSegs[i])) {
1352
128
    goto eofError2;
1353
128
  }
1354
4.50k
      }
1355
97.0k
    } 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
92.9k
    } else {
1362
376k
      for (i = 0; i < nRefSegs; ++i) {
1363
284k
  if (!readULong(&refSegs[i])) {
1364
245
    goto eofError2;
1365
245
  }
1366
284k
      }
1367
92.9k
    }
1368
1369
    // segment page association
1370
113k
    if (segFlags & 0x40) {
1371
24.5k
      if (!readULong(&page)) {
1372
266
  goto eofError2;
1373
266
      }
1374
89.3k
    } else {
1375
89.3k
      if (!readUByte(&page)) {
1376
234
  goto eofError2;
1377
234
      }
1378
89.3k
    }
1379
1380
    // segment data length
1381
113k
    if (!readULong(&segLength)) {
1382
438
      goto eofError2;
1383
438
    }
1384
1385
    // check for missing page information segment
1386
112k
    if (!pageBitmap && ((segType >= 4 && segType <= 7) ||
1387
55.3k
      (segType >= 20 && segType <= 43))) {
1388
675
      error(errSyntaxError, getPos(),
1389
675
      "First JBIG2 segment associated with a page must be a page information segment");
1390
675
      goto syntaxError;
1391
675
    }
1392
1393
    // read the segment data
1394
112k
    arithDecoder->resetByteCounter();
1395
112k
    huffDecoder->resetByteCounter();
1396
112k
    mmrDecoder->resetByteCounter();
1397
112k
    byteCounter = 0;
1398
112k
    switch (segType) {
1399
17.2k
    case 0:
1400
17.2k
      if (!readSymbolDictSeg(segNum, segLength, refSegs, nRefSegs)) {
1401
12.9k
  goto syntaxError;
1402
12.9k
      }
1403
4.32k
      break;
1404
4.32k
    case 4:
1405
865
      readTextRegionSeg(segNum, gFalse, gFalse, segLength, refSegs, nRefSegs);
1406
865
      break;
1407
5.39k
    case 6:
1408
5.39k
      readTextRegionSeg(segNum, gTrue, gFalse, segLength, refSegs, nRefSegs);
1409
5.39k
      break;
1410
1.18k
    case 7:
1411
1.18k
      readTextRegionSeg(segNum, gTrue, gTrue, segLength, refSegs, nRefSegs);
1412
1.18k
      break;
1413
1.53k
    case 16:
1414
1.53k
      readPatternDictSeg(segNum, segLength);
1415
1.53k
      break;
1416
962
    case 20:
1417
962
      readHalftoneRegionSeg(segNum, gFalse, gFalse, segLength,
1418
962
          refSegs, nRefSegs);
1419
962
      break;
1420
4.63k
    case 22:
1421
4.63k
      readHalftoneRegionSeg(segNum, gTrue, gFalse, segLength,
1422
4.63k
          refSegs, nRefSegs);
1423
4.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.79k
    case 38:
1432
5.79k
      readGenericRegionSeg(segNum, gTrue, gFalse, segLength);
1433
5.79k
      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.96k
    case 43:
1446
1.96k
      readGenericRefinementRegionSeg(segNum, gTrue, gTrue, segLength,
1447
1.96k
             refSegs, nRefSegs);
1448
1.96k
      break;
1449
56.6k
    case 48:
1450
56.6k
      readPageInfoSeg(segLength);
1451
56.6k
      break;
1452
110
    case 50:
1453
110
      readEndOfStripeSeg(segLength);
1454
110
      break;
1455
179
    case 51:
1456
      // end of file segment
1457
179
      done = gTrue;
1458
179
      break;
1459
37
    case 52:
1460
37
      readProfilesSeg(segLength);
1461
37
      break;
1462
5.32k
    case 53:
1463
5.32k
      readCodeTableSeg(segNum, segLength);
1464
5.32k
      break;
1465
425
    case 62:
1466
425
      readExtensionSeg(segLength);
1467
425
      break;
1468
7.17k
    default:
1469
7.17k
      error(errSyntaxError, getPos(), "Unknown segment type in JBIG2 stream");
1470
7.17k
      if (curStr->discardChars(segLength) != segLength) {
1471
3.51k
  goto eofError2;
1472
3.51k
      }
1473
3.66k
      break;
1474
112k
    }
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
95.8k
    if (!(segType == 38 && segLength == 0xffffffff)) {
1480
95.7k
      byteCounter += arithDecoder->getByteCounter();
1481
95.7k
      byteCounter += huffDecoder->getByteCounter();
1482
95.7k
      byteCounter += mmrDecoder->getByteCounter();
1483
      // do a sanity check on byteCounter vs segLength -- if there is
1484
      // a problem, abort the decode
1485
95.7k
      if (byteCounter > segLength ||
1486
95.7k
    segLength - byteCounter > 65536) {
1487
24.2k
  error(errSyntaxError, getPos(),
1488
24.2k
        "Invalid segment length in JBIG2 stream");
1489
24.2k
  gfree(refSegs);
1490
24.2k
  break;
1491
24.2k
      }
1492
71.4k
      byteCounter += curStr->discardChars(segLength - byteCounter);
1493
71.4k
    }
1494
1495
71.5k
    gfree(refSegs);
1496
71.5k
  }
1497
1498
31.9k
  return;
1499
1500
31.9k
 syntaxError:
1501
13.6k
  gfree(refSegs);
1502
13.6k
  return;
1503
1504
4.88k
 eofError2:
1505
4.88k
  gfree(refSegs);
1506
5.67k
 eofError1:
1507
5.67k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
1508
5.67k
}
1509
1510
GBool JBIG2Stream::readSymbolDictSeg(Guint segNum, Guint length,
1511
17.2k
             Guint *refSegs, Guint nRefSegs) {
1512
17.2k
  JBIG2SymbolDict *symbolDict;
1513
17.2k
  JBIG2HuffmanTable *huffDHTable, *huffDWTable;
1514
17.2k
  JBIG2HuffmanTable *huffBMSizeTable, *huffAggInstTable;
1515
17.2k
  JBIG2Segment *seg;
1516
17.2k
  GList *codeTables;
1517
17.2k
  JBIG2SymbolDict *inputSymbolDict;
1518
17.2k
  Guint flags, sdTemplate, sdrTemplate, huff, refAgg;
1519
17.2k
  Guint huffDH, huffDW, huffBMSize, huffAggInst;
1520
17.2k
  Guint contextUsed, contextRetained;
1521
17.2k
  int sdATX[4], sdATY[4], sdrATX[2], sdrATY[2];
1522
17.2k
  Guint numExSyms, numNewSyms, numInputSyms, symCodeLen;
1523
17.2k
  JBIG2Bitmap **bitmaps;
1524
17.2k
  JBIG2Bitmap *collBitmap, *refBitmap;
1525
17.2k
  Guint *symWidths;
1526
17.2k
  Guint symHeight, symWidth, totalWidth, x, symID;
1527
17.2k
  int dh, dw, refAggNum, refDX, refDY, bmSize;
1528
17.2k
  GBool ex;
1529
17.2k
  int run, prevRun, cnt;
1530
17.2k
  Guint i, j, k;
1531
1532
17.2k
  symWidths = NULL;
1533
1534
  // symbol dictionary flags
1535
17.2k
  if (!readUWord(&flags)) {
1536
0
    goto eofError;
1537
0
  }
1538
17.2k
  sdTemplate = (flags >> 10) & 3;
1539
17.2k
  sdrTemplate = (flags >> 12) & 1;
1540
17.2k
  huff = flags & 1;
1541
17.2k
  refAgg = (flags >> 1) & 1;
1542
17.2k
  huffDH = (flags >> 2) & 3;
1543
17.2k
  huffDW = (flags >> 4) & 3;
1544
17.2k
  huffBMSize = (flags >> 6) & 1;
1545
17.2k
  huffAggInst = (flags >> 7) & 1;
1546
17.2k
  contextUsed = (flags >> 8) & 1;
1547
17.2k
  contextRetained = (flags >> 9) & 1;
1548
1549
  // symbol dictionary AT flags
1550
17.2k
  if (!huff) {
1551
9.43k
    if (sdTemplate == 0) {
1552
7.54k
      if (!readByte(&sdATX[0]) ||
1553
7.54k
    !readByte(&sdATY[0]) ||
1554
7.54k
    !readByte(&sdATX[1]) ||
1555
7.54k
    !readByte(&sdATY[1]) ||
1556
7.54k
    !readByte(&sdATX[2]) ||
1557
7.54k
    !readByte(&sdATY[2]) ||
1558
7.54k
    !readByte(&sdATX[3]) ||
1559
7.54k
    !readByte(&sdATY[3])) {
1560
1.99k
  goto eofError;
1561
1.99k
      }
1562
7.54k
    } else {
1563
1.88k
      if (!readByte(&sdATX[0]) ||
1564
1.88k
    !readByte(&sdATY[0])) {
1565
134
  goto eofError;
1566
134
      }
1567
1.88k
    }
1568
9.43k
  }
1569
1570
  // symbol dictionary refinement AT flags
1571
15.1k
  if (refAgg && !sdrTemplate) {
1572
2.15k
    if (!readByte(&sdrATX[0]) ||
1573
2.15k
  !readByte(&sdrATY[0]) ||
1574
2.15k
  !readByte(&sdrATX[1]) ||
1575
2.15k
  !readByte(&sdrATY[1])) {
1576
144
      goto eofError;
1577
144
    }
1578
2.15k
  }
1579
1580
  // SDNUMEXSYMS and SDNUMNEWSYMS
1581
15.0k
  if (!readULong(&numExSyms) || !readULong(&numNewSyms)) {
1582
9
    goto eofError;
1583
9
  }
1584
1585
  // get referenced segments: input symbol dictionaries and code tables
1586
15.0k
  codeTables = new GList();
1587
15.0k
  numInputSyms = 0;
1588
113k
  for (i = 0; i < nRefSegs; ++i) {
1589
98.2k
    if ((seg = findSegment(refSegs[i]))) {
1590
5.58k
      if (seg->getType() == jbig2SegSymbolDict) {
1591
1.30k
  j = ((JBIG2SymbolDict *)seg)->getSize();
1592
1.30k
  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.30k
  numInputSyms += j;
1599
4.27k
      } else if (seg->getType() == jbig2SegCodeTable) {
1600
4.23k
  codeTables->append(seg);
1601
4.23k
      }
1602
5.58k
    }
1603
98.2k
  }
1604
15.0k
  if (numNewSyms > INT_MAX || numInputSyms > INT_MAX - numNewSyms) {
1605
4.44k
    error(errSyntaxError, getPos(),
1606
4.44k
    "Too many input symbols in JBIG2 symbol dictionary");
1607
4.44k
    delete codeTables;
1608
4.44k
    goto eofError;
1609
4.44k
  }
1610
1611
  // compute symbol code length
1612
10.5k
  i = numInputSyms + numNewSyms;
1613
10.5k
  if (i <= 1) {
1614
4.32k
    symCodeLen = huff ? 1 : 0;
1615
6.24k
  } else {
1616
6.24k
    --i;
1617
6.24k
    symCodeLen = 0;
1618
    // i = floor((numSyms-1) / 2^symCodeLen)
1619
74.3k
    while (i > 0) {
1620
68.1k
      ++symCodeLen;
1621
68.1k
      i >>= 1;
1622
68.1k
    }
1623
6.24k
  }
1624
1625
  // get the input symbol bitmaps
1626
10.5k
  bitmaps = (JBIG2Bitmap **)gmallocn(numInputSyms + numNewSyms,
1627
10.5k
             sizeof(JBIG2Bitmap *));
1628
277M
  for (i = 0; i < numInputSyms + numNewSyms; ++i) {
1629
277M
    bitmaps[i] = NULL;
1630
277M
  }
1631
10.5k
  k = 0;
1632
10.5k
  inputSymbolDict = NULL;
1633
15.1k
  for (i = 0; i < nRefSegs; ++i) {
1634
4.53k
    if ((seg = findSegment(refSegs[i]))) {
1635
3.85k
      if (seg->getType() == jbig2SegSymbolDict) {
1636
611
  inputSymbolDict = (JBIG2SymbolDict *)seg;
1637
611
  for (j = 0; j < inputSymbolDict->getSize(); ++j) {
1638
0
    bitmaps[k++] = inputSymbolDict->getBitmap(j);
1639
0
  }
1640
611
      }
1641
3.85k
    }
1642
4.53k
  }
1643
1644
  // get the Huffman tables
1645
10.5k
  huffDHTable = huffDWTable = NULL; // make gcc happy
1646
10.5k
  huffBMSizeTable = huffAggInstTable = NULL; // make gcc happy
1647
10.5k
  i = 0;
1648
10.5k
  if (huff) {
1649
3.74k
    if (huffDH == 0) {
1650
2.54k
      huffDHTable = huffTableD;
1651
2.54k
    } else if (huffDH == 1) {
1652
779
      huffDHTable = huffTableE;
1653
779
    } else {
1654
418
      if (i >= (Guint)codeTables->getLength()) {
1655
0
  goto codeTableError;
1656
0
      }
1657
418
      huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1658
418
    }
1659
3.74k
    if (huffDW == 0) {
1660
2.89k
      huffDWTable = huffTableB;
1661
2.89k
    } else if (huffDW == 1) {
1662
274
      huffDWTable = huffTableC;
1663
573
    } else {
1664
573
      if (i >= (Guint)codeTables->getLength()) {
1665
155
  goto codeTableError;
1666
155
      }
1667
418
      huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1668
418
    }
1669
3.58k
    if (huffBMSize == 0) {
1670
3.16k
      huffBMSizeTable = huffTableA;
1671
3.16k
    } else {
1672
418
      if (i >= (Guint)codeTables->getLength()) {
1673
0
  goto codeTableError;
1674
0
      }
1675
418
      huffBMSizeTable =
1676
418
    ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1677
418
    }
1678
3.58k
    if (huffAggInst == 0) {
1679
3.04k
      huffAggInstTable = huffTableA;
1680
3.04k
    } else {
1681
546
      if (i >= (Guint)codeTables->getLength()) {
1682
191
  goto codeTableError;
1683
191
      }
1684
355
      huffAggInstTable =
1685
355
    ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
1686
355
    }
1687
3.58k
  }
1688
10.2k
  delete codeTables;
1689
1690
  // set up the Huffman decoder
1691
10.2k
  if (huff) {
1692
3.39k
    huffDecoder->reset();
1693
1694
  // set up the arithmetic decoder
1695
6.82k
  } else {
1696
6.82k
    if (contextUsed && inputSymbolDict) {
1697
256
      resetGenericStats(sdTemplate, inputSymbolDict->getGenericRegionStats());
1698
6.57k
    } else {
1699
6.57k
      resetGenericStats(sdTemplate, NULL);
1700
6.57k
    }
1701
6.82k
    resetIntStats(symCodeLen);
1702
6.82k
    arithDecoder->start();
1703
6.82k
  }
1704
1705
  // set up the arithmetic decoder for refinement/aggregation
1706
10.2k
  if (refAgg) {
1707
2.35k
    if (contextUsed && inputSymbolDict) {
1708
356
      resetRefinementStats(sdrTemplate,
1709
356
         inputSymbolDict->getRefinementRegionStats());
1710
2.00k
    } else {
1711
2.00k
      resetRefinementStats(sdrTemplate, NULL);
1712
2.00k
    }
1713
2.35k
  }
1714
1715
  // allocate symbol widths storage
1716
10.2k
  if (huff && !refAgg) {
1717
2.16k
    symWidths = (Guint *)gmallocn(numNewSyms, sizeof(Guint));
1718
2.16k
  }
1719
1720
10.2k
  symHeight = 0;
1721
10.2k
  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
6.01k
      arithDecoder->decodeInt(&dh, iadhStats);
1729
6.01k
    }
1730
296k
    if ((dh <= 0 && (Guint)-dh >= symHeight) ||
1731
296k
  (dh > 0 && (Guint)dh > UINT_MAX - symHeight)) {
1732
194
      error(errSyntaxError, getPos(),
1733
194
      "Bad delta-height value in JBIG2 symbol dictionary");
1734
194
      goto syntaxError;
1735
194
    }
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
432k
    while (1) {
1750
1751
      // read the delta width
1752
432k
      if (huff) {
1753
347k
  if (!huffDecoder->decodeInt(&dw, huffDWTable)) {
1754
289k
    break;
1755
289k
  }
1756
347k
      } else {
1757
84.6k
  if (!arithDecoder->decodeInt(&dw, iadwStats)) {
1758
3.47k
    break;
1759
3.47k
  }
1760
84.6k
      }
1761
139k
      if ((dw <= 0 && (Guint)-dw >= symWidth) ||
1762
139k
    (dw > 0 && (Guint)dw > UINT_MAX - symWidth)) {
1763
772
  error(errSyntaxError, getPos(),
1764
772
        "Bad delta-height value in JBIG2 symbol dictionary");
1765
772
  goto syntaxError;
1766
772
      }
1767
139k
      symWidth += dw;
1768
139k
      if (i >= numNewSyms) {
1769
500
  error(errSyntaxError, getPos(),
1770
500
        "Too many symbols in JBIG2 symbol dictionary");
1771
500
  goto syntaxError;
1772
500
      }
1773
1774
      // sanity check to avoid extremely long run-times with damaged streams
1775
138k
      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
138k
      if (huff && !refAgg) {
1783
54.5k
  symWidths[i] = symWidth;
1784
54.5k
  totalWidth += symWidth;
1785
1786
      // refinement/aggregate coding
1787
84.0k
      } else if (refAgg) {
1788
55.0k
  if (huff) {
1789
3.39k
    if (!huffDecoder->decodeInt(&refAggNum, huffAggInstTable)) {
1790
0
      break;
1791
0
    }
1792
51.6k
  } else {
1793
51.6k
    if (!arithDecoder->decodeInt(&refAggNum, iaaiStats)) {
1794
162
      break;
1795
162
    }
1796
51.6k
  }
1797
54.8k
  if (refAggNum <= 0 || refAggNum > 10000) {
1798
630
    error(errSyntaxError, getPos(),
1799
630
    "Invalid refinement/aggregation instance count in JBIG2 symbol dictionary");
1800
630
    goto syntaxError;
1801
630
  }
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
54.2k
  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
54.1k
  } else {
1834
54.1k
    bitmaps[numInputSyms + i] =
1835
54.1k
        readTextRegion(huff, gTrue, symWidth, symHeight,
1836
54.1k
           refAggNum, 0, numInputSyms + i, NULL,
1837
54.1k
           symCodeLen, bitmaps, 0, 0, 0, 1, 0,
1838
54.1k
           huffTableF, huffTableH, huffTableK, huffTableO,
1839
54.1k
           huffTableO, huffTableO, huffTableO, huffTableA,
1840
54.1k
           sdrTemplate, sdrATX, sdrATY);
1841
54.1k
  }
1842
1843
      // non-ref/agg coding
1844
54.2k
      } 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
137k
      ++i;
1852
137k
    }
1853
1854
    // read the collective bitmap
1855
292k
    if (huff && !refAgg) {
1856
3.58k
      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.54k
      huffDecoder->decodeInt(&bmSize, huffBMSizeTable);
1862
2.54k
      huffDecoder->reset();
1863
2.54k
      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.24k
      } else {
1869
2.24k
  collBitmap = readGenericBitmap(gTrue, totalWidth, symHeight,
1870
2.24k
               0, gFalse, gFalse, NULL, NULL, NULL,
1871
2.24k
               bmSize);
1872
2.24k
      }
1873
2.54k
      x = 0;
1874
56.8k
      for (; j < i; ++j) {
1875
54.2k
  bitmaps[numInputSyms + j] =
1876
54.2k
      collBitmap->getSlice(x, 0, symWidths[j], symHeight);
1877
54.2k
  x += symWidths[j];
1878
54.2k
      }
1879
2.54k
      delete collBitmap;
1880
2.54k
    }
1881
292k
  }
1882
1883
  // create the symbol dict object
1884
5.39k
  symbolDict = new JBIG2SymbolDict(segNum, numExSyms);
1885
1886
  // exported symbol list
1887
5.39k
  i = j = 0;
1888
5.39k
  ex = gFalse;
1889
5.39k
  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.58k
  if (j != numExSyms) {
1922
259
    error(errSyntaxError, getPos(), "Too few symbols in JBIG2 symbol dictionary");
1923
259
    delete symbolDict;
1924
259
    goto syntaxError;
1925
259
  }
1926
1927
4.46k
  for (i = 0; i < numNewSyms; ++i) {
1928
139
    delete bitmaps[numInputSyms + i];
1929
139
  }
1930
4.32k
  gfree(bitmaps);
1931
4.32k
  if (symWidths) {
1932
0
    gfree(symWidths);
1933
0
  }
1934
1935
  // save the arithmetic decoder stats
1936
4.32k
  if (!huff && contextRetained) {
1937
572
    symbolDict->setGenericRegionStats(genericRegionStats->copy());
1938
572
    if (refAgg) {
1939
428
      symbolDict->setRefinementRegionStats(refinementRegionStats->copy());
1940
428
    }
1941
572
  }
1942
1943
  // store the new symbol dict
1944
4.32k
  segments->append(symbolDict);
1945
1946
4.32k
  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.24k
 syntaxError:
1953
277M
  for (i = 0; i < numNewSyms; ++i) {
1954
277M
    if (bitmaps[numInputSyms + i]) {
1955
137k
      delete bitmaps[numInputSyms + i];
1956
137k
    }
1957
277M
  }
1958
6.24k
  gfree(bitmaps);
1959
6.24k
  if (symWidths) {
1960
1.57k
    gfree(symWidths);
1961
1.57k
  }
1962
6.24k
  return gFalse;
1963
1964
6.72k
 eofError:
1965
6.72k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
1966
6.72k
  return gFalse;
1967
346
}
1968
1969
void JBIG2Stream::readTextRegionSeg(Guint segNum, GBool imm,
1970
            GBool lossless, Guint length,
1971
7.43k
            Guint *refSegs, Guint nRefSegs) {
1972
7.43k
  JBIG2Bitmap *bitmap;
1973
7.43k
  JBIG2HuffmanTable runLengthTab[36];
1974
7.43k
  JBIG2HuffmanTable *symCodeTab;
1975
7.43k
  JBIG2HuffmanTable *huffFSTable, *huffDSTable, *huffDTTable;
1976
7.43k
  JBIG2HuffmanTable *huffRDWTable, *huffRDHTable;
1977
7.43k
  JBIG2HuffmanTable *huffRDXTable, *huffRDYTable, *huffRSizeTable;
1978
7.43k
  JBIG2Segment *seg;
1979
7.43k
  GList *codeTables;
1980
7.43k
  JBIG2SymbolDict *symbolDict;
1981
7.43k
  JBIG2Bitmap **syms;
1982
7.43k
  Guint w, h, x, y, segInfoFlags, extCombOp;
1983
7.43k
  Guint flags, huff, refine, logStrips, refCorner, transposed;
1984
7.43k
  Guint combOp, defPixel, templ;
1985
7.43k
  int sOffset;
1986
7.43k
  Guint huffFlags, huffFS, huffDS, huffDT;
1987
7.43k
  Guint huffRDW, huffRDH, huffRDX, huffRDY, huffRSize;
1988
7.43k
  Guint numInstances, numSyms, symCodeLen;
1989
7.43k
  int atx[2], aty[2];
1990
7.43k
  Guint i, k, kk;
1991
7.43k
  int j;
1992
1993
  // region segment info field
1994
7.43k
  if (!readULong(&w) || !readULong(&h) ||
1995
7.43k
      !readULong(&x) || !readULong(&y) ||
1996
7.43k
      !readUByte(&segInfoFlags)) {
1997
1.89k
    goto eofError;
1998
1.89k
  }
1999
5.54k
  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.75k
  if (w / 10 > pageW || h / 10 > pageH ||
2006
4.75k
      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.15k
  extCombOp = segInfoFlags & 7;
2013
2014
  // rest of the text region header
2015
4.15k
  if (!readUWord(&flags)) {
2016
0
    goto eofError;
2017
0
  }
2018
4.15k
  huff = flags & 1;
2019
4.15k
  refine = (flags >> 1) & 1;
2020
4.15k
  logStrips = (flags >> 2) & 3;
2021
4.15k
  refCorner = (flags >> 4) & 3;
2022
4.15k
  transposed = (flags >> 6) & 1;
2023
4.15k
  combOp = (flags >> 7) & 3;
2024
4.15k
  defPixel = (flags >> 9) & 1;
2025
4.15k
  sOffset = (flags >> 10) & 0x1f;
2026
4.15k
  if (sOffset & 0x10) {
2027
2.33k
    sOffset |= -1 - 0x0f;
2028
2.33k
  }
2029
4.15k
  templ = (flags >> 15) & 1;
2030
4.15k
  huffFS = huffDS = huffDT = 0; // make gcc happy
2031
4.15k
  huffRDW = huffRDH = huffRDX = huffRDY = huffRSize = 0; // make gcc happy
2032
4.15k
  if (huff) {
2033
2.67k
    if (!readUWord(&huffFlags)) {
2034
128
      goto eofError;
2035
128
    }
2036
2.54k
    huffFS = huffFlags & 3;
2037
2.54k
    huffDS = (huffFlags >> 2) & 3;
2038
2.54k
    huffDT = (huffFlags >> 4) & 3;
2039
2.54k
    huffRDW = (huffFlags >> 6) & 3;
2040
2.54k
    huffRDH = (huffFlags >> 8) & 3;
2041
2.54k
    huffRDX = (huffFlags >> 10) & 3;
2042
2.54k
    huffRDY = (huffFlags >> 12) & 3;
2043
2.54k
    huffRSize = (huffFlags >> 14) & 1;
2044
2.54k
  }
2045
4.02k
  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.37k
  if (!readULong(&numInstances)) {
2052
0
    goto eofError;
2053
0
  }
2054
2055
  // get symbol dictionaries and tables
2056
3.37k
  codeTables = new GList();
2057
3.37k
  numSyms = 0;
2058
5.62k
  for (i = 0; i < nRefSegs; ++i) {
2059
2.96k
    if ((seg = findSegment(refSegs[i]))) {
2060
2.25k
      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.98k
      } else if (seg->getType() == jbig2SegCodeTable) {
2070
1.98k
  codeTables->append(seg);
2071
1.98k
      }
2072
2.25k
    } else {
2073
710
      error(errSyntaxError, getPos(),
2074
710
      "Invalid segment reference in JBIG2 text region");
2075
710
      delete codeTables;
2076
710
      return;
2077
710
    }
2078
2.96k
  }
2079
2.66k
  i = numSyms;
2080
2.66k
  if (i <= 1) {
2081
2.66k
    symCodeLen = huff ? 1 : 0;
2082
2.66k
  } 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.66k
  syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *));
2094
2.66k
  kk = 0;
2095
4.83k
  for (i = 0; i < nRefSegs; ++i) {
2096
2.16k
    if ((seg = findSegment(refSegs[i]))) {
2097
2.16k
      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.16k
    }
2104
2.16k
  }
2105
2106
  // get the Huffman tables
2107
2.66k
  huffFSTable = huffDSTable = huffDTTable = NULL; // make gcc happy
2108
2.66k
  huffRDWTable = huffRDHTable = NULL; // make gcc happy
2109
2.66k
  huffRDXTable = huffRDYTable = huffRSizeTable = NULL; // make gcc happy
2110
2.66k
  i = 0;
2111
2.66k
  if (huff) {
2112
2.26k
    if (huffFS == 0) {
2113
585
      huffFSTable = huffTableF;
2114
1.67k
    } else if (huffFS == 1) {
2115
1.15k
      huffFSTable = huffTableG;
2116
1.15k
    } else {
2117
522
      if (i >= (Guint)codeTables->getLength()) {
2118
131
  goto codeTableError;
2119
131
      }
2120
391
      huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2121
391
    }
2122
2.13k
    if (huffDS == 0) {
2123
1.00k
      huffDSTable = huffTableH;
2124
1.13k
    } else if (huffDS == 1) {
2125
339
      huffDSTable = huffTableI;
2126
791
    } else if (huffDS == 2) {
2127
290
      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.98k
    if (huffDT == 0) {
2135
814
      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.83k
    if (huffRDW == 0) {
2147
814
      huffRDWTable = huffTableN;
2148
1.01k
    } else if (huffRDW == 1) {
2149
624
      huffRDWTable = huffTableO;
2150
624
    } else {
2151
395
      if (i >= (Guint)codeTables->getLength()) {
2152
148
  goto codeTableError;
2153
148
      }
2154
247
      huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2155
247
    }
2156
1.68k
    if (huffRDH == 0) {
2157
243
      huffRDHTable = huffTableN;
2158
1.44k
    } else if (huffRDH == 1) {
2159
890
      huffRDHTable = huffTableO;
2160
890
    } else {
2161
552
      if (i >= (Guint)codeTables->getLength()) {
2162
289
  goto codeTableError;
2163
289
      }
2164
263
      huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2165
263
    }
2166
1.39k
    if (huffRDX == 0) {
2167
592
      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
966
    if (huffRDY == 0) {
2177
233
      huffRDYTable = huffTableN;
2178
733
    } else if (huffRDY == 1) {
2179
176
      huffRDYTable = huffTableO;
2180
557
    } else {
2181
557
      if (i >= (Guint)codeTables->getLength()) {
2182
345
  goto codeTableError;
2183
345
      }
2184
212
      huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2185
212
    }
2186
621
    if (huffRSize == 0) {
2187
90
      huffRSizeTable = huffTableA;
2188
531
    } else {
2189
531
      if (i >= (Guint)codeTables->getLength()) {
2190
465
  goto codeTableError;
2191
465
      }
2192
66
      huffRSizeTable =
2193
66
    ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
2194
66
    }
2195
621
  }
2196
561
  delete codeTables;
2197
2198
  // symbol ID Huffman decoding table
2199
561
  if (huff) {
2200
156
    huffDecoder->reset();
2201
5.14k
    for (i = 0; i < 32; ++i) {
2202
4.99k
      runLengthTab[i].val = i;
2203
4.99k
      runLengthTab[i].prefixLen = huffDecoder->readBits(4);
2204
4.99k
      runLengthTab[i].rangeLen = 0;
2205
4.99k
      runLengthTab[i].prefix = 0;
2206
4.99k
    }
2207
156
    runLengthTab[32].val = 0x103;
2208
156
    runLengthTab[32].prefixLen = huffDecoder->readBits(4);
2209
156
    runLengthTab[32].rangeLen = 2;
2210
156
    runLengthTab[32].prefix = 0;
2211
156
    runLengthTab[33].val = 0x203;
2212
156
    runLengthTab[33].prefixLen = huffDecoder->readBits(4);
2213
156
    runLengthTab[33].rangeLen = 3;
2214
156
    runLengthTab[33].prefix = 0;
2215
156
    runLengthTab[34].val = 0x20b;
2216
156
    runLengthTab[34].prefixLen = huffDecoder->readBits(4);
2217
156
    runLengthTab[34].rangeLen = 7;
2218
156
    runLengthTab[34].prefix = 0;
2219
156
    runLengthTab[35].prefixLen = 0;
2220
156
    runLengthTab[35].rangeLen = jbig2HuffmanEOT;
2221
156
    runLengthTab[35].prefix = 0;
2222
156
    huffDecoder->buildTable(runLengthTab, 35);
2223
156
    symCodeTab = (JBIG2HuffmanTable *)gmallocn(numSyms + 1,
2224
156
                 sizeof(JBIG2HuffmanTable));
2225
156
    for (i = 0; i < numSyms; ++i) {
2226
0
      symCodeTab[i].val = i;
2227
0
      symCodeTab[i].rangeLen = 0;
2228
0
    }
2229
156
    i = 0;
2230
156
    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
156
    symCodeTab[numSyms].prefixLen = 0;
2252
156
    symCodeTab[numSyms].rangeLen = jbig2HuffmanEOT;
2253
156
    huffDecoder->buildTable(symCodeTab, numSyms);
2254
156
    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
561
  if (refine) {
2263
194
    resetRefinementStats(templ, NULL);
2264
194
  }
2265
2266
561
  bitmap = readTextRegion(huff, refine, w, h, numInstances,
2267
561
        logStrips, numSyms, symCodeTab, symCodeLen, syms,
2268
561
        defPixel, combOp, transposed, refCorner, sOffset,
2269
561
        huffFSTable, huffDSTable, huffDTTable,
2270
561
        huffRDWTable, huffRDHTable,
2271
561
        huffRDXTable, huffRDYTable, huffRSizeTable,
2272
561
        templ, atx, aty);
2273
2274
561
  gfree(syms);
2275
2276
  // combine the region bitmap into the page bitmap
2277
561
  if (imm) {
2278
156
    if (pageH == 0xffffffff && y + h > curPageH) {
2279
56
      pageBitmap->expand(y + h, pageDefPixel);
2280
56
    }
2281
156
    pageBitmap->combine(bitmap, x, y, extCombOp);
2282
156
    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
561
  if (huff) {
2292
156
    gfree(symCodeTab);
2293
156
  }
2294
2295
561
  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
561
}
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
54.7k
           int *atx, int *aty) {
2329
54.7k
  JBIG2Bitmap *bitmap;
2330
54.7k
  JBIG2Bitmap *symbolBitmap;
2331
54.7k
  Guint strips;
2332
54.7k
  int t, dt, tt, s, ds, sFirst, j;
2333
54.7k
  int rdw, rdh, rdx, rdy, ri, refDX, refDY, bmSize;
2334
54.7k
  Guint symID, inst, bw, bh;
2335
2336
54.7k
  strips = 1 << logStrips;
2337
2338
  // allocate the bitmap
2339
54.7k
  bitmap = new JBIG2Bitmap(0, w, h);
2340
54.7k
  if (defPixel) {
2341
34
    bitmap->clearToOne();
2342
54.6k
  } else {
2343
54.6k
    bitmap->clearToZero();
2344
54.6k
  }
2345
2346
  // decode initial T value
2347
54.7k
  if (huff) {
2348
3.26k
    huffDecoder->decodeInt(&t, huffDTTable);
2349
51.4k
  } else {
2350
51.4k
    arithDecoder->decodeInt(&t, iadtStats);
2351
51.4k
  }
2352
54.7k
  t *= -(int)strips;
2353
2354
54.7k
  inst = 0;
2355
54.7k
  sFirst = 0;
2356
113k
  while (inst < numInstances) {
2357
2358
    // decode delta-T
2359
99.6k
    if (huff) {
2360
28.0k
      if (!huffDecoder->decodeInt(&dt, huffDTTable)) {
2361
38
  break;
2362
38
      }
2363
71.6k
    } else {
2364
71.6k
      if (!arithDecoder->decodeInt(&dt, iadtStats)) {
2365
34.8k
  break;
2366
34.8k
      }
2367
71.6k
    }
2368
64.7k
    t += dt * strips;
2369
2370
    // first S value
2371
64.7k
    if (huff) {
2372
27.9k
      if (!huffDecoder->decodeInt(&ds, huffFSTable)) {
2373
28
  break;
2374
28
      }
2375
36.7k
    } else {
2376
36.7k
      if (!arithDecoder->decodeInt(&ds, iafsStats)) {
2377
5.85k
  break;
2378
5.85k
      }
2379
36.7k
    }
2380
58.8k
    sFirst += ds;
2381
58.8k
    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
468k
    while (inst < numInstances) {
2387
2388
      // T value
2389
455k
      if (strips == 1) {
2390
446k
  dt = 0;
2391
446k
      } else if (huff) {
2392
9.18k
  dt = huffDecoder->readBits(logStrips);
2393
9.18k
      } else {
2394
0
  arithDecoder->decodeInt(&dt, iaitStats);
2395
0
      }
2396
455k
      tt = t + dt;
2397
2398
      // symbol ID
2399
455k
      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
326k
      } else {
2407
326k
  symID = arithDecoder->decodeIAID(symCodeLen, iaidStats);
2408
326k
      }
2409
2410
455k
      if (symID >= (Guint)numSyms) {
2411
397k
  error(errSyntaxError, getPos(),
2412
397k
        "Invalid symbol number in JBIG2 text region");
2413
397k
      } else {
2414
2415
  // get the symbol bitmap
2416
58.4k
  symbolBitmap = NULL;
2417
58.4k
  if (refine) {
2418
58.4k
    if (huff) {
2419
18.9k
      ri = (int)huffDecoder->readBit();
2420
39.5k
    } else {
2421
39.5k
      arithDecoder->decodeInt(&ri, iariStats);
2422
39.5k
    }
2423
58.4k
  } else {
2424
0
    ri = 0;
2425
0
  }
2426
58.4k
  if (ri) {
2427
41.9k
    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
39.3k
    } else {
2436
39.3k
      arithDecoder->decodeInt(&rdw, iardwStats);
2437
39.3k
      arithDecoder->decodeInt(&rdh, iardhStats);
2438
39.3k
      arithDecoder->decodeInt(&rdx, iardxStats);
2439
39.3k
      arithDecoder->decodeInt(&rdy, iardyStats);
2440
39.3k
    }
2441
41.9k
    refDX = ((rdw >= 0) ? rdw : rdw - 1) / 2 + rdx;
2442
41.9k
    refDY = ((rdh >= 0) ? rdh : rdh - 1) / 2 + rdy;
2443
2444
41.9k
    if (rdw > INT_MAX - syms[symID]->getWidth() ||
2445
41.9k
        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.8k
    if (rdw > 1000 || rdh > 1000) {
2452
737
      error(errSyntaxError, getPos(),
2453
737
      "Invalid refinement size in JBIG2 text region");
2454
737
      continue;
2455
737
    }
2456
41.1k
    symbolBitmap =
2457
41.1k
      readGenericRefinementRegion(rdw + syms[symID]->getWidth(),
2458
41.1k
          rdh + syms[symID]->getHeight(),
2459
41.1k
          templ, gFalse, syms[symID],
2460
41.1k
          refDX, refDY, atx, aty);
2461
    //~ do we need to use the bmSize value here (in Huffman mode)?
2462
41.1k
  } 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.6k
  bw = symbolBitmap->getWidth() - 1;
2470
57.6k
  bh = symbolBitmap->getHeight() - 1;
2471
57.6k
  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.6k
  } else {
2488
57.6k
    switch (refCorner) {
2489
0
    case 0: // bottom left
2490
0
      bitmap->combine(symbolBitmap, s, tt - bh, combOp);
2491
0
      break;
2492
57.6k
    case 1: // top left
2493
57.6k
      bitmap->combine(symbolBitmap, s, tt, combOp);
2494
57.6k
      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.6k
    }
2502
57.6k
    s += bw;
2503
57.6k
  }
2504
57.6k
  if (ri) {
2505
41.1k
    delete symbolBitmap;
2506
41.1k
  }
2507
57.6k
      }
2508
2509
      // next instance
2510
454k
      ++inst;
2511
2512
      // next S value
2513
454k
      if (huff) {
2514
129k
  if (!huffDecoder->decodeInt(&ds, huffDSTable)) {
2515
25.3k
    break;
2516
25.3k
  }
2517
325k
      } else {
2518
325k
  if (!arithDecoder->decodeInt(&ds, iadsStats)) {
2519
20.6k
    break;
2520
20.6k
  }
2521
325k
      }
2522
408k
      s += sOffset + ds;
2523
408k
    }
2524
58.8k
  }
2525
2526
54.7k
  return bitmap;
2527
54.7k
}
2528
2529
1.53k
void JBIG2Stream::readPatternDictSeg(Guint segNum, Guint length) {
2530
1.53k
  JBIG2PatternDict *patternDict;
2531
1.53k
  JBIG2Bitmap *bitmap;
2532
1.53k
  Guint flags, patternW, patternH, grayMax, templ, mmr;
2533
1.53k
  int atx[4], aty[4];
2534
1.53k
  Guint i, x;
2535
2536
  // halftone dictionary flags, pattern width and height, max gray value
2537
1.53k
  if (!readUByte(&flags) ||
2538
1.53k
      !readUByte(&patternW) ||
2539
1.53k
      !readUByte(&patternH) ||
2540
1.53k
      !readULong(&grayMax)) {
2541
856
    goto eofError;
2542
856
  }
2543
683
  if (patternW == 0 || patternH == 0 ||
2544
683
      grayMax > UINT_MAX / patternW - 1) {
2545
552
    error(errSyntaxError, getPos(),
2546
552
    "Bad size in JBIG2 pattern dictionary segment");
2547
552
    return;
2548
552
  }
2549
131
  templ = (flags >> 1) & 3;
2550
131
  mmr = flags & 1;
2551
2552
  // set up the arithmetic decoder
2553
131
  if (!mmr) {
2554
126
    resetGenericStats(templ, NULL);
2555
126
    arithDecoder->start();
2556
126
  }
2557
2558
  // read the bitmap
2559
131
  atx[0] = -(int)patternW; aty[0] =  0;
2560
131
  atx[1] = -3;             aty[1] = -1;
2561
131
  atx[2] =  2;             aty[2] = -2;
2562
131
  atx[3] = -2;             aty[3] = -2;
2563
131
  bitmap = readGenericBitmap(mmr, (grayMax + 1) * patternW, patternH,
2564
131
           templ, gFalse, gFalse, NULL,
2565
131
           atx, aty, length - 7);
2566
2567
  // create the pattern dict object
2568
131
  patternDict = new JBIG2PatternDict(segNum, grayMax + 1);
2569
2570
  // split up the bitmap
2571
131
  x = 0;
2572
340
  for (i = 0; i <= grayMax; ++i) {
2573
209
    patternDict->setBitmap(i, bitmap->getSlice(x, 0, patternW, patternH));
2574
209
    x += patternW;
2575
209
  }
2576
2577
  // free memory
2578
131
  delete bitmap;
2579
2580
  // store the new pattern dict
2581
131
  segments->append(patternDict);
2582
2583
131
  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
5.73k
          Guint *refSegs, Guint nRefSegs) {
2592
5.73k
  JBIG2Bitmap *bitmap;
2593
5.73k
  JBIG2Segment *seg;
2594
5.73k
  JBIG2PatternDict *patternDict;
2595
5.73k
  JBIG2Bitmap *skipBitmap;
2596
5.73k
  Guint *grayImg;
2597
5.73k
  JBIG2Bitmap *grayBitmap;
2598
5.73k
  JBIG2Bitmap *patternBitmap;
2599
5.73k
  Guint w, h, x, y, segInfoFlags, extCombOp;
2600
5.73k
  Guint flags, mmr, templ, enableSkip, combOp;
2601
5.73k
  Guint gridW, gridH, stepX, stepY, patW, patH;
2602
5.73k
  int atx[4], aty[4];
2603
5.73k
  int gridX, gridY, xx, yy, bit, j;
2604
5.73k
  Guint bpp, m, n, i;
2605
2606
  // region segment info field
2607
5.73k
  if (!readULong(&w) || !readULong(&h) ||
2608
5.73k
      !readULong(&x) || !readULong(&y) ||
2609
5.73k
      !readUByte(&segInfoFlags)) {
2610
601
    goto eofError;
2611
601
  }
2612
  // sanity check: if the w/h/x/y values are way out of range, it likely
2613
  // indicates a damaged JBIG2 stream
2614
5.12k
  if (w / 10 > pageW || h / 10 > pageH ||
2615
5.12k
      x / 10 > pageW || y / 10 > pageH) {
2616
2.36k
    error(errSyntaxError, getPos(),
2617
2.36k
    "Bad size or position in JBIG2 halftone region segment");
2618
2.36k
    done = gTrue;
2619
2.36k
    return;
2620
2.36k
  }
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
620
 eofError:
2763
620
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
2764
620
}
2765
2766
void JBIG2Stream::readGenericRegionSeg(Guint segNum, GBool imm,
2767
6.67k
               GBool lossless, Guint length) {
2768
6.67k
  JBIG2Bitmap *bitmap;
2769
6.67k
  Guint w, h, x, y, segInfoFlags, extCombOp, rowCount;
2770
6.67k
  Guint flags, mmr, templ, tpgdOn;
2771
6.67k
  int atx[4], aty[4];
2772
2773
  // region segment info field
2774
6.67k
  if (!readULong(&w) || !readULong(&h) ||
2775
6.67k
      !readULong(&x) || !readULong(&y) ||
2776
6.67k
      !readUByte(&segInfoFlags)) {
2777
3.09k
    goto eofError;
2778
3.09k
  }
2779
3.57k
  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.15k
  extCombOp = segInfoFlags & 7;
2794
2795
  // rest of the generic region segment header
2796
3.15k
  if (!readUByte(&flags)) {
2797
149
    goto eofError;
2798
149
  }
2799
3.00k
  mmr = flags & 1;
2800
3.00k
  templ = (flags >> 1) & 3;
2801
3.00k
  tpgdOn = (flags >> 3) & 1;
2802
2803
  // AT flags
2804
3.00k
  if (!mmr) {
2805
2.70k
    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
778
      if (!readByte(&atx[0]) ||
2818
778
    !readByte(&aty[0])) {
2819
128
  goto eofError;
2820
128
      }
2821
778
    }
2822
2.70k
  }
2823
2824
  // set up the arithmetic decoder
2825
1.91k
  if (!mmr) {
2826
1.61k
    resetGenericStats(templ, NULL);
2827
1.61k
    arithDecoder->start();
2828
1.61k
  }
2829
2830
  // read the bitmap
2831
1.91k
  bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
2832
1.91k
           NULL, atx, aty, mmr ? length - 18 : 0);
2833
2834
  // combine the region bitmap into the page bitmap
2835
1.91k
  if (imm) {
2836
1.64k
    if (pageH == 0xffffffff && y + h > curPageH) {
2837
695
      pageBitmap->expand(y + h, pageDefPixel);
2838
695
    }
2839
1.64k
    pageBitmap->combine(bitmap, x, y, extCombOp);
2840
1.64k
    delete bitmap;
2841
2842
  // store the region bitmap
2843
1.64k
  } else {
2844
277
    bitmap->setSegNum(segNum);
2845
277
    segments->append(bitmap);
2846
277
  }
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.91k
  if (imm && length == 0xffffffff) {
2851
44
    readULong(&rowCount);
2852
44
  }
2853
2854
1.91k
  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.6k
      error(errSyntaxError, getPos(),
2865
14.6k
            "JBIG2 MMR row is wrong length ({0:d})", a1);
2866
14.6k
      a1 = w;
2867
14.6k
    }
2868
57.9M
    if ((*a0i & 1) ^ blackPixels) {
2869
95.6k
      ++*a0i;
2870
95.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.6k
           int *codingLine, int *a0i, int w) {
2877
25.6k
  if (a1 > codingLine[*a0i]) {
2878
16.5k
    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
16.5k
    if ((*a0i & 1) ^ blackPixels) {
2884
11.9k
      ++*a0i;
2885
11.9k
    }
2886
16.5k
    codingLine[*a0i] = a1;
2887
16.5k
  } else if (a1 < codingLine[*a0i]) {
2888
6.21k
    if (a1 < 0) {
2889
1.75k
      error(errSyntaxError, getPos(), "Invalid JBIG2 MMR code");
2890
1.75k
      a1 = 0;
2891
1.75k
    }
2892
9.05k
    while (*a0i > 0 && a1 <= codingLine[*a0i - 1]) {
2893
2.83k
      --*a0i;
2894
2.83k
    }
2895
6.21k
    codingLine[*a0i] = a1;
2896
6.21k
  }
2897
25.6k
}
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.3k
              int mmrDataLength) {
2904
33.3k
  JBIG2Bitmap *bitmap;
2905
33.3k
  GBool ltp;
2906
33.3k
  Guint ltpCX, cx, cx0, cx1, cx2;
2907
33.3k
  int *refLine, *codingLine;
2908
33.3k
  int code1, code2, code3;
2909
33.3k
  Guchar *p0, *p1, *p2, *pp;
2910
33.3k
  Guchar *atP0, *atP1, *atP2, *atP3;
2911
33.3k
  Guint buf0, buf1, buf2;
2912
33.3k
  Guint atBuf0, atBuf1, atBuf2, atBuf3;
2913
33.3k
  int atShift0, atShift1, atShift2, atShift3;
2914
33.3k
  Guchar mask;
2915
33.3k
  int x, y, x0, x1, a0i, b1i, blackPixels, pix, i;
2916
2917
33.3k
  bitmap = new JBIG2Bitmap(0, w, h);
2918
33.3k
  bitmap->clearToZero();
2919
2920
  //----- MMR decode
2921
2922
33.3k
  if (mmr) {
2923
2924
2.55k
    mmrDecoder->reset();
2925
2.55k
    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.55k
    codingLine = (int *)gmallocn(w + 1, sizeof(int));
2935
2.55k
    refLine = (int *)gmallocn(w + 3, sizeof(int));
2936
2.55k
    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
103k
  refLine[i] = codingLine[i];
2943
103k
      }
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.25k
  case twoDimPass:
2963
7.25k
          mmrAddPixels(refLine[b1i + 1], blackPixels, codingLine, &a0i, w);
2964
7.25k
          if (refLine[b1i + 1] < w) {
2965
3.00k
            b1i += 2;
2966
3.00k
          }
2967
7.25k
          break;
2968
20.4k
  case twoDimHoriz:
2969
20.4k
          code1 = code2 = 0;
2970
20.4k
          if (blackPixels) {
2971
8.23k
            do {
2972
8.23k
              code1 += code3 = mmrDecoder->getBlackCode();
2973
8.23k
            } while (code3 >= 64);
2974
10.3k
            do {
2975
10.3k
              code2 += code3 = mmrDecoder->getWhiteCode();
2976
10.3k
            } while (code3 >= 64);
2977
12.3k
          } else {
2978
13.0k
            do {
2979
13.0k
              code1 += code3 = mmrDecoder->getWhiteCode();
2980
13.0k
            } while (code3 >= 64);
2981
12.6k
            do {
2982
12.6k
              code2 += code3 = mmrDecoder->getBlackCode();
2983
12.6k
            } while (code3 >= 64);
2984
12.3k
          }
2985
20.4k
          mmrAddPixels(codingLine[a0i] + code1, blackPixels,
2986
20.4k
           codingLine, &a0i, w);
2987
20.4k
          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
10.9k
            b1i += 2;
2993
10.9k
          }
2994
20.4k
          break;
2995
1.88k
  case twoDimVertR3:
2996
1.88k
          mmrAddPixels(refLine[b1i] + 3, blackPixels, codingLine, &a0i, w);
2997
1.88k
          blackPixels ^= 1;
2998
1.88k
          if (codingLine[a0i] < w) {
2999
1.75k
            ++b1i;
3000
2.03k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3001
278
              b1i += 2;
3002
278
            }
3003
1.75k
          }
3004
1.88k
          break;
3005
1.06k
  case twoDimVertR2:
3006
1.06k
          mmrAddPixels(refLine[b1i] + 2, blackPixels, codingLine, &a0i, w);
3007
1.06k
          blackPixels ^= 1;
3008
1.06k
          if (codingLine[a0i] < w) {
3009
778
            ++b1i;
3010
907
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3011
129
              b1i += 2;
3012
129
            }
3013
778
          }
3014
1.06k
          break;
3015
14.3k
  case twoDimVertR1:
3016
14.3k
          mmrAddPixels(refLine[b1i] + 1, blackPixels, codingLine, &a0i, w);
3017
14.3k
          blackPixels ^= 1;
3018
14.3k
          if (codingLine[a0i] < w) {
3019
4.80k
            ++b1i;
3020
5.05k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3021
250
              b1i += 2;
3022
250
            }
3023
4.80k
          }
3024
14.3k
          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
53.7k
            ++b1i;
3030
53.7k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3031
0
              b1i += 2;
3032
0
            }
3033
53.7k
          }
3034
57.7M
          break;
3035
9.23k
  case twoDimVertL3:
3036
9.23k
          mmrAddPixelsNeg(refLine[b1i] - 3, blackPixels, codingLine, &a0i, w);
3037
9.23k
          blackPixels ^= 1;
3038
9.23k
          if (codingLine[a0i] < w) {
3039
9.23k
            if (b1i > 0) {
3040
7.34k
              --b1i;
3041
7.34k
            } else {
3042
1.88k
              ++b1i;
3043
1.88k
            }
3044
13.5k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3045
4.36k
              b1i += 2;
3046
4.36k
            }
3047
9.23k
          }
3048
9.23k
          break;
3049
6.40k
  case twoDimVertL2:
3050
6.40k
          mmrAddPixelsNeg(refLine[b1i] - 2, blackPixels, codingLine, &a0i, w);
3051
6.40k
          blackPixels ^= 1;
3052
6.40k
          if (codingLine[a0i] < w) {
3053
6.40k
            if (b1i > 0) {
3054
5.28k
              --b1i;
3055
5.28k
            } else {
3056
1.11k
              ++b1i;
3057
1.11k
            }
3058
9.75k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3059
3.35k
              b1i += 2;
3060
3.35k
            }
3061
6.40k
          }
3062
6.40k
          break;
3063
9.98k
  case twoDimVertL1:
3064
9.98k
          mmrAddPixelsNeg(refLine[b1i] - 1, blackPixels, codingLine, &a0i, w);
3065
9.98k
          blackPixels ^= 1;
3066
9.98k
          if (codingLine[a0i] < w) {
3067
9.98k
            if (b1i > 0) {
3068
5.82k
              --b1i;
3069
5.82k
            } else {
3070
4.16k
              ++b1i;
3071
4.16k
            }
3072
15.5k
            while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
3073
5.54k
              b1i += 2;
3074
5.54k
            }
3075
9.98k
          }
3076
9.98k
          break;
3077
95.3k
  case EOF:
3078
95.3k
          mmrAddPixels(w, 0, codingLine, &a0i, w);
3079
95.3k
          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.30M
  for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
3095
1.24M
    bitmap->setPixel(x, y);
3096
1.24M
  }
3097
59.2k
  if (codingLine[i+1] >= w) {
3098
13.7k
    break;
3099
13.7k
  }
3100
45.4k
  i += 2;
3101
45.4k
      }
3102
57.8M
    }
3103
3104
2.55k
    if (mmrDataLength >= 0) {
3105
2.23k
      mmrDecoder->skipTo(mmrDataLength);
3106
2.23k
    } else {
3107
316
      if (mmrDecoder->get24Bits() != 0x001001) {
3108
187
  error(errSyntaxError, getPos(),
3109
187
        "Missing EOFB in JBIG2 MMR bitmap data");
3110
187
      }
3111
316
    }
3112
3113
2.55k
    gfree(refLine);
3114
2.55k
    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
530
      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
283
      case 3:
3133
283
  ltpCX = 0x18b; // 01100 0101 1
3134
283
  break;
3135
530
      }
3136
530
    }
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
274k
      if (tpgdOn) {
3144
177k
  if (arithDecoder->decodeBit(ltpCX, genericRegionStats)) {
3145
53.8k
    ltp = !ltp;
3146
53.8k
  }
3147
177k
  if (ltp) {
3148
85.2k
    if (y > 0) {
3149
85.2k
      bitmap->duplicateRow(y, y-1);
3150
85.2k
    }
3151
85.2k
    continue;
3152
85.2k
  }
3153
177k
      }
3154
3155
189k
      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
126k
    p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
3163
126k
    buf1 = *p1++ << 8;
3164
126k
    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
126k
  } 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
532
      atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
3183
532
      atBuf0 = *atP0++ << 8;
3184
532
    } 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
260
      atP1 = NULL;
3194
260
      atBuf1 = 0;
3195
260
    }
3196
1.05k
    atShift1 = 15 - atx[1];
3197
1.05k
    if (aty[2] <= 0 && y + aty[2] >= 0) {
3198
965
      atP2 = bitmap->getDataPtr() + (y + aty[2]) * bitmap->getLineSize();
3199
965
      atBuf2 = *atP2++ << 8;
3200
965
    } 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
243
      atP3 = bitmap->getDataPtr() + (y + aty[3]) * bitmap->getLineSize();
3207
243
      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.85M
      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.85M
      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.75M
      *pp |= mask;
3316
6.75M
      buf2 |= 0x8000;
3317
6.75M
    }
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.85M
    }
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
140
    p1 = p0 = NULL;
3346
140
    buf1 = buf0 = 0;
3347
140
  }
3348
3349
10.6k
  if (atx[0] >= -8 && atx[0] <= 8) {
3350
    // set up the adaptive context
3351
171
    if (aty[0] <= 0 && y + aty[0] >= 0) {
3352
105
      atP0 = bitmap->getDataPtr() + (y + aty[0]) * bitmap->getLineSize();
3353
105
      atBuf0 = *atP0++ << 8;
3354
105
    } else {
3355
66
      atP0 = NULL;
3356
66
      atBuf0 = 0;
3357
66
    }
3358
171
    atShift0 = 15 - atx[0];
3359
3360
    // decode the row
3361
628
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3362
457
      if (x0 + 8 < w) {
3363
286
        if (p0) {
3364
234
    buf0 |= *p0++;
3365
234
        }
3366
286
        if (p1) {
3367
260
    buf1 |= *p1++;
3368
260
        }
3369
286
        buf2 |= *p2++;
3370
286
        if (atP0) {
3371
0
    atBuf0 |= *atP0++;
3372
0
        }
3373
286
      }
3374
457
      for (x1 = 0, mask = 0x80;
3375
3.18k
     x1 < 8 && x < w;
3376
2.72k
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3377
3378
        // build the context
3379
2.72k
        cx0 = (buf0 >> 13) & 0x0f;
3380
2.72k
        cx1 = (buf1 >> 13) & 0x1f;
3381
2.72k
        cx2 = (buf2 >> 16) & 0x07;
3382
2.72k
        cx = (cx0 << 9) | (cx1 << 4) | (cx2 << 1) |
3383
2.72k
       ((atBuf0 >> atShift0) & 1);
3384
3385
        // check for a skipped pixel
3386
2.72k
        if (!(useSkip && skip->getPixel(x, y))) {
3387
3388
    // decode the pixel
3389
2.72k
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3390
1.28k
      *pp |= mask;
3391
1.28k
      buf2 |= 0x8000;
3392
1.28k
      if (aty[0] == 0) {
3393
127
        atBuf0 |= 0x8000;
3394
127
      }
3395
1.28k
    }
3396
2.72k
        }
3397
3398
        // update the context
3399
2.72k
        buf0 <<= 1;
3400
2.72k
        buf1 <<= 1;
3401
2.72k
        buf2 <<= 1;
3402
2.72k
        atBuf0 <<= 1;
3403
2.72k
      }
3404
457
    }
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
17.2k
      case 3:
3568
3569
  // set up the context
3570
17.2k
  p2 = pp = bitmap->getDataPtr() + y * bitmap->getLineSize();
3571
17.2k
  buf2 = *p2++ << 8;
3572
17.2k
  if (y >= 1) {
3573
16.8k
    p1 = bitmap->getDataPtr() + (y - 1) * bitmap->getLineSize();
3574
16.8k
    buf1 = *p1++ << 8;
3575
16.8k
  } else {
3576
429
    p1 = NULL;
3577
429
    buf1 = 0;
3578
429
  }
3579
3580
17.2k
  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
16.1k
  } else {
3633
    // decode the row
3634
787k
    for (x0 = 0, x = 0; x0 < w; x0 += 8, ++pp) {
3635
770k
      if (x0 + 8 < w) {
3636
754k
        if (p1) {
3637
713k
    buf1 |= *p1++;
3638
713k
        }
3639
754k
        buf2 |= *p2++;
3640
754k
      }
3641
770k
      for (x1 = 0, mask = 0x80;
3642
6.83M
     x1 < 8 && x < w;
3643
6.06M
     ++x1, ++x, mask = (Guchar)(mask >> 1)) {
3644
3645
        // build the context
3646
6.06M
        cx1 = (buf1 >> 14) & 0x1f;
3647
6.06M
        cx2 = (buf2 >> 16) & 0x0f;
3648
6.06M
        cx = (cx1 << 5) | (cx2 << 1) |
3649
6.06M
       bitmap->getPixel(x + atx[0], y + aty[0]);
3650
3651
        // check for a skipped pixel
3652
6.06M
        if (!(useSkip && skip->getPixel(x, y))) {
3653
3654
    // decode the pixel
3655
6.06M
    if ((pix = arithDecoder->decodeBit(cx, genericRegionStats))) {
3656
2.32M
      *pp |= mask;
3657
2.32M
      buf2 |= 0x8000;
3658
2.32M
    }
3659
6.06M
        }
3660
3661
        // update the context
3662
6.06M
        buf1 <<= 1;
3663
6.06M
        buf2 <<= 1;
3664
6.06M
      }
3665
770k
    }
3666
16.1k
  }
3667
17.2k
  break;
3668
189k
      }
3669
189k
    }
3670
30.7k
  }
3671
3672
33.3k
  return bitmap;
3673
33.3k
}
3674
3675
void JBIG2Stream::readGenericRefinementRegionSeg(Guint segNum, GBool imm,
3676
             GBool lossless, Guint length,
3677
             Guint *refSegs,
3678
3.72k
             Guint nRefSegs) {
3679
3.72k
  JBIG2Bitmap *bitmap, *refBitmap;
3680
3.72k
  Guint w, h, x, y, segInfoFlags, extCombOp;
3681
3.72k
  Guint flags, templ, tpgrOn;
3682
3.72k
  int atx[2], aty[2];
3683
3.72k
  JBIG2Segment *seg;
3684
3685
  // region segment info field
3686
3.72k
  if (!readULong(&w) || !readULong(&h) ||
3687
3.72k
      !readULong(&x) || !readULong(&y) ||
3688
3.72k
      !readUByte(&segInfoFlags)) {
3689
904
    goto eofError;
3690
904
  }
3691
2.81k
  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.81k
  if (w / 10 > pageW || h / 10 > pageH ||
3699
2.81k
      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.24k
  extCombOp = segInfoFlags & 7;
3706
3707
  // rest of the generic refinement region segment header
3708
2.24k
  if (!readUByte(&flags)) {
3709
130
    goto eofError;
3710
130
  }
3711
2.11k
  templ = flags & 1;
3712
2.11k
  tpgrOn = (flags >> 1) & 1;
3713
3714
  // AT flags
3715
2.11k
  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.72k
  if (nRefSegs == 0 || imm) {
3724
1.40k
    if (pageH == 0xffffffff && y + h > curPageH) {
3725
477
      pageBitmap->expand(y + h, pageDefPixel);
3726
477
    }
3727
1.40k
  }
3728
3729
  // get referenced bitmap
3730
1.72k
  if (nRefSegs > 1) {
3731
448
    error(errSyntaxError, getPos(),
3732
448
    "Bad reference in JBIG2 generic refinement segment");
3733
448
    return;
3734
448
  }
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
939
    pageBitmap->combine(bitmap, x, y, extCombOp);
3758
939
    delete bitmap;
3759
3760
  // store the region bitmap
3761
939
  } 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.2k
                  int *atx, int *aty) {
3784
42.2k
  JBIG2Bitmap *bitmap;
3785
42.2k
  GBool ltp;
3786
42.2k
  Guint ltpCX, cx, cx0, cx2, cx3, cx4, tpgrCX0, tpgrCX1, tpgrCX2;
3787
42.2k
  JBIG2BitmapPtr cxPtr0, cxPtr1, cxPtr2, cxPtr3, cxPtr4, cxPtr5, cxPtr6;
3788
42.2k
  JBIG2BitmapPtr tpgrCXPtr0, tpgrCXPtr1, tpgrCXPtr2;
3789
42.2k
  int x, y, pix;
3790
3791
42.2k
  bitmap = new JBIG2Bitmap(0, w, h);
3792
42.2k
  bitmap->clearToZero();
3793
3794
  // set up the typical row context
3795
42.2k
  if (templ) {
3796
39.1k
    ltpCX = 0x008;
3797
39.1k
  } else {
3798
3.09k
    ltpCX = 0x0010;
3799
3.09k
  }
3800
3801
42.2k
  ltp = 0;
3802
4.60M
  for (y = 0; y < h; ++y) {
3803
3804
4.56M
    if (templ) {
3805
3806
      // set up the context
3807
2.96M
      bitmap->getPixelPtr(0, y-1, &cxPtr0);
3808
2.96M
      cx0 = bitmap->nextPixel(&cxPtr0);
3809
2.96M
      bitmap->getPixelPtr(-1, y, &cxPtr1);
3810
2.96M
      refBitmap->getPixelPtr(-refDX, y-1-refDY, &cxPtr2);
3811
2.96M
      refBitmap->getPixelPtr(-1-refDX, y-refDY, &cxPtr3);
3812
2.96M
      cx3 = refBitmap->nextPixel(&cxPtr3);
3813
2.96M
      cx3 = (cx3 << 1) | refBitmap->nextPixel(&cxPtr3);
3814
2.96M
      refBitmap->getPixelPtr(-refDX, y+1-refDY, &cxPtr4);
3815
2.96M
      cx4 = refBitmap->nextPixel(&cxPtr4);
3816
3817
      // set up the typical prediction context
3818
2.96M
      tpgrCX0 = tpgrCX1 = tpgrCX2 = 0; // make gcc happy
3819
2.96M
      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
113M
      for (x = 0; x < w; ++x) {
3839
3840
  // update the context
3841
110M
  cx0 = ((cx0 << 1) | bitmap->nextPixel(&cxPtr0)) & 7;
3842
110M
  cx3 = ((cx3 << 1) | refBitmap->nextPixel(&cxPtr3)) & 7;
3843
110M
  cx4 = ((cx4 << 1) | refBitmap->nextPixel(&cxPtr4)) & 3;
3844
3845
110M
  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
108M
  cx = (cx0 << 7) | (bitmap->nextPixel(&cxPtr1) << 6) |
3866
108M
       (refBitmap->nextPixel(&cxPtr2) << 5) |
3867
108M
       (cx3 << 2) | cx4;
3868
3869
  // decode the pixel
3870
108M
  if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3871
70.8M
    bitmap->setPixel(x, y);
3872
70.8M
  }
3873
108M
      }
3874
3875
2.96M
    } 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
456k
  refBitmap->getPixelPtr(-1-refDX, y-1-refDY, &tpgrCXPtr0);
3896
456k
  tpgrCX0 = refBitmap->nextPixel(&tpgrCXPtr0);
3897
456k
  tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3898
456k
  tpgrCX0 = (tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0);
3899
456k
  refBitmap->getPixelPtr(-1-refDX, y-refDY, &tpgrCXPtr1);
3900
456k
  tpgrCX1 = refBitmap->nextPixel(&tpgrCXPtr1);
3901
456k
  tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3902
456k
  tpgrCX1 = (tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1);
3903
456k
  refBitmap->getPixelPtr(-1-refDX, y+1-refDY, &tpgrCXPtr2);
3904
456k
  tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
3905
456k
  tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
3906
456k
  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
1.00M
    tpgrCX0 = ((tpgrCX0 << 1) | refBitmap->nextPixel(&tpgrCXPtr0)) & 7;
3924
1.00M
    tpgrCX1 = ((tpgrCX1 << 1) | refBitmap->nextPixel(&tpgrCXPtr1)) & 7;
3925
1.00M
    tpgrCX2 = ((tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2)) & 7;
3926
3927
    // check for a "typical" pixel
3928
1.00M
    if (arithDecoder->decodeBit(ltpCX, refinementRegionStats)) {
3929
578k
      ltp = !ltp;
3930
578k
    }
3931
1.00M
    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
43.7k
      bitmap->setPixel(x, y);
3936
43.7k
      continue;
3937
43.7k
    }
3938
1.00M
  }
3939
3940
  // build the context
3941
9.38M
  cx = (cx0 << 11) | (bitmap->nextPixel(&cxPtr1) << 10) |
3942
9.38M
       (cx2 << 8) | (cx3 << 5) | (cx4 << 2) |
3943
9.38M
       (bitmap->nextPixel(&cxPtr5) << 1) |
3944
9.38M
       refBitmap->nextPixel(&cxPtr6);
3945
3946
  // decode the pixel
3947
9.38M
  if ((pix = arithDecoder->decodeBit(cx, refinementRegionStats))) {
3948
5.26M
    bitmap->setPixel(x, y);
3949
5.26M
  }
3950
9.38M
      }
3951
1.59M
    }
3952
4.56M
  }
3953
3954
42.2k
  return bitmap;
3955
42.2k
}
3956
3957
56.6k
void JBIG2Stream::readPageInfoSeg(Guint length) {
3958
56.6k
  Guint xRes, yRes, flags, striping;
3959
3960
56.6k
  if (!readULong(&pageW) || !readULong(&pageH) ||
3961
56.6k
      !readULong(&xRes) || !readULong(&yRes) ||
3962
56.6k
      !readUByte(&flags) || !readUWord(&striping)) {
3963
1.29k
    goto eofError;
3964
1.29k
  }
3965
55.3k
  if (pageW == 0 || pageH == 0 ||
3966
55.3k
      pageW > INT_MAX || pageH > INT_MAX ||
3967
55.3k
      pageH > INT_MAX / pageW) {
3968
24.4k
    error(errSyntaxError, getPos(), "Bad page size in JBIG2 stream");
3969
24.4k
    return;
3970
24.4k
  }
3971
30.9k
  pageDefPixel = (flags >> 2) & 1;
3972
30.9k
  defCombOp = (flags >> 3) & 3;
3973
3974
  // this will only happen if there are multiple page info segments
3975
30.9k
  if (pageBitmap) {
3976
3.42k
    delete pageBitmap;
3977
3.42k
  }
3978
3979
  // allocate the page bitmap
3980
30.9k
  if (pageH == 0xffffffff) {
3981
0
    curPageH = striping & 0x7fff;
3982
30.9k
  } else {
3983
30.9k
    curPageH = pageH;
3984
30.9k
  }
3985
30.9k
  pageBitmap = new JBIG2Bitmap(0, pageW, curPageH);
3986
3987
  // default pixel value
3988
30.9k
  if (pageDefPixel) {
3989
10.9k
    pageBitmap->clearToOne();
3990
20.0k
  } else {
3991
20.0k
    pageBitmap->clearToZero();
3992
20.0k
  }
3993
3994
30.9k
  return;
3995
3996
1.29k
 eofError:
3997
1.29k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
3998
1.29k
}
3999
4000
110
void JBIG2Stream::readEndOfStripeSeg(Guint length) {
4001
  // skip the segment
4002
110
  byteCounter += curStr->discardChars(length);
4003
110
}
4004
4005
37
void JBIG2Stream::readProfilesSeg(Guint length) {
4006
  // skip the segment
4007
37
  byteCounter += curStr->discardChars(length);
4008
37
}
4009
4010
5.32k
void JBIG2Stream::readCodeTableSeg(Guint segNum, Guint length) {
4011
5.32k
  JBIG2HuffmanTable *huffTab;
4012
5.32k
  Guint flags, oob, prefixBits, rangeBits;
4013
5.32k
  int lowVal, highVal, val;
4014
5.32k
  Guint huffTabSize, i;
4015
4016
5.32k
  if (!readUByte(&flags) || !readLong(&lowVal) || !readLong(&highVal)) {
4017
1.14k
    goto eofError;
4018
1.14k
  }
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
204
    huffTab[i].val = 0;
4056
204
    huffTab[i].prefixLen = huffDecoder->readBits(prefixBits);
4057
204
    huffTab[i].rangeLen = jbig2HuffmanOOB;
4058
204
    ++i;
4059
204
  }
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
1.14k
 eofError:
4071
1.14k
  error(errSyntaxError, getPos(), "Unexpected EOF in JBIG2 stream");
4072
1.14k
}
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
115k
  for (i = 0; i < globalSegments->getLength(); ++i) {
4084
13.8k
    seg = (JBIG2Segment *)globalSegments->get(i);
4085
13.8k
    if (seg->getSegNum() == segNum) {
4086
6.22k
      return seg;
4087
6.22k
    }
4088
13.8k
  }
4089
103k
  for (i = 0; i < segments->getLength(); ++i) {
4090
9.24k
    seg = (JBIG2Segment *)segments->get(i);
4091
9.24k
    if (seg->getSegNum() == segNum) {
4092
7.69k
      return seg;
4093
7.69k
    }
4094
9.24k
  }
4095
94.2k
  return NULL;
4096
101k
}
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.56k
            JArithmeticDecoderStats *prevStats) {
4120
8.56k
  int size;
4121
4122
8.56k
  size = contextSize[templ];
4123
8.56k
  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.56k
  } else {
4131
8.56k
    if (genericRegionStats->getContextSize() == size) {
4132
0
      genericRegionStats->reset();
4133
8.56k
    } else {
4134
8.56k
      delete genericRegionStats;
4135
8.56k
      genericRegionStats = new JArithmeticDecoderStats(1 << size);
4136
8.56k
    }
4137
8.56k
  }
4138
8.56k
}
4139
4140
void JBIG2Stream::resetRefinementStats(Guint templ,
4141
3.62k
               JArithmeticDecoderStats *prevStats) {
4142
3.62k
  int size;
4143
4144
3.62k
  size = refContextSize[templ];
4145
3.62k
  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.62k
  } else {
4153
3.62k
    if (refinementRegionStats->getContextSize() == size) {
4154
0
      refinementRegionStats->reset();
4155
3.62k
    } else {
4156
3.62k
      delete refinementRegionStats;
4157
3.62k
      refinementRegionStats = new JArithmeticDecoderStats(1 << size);
4158
3.62k
    }
4159
3.62k
  }
4160
3.62k
}
4161
4162
7.23k
void JBIG2Stream::resetIntStats(int symCodeLen) {
4163
7.23k
  iadhStats->reset();
4164
7.23k
  iadwStats->reset();
4165
7.23k
  iaexStats->reset();
4166
7.23k
  iaaiStats->reset();
4167
7.23k
  iadtStats->reset();
4168
7.23k
  iaitStats->reset();
4169
7.23k
  iafsStats->reset();
4170
7.23k
  iadsStats->reset();
4171
7.23k
  iardxStats->reset();
4172
7.23k
  iardyStats->reset();
4173
7.23k
  iardwStats->reset();
4174
7.23k
  iardhStats->reset();
4175
7.23k
  iariStats->reset();
4176
7.23k
  if (iaidStats->getContextSize() == 1 << (symCodeLen + 1)) {
4177
3.78k
    iaidStats->reset();
4178
3.78k
  } else {
4179
3.44k
    delete iaidStats;
4180
3.44k
    iaidStats = new JArithmeticDecoderStats(1 << (symCodeLen + 1));
4181
3.44k
  }
4182
7.23k
}
4183
4184
414k
GBool JBIG2Stream::readUByte(Guint *x) {
4185
414k
  int c0;
4186
4187
414k
  if ((c0 = curStr->getChar()) == EOF) {
4188
2.10k
    return gFalse;
4189
2.10k
  }
4190
412k
  ++byteCounter;
4191
412k
  *x = (Guint)c0;
4192
412k
  return gTrue;
4193
414k
}
4194
4195
95.4k
GBool JBIG2Stream::readByte(int *x) {
4196
95.4k
 int c0;
4197
4198
95.4k
  if ((c0 = curStr->getChar()) == EOF) {
4199
4.39k
    return gFalse;
4200
4.39k
  }
4201
91.0k
  ++byteCounter;
4202
91.0k
  *x = c0;
4203
91.0k
  if (c0 & 0x80) {
4204
15.6k
    *x |= -1 - 0xff;
4205
15.6k
  }
4206
91.0k
  return gTrue;
4207
95.4k
}
4208
4209
347k
GBool JBIG2Stream::readUWord(Guint *x) {
4210
347k
  int c0, c1;
4211
4212
347k
  if ((c0 = curStr->getChar()) == EOF ||
4213
347k
      (c1 = curStr->getChar()) == EOF) {
4214
333
    return gFalse;
4215
333
  }
4216
346k
  byteCounter += 2;
4217
346k
  *x = (Guint)((c0 << 8) | c1);
4218
346k
  return gTrue;
4219
347k
}
4220
4221
895k
GBool JBIG2Stream::readULong(Guint *x) {
4222
895k
  int c0, c1, c2, c3;
4223
4224
895k
  if ((c0 = curStr->getChar()) == EOF ||
4225
895k
      (c1 = curStr->getChar()) == EOF ||
4226
895k
      (c2 = curStr->getChar()) == EOF ||
4227
895k
      (c3 = curStr->getChar()) == EOF) {
4228
15.8k
    return gFalse;
4229
15.8k
  }
4230
879k
  byteCounter += 4;
4231
879k
  *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
4232
879k
  return gTrue;
4233
895k
}
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
623
    *x |= -1 - (int)0xffffffff;
4248
623
  }
4249
14.3k
  return gTrue;
4250
15.1k
}