Coverage Report

Created: 2026-07-04 07:11

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