Coverage Report

Created: 2026-10-31 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xpdf-4.06/xpdf/JPXStream.cc
Line
Count
Source
1
//========================================================================
2
//
3
// JPXStream.cc
4
//
5
// Copyright 2002-2003 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
#include <aconf.h>
10
11
#include <limits.h>
12
#include "gmem.h"
13
#include "gmempp.h"
14
#include "Error.h"
15
#include "JArithmeticDecoder.h"
16
#include "JPXStream.h"
17
18
//~ to do:
19
//  - ROI
20
//  - progression order changes
21
//  - packed packet headers
22
//  - support for palettes, channel maps, etc.
23
//  - make sure all needed JP2/JPX subboxes are parsed (readBoxes)
24
//  - can we assume that QCC segments must come after the QCD segment?
25
//  - handle tilePartToEOC in readTilePartData
26
//  - in coefficient decoding (readCodeBlockData):
27
//    - selective arithmetic coding bypass
28
//      (this also affects reading the cb->dataLen array)
29
//    - coeffs longer than 31 bits (should just ignore the extra bits?)
30
//  - handle boxes larger than 2^32 bytes
31
//  - the fixed-point arithmetic won't handle 16-bit pixels
32
33
//------------------------------------------------------------------------
34
35
// number of contexts for the arithmetic decoder
36
293k
#define jpxNContexts        19
37
38
1.21M
#define jpxContextSigProp    0  // 0 - 8: significance prop and cleanup
39
#define jpxContextSign       9  // 9 - 13: sign
40
#define jpxContextMagRef    14  // 14 - 16: magnitude refinement
41
11.9M
#define jpxContextRunLength 17  // cleanup: run length
42
2.05M
#define jpxContextUniform   18  // cleanup: first signif coeff
43
44
//------------------------------------------------------------------------
45
46
1.47M
#define jpxPassSigProp       0
47
565k
#define jpxPassMagRef        1
48
42.1M
#define jpxPassCleanup       2
49
50
//------------------------------------------------------------------------
51
52
// arithmetic decoder context for the significance propagation and
53
// cleanup passes:
54
//     [horiz][vert][diag][subband]
55
// where subband = 0 for HL
56
//               = 1 for LH and LL
57
//               = 2 for HH
58
static Guint sigPropContext[3][3][5][3] = {
59
  {{{ 0, 0, 0 },   // horiz=0, vert=0, diag=0
60
    { 1, 1, 3 },   // horiz=0, vert=0, diag=1
61
    { 2, 2, 6 },   // horiz=0, vert=0, diag=2
62
    { 2, 2, 8 },   // horiz=0, vert=0, diag=3
63
    { 2, 2, 8 }},  // horiz=0, vert=0, diag=4
64
   {{ 5, 3, 1 },   // horiz=0, vert=1, diag=0
65
    { 6, 3, 4 },   // horiz=0, vert=1, diag=1
66
    { 6, 3, 7 },   // horiz=0, vert=1, diag=2
67
    { 6, 3, 8 },   // horiz=0, vert=1, diag=3
68
    { 6, 3, 8 }},  // horiz=0, vert=1, diag=4
69
   {{ 8, 4, 2 },   // horiz=0, vert=2, diag=0
70
    { 8, 4, 5 },   // horiz=0, vert=2, diag=1
71
    { 8, 4, 7 },   // horiz=0, vert=2, diag=2
72
    { 8, 4, 8 },   // horiz=0, vert=2, diag=3
73
    { 8, 4, 8 }}}, // horiz=0, vert=2, diag=4
74
  {{{ 3, 5, 1 },   // horiz=1, vert=0, diag=0
75
    { 3, 6, 4 },   // horiz=1, vert=0, diag=1
76
    { 3, 6, 7 },   // horiz=1, vert=0, diag=2
77
    { 3, 6, 8 },   // horiz=1, vert=0, diag=3
78
    { 3, 6, 8 }},  // horiz=1, vert=0, diag=4
79
   {{ 7, 7, 2 },   // horiz=1, vert=1, diag=0
80
    { 7, 7, 5 },   // horiz=1, vert=1, diag=1
81
    { 7, 7, 7 },   // horiz=1, vert=1, diag=2
82
    { 7, 7, 8 },   // horiz=1, vert=1, diag=3
83
    { 7, 7, 8 }},  // horiz=1, vert=1, diag=4
84
   {{ 8, 7, 2 },   // horiz=1, vert=2, diag=0
85
    { 8, 7, 5 },   // horiz=1, vert=2, diag=1
86
    { 8, 7, 7 },   // horiz=1, vert=2, diag=2
87
    { 8, 7, 8 },   // horiz=1, vert=2, diag=3
88
    { 8, 7, 8 }}}, // horiz=1, vert=2, diag=4
89
  {{{ 4, 8, 2 },   // horiz=2, vert=0, diag=0
90
    { 4, 8, 5 },   // horiz=2, vert=0, diag=1
91
    { 4, 8, 7 },   // horiz=2, vert=0, diag=2
92
    { 4, 8, 8 },   // horiz=2, vert=0, diag=3
93
    { 4, 8, 8 }},  // horiz=2, vert=0, diag=4
94
   {{ 7, 8, 2 },   // horiz=2, vert=1, diag=0
95
    { 7, 8, 5 },   // horiz=2, vert=1, diag=1
96
    { 7, 8, 7 },   // horiz=2, vert=1, diag=2
97
    { 7, 8, 8 },   // horiz=2, vert=1, diag=3
98
    { 7, 8, 8 }},  // horiz=2, vert=1, diag=4
99
   {{ 8, 8, 2 },   // horiz=2, vert=2, diag=0
100
    { 8, 8, 5 },   // horiz=2, vert=2, diag=1
101
    { 8, 8, 7 },   // horiz=2, vert=2, diag=2
102
    { 8, 8, 8 },   // horiz=2, vert=2, diag=3
103
    { 8, 8, 8 }}}  // horiz=2, vert=2, diag=4
104
};
105
106
// arithmetic decoder context and xor bit for the sign bit in the
107
// significance propagation pass:
108
//     [horiz][vert][k]
109
// where horiz/vert are offset by 2 (i.e., range is -2 .. 2)
110
// and k = 0 for the context
111
//       = 1 for the xor bit
112
static Guint signContext[5][5][2] = {
113
  {{ 13, 1 },  // horiz=-2, vert=-2
114
   { 13, 1 },  // horiz=-2, vert=-1
115
   { 12, 1 },  // horiz=-2, vert= 0
116
   { 11, 1 },  // horiz=-2, vert=+1
117
   { 11, 1 }}, // horiz=-2, vert=+2
118
  {{ 13, 1 },  // horiz=-1, vert=-2
119
   { 13, 1 },  // horiz=-1, vert=-1
120
   { 12, 1 },  // horiz=-1, vert= 0
121
   { 11, 1 },  // horiz=-1, vert=+1
122
   { 11, 1 }}, // horiz=-1, vert=+2
123
  {{ 10, 1 },  // horiz= 0, vert=-2
124
   { 10, 1 },  // horiz= 0, vert=-1
125
   {  9, 0 },  // horiz= 0, vert= 0
126
   { 10, 0 },  // horiz= 0, vert=+1
127
   { 10, 0 }}, // horiz= 0, vert=+2
128
  {{ 11, 0 },  // horiz=+1, vert=-2
129
   { 11, 0 },  // horiz=+1, vert=-1
130
   { 12, 0 },  // horiz=+1, vert= 0
131
   { 13, 0 },  // horiz=+1, vert=+1
132
   { 13, 0 }}, // horiz=+1, vert=+2
133
  {{ 11, 0 },  // horiz=+2, vert=-2
134
   { 11, 0 },  // horiz=+2, vert=-1
135
   { 12, 0 },  // horiz=+2, vert= 0
136
   { 13, 0 },  // horiz=+2, vert=+1
137
   { 13, 0 }}, // horiz=+2, vert=+2
138
};
139
140
//------------------------------------------------------------------------
141
142
// constants used in the IDWT
143
405M
#define idwtAlpha  -1.586134342059924
144
427M
#define idwtBeta   -0.052980118572961
145
449M
#define idwtGamma   0.882911075530934
146
470M
#define idwtDelta   0.443506852043971
147
963M
#define idwtKappa   1.230174104914001
148
492M
#define idwtIKappa  (1.0 / idwtKappa)
149
150
// sum of the sample size (number of bits) and the number of bits to
151
// the right of the decimal point for the fixed point arithmetic used
152
// in the IDWT
153
20.0M
#define fracBits 24
154
155
//------------------------------------------------------------------------
156
157
// floor(x / y)
158
278M
#define jpxFloorDiv(x, y) ((x) / (y))
159
160
// floor(x / 2^y)
161
11.7M
#define jpxFloorDivPow2(x, y) ((x) >> (y))
162
163
// ceil(x / y)
164
267k
#define jpxCeilDiv(x, y) (((x) + (y) - 1) / (y))
165
166
// ceil(x / 2^y)
167
78.5M
#define jpxCeilDivPow2(x, y) (((x) + (1 << (y)) - 1) >> (y))
168
169
//------------------------------------------------------------------------
170
171
#if 1 //----- disable coverage tracking
172
173
#define cover(idx)
174
175
#else //----- enable coverage tracking
176
177
class JPXCover {
178
public:
179
180
  JPXCover(int sizeA);
181
  ~JPXCover();
182
  void incr(int idx);
183
184
private:
185
186
  int size, used;
187
  int *data;
188
};
189
190
JPXCover::JPXCover(int sizeA) {
191
  size = sizeA;
192
  used = -1;
193
  data = (int *)gmallocn(size, sizeof(int));
194
  memset(data, 0, size * sizeof(int));
195
}
196
197
JPXCover::~JPXCover() {
198
  int i;
199
200
  printf("JPX coverage:\n");
201
  for (i = 0; i <= used; ++i) {
202
    printf("  %4d: %8d\n", i, data[i]);
203
  }
204
  gfree(data);
205
}
206
207
void JPXCover::incr(int idx) {
208
  if (idx < size) {
209
    ++data[idx];
210
    if (idx > used) {
211
      used = idx;
212
    }
213
  }
214
}
215
216
JPXCover jpxCover(150);
217
218
#define cover(idx) jpxCover.incr(idx)
219
220
#endif //----- coverage tracking
221
222
//------------------------------------------------------------------------
223
224
JPXStream::JPXStream(Stream *strA):
225
353k
  FilterStream(strA)
226
353k
{
227
353k
  bufStr = new BufStream(str, 3);
228
229
353k
  decoded = gFalse;
230
353k
  nComps = 0;
231
353k
  bpc = NULL;
232
353k
  width = height = 0;
233
353k
  reduction = 0;
234
353k
  haveCS = gFalse;
235
236
353k
  palette.bpc = NULL;
237
353k
  palette.c = NULL;
238
353k
  havePalette = gFalse;
239
240
353k
  compMap.comp = NULL;
241
353k
  compMap.type = NULL;
242
353k
  compMap.pComp = NULL;
243
353k
  haveCompMap = gFalse;
244
245
353k
  channelDefn.idx = NULL;
246
353k
  channelDefn.type = NULL;
247
353k
  channelDefn.assoc = NULL;
248
353k
  haveChannelDefn = gFalse;
249
250
353k
  img.tiles = NULL;
251
252
353k
  bitBuf = 0;
253
353k
  bitBufLen = 0;
254
353k
  bitBufSkip = gFalse;
255
353k
  byteCount = 0;
256
353k
}
257
258
353k
JPXStream::~JPXStream() {
259
353k
  close();
260
353k
  delete bufStr;
261
353k
}
262
263
341k
Stream *JPXStream::copy() {
264
341k
  return new JPXStream(str->copy());
265
341k
}
266
267
112k
void JPXStream::reset() {
268
112k
  img.ySize = 0;
269
112k
  bufStr->reset();
270
112k
  decoded = gFalse;
271
112k
}
272
273
465k
void JPXStream::close() {
274
465k
  JPXTile *tile;
275
465k
  JPXTileComp *tileComp;
276
465k
  JPXResLevel *resLevel;
277
465k
  JPXPrecinct *precinct;
278
465k
  JPXSubband *subband;
279
465k
  JPXCodeBlock *cb;
280
465k
  Guint comp, i, k, r, pre, sb;
281
282
465k
  gfree(bpc);
283
465k
  bpc = NULL;
284
465k
  if (havePalette) {
285
1.09k
    gfree(palette.bpc);
286
1.09k
    gfree(palette.c);
287
1.09k
    havePalette = gFalse;
288
1.09k
  }
289
465k
  if (haveCompMap) {
290
1.61k
    gfree(compMap.comp);
291
1.61k
    gfree(compMap.type);
292
1.61k
    gfree(compMap.pComp);
293
1.61k
    haveCompMap = gFalse;
294
1.61k
  }
295
465k
  if (haveChannelDefn) {
296
2.19k
    gfree(channelDefn.idx);
297
2.19k
    gfree(channelDefn.type);
298
2.19k
    gfree(channelDefn.assoc);
299
2.19k
    haveChannelDefn = gFalse;
300
2.19k
  }
301
302
465k
  if (img.tiles) {
303
14.2M
    for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
304
14.1M
      tile = &img.tiles[i];
305
14.1M
      if (tile->tileComps) {
306
86.9M
  for (comp = 0; comp < img.nComps; ++comp) {
307
72.7M
    tileComp = &tile->tileComps[comp];
308
72.7M
    gfree(tileComp->quantSteps);
309
72.7M
    gfree(tileComp->data);
310
72.7M
    gfree(tileComp->buf);
311
72.7M
    if (tileComp->resLevels) {
312
111M
      for (r = 0; r <= tileComp->nDecompLevels; ++r) {
313
91.4M
        resLevel = &tileComp->resLevels[r];
314
91.4M
        if (resLevel->precincts) {
315
2.32M
    for (pre = 0; pre < resLevel->nPrecincts; ++pre) {
316
1.99M
      precinct = &resLevel->precincts[pre];
317
1.99M
      if (precinct->subbands) {
318
7.54M
        for (sb = 0; sb < (Guint)(r == 0 ? 1 : 3); ++sb) {
319
5.55M
          subband = &precinct->subbands[sb];
320
5.55M
          gfree(subband->inclusion);
321
5.55M
          gfree(subband->zeroBitPlane);
322
5.55M
          if (subband->cbs) {
323
46.2M
      for (k = 0; k < subband->nXCBs * subband->nYCBs; ++k) {
324
41.1M
        cb = &subband->cbs[k];
325
41.1M
        gfree(cb->dataLen);
326
41.1M
        gfree(cb->touched);
327
41.1M
        if (cb->arithDecoder) {
328
293k
          delete cb->arithDecoder;
329
293k
        }
330
41.1M
        if (cb->stats) {
331
293k
          delete cb->stats;
332
293k
        }
333
41.1M
      }
334
5.14M
      gfree(subband->cbs);
335
5.14M
          }
336
5.55M
        }
337
1.99M
        gfree(precinct->subbands);
338
1.99M
      }
339
1.99M
    }
340
333k
    gfree(resLevel->precincts);
341
333k
        }
342
91.4M
      }
343
19.5M
      gfree(tileComp->resLevels);
344
19.5M
    }
345
72.7M
  }
346
14.1M
  gfree(tile->tileComps);
347
14.1M
      }
348
14.1M
    }
349
65.6k
    gfree(img.tiles);
350
65.6k
    img.tiles = NULL;
351
65.6k
  }
352
465k
  bufStr->close();
