//======================================================================== // // 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 // // 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