summaryrefslogtreecommitdiff
path: root/poppler/JPXStream.h
blob: 047579e4d9f087b572d4ef545432def0d423b4b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
//========================================================================
//
// JPXStream.h
//
// Copyright 2002-2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2019 Albert Astals Cid <aacid@kde.org>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#ifndef JPXSTREAM_H
#define JPXSTREAM_H

#include "Object.h"
#include "Stream.h"

class JArithmeticDecoder;
class JArithmeticDecoderStats;

//------------------------------------------------------------------------

enum JPXColorSpaceType {
  jpxCSBiLevel = 0,
  jpxCSYCbCr1 = 1,
  jpxCSYCbCr2 = 3,
  jpxCSYCBCr3 = 4,
  jpxCSPhotoYCC = 9,
  jpxCSCMY = 11,
  jpxCSCMYK = 12,
  jpxCSYCCK = 13,
  jpxCSCIELab = 14,
  jpxCSsRGB = 16,
  jpxCSGrayscale = 17,
  jpxCSBiLevel2 = 18,
  jpxCSCIEJab = 19,
  jpxCSCISesRGB = 20,
  jpxCSROMMRGB = 21,
  jpxCSsRGBYCbCr = 22,
  jpxCSYPbPr1125 = 23,
  jpxCSYPbPr1250 = 24
};

struct JPXColorSpecCIELab {
  unsigned int rl, ol, ra, oa, rb, ob, il;
};

struct JPXColorSpecEnumerated {
  JPXColorSpaceType type;	// color space type
  union {
    JPXColorSpecCIELab cieLab;
  };
};

struct JPXColorSpec {
  unsigned int meth;			// method
  int prec;			// precedence
  union {
    JPXColorSpecEnumerated enumerated;
  };
};

//------------------------------------------------------------------------

struct JPXPalette {
  unsigned int nEntries;		// number of entries in the palette
  unsigned int nComps;			// number of components in each entry
  unsigned int *bpc;			// bits per component, for each component
  int *c;			// color data:
				//   c[i*nComps+j] = entry i, component j
};

//------------------------------------------------------------------------

struct JPXCompMap {
  unsigned int nChannels;		// number of channels
  unsigned int *comp;			// codestream components mapped to each channel
  unsigned int *type;			// 0 for direct use, 1 for palette mapping
  unsigned int *pComp;			// palette components to use
};

//------------------------------------------------------------------------

struct JPXChannelDefn {
  unsigned int nChannels;		// number of channels
  unsigned int *idx;			// channel indexes
  unsigned int *type;			// channel types
  unsigned int *assoc;			// channel associations
};

//------------------------------------------------------------------------

struct JPXTagTreeNode {
  bool finished;		// true if this node is finished
  unsigned int val;			// current value
};

//------------------------------------------------------------------------

struct JPXCodeBlock {
  //----- size
  unsigned int x0, y0, x1, y1;		// bounds

  //----- persistent state
  bool seen;			// true if this code-block has already
				//   been seen
  unsigned int lBlock;			// base number of bits used for pkt data length
  unsigned int nextPass;		// next coding pass

  //---- info from first packet
  unsigned int nZeroBitPlanes;		// number of zero bit planes

  //----- info for the current packet
  unsigned int included;		// code-block inclusion in this packet:
				//   0=not included, 1=included
  unsigned int nCodingPasses;		// number of coding passes in this pkt
  unsigned int *dataLen;		// data lengths (one per codeword segment)
  unsigned int dataLenSize;		// size of the dataLen array

  //----- coefficient data
  int *coeffs;
  char *touched;		// coefficient 'touched' flags
  unsigned short len;			// coefficient length
  JArithmeticDecoder		// arithmetic decoder
    *arithDecoder;
  JArithmeticDecoderStats	// arithmetic decoder stats
    *stats;
};

//------------------------------------------------------------------------

struct JPXSubband {
  //----- computed
  unsigned int x0, y0, x1, y1;		// bounds
  unsigned int nXCBs, nYCBs;		// number of code-blocks in the x and y
				//   directions

  //----- tag trees
  unsigned int maxTTLevel;		// max tag tree level
  JPXTagTreeNode *inclusion;	// inclusion tag tree for each subband
  JPXTagTreeNode *zeroBitPlane;	// zero-bit plane tag tree for each
				//   subband

  //----- children
  JPXCodeBlock *cbs;		// the code-blocks (len = nXCBs * nYCBs)
};

//------------------------------------------------------------------------

struct JPXPrecinct {
  //----- computed
  unsigned int x0, y0, x1, y1;		// bounds of the precinct

  //----- children
  JPXSubband *subbands;		// the subbands
};

//------------------------------------------------------------------------

struct JPXResLevel {
  //----- from the COD and COC segments (main and tile)
  unsigned int precinctWidth;		// log2(precinct width)
  unsigned int precinctHeight;		// log2(precinct height)

  //----- computed
  unsigned int x0, y0, x1, y1;		// bounds of the tile-comp (for this res level)
  unsigned int bx0[3], by0[3],		// subband bounds
        bx1[3], by1[3];

  //---- children
  JPXPrecinct *precincts;	// the precincts
};

//------------------------------------------------------------------------

struct JPXTileComp {
  //----- from the SIZ segment
  bool sgned;			// 1 for signed, 0 for unsigned
  unsigned int prec;			// precision, in bits
  unsigned int hSep;			// horizontal separation of samples
  unsigned int vSep;			// vertical separation of samples