353
465k
}
354
355
111k
void JPXStream::decodeImage() {
356
111k
  if (readBoxes() == jpxDecodeFatalError) {
357
    // readBoxes reported an error, so we go immediately to EOF
358
95.7k
    curY = img.ySize >> reduction;
359
95.7k
  } else {
360
15.5k
    curY = img.yOffsetR;
361
15.5k
  }
362
111k
  curX = img.xOffsetR;
363
111k
  curComp = 0;
364
111k
  readBufLen = 0;
365
111k
  decoded = gTrue;
366
111k
}
367
368
1.00G
int JPXStream::getChar() {
369
1.00G
  int c;
370
371
1.00G
  if (!decoded) {
372
111k
    decodeImage();
373
111k
  }
374
1.00G
  if (readBufLen < 8) {
375
111M
    fillReadBuf();
376
111M
  }
377
1.00G
  if (readBufLen == 8) {
378
36.2M
    c = readBuf & 0xff;
379
36.2M
    readBufLen = 0;
380
967M
  } else if (readBufLen > 8) {
381
967M
    c = (readBuf >> (readBufLen - 8)) & 0xff;
382
967M
    readBufLen -= 8;
383
967M
  } else if (readBufLen == 0) {
384
111k
    c = EOF;
385
111k
  } else {
386
3
    c = (readBuf << (8 - readBufLen)) & 0xff;
387
3
    readBufLen = 0;
388
3
  }
389
1.00G
  return c;
390
1.00G
}
391
392
54.7M
int JPXStream::lookChar() {
393
54.7M
  int c;
394
395
54.7M
  if (!decoded) {
396
0
    decodeImage();
397
0
  }
398
54.7M
  if (readBufLen < 8) {
399
11.7M
    fillReadBuf();
400
11.7M
  }
401
54.7M
  if (readBufLen == 8) {
402
10.0M
    c = readBuf & 0xff;
403
44.6M
  } else if (readBufLen > 8) {
404
44.6M
    c = (readBuf >> (readBufLen - 8)) & 0xff;
405
44.6M
  } else if (readBufLen == 0) {
406
964
    c = EOF;
407
964
  } else {
408
0
    c = (readBuf << (8 - readBufLen)) & 0xff;
409
0
  }
410
54.7M
  return c;
411
54.7M
}
412
413
122M
void JPXStream::fillReadBuf() {
414
122M
  JPXTileComp *tileComp;
415
122M
  Guint tileIdx, tx, ty;
416
122M
  int pix, pixBits, k;
417
122M
  GBool eol;
418
419
139M
  do {
420
139M
    if (curY >= (img.ySize >> reduction)) {
421
112k
      return;
422
112k
    }
423
139M
    tileIdx = (((curY << reduction) - img.yTileOffset) / img.yTileSize)
424
139M
                * img.nXTiles
425
139M
              + ((curX << reduction) - img.xTileOffset) / img.xTileSize;
426
139M
#if 1 //~ ignore the palette, assume the PDF ColorSpace object is valid
427
139M
    tileComp = &img.tiles[tileIdx].tileComps[curComp];
428
#else
429
    tileComp = &img.tiles[tileIdx].tileComps[havePalette ? 0 : curComp];
430
#endif
431
139M
    tx = jpxFloorDiv(curX, tileComp->hSep);
432
139M
    if (tx < tileComp->x0r) {
433
15.5M
      tx = 0;
434
123M
    } else {
435
123M
      tx -= tileComp->x0r;
436
123M
    }
437
139M
    ty = jpxFloorDiv(curY, tileComp->vSep);
438
139M
    if (ty < tileComp->y0r) {
439
5.44M
      ty  = 0;
440
133M
    } else {
441
133M
      ty -= tileComp->y0r;
442
133M
    }
443
139M
    pix = (int)tileComp->data[ty * tileComp->w + tx];
444
139M
    pixBits = tileComp->prec;
445
139M
    eol = gFalse;
446
139M
#if 1 //~ ignore the palette, assume the PDF ColorSpace object is valid
447
139M
    if (++curComp == img.nComps) {
448
#else
449
    if (havePalette) {
450
      if (pix >= 0 && pix < palette.nEntries) {
451
  pix = palette.c[pix * palette.nComps + curComp];
452
      } else {
453
  pix = 0;
454
      }
455
      pixBits = palette.bpc[curComp];
456
    }
457
    if (++curComp == (Guint)(havePalette ? palette.nComps : img.nComps)) {
458
#endif
459
104M
      curComp = 0;
460
104M
      if (++curX == (img.xSize >> reduction)) {
461
303k
  curX = img.xOffsetR;
462
303k
  ++curY;
463
303k
  eol = gTrue;
464
303k
      }
465
104M
    }
466
139M
    if (pixBits == 8) {
467
22.4M
      readBuf = (readBuf << 8) | (pix & 0xff);
468
116M
    } else {
469
116M
      readBuf = (readBuf << pixBits) | (pix & ((1 << pixBits) - 1));
470
116M
    }
471
139M
    readBufLen += pixBits;
472
139M
    if (eol && (k = readBufLen & 7)) {
473
254k
      readBuf <<= 8 - k;
474
254k
      readBufLen += 8 - k;
475
254k
    }
476
139M
  } while (readBufLen < 8);
477
122M
}
478
479
GString *JPXStream::getPSFilter(int psLevel, const char *indent,
480
0
        GBool okToReadStream) {
481
0
  return NULL;
482
0
}
483
484
0
GBool JPXStream::isBinary(GBool last) {
485
0
  return str->isBinary(gTrue);
486
0
}
487
488
void JPXStream::getImageParams(int *bitsPerComponent,
489
2.12k
             StreamColorSpaceMode *csMode) {
490
2.12k
  Guint boxType, boxLen, dataLen, csEnum;
491
2.12k
  Guint bpc1, dummy;
492
2.12k
  int csMeth, csPrec, csPrec1, dummy2;
493
2.12k
  StreamColorSpaceMode csMode1;
494
2.12k
  GBool haveBPC, haveCSMode;
495
496
2.12k
  csPrec = 0; // make gcc happy
497
2.12k
  haveBPC = haveCSMode = gFalse;
498
2.12k
  bufStr->reset();
499
2.12k
  if (bufStr->lookChar() == 0xff) {
500
1.03k
    getImageParams2(bitsPerComponent, csMode);
501
1.09k
  } else {
502
6.15k
    while (readBoxHdr(&boxType, &boxLen, &dataLen)) {
503
5.38k
      if (boxType == 0x6a703268) { // JP2 header
504
797
  cover(0);
505
  // skip the superbox
506
4.58k
      } else if (boxType == 0x69686472) { // image header
507
587
  cover(1);
508
587
  if (readULong(&dummy) &&
509
509
      readULong(&dummy) &&
510
360
      readUWord(&dummy) &&
511
300
      readUByte(&bpc1) &&
512
280
      readUByte(&dummy) &&
513
239
      readUByte(&dummy) &&
514
217
      readUByte(&dummy)) {
515
199
    *bitsPerComponent = bpc1 + 1;
516
199
    haveBPC = gTrue;
517
199
  }
518
4.00k
      } else if (boxType == 0x636F6C72) { // color specification
519
417
  cover(2);
520
417
  if (readByte(&csMeth) &&
521
397
      readByte(&csPrec1) &&
522
397
      readByte(&dummy2)) {
523
373
    if (csMeth == 1) {
524
257
      if (readULong(&csEnum)) {
525
220
        csMode1 = streamCSNone;
526
220
        if (csEnum == jpxCSBiLevel ||
527
183
      csEnum == jpxCSGrayscale) {
528
37
    csMode1 = streamCSDeviceGray;
529
183
        } else if (csEnum == jpxCSCMYK) {
530
0
    csMode1 = streamCSDeviceCMYK;
531
183
        } else if (csEnum == jpxCSsRGB ||
532
66
       csEnum == jpxCSCISesRGB ||
533
135
       csEnum == jpxCSROMMRGB) {
534
135
    csMode1 = streamCSDeviceRGB;
535
135
        }
536
220
        if (csMode1 != streamCSNone &&
537
172
      (!haveCSMode || csPrec1 > csPrec)) {
538
172
    *csMode = csMode1;
539
172
    csPrec = csPrec1;
540
172
    haveCSMode = gTrue;
541
172
        }
542
220
        if (dataLen > 7) {
543
45
    bufStr->discardChars(dataLen - 7);
544
45
        }
545
220
      }
546
257
    } else {
547
116
      if (dataLen > 3) {
548
79
        bufStr->discardChars(dataLen - 3);
549
79
      }
550
116
    }
551
373
  }
552
3.58k
      } else if (boxType == 0x6A703263) { // codestream
553
319
  cover(3);
554
319
  if (!(haveBPC && haveCSMode)) {
555
308
    getImageParams2(bitsPerComponent, csMode);
556
308
  }
557
319
  break;
558
3.26k
      } else {
559
3.26k
  cover(4);
560
3.26k
  bufStr->discardChars(dataLen);
561
3.26k
      }
562
5.38k
    }
563
1.09k
  }
564
2.12k
  bufStr->close();
565
2.12k
}
566
567
// Get image parameters from the codestream.
568
void JPXStream::getImageParams2(int *bitsPerComponent,
569
1.34k
        StreamColorSpaceMode *csMode) {
570
1.34k
  int segType;
571
1.34k
  Guint segLen, nComps1, bpc1, dummy;
572
573
3.73k
  while (readMarkerHdr(&segType, &segLen)) {
574
3.57k
    if (segType == 0x51) { // SIZ - image and tile size
575
1.17k
      cover(5);
576
1.17k
      if (readUWord(&dummy) &&
577
1.14k
    readULong(&dummy) &&
578
1.01k
    readULong(&dummy) &&
579
891
    readULong(&dummy) &&
580
777
    readULong(&dummy) &&
581
643
    readULong(&dummy) &&
582
475
    readULong(&dummy) &&
583
372
    readULong(&dummy) &&
584
353
    readULong(&dummy) &&
585
317
    readUWord(&nComps1) &&
586
253
    readUByte(&bpc1)) {
587
233
  *bitsPerComponent = (bpc1 & 0x7f) + 1;
588
  // if there's no color space info, take a guess
589
233
  if (nComps1 == 1) {
590
168
    *csMode = streamCSDeviceGray;
591
168
  } else if (nComps1 == 3) {
592
24
    *csMode = streamCSDeviceRGB;
593
41
  } else if (nComps1 == 4) {
594
0
    *csMode = streamCSDeviceCMYK;
595
0
  }
596
233
      }
597
1.17k
      break;
598
2.39k
    } else {
599
2.39k
      cover(6);
600
2.39k
      if (segLen > 2) {
601
643
  bufStr->discardChars(segLen - 2);
602
643
      }
603
2.39k
    }
604
3.57k
  }
605
1.34k
}
606
607
111k
JPXDecodeResult JPXStream::readBoxes() {
608
111k
  JPXDecodeResult result;
609
111k
  GBool haveCodestream;
610
111k
  Guint boxType, boxLen, dataLen;
611
111k
  Guint w, h, n, bpc1, compression, unknownColorspace, ipr;
612
111k
  Guint i, j;
613
614
111k
  haveImgHdr = gFalse;
615
111k
  haveCodestream = gFalse;
616
617
  // check for a naked JPEG 2000 codestream (without the JP2/JPX
618
  // wrapper) -- this appears to be a violation of the PDF spec, but
619
  // Acrobat allows it
620
111k
  if (bufStr->lookChar() == 0xff) {
621
85.5k
    cover(7);
622
85.5k
    error(errSyntaxWarning, getPos(),
623
85.5k
    "Naked JPEG 2000 codestream, missing JP2/JPX wrapper");
624
85.5k
    if ((result = readCodestream(0)) == jpxDecodeFatalError) {
625
75.4k
      return result;
626
75.4k
    }
627
10.0k
    nComps = img.nComps;
628
10.0k
    bpc = (Guint *)gmallocn(nComps, sizeof(Guint));
629
38.5k
    for (i = 0; i < nComps; ++i) {
630
28.4k
      bpc[i] = img.tiles[0].tileComps[i].prec;
631
28.4k
    }
632
10.0k
    width = img.xSize - img.xOffset;
633
10.0k
    height = img.ySize - img.yOffset;
634
10.0k
    return result;
635
85.5k
  }
636
637
116k
  while (readBoxHdr(&boxType, &boxLen, &dataLen)) {
638
111k
    switch (boxType) {
639
13.4k
    case 0x6a703268:    // JP2 header
640
      // this is a grouping box ('superbox') which has no real
641
      // contents and doesn't appear to be used consistently, i.e.,
642
      // some things which should be subboxes of the JP2 header box
643
      // show up outside of it - so we simply ignore the JP2 header
644
      // box
645
13.4k
      cover(8);
646
13.4k
      break;
647
11.8k
    case 0x69686472:    // image header
648
11.8k
      cover(9);
649
11.8k
      if (!readULong(&h) ||
650
10.9k
    !readULong(&w) ||
651
9.92k
    !readUWord(&n) ||
652
9.39k
    !readUByte(&bpc1) ||
653
9.14k
    !readUByte(&compression) ||
654
8.91k
    !readUByte(&unknownColorspace) ||
655
8.68k
    !readUByte(&ipr)) {
656
3.43k
  error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
657
3.43k
  return jpxDecodeFatalError;
658
3.43k
      }
659
8.43k
      if (compression != 7) {
660
404
  error(errSyntaxError, getPos(),
661
404
        "Unknown compression type in JPX stream");
662
404
  return jpxDecodeFatalError;
663
404
      }
664
8.03k
      height = h;
665
8.03k
      width = w;
666
8.03k
      nComps = n;
667
8.03k
      bpc = (Guint *)gmallocn(nComps, sizeof(Guint));
668
7.55M
      for (i = 0; i < nComps; ++i) {
669
7.54M
  bpc[i] = bpc1;
670
7.54M
      }
671
8.03k
      haveImgHdr = gTrue;
672
8.03k
      break;
673
255
    case 0x62706363:    // bits per component
674
255
      cover(10);
675
255
      if (!haveImgHdr) {
676
255
  error(errSyntaxError, getPos(),
677
255
        "Found bits per component box before image header box in JPX stream");
678
255
  return jpxDecodeFatalError;
679
255
      }
680
0
      if (dataLen != nComps) {
681
0
  error(errSyntaxError, getPos(),
682
0
        "Invalid bits per component box in JPX stream");
683
0
  return jpxDecodeFatalError;
684
0
      }
685
0
      for (i = 0; i < nComps; ++i) {
686
0
  if (!readUByte(&bpc[i])) {
687
0
    error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
688
0
    return jpxDecodeFatalError;
689
0
  }
690
0
      }
691
0
      break;
692
12.1k
    case 0x636F6C72:    // color specification
693
12.1k
      cover(11);
694
12.1k
      if (!readColorSpecBox(dataLen)) {
695
4.38k
  return jpxDecodeFatalError;
696
4.38k
      }
697
7.75k
      break;
698
7.75k
    case 0x70636c72:    // palette
699
1.84k
      cover(12);
700
1.84k
      if (!readUWord(&palette.nEntries) ||
701
1.34k
    !readUByte(&palette.nComps)) {
702
746
  error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
703
746
  return jpxDecodeFatalError;
704
746
      }
705
1.09k
      havePalette = gTrue;
706
1.09k
      palette.bpc = (Guint *)gmallocn(palette.nComps, sizeof(Guint));
707
1.09k
      palette.c =
708
1.09k
          (int *)gmallocn(palette.nEntries * palette.nComps, sizeof(int));
709
17.8k
      for (i = 0; i < palette.nComps; ++i) {
710
17.0k
  if (!readUByte(&palette.bpc[i])) {
711
221
    error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
712
221
    return jpxDecodeFatalError;
713
221
  }
714
16.7k
  ++palette.bpc[i];
715
16.7k
      }
716
410k
      for (i = 0; i < palette.nEntries; ++i) {
717
576k
  for (j = 0; j < palette.nComps; ++j) {
718
167k
    if (!readNBytes(((palette.bpc[j] & 0x7f) + 7) >> 3,
719
167k
        (palette.bpc[j] & 0x80) ? gTrue : gFalse,
720
167k
        &palette.c[i * palette.nComps + j])) {
721
389
      error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
722
389
      return jpxDecodeFatalError;
723
389
    }
724
167k
  }
725
410k
      }
726
484
      break;
727
1.61k
    case 0x636d6170:    // component mapping
728
1.61k
      cover(13);
729
1.61k
      haveCompMap = gTrue;
730
1.61k
      compMap.nChannels = dataLen / 4;
731
1.61k
      compMap.comp = (Guint *)gmallocn(compMap.nChannels, sizeof(Guint));
732
1.61k
      compMap.type = (Guint *)gmallocn(compMap.nChannels, sizeof(Guint));
733
1.61k
      compMap.pComp = (Guint *)gmallocn(compMap.nChannels, sizeof(Guint));
734
694k
      for (i = 0; i < compMap.nChannels; ++i) {
735
694k
  if (!readUWord(&compMap.comp[i]) ||
736
693k
      !readUByte(&compMap.type[i]) ||
737
693k
      !readUByte(&compMap.pComp[i])) {
738
1.05k
    error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
739
1.05k
    return jpxDecodeFatalError;
740
1.05k
  }
741
694k
      }
742
556
      break;
743
2.66k
    case 0x63646566:    // channel definition
744
2.66k
      cover(14);
745
2.66k
      if (!readUWord(&channelDefn.nChannels)) {
746
469
  error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
747
469
  return jpxDecodeFatalError;
748
469
      }
749
2.19k
      haveChannelDefn = gTrue;
750
2.19k
      channelDefn.idx =
751
2.19k
    (Guint *)gmallocn(channelDefn.nChannels, sizeof(Guint));
752
2.19k
      channelDefn.type =
753
2.19k
    (Guint *)gmallocn(channelDefn.nChannels, sizeof(Guint));
754
2.19k
      channelDefn.assoc =
755
2.19k
    (Guint *)gmallocn(channelDefn.nChannels, sizeof(Guint));
756
495k
      for (i = 0; i < channelDefn.nChannels; ++i) {
757
494k
  if (!readUWord(&channelDefn.idx[i]) ||
758
494k
      !readUWord(&channelDefn.type[i]) ||
759
493k
      !readUWord(&channelDefn.assoc[i])) {
760
1.70k
    error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
761
1.70k
    return jpxDecodeFatalError;
762
1.70k
  }
763
494k
      }
764
490
      break;
765
1.18k
    case 0x6A703263:    // contiguous codestream
766
1.18k
      cover(15);
767
1.18k
      if (!bpc) {
768
621
  error(errSyntaxError, getPos(),
769
621
        "JPX stream is missing the image header box");
770
621
      }
771
1.18k
      if (!haveCS) {
772
378
  error(errSyntaxError, getPos(),
773
378
        "JPX stream has no supported color spec");
774
378
      }
775
1.18k
      if ((result = readCodestream(dataLen)) != jpxDecodeOk) {
776
913
  return result;
777
913
      }
778
271
      haveCodestream = gTrue;
779
271
      break;
780
66.1k
    default:
781
66.1k
      cover(16);
782
66.1k
      if (bufStr->discardChars(dataLen) != dataLen) {
783
6.67k
  error(errSyntaxError, getPos(), "Unexpected EOF in JPX stream");
784
6.67k
  return haveCodestream ? jpxDecodeNonFatalError : jpxDecodeFatalError;
785
6.67k
      }
786
59.4k
      break;
787
111k
    }
788
111k
  }
789
5.16k
  return jpxDecodeOk;
790
25.8k
}
791
792
12.1k
GBool JPXStream::readColorSpecBox(Guint dataLen) {
793
12.1k
  JPXColorSpec newCS;
794
12.1k
  Guint csApprox, csEnum;
795
12.1k
  GBool ok;
796
797
12.1k
  ok = gFalse;
798
12.1k
  if (!readUByte(&newCS.meth) ||
799
11.8k
      !readByte(&newCS.prec) ||
800
11.5k
      !readUByte(&csApprox)) {
801
839
    goto err;
802
839
  }
803
11.2k
  switch (newCS.meth) {
804
10.0k
  case 1:     // enumerated colorspace
805
10.0k
    cover(17);
806
10.0k
    if (!readULong(&csEnum)) {
807
1.01k
      goto err;
808
1.01k
    }
809
9.00k
    newCS.enumerated.type = (JPXColorSpaceType)csEnum;
810
9.00k
    switch (newCS.enumerated.type) {
811
262
    case jpxCSBiLevel:
812
262
      ok = gTrue;
813
262
      break;
814
368
    case jpxCSYCbCr1:
815
368
      ok = gTrue;
816
368
      break;
817
240
    case jpxCSYCbCr2:
818
240
      ok = gTrue;
819
240
      break;
820
324
    case jpxCSYCBCr3:
821
324
      ok = gTrue;
822
324
      break;
823
257
    case jpxCSPhotoYCC:
824
257
      ok = gTrue;
825
257
      break;
826
278
    case jpxCSCMY:
827
278
      ok = gTrue;
828
278
      break;
829
242
    case jpxCSCMYK:
830
242
      ok = gTrue;
831
242
      break;
832
254
    case jpxCSYCCK:
833
254
      ok = gTrue;
834
254
      break;
835
4.25k
    case jpxCSCIELab:
836
4.25k
      if (dataLen == 7 + 7*4) {
837
3.72k
  if (!readULong(&newCS.enumerated.cieLab.rl) ||
838
3.48k
      !readULong(&newCS.enumerated.cieLab.ol) ||
839
3.24k
      !readULong(&newCS.enumerated.cieLab.ra) ||
840
3.02k
      !readULong(&newCS.enumerated.cieLab.oa) ||
841
2.80k
      !readULong(&newCS.enumerated.cieLab.rb) ||
842
2.54k
      !readULong(&newCS.enumerated.cieLab.ob) ||
843
2.31k
      !readULong(&newCS.enumerated.cieLab.il)) {
844
1.62k
    goto err;
845
1.62k
  }
846
3.72k
      } else if (dataLen == 7) {
847
  //~ this assumes the 8-bit case
848
232
  cover(92);
849
232
  newCS.enumerated.cieLab.rl = 100;
850
232
  newCS.enumerated.cieLab.ol = 0;
851
232
  newCS.enumerated.cieLab.ra = 255;
852
232
  newCS.enumerated.cieLab.oa = 128;
853
232
  newCS.enumerated.cieLab.rb = 255;
854
232
  newCS.enumerated.cieLab.ob = 96;
855
232
  newCS.enumerated.cieLab.il = 0x00443530;
856
289
      } else {
857
289
  goto err;
858
289
      }
859
2.33k
      ok = gTrue;
860
2.33k
      break;
861
318
    case jpxCSsRGB:
862
318
      ok = gTrue;
863
318
      break;
864
231
    case jpxCSGrayscale:
865
231
      ok = gTrue;
866
231
      break;
867
400
    case jpxCSBiLevel2:
868
400
      ok = gTrue;
869
400
      break;
870
0
    case jpxCSCIEJab:
871
      // not allowed in PDF
872
0
      goto err;
873
211
    case jpxCSCISesRGB:
874
211
      ok = gTrue;
875
211
      break;
876
257
    case jpxCSROMMRGB:
877
257
      ok = gTrue;
878
257
      break;
879
211
    case jpxCSsRGBYCbCr:
880
211
      ok = gTrue;
881
211
      break;
882
268
    case jpxCSYPbPr1125:
883
268
      ok = gTrue;
884
268
      break;
885
234
    case jpxCSYPbPr1250:
886
234
      ok = gTrue;
887
234
      break;
888
395
    default:
889
395
      goto err;
890
9.00k
    }
891
6.68k
    break;
892
6.68k
  case 2:     // restricted ICC profile
893
739
  case 3:       // any ICC profile (JPX)
894
1.07k
  case 4:     // vendor color (JPX)
895
1.07k
    cover(18);
896
1.07k
    if (dataLen > 3 &&
897
822
  bufStr->discardChars(dataLen - 3) != dataLen - 3) {
898
221
      goto err;
899
221
    }
900
855
    break;
901
11.2k
  }
902
903
7.75k
  if (ok && (!haveCS || newCS.prec > cs.prec)) {
904
5.69k
    cs = newCS;
905
5.69k
    haveCS = gTrue;
906
5.69k
  }
907
908
7.75k
  return gTrue;
909
910
4.38k
 err:
911
4.38k
  error(errSyntaxError, getPos(), "Error in JPX color spec");
912
4.38k
  return gFalse;
913
11.2k
}
914
915
86.7k
JPXDecodeResult JPXStream::readCodestream(Guint len) {
916
86.7k
  JPXTile *tile;
917
86.7k
  JPXTileComp *tileComp;
918
86.7k
  int segType;
919
86.7k
  GBool haveSIZ, haveCOD, haveQCD, haveSOT, ok;
920
86.7k
  Guint style, progOrder, nLayers, multiComp, nDecompLevels;
921
86.7k
  Guint codeBlockW, codeBlockH, codeBlockStyle, transform;
922
86.7k
  Guint precinctSize;
923
86.7k
  Guint segLen, capabilities, comp, i, j, r;
924
925
  //----- main header
926
86.7k
  haveSIZ = haveCOD = haveQCD = haveSOT = gFalse;
927
551k
  do {
928
551k
    if (!readMarkerHdr(&segType, &segLen)) {
929
3.26k
      error(errSyntaxError, getPos(), "Error in JPX codestream");
930
3.26k
      return jpxDecodeFatalError;
931
3.26k
    }
932
547k
    switch (segType) {
933
58.3k
    case 0x4f:      // SOC - start of codestream
934
      // marker only
935
58.3k
      cover(19);
936
58.3k
      break;
937
81.5k
    case 0x51:      // SIZ - image and tile size
938
81.5k
      cover(20);
939
81.5k
      if (haveSIZ) {
940
550
  error(errSyntaxError, getPos(),
941
550
        "Duplicate SIZ marker segment in JPX stream");
942
550
  return jpxDecodeFatalError;
943
550
      }
944
81.0k
      if (!readUWord(&capabilities) ||
945
80.4k
    !readULong(&img.xSize) ||
946
79.2k
    !readULong(&img.ySize) ||
947
78.1k
    !readULong(&img.xOffset) ||
948
77.2k
    !readULong(&img.yOffset) ||
949
76.1k
    !readULong(&img.xTileSize) ||
950
75.0k
    !readULong(&img.yTileSize) ||
951
73.8k
    !readULong(&img.xTileOffset) ||
952
73.0k
    !readULong(&img.yTileOffset) ||
953
71.9k
    !readUWord(&img.nComps)) {
954
9.50k
  error(errSyntaxError, getPos(), "Error in JPX SIZ marker segment");
955
9.50k
  return jpxDecodeFatalError;
956
9.50k
      }
957
71.4k
      if (haveImgHdr && img.nComps != nComps) {
958
285
  error(errSyntaxError, getPos(),
959
285
        "Different number of components in JPX SIZ marker segment");
960
285
  return jpxDecodeFatalError;
961
285
      }
962
71.2k
      if (img.xSize == 0 || img.ySize == 0 ||
963
70.6k
    img.xOffset >= img.xSize || img.yOffset >= img.ySize ||
964
69.7k
    img.xTileSize == 0 || img.yTileSize == 0 ||
965
69.0k
    img.xTileOffset > img.xOffset ||
966
68.1k
    img.yTileOffset > img.yOffset ||
967
67.6k
    img.xTileSize + img.xTileOffset <= img.xOffset ||
968
67.3k
    img.yTileSize + img.yTileOffset <= img.yOffset ||
969
67.0k
    img.nComps == 0) {
970
4.39k
  error(errSyntaxError, getPos(), "Error in JPX SIZ marker segment");
971
4.39k
  return jpxDecodeFatalError;
972
4.39k
      }
973
66.8k
      img.xSizeR = jpxCeilDivPow2(img.xSize, reduction);
974
66.8k
      img.ySizeR = jpxCeilDivPow2(img.ySize, reduction);
975
66.8k
      img.xOffsetR = jpxCeilDivPow2(img.xOffset, reduction);
976
66.8k
      img.yOffsetR = jpxCeilDivPow2(img.yOffset, reduction);
977
66.8k
      img.nXTiles = (img.xSize - img.xTileOffset + img.xTileSize - 1)
978
66.8k
              / img.xTileSize;
979
66.8k
      img.nYTiles = (img.ySize - img.yTileOffset + img.yTileSize - 1)
980
66.8k
              / img.yTileSize;
981
      // check for overflow before allocating memory
982
66.8k
      if (img.nXTiles <= 0 || img.nYTiles <= 0 ||
983
66.0k
    img.nXTiles >= INT_MAX / img.nYTiles) {
984
1.13k
  error(errSyntaxError, getPos(),
985
1.13k
        "Bad tile count in JPX SIZ marker segment");
986
1.13k
  return jpxDecodeFatalError;
987
1.13k
      }
988
65.6k
      img.tiles = (JPXTile *)gmallocn(img.nXTiles * img.nYTiles,
989
65.6k
              sizeof(JPXTile));
990
14.2M
      for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
991
14.1M
  img.tiles[i].init = gFalse;
992
14.1M
  img.tiles[i].nextTilePart = 0;
993
14.1M
  img.tiles[i].tileComps = NULL;
994
14.1M
      }
995
14.2M
      for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
996
14.1M
  img.tiles[i].tileComps = (JPXTileComp *)gmallocn(img.nComps,
997
14.1M
               sizeof(JPXTileComp));
998
86.9M
  for (comp = 0; comp < img.nComps; ++comp) {
999
72.7M
    img.tiles[i].tileComps[comp].quantSteps = NULL;
1000
72.7M
    img.tiles[i].tileComps[comp].data = NULL;
1001
72.7M
    img.tiles[i].tileComps[comp].buf = NULL;
1002
72.7M
    img.tiles[i].tileComps[comp].resLevels = NULL;
1003
72.7M
  }
1004
14.1M
      }
1005
1.61M
      for (comp = 0; comp < img.nComps; ++comp) {
1006
1.55M
  if (!readUByte(&img.tiles[0].tileComps[comp].prec) ||
1007
1.55M
      !readUByte(&img.tiles[0].tileComps[comp].hSep) ||
1008
1.55M
      !readUByte(&img.tiles[0].tileComps[comp].vSep)) {
1009
771
    error(errSyntaxError, getPos(), "Error in JPX SIZ marker segment");
1010
771
    return jpxDecodeFatalError;
1011
771
  }
1012
1.55M
  if (img.tiles[0].tileComps[comp].hSep == 0 ||
1013
1.55M
      img.tiles[0].tileComps[comp].vSep == 0) {
1014
491
    error(errSyntaxError, getPos(), "Error in JPX SIZ marker segment");
1015
491
    return jpxDecodeFatalError;
1016
491
  }
1017
1.55M
  img.tiles[0].tileComps[comp].sgned =
1018
1.55M
      (img.tiles[0].tileComps[comp].prec & 0x80) ? gTrue : gFalse;
1019
1.55M
  img.tiles[0].tileComps[comp].prec =
1020
1.55M
      (img.tiles[0].tileComps[comp].prec & 0x7f) + 1;
1021
24.5M
  for (i = 1; i < img.nXTiles * img.nYTiles; ++i) {
1022
22.9M
    img.tiles[i].tileComps[comp] = img.tiles[0].tileComps[comp];
1023
22.9M
  }
1024
1.55M
      }
1025
64.4k
      haveSIZ = gTrue;
1026
64.4k
      break;
1027
66.7k
    case 0x52:      // COD - coding style default
1028
66.7k
      cover(21);
1029
66.7k
      if (!haveSIZ) {
1030
432
  error(errSyntaxError, getPos(),
1031
432
        "JPX COD marker segment before SIZ segment");
1032
432
  return jpxDecodeFatalError;
1033
432
      }
1034
66.3k
      if (!readUByte(&style) ||
1035
66.0k
    !readUByte(&progOrder) ||
1036
65.8k
    !readUWord(&nLayers) ||
1037
65.3k
    !readUByte(&multiComp) ||
1038
65.0k
    !readUByte(&nDecompLevels) ||
1039
64.7k
    !readUByte(&codeBlockW) ||
1040
64.5k
    !readUByte(&codeBlockH) ||
1041
64.3k
    !readUByte(&codeBlockStyle) ||
1042
63.9k
    !readUByte(&transform)) {
1043
2.52k
  error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
1044
2.52k
  return jpxDecodeFatalError;
1045
2.52k
      }
1046
63.7k
      if (nDecompLevels < 1 ||
1047
63.5k
    nDecompLevels > 31 ||
1048
62.9k
    codeBlockW > 8 ||
1049
62.6k
    codeBlockH > 8) {
1050
1.39k
  error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
1051
1.39k
  return jpxDecodeFatalError;
1052
1.39k
      }
1053
62.3k
      codeBlockW += 2;
1054
62.3k
      codeBlockH += 2;
1055
10.7M
      for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
1056
10.6M
  img.tiles[i].progOrder = progOrder;
1057
10.6M
  img.tiles[i].nLayers = nLayers;
1058
10.6M
  img.tiles[i].multiComp = multiComp;
1059
31.0M
  for (comp = 0; comp < img.nComps; ++comp) {
1060
20.4M
    img.tiles[i].tileComps[comp].style = style;
1061
20.4M
    img.tiles[i].tileComps[comp].nDecompLevels = nDecompLevels;
1062
20.4M
    img.tiles[i].tileComps[comp].codeBlockW = codeBlockW;
1063
20.4M
    img.tiles[i].tileComps[comp].codeBlockH = codeBlockH;
1064
20.4M
    img.tiles[i].tileComps[comp].codeBlockStyle = codeBlockStyle;
1065
20.4M
    img.tiles[i].tileComps[comp].transform = transform;
1066
20.4M
    img.tiles[i].tileComps[comp].resLevels =
1067
20.4M
        (JPXResLevel *)gmallocn(nDecompLevels + 1, sizeof(JPXResLevel));
1068
105M
    for (r = 0; r <= nDecompLevels; ++r) {
1069
85.4M
      img.tiles[i].tileComps[comp].resLevels[r].precincts = NULL;
1070
85.4M
    }
1071
20.4M
  }
1072
10.6M
      }
1073
292k
      for (r = 0; r <= nDecompLevels; ++r) {
1074
230k
  if (style & 0x01) {
1075
25.4k
    cover(91);
1076
25.4k
    if (!readUByte(&precinctSize)) {
1077
279
      error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
1078
279
      return jpxDecodeFatalError;
1079
279
    }
1080
25.2k
    if (r > 0 && ((precinctSize & 0x0f) == 0 ||
1081
16.2k
      (precinctSize & 0xf0) == 0)) {
1082
536
      error(errSyntaxError, getPos(),
1083
536
      "Invalid precinct size in JPX COD marker segment");
1084
536
      return jpxDecodeFatalError;
1085
536
    }
1086
24.6k
    img.tiles[0].tileComps[0].resLevels[r].precinctWidth =
1087
24.6k
        precinctSize & 0x0f;
1088
24.6k
    img.tiles[0].tileComps[0].resLevels[r].precinctHeight =
1089
24.6k
        (precinctSize >> 4) & 0x0f;
1090
205k
  } else {
1091
205k
    img.tiles[0].tileComps[0].resLevels[r].precinctWidth = 15;
1092
205k
    img.tiles[0].tileComps[0].resLevels[r].precinctHeight = 15;
1093
205k
  }
1094
230k
      }
1095
10.7M
      for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
1096
31.0M
  for (comp = 0; comp < img.nComps; ++comp) {
1097
20.4M
    if (!(i == 0 && comp == 0)) {
1098
105M
      for (r = 0; r <= nDecompLevels; ++r) {
1099
85.1M
        img.tiles[i].tileComps[comp].resLevels[r].precinctWidth =
1100
85.1M
      img.tiles[0].tileComps[0].resLevels[r].precinctWidth;
1101
85.1M
        img.tiles[i].tileComps[comp].resLevels[r].precinctHeight =
1102
85.1M
      img.tiles[0].tileComps[0].resLevels[r].precinctHeight;
1103
85.1M
      }
1104
20.3M
    }
1105
20.4M
  }
1106
10.6M
      }
