text: //========================================================================
  //
  // 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>
  //
  // 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) 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
  