1 // Copyright 2014 The PDFium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef CORE_FXCODEC_PROGRESSIVE_DECODER_H_ 8 #define CORE_FXCODEC_PROGRESSIVE_DECODER_H_ 9 10 #include <stddef.h> 11 #include <stdint.h> 12 13 #include <memory> 14 #include <utility> 15 16 #include "core/fxcodec/fx_codec_def.h" 17 #include "core/fxcodec/jpeg/jpegmodule.h" 18 #include "core/fxcodec/progressive_decoder_iface.h" 19 #include "core/fxcrt/data_vector.h" 20 #include "core/fxcrt/retain_ptr.h" 21 #include "core/fxcrt/span.h" 22 #include "core/fxcrt/unowned_ptr_exclusion.h" 23 #include "core/fxge/dib/cstretchengine.h" 24 #include "core/fxge/dib/fx_dib.h" 25 26 #ifdef PDF_ENABLE_XFA_BMP 27 #include "core/fxcodec/bmp/bmp_decoder.h" 28 #endif // PDF_ENABLE_XFA_BMP 29 30 #ifdef PDF_ENABLE_XFA_GIF 31 #include "core/fxcodec/gif/gif_decoder.h" 32 #endif // PDF_ENABLE_XFA_GIF 33 34 #ifdef PDF_ENABLE_XFA_PNG 35 #include "core/fxcodec/png/png_decoder.h" 36 #endif // PDF_ENABLE_XFA_PNG 37 38 class CFX_DIBitmap; 39 class IFX_SeekableReadStream; 40 41 namespace fxcodec { 42 43 class CFX_DIBAttribute; 44 45 class Dummy {}; // Placeholder to work around C++ syntax issues 46 47 class ProgressiveDecoder final : 48 #ifdef PDF_ENABLE_XFA_BMP 49 public BmpDecoder::Delegate, 50 #endif // PDF_ENABLE_XFA_BMP 51 #ifdef PDF_ENABLE_XFA_GIF 52 public GifDecoder::Delegate, 53 #endif // PDF_ENABLE_XFA_GIF 54 #ifdef PDF_ENABLE_XFA_PNG 55 public PngDecoder::Delegate, 56 #endif // PDF_ENABLE_XFA_PNG 57 public Dummy { 58 public: 59 enum FXCodec_Format { 60 FXCodec_Invalid = 0, 61 FXCodec_8bppGray = 0x108, 62 FXCodec_8bppRgb = 0x008, 63 FXCodec_Rgb = 0x018, 64 FXCodec_Rgb32 = 0x020, 65 FXCodec_Argb = 0x220, 66 FXCodec_Cmyk = 0x120 67 }; 68 69 ProgressiveDecoder(); 70 virtual ~ProgressiveDecoder(); 71 72 FXCODEC_STATUS LoadImageInfo(RetainPtr<IFX_SeekableReadStream> pFile, 73 FXCODEC_IMAGE_TYPE imageType, 74 CFX_DIBAttribute* pAttribute, 75 bool bSkipImageTypeCheck); 76 GetWidth()77 int32_t GetWidth() const { return m_SrcWidth; } GetHeight()78 int32_t GetHeight() const { return m_SrcHeight; } 79 80 FXDIB_Format GetBitmapFormat() const; 81 82 std::pair<FXCODEC_STATUS, size_t> GetFrames(); 83 FXCODEC_STATUS StartDecode(RetainPtr<CFX_DIBitmap> bitmap); 84 85 FXCODEC_STATUS ContinueDecode(); 86 87 #ifdef PDF_ENABLE_XFA_PNG 88 // PngDecoder::Delegate 89 bool PngReadHeader(int width, 90 int height, 91 int bpc, 92 int pass, 93 int* color_type, 94 double* gamma) override; 95 uint8_t* PngAskScanlineBuf(int line) override; 96 void PngFillScanlineBufCompleted(int pass, int line) override; 97 #endif // PDF_ENABLE_XFA_PNG 98 99 #ifdef PDF_ENABLE_XFA_GIF 100 // GifDecoder::Delegate 101 uint32_t GifCurrentPosition() const override; 102 bool GifInputRecordPositionBuf(uint32_t rcd_pos, 103 const FX_RECT& img_rc, 104 pdfium::span<CFX_GifPalette> pal_span, 105 int32_t trans_index, 106 bool interlace) override; 107 void GifReadScanline(int32_t row_num, pdfium::span<uint8_t> row_buf) override; 108 #endif // PDF_ENABLE_XFA_GIF 109 110 #ifdef PDF_ENABLE_XFA_BMP 111 // BmpDecoder::Delegate 112 bool BmpInputImagePositionBuf(uint32_t rcd_pos) override; 113 void BmpReadScanline(uint32_t row_num, 114 pdfium::span<const uint8_t> row_buf) override; 115 #endif // PDF_ENABLE_XFA_BMP 116 117 private: 118 using WeightTable = CStretchEngine::WeightTable; 119 120 enum class TransformMethod : uint8_t { 121 kInvalid, 122 k8BppGrayToRgbMaybeAlpha, 123 k8BppRgbToRgbNoAlpha, 124 k8BppRgbToArgb, 125 kRgbMaybeAlphaToRgbMaybeAlpha, 126 kCmykToRgbMaybeAlpha, 127 kArgbToArgb, 128 }; 129 130 #ifdef PDF_ENABLE_XFA_BMP 131 bool BmpReadMoreData(ProgressiveDecoderIface::Context* pBmpContext, 132 FXCODEC_STATUS* err_status); 133 bool BmpDetectImageTypeInBuffer(CFX_DIBAttribute* pAttribute); 134 FXCODEC_STATUS BmpStartDecode(); 135 FXCODEC_STATUS BmpContinueDecode(); 136 #endif // PDF_ENABLE_XFA_BMP 137 138 #ifdef PDF_ENABLE_XFA_GIF 139 bool GifReadMoreData(FXCODEC_STATUS* err_status); 140 bool GifDetectImageTypeInBuffer(); 141 FXCODEC_STATUS GifStartDecode(); 142 FXCODEC_STATUS GifContinueDecode(); 143 #endif // PDF_ENABLE_XFA_GIF 144 145 #ifdef PDF_ENABLE_XFA_PNG 146 bool PngDetectImageTypeInBuffer(CFX_DIBAttribute* pAttribute); 147 FXCODEC_STATUS PngStartDecode(); 148 FXCODEC_STATUS PngContinueDecode(); 149 #endif // PDF_ENABLE_XFA_PNG 150 151 #ifdef PDF_ENABLE_XFA_TIFF 152 bool TiffDetectImageTypeFromFile(CFX_DIBAttribute* pAttribute); 153 FXCODEC_STATUS TiffContinueDecode(); 154 #endif // PDF_ENABLE_XFA_TIFF 155 156 bool JpegReadMoreData(FXCODEC_STATUS* err_status); 157 bool JpegDetectImageTypeInBuffer(CFX_DIBAttribute* pAttribute); 158 FXCODEC_STATUS JpegStartDecode(); 159 FXCODEC_STATUS JpegContinueDecode(); 160 GetBitsPerPixel()161 int32_t GetBitsPerPixel() const { return m_SrcComponents * m_SrcBPC; } 162 163 bool DetectImageType(FXCODEC_IMAGE_TYPE imageType, 164 CFX_DIBAttribute* pAttribute); 165 bool ReadMoreData(ProgressiveDecoderIface* pModule, 166 ProgressiveDecoderIface::Context* pContext, 167 FXCODEC_STATUS* err_status); 168 169 void SetTransMethod(); 170 171 void ResampleScanline(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 172 int32_t dest_line, 173 pdfium::span<uint8_t> src_span, 174 FXCodec_Format src_format); 175 void Resample(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 176 int32_t src_line, 177 uint8_t* src_scan, 178 FXCodec_Format src_format); 179 180 FXCODEC_STATUS m_status = FXCODEC_STATUS::kDecodeFinished; 181 FXCODEC_IMAGE_TYPE m_imageType = FXCODEC_IMAGE_UNKNOWN; 182 RetainPtr<IFX_SeekableReadStream> m_pFile; 183 RetainPtr<CFX_DIBitmap> m_pDeviceBitmap; 184 RetainPtr<CFX_CodecMemory> m_pCodecMemory; 185 DataVector<uint8_t> m_DecodeBuf; 186 DataVector<FX_ARGB> m_SrcPalette; 187 std::unique_ptr<ProgressiveDecoderIface::Context> m_pJpegContext; 188 #ifdef PDF_ENABLE_XFA_BMP 189 std::unique_ptr<ProgressiveDecoderIface::Context> m_pBmpContext; 190 #endif // PDF_ENABLE_XFA_BMP 191 #ifdef PDF_ENABLE_XFA_GIF 192 std::unique_ptr<ProgressiveDecoderIface::Context> m_pGifContext; 193 #endif // PDF_ENABLE_XFA_GIF 194 #ifdef PDF_ENABLE_XFA_PNG 195 std::unique_ptr<ProgressiveDecoderIface::Context> m_pPngContext; 196 #endif // PDF_ENABLE_XFA_PNG 197 #ifdef PDF_ENABLE_XFA_TIFF 198 std::unique_ptr<ProgressiveDecoderIface::Context> m_pTiffContext; 199 #endif // PDF_ENABLE_XFA_TIFF 200 uint32_t m_offSet = 0; 201 int m_ScanlineSize = 0; 202 WeightTable m_WeightHorz; 203 int m_SrcWidth = 0; 204 int m_SrcHeight = 0; 205 int m_SrcComponents = 0; 206 int m_SrcBPC = 0; 207 TransformMethod m_TransMethod; 208 int m_SrcRow = 0; 209 FXCodec_Format m_SrcFormat = FXCodec_Invalid; 210 int m_SrcPassNumber = 0; 211 size_t m_FrameNumber = 0; 212 size_t m_FrameCur = 0; 213 #ifdef PDF_ENABLE_XFA_GIF 214 int m_GifBgIndex = 0; 215 pdfium::span<CFX_GifPalette> m_GifPalette; 216 int m_GifTransIndex = -1; 217 FX_RECT m_GifFrameRect; 218 #endif // PDF_ENABLE_XFA_GIF 219 #ifdef PDF_ENABLE_XFA_BMP 220 bool m_BmpIsTopBottom = false; 221 #endif // PDF_ENABLE_XFA_BMP 222 }; 223 224 } // namespace fxcodec 225 226 using ProgressiveDecoder = fxcodec::ProgressiveDecoder; 227 228 #endif // CORE_FXCODEC_PROGRESSIVE_DECODER_H_ 229