1107
61.5k
      haveCOD = gTrue;
1108
61.5k
      break;
1109
10.3k
    case 0x53:      // COC - coding style component
1110
10.3k
      cover(22);
1111
10.3k
      if (!haveCOD) {
1112
361
  error(errSyntaxError, getPos(),
1113
361
        "JPX COC marker segment before COD segment");
1114
361
  return jpxDecodeFatalError;
1115
361
      }
1116
9.96k
      comp = 0;
1117
9.96k
      if ((img.nComps > 256 && !readUWord(&comp)) ||
1118
9.45k
    (img.nComps <= 256 && !readUByte(&comp)) ||
1119
9.14k
    comp >= img.nComps ||
1120
8.92k
    !readUByte(&style) ||
1121
8.62k
    !readUByte(&nDecompLevels) ||
1122
8.29k
    !readUByte(&codeBlockW) ||
1123
8.03k
    !readUByte(&codeBlockH) ||
1124
7.80k
    !readUByte(&codeBlockStyle) ||
1125
7.55k
    !readUByte(&transform)) {
1126
2.63k
  error(errSyntaxError, getPos(), "Error in JPX COC marker segment");
1127
2.63k
  return jpxDecodeFatalError;
1128
2.63k
      }
1129
7.32k
      if (nDecompLevels < 1 ||
1130
7.23k
    nDecompLevels > 31 ||
1131
7.02k
    codeBlockW > 8 ||
1132
6.79k
    codeBlockH > 8) {
1133
801
  error(errSyntaxError, getPos(), "Error in JPX COC marker segment");
1134
801
  return jpxDecodeFatalError;
1135
801
      }
1136
6.52k
      style = (img.tiles[0].tileComps[comp].style & ~1) | (style & 1);
1137
6.52k
      codeBlockW += 2;
1138
6.52k
      codeBlockH += 2;
1139
721k
      for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
1140
715k
  img.tiles[i].tileComps[comp].style = style;
1141
715k
  img.tiles[i].tileComps[comp].nDecompLevels = nDecompLevels;
1142
715k
  img.tiles[i].tileComps[comp].codeBlockW = codeBlockW;
1143
715k
  img.tiles[i].tileComps[comp].codeBlockH = codeBlockH;
1144
715k
  img.tiles[i].tileComps[comp].codeBlockStyle = codeBlockStyle;
1145
715k
  img.tiles[i].tileComps[comp].transform = transform;
1146
715k
  img.tiles[i].tileComps[comp].resLevels =
1147
715k
      (JPXResLevel *)greallocn(
1148
715k
         img.tiles[i].tileComps[comp].resLevels,
1149
715k
         nDecompLevels + 1,
1150
715k
         sizeof(JPXResLevel));
1151
13.9M
  for (r = 0; r <= nDecompLevels; ++r) {
1152
13.2M
    img.tiles[i].tileComps[comp].resLevels[r].precincts = NULL;
1153
13.2M
  }
1154
715k
      }
1155
57.2k
      for (r = 0; r <= nDecompLevels; ++r) {
1156
51.3k
  if (style & 0x01) {
1157
4.16k
    if (!readUByte(&precinctSize)) {
1158
247
      error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
1159
247
      return jpxDecodeFatalError;
1160
247
    }
1161
3.91k
    if (r > 0 && ((precinctSize & 0x0f) == 0 ||
1162
2.03k
      (precinctSize & 0xf0) == 0)) {
1163
391
      error(errSyntaxError, getPos(),
1164
391
      "Invalid precinct size in JPX COD marker segment");
1165
391
      return jpxDecodeFatalError;
1166
391
    }
1167
3.52k
    img.tiles[0].tileComps[comp].resLevels[r].precinctWidth =
1168
3.52k
        precinctSize & 0x0f;
1169
3.52k
    img.tiles[0].tileComps[comp].resLevels[r].precinctHeight =
1170
3.52k
        (precinctSize >> 4) & 0x0f;
1171
47.1k
  } else {
1172
47.1k
    img.tiles[0].tileComps[comp].resLevels[r].precinctWidth = 15;
1173
47.1k
    img.tiles[0].tileComps[comp].resLevels[r].precinctHeight = 15;
1174
47.1k
  }
1175
51.3k
      }
1176
623k
      for (i = 1; i < img.nXTiles * img.nYTiles; ++i) {
1177
10.9M
  for (r = 0; r <= img.tiles[i].tileComps[comp].nDecompLevels; ++r) {
1178
10.3M
    img.tiles[i].tileComps[comp].resLevels[r].precinctWidth =
1179
10.3M
        img.tiles[0].tileComps[comp].resLevels[r].precinctWidth;
1180
10.3M
    img.tiles[i].tileComps[comp].resLevels[r].precinctHeight =
1181
10.3M
        img.tiles[0].tileComps[comp].resLevels[r].precinctHeight;
1182
10.3M
  }
1183
617k
      }
1184
5.88k
      break;
1185
62.9k
    case 0x5c:      // QCD - quantization default
1186
62.9k
      cover(23);
1187
62.9k
      if (!haveSIZ) {
1188
384
  error(errSyntaxError, getPos(),
1189
384
        "JPX QCD marker segment before SIZ segment");
1190
384
  return jpxDecodeFatalError;
1191
384
      }
1192
62.6k
      if (!readUByte(&img.tiles[0].tileComps[0].quantStyle)) {
1193
323
  error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1194
323
  return jpxDecodeFatalError;
1195
323
      }
1196
62.2k
      if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x00) {
1197
16.8k
  if (segLen <= 3) {
1198
351
    error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1199
351
    return jpxDecodeFatalError;
1200
351
  }
1201
16.5k
  img.tiles[0].tileComps[0].nQuantSteps = segLen - 3;
1202
16.5k
  img.tiles[0].tileComps[0].quantSteps =
1203
16.5k
      (Guint *)greallocn(img.tiles[0].tileComps[0].quantSteps,
1204
16.5k
             img.tiles[0].tileComps[0].nQuantSteps,
1205
16.5k
             sizeof(Guint));
1206
1.55M
  for (i = 0; i < img.tiles[0].tileComps[0].nQuantSteps; ++i) {
1207
1.54M
    if (!readUByte(&img.tiles[0].tileComps[0].quantSteps[i])) {
1208
367
      error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1209
367
      return jpxDecodeFatalError;
1210
367
    }
1211
1.54M
  }
1212
45.4k
      } else if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x01) {
1213
2.56k
  img.tiles[0].tileComps[0].nQuantSteps = 1;
1214
2.56k
  img.tiles[0].tileComps[0].quantSteps =
1215
2.56k
      (Guint *)greallocn(img.tiles[0].tileComps[0].quantSteps,
1216
2.56k
             img.tiles[0].tileComps[0].nQuantSteps,
1217
2.56k
             sizeof(Guint));
1218
2.56k
  if (!readUWord(&img.tiles[0].tileComps[0].quantSteps[0])) {
1219
525
    error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1220
525
    return jpxDecodeFatalError;
1221
525
  }
1222
42.8k
      } else if ((img.tiles[0].tileComps[0].quantStyle & 0x1f) == 0x02) {
1223
42.4k
  if (segLen < 5) {
1224
235
    error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1225
235
    return jpxDecodeFatalError;
1226
235
  }
1227
42.1k
  img.tiles[0].tileComps[0].nQuantSteps = (segLen - 3) / 2;
1228
42.1k
  img.tiles[0].tileComps[0].quantSteps =
1229
42.1k
      (Guint *)greallocn(img.tiles[0].tileComps[0].quantSteps,
1230
42.1k
             img.tiles[0].tileComps[0].nQuantSteps,
1231
42.1k
             sizeof(Guint));
1232
1.58M
  for (i = 0; i < img.tiles[0].tileComps[0].nQuantSteps; ++i) {
1233
1.54M
    if (!readUWord(&img.tiles[0].tileComps[0].quantSteps[i])) {
1234
795
      error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1235
795
      return jpxDecodeFatalError;
1236
795
    }
1237
1.54M
  }
1238
42.1k
      } else {
1239
421
  error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1240
421
  return jpxDecodeFatalError;
1241
421
      }
1242
8.57M
      for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
1243
25.3M
  for (comp = 0; comp < img.nComps; ++comp) {
1244
16.8M
    if (!(i == 0 && comp == 0)) {
1245
16.8M
      img.tiles[i].tileComps[comp].quantStyle =
1246
16.8M
          img.tiles[0].tileComps[0].quantStyle;
1247
16.8M
      img.tiles[i].tileComps[comp].nQuantSteps =
1248
16.8M
          img.tiles[0].tileComps[0].nQuantSteps;
1249
16.8M
      img.tiles[i].tileComps[comp].quantSteps = 
1250
16.8M
          (Guint *)greallocn(img.tiles[i].tileComps[comp].quantSteps,
1251
16.8M
           img.tiles[0].tileComps[0].nQuantSteps,
1252
16.8M
           sizeof(Guint));
1253
282M
      for (j = 0; j < img.tiles[0].tileComps[0].nQuantSteps; ++j) {
1254
265M
        img.tiles[i].tileComps[comp].quantSteps[j] =
1255
265M
      img.tiles[0].tileComps[0].quantSteps[j];
1256
265M
      }
1257
16.8M
    }
1258
16.8M
  }
1259
8.51M
      }
1260
59.5k
      haveQCD = gTrue;
1261
59.5k
      break;
1262
5.91k
    case 0x5d:      // QCC - quantization component
1263
5.91k
      cover(24);
1264
5.91k
      if (!haveQCD) {
1265
330
  error(errSyntaxError, getPos(),
1266
330
        "JPX QCC marker segment before QCD segment");
1267
330
  return jpxDecodeFatalError;
1268
330
      }
1269
5.58k
      comp = 0;
1270
5.58k
      if ((img.nComps > 256 && !readUWord(&comp)) ||
1271
5.11k
    (img.nComps <= 256 && !readUByte(&comp)) ||
1272
4.83k
    comp >= img.nComps ||
1273
4.46k
    !readUByte(&img.tiles[0].tileComps[comp].quantStyle)) {
1274
1.33k
  error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
1275
1.33k
  return jpxDecodeFatalError;
1276
1.33k
      }
1277
4.25k
      if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x00) {
1278
1.58k
  if (segLen <= (img.nComps > 256 ? 5U : 4U)) {
1279
217
    error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
1280
217
    return jpxDecodeFatalError;
1281
217
  }
1282
1.37k
  img.tiles[0].tileComps[comp].nQuantSteps =
1283
1.37k
      segLen - (img.nComps > 256 ? 5 : 4);
1284
1.37k
  img.tiles[0].tileComps[comp].quantSteps =
1285
1.37k
      (Guint *)greallocn(img.tiles[0].tileComps[comp].quantSteps,
1286
1.37k
             img.tiles[0].tileComps[comp].nQuantSteps,
1287
1.37k
             sizeof(Guint));
1288
615k
  for (i = 0; i < img.tiles[0].tileComps[comp].nQuantSteps; ++i) {
1289
614k
    if (!readUByte(&img.tiles[0].tileComps[comp].quantSteps[i])) {
1290
431
      error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
1291
431
      return jpxDecodeFatalError;
1292
431
    }
1293
614k
  }
1294
2.66k
      } else if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x01) {
1295
1.25k
  img.tiles[0].tileComps[comp].nQuantSteps = 1;
1296
1.25k
  img.tiles[0].tileComps[comp].quantSteps =
1297
1.25k
      (Guint *)greallocn(img.tiles[0].tileComps[comp].quantSteps,
1298
1.25k
             img.tiles[0].tileComps[comp].nQuantSteps,
1299
1.25k
             sizeof(Guint));
1300
1.25k
  if (!readUWord(&img.tiles[0].tileComps[comp].quantSteps[0])) {
1301
532
    error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
1302
532
    return jpxDecodeFatalError;
1303
532
  }
1304
1.41k
      } else if ((img.tiles[0].tileComps[comp].quantStyle & 0x1f) == 0x02) {
1305
1.15k
  if (segLen < (img.nComps > 256 ? 5U : 4U) + 2) {
1306
322
    error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
1307
322
    return jpxDecodeFatalError;
1308
322
  }
1309
831
  img.tiles[0].tileComps[comp].nQuantSteps =
1310
831
      (segLen - (img.nComps > 256 ? 5 : 4)) / 2;
1311
831
  img.tiles[0].tileComps[comp].quantSteps =
1312
831
      (Guint *)greallocn(img.tiles[0].tileComps[comp].quantSteps,
1313
831
             img.tiles[0].tileComps[comp].nQuantSteps,
1314
831
             sizeof(Guint));
1315
49.6k
  for (i = 0; i < img.tiles[0].tileComps[comp].nQuantSteps; ++i) {
1316
49.3k
    if (!readUWord(&img.tiles[0].tileComps[comp].quantSteps[i])) {
1317
595
      error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1318
595
      return jpxDecodeFatalError;
1319
595
    }
1320
49.3k
  }
1321
831
      } else {
1322
258
  error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
1323
258
  return jpxDecodeFatalError;
1324
258
      }
1325
49.9k
      for (i = 1; i < img.nXTiles * img.nYTiles; ++i) {
1326
48.0k
  img.tiles[i].tileComps[comp].quantStyle =
1327
48.0k
      img.tiles[0].tileComps[comp].quantStyle;
1328
48.0k
  img.tiles[i].tileComps[comp].nQuantSteps =
1329
48.0k
      img.tiles[0].tileComps[comp].nQuantSteps;
1330
48.0k
  img.tiles[i].tileComps[comp].quantSteps = 
1331
48.0k
      (Guint *)greallocn(img.tiles[i].tileComps[comp].quantSteps,
1332
48.0k
             img.tiles[0].tileComps[comp].nQuantSteps,
1333
48.0k
             sizeof(Guint));
1334
469k
  for (j = 0; j < img.tiles[0].tileComps[comp].nQuantSteps; ++j) {
1335
420k
    img.tiles[i].tileComps[comp].quantSteps[j] =
1336
420k
        img.tiles[0].tileComps[comp].quantSteps[j];
1337
420k
  }
1338
48.0k
      }
1339
1.89k
      break;
1340
113k
    case 0x5e:      // RGN - region of interest
1341
113k
      cover(25);
1342
113k
#if 1 //~ ROI is unimplemented
1343
113k
      error(errUnimplemented, -1, "got a JPX RGN segment");
1344
113k
      if (segLen > 2 &&
1345
111k
    bufStr->discardChars(segLen - 2) != segLen - 2) {
1346
639
  error(errSyntaxError, getPos(), "Error in JPX RGN marker segment");
1347
639
  return jpxDecodeFatalError;
1348
639
      }
1349
#else
1350
      if ((img.nComps > 256 && !readUWord(&comp)) ||
1351
    (img.nComps <= 256 && !readUByte(&comp)) ||
1352
    comp >= img.nComps ||
1353
    !readUByte(&compInfo[comp].defROI.style) ||
1354
    !readUByte(&compInfo[comp].defROI.shift)) {
1355
  error(errSyntaxError, getPos(), "Error in JPX RGN marker segment");
1356
  return jpxDecodeFatalError;
1357
      }
1358
#endif
1359
112k
      break;
1360
112k
    case 0x5f:      // POC - progression order change
1361
14.5k
      cover(26);
1362
14.5k
#if 1 //~ progression order changes are unimplemented
1363
14.5k
      error(errUnimplemented, -1, "got a JPX POC segment");
1364
14.5k
      if (segLen > 2 &&
1365
10.8k
    bufStr->discardChars(segLen - 2) != segLen - 2) {
1366
241
  error(errSyntaxError, getPos(), "Error in JPX POC marker segment");
1367
241
  return jpxDecodeFatalError;
1368
241
      }
1369
#else
1370
      nProgs = (segLen - 2) / (img.nComps > 256 ? 9 : 7);
1371
      progs = (JPXProgOrder *)gmallocn(nProgs, sizeof(JPXProgOrder));
1372
      for (i = 0; i < nProgs; ++i) {
1373
  if (!readUByte(&progs[i].startRes) ||
1374
      !(img.nComps > 256 && readUWord(&progs[i].startComp)) ||
1375
      !(img.nComps <= 256 && readUByte(&progs[i].startComp)) ||
1376
      !readUWord(&progs[i].endLayer) ||
1377
      !readUByte(&progs[i].endRes) ||
1378
      !(img.nComps > 256 && readUWord(&progs[i].endComp)) ||
1379
      !(img.nComps <= 256 && readUByte(&progs[i].endComp)) ||
1380
      !readUByte(&progs[i].progOrder)) {
1381
    error(errSyntaxError, getPos(), "Error in JPX POC marker segment");
1382
    return jpxDecodeFatalError;
1383
  }
1384
      }
1385
#endif
1386
14.3k
      break;
1387
14.3k
    case 0x60:      // PPM - packed packet headers, main header
1388
7.29k
      cover(27);
1389
7.29k
#if 1 //~ packed packet headers are unimplemented
1390
7.29k
      error(errUnimplemented, -1, "Got a JPX PPM segment");
1391
7.29k
      if (segLen > 2 &&
1392
6.37k
    bufStr->discardChars(segLen - 2) != segLen - 2) {
1393
259
  error(errSyntaxError, getPos(), "Error in JPX PPM marker segment");
1394
259
  return jpxDecodeFatalError;
1395
259
      }
1396
7.04k
#endif
1397
7.04k
      break;
1398
7.04k
    case 0x55:      // TLM - tile-part lengths
1399
      // skipped
1400
1.80k
      cover(28);
1401
1.80k
      if (segLen > 2 &&
1402
963
    bufStr->discardChars(segLen - 2) != segLen - 2) {
1403
450
  error(errSyntaxError, getPos(), "Error in JPX TLM marker segment");
1404
450
  return jpxDecodeFatalError;
1405
450
      }
1406
1.35k
      break;
1407
2.11k
    case 0x57:      // PLM - packet length, main header
1408
      // skipped
1409
2.11k
      cover(29);
