blob: c7bd9fc6fe165efabbcdce415a6ee04d17a0d9d1 [file] [log] [blame]
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#ifndef CORE_FXCODEC_CODEC_CODEC_INT_H_
#define CORE_FXCODEC_CODEC_CODEC_INT_H_
#include <limits.h>
#include <list>
#include <map>
#include <memory>
#include <vector>
#include "core/fxcodec/jbig2/JBig2_Context.h"
#include "core/include/fxcodec/fx_codec.h"
#include "third_party/libopenjpeg20/openjpeg.h" // For OPJ_SIZE_T.
class CFX_IccProfileCache;
class CFX_IccTransformCache;
class CPDF_ColorSpace;
class CCodec_BasicModule : public ICodec_BasicModule {
public:
// ICodec_BasicModule:
FX_BOOL RunLengthEncode(const uint8_t* src_buf,
uint32_t src_size,
uint8_t*& dest_buf,
uint32_t& dest_size) override;
FX_BOOL A85Encode(const uint8_t* src_buf,
uint32_t src_size,
uint8_t*& dest_buf,
uint32_t& dest_size) override;
ICodec_ScanlineDecoder* CreateRunLengthDecoder(const uint8_t* src_buf,
uint32_t src_size,
int width,
int height,
int nComps,
int bpc) override;
};
class CCodec_ScanlineDecoder : public ICodec_ScanlineDecoder {
public:
CCodec_ScanlineDecoder();
~CCodec_ScanlineDecoder() override;
// ICodec_ScanlineDecoder
void DownScale(int dest_width, int dest_height) override;
const uint8_t* GetScanline(int line) override;
FX_BOOL SkipToScanline(int line, IFX_Pause* pPause) override;
int GetWidth() override { return m_OutputWidth; }
int GetHeight() override { return m_OutputHeight; }
int CountComps() override { return m_nComps; }
int GetBPC() override { return m_bpc; }
FX_BOOL IsColorTransformed() override { return m_bColorTransformed; }
void ClearImageData() override { m_pDataCache.reset(); }
protected:
class ImageDataCache {
public:
ImageDataCache(int width, int height, uint32_t pitch);
~ImageDataCache();
bool AllocateCache();
void AppendLine(const uint8_t* line);
int NumLines() const { return m_nCachedLines; }
const uint8_t* GetLine(int line) const;
bool IsSameDimensions(int width, int height) const {
return width == m_Width && height == m_Height;
}
private:
bool IsValid() const { return m_Data.get() != nullptr; }
const int m_Width;
const int m_Height;
const uint32_t m_Pitch;
int m_nCachedLines;
std::unique_ptr<uint8_t, FxFreeDeleter> m_Data;
};
virtual FX_BOOL v_Rewind() = 0;
virtual uint8_t* v_GetNextLine() = 0;
virtual void v_DownScale(int dest_width, int dest_height) = 0;
uint8_t* ReadNextLine();
int m_OrigWidth;
int m_OrigHeight;
int m_DownScale;
int m_OutputWidth;
int m_OutputHeight;
int m_nComps;
int m_bpc;
uint32_t m_Pitch;
FX_BOOL m_bColorTransformed;
int m_NextLine;
uint8_t* m_pLastScanline;
std::unique_ptr<ImageDataCache> m_pDataCache;
};
class CCodec_FaxModule : public ICodec_FaxModule {
public:
// ICodec_FaxModule:
ICodec_ScanlineDecoder* CreateDecoder(const uint8_t* src_buf,
uint32_t src_size,
int width,
int height,
int K,
FX_BOOL EndOfLine,
FX_BOOL EncodedByteAlign,
FX_BOOL BlackIs1,
int Columns,
int Rows) override;
FX_BOOL Encode(const uint8_t* src_buf,
int width,
int height,
int pitch,
uint8_t*& dest_buf,
uint32_t& dest_size) override;
};
class CCodec_FlateModule : public ICodec_FlateModule {
public:
virtual ICodec_ScanlineDecoder* CreateDecoder(const uint8_t* src_buf,
uint32_t src_size,
int width,
int height,
int nComps,
int bpc,
int predictor,
int Colors,
int BitsPerComponent,
int Columns);
virtual uint32_t FlateOrLZWDecode(FX_BOOL bLZW,
const uint8_t* src_buf,
uint32_t src_size,
FX_BOOL bEarlyChange,
int predictor,
int Colors,
int BitsPerComponent,
int Columns,
uint32_t estimated_size,
uint8_t*& dest_buf,
uint32_t& dest_size);
virtual FX_BOOL Encode(const uint8_t* src_buf,
uint32_t src_size,
int predictor,
int Colors,
int BitsPerComponent,
int Columns,
uint8_t*& dest_buf,
uint32_t& dest_size);
virtual FX_BOOL Encode(const uint8_t* src_buf,
uint32_t src_size,
uint8_t*& dest_buf,
uint32_t& dest_size);
};
class CCodec_JpegModule : public ICodec_JpegModule {
public:
CCodec_JpegModule() {}
ICodec_ScanlineDecoder* CreateDecoder(const uint8_t* src_buf,
uint32_t src_size,
int width,
int height,
int nComps,
FX_BOOL ColorTransform) override;
FX_BOOL LoadInfo(const uint8_t* src_buf,
uint32_t src_size,
int& width,
int& height,
int& num_components,
int& bits_per_components,
FX_BOOL& color_transform,
uint8_t** icc_buf_ptr,
uint32_t* icc_length) override;
FX_BOOL Encode(const CFX_DIBSource* pSource,
uint8_t*& dest_buf,
FX_STRSIZE& dest_size,
int quality,
const uint8_t* icc_buf,
uint32_t icc_length) override;
void* Start() override;
void Finish(void* pContext) override;
void Input(void* pContext,
const uint8_t* src_buf,
uint32_t src_size) override;
#ifndef PDF_ENABLE_XFA
int ReadHeader(void* pContext, int* width, int* height, int* nComps) override;
#else // PDF_ENABLE_XFA
int ReadHeader(void* pContext,
int* width,
int* height,
int* nComps,
CFX_DIBAttribute* pAttribute) override;
#endif // PDF_ENABLE_XFA
int StartScanline(void* pContext, int down_scale) override;
FX_BOOL ReadScanline(void* pContext, uint8_t* dest_buf) override;
uint32_t GetAvailInput(void* pContext, uint8_t** avail_buf_ptr) override;
};
#ifdef PDF_ENABLE_XFA
#define PNG_ERROR_SIZE 256
class CCodec_PngModule : public ICodec_PngModule {
public:
CCodec_PngModule() { FXSYS_memset(m_szLastError, '\0', PNG_ERROR_SIZE); }
virtual void* Start(void* pModule);
virtual void Finish(void* pContext);
virtual FX_BOOL Input(void* pContext,
const uint8_t* src_buf,
uint32_t src_size,
CFX_DIBAttribute* pAttribute);
protected:
FX_CHAR m_szLastError[PNG_ERROR_SIZE];
};
class CCodec_GifModule : public ICodec_GifModule {
public:
CCodec_GifModule() { FXSYS_memset(m_szLastError, '\0', 256); }
virtual void* Start(void* pModule);
virtual void Finish(void* pContext);
virtual uint32_t GetAvailInput(void* pContext, uint8_t** avail_buf_ptr);
virtual void Input(void* pContext, const uint8_t* src_buf, uint32_t src_size);
virtual int32_t ReadHeader(void* pContext,
int* width,
int* height,
int* pal_num,
void** pal_pp,
int* bg_index,
CFX_DIBAttribute* pAttribute);
virtual int32_t LoadFrameInfo(void* pContext, int* frame_num);
virtual int32_t LoadFrame(void* pContext,
int frame_num,
CFX_DIBAttribute* pAttribute);
protected:
FX_CHAR m_szLastError[256];
};
class CCodec_BmpModule : public ICodec_BmpModule {
public:
CCodec_BmpModule() { FXSYS_memset(m_szLastError, 0, sizeof(m_szLastError)); }
void* Start(void* pModule) override;
void Finish(void* pContext) override;
uint32_t GetAvailInput(void* pContext, uint8_t** avail_buf_ptr) override;
void Input(void* pContext,
const uint8_t* src_buf,
uint32_t src_size) override;
int32_t ReadHeader(void* pContext,
int32_t* width,
int32_t* height,
FX_BOOL* tb_flag,
int32_t* components,
int32_t* pal_num,
uint32_t** pal_pp,
CFX_DIBAttribute* pAttribute) override;
int32_t LoadImage(void* pContext) override;
protected:
FX_CHAR m_szLastError[256];
};
#endif // PDF_ENABLE_XFA
class CCodec_IccModule : public ICodec_IccModule {
public:
~CCodec_IccModule() override;
// ICodec_IccModule:
IccCS GetProfileCS(const uint8_t* pProfileData,
unsigned int dwProfileSize) override;
IccCS GetProfileCS(IFX_FileRead* pFile) override;
void* CreateTransform(ICodec_IccModule::IccParam* pInputParam,
ICodec_IccModule::IccParam* pOutputParam,
ICodec_IccModule::IccParam* pProofParam = NULL,
uint32_t dwIntent = Icc_INTENT_PERCEPTUAL,
uint32_t dwFlag = Icc_FLAGS_DEFAULT,
uint32_t dwPrfIntent = Icc_INTENT_ABSOLUTE_COLORIMETRIC,
uint32_t dwPrfFlag = Icc_FLAGS_SOFTPROOFING) override;
void* CreateTransform_sRGB(
const uint8_t* pProfileData,
uint32_t dwProfileSize,
uint32_t& nComponents,
int32_t intent = 0,
uint32_t dwSrcFormat = Icc_FORMAT_DEFAULT) override;
void* CreateTransform_CMYK(
const uint8_t* pSrcProfileData,
uint32_t dwSrcProfileSize,
uint32_t& nSrcComponents,
const uint8_t* pDstProfileData,
uint32_t dwDstProfileSize,
int32_t intent = 0,
uint32_t dwSrcFormat = Icc_FORMAT_DEFAULT,
uint32_t dwDstFormat = Icc_FORMAT_DEFAULT) override;
void DestroyTransform(void* pTransform) override;
void Translate(void* pTransform,
FX_FLOAT* pSrcValues,
FX_FLOAT* pDestValues) override;
void TranslateScanline(void* pTransform,
uint8_t* pDest,
const uint8_t* pSrc,
int pixels) override;
void SetComponents(uint32_t nComponents) override {
m_nComponents = nComponents;
}
protected:
enum Icc_CLASS {
Icc_CLASS_INPUT = 0,
Icc_CLASS_OUTPUT,
Icc_CLASS_PROOF,
Icc_CLASS_MAX
};
void* CreateProfile(ICodec_IccModule::IccParam* pIccParam,
Icc_CLASS ic,
CFX_BinaryBuf* pTransformKey);
uint32_t m_nComponents;
std::map<CFX_ByteString, CFX_IccTransformCache*> m_MapTranform;
std::map<CFX_ByteString, CFX_IccProfileCache*> m_MapProfile;
};
class CCodec_JpxModule : public ICodec_JpxModule {
public:
CCodec_JpxModule();
~CCodec_JpxModule() override;
// ICodec_JpxModule:
CJPX_Decoder* CreateDecoder(const uint8_t* src_buf,
uint32_t src_size,
CPDF_ColorSpace* cs) override;
void GetImageInfo(CJPX_Decoder* pDecoder,
uint32_t* width,
uint32_t* height,
uint32_t* components) override;
bool Decode(CJPX_Decoder* pDecoder,
uint8_t* dest_data,
int pitch,
const std::vector<uint8_t>& offsets) override;
void DestroyDecoder(CJPX_Decoder* pDecoder) override;
};
#ifdef PDF_ENABLE_XFA
class CCodec_TiffModule : public ICodec_TiffModule {
public:
// ICodec_TiffModule
void* CreateDecoder(IFX_FileRead* file_ptr) override;
void GetFrames(void* ctx, int32_t& frames) override;
FX_BOOL LoadFrameInfo(void* ctx,
int32_t frame,
uint32_t& width,
uint32_t& height,
uint32_t& comps,
uint32_t& bpc,
CFX_DIBAttribute* pAttribute) override;
FX_BOOL Decode(void* ctx, class CFX_DIBitmap* pDIBitmap) override;
void DestroyDecoder(void* ctx) override;
protected:
~CCodec_TiffModule() override {}
};
#endif // PDF_ENABLE_XFA
class CCodec_Jbig2Context {
public:
CCodec_Jbig2Context();
~CCodec_Jbig2Context() {}
uint32_t m_width;
uint32_t m_height;
CPDF_StreamAcc* m_pGlobalStream;
CPDF_StreamAcc* m_pSrcStream;
uint8_t* m_dest_buf;
uint32_t m_dest_pitch;
IFX_Pause* m_pPause;
CJBig2_Context* m_pContext;
CJBig2_Image* m_dest_image;
};
class CCodec_Jbig2Module : public ICodec_Jbig2Module {
public:
CCodec_Jbig2Module() {}
~CCodec_Jbig2Module() override;
// ICodec_Jbig2Module
void* CreateJbig2Context() override;
FXCODEC_STATUS StartDecode(void* pJbig2Context,
CFX_PrivateData* pPrivateData,
uint32_t width,
uint32_t height,
CPDF_StreamAcc* src_stream,
CPDF_StreamAcc* global_stream,
uint8_t* dest_buf,
uint32_t dest_pitch,
IFX_Pause* pPause) override;
FXCODEC_STATUS ContinueDecode(void* pJbig2Context,
IFX_Pause* pPause) override;
void DestroyJbig2Context(void* pJbig2Context) override;
};
struct DecodeData {
public:
DecodeData(unsigned char* src_data, OPJ_SIZE_T src_size)
: src_data(src_data), src_size(src_size), offset(0) {}
unsigned char* src_data;
OPJ_SIZE_T src_size;
OPJ_SIZE_T offset;
};
void sycc420_to_rgb(opj_image_t* img);
/* Wrappers for C-style callbacks. */
OPJ_SIZE_T opj_read_from_memory(void* p_buffer,
OPJ_SIZE_T nb_bytes,
void* p_user_data);
OPJ_SIZE_T opj_write_from_memory(void* p_buffer,
OPJ_SIZE_T nb_bytes,
void* p_user_data);
OPJ_OFF_T opj_skip_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data);
OPJ_BOOL opj_seek_from_memory(OPJ_OFF_T nb_bytes, void* p_user_data);
#endif // CORE_FXCODEC_CODEC_CODEC_INT_H_