| //======================================================================== |
| // |
| // 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, 2021 Albert Astals Cid <aacid@kde.org> |
| // Copyright (C) 2024 Nelson Benítez León <nbenitezl@gmail.com> |
| // |
| // 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) const override; |
| void getImageParams(int *bitsPerComponent, StreamColorSpaceMode *csMode, bool *hasAlpha) 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 |