1410
2.11k
      if (segLen > 2 &&
1411
1.82k
    bufStr->discardChars(segLen - 2) != segLen - 2) {
1412
325
  error(errSyntaxError, getPos(), "Error in JPX PLM marker segment");
1413
325
  return jpxDecodeFatalError;
1414
325
      }
1415
1.78k
      break;
1416
1.92k
    case 0x63:      // CRG - component registration
1417
      // skipped
1418
1.92k
      cover(30);
1419
1.92k
      if (segLen > 2 &&
1420
759
    bufStr->discardChars(segLen - 2) != segLen - 2) {
1421
437
  error(errSyntaxError, getPos(), "Error in JPX CRG marker segment");
1422
437
  return jpxDecodeFatalError;
1423
437
      }
1424
1.48k
      break;
1425
2.78k
    case 0x64:      // COM - comment
1426
      // skipped
1427
2.78k
      cover(31);
1428
2.78k
      if (segLen > 2 &&
1429
1.62k
    bufStr->discardChars(segLen - 2) != segLen - 2) {
1430
560
  error(errSyntaxError, getPos(), "Error in JPX COM marker segment");
1431
560
  return jpxDecodeFatalError;
1432
560
      }
1433
2.22k
      break;
1434
46.3k
    case 0x90:      // SOT - start of tile
1435
46.3k
      cover(32);
1436
46.3k
      haveSOT = gTrue;
1437
46.3k
      break;
1438
72.0k
    default:
1439
72.0k
      cover(33);
1440
72.0k
      error(errSyntaxError, getPos(),
1441
72.0k
      "Unknown marker segment {0:02x} in JPX stream", segType);
1442
72.0k
      if (segLen > 2) {
1443
25.1k
  bufStr->discardChars(segLen - 2);
1444
25.1k
      }
1445
72.0k
      break;
1446
547k
    }
1447
547k
  } while (!haveSOT);
1448
1449
46.3k
  if (!haveSIZ) {
1450
274
    error(errSyntaxError, getPos(),
1451
274
    "Missing SIZ marker segment in JPX stream");
1452
274
    return jpxDecodeFatalError;
1453
274
  }
1454
46.0k
  if (!haveCOD) {
1455
365
    error(errSyntaxError, getPos(),
1456
365
    "Missing COD marker segment in JPX stream");
1457
365
    return jpxDecodeFatalError;
1458
365
  }
1459
45.7k
  if (!haveQCD) {
1460
361
    error(errSyntaxError, getPos(),
1461
361
    "Missing QCD marker segment in JPX stream");
1462
361
    return jpxDecodeFatalError;
1463
361
  }
1464
1465
  //----- read the tile-parts
1466
45.3k
  ok = gTrue;
1467
47.7k
  while (1) {
1468
47.7k
    if (!readTilePart()) {
1469
40.0k
      ok = gFalse;
1470
40.0k
      break;
1471
40.0k
    }
1472
7.67k
    if (!readMarkerHdr(&segType, &segLen)) {
1473
2.56k
      error(errSyntaxError, getPos(), "Error in JPX codestream");
1474
2.56k
      ok = gFalse;
1475
2.56k
      break;
1476
2.56k
    }
1477
5.10k
    if (segType != 0x90) { // SOT - start of tile
1478
2.71k
      break;
1479
2.71k
    }
1480
5.10k
  }
1481
1482
45.3k
  if (segType != 0xd9) { // EOC - end of codestream
1483
44.8k
    error(errSyntaxError, getPos(), "Missing EOC marker in JPX codestream");
1484
44.8k
    ok = gFalse;
1485
44.8k
  }
1486
1487
  //----- finish decoding the image
1488
57.1k
  for (i = 0; i < img.nXTiles * img.nYTiles; ++i) {
1489
46.7k
    tile = &img.tiles[i];
1490
46.7k
    if (!tile->init) {
1491
27.7k
      error(errSyntaxError, getPos(), "Uninitialized tile in JPX codestream");
1492
27.7k
      return jpxDecodeFatalError;
1493
27.7k
    }
1494
83.6k
    for (comp = 0; comp < img.nComps; ++comp) {
1495
64.6k
      tileComp = &tile->tileComps[comp];
1496
64.6k
      inverseTransform(tileComp);
1497
64.6k
    }
1498
18.9k
    if (!inverseMultiCompAndDC(tile)) {
1499
7.15k
      return jpxDecodeFatalError;
1500
7.15k
    }
1501
18.9k
  }
1502
1503
  //~ can free memory below tileComps here, and also tileComp.buf
1504
1505
10.4k
  return ok ? jpxDecodeOk : jpxDecodeNonFatalError;
1506
45.3k
}
1507
1508
47.7k
GBool JPXStream::readTilePart() {
1509
47.7k
  JPXTile *tile;
1510
47.7k
  JPXTileComp *tileComp;
1511
47.7k
  JPXResLevel *resLevel;
1512
47.7k
  JPXPrecinct *precinct;
1513
47.7k
  JPXSubband *subband;
1514
47.7k
  JPXCodeBlock *cb;
1515
47.7k
  int *sbCoeffs;
1516
47.7k
  GBool haveSOD;
1517
47.7k
  Guint tileIdx, tilePartLen, tilePartIdx, nTileParts;
1518
47.7k
  GBool tilePartToEOC;
1519
47.7k
  Guint style, progOrder, nLayers, multiComp, nDecompLevels;
1520
47.7k
  Guint codeBlockW, codeBlockH, codeBlockStyle, transform;
1521
47.7k
  Guint precinctSize, qStyle;
1522
47.7k
  Guint px0, py0, px1, py1;
1523
47.7k
  Guint preCol0, preCol1, preRow0, preRow1, preCol, preRow;
1524
47.7k
  Guint cbCol0, cbCol1, cbRow0, cbRow1, cbX, cbY;
1525
47.7k
  Guint n, nSBs, nx, ny, comp, segLen;
1526
47.7k
  Guint i, j, k, r, pre, sb, cbi, cbj;
1527
47.7k
  int segType, level;
1528
1529
  // process the SOT marker segment
1530
47.7k
  if (!readUWord(&tileIdx) ||
1531
47.1k
      !readULong(&tilePartLen) ||
1532
45.9k
      !readUByte(&tilePartIdx) ||
1533
45.5k
      !readUByte(&nTileParts)) {
1534
2.60k
    error(errSyntaxError, getPos(), "Error in JPX SOT marker segment");
1535
2.60k
    return gFalse;
1536
2.60k
  }
1537
1538
  // check tileIdx and tilePartIdx
1539
  // (this ignores nTileParts, because some encoders get it wrong)
1540
45.1k
  if (tileIdx >= img.nXTiles * img.nYTiles ||
1541
44.7k
      tilePartIdx != img.tiles[tileIdx].nextTilePart ||
1542
44.4k
      (tilePartIdx > 0 && !img.tiles[tileIdx].init) ||
1543
44.4k
      (tilePartIdx == 0 && img.tiles[tileIdx].init)) {
1544
715
    error(errSyntaxError, getPos(), "Weird tile-part header in JPX stream");
1545
715
    return gFalse;
1546
715
  }
1547
44.4k
  ++img.tiles[tileIdx].nextTilePart;
1548
1549
44.4k
  tilePartToEOC = tilePartLen == 0;
1550
44.4k
  tilePartLen -= 12; // subtract size of SOT segment
1551
1552
44.4k
  haveSOD = gFalse;
1553
229k
  do {
1554
229k
    if (!readMarkerHdr(&segType, &segLen)) {
1555
4.91k
      error(errSyntaxError, getPos(), "Error in JPX tile-part codestream");
1556
4.91k
      return gFalse;
1557
4.91k
    }
1558
224k
    tilePartLen -= 2 + segLen;
1559
224k
    switch (segType) {
1560
20.0k
    case 0x52:      // COD - coding style default
1561
20.0k
      cover(34);
1562
20.0k
      if (tilePartIdx != 0) {
1563
390
  error(errSyntaxError, getPos(), "Extraneous JPX COD marker segment");
1564
390
  return gFalse;
1565
390
      }
1566
19.6k
      if (!readUByte(&style) ||
1567
19.3k
    !readUByte(&progOrder) ||
1568
19.0k
    !readUWord(&nLayers) ||
1569
18.3k
    !readUByte(&multiComp) ||
1570
18.0k
    !readUByte(&nDecompLevels) ||
1571
17.7k
    !readUByte(&codeBlockW) ||
1572
17.5k
    !readUByte(&codeBlockH) ||
1573
17.2k
    !readUByte(&codeBlockStyle) ||
1574
16.9k
    !readUByte(&transform)) {
1575
2.98k
  error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
1576
2.98k
  return gFalse;
1577
2.98k
      }
1578
16.6k
      if (nDecompLevels < 1 ||
1579
16.5k
    nDecompLevels > 31 ||
1580
16.3k
    codeBlockW > 8 ||
1581
16.2k
    codeBlockH > 8) {
1582
844
  error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
1583
844
  return gFalse;
1584
844
      }
1585
15.8k
      codeBlockW += 2;
1586
15.8k
      codeBlockH += 2;
1587
15.8k
      img.tiles[tileIdx].progOrder = progOrder;
1588
15.8k
      img.tiles[tileIdx].nLayers = nLayers;
1589
15.8k
      img.tiles[tileIdx].multiComp = multiComp;
1590
210k
      for (comp = 0; comp < img.nComps; ++comp) {
1591
194k
  img.tiles[tileIdx].tileComps[comp].style = style;
1592
194k
  img.tiles[tileIdx].tileComps[comp].nDecompLevels = nDecompLevels;
1593
194k
  img.tiles[tileIdx].tileComps[comp].codeBlockW = codeBlockW;
1594
194k
  img.tiles[tileIdx].tileComps[comp].codeBlockH = codeBlockH;
1595
194k
  img.tiles[tileIdx].tileComps[comp].codeBlockStyle = codeBlockStyle;
1596
194k
  img.tiles[tileIdx].tileComps[comp].transform = transform;
1597
194k
  img.tiles[tileIdx].tileComps[comp].resLevels =
1598
194k
      (JPXResLevel *)greallocn(
1599
194k
         img.tiles[tileIdx].tileComps[comp].resLevels,
1600
194k
         nDecompLevels + 1,
1601
194k
         sizeof(JPXResLevel));
1602
787k
  for (r = 0; r <= nDecompLevels; ++r) {
1603
593k
    img.tiles[tileIdx].tileComps[comp].resLevels[r].precincts = NULL;
1604
593k
  }
1605
194k
      }
1606
63.6k
      for (r = 0; r <= nDecompLevels; ++r) {
1607
48.5k
  if (style & 0x01) {
1608
3.84k
    if (!readUByte(&precinctSize)) {
1609
301
      error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
1610
301
      return gFalse;
1611
301
    }
1612
3.54k
    if (r > 0 && ((precinctSize & 0x0f) == 0 ||
1613
1.66k
      (precinctSize & 0xf0) == 0)) {
1614
395
      error(errSyntaxError, getPos(),
1615
395
      "Invalid precinct size in JPX COD marker segment");
1616
395
      return gFalse;
1617
395
    }
1618
3.14k
    img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth =
1619
3.14k
        precinctSize & 0x0f;
1620
3.14k
    img.tiles[tileIdx].tileComps[0].resLevels[r].precinctHeight =
1621
3.14k
        (precinctSize >> 4) & 0x0f;
1622
44.7k
  } else {
1623
44.7k
    img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth = 15;
1624
44.7k
    img.tiles[tileIdx].tileComps[0].resLevels[r].precinctHeight = 15;
1625
44.7k
  }
1626
48.5k
      }
1627
192k
      for (comp = 1; comp < img.nComps; ++comp) {
1628
717k
  for (r = 0; r <= nDecompLevels; ++r) {
1629
540k
    img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth =
1630
540k
        img.tiles[tileIdx].tileComps[0].resLevels[r].precinctWidth;
1631
540k
    img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctHeight =
1632
540k
        img.tiles[tileIdx].tileComps[0].resLevels[r].precinctHeight;
1633
540k
  }
1634
177k
      }
1635
15.1k
      break;
1636
26.6k
    case 0x53:      // COC - coding style component
1637
26.6k
      cover(35);
1638
26.6k
      if (tilePartIdx != 0) {
1639
490
  error(errSyntaxError, getPos(), "Extraneous JPX COC marker segment");
1640
490
  return gFalse;
1641
490
      }
1642
26.1k
      comp = 0;
1643
26.1k
      if ((img.nComps > 256 && !readUWord(&comp)) ||
1644
25.5k
    (img.nComps <= 256 && !readUByte(&comp)) ||
1645
25.2k
    comp >= img.nComps ||
1646
24.8k
    !readUByte(&style) ||
1647
24.5k
    !readUByte(&nDecompLevels) ||
1648
24.2k
    !readUByte(&codeBlockW) ||
1649
24.0k
    !readUByte(&codeBlockH) ||
1650
23.7k
    !readUByte(&codeBlockStyle) ||
1651
23.4k
    !readUByte(&transform)) {
1652
3.06k
  error(errSyntaxError, getPos(), "Error in JPX COC marker segment");
1653
3.06k
  return gFalse;
1654
3.06k
      }
1655
23.1k
      if (nDecompLevels < 1 ||
1656
22.8k
    nDecompLevels > 31 ||
1657
22.4k
    codeBlockW > 8 ||
1658
22.3k
    codeBlockH > 8) {
1659
880
  error(errSyntaxError, getPos(), "Error in JPX COC marker segment");
1660
880
  return gFalse;
1661
880
      }
1662
22.2k
      img.tiles[tileIdx].tileComps[comp].style =
1663
22.2k
    (img.tiles[tileIdx].tileComps[comp].style & ~1) | (style & 1);
1664
22.2k
      img.tiles[tileIdx].tileComps[comp].nDecompLevels = nDecompLevels;
1665
22.2k
      img.tiles[tileIdx].tileComps[comp].codeBlockW = codeBlockW + 2;
1666
22.2k
      img.tiles[tileIdx].tileComps[comp].codeBlockH = codeBlockH + 2;
1667
22.2k
      img.tiles[tileIdx].tileComps[comp].codeBlockStyle = codeBlockStyle;
1668
22.2k
      img.tiles[tileIdx].tileComps[comp].transform = transform;
1669
22.2k
      img.tiles[tileIdx].tileComps[comp].resLevels =
1670
22.2k
    (JPXResLevel *)greallocn(
1671
22.2k
         img.tiles[tileIdx].tileComps[comp].resLevels,
1672
22.2k
         nDecompLevels + 1,
1673
22.2k
         sizeof(JPXResLevel));
1674
511k
      for (r = 0; r <= nDecompLevels; ++r) {
1675
489k
  img.tiles[tileIdx].tileComps[comp].resLevels[r].precincts = NULL;
1676
489k
      }
1677
509k
      for (r = 0; r <= nDecompLevels; ++r) {
1678
488k
  if (style & 0x01) {
1679
12.0k
    if (!readUByte(&precinctSize)) {
1680
233
      error(errSyntaxError, getPos(), "Error in JPX COD marker segment");
1681
233
      return gFalse;
1682
233
    }
1683
11.8k
    if (r > 0 && ((precinctSize & 0x0f) == 0 ||
1684
5.75k
      (precinctSize & 0xf0) == 0)) {
1685
515
      error(errSyntaxError, getPos(),
1686
515
      "Invalid precinct size in JPX COD marker segment");
1687
515
      return gFalse;
1688
515
    }
1689
11.2k
    img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth =
1690
11.2k
        precinctSize & 0x0f;
1691
11.2k
    img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctHeight =
1692
11.2k
        (precinctSize >> 4) & 0x0f;
1693
476k
  } else {
1694
476k
    img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctWidth = 15;
1695
476k
    img.tiles[tileIdx].tileComps[comp].resLevels[r].precinctHeight = 15;
1696
476k
  }
1697
488k
      }
1698
21.4k
      break;
1699
21.4k
    case 0x5c:      // QCD - quantization default
1700
18.4k
      cover(36);
1701
18.4k
      if (tilePartIdx != 0) {
1702
275
  error(errSyntaxError, getPos(), "Extraneous JPX QCD marker segment");
1703
275
  return gFalse;
1704
275
      }
1705
18.1k
      if (!readUByte(&img.tiles[tileIdx].tileComps[0].quantStyle)) {
1706
426
  error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1707
426
  return gFalse;
1708
426
      }
1709
17.7k
      if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x00) {
1710
6.51k
  if (segLen <= 3) {
1711
379
    error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1712
379
    return gFalse;
1713
379
  }
1714
6.13k
  img.tiles[tileIdx].tileComps[0].nQuantSteps = segLen - 3;
1715
6.13k
  img.tiles[tileIdx].tileComps[0].quantSteps =
1716
6.13k
      (Guint *)greallocn(img.tiles[tileIdx].tileComps[0].quantSteps,
1717
6.13k
             img.tiles[tileIdx].tileComps[0].nQuantSteps,
1718
6.13k
             sizeof(Guint));
1719
330k
  for (i = 0; i < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++i) {
1720
324k
    if (!readUByte(&img.tiles[tileIdx].tileComps[0].quantSteps[i])) {
1721
260
      error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1722
260
      return gFalse;
1723
260
    }
1724
324k
  }
1725
11.2k
      } else if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x01) {
1726
2.85k
  img.tiles[tileIdx].tileComps[0].nQuantSteps = 1;
1727
2.85k
  img.tiles[tileIdx].tileComps[0].quantSteps =
1728
2.85k
      (Guint *)greallocn(img.tiles[tileIdx].tileComps[0].quantSteps,
1729
2.85k
             img.tiles[tileIdx].tileComps[0].nQuantSteps,
1730
2.85k
             sizeof(Guint));
1731
2.85k
  if (!readUWord(&img.tiles[tileIdx].tileComps[0].quantSteps[0])) {
1732
88
    error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1733
88
    return gFalse;
1734
88
  }
1735
8.36k
      } else if ((img.tiles[tileIdx].tileComps[0].quantStyle & 0x1f) == 0x02) {
1736
8.13k
  if (segLen < 5) {
1737
243
    error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1738
243
    return gFalse;
1739
243
  }
1740
7.89k
  img.tiles[tileIdx].tileComps[0].nQuantSteps = (segLen - 3) / 2;
1741
7.89k
  img.tiles[tileIdx].tileComps[0].quantSteps =
1742
7.89k
      (Guint *)greallocn(img.tiles[tileIdx].tileComps[0].quantSteps,
1743
7.89k
             img.tiles[tileIdx].tileComps[0].nQuantSteps,
1744
7.89k
             sizeof(Guint));
1745
135k
  for (i = 0; i < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++i) {
1746
128k
    if (!readUWord(&img.tiles[tileIdx].tileComps[0].quantSteps[i])) {
1747
485
      error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1748
485
      return gFalse;
1749
485
    }
1750
128k
  }
1751
7.89k
      } else {
1752
229
  error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1753
229
  return gFalse;
1754
229
      }
1755
127k
      for (comp = 1; comp < img.nComps; ++comp) {
1756
111k
  img.tiles[tileIdx].tileComps[comp].quantStyle =
1757
111k
      img.tiles[tileIdx].tileComps[0].quantStyle;
1758
111k
  img.tiles[tileIdx].tileComps[comp].nQuantSteps =
1759
111k
      img.tiles[tileIdx].tileComps[0].nQuantSteps;
1760
111k
  img.tiles[tileIdx].tileComps[comp].quantSteps = 
1761
111k
      (Guint *)greallocn(img.tiles[tileIdx].tileComps[comp].quantSteps,
1762
111k
             img.tiles[tileIdx].tileComps[0].nQuantSteps,
1763
111k
             sizeof(Guint));
1764
2.14M
  for (j = 0; j < img.tiles[tileIdx].tileComps[0].nQuantSteps; ++j) {
1765
2.03M
    img.tiles[tileIdx].tileComps[comp].quantSteps[j] =
1766
2.03M
        img.tiles[tileIdx].tileComps[0].quantSteps[j];
1767
2.03M
  }
1768
111k
      }
1769
16.0k
      break;
1770
8.68k
    case 0x5d:      // QCC - quantization component
1771
8.68k
      cover(37);
1772
8.68k
      if (tilePartIdx != 0) {
1773
295
  error(errSyntaxError, getPos(), "Extraneous JPX QCC marker segment");
1774
295
  return gFalse;
1775
295
      }
1776
8.38k
      comp = 0;
1777
8.38k
      if ((img.nComps > 256 && !readUWord(&comp)) ||
1778
7.87k
    (img.nComps <= 256 && !readUByte(&comp)) ||
1779
7.59k
    comp >= img.nComps ||
1780
7.33k
    !readUByte(&img.tiles[tileIdx].tileComps[comp].quantStyle)) {
1781
1.29k
  error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
1782
1.29k
  return gFalse;
1783
1.29k
      }
1784
7.09k
      if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f) == 0x00) {
1785
1.30k
  if (segLen <= (img.nComps > 256 ? 5U : 4U)) {
1786
243
    error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
1787
243
    return gFalse;
1788
243
  }
1789
1.05k
  img.tiles[tileIdx].tileComps[comp].nQuantSteps =
1790
1.05k
      segLen - (img.nComps > 256 ? 5 : 4);
1791
1.05k
  img.tiles[tileIdx].tileComps[comp].quantSteps =
1792
1.05k
      (Guint *)greallocn(img.tiles[tileIdx].tileComps[comp].quantSteps,
1793
1.05k
             img.tiles[tileIdx].tileComps[comp].nQuantSteps,
1794
1.05k
             sizeof(Guint));
1795
26.3k
  for (i = 0; i < img.tiles[tileIdx].tileComps[comp].nQuantSteps; ++i) {
1796
25.6k
    if (!readUByte(&img.tiles[tileIdx].tileComps[comp].quantSteps[i])) {
1797
309
      error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
1798
309
      return gFalse;
1799
309
    }
1800
25.6k
  }
1801
5.79k
      } else if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f)
1802
5.79k
     == 0x01) {
1803
2.28k
  img.tiles[tileIdx].tileComps[comp].nQuantSteps = 1;
1804
2.28k
  img.tiles[tileIdx].tileComps[comp].quantSteps =
1805
2.28k
      (Guint *)greallocn(img.tiles[tileIdx].tileComps[comp].quantSteps,
1806
2.28k
             img.tiles[tileIdx].tileComps[comp].nQuantSteps,
1807
2.28k
             sizeof(Guint));
1808
2.28k
  if (!readUWord(&img.tiles[tileIdx].tileComps[comp].quantSteps[0])) {
1809
469
    error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
1810
469
    return gFalse;
1811
469
  }
1812
3.51k
      } else if ((img.tiles[tileIdx].tileComps[comp].quantStyle & 0x1f)
1813
3.51k
     == 0x02) {
1814
3.26k
  if (segLen < (img.nComps > 256 ? 5U : 4U) + 2) {
1815
342
    error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
1816
342
    return gFalse;
1817
342
  }
1818
2.91k
  img.tiles[tileIdx].tileComps[comp].nQuantSteps =
1819
2.91k
      (segLen - (img.nComps > 256 ? 5 : 4)) / 2;
1820
2.91k
  img.tiles[tileIdx].tileComps[comp].quantSteps =
1821
2.91k
      (Guint *)greallocn(img.tiles[tileIdx].tileComps[comp].quantSteps,
1822
2.91k
             img.tiles[tileIdx].tileComps[comp].nQuantSteps,
1823
2.91k
             sizeof(Guint));
1824
383k
  for (i = 0; i < img.tiles[tileIdx].tileComps[comp].nQuantSteps; ++i) {
1825
380k
    if (!readUWord(&img.tiles[tileIdx].tileComps[comp].quantSteps[i])) {
1826
592
      error(errSyntaxError, getPos(), "Error in JPX QCD marker segment");
1827
592
      return gFalse;
1828
592
    }
1829
380k
  }
1830
2.91k
      } else {
1831
249
  error(errSyntaxError, getPos(), "Error in JPX QCC marker segment");
1832
249
  return gFalse;
1833
249
      }
