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