blob: ed2d942e08a592f61d27e0aaaae69bcc76fc43cf [file] [log] [blame] [edit]
//========================================================================
//
// 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