1834
4.89k
      break;
1835
9.37k
    case 0x5e:      // RGN - region of interest
1836
9.37k
      cover(38);
1837
9.37k
      if (tilePartIdx != 0) {
1838
282
  error(errSyntaxError, getPos(), "Extraneous JPX RGN marker segment");
1839
282
  return gFalse;
1840
282
      }
1841
9.09k
#if 1 //~ ROI is unimplemented
1842
9.09k
      error(errUnimplemented, -1, "Got a JPX RGN segment");
1843
9.09k
      if (segLen > 2 &&
1844
8.64k
    bufStr->discardChars(segLen - 2) != segLen - 2) {
1845
227
  error(errSyntaxError, getPos(), "Error in JPX RGN marker segment");
1846
227
  return gFalse;
1847
227
      }
1848
#else
1849
      if ((img.nComps > 256 && !readUWord(&comp)) ||
1850
    (img.nComps <= 256 && !readUByte(&comp)) ||
1851
    comp >= img.nComps ||
1852
    !readUByte(&compInfo[comp].roi.style) ||
1853
    !readUByte(&compInfo[comp].roi.shift)) {
1854
  error(errSyntaxError, getPos(), "Error in JPX RGN marker segment");
1855
  return gFalse;
1856
      }
1857
#endif
1858
8.86k
      break;
1859
61.3k
    case 0x5f:      // POC - progression order change
1860
61.3k
      cover(39);
1861
61.3k
#if 1 //~ progression order changes are unimplemented
1862
61.3k
      error(errUnimplemented, -1, "Got a JPX POC segment");
1863
61.3k
      if (segLen > 2 &&
1864
4.87k
    bufStr->discardChars(segLen - 2) != segLen - 2) {
1865
453
  error(errSyntaxError, getPos(), "Error in JPX POC marker segment");
1866
453
  return gFalse;
1867
453
      }
1868
#else
1869
      nTileProgs = (segLen - 2) / (img.nComps > 256 ? 9 : 7);
1870
      tileProgs = (JPXProgOrder *)gmallocn(nTileProgs, sizeof(JPXProgOrder));
1871
      for (i = 0; i < nTileProgs; ++i) {
1872
  if (!readUByte(&tileProgs[i].startRes) ||
1873
      !(img.nComps > 256 && readUWord(&tileProgs[i].startComp)) ||
1874
      !(img.nComps <= 256 && readUByte(&tileProgs[i].startComp)) ||
1875
      !readUWord(&tileProgs[i].endLayer) ||
1876
      !readUByte(&tileProgs[i].endRes) ||
1877
      !(img.nComps > 256 && readUWord(&tileProgs[i].endComp)) ||
1878
      !(img.nComps <= 256 && readUByte(&tileProgs[i].endComp)) ||
1879
      !readUByte(&tileProgs[i].progOrder)) {
1880
    error(errSyntaxError, getPos(), "Error in JPX POC marker segment");
1881
    return gFalse;
1882
  }
1883
      }
1884
#endif
1885
60.9k
      break;
1886
60.9k
    case 0x61:      // PPT - packed packet headers, tile-part hdr
1887
3.40k
      cover(40);
1888
3.40k
#if 1 //~ packed packet headers are unimplemented
1889
3.40k
      error(errUnimplemented, -1, "Got a JPX PPT segment");
1890
3.40k
      if (segLen > 2 &&
1891
3.13k
    bufStr->discardChars(segLen - 2) != segLen - 2) {
1892
258
  error(errSyntaxError, getPos(), "Error in JPX PPT marker segment");
1893
258
  return gFalse;
1894
258
      }
1895
3.14k
#endif
1896
4.47k
    case 0x58:      // PLT - packet length, tile-part header
1897
      // skipped
1898
4.47k
      cover(41);
1899
4.47k
      if (segLen > 2 &&
1900
3.53k
    bufStr->discardChars(segLen - 2) != segLen - 2) {
1901
258
  error(errSyntaxError, getPos(), "Error in JPX PLT marker segment");
1902
258
  return gFalse;
1903
258
      }
1904
4.21k
      break;
1905
4.21k
    case 0x64:      // COM - comment
1906
      // skipped
1907
2.92k
      cover(42);
1908
2.92k
      if (segLen > 2 &&
1909
1.32k
    bufStr->discardChars(segLen - 2) != segLen - 2) {
1910
476
  error(errSyntaxError, getPos(), "Error in JPX COM marker segment");
1911
476
  return gFalse;
1912
476
      }
1913
2.44k
      break;
1914
21.2k
    case 0x93:      // SOD - start of data
1915
21.2k
      cover(43);
1916
21.2k
      haveSOD = gTrue;
1917
21.2k
      break;
1918
50.9k
    default:
1919
50.9k
      cover(44);
1920
50.9k
      error(errSyntaxError, getPos(),
1921
50.9k
      "Unknown marker segment {0:02x} in JPX tile-part stream",
1922
50.9k
      segType);
1923
50.9k
      if (segLen > 2) {
1924
23.5k
  bufStr->discardChars(segLen - 2);
1925
23.5k
      }
1926
50.9k
      break;
1927
224k
    }
1928
224k
  } while (!haveSOD);
1929
1930
92.3k
  for (comp = 0; comp < img.nComps; ++comp) {
1931
71.7k
    tileComp = &img.tiles[tileIdx].tileComps[comp];
1932
71.7k
    qStyle = tileComp->quantStyle & 0x1f;
1933
71.7k
    if ((qStyle == 0 && tileComp->nQuantSteps < 3 * tileComp->nDecompLevels + 1) ||
1934
71.4k
  (qStyle == 1 && tileComp->nQuantSteps < 1) ||
1935
71.4k
  (qStyle == 2 && tileComp->nQuantSteps < 3 * tileComp->nDecompLevels + 1)) {
1936
663
      error(errSyntaxError, getPos(), "Too few quant steps in JPX tile part");
1937
663
      return gFalse;
1938
663
    }
1939
71.7k
  }
1940
1941
  //----- initialize the tile, precincts, and code-blocks
1942
20.6k
  if (tilePartIdx == 0) {
1943
20.3k
    tile = &img.tiles[tileIdx];
1944
20.3k
    i = tileIdx / img.nXTiles;
1945
20.3k
    j = tileIdx % img.nXTiles;
1946
20.3k
    if ((tile->x0 = img.xTileOffset + j * img.xTileSize) < img.xOffset) {
1947
15.4k
      tile->x0 = img.xOffset;
1948
15.4k
    }
1949
20.3k
    if ((tile->y0 = img.yTileOffset + i * img.yTileSize) < img.yOffset) {
1950
18.1k
      tile->y0 = img.yOffset;
1951
18.1k
    }
1952
20.3k
    if ((tile->x1 = img.xTileOffset + (j + 1) * img.xTileSize) > img.xSize) {
1953
19.1k
      tile->x1 = img.xSize;
1954
19.1k
    }
1955
20.3k
    if ((tile->y1 = img.yTileOffset + (i + 1) * img.yTileSize) > img.ySize) {
1956
18.0k
      tile->y1 = img.ySize;
1957
18.0k
    }
1958
20.3k
    tile->comp = 0;
1959
20.3k
    tile->res = 0;
1960
20.3k
    tile->precinct = 0;
1961
20.3k
    tile->layer = 0;
1962
20.3k
    tile->done = gFalse;
1963
20.3k
    tile->maxNDecompLevels = 0;
1964
20.3k
    tile->maxNPrecincts = 0;
1965
86.4k
    for (comp = 0; comp < img.nComps; ++comp) {
1966
66.8k
      tileComp = &tile->tileComps[comp];
1967
66.8k
      if (tileComp->nDecompLevels > tile->maxNDecompLevels) {
1968
20.4k
  tile->maxNDecompLevels = tileComp->nDecompLevels;
1969
20.4k
      }
1970
66.8k
      tileComp->x0 = jpxCeilDiv(tile->x0, tileComp->hSep);
1971
66.8k
      tileComp->y0 = jpxCeilDiv(tile->y0, tileComp->vSep);
1972
66.8k
      tileComp->x1 = jpxCeilDiv(tile->x1, tileComp->hSep);
1973
66.8k
      tileComp->y1 = jpxCeilDiv(tile->y1, tileComp->vSep);
1974
66.8k
      tileComp->x0r = jpxCeilDivPow2(tileComp->x0, reduction);
1975
66.8k
      tileComp->w = jpxCeilDivPow2(tileComp->x1, reduction) - tileComp->x0r;
1976
66.8k
      tileComp->y0r = jpxCeilDivPow2(tileComp->y0, reduction);
1977
66.8k
      tileComp->h = jpxCeilDivPow2(tileComp->y1, reduction) - tileComp->y0r;
1978
66.8k
      if (tileComp->w == 0 || tileComp->h == 0 ||
1979
66.4k
    tileComp->w > INT_MAX / tileComp->h) {
1980
792
  error(errSyntaxError, getPos(),
1981
792
        "Invalid tile size or sample separation in JPX stream");
1982
792
  return gFalse;
1983
792
      }
1984
66.1k
      tileComp->data = (int *)gmallocn(tileComp->w * tileComp->h, sizeof(int));
1985
66.1k
      if (tileComp->x1 - tileComp->x0 > tileComp->y1 - tileComp->y0) {
1986
19.4k
  n = tileComp->x1 - tileComp->x0;
1987
46.6k
      } else {
1988
46.6k
  n = tileComp->y1 - tileComp->y0;
1989
46.6k
      }
1990
66.1k
      tileComp->buf = (int *)gmallocn(n + 8, sizeof(int));
1991
400k
      for (r = 0; r <= tileComp->nDecompLevels; ++r) {
1992
334k
  resLevel = &tileComp->resLevels[r];
1993
334k
  resLevel->x0 = jpxCeilDivPow2(tileComp->x0,
1994
334k
              tileComp->nDecompLevels - r);
1995
334k
  resLevel->y0 = jpxCeilDivPow2(tileComp->y0,
1996
334k
              tileComp->nDecompLevels - r);
1997
334k
  resLevel->x1 = jpxCeilDivPow2(tileComp->x1,
1998
334k
              tileComp->nDecompLevels - r);
1999
334k
  resLevel->y1 = jpxCeilDivPow2(tileComp->y1,
2000
334k
              tileComp->nDecompLevels - r);
2001
334k
  resLevel->codeBlockW = r == 0 ? resLevel->precinctWidth
2002
334k
                                : resLevel->precinctWidth - 1;
2003
334k
  if (resLevel->codeBlockW > tileComp->codeBlockW) {
2004
329k
    resLevel->codeBlockW = tileComp->codeBlockW;
2005
329k
  }
2006
334k
  resLevel->cbW = 1 << resLevel->codeBlockW;
2007
334k
  resLevel->codeBlockH = r == 0 ? resLevel->precinctHeight
2008
334k
                                : resLevel->precinctHeight - 1;
2009
334k
  if (resLevel->codeBlockH > tileComp->codeBlockH) {
2010
326k
    resLevel->codeBlockH = tileComp->codeBlockH;
2011
326k
  }
2012
334k
  resLevel->cbH = 1 << resLevel->codeBlockH;
2013
  // the JPEG 2000 spec says that packets for empty res levels
2014
  // should all be present in the codestream (B.6, B.9, B.10),
2015
  // but it appears that encoders drop packets if the res level
2016
  // AND the subbands are all completely empty
2017
334k
  resLevel->empty = resLevel->x0 == resLevel->x1 ||
2018
249k
                    resLevel->y0 == resLevel->y1;
2019
334k
  if (r == 0) {
2020
66.1k
    nSBs = 1;
2021
66.1k
    resLevel->bx0[0] = resLevel->x0;
2022
66.1k
    resLevel->by0[0] = resLevel->y0;
2023
66.1k
    resLevel->bx1[0] = resLevel->x1;
2024
66.1k
    resLevel->by1[0] = resLevel->y1;
2025
66.1k
    resLevel->empty = resLevel->empty &&
2026
45.9k
                      (resLevel->bx0[0] == resLevel->bx1[0] ||
2027
14.2k
           resLevel->by0[0] == resLevel->by1[0]);
2028
268k
  } else {
2029
268k
    nSBs = 3;
2030
268k
    resLevel->bx0[0] = jpxCeilDivPow2(resLevel->x0 - 1, 1);
2031
268k
    resLevel->by0[0] = jpxCeilDivPow2(resLevel->y0, 1);
2032
268k
    resLevel->bx1[0] = jpxCeilDivPow2(resLevel->x1 - 1, 1);
2033
268k
    resLevel->by1[0] = jpxCeilDivPow2(resLevel->y1, 1);
2034
268k
    resLevel->bx0[1] = jpxCeilDivPow2(resLevel->x0, 1);
2035
268k
    resLevel->by0[1] = jpxCeilDivPow2(resLevel->y0 - 1, 1);
2036
268k
    resLevel->bx1[1] = jpxCeilDivPow2(resLevel->x1, 1);
2037
268k
    resLevel->by1[1] = jpxCeilDivPow2(resLevel->y1 - 1, 1);
2038
268k
    resLevel->bx0[2] = jpxCeilDivPow2(resLevel->x0 - 1, 1);
2039
268k
    resLevel->by0[2] = jpxCeilDivPow2(resLevel->y0 - 1, 1);
2040
268k
    resLevel->bx1[2] = jpxCeilDivPow2(resLevel->x1 - 1, 1);
2041
268k
    resLevel->by1[2] = jpxCeilDivPow2(resLevel->y1 - 1, 1);
2042
268k
    resLevel->empty = resLevel->empty &&
2043
85.1k
                      (resLevel->bx0[0] == resLevel->bx1[0] ||
2044
25.3k
           resLevel->by0[0] == resLevel->by1[0]) &&
2045
85.1k
                      (resLevel->bx0[1] == resLevel->bx1[1] ||
2046
28.3k
           resLevel->by0[1] == resLevel->by1[1]) &&
2047
85.1k
                      (resLevel->bx0[2] == resLevel->bx1[2] ||
2048
25.3k
           resLevel->by0[2] == resLevel->by1[2]);
2049
268k
  }
2050
334k
  preCol0 = jpxFloorDivPow2(resLevel->x0, resLevel->precinctWidth);
2051
334k
  preCol1 = jpxCeilDivPow2(resLevel->x1, resLevel->precinctWidth);
2052
334k
  preRow0 = jpxFloorDivPow2(resLevel->y0, resLevel->precinctHeight);
2053
334k
  preRow1 = jpxCeilDivPow2(resLevel->y1, resLevel->precinctHeight);
2054
334k
  resLevel->nPrecincts = (preCol1 - preCol0) * (preRow1 - preRow0);
2055
334k
  resLevel->precincts = (JPXPrecinct *)gmallocn(resLevel->nPrecincts,
2056
334k
                  sizeof(JPXPrecinct));
2057
334k
  if (resLevel->nPrecincts > tile->maxNPrecincts) {
2058
27.1k
    tile->maxNPrecincts = resLevel->nPrecincts;
2059
27.1k
  }
2060
2.32M
  for (pre = 0; pre < resLevel->nPrecincts; ++pre) {
2061
1.99M
    resLevel->precincts[pre].subbands = NULL;
2062
1.99M
  }
2063
334k
  precinct = resLevel->precincts;
2064
1.35M
  for (preRow = preRow0; preRow < preRow1; ++preRow) {
2065
3.01M
    for (preCol = preCol0; preCol < preCol1; ++preCol) {
2066
1.99M
      precinct->subbands =
2067
1.99M
          (JPXSubband *)gmallocn(nSBs, sizeof(JPXSubband));
2068
7.54M
      for (sb = 0; sb < nSBs; ++sb) {
2069
5.55M
        precinct->subbands[sb].inclusion = NULL;
2070
5.55M
        precinct->subbands[sb].zeroBitPlane = NULL;
2071
5.55M
        precinct->subbands[sb].cbs = NULL;
2072
5.55M
      }
2073
7.54M
      for (sb = 0; sb < nSBs; ++sb) {
2074
5.55M
        subband = &precinct->subbands[sb];
2075
5.55M
        if (r == 0) {
2076
214k
    px0 = preCol << resLevel->precinctWidth;
2077
214k
    px1 = (preCol + 1) << resLevel->precinctWidth;
2078
214k
    py0 = preRow << resLevel->precinctHeight;
2079
214k
    py1 = (preRow + 1) << resLevel->precinctHeight;
2080
5.33M
        } else {
2081
5.33M
    px0 = preCol << (resLevel->precinctWidth - 1);
2082
5.33M
    px1 = (preCol + 1) << (resLevel->precinctWidth - 1);
2083
5.33M
    py0 = preRow << (resLevel->precinctHeight - 1);
2084
5.33M
    py1 = (preRow + 1) << (resLevel->precinctHeight - 1);
2085
5.33M
        }
2086
5.55M
        if (px0 < resLevel->bx0[sb]) {
2087
647k
    px0 = resLevel->bx0[sb];
2088
647k
        }
2089
5.55M
        if (px1 > resLevel->bx1[sb]) {
2090
1.36M
    px1 = resLevel->bx1[sb];
2091
1.36M
        }
2092
5.55M
        if (py0 < resLevel->by0[sb]) {
2093
1.41M
    py0 = resLevel->by0[sb];
2094
1.41M
        }
2095
5.55M
        if (py1 > resLevel->by1[sb]) {
2096
1.81M
    py1 = resLevel->by1[sb];
2097
1.81M
        }
2098
5.55M
        if (r == 0) { // (NL)LL
2099
214k
    sbCoeffs = tileComp->data;
2100
5.33M
        } else if (sb == 0) { // (NL-r+1)HL
2101
1.77M
    sbCoeffs = tileComp->data
2102
1.77M
                           + resLevel->bx1[1] - resLevel->bx0[1];
2103
3.55M
        } else if (sb == 1) { // (NL-r+1)LH
2104
1.77M
    sbCoeffs = tileComp->data
2105
1.77M
               + (resLevel->by1[0] - resLevel->by0[0]) * tileComp->w;
2106
1.77M
        } else { // (NL-r+1)HH
2107
1.77M
    sbCoeffs = tileComp->data
2108
1.77M
               + (resLevel->by1[0] - resLevel->by0[0]) * tileComp->w
2109
1.77M
               + (resLevel->bx1[1] - resLevel->bx0[1]);
2110
1.77M
        }
2111
5.55M
        cbCol0 = jpxFloorDivPow2(px0, resLevel->codeBlockW);
2112
5.55M
        cbCol1 = jpxCeilDivPow2(px1, resLevel->codeBlockW);
2113
5.55M
        cbRow0 = jpxFloorDivPow2(py0, resLevel->codeBlockH);
2114
5.55M
        cbRow1 = jpxCeilDivPow2(py1, resLevel->codeBlockH);
2115
5.55M
        subband->nXCBs = cbCol1 - cbCol0;
2116
5.55M
        subband->nYCBs = cbRow1 - cbRow0;
2117
5.55M
        n = subband->nXCBs > subband->nYCBs ? subband->nXCBs
2118
5.55M
                                            : subband->nYCBs;
2119
5.55M
        for (subband->maxTTLevel = 0, --n;
2120
8.66M
       n;
2121
5.55M
       ++subband->maxTTLevel, n >>= 1) ;
2122
5.55M
        n = 0;
2123
14.2M
        for (level = subband->maxTTLevel; level >= 0; --level) {
2124
8.66M
    nx = jpxCeilDivPow2(subband->nXCBs, level);
2125
8.66M
    ny = jpxCeilDivPow2(subband->nYCBs, level);
2126
8.66M
    n += nx * ny;
2127
8.66M
        }
2128
5.55M
        subband->inclusion =
2129
5.55M
            (JPXTagTreeNode *)gmallocn(n, sizeof(JPXTagTreeNode));
2130
5.55M
        subband->zeroBitPlane =
2131
5.55M
            (JPXTagTreeNode *)gmallocn(n, sizeof(JPXTagTreeNode));
2132
78.5M
        for (k = 0; k < n; ++k) {
2133
72.9M
    subband->inclusion[k].finished = gFalse;
2134
72.9M
    subband->inclusion[k].val = 0;
2135
72.9M
    subband->zeroBitPlane[k].finished = gFalse;
2136
72.9M
    subband->zeroBitPlane[k].val = 0;
2137
72.9M
        }
2138
5.55M
        subband->cbs = (JPXCodeBlock *)gmallocn(subband->nXCBs *
2139
5.55M
                    subband->nYCBs,
2140
5.55M
                  sizeof(JPXCodeBlock));
2141
46.8M
        for (k = 0; k < subband->nXCBs * subband->nYCBs; ++k) {
2142
41.3M
    subband->cbs[k].dataLen = NULL;
2143
41.3M
    subband->cbs[k].touched = NULL;
2144
41.3M
    subband->cbs[k].arithDecoder = NULL;
2145
41.3M
    subband->cbs[k].stats = NULL;
2146
41.3M
        }
2147
5.55M
        cb = subband->cbs;
2148
35.0M
        for (cbY = cbRow0; cbY < cbRow1; ++cbY) {
2149
70.8M
    for (cbX = cbCol0; cbX < cbCol1; ++cbX) {
2150
41.3M
      cb->x0 = cbX << resLevel->codeBlockW;
2151
41.3M
      cb->x1 = cb->x0 + resLevel->cbW;
2152
41.3M
      if (cb->x0 < px0) {
2153
5.83M
        cb->x0 = px0;
2154
5.83M
      }
2155
41.3M
      if (cb->x1 > px1) {
2156
19.7M
        cb->x1 = px1;
2157
19.7M
      }
2158
41.3M
      cb->y0 = cbY << resLevel->codeBlockH;
2159
41.3M
      cb->y1 = cb->y0 + resLevel->cbH;
2160
41.3M
      if (cb->y0 < py0) {
2161
6.37M
        cb->y0 = py0;
2162
6.37M
      }
2163
41.3M
      if (cb->y1 > py1) {
2164
10.5M
        cb->y1 = py1;
2165
10.5M
      }
2166
41.3M
      cb->seen = gFalse;
2167
41.3M
      cb->lBlock = 3;
2168
41.3M
      cb->nextPass = jpxPassCleanup;
2169
41.3M
      cb->nZeroBitPlanes = 0;
2170
41.3M
      cb->dataLenSize = 1;
2171
41.3M
      cb->dataLen = (Guint *)gmalloc(sizeof(Guint));
2172
41.3M
      if (r <= tileComp->nDecompLevels - reduction) {
2173
41.3M
        cb->coeffs = sbCoeffs
2174
41.3M
                     + (cb->y0 - resLevel->by0[sb]) * tileComp->w
2175
41.3M
                     + (cb->x0 - resLevel->bx0[sb]);
2176
41.3M
        cb->touched = (char *)gmalloc(1 << (resLevel->codeBlockW
2177
41.3M
              + resLevel->codeBlockH));
2178
41.3M
        cb->len = 0;
2179
372M
        for (cbj = 0; cbj < cb->y1 - cb->y0; ++cbj) {
2180
2.00G
          for (cbi = 0; cbi < cb->x1 - cb->x0; ++cbi) {
2181
1.66G
      cb->coeffs[cbj * tileComp->w + cbi] = 0;
2182
1.66G
          }
2183
330M
        }
2184
41.3M
        memset(cb->touched, 0,
2185
41.3M
         ((size_t)1 << (resLevel->codeBlockW
2186
41.3M
            + resLevel->codeBlockH)));
2187
41.3M
      } else {
2188
0
        cb->coeffs = NULL;
2189
0
        cb->touched = NULL;
2190
0
        cb->len = 0;
2191
0
      }
2192
41.3M
      ++cb;
2193
41.3M
    }
2194
29.4M
        }
2195
5.55M
      }
2196
1.99M
      ++precinct;
2197
1.99M
    }
2198
1.02M
  }
2199
334k
      }
2200
66.1k
    }
2201
19.5k
    tile->init = gTrue;
2202
19.5k
  }
