~ubuntu-branches/ubuntu/natty/xpdf/natty

« back to all changes in this revision

Viewing changes to .pc/fix-CVE-2009-0146,0147,0165,0166,0799,0800,1179-1183.dpatch/xpdf/JBIG2Stream.cc

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-10-17 00:53:43 UTC
  • mfrom: (6.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20101017005343-3arnd6x6b55ou9ue
Tags: 3.02-11ubuntu1
Add -lXt -lX11 to LIBS definition in debian/rules to fix FTBFS due to
indirect linking

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