  //----- from the COD and COC segments (main and tile)
  unsigned int style;			// coding style parameter (Scod / Scoc)
  unsigned int nDecompLevels;		// number of decomposition levels
  unsigned int codeBlockW;		// log2(code-block width)
  unsigned int codeBlockH;		// log2(code-block height)
  unsigned int codeBlockStyle;		// code-block style
  unsigned int transform;		// wavelet transformation

  //----- from the QCD and QCC segments (main and tile)
  unsigned int quantStyle;		// quantization style
  unsigned int *quantSteps;		// quantization step size for each subband
  unsigned int nQuantSteps;		// number of entries in quantSteps

  //----- computed
  unsigned int x0, y0, x1, y1;		// bounds of the tile-comp, in ref coords
  unsigned int w;			// x1 - x0
  unsigned int cbW;			// code-block width
  unsigned int cbH;			// code-block height

  //----- image data
  int *data;			// the decoded image data
  int *buf;			// intermediate buffer for the inverse
				//   transform

  //----- children
  JPXResLevel *resLevels;	// the resolution levels
				//   (len = nDecompLevels + 1)
};

//------------------------------------------------------------------------

struct JPXTile {
  bool init;

  //----- from the COD segments (main and tile)
  unsigned int progOrder;		// progression order
  unsigned int nLayers;		// number of layers
  unsigned int multiComp;		// multiple component transformation

  //----- computed
  unsigned int x0, y0, x1, y1;		// bounds of the tile, in ref coords
  unsigned int maxNDecompLevels;	// max number of decomposition levels used
				//   in any component in this tile

  //----- progression order loop counters
  unsigned int comp;			//   component
  unsigned int res;			//   resolution level
  unsigned int precinct;		//   precinct
  unsigned int layer;			//   layer

  //----- children
  JPXTileComp *tileComps;	// the tile-components (len = JPXImage.nComps)
};

//------------------------------------------------------------------------

struct JPXImage {
  //----- from the SIZ segment
  unsigned int xSize, ySize;		// size of reference grid
  unsigned int xOffset, yOffset;	// image offset
  unsigned int xTileSize, yTileSize;	// size of tiles
  unsigned int xTileOffset,		// offset of first tile
        yTileOffset;
  unsigned int nComps;			// number of components

  //----- computed
  unsigned int nXTiles;		// number of tiles in x direction
  unsigned int nYTiles;		// number of tiles in y direction

  //----- children
  JPXTile *tiles;		// the tiles (len = nXTiles * nYTiles)
};

//------------------------------------------------------------------------

class JPXStream: public FilterStream {
public:

  JPXStream(Stream *strA);
  virtual ~JPXStream();
  StreamKind getKind() const override { return strJPX; }
  void reset() override;
  void close() override;
  int getChar() override;
  int lookChar() override;
  GooString *getPSFilter(int psLevel, const char *indent) override;
  bool isBinary(bool last = true) override;
  void getImageParams(int *bitsPerComponent,
			      StreamColorSpaceMode *csMode) override;

private:

  void fillReadBuf();
  void getImageParams2(int *bitsPerComponent, StreamColorSpaceMode *csMode);
  bool readBoxes();
  bool readColorSpecBox(unsigned int dataLen);
  bool readCodestream(unsigned int len);
  bool readTilePart();
  bool readTilePartData(unsigned int tileIdx,
			 unsigned int tilePartLen, bool tilePartToEOC);
  bool readCodeBlockData(JPXTileComp *tileComp,
			  JPXResLevel *resLevel,
			  JPXPrecinct *precinct,
			  JPXSubband *subband,
			  unsigned int res, unsigned int sb,
			  JPXCodeBlock *cb);
  void inverseTransform(JPXTileComp *tileComp);
  void inverseTransformLevel(JPXTileComp *tileComp,
			     unsigned int r, JPXResLevel *resLevel);
  void inverseTransform1D(JPXTileComp *tileComp, int *data,
			  unsigned int offset, unsigned int n);
  bool inverseMultiCompAndDC(JPXTile *tile);
  bool readBoxHdr(unsigned int *boxType, unsigned int *boxLen, unsigned int *dataLen);
  int readMarkerHdr(int *segType, unsigned int *segLen);
  bool readUByte(unsigned int *x);
  bool readByte(int *x);
  bool readUWord(unsigned int *x);
  bool readULong(unsigned int *x);
  bool readNBytes(int nBytes, bool signd, int *x);
  void startBitBuf(unsigned int byteCountA);
  bool readBits(int nBits, unsigned int *x);
  void skipSOP();
  void skipEPH();
  unsigned int finishBitBuf();

  BufStream *bufStr;		// buffered stream (for lookahead)

  unsigned int nComps;			// number of components
  unsigned int *bpc;			// bits per component, for each component
  unsigned int width, height;		// image size
  bool haveImgHdr;		// set if a JP2/JPX image header has been
				//   found
  JPXColorSpec cs;		// color specification
  bool haveCS;			// set if a color spec has been found
  JPXPalette palette;		// the palette
  bool havePalette;		// set if a palette has been found
  JPXCompMap compMap;		// the component mapping
  bool haveCompMap;		// set if a component mapping has been found
  JPXChannelDefn channelDefn;	// channel definition
  bool haveChannelDefn;	// set if a channel defn has been found

  JPXImage img;			// JPEG2000 decoder data
  unsigned int bitBuf;			// buffer for bit reads
  int bitBufLen;		// number of bits in bitBuf
  bool bitBufSkip;		// true if next bit should be skipped
				//   (for bit stuffing)
  unsigned int byteCount;		// number of available bytes left

  unsigned int curX, curY, curComp;	// current position for lookChar/getChar
  unsigned int readBuf;		// read buffer
  unsigned int readBufLen;		// number of valid bits in readBuf
};

#endif