2203
2204
19.8k
  return readTilePartData(tileIdx, tilePartLen, tilePartToEOC);
2205
20.6k
}
2206
2207
GBool JPXStream::readTilePartData(Guint tileIdx,
2208
19.8k
          Guint tilePartLen, GBool tilePartToEOC) {
2209
19.8k
  JPXTile *tile;
2210
19.8k
  JPXTileComp *tileComp;
2211
19.8k
  JPXResLevel *resLevel;
2212
19.8k
  JPXPrecinct *precinct;
2213
19.8k
  JPXSubband *subband;
2214
19.8k
  JPXCodeBlock *cb;
2215
19.8k
  Guint ttVal;
2216
19.8k
  Guint bits, cbX, cbY, nx, ny, i, j, n, sb;
2217
19.8k
  int level;
2218
2219
19.8k
  tile = &img.tiles[tileIdx];
2220
2221
  // read all packets from this tile-part
2222
39.5M
  while (1) {
2223
2224
    // if the tile is finished, skip any remaining data
2225
39.5M
    if (tile->done) {
2226
6.31k
      bufStr->discardChars(tilePartLen);
2227
6.31k
      return gTrue;
2228
6.31k
    }
2229
2230
39.5M
    if (tilePartToEOC) {
2231
      //~ peek for an EOC marker
2232
1.16M
      cover(93);
2233
38.3M
    } else if (tilePartLen == 0) {
2234
1.36k
      break;
2235
1.36k
    }
2236
2237
39.5M
    tileComp = &tile->tileComps[tile->comp];
2238
39.5M
    resLevel = &tileComp->resLevels[tile->res];
2239
39.5M
    precinct = &resLevel->precincts[tile->precinct];
2240
2241
39.5M
    if (resLevel->empty) {
2242
37.5M
      goto nextPacket;
2243
37.5M
    }
2244
2245
    //----- packet header
2246
2247
    // setup
2248
1.93M
    startBitBuf(tilePartLen);
2249
1.93M
    if (tileComp->style & 0x02) {
2250
378k
      skipSOP();
2251
378k
    }
2252
2253
    // zero-length flag
2254
1.93M
    if (!readBits(1, &bits)) {
2255
3.81k
      goto err;
2256
3.81k
    }
2257
1.93M
    if (!bits) {
2258
      // packet is empty -- clear all code-block inclusion flags
2259
1.83M
      cover(45);
2260
6.43M
      for (sb = 0; sb < (Guint)(tile->res == 0 ? 1 : 3); ++sb) {
2261
4.59M
  subband = &precinct->subbands[sb];
2262
172M
  for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
2263
409M
    for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
2264
242M
      cb = &subband->cbs[cbY * subband->nXCBs + cbX];
2265
242M
      cb->included = gFalse;
2266
242M
    }
2267
167M
  }
2268
4.59M
      }
2269
1.83M
    } else {
2270
2271
310k
      for (sb = 0; sb < (Guint)(tile->res == 0 ? 1 : 3); ++sb) {
2272
221k
  subband = &precinct->subbands[sb];
2273
3.50M
  for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
2274
9.41M
    for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
2275
6.13M
      cb = &subband->cbs[cbY * subband->nXCBs + cbX];
2276
2277
      // skip code-blocks with no coefficients
2278
6.13M
      if (cb->x0 >= cb->x1 || cb->y0 >= cb->y1) {
2279
329k
        cover(46);
2280
329k
        cb->included = gFalse;
2281
329k
        continue;
2282
329k
      }
2283
2284
      // code-block inclusion
2285
5.80M
      if (cb->seen) {
2286
90.1k
        cover(47);
2287
90.1k
        if (!readBits(1, &cb->included)) {
2288
903
    goto err;
2289
903
        }
2290
5.71M
      } else {
2291
5.71M
        cover(48);
2292
5.71M
        ttVal = 0;
2293
5.71M
        i = 0;
2294
18.8M
        for (level = subband->maxTTLevel; level >= 0; --level) {
2295
18.2M
    nx = jpxCeilDivPow2(subband->nXCBs, level);
2296
18.2M
    ny = jpxCeilDivPow2(subband->nYCBs, level);
2297
18.2M
    j = i + (cbY >> level) * nx + (cbX >> level);
2298
18.2M
    if (!subband->inclusion[j].finished &&
2299
6.24M
        !subband->inclusion[j].val) {
2300
1.39M
      subband->inclusion[j].val = ttVal;
2301
16.8M
    } else {
2302
16.8M
      ttVal = subband->inclusion[j].val;
2303
16.8M
    }
2304
20.6M
    while (!subband->inclusion[j].finished &&
2305
7.52M
           ttVal <= tile->layer) {
2306
2.42M
      if (!readBits(1, &bits)) {
2307
1.04k
        goto err;
2308
1.04k
      }
2309
2.41M
      if (bits == 1) {
2310
1.13M
        subband->inclusion[j].finished = gTrue;
2311
1.27M
      } else {
2312
1.27M
        ++ttVal;
2313
1.27M
      }
2314
2.41M
    }
2315
18.2M
    subband->inclusion[j].val = ttVal;
2316
18.2M
    if (ttVal > tile->layer) {
2317
5.10M
      break;
2318
5.10M
    }
2319
13.1M
    i += nx * ny;
2320
13.1M
        }
2321
5.70M
        cb->included = level < 0;
2322
5.70M
      }
2323
2324
5.79M
      if (cb->included) {
2325
644k
        cover(49);
2326
2327
        // zero bit-plane count
2328
644k
        if (!cb->seen) {
2329
604k
    cover(50);
2330
604k
    ttVal = 0;
2331
604k
    i = 0;
2332
4.55M
    for (level = subband->maxTTLevel; level >= 0; --level) {
2333
3.95M
      nx = jpxCeilDivPow2(subband->nXCBs, level);
2334
3.95M
      ny = jpxCeilDivPow2(subband->nYCBs, level);
2335
3.95M
      j = i + (cbY >> level) * nx + (cbX >> level);
2336
3.95M
      if (!subband->zeroBitPlane[j].finished &&
2337
1.07M
          !subband->zeroBitPlane[j].val) {
2338
1.07M
        subband->zeroBitPlane[j].val = ttVal;
2339
2.87M
      } else {
2340
2.87M
        ttVal = subband->zeroBitPlane[j].val;
2341
2.87M
      }
2342
6.21M
      while (!subband->zeroBitPlane[j].finished) {
2343
2.25M
        if (!readBits(1, &bits)) {
2344
910
          goto err;
2345
910
        }
2346
2.25M
        if (bits == 1) {
2347
1.07M
          subband->zeroBitPlane[j].finished = gTrue;
2348
1.18M
        } else {
2349
1.18M
          ++ttVal;
2350
1.18M
        }
2351
2.25M
      }
2352
3.95M
      subband->zeroBitPlane[j].val = ttVal;
2353
3.95M
      i += nx * ny;
2354
3.95M
    }
2355
603k
    cb->nZeroBitPlanes = ttVal;
2356
603k
        }
2357
2358
        // number of coding passes
2359
643k
        if (!readBits(1, &bits)) {
2360
642
    goto err;
2361
642
        }
2362
642k
        if (bits == 0) {
2363
347k
    cover(51);
2364
347k
    cb->nCodingPasses = 1;
2365
347k
        } else {
2366
294k
    if (!readBits(1, &bits)) {
2367
647
      goto err;
2368
647
    }
2369
294k
    if (bits == 0) {
2370
153k
      cover(52);
2371
153k
      cb->nCodingPasses = 2;
2372
153k
    } else {
2373
140k
      cover(53);
2374
140k
      if (!readBits(2, &bits)) {
2375
755
        goto err;
2376
755
      }
2377
139k
      if (bits < 3) {
2378
84.3k
        cover(54);
2379
84.3k
        cb->nCodingPasses = 3 + bits;
2380
84.3k
      } else {
2381
55.5k
        cover(55);
2382
55.5k
        if (!readBits(5, &bits)) {
2383
507
          goto err;
2384
507
        }
2385
55.0k
        if (bits < 31) {
2386
43.2k
          cover(56);
2387
43.2k
          cb->nCodingPasses = 6 + bits;
2388
43.2k
        } else {
2389
11.7k
          cover(57);
2390
11.7k
          if (!readBits(7, &bits)) {
2391
535
      goto err;
2392
535
          }
2393
11.2k
          cb->nCodingPasses = 37 + bits;
2394
11.2k
        }
2395
55.0k
      }
2396
139k
    }
2397
294k
        }
2398
2399
        // update Lblock
2400
1.46M
        while (1) {
2401
1.46M
    if (!readBits(1, &bits)) {
2402
753
      goto err;
2403
753
    }
2404
1.46M
    if (!bits) {
2405
639k
      break;
2406
639k
    }
2407
828k
    ++cb->lBlock;
2408
828k
        }
2409
2410
        // one codeword segment for each of the coding passes
2411
639k
        if (tileComp->codeBlockStyle & 0x04) {
2412
123k
    if (cb->nCodingPasses > cb->dataLenSize) {
2413
57.1k
      cb->dataLenSize = cb->nCodingPasses;
2414
57.1k
      cb->dataLen = (Guint *)greallocn(cb->dataLen,
2415
57.1k
               cb->dataLenSize,
2416
57.1k
               sizeof(Guint));
2417
57.1k
    }
2418
2419
    // read the lengths
2420
699k
    for (i = 0; i < cb->nCodingPasses; ++i) {
2421
576k
      if (!readBits(cb->lBlock, &cb->dataLen[i])) {
2422
732
        goto err;
2423
732
      }
2424
576k
    }
2425
2426
        // one codeword segment for all of the coding passes
2427
515k
        } else {
2428
2429
    // read the length
2430
515k
    for (n = cb->lBlock, i = cb->nCodingPasses >> 1;
2431
924k
         i;
2432
515k
         ++n, i >>= 1) ;
2433
515k
    if (!readBits(n, &cb->dataLen[0])) {
2434
929
      goto err;
2435
929
    }
2436
515k
        }
2437
639k
      }
2438
5.79M
    }
2439
3.29M
  }
2440
221k
      }
2441
96.7k
    }
2442
1.92M
    if (tileComp->style & 0x04) {
2443
491k
      skipEPH();
2444
491k
    }
2445
1.92M
    tilePartLen = finishBitBuf();
2446
2447
    //----- packet data
2448
2449
6.73M
    for (sb = 0; sb < (Guint)(tile->res == 0 ? 1 : 3); ++sb) {
2450
4.80M
      subband = &precinct->subbands[sb];
2451
174M
      for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
2452
417M
  for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
2453
247M
    cb = &subband->cbs[cbY * subband->nXCBs + cbX];
2454
247M
    if (cb->included) {
2455
330k
      if (!readCodeBlockData(tileComp, resLevel, precinct, subband,
2456
330k
           tile->res, sb, cb)) {
2457
0
        return gFalse;
2458
0
      }
2459
330k
      if (tileComp->codeBlockStyle & 0x04) {
2460
588k
        for (i = 0; i < cb->nCodingPasses; ++i) {
2461
485k
    tilePartLen -= cb->dataLen[i];
2462
485k
        }
2463
227k
      } else {
2464
227k
        tilePartLen -= cb->dataLen[0];
2465
227k
      }
2466
330k
      cb->seen = gTrue;
2467
330k
    }
2468
247M
  }
2469
170M
      }
2470
4.80M
    }
2471
2472
    //----- next packet
2473
2474
39.5M
  nextPacket:
2475
39.5M
    switch (tile->progOrder) {
2476
1.57M
    case 0: // layer, resolution level, component, precinct
2477
1.57M
      cover(58);
2478
2.06M
      do {
2479
2.06M
  if (++tile->precinct == tile->maxNPrecincts) {
2480
1.47M
    tile->precinct = 0;
2481
1.47M
    if (++tile->comp == img.nComps) {
2482
581k
      tile->comp = 0;
2483
581k
      if (++tile->res == tile->maxNDecompLevels + 1) {
2484
143k
        tile->res = 0;
2485
143k
        if (++tile->layer == tile->nLayers) {
2486
707
    tile->layer = 0;
2487
707
    tile->done = gTrue;
2488
707
        }
2489
143k
      }
2490
581k
    }
2491
1.47M
  }
2492
2.06M
      } while (!tile->done &&
2493
2.05M
         (tile->res > tile->tileComps[tile->comp].nDecompLevels ||
2494
2.00M
    tile->precinct >= tile->tileComps[tile->comp]
2495
2.00M
                                    .resLevels[tile->res].nPrecincts));
2496
1.57M
      break;
2497
4.16M
    case 1: // resolution level, layer, component, precinct
2498
4.16M
      cover(59);
2499
8.74M
      do {
2500
8.74M
  if (++tile->precinct == tile->maxNPrecincts) {
2501
2.60M
    tile->precinct = 0;
2502
2.60M
    if (++tile->comp == img.nComps) {
2503
1.74M
      tile->comp = 0;
2504
1.74M
      if (++tile->layer == tile->nLayers) {
2505
8.58k
        tile->layer = 0;
2506
8.58k
        if (++tile->res == tile->maxNDecompLevels + 1) {
2507
1.14k
    tile->res = 0;
2508
1.14k
    tile->done = gTrue;
2509
1.14k
        }
2510
8.58k
      }
2511
1.74M
    }
2512
2.60M
  }
2513
8.74M
      } while (!tile->done &&
2514
8.74M
         (tile->res > tile->tileComps[tile->comp].nDecompLevels ||
2515
8.74M
    tile->precinct >= tile->tileComps[tile->comp]
2516
8.74M
                                    .resLevels[tile->res].nPrecincts));
2517
4.16M
      break;
2518
31.6M
    case 2: // resolution level, precinct, component, layer
2519
31.6M
      cover(60);
2520
      //~ this is incorrect if there are subsampled components (?)
2521
32.6M
      do {
2522
32.6M
  if (++tile->layer == tile->nLayers) {
2523
539k
    tile->layer = 0;
2524
539k
    if (++tile->comp == img.nComps) {
2525
530k
      tile->comp = 0;
2526
530k
      if (++tile->precinct == tile->maxNPrecincts) {
2527
7.68k
        tile->precinct = 0;
2528
7.68k
        if (++tile->res == tile->maxNDecompLevels + 1) {
2529
1.30k
    tile->res = 0;
2530
1.30k
    tile->done = gTrue;
2531
1.30k
        }
2532
7.68k
      }
2533
530k
    }
2534
539k
  }
2535
32.6M
      } while (!tile->done &&
2536
32.6M
         (tile->res > tile->tileComps[tile->comp].nDecompLevels ||
2537
32.6M
    tile->precinct >= tile->tileComps[tile->comp]
2538
32.6M
                                    .resLevels[tile->res].nPrecincts));
2539
31.6M
      break;
2540
1.49M
    case 3: // precinct, component, resolution level, layer
2541
1.49M
      cover(61);
2542
      //~ this is incorrect if there are subsampled components (?)
2543
1.57M
      do {
2544
1.57M
  if (++tile->layer == tile->nLayers) {
2545
83.2k
    tile->layer = 0;
2546
83.2k
    if (++tile->res == tile->maxNDecompLevels + 1) {
2547
11.4k
      tile->res = 0;
2548
11.4k
      if (++tile->comp == img.nComps) {
2549
3.24k
        tile->comp = 0;
2550
3.24k
        if (++tile->precinct == tile->maxNPrecincts) {
2551
2.50k
    tile->precinct = 0;
2552
2.50k
    tile->done = gTrue;
2553
2.50k
        }
2554
3.24k
      }
2555
11.4k
    }
2556
83.2k
  }
2557
1.57M
      } while (!tile->done &&
2558
1.57M
         (tile->res > tile->tileComps[tile->comp].nDecompLevels ||
2559
1.57M
    tile->precinct >= tile->tileComps[tile->comp]
2560
1.57M
                                    .resLevels[tile->res].nPrecincts));
2561
1.49M
      break;
2562
587k
    case 4: // component, precinct, resolution level, layer
2563
587k
      cover(62);
2564
2.26M
      do {
2565
2.26M
  if (++tile->layer == tile->nLayers) {
2566
707k
    tile->layer = 0;
2567
707k
    if (++tile->res == tile->maxNDecompLevels + 1) {
2568
117k
      tile->res = 0;
2569
117k
      if (++tile->precinct == tile->maxNPrecincts) {
2570
1.05k
        tile->precinct = 0;
2571
1.05k
        if (++tile->comp == img.nComps) {
2572
357
    tile->comp = 0;
2573
357
    tile->done = gTrue;
2574
357
        }
2575
1.05k
      }
2576
117k
    }
2577
707k
  }
2578
2.26M
      } while (!tile->done &&
2579
2.25M
         (tile->res > tile->tileComps[tile->comp].nDecompLevels ||
2580
2.25M
    tile->precinct >= tile->tileComps[tile->comp]
2581
2.25M
                                    .resLevels[tile->res].nPrecincts));
2582
587k
      break;
2583
39.5M
    }
2584
39.5M
  }
2585
2586
1.36k
  return gTrue;
2587
2588
12.1k
 err:
2589
12.1k
  error(errSyntaxError, getPos(), "Error in JPX stream");
2590
12.1k
  return gFalse;
