// Copyright 2014 The PDFium Authors // 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_PROGRESSIVE_DECODER_H_ #define CORE_FXCODEC_PROGRESSIVE_DECODER_H_ #include #include #include #include #include "core/fxcodec/fx_codec_def.h" #include "core/fxcodec/jpeg/jpegmodule.h" #include "core/fxcodec/progressive_decoder_iface.h" #include "core/fxcrt/data_vector.h" #include "core/fxcrt/retain_ptr.h" #include "core/fxge/dib/cstretchengine.h" #include "core/fxge/dib/fx_dib.h" #include "third_party/base/span.h" #ifdef PDF_ENABLE_XFA_BMP #include "core/fxcodec/bmp/bmp_decoder.h" #endif // PDF_ENABLE_XFA_BMP #ifdef PDF_ENABLE_XFA_GIF #include "core/fxcodec/gif/gif_decoder.h" #endif // PDF_ENABLE_XFA_GIF #ifdef PDF_ENABLE_XFA_PNG #include "core/fxcodec/png/png_decoder.h" #endif // PDF_ENABLE_XFA_PNG class CFX_DIBitmap; class IFX_SeekableReadStream; namespace fxcodec { class CFX_DIBAttribute; class Dummy {}; // Placeholder to work around C++ syntax issues class ProgressiveDecoder final : #ifdef PDF_ENABLE_XFA_BMP public BmpDecoder::Delegate, #endif // PDF_ENABLE_XFA_BMP #ifdef PDF_ENABLE_XFA_GIF public GifDecoder::Delegate, #endif // PDF_ENABLE_XFA_GIF #ifdef PDF_ENABLE_XFA_PNG public PngDecoder::Delegate, #endif // PDF_ENABLE_XFA_PNG public Dummy { public: enum FXCodec_Format { FXCodec_Invalid = 0, FXCodec_1bppGray = 0x101, FXCodec_1bppRgb = 0x001, FXCodec_8bppGray = 0x108, FXCodec_8bppRgb = 0x008, FXCodec_Rgb = 0x018, FXCodec_Rgb32 = 0x020, FXCodec_Argb = 0x220, FXCodec_Cmyk = 0x120 }; ProgressiveDecoder(); virtual ~ProgressiveDecoder(); FXCODEC_STATUS LoadImageInfo(RetainPtr pFile, FXCODEC_IMAGE_TYPE imageType, CFX_DIBAttribute* pAttribute, bool bSkipImageTypeCheck); FXCODEC_IMAGE_TYPE GetType() const { return m_imageType; } int32_t GetWidth() const { return m_SrcWidth; } int32_t GetHeight() const { return m_SrcHeight; } int32_t GetNumComponents() const { return m_SrcComponents; } int32_t GetBPC() const { return m_SrcBPC; } void SetClipBox(FX_RECT* clip); std::pair GetFrames(); FXCODEC_STATUS StartDecode(const RetainPtr& pDIBitmap, int start_x, int start_y, int size_x, int size_y); FXCODEC_STATUS ContinueDecode(); #ifdef PDF_ENABLE_XFA_PNG // PngDecoder::Delegate bool PngReadHeader(int width, int height, int bpc, int pass, int* color_type, double* gamma) override; bool PngAskScanlineBuf(int line, uint8_t** pSrcBuf) override; void PngFillScanlineBufCompleted(int pass, int line) override; #endif // PDF_ENABLE_XFA_PNG #ifdef PDF_ENABLE_XFA_GIF // GifDecoder::Delegate uint32_t GifCurrentPosition() const override; bool GifInputRecordPositionBuf(uint32_t rcd_pos, const FX_RECT& img_rc, int32_t pal_num, CFX_GifPalette* pal_ptr, int32_t trans_index, bool interlace) override; void GifReadScanline(int32_t row_num, pdfium::span row_buf) override; #endif // PDF_ENABLE_XFA_GIF #ifdef PDF_ENABLE_XFA_BMP // BmpDecoder::Delegate bool BmpInputImagePositionBuf(uint32_t rcd_pos) override; void BmpReadScanline(uint32_t row_num, pdfium::span row_buf) override; #endif // PDF_ENABLE_XFA_BMP private: using WeightTable = CStretchEngine::WeightTable; using PixelWeight = CStretchEngine::PixelWeight; class HorzTable { public: HorzTable(); ~HorzTable(); void CalculateWeights(int dest_len, int src_len); PixelWeight* GetPixelWeight(int pixel) { return reinterpret_cast(m_pWeightTables.data() + pixel * m_ItemSize); } private: int m_ItemSize = 0; DataVector m_pWeightTables; }; class VertTable { public: VertTable(); ~VertTable(); void CalculateWeights(int dest_len, int src_len); PixelWeight* GetPixelWeight(int pixel) { return reinterpret_cast(m_pWeightTables.data() + pixel * m_ItemSize); } private: int m_ItemSize = 0; DataVector m_pWeightTables; }; #ifdef PDF_ENABLE_XFA_BMP bool BmpReadMoreData(ProgressiveDecoderIface::Context* pBmpContext, FXCODEC_STATUS* err_status); bool BmpDetectImageTypeInBuffer(CFX_DIBAttribute* pAttribute); FXCODEC_STATUS BmpStartDecode(); FXCODEC_STATUS BmpContinueDecode(); #endif // PDF_ENABLE_XFA_BMP #ifdef PDF_ENABLE_XFA_GIF bool GifReadMoreData(FXCODEC_STATUS* err_status); bool GifDetectImageTypeInBuffer(); FXCODEC_STATUS GifStartDecode(); FXCODEC_STATUS GifContinueDecode(); void GifDoubleLineResampleVert(const RetainPtr& pDeviceBitmap, double scale_y, int dest_row); #endif // PDF_ENABLE_XFA_GIF #ifdef PDF_ENABLE_XFA_PNG void PngOneOneMapResampleHorz(const RetainPtr& pDeviceBitmap, int32_t dest_line, pdfium::span src_span, FXCodec_Format src_format); bool PngDetectImageTypeInBuffer(CFX_DIBAttribute* pAttribute); FXCODEC_STATUS PngStartDecode(); FXCODEC_STATUS PngContinueDecode(); #endif // PDF_ENABLE_XFA_PNG #ifdef PDF_ENABLE_XFA_TIFF bool TiffDetectImageTypeFromFile(CFX_DIBAttribute* pAttribute); FXCODEC_STATUS TiffContinueDecode(); #endif // PDF_ENABLE_XFA_TIFF bool JpegReadMoreData(FXCODEC_STATUS* err_status); bool JpegDetectImageTypeInBuffer(CFX_DIBAttribute* pAttribute); FXCODEC_STATUS JpegStartDecode(FXDIB_Format format); FXCODEC_STATUS JpegContinueDecode(); bool DetectImageType(FXCODEC_IMAGE_TYPE imageType, CFX_DIBAttribute* pAttribute); bool ReadMoreData(ProgressiveDecoderIface* pModule, ProgressiveDecoderIface::Context* pContext, FXCODEC_STATUS* err_status); int GetDownScale(); void GetTransMethod(FXDIB_Format dest_format, FXCodec_Format src_format); void ResampleScanline(const RetainPtr& pDeviceBitmap, int32_t dest_line, pdfium::span src_span, FXCodec_Format src_format); void Resample(const RetainPtr& pDeviceBitmap, int32_t src_line, uint8_t* src_scan, FXCodec_Format src_format); void ResampleVert(const RetainPtr& pDeviceBitmap, double scale_y, int dest_row); void ResampleVertBT(const RetainPtr& pDeviceBitmap, double scale_y, int dest_row); FXCODEC_STATUS m_status = FXCODEC_STATUS::kDecodeFinished; FXCODEC_IMAGE_TYPE m_imageType = FXCODEC_IMAGE_UNKNOWN; RetainPtr m_pFile; RetainPtr m_pDeviceBitmap; RetainPtr m_pCodecMemory; DataVector m_DecodeBuf; DataVector m_SrcPalette; std::unique_ptr m_pJpegContext; #ifdef PDF_ENABLE_XFA_BMP std::unique_ptr m_pBmpContext; #endif // PDF_ENABLE_XFA_BMP #ifdef PDF_ENABLE_XFA_GIF std::unique_ptr m_pGifContext; #endif // PDF_ENABLE_XFA_GIF #ifdef PDF_ENABLE_XFA_PNG std::unique_ptr m_pPngContext; #endif // PDF_ENABLE_XFA_PNG #ifdef PDF_ENABLE_XFA_TIFF std::unique_ptr m_pTiffContext; #endif // PDF_ENABLE_XFA_TIFF uint32_t m_offSet = 0; int m_ScanlineSize = 0; WeightTable m_WeightHorz; VertTable m_WeightVert; HorzTable m_WeightHorzOO; int m_SrcWidth = 0; int m_SrcHeight = 0; int m_SrcComponents = 0; int m_SrcBPC = 0; FX_RECT m_clipBox; int m_startX = 0; int m_startY = 0; int m_sizeX = 0; int m_sizeY = 0; int m_TransMethod = -1; int m_SrcPaletteNumber = 0; int m_SrcRow = 0; FXCodec_Format m_SrcFormat = FXCodec_Invalid; int m_SrcPassNumber = 0; size_t m_FrameNumber = 0; size_t m_FrameCur = 0; #ifdef PDF_ENABLE_XFA_GIF int m_GifBgIndex = 0; CFX_GifPalette* m_pGifPalette = nullptr; int32_t m_GifPltNumber = 0; int m_GifTransIndex = -1; FX_RECT m_GifFrameRect; #endif // PDF_ENABLE_XFA_GIF #ifdef PDF_ENABLE_XFA_BMP bool m_BmpIsTopBottom = false; #endif // PDF_ENABLE_XFA_BMP }; } // namespace fxcodec using ProgressiveDecoder = fxcodec::ProgressiveDecoder; #endif // CORE_FXCODEC_PROGRESSIVE_DECODER_H_