~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/poppler/poppler/JBIG2Stream.cc

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

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