2591
19.8k
}
2592
2593
GBool JPXStream::readCodeBlockData(JPXTileComp *tileComp,
2594
           JPXResLevel *resLevel,
2595
           JPXPrecinct *precinct,
2596
           JPXSubband *subband,
2597
           Guint res, Guint sb,
2598
330k
           JPXCodeBlock *cb) {
2599
330k
  int *coeff0, *coeff1, *coeff;
2600
330k
  char *touched0, *touched1, *touched;
2601
330k
  Guint horiz, vert, diag, all, cx, xorBit;
2602
330k
  int horizSign, vertSign, bit;
2603
330k
  int segSym;
2604
330k
  Guint n, i, x, y0, y1;
2605
2606
330k
  if (res > tileComp->nDecompLevels - reduction) {
2607
    // skip the codeblock data
2608
0
    if (tileComp->codeBlockStyle & 0x04) {
2609
0
      n = 0;
2610
0
      for (i = 0; i < cb->nCodingPasses; ++i) {
2611
0
  n += cb->dataLen[i];
2612
0
      }
2613
0
    } else {
2614
0
      n = cb->dataLen[0];
2615
0
    }
2616
0
    bufStr->discardChars(n);
2617
0
    return gTrue;
2618
0
  }
2619
2620
330k
  if (cb->arithDecoder) {
2621
37.2k
    cover(63);
2622
37.2k
    if (tileComp->codeBlockStyle & 0x04) {
2623
5.76k
      cb->arithDecoder->setStream(bufStr, cb->dataLen[0]);
2624
5.76k
      cb->arithDecoder->start();
2625
31.4k
    } else {
2626
31.4k
      cb->arithDecoder->restart(cb->dataLen[0]);
2627
31.4k
    }
2628
293k
  } else {
2629
293k
    cover(64);
2630
293k
    cb->arithDecoder = new JArithmeticDecoder();
2631
293k
    cb->arithDecoder->setStream(bufStr, cb->dataLen[0]);
2632
293k
    cb->arithDecoder->start();
2633
293k
    cb->stats = new JArithmeticDecoderStats(jpxNContexts);
2634
293k
    cb->stats->setEntry(jpxContextSigProp, 4, 0);
2635
293k
    cb->stats->setEntry(jpxContextRunLength, 3, 0);
2636
293k
    cb->stats->setEntry(jpxContextUniform, 46, 0);
2637
293k
  }
2638
2639
2.37M
  for (i = 0; i < cb->nCodingPasses; ++i) {
2640
2.04M
    if ((tileComp->codeBlockStyle & 0x04) && i > 0) {
2641
382k
      cb->arithDecoder->setStream(bufStr, cb->dataLen[i]);
2642
382k
      cb->arithDecoder->start();
2643
382k
    }
2644
2645
2.04M
    switch (cb->nextPass) {
2646
2647
    //----- significance propagation pass
2648
656k
    case jpxPassSigProp:
2649
656k
      cover(65);
2650
656k
      for (y0 = cb->y0, coeff0 = cb->coeffs, touched0 = cb->touched;
2651
3.43M
     y0 < cb->y1;
2652
2.78M
     y0 += 4, coeff0 += 4 * tileComp->w,
2653
2.78M
       touched0 += 4 << resLevel->codeBlockW) {
2654
2.78M
  for (x = cb->x0, coeff1 = coeff0, touched1 = touched0;
2655
26.9M
       x < cb->x1;
2656
24.1M
       ++x, ++coeff1, ++touched1) {
2657
24.1M
    for (y1 = 0, coeff = coeff1, touched = touched1;
2658
113M
         y1 < 4 && y0+y1 < cb->y1;
2659
89.3M
         ++y1, coeff += tileComp->w, touched += resLevel->cbW) {
2660
89.3M
      if (!*coeff) {
2661
39.0M
        horiz = vert = diag = 0;
2662
39.0M
        horizSign = vertSign = 2;
2663
39.0M
        if (x > cb->x0) {
2664
33.3M
    if (coeff[-1]) {
2665
4.19M
      ++horiz;
2666
4.19M
      horizSign += coeff[-1] < 0 ? -1 : 1;
2667
4.19M
    }
2668
33.3M
    if (y0+y1 > cb->y0) {
2669
30.9M
      diag += coeff[-(int)tileComp->w - 1] ? 1 : 0;
2670
30.9M
    }
2671
33.3M
    if (y0+y1 < cb->y1 - 1 &&
2672
31.1M
        (!(tileComp->codeBlockStyle & 0x08) || y1 < 3)) {
2673
30.6M
      diag += coeff[tileComp->w - 1] ? 1 : 0;
2674
30.6M
    }
2675
33.3M
        }
2676
39.0M
        if (x < cb->x1 - 1) {
2677
33.6M
    if (coeff[1]) {
2678
2.85M
      ++horiz;
2679
2.85M
      horizSign += coeff[1] < 0 ? -1 : 1;
2680
2.85M
    }
2681
33.6M
    if (y0+y1 > cb->y0) {
2682
31.1M
      diag += coeff[-(int)tileComp->w + 1] ? 1 : 0;
2683
31.1M
    }
2684
33.6M
    if (y0+y1 < cb->y1 - 1 &&
2685
31.3M
        (!(tileComp->codeBlockStyle & 0x08) || y1 < 3)) {
2686
30.7M
      diag += coeff[tileComp->w + 1] ? 1 : 0;
2687
30.7M
    }
2688
33.6M
        }
2689
39.0M
        if (y0+y1 > cb->y0) {
2690
36.2M
    if (coeff[-(int)tileComp->w]) {
2691
4.29M
      ++vert;
2692
4.29M
      vertSign += coeff[-(int)tileComp->w] < 0 ? -1 : 1;
2693
4.29M
    }
2694
36.2M
        }
2695
39.0M
        if (y0+y1 < cb->y1 - 1 &&
2696
36.3M
      (!(tileComp->codeBlockStyle & 0x08) || y1 < 3)) {
2697
35.7M
    if (coeff[tileComp->w]) {
2698
2.65M
      ++vert;
2699
2.65M
      vertSign += coeff[tileComp->w] < 0 ? -1 : 1;
2700
2.65M
    }
2701
35.7M
        }
2702
39.0M
        cx = sigPropContext[horiz][vert][diag][res == 0 ? 1 : sb];
2703
39.0M
        if (cx != 0) {
2704
6.83M
    if (cb->arithDecoder->decodeBit(cx, cb->stats)) {
2705
2.89M
      cx = signContext[horizSign][vertSign][0];
2706
2.89M
      xorBit = signContext[horizSign][vertSign][1];
2707
2.89M
      if (cb->arithDecoder->decodeBit(cx, cb->stats) ^ xorBit) {
2708
1.45M
        *coeff = -1;
2709
1.45M
      } else {
2710
1.43M
        *coeff = 1;
2711
1.43M
      }
2712
2.89M
    }
2713
6.83M
    *touched = 1;
2714
6.83M
        }
2715
39.0M
      }
2716
89.3M
    }
2717
24.1M
  }
2718
2.78M
      }
2719
656k
      ++cb->nextPass;
2720
656k
      break;
2721
2722
    //----- magnitude refinement pass
2723
565k
    case jpxPassMagRef:
2724
565k
      cover(66);
2725
565k
      for (y0 = cb->y0, coeff0 = cb->coeffs, touched0 = cb->touched;
2726
3.09M
     y0 < cb->y1;
2727
2.52M
     y0 += 4, coeff0 += 4 * tileComp->w,
2728
2.52M
       touched0 += 4 << resLevel->codeBlockW) {
2729
2.52M
  for (x = cb->x0, coeff1 = coeff0, touched1 = touched0;
2730
23.5M
       x < cb->x1;
2731
21.0M
       ++x, ++coeff1, ++touched1) {
2732
21.0M
    for (y1 = 0, coeff = coeff1, touched = touched1;
2733
98.7M
         y1 < 4 && y0+y1 < cb->y1;
2734
77.7M
         ++y1, coeff += tileComp->w, touched += resLevel->cbW) {
2735
77.7M
      if (*coeff && !*touched) {
2736
47.9M
        if (*coeff == 1 || *coeff == -1) {
2737
3.07M
    all = 0;
2738
3.07M
    if (x > cb->x0) {
2739
2.77M
      all += coeff[-1] ? 1 : 0;
2740
2.77M
      if (y0+y1 > cb->y0) {
2741
2.61M
        all += coeff[-(int)tileComp->w - 1] ? 1 : 0;
2742
2.61M
      }
2743
2.77M
      if (y0+y1 < cb->y1 - 1 &&
2744
2.58M
          (!(tileComp->codeBlockStyle & 0x08) || y1 < 3)) {
2745
2.50M
        all += coeff[tileComp->w - 1] ? 1 : 0;
2746
2.50M
      }
2747
2.77M
    }
2748
3.07M
    if (x < cb->x1 - 1) {
2749
2.72M
      all += coeff[1] ? 1 : 0;
2750
2.72M
      if (y0+y1 > cb->y0) {
2751
2.56M
        all += coeff[-(int)tileComp->w + 1] ? 1 : 0;
2752
2.56M
      }
2753
2.72M
      if (y0+y1 < cb->y1 - 1 &&
2754
2.53M
          (!(tileComp->codeBlockStyle & 0x08) || y1 < 3)) {
2755
2.46M
        all += coeff[tileComp->w + 1] ? 1 : 0;
2756
2.46M
      }
2757
2.72M
    }
2758
3.07M
    if (y0+y1 > cb->y0) {
2759
2.89M
      all += coeff[-(int)tileComp->w] ? 1 : 0;
2760
2.89M
    }
2761
3.07M
    if (y0+y1 < cb->y1 - 1 &&
2762
2.86M
        (!(tileComp->codeBlockStyle & 0x08) || y1 < 3)) {
2763
2.78M
      all += coeff[tileComp->w] ? 1 : 0;
2764
2.78M
    }
2765
3.07M
    cx = all ? 15 : 14;
2766
44.9M
        } else {
2767
44.9M
    cx = 16;
2768
44.9M
        }
2769
47.9M
        bit = cb->arithDecoder->decodeBit(cx, cb->stats);
2770
47.9M
        if (*coeff < 0) {
2771
24.2M
    *coeff = (*coeff << 1) - bit;
2772
24.2M
        } else {
2773
23.7M
    *coeff = (*coeff << 1) + bit;
2774
23.7M
        }
2775
47.9M
        *touched = 1;
2776
47.9M
      }
2777
77.7M
    }
2778
21.0M
  }
2779
2.52M
      }
2780
565k
      ++cb->nextPass;
2781
565k
      break;
2782
2783
    //----- cleanup pass
2784
821k
    case jpxPassCleanup:
2785
821k
      cover(67);
2786
821k
      for (y0 = cb->y0, coeff0 = cb->coeffs, touched0 = cb->touched;
2787
4.07M
     y0 < cb->y1;
2788
3.25M
     y0 += 4, coeff0 += 4 * tileComp->w,
2789
3.25M
       touched0 += 4 << resLevel->codeBlockW) {
2790
3.25M
  for (x = cb->x0, coeff1 = coeff0, touched1 = touched0;
2791
31.6M
       x < cb->x1;
2792
28.3M
       ++x, ++coeff1, ++touched1) {
2793
28.3M
    y1 = 0;
2794
28.3M
    if (y0 + 3 < cb->y1 &&
2795
24.4M
        !(*touched1) &&
2796
12.6M
        !(touched1[resLevel->cbW]) &&
2797
12.6M
        !(touched1[2 * resLevel->cbW]) &&
2798
12.5M
        !(touched1[3 * resLevel->cbW]) &&
2799
12.5M
        (x == cb->x0 || y0 == cb->y0 ||
2800
8.72M
         !coeff1[-(int)tileComp->w - 1]) &&
2801
11.9M
        (y0 == cb->y0 ||
2802
9.40M
         !coeff1[-(int)tileComp->w]) &&
2803
11.6M
        (x == cb->x1 - 1 || y0 == cb->y0 ||
2804
7.92M
         !coeff1[-(int)tileComp->w + 1]) &&
2805
11.4M
        (x == cb->x0 ||
2806
9.85M
         (!coeff1[-1] &&
2807
9.53M
    !coeff1[tileComp->w - 1] &&
2808
9.34M
    !coeff1[2 * tileComp->w - 1] && 
2809
9.22M
    !coeff1[3 * tileComp->w - 1])) &&
2810
10.7M
        (x == cb->x1 - 1 ||
2811
9.24M
         (!coeff1[1] &&
2812
9.24M
    !coeff1[tileComp->w + 1] &&
2813
9.23M
    !coeff1[2 * tileComp->w + 1] &&
2814
9.23M
    !coeff1[3 * tileComp->w + 1])) &&
2815
10.7M
        ((tileComp->codeBlockStyle & 0x08) ||
2816
9.88M
         ((x == cb->x0 || y0+4 == cb->y1 ||
2817
7.26M
     !coeff1[4 * tileComp->w - 1]) &&
2818
9.87M
    (y0+4 == cb->y1 ||
2819
8.44M
     !coeff1[4 * tileComp->w]) &&
2820
9.86M
    (x == cb->x1 - 1 || y0+4 == cb->y1 ||
2821
10.6M
     !coeff1[4 * tileComp->w + 1])))) {
2822
10.6M
      if (cb->arithDecoder->decodeBit(jpxContextRunLength, cb->stats)) {
2823
179k
        y1 = cb->arithDecoder->decodeBit(jpxContextUniform, cb->stats);
2824
179k
        y1 = (y1 << 1) |
2825
179k
       cb->arithDecoder->decodeBit(jpxContextUniform, cb->stats);
2826
179k
        coeff = &coeff1[y1 * tileComp->w];
2827
179k
        cx = signContext[2][2][0];
2828
179k
        xorBit = signContext[2][2][1];
2829
179k
        if (cb->arithDecoder->decodeBit(cx, cb->stats) ^ xorBit) {
2830
115k
    *coeff = -1;
2831
115k
        } else {
2832
63.8k
    *coeff = 1;
2833
63.8k
        }
2834
179k
        ++y1;
2835
10.5M
      } else {
2836
10.5M
        y1 = 4;
2837
10.5M
      }
2838
10.6M
    }
2839
28.3M
    for (coeff = &coeff1[y1 * tileComp->w],
2840
28.3M
     touched = &touched1[y1 << resLevel->codeBlockW];
2841
90.4M
         y1 < 4 && y0 + y1 < cb->y1;
2842
62.0M
         ++y1, coeff += tileComp->w, touched += resLevel->cbW) {
2843
62.0M
      if (!*touched) {
2844
11.2M
        horiz = vert = diag = 0;
2845
11.2M
        horizSign = vertSign = 2;
2846
11.2M
        if (x > cb->x0) {
2847
10.3M
    if (coeff[-1]) {
2848
3.72M
      ++horiz;
2849
3.72M
      horizSign += coeff[-1] < 0 ? -1 : 1;
2850
3.72M
    }
2851
10.3M
    if (y0+y1 > cb->y0) {
2852
8.75M
      diag += coeff[-(int)tileComp->w - 1] ? 1 : 0;
2853
8.75M
    }
2854
10.3M
    if (y0+y1 < cb->y1 - 1 &&
2855
8.28M
        (!(tileComp->codeBlockStyle & 0x08) || y1 < 3)) {
2856
8.15M
      diag += coeff[tileComp->w - 1] ? 1 : 0;
2857
8.15M
    }
2858
10.3M
        }
2859
11.2M
        if (x < cb->x1 - 1) {
2860
10.0M
    if (coeff[1]) {
2861
102k
      ++horiz;
2862
102k
      horizSign += coeff[1] < 0 ? -1 : 1;
2863
102k
    }
2864
10.0M
    if (y0+y1 > cb->y0) {
2865
8.47M
      diag += coeff[-(int)tileComp->w + 1] ? 1 : 0;
2866
8.47M
    }
2867
10.0M
    if (y0+y1 < cb->y1 - 1 &&
2868
7.97M
        (!(tileComp->codeBlockStyle & 0x08) || y1 < 3)) {
2869
7.84M
      diag += coeff[tileComp->w + 1] ? 1 : 0;
2870
7.84M
    }
2871
10.0M
        }
2872
11.2M
        if (y0+y1 > cb->y0) {
2873
9.48M
    if (coeff[-(int)tileComp->w]) {
2874
3.78M
      ++vert;
2875
3.78M
      vertSign += coeff[-(int)tileComp->w] < 0 ? -1 : 1;
2876
3.78M
    }
2877
9.48M
        }
2878
11.2M
        if (y0+y1 < cb->y1 - 1 &&
2879
8.90M
      (!(tileComp->codeBlockStyle & 0x08) || y1 < 3)) {
2880
8.76M
    if (coeff[tileComp->w]) {
2881
94.4k
      ++vert;
2882
94.4k
      vertSign += coeff[tileComp->w] < 0 ? -1 : 1;
2883
94.4k
    }
2884
8.76M
        }
2885
11.2M
        cx = sigPropContext[horiz][vert][diag][res == 0 ? 1 : sb];
2886
11.2M
        if (cb->arithDecoder->decodeBit(cx, cb->stats)) {
2887
4.05M
    cx = signContext[horizSign][vertSign][0];
2888
4.05M
    xorBit = signContext[horizSign][vertSign][1];
2889
4.05M
    if (cb->arithDecoder->decodeBit(cx, cb->stats) ^ xorBit) {
2890
2.01M
      *coeff = -1;
2891
2.04M
    } else {
2892
2.04M
      *coeff = 1;
2893
2.04M
    }
2894
4.05M
        }
2895
50.8M
      } else {
2896
50.8M
        *touched = 0;
2897
50.8M
      }
2898
62.0M
    }
2899
28.3M
  }
2900
3.25M
      }
2901
821k
      ++cb->len;
2902
      // look for a segmentation symbol
2903
821k
      if (tileComp->codeBlockStyle & 0x20) {
2904
121k
  segSym = cb->arithDecoder->decodeBit(jpxContextUniform,
2905
121k
               cb->stats) << 3;
2906
121k
  segSym |= cb->arithDecoder->decodeBit(jpxContextUniform,
2907
121k
                cb->stats) << 2;
2908
121k
  segSym |= cb->arithDecoder->decodeBit(jpxContextUniform,
2909
121k
                cb->stats) << 1;
2910
121k
  segSym |= cb->arithDecoder->decodeBit(jpxContextUniform,
2911
121k
                cb->stats);
2912
121k
  if (segSym != 0x0a) {
2913
    // in theory this should be a fatal error, but it seems to
2914
    // be problematic
2915
115k
    error(errSyntaxWarning, getPos(),
2916
115k
    "Missing or invalid segmentation symbol in JPX stream");
2917
115k
  }
2918
121k
      }
2919
821k
      cb->nextPass = jpxPassSigProp;
2920
821k
      break;
2921
2.04M
    }
2922
2923
2.04M
    if (tileComp->codeBlockStyle & 0x02) {
2924
917k
      cb->stats->reset();
2925
917k
      cb->stats->setEntry(jpxContextSigProp, 4, 0);
2926
917k
      cb->stats->setEntry(jpxContextRunLength, 3, 0);
2927
917k
      cb->stats->setEntry(jpxContextUniform, 46, 0);
2928
917k
    }
2929
2930
2.04M
    if (tileComp->codeBlockStyle & 0x04) {
2931
485k
      cb->arithDecoder->cleanup();
2932
485k
    }
2933
2.04M
  }
2934
2935
330k
  cb->arithDecoder->cleanup();
2936
330k
  return gTrue;
2937
330k
}
2938
2939
// Inverse quantization, and wavelet transform (IDWT).  This also does
2940
// the initial shift to convert to fixed point format.
2941
64.6k
void JPXStream::inverseTransform(JPXTileComp *tileComp) {
2942
64.6k
  JPXResLevel *resLevel;
2943
64.6k
  JPXPrecinct *precinct;
2944
64.6k
  JPXSubband *subband;
2945
64.6k
  JPXCodeBlock *cb;
2946
64.6k
  int *coeff0, *coeff;
2947
64.6k
  char *touched0, *touched;
2948
64.6k
  Guint qStyle, guard, eps, shift;
2949
64.6k
  int shift2;
2950
64.6k
  double mu;
2951
64.6k
  int val;
2952
64.6k
  Guint r, pre, cbX, cbY, x, y;
2953
2954
64.6k
  cover(68);
2955
2956
  //----- (NL)LL subband (resolution level 0)
2957
2958
64.6k
  resLevel = &tileComp->resLevels[0];
2959
2960
  // i-quant parameters
2961
64.6k
  qStyle = tileComp->quantStyle & 0x1f;
2962
64.6k
  guard = (tileComp->quantStyle >> 5) & 7;
2963
64.6k
  if (qStyle == 0) {
2964
12.8k
    cover(69);
2965
12.8k
    eps = (tileComp->quantSteps[0] >> 3) & 0x1f;
2966
12.8k
    shift = guard + eps - 1;
2967
12.8k
    mu = 0; // make gcc happy
2968
51.8k
  } else {
2969
51.8k
    cover(70);
2970
51.8k
    shift = guard - 1 + tileComp->prec;
2971
51.8k
    mu = (double)(0x800 + (tileComp->quantSteps[0] & 0x7ff)) / 2048.0;
2972
51.8k
  }
2973
64.6k
  if (tileComp->transform == 0) {
2974
19.6k
    cover(71);
2975
19.6k
    shift += fracBits - tileComp->prec;
2976
19.6k
  }
2977
2978
  // do fixed point adjustment and dequantization on (NL)LL
2979
277k
  for (pre = 0; pre < resLevel->nPrecincts; ++pre) {
2980
212k
    precinct = &resLevel->precincts[pre];
2981
212k
    subband = &precinct->subbands[0];
2982
212k
    cb = subband->cbs;
2983
2.02M
    for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
2984
5.24M
      for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
2985
3.43M
  for (y = cb->y0, coeff0 = cb->coeffs, touched0 = cb->touched;
2986
32.0M
       y < cb->y1;
2987
28.6M
       ++y, coeff0 += tileComp->w, touched0 += resLevel->cbW) {
2988
28.6M
    for (x = cb->x0, coeff = coeff0, touched = touched0;
2989
122M
         x < cb->x1;
2990
93.9M
         ++x, ++coeff, ++touched) {
2991
93.9M
      val = *coeff;
2992
93.9M
      if (val != 0) {
2993
1.45M
        shift2 = shift - (cb->nZeroBitPlanes + cb->len + *touched);
2994
1.45M
        if (shift2 > 0) {
2995
1.17M
    cover(94);
2996
1.17M
    if (val < 0) {
2997
587k
      val = (val << shift2) - (1 << (shift2 - 1));
2998
588k
    } else {
2999
588k
      val = (val << shift2) + (1 << (shift2 - 1));
3000
588k
    }
3001
1.17M
        } else {
3002
277k
    cover(95);
3003
277k
    val >>= -shift2;
3004
277k
        }
3005
1.45M
        if (qStyle == 0) {
3006
68.1k
    cover(96);
3007
68.1k
    if (tileComp->transform == 0) {
3008
6.80k
      cover(97);
3009
6.80k
      val &= -1 << (fracBits - tileComp->prec);
3010
6.80k
    }
3011
1.38M
        } else {
3012
1.38M
    cover(98);
3013
1.38M
    val = (int)((double)val * mu);
3014
1.38M
        }
3015
1.45M
      }
3016
93.9M
      *coeff = val;
3017
93.9M
    }
3018
28.6M
  }
3019
3.43M
  ++cb;
3020
3.43M
      }
3021
1.81M
    }
3022
212k
  }
3023
3024
  //----- IDWT for each level
3025
3026
331k
  for (r = 1; r <= tileComp->nDecompLevels - reduction; ++r) {
3027
266k
    resLevel = &tileComp->resLevels[r];
3028
3029
    // (n)LL is already in the upper-left corner of the
3030
    // tile-component data array -- interleave with (n)HL/LH/HH
3031
    // and inverse transform to get (n-1)LL, which will be stored
3032
    // in the upper-left corner of the tile-component data array
3033
266k
    inverseTransformLevel(tileComp, r, resLevel);
3034
266k
  }
3035
64.6k
}
3036
3037
// Do one level of the inverse transform:
3038
// - take (n)LL, (n)HL, (n)LH, and (n)HH from the upper-left corner
3039
//   of the tile-component data array
3040
// - leave the resulting (n-1)LL in the same place
3041
void JPXStream::inverseTransformLevel(JPXTileComp *tileComp,
3042
266k
              Guint r, JPXResLevel *resLevel) {
3043
266k
  JPXPrecinct *precinct;
3044
266k
  JPXSubband *subband;
3045
266k
  JPXCodeBlock *cb;
3046
266k
  int *coeff0, *coeff;
3047
266k
  char *touched0, *touched;
3048
266k
  Guint qStyle, guard, eps, shift, t;
3049
266k
  int shift2;
3050
266k
  double mu;
3051
266k
  int val;
3052
266k
  int *dataPtr, *bufPtr;
3053
266k
  Guint nx1, nx2, ny1, ny2, offset;
3054
266k
  Guint x, y, sb, pre, cbX, cbY;
3055
3056
266k
  qStyle = tileComp->quantStyle & 0x1f;
3057
266k
  guard = (tileComp->quantStyle >> 5) & 7;
3058
3059
  //----- compute subband bounds
3060
3061
  //    0   nx1  nx2
3062
  //    |    |    |
3063
  //    v    v    v
3064
  //   +----+----+
3065
  //   | LL | HL | <- 0
3066
  //   +----+----+
3067
  //   | LH | HH | <- ny1
3068
  //   +----+----+
3069
  //               <- ny2
3070
266k
  nx1 = resLevel->bx1[1] - resLevel->bx0[1];
3071
266k
  nx2 = nx1 + resLevel->bx1[0] - resLevel->bx0[0];
3072
266k
  ny1 = resLevel->by1[0] - resLevel->by0[0];
3073
266k
  ny2 = ny1 + resLevel->by1[1] - resLevel->by0[1];
3074
266k
  if (nx2 == 0 || ny2 == 0) {
3075
84.5k
    return;
3076
84.5k
  }
3077
3078
  //----- fixed-point adjustment and dequantization
3079
3080
727k
  for (sb = 0; sb < 3; ++sb) {
3081
3082
    // i-quant parameters
3083
545k
    if (qStyle == 0) {
3084
74.2k
      cover(100);
3085
74.2k
      eps = (tileComp->quantSteps[3*r - 2 + sb] >> 3) & 0x1f;
3086
74.2k
      shift = guard + eps - 1;
3087
74.2k
      mu = 0; // make gcc happy
3088
471k
    } else {
3089
471k
      cover(101);
3090
471k
      shift = guard + tileComp->prec;
3091
471k
      if (sb == 2) {
3092
157k
  cover(102);
3093
157k
  ++shift;
3094
157k
      }
3095
471k
      t = tileComp->quantSteps[qStyle == 1 ? 0 : (3*r - 2 + sb)];
3096
471k
      mu = (double)(0x800 + (t & 0x7ff)) / 2048.0;
3097
471k
    }
3098
545k
    if (tileComp->transform == 0) {
3099
181k
      cover(103);
3100
181k
      shift += fracBits - tileComp->prec;
3101
181k
    }
3102
3103
    // fixed point adjustment and dequantization
3104
3105
5.06M
    for (pre = 0; pre < resLevel->nPrecincts; ++pre) {
3106
4.52M
      precinct = &resLevel->precincts[pre];
3107
4.52M
      subband = &precinct->subbands[sb];
3108
4.52M
      cb = subband->cbs;
3109
27.9M
      for (cbY = 0; cbY < subband->nYCBs; ++cbY) {
3110
56.4M
  for (cbX = 0; cbX < subband->nXCBs; ++cbX) {
3111
33.0M
    for (y = cb->y0, coeff0 = cb->coeffs, touched0 = cb->touched;
3112
305M
         y < cb->y1;
3113
272M
         ++y, coeff0 += tileComp->w, touched0 += resLevel->cbW) {
3114
272M
      for (x = cb->x0, coeff = coeff0, touched = touched0;
3115
1.67G
     x < cb->x1;
3116
1.39G
     ++x, ++coeff, ++touched) {
3117
1.39G
        val = *coeff;
3118
1.39G
        if (val != 0) {
3119
4.67M
    shift2 = shift - (cb->nZeroBitPlanes + cb->len + *touched);
3120
4.67M
    if (shift2 > 0) {
3121
3.03M
      cover(74);
3122
3.03M
      if (val < 0) {
3123
1.53M
        val = (val << shift2) - (1 << (shift2 - 1));
3124
1.53M
      } else {
3125
1.49M
        val = (val << shift2) + (1 << (shift2 - 1));
3126
1.49M
      }
3127
3.03M
    } else {
3128
1.64M
      cover(75);
3129
1.64M
      val >>= -shift2;
3130
1.64M
    }
3131
4.67M
    if (qStyle == 0) {
3132
1.91M
      cover(76);
3133
1.91M
      if (tileComp->transform == 0) {
3134
7.74k
        val &= -1 << (fracBits - tileComp->prec);
3135
7.74k
      }
3136
2.75M
    } else {
3137
2.75M
      cover(77);
3138
2.75M
      val = (int)((double)val * mu);
3139
2.75M
    }
3140
4.67M
        }
3141
1.39G
        *coeff = val;
3142
1.39G
      }
3143
272M
    }
3144
33.0M
    ++cb;
3145
33.0M
  }
3146
23.4M
      }
3147
4.52M
    }
3148
545k
  }
3149
3150
  //----- inverse transform
3151
3152
  // horizontal (row) transforms
3153
181k
  offset = 3 + (resLevel->x0 & 1);
3154
144M
  for (y = 0, dataPtr = tileComp->data; y < ny2; ++y, dataPtr += tileComp->w) {
3155
144M
    if (resLevel->bx0[0] == resLevel->bx0[1]) {
3156
      // fetch LL/LH
3157
60.1M
      for (x = 0, bufPtr = tileComp->buf + offset;
3158
531M
     x < nx1;
3159
470M
     ++x, bufPtr += 2) {
3160
470M
  *bufPtr = dataPtr[x];
3161
470M
      }
3162
      // fetch HL/HH
3163
60.1M
      for (x = nx1, bufPtr = tileComp->buf + offset + 1;
3164
504M
     x < nx2;
3165
444M
     ++x, bufPtr += 2) {
3166
444M
  *bufPtr = dataPtr[x];
3167
444M
      }
3168
84.1M
    } else {
3169
      // fetch LL/LH
3170
84.1M
      for (x = 0, bufPtr = tileComp->buf + offset + 1;
3171
517M
     x < nx1;
3172
432M
     ++x, bufPtr += 2) {
3173
432M
  *bufPtr = dataPtr[x];
3174
432M
      }
3175
      // fetch HL/HH
3176
84.1M
      for (x = nx1, bufPtr = tileComp->buf + offset;
3177
565M
     x < nx2;
3178
481M
     ++x, bufPtr += 2) {
3179
481M
  *bufPtr = dataPtr[x];
3180
481M
      }
3181
84.1M
    }
3182
144M
    inverseTransform1D(tileComp, tileComp->buf, offset, nx2);
3183
1.97G
    for (x = 0, bufPtr = tileComp->buf + offset; x < nx2; ++x, ++bufPtr) {
3184
1.82G
      dataPtr[x] = *bufPtr;
3185
1.82G
    }
3186
144M
  }
3187
3188
  // vertical (column) transforms
3189
181k
  offset = 3 + (resLevel->y0 & 1);
3190
154M
  for (x = 0, dataPtr = tileComp->data; x < nx2; ++x, ++dataPtr) {
3191
153M
    if (resLevel->by0[0] == resLevel->by0[1]) {
3192
      // fetch LL/HL
3193
28.5M
      for (y = 0, bufPtr = tileComp->buf + offset;
3194
385M
     y < ny1;
3195
357M
     ++y, bufPtr += 2) {
3196
357M
  *bufPtr = dataPtr[y * tileComp->w];
3197
357M
      }
3198
      // fetch LH/HH
3199
28.5M
      for (y = ny1, bufPtr = tileComp->buf + offset + 1;
3200
364M
     y < ny2;
3201
335M
     ++y, bufPtr += 2) {
3202
335M
  *bufPtr = dataPtr[y * tileComp->w];
3203
335M
      }
3204
125M
    } else {
3205
      // fetch LL/HL
3206
125M
      for (y = 0, bufPtr = tileComp->buf + offset + 1;
3207
640M
     y < ny1;
3208
515M
     ++y, bufPtr += 2) {
3209
515M
  *bufPtr = dataPtr[y * tileComp->w];
3210
515M
      }
3211
      // fetch LH/HH
3212
125M
      for (y = ny1, bufPtr = tileComp->buf + offset;
3213
746M
     y < ny2;
3214
621M
     ++y, bufPtr += 2) {
3215
621M
  *bufPtr = dataPtr[y * tileComp->w];
3216
621M
      }
3217
125M
    }
3218
153M
    inverseTransform1D(tileComp, tileComp->buf, offset, ny2);
3219
1.98G
    for (y = 0, bufPtr = tileComp->buf + offset; y < ny2; ++y, ++bufPtr) {
3220
1.82G
      dataPtr[y * tileComp->w] = *bufPtr;
3221
1.82G
    }
3222
153M
  }
3223
181k
}
3224
3225
void JPXStream::inverseTransform1D(JPXTileComp *tileComp, int *data,
3226
298M
           Guint offset, Guint n) {
3227
298M
  Guint end, i;
3228
3229
  //----- special case for length = 1
3230
298M
  if (n == 1) {
3231
170M
    cover(79);
3232
170M
    if (offset == 4) {
3233
132M
      cover(104);
3234
132M
      *data >>= 1;
3235
132M
    }
3236
3237
170M
  } else {
3238
127M
    cover(80);
3239
3240
127M
    end = offset + n;
3241
3242
    //----- extend right
3243
127M
    data[end] = data[end - 2];
3244
127M
    if (n == 2) {
3245
46.3M
      cover(81);
3246
46.3M
      data[end+1] = data[offset + 1];
3247
46.3M
      data[end+2] = data[offset];
3248
46.3M
      data[end+3] = data[offset + 1];
3249
81.4M
    } else {
3250
81.4M
      cover(82);
3251
81.4M
      data[end+1] = data[end - 3];
3252
81.4M
      if (n == 3) {
3253
8.46M
  cover(105);
3254
8.46M
  data[end+2] = data[offset + 1];
3255
8.46M
  data[end+3] = data[offset + 2];
3256
72.9M
      } else {
3257
72.9M
  cover(106);
3258
72.9M
  data[end+2] = data[end - 4];
3259
72.9M
  if (n == 4) {
3260
8.81M
    cover(107);
3261
8.81M
    data[end+3] = data[offset + 1];
3262
64.1M
  } else {
3263
64.1M
    cover(108);
3264
64.1M
    data[end+3] = data[end - 5];
3265
64.1M
  }
3266
72.9M
      }
3267
81.4M
    }
3268
3269
    //----- extend left
3270
127M
    data[offset - 1] = data[offset + 1];
3271
127M
    data[offset - 2] = data[offset + 2];
3272
127M
    data[offset - 3] = data[offset + 3];
3273
127M
    if (offset == 4) {
3274
76.9M
      cover(83);
3275
76.9M
      data[0] = data[offset + 4];
3276
76.9M
    }
3277
3278
    //----- 9-7 irreversible filter
3279
3280
127M
    if (tileComp->transform == 0) {
3281
21.8M
      cover(84);
3282
      // step 1 (even)
3283
492M
      for (i = 1; i <= end + 2; i += 2) {
3284
470M
  data[i] = (int)(idwtKappa * data[i]);
3285
470M
      }
3286
      // step 2 (odd)
3287
514M
      for (i = 0; i <= end + 3; i += 2) {
3288
492M
  data[i] = (int)(idwtIKappa * data[i]);
3289
492M
      }
3290
      // step 3 (even)
3291
492M
      for (i = 1; i <= end + 2; i += 2) {
3292
470M
  data[i] = (int)(data[i] - idwtDelta * (data[i-1] + data[i+1]));
3293
470M
      }
3294
      // step 4 (odd)
3295
470M
      for (i = 2; i <= end + 1; i += 2) {
3296
449M
  data[i] = (int)(data[i] - idwtGamma * (data[i-1] + data[i+1]));
3297
449M
      }
3298
      // step 5 (even)
3299
449M
      for (i = 3; i <= end; i += 2) {
3300
427M
  data[i] = (int)(data[i] - idwtBeta * (data[i-1] + data[i+1]));
3301
427M
      }
3302
      // step 6 (odd)
3303
427M
      for (i = 4; i <= end - 1; i += 2) {
3304
405M
  data[i] = (int)(data[i] - idwtAlpha * (data[i-1] + data[i+1]));
3305
405M
      }
3306
3307
    //----- 5-3 reversible filter
3308
3309
105M
    } else {
3310
105M
      cover(85);
3311
      // step 1 (even)
3312
1.55G
      for (i = 3; i <= end; i += 2) {
3313
1.45G
  data[i] -= (data[i-1] + data[i+1] + 2) >> 2;
3314
1.45G
      }
3315
      // step 2 (odd)
3316
1.45G
      for (i = 4; i < end; i += 2) {
3317
1.34G
  data[i] += (data[i-1] + data[i+1]) >> 1;
3318
1.34G
      }
3319
105M
    }
3320
127M
  }
3321
298M
}
3322
3323
// Inverse multi-component transform and DC level shift.  This also
3324
// converts fixed point samples back to integers.
3325
18.9k
GBool JPXStream::inverseMultiCompAndDC(JPXTile *tile) {
3326
18.9k
  JPXTileComp *tileComp;
3327
18.9k
  int coeff, d0, d1, d2, t, minVal, maxVal, zeroVal, shift, rounding;
3328
18.9k
  int *dataPtr;
3329
18.9k
  Guint j, comp, x, y;
3330
3331
  //----- inverse multi-component transform
3332
3333
18.9k
  if (tile->multiComp == 1) {
3334
8.60k
    cover(86);
3335
8.60k
    if (img.nComps < 3 ||
3336
4.50k
  tile->tileComps[0].hSep != tile->tileComps[1].hSep ||
3337
3.32k
  tile->tileComps[0].vSep != tile->tileComps[1].vSep ||
3338
2.50k
  tile->tileComps[1].hSep != tile->tileComps[2].hSep ||
3339
7.15k
  tile->tileComps[1].vSep != tile->tileComps[2].vSep) {
3340
7.15k
      return gFalse;
3341
7.15k
    }
3342
3343
    // inverse irreversible multiple component transform
3344
1.45k
    if (tile->tileComps[0].transform == 0) {
3345
596
      cover(87);
3346
596
      j = 0;
3347
334k
      for (y = 0; y < tile->tileComps[0].h; ++y) {
3348
11.4M
  for (x = 0; x < tile->tileComps[0].w; ++x) {
3349
11.1M
    d0 = tile->tileComps[0].data[j];
3350
11.1M
    d1 = tile->tileComps[1].data[j];
3351
11.1M
    d2 = tile->tileComps[2].data[j];
3352
11.1M
    tile->tileComps[0].data[j] = (int)(d0 + 1.402 * d2 + 0.5);
3353
11.1M
    tile->tileComps[1].data[j] =
3354
11.1M
        (int)(d0 - 0.34413 * d1 - 0.71414 * d2 + 0.5);
3355
11.1M
    tile->tileComps[2].data[j] = (int)(d0 + 1.772 * d1 + 0.5);
3356
11.1M
    ++j;
3357
11.1M
  }
3358
334k
      }
3359
3360
    // inverse reversible multiple component transform
3361
856
    } else {
3362
856
      cover(88);
3363
856
      j = 0;
3364
155k
      for (y = 0; y < tile->tileComps[0].h; ++y) {
3365
25.6M
  for (x = 0; x < tile->tileComps[0].w; ++x) {
3366
25.5M
    d0 = tile->tileComps[0].data[j];
3367
25.5M
    d1 = tile->tileComps[1].data[j];
3368
25.5M
    d2 = tile->tileComps[2].data[j];
3369
25.5M
    tile->tileComps[1].data[j] = t = d0 - ((d2 + d1) >> 2);
3370
25.5M
    tile->tileComps[0].data[j] = d2 + t;
3371
25.5M
    tile->tileComps[2].data[j] = d1 + t;
3372
25.5M
    ++j;
3373
25.5M
  }
3374
154k
      }
3375
856
    }
3376
1.45k
  }
3377
3378
  //----- DC level shift
3379
43.4k
  for (comp = 0; comp < img.nComps; ++comp) {
3380
31.6k
    tileComp = &tile->tileComps[comp];
3381
3382
    // signed: clip
3383
31.6k
    if (tileComp->sgned) {
3384
8.38k
      cover(89);
3385
8.38k
      minVal = -(1 << (tileComp->prec - 1));
3386
8.38k
      maxVal = (1 << (tileComp->prec - 1)) - 1;
3387
8.38k
      dataPtr = tileComp->data;
3388
2.51M
      for (y = 0; y < tileComp->h; ++y) {
3389
90.9M
  for (x = 0; x < tileComp->w; ++x) {
3390
88.4M
    coeff = *dataPtr;
3391
88.4M
    if (tileComp->transform == 0) {
3392
19.7M
      cover(109);
3393
19.7M
      coeff >>= fracBits - tileComp->prec;
3394
19.7M
    }
3395
88.4M
    if (coeff < minVal) {
3396
1.76M
      cover(110);
3397
1.76M
      coeff = minVal;
3398
86.6M
    } else if (coeff > maxVal) {
3399
40.3M
      cover(111);
3400
40.3M
      coeff = maxVal;
3401
40.3M
    }
3402
88.4M
    *dataPtr++ = coeff;
3403
88.4M
  }
3404
2.50M
      }
3405
3406
    // unsigned: inverse DC level shift and clip
3407
23.2k
    } else {
3408
23.2k
      cover(90);
3409
23.2k
      maxVal = (1 << tileComp->prec) - 1;
3410
23.2k
      zeroVal = 1 << (tileComp->prec - 1);
3411
23.2k
      dataPtr = tileComp->data;
3412
23.2k
      shift = fracBits - tileComp->prec;
3413
23.2k
      rounding = 1 << (shift - 1);
3414
69.4M
      for (y = 0; y < tileComp->h; ++y) {
3415
963M
  for (x = 0; x < tileComp->w; ++x) {
3416
894M
    coeff = *dataPtr;
3417
894M
    if (tileComp->transform == 0) {
3418
224M
      cover(112);
3419
224M
      coeff = (coeff + rounding) >> shift;
3420
224M
    }
3421
894M
    coeff += zeroVal;
3422
894M
    if (coeff < 0) {
3423
26.0M
      cover(113);
3424
26.0M
      coeff = 0;
3425
868M
    } else if (coeff > maxVal) {
3426
22.9M
      cover(114);
3427
22.9M
      coeff = maxVal;
3428
22.9M
    }
3429
894M
    *dataPtr++ = coeff;
3430
894M
  }
3431
69.3M
      }
3432
23.2k
    }
3433
31.6k
  }
3434
3435
11.8k
  return gTrue;
3436
18.9k
}
3437
3438
122k
GBool JPXStream::readBoxHdr(Guint *boxType, Guint *boxLen, Guint *dataLen) {
3439
122k
  Guint len, lenH;
3440
3441
122k
  if (!readULong(&len) ||
3442
120k
      !readULong(boxType)) {
3443
3.06k
    return gFalse;
3444
3.06k
  }
3445
119k
  if (len == 1) {
3446
3.17k
    if (!readULong(&lenH) || !readULong(&len)) {
3447
2.33k
      return gFalse;
3448
2.33k
    }
3449
837
    if (lenH) {
3450
537
      error(errSyntaxError, getPos(),
3451
537
      "JPX stream contains a box larger than 2^32 bytes");
3452
537
      return gFalse;
3453
537
    }
3454
300
    *boxLen = len;
3455
300
    *dataLen = len - 16;
3456
116k
  } else if (len == 0) {
3457
2.80k
    *boxLen = 0;
3458
2.80k
    *dataLen = 0;
3459
113k
  } else {
3460
113k
    *boxLen = len;
3461
113k
    *dataLen = len - 8;
3462
113k
  }
3463
116k
  return gTrue;
3464
119k
}
3465
3466
791k
int JPXStream::readMarkerHdr(int *segType, Guint *segLen) {
3467
791k
  int c;
3468
3469
836k
  do {
3470
51.4M
    do {
3471
51.4M
      if ((c = bufStr->getChar()) == EOF) {
3472
8.34k
  return gFalse;
3473
8.34k
      }
3474
51.4M
    } while (c != 0xff);
3475
1.25M
    do {
3476
1.25M
      if ((c = bufStr->getChar()) == EOF) {
3477
753
  return gFalse;
3478
753
      }
3479
1.25M
    } while (c == 0xff);
3480
828k
  } while (c == 0x00);
3481
782k
  *segType = c;
3482
782k
  if ((c >= 0x30 && c <= 0x3f) ||
3483
755k
      c == 0x4f || c == 0x92 || c == 0x93 || c == 0xd9) {
3484
123k
    *segLen = 0;
3485
123k
    return gTrue;
3486
123k
  }
3487
659k
  return readUWord(segLen);
3488
782k
}
3489
3490
9.76M
GBool JPXStream::readUByte(Guint *x) {
3491
9.76M
  int c0;
3492
3493
9.76M
  if ((c0 = bufStr->getChar()) == EOF) {
3494
16.5k
    return gFalse;
3495
16.5k
  }
3496
9.75M
  *x = (Guint)c0;
3497
9.75M
  return gTrue;
3498
9.76M
}
3499
3500
13.0k
GBool JPXStream::readByte(int *x) {
3501
13.0k
 int c0;
3502
3503
13.0k
  if ((c0 = bufStr->getChar()) == EOF) {
3504
368
    return gFalse;
3505
368
  }
3506
12.7k
  *x = c0;
3507
12.7k
  if (c0 & 0x80) {
3508
9.91k
    *x |= -1 - 0xff;
3509
9.91k
  }
3510
12.7k
  return gTrue;
3511
13.0k
}
3512
3513
5.25M
GBool JPXStream::readUWord(Guint *x) {
3514
5.25M
  int c0, c1;
3515
3516
5.25M
  if ((c0 = bufStr->getChar()) == EOF ||
3517
5.25M
      (c1 = bufStr->getChar()) == EOF) {
3518
14.7k
    return gFalse;
3519
14.7k
  }
3520
5.24M
  *x = (Guint)((c0 << 8) | c1);
3521
5.24M
  return gTrue;
3522
5.25M
}
3523
3524
969k
GBool JPXStream::readULong(Guint *x) {
3525
969k
  int c0, c1, c2, c3;
3526
3527
969k
  if ((c0 = bufStr->getChar()) == EOF ||
3528
962k
      (c1 = bufStr->getChar()) == EOF ||
3529
958k
      (c2 = bufStr->getChar()) == EOF ||
3530
953k
      (c3 = bufStr->getChar()) == EOF) {
3531
20.7k
    return gFalse;
3532
20.7k
  }
3533
948k
  *x = (Guint)((c0 << 24) | (c1 << 16) | (c2 << 8) | c3);
3534
948k
  return gTrue;
3535
969k
}
3536
3537
167k
GBool JPXStream::readNBytes(int nBytes, GBool signd, int *x) {
3538
167k
  int y, c, i;
3539
3540
167k
  y = 0;
3541
1.59M
  for (i = 0; i < nBytes; ++i) {
3542
1.42M
    if ((c = bufStr->getChar()) == EOF) {
3543
389
      return gFalse;
3544
389
    }
3545
1.42M
    y = (y << 8) + c;
3546
1.42M
  }
3547
166k
  if (signd) {
3548
47.6k
    if (y & (1 << (8 * nBytes - 1))) {
3549
3.09k
      y |= -1 << (8 * nBytes);
3550
3.09k
    }
3551
47.6k
  }
3552
166k
  *x = y;
3553
166k
  return gTrue;
3554
167k
}
3555
3556
1.93M
void JPXStream::startBitBuf(Guint byteCountA) {
3557
1.93M
  bitBufLen = 0;
3558
1.93M
  bitBufSkip = gFalse;
3559
1.93M
  byteCount = byteCountA;
3560
1.93M
}
3561
3562
10.4M
GBool JPXStream::readBits(int nBits, Guint *x) {
3563
10.4M
  int c;
3564
3565
14.7M
  while (bitBufLen < nBits) {
3566
4.30M
    if (byteCount == 0 || (c = bufStr->getChar()) == EOF) {
3567
12.1k
      return gFalse;
3568
12.1k
    }
3569
4.29M
    --byteCount;
3570
4.29M
    if (bitBufSkip) {
3571
131k
      bitBuf = (bitBuf << 7) | (c & 0x7f);
3572
131k
      bitBufLen += 7;
3573
4.15M
    } else {
3574
4.15M
      bitBuf = (bitBuf << 8) | (c & 0xff);
3575
4.15M
      bitBufLen += 8;
3576
4.15M
    }
3577
4.29M
    bitBufSkip = c == 0xff;
3578
4.29M
  }
3579
10.4M
  *x = (bitBuf >> (bitBufLen - nBits)) & ((1 << nBits) - 1);
3580
10.4M
  bitBufLen -= nBits;
3581
10.4M
  return gTrue;
3582
10.4M
}
3583
3584
378k
void JPXStream::skipSOP() {
3585
  // SOP occurs at the start of the packet header, so we don't need to
3586
  // worry about bit-stuff prior to it
3587
378k
  if (byteCount >= 6 &&
3588
376k
      bufStr->lookChar(0) == 0xff &&
3589
11.3k
      bufStr->lookChar(1) == 0x91) {
3590
2.53k
    bufStr->discardChars(6);
3591
2.53k
    byteCount -= 6;
3592
2.53k
    bitBufLen = 0;
3593
2.53k
    bitBufSkip = gFalse;
3594
2.53k
  }
3595
378k
}
3596
3597
491k
void JPXStream::skipEPH() {
3598
491k
  int k;
3599
3600
491k
  k = bitBufSkip ? 1 : 0;
3601
491k
  if (byteCount >= (Guint)(k + 2) &&
3602
489k
      bufStr->lookChar(k) == 0xff &&
3603
12.1k
      bufStr->lookChar(k + 1) == 0x92) {
3604
247
    bufStr->discardChars(k + 2);
3605
247
    byteCount -= k + 2;
3606
247
    bitBufLen = 0;
3607
247
    bitBufSkip = gFalse;
3608
247
  }
3609
491k
}
3610
3611
1.92M
Guint JPXStream::finishBitBuf() {
3612
1.92M
  if (bitBufSkip) {
3613
2.61k
    bufStr->getChar();
3614
2.61k
    --byteCount;
3615
2.61k
  }
3616
1.92M
  return byteCount;
3617
1.92M
}