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/fxge/dib/cstretchengine.h" 22 #include "core/fxge/dib/fx_dib.h" 23 #include "third_party/base/span.h" 24 25 #ifdef PDF_ENABLE_XFA_BMP 26 #include "core/fxcodec/bmp/bmp_decoder.h" 27 #endif // PDF_ENABLE_XFA_BMP 28 29 #ifdef PDF_ENABLE_XFA_GIF 30 #include "core/fxcodec/gif/gif_decoder.h" 31 #endif // PDF_ENABLE_XFA_GIF 32 33 #ifdef PDF_ENABLE_XFA_PNG 34 #include "core/fxcodec/png/png_decoder.h" 35 #endif // PDF_ENABLE_XFA_PNG 36 37 class CFX_DIBitmap; 38 class IFX_SeekableReadStream; 39 40 namespace fxcodec { 41 42 class CFX_DIBAttribute; 43 44 class Dummy {}; // Placeholder to work around C++ syntax issues 45 46 class ProgressiveDecoder final : 47 #ifdef PDF_ENABLE_XFA_BMP 48 public BmpDecoder::Delegate, 49 #endif // PDF_ENABLE_XFA_BMP 50 #ifdef PDF_ENABLE_XFA_GIF 51 public GifDecoder::Delegate, 52 #endif // PDF_ENABLE_XFA_GIF 53 #ifdef PDF_ENABLE_XFA_PNG 54 public PngDecoder::Delegate, 55 #endif // PDF_ENABLE_XFA_PNG 56 public Dummy { 57 public: 58 enum FXCodec_Format { 59 FXCodec_Invalid = 0, 60 FXCodec_1bppGray = 0x101, 61 FXCodec_1bppRgb = 0x001, 62 FXCodec_8bppGray = 0x108, 63 FXCodec_8bppRgb = 0x008, 64 FXCodec_Rgb = 0x018, 65 FXCodec_Rgb32 = 0x020, 66 FXCodec_Argb = 0x220, 67 FXCodec_Cmyk = 0x120 68 }; 69 70 ProgressiveDecoder(); 71 virtual ~ProgressiveDecoder(); 72 73 FXCODEC_STATUS LoadImageInfo(RetainPtr<IFX_SeekableReadStream> pFile, 74 FXCODEC_IMAGE_TYPE imageType, 75 CFX_DIBAttribute* pAttribute, 76 bool bSkipImageTypeCheck); 77 GetType()78 FXCODEC_IMAGE_TYPE GetType() const { return m_imageType; } GetWidth()79 int32_t GetWidth() const { return m_SrcWidth; } GetHeight()80 int32_t GetHeight() const { return m_SrcHeight; } GetNumComponents()81 int32_t GetNumComponents() const { return m_SrcComponents; } GetBPC()82 int32_t GetBPC() const { return m_SrcBPC; } 83 void SetClipBox(FX_RECT* clip); 84 85 std::pair<FXCODEC_STATUS, size_t> GetFrames(); 86 FXCODEC_STATUS StartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap, 87 int start_x, 88 int start_y, 89 int size_x, 90 int size_y); 91 92 FXCODEC_STATUS ContinueDecode(); 93 94 #ifdef PDF_ENABLE_XFA_PNG 95 // PngDecoder::Delegate 96 bool PngReadHeader(int width, 97 int height, 98 int bpc, 99 int pass, 100 int* color_type, 101 double* gamma) override; 102 bool PngAskScanlineBuf(int line, uint8_t** pSrcBuf) override; 103 void PngFillScanlineBufCompleted(int pass, int line) override; 104 #endif // PDF_ENABLE_XFA_PNG 105 106 #ifdef PDF_ENABLE_XFA_GIF 107 // GifDecoder::Delegate 108 uint32_t GifCurrentPosition() const override; 109 bool GifInputRecordPositionBuf(uint32_t rcd_pos, 110 const FX_RECT& img_rc, 111 int32_t pal_num, 112 CFX_GifPalette* pal_ptr, 113 int32_t trans_index, 114 bool interlace) override; 115 void GifReadScanline(int32_t row_num, pdfium::span<uint8_t> row_buf) override; 116 #endif // PDF_ENABLE_XFA_GIF 117 118 #ifdef PDF_ENABLE_XFA_BMP 119 // BmpDecoder::Delegate 120 bool BmpInputImagePositionBuf(uint32_t rcd_pos) override; 121 void BmpReadScanline(uint32_t row_num, 122 pdfium::span<const uint8_t> row_buf) override; 123 #endif // PDF_ENABLE_XFA_BMP 124 125 private: 126 using WeightTable = CStretchEngine::WeightTable; 127 using PixelWeight = CStretchEngine::PixelWeight; 128 129 class HorzTable { 130 public: 131 HorzTable(); 132 ~HorzTable(); 133 134 void CalculateWeights(int dest_len, int src_len); GetPixelWeight(int pixel)135 PixelWeight* GetPixelWeight(int pixel) { 136 return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() + 137 pixel * m_ItemSize); 138 } 139 140 private: 141 int m_ItemSize = 0; 142 DataVector<uint8_t> m_pWeightTables; 143 }; 144 145 class VertTable { 146 public: 147 VertTable(); 148 ~VertTable(); 149 150 void CalculateWeights(int dest_len, int src_len); GetPixelWeight(int pixel)151 PixelWeight* GetPixelWeight(int pixel) { 152 return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() + 153 pixel * m_ItemSize); 154 } 155 156 private: 157 int m_ItemSize = 0; 158 DataVector<uint8_t> m_pWeightTables; 159 }; 160 161 #ifdef PDF_ENABLE_XFA_BMP 162 bool BmpReadMoreData(ProgressiveDecoderIface::Context* pBmpContext, 163 FXCODEC_STATUS* err_status); 164 bool BmpDetectImageTypeInBuffer(CFX_DIBAttribute* pAttribute); 165 FXCODEC_STATUS BmpStartDecode(); 166 FXCODEC_STATUS BmpContinueDecode(); 167 #endif // PDF_ENABLE_XFA_BMP 168 169 #ifdef PDF_ENABLE_XFA_GIF 170 bool GifReadMoreData(FXCODEC_STATUS* err_status); 171 bool GifDetectImageTypeInBuffer(); 172 FXCODEC_STATUS GifStartDecode(); 173 FXCODEC_STATUS GifContinueDecode(); 174 void GifDoubleLineResampleVert(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 175 double scale_y, 176 int dest_row); 177 #endif // PDF_ENABLE_XFA_GIF 178 179 #ifdef PDF_ENABLE_XFA_PNG 180 void PngOneOneMapResampleHorz(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 181 int32_t dest_line, 182 pdfium::span<uint8_t> src_span, 183 FXCodec_Format src_format); 184 bool PngDetectImageTypeInBuffer(CFX_DIBAttribute* pAttribute); 185 FXCODEC_STATUS PngStartDecode(); 186 FXCODEC_STATUS PngContinueDecode(); 187 #endif // PDF_ENABLE_XFA_PNG 188 189 #ifdef PDF_ENABLE_XFA_TIFF 190 bool TiffDetectImageTypeFromFile(CFX_DIBAttribute* pAttribute); 191 FXCODEC_STATUS TiffContinueDecode(); 192 #endif // PDF_ENABLE_XFA_TIFF 193 194 bool JpegReadMoreData(FXCODEC_STATUS* err_status); 195 bool JpegDetectImageTypeInBuffer(CFX_DIBAttribute* pAttribute); 196 FXCODEC_STATUS JpegStartDecode(FXDIB_Format format); 197 FXCODEC_STATUS JpegContinueDecode(); 198 199 bool DetectImageType(FXCODEC_IMAGE_TYPE imageType, 200 CFX_DIBAttribute* pAttribute); 201 bool ReadMoreData(ProgressiveDecoderIface* pModule, 202 ProgressiveDecoderIface::Context* pContext, 203 FXCODEC_STATUS* err_status); 204 205 int GetDownScale(); 206 void GetTransMethod(FXDIB_Format dest_format, FXCodec_Format src_format); 207 208 void ResampleScanline(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 209 int32_t dest_line, 210 pdfium::span<uint8_t> src_span, 211 FXCodec_Format src_format); 212 void Resample(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 213 int32_t src_line, 214 uint8_t* src_scan, 215 FXCodec_Format src_format); 216 void ResampleVert(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 217 double scale_y, 218 int dest_row); 219 void ResampleVertBT(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 220 double scale_y, 221 int dest_row); 222 223 FXCODEC_STATUS m_status = FXCODEC_STATUS::kDecodeFinished; 224 FXCODEC_IMAGE_TYPE m_imageType = FXCODEC_IMAGE_UNKNOWN; 225 RetainPtr<IFX_SeekableReadStream> m_pFile; 226 RetainPtr<CFX_DIBitmap> m_pDeviceBitmap; 227 RetainPtr<CFX_CodecMemory> m_pCodecMemory; 228 DataVector<uint8_t> m_DecodeBuf; 229 DataVector<FX_ARGB> m_SrcPalette; 230 std::unique_ptr<ProgressiveDecoderIface::Context> m_pJpegContext; 231 #ifdef PDF_ENABLE_XFA_BMP 232 std::unique_ptr<ProgressiveDecoderIface::Context> m_pBmpContext; 233 #endif // PDF_ENABLE_XFA_BMP 234 #ifdef PDF_ENABLE_XFA_GIF 235 std::unique_ptr<ProgressiveDecoderIface::Context> m_pGifContext; 236 #endif // PDF_ENABLE_XFA_GIF 237 #ifdef PDF_ENABLE_XFA_PNG 238 std::unique_ptr<ProgressiveDecoderIface::Context> m_pPngContext; 239 #endif // PDF_ENABLE_XFA_PNG 240 #ifdef PDF_ENABLE_XFA_TIFF 241 std::unique_ptr<ProgressiveDecoderIface::Context> m_pTiffContext; 242 #endif // PDF_ENABLE_XFA_TIFF 243 uint32_t m_offSet = 0; 244 int m_ScanlineSize = 0; 245 WeightTable m_WeightHorz; 246 VertTable m_WeightVert; 247 HorzTable m_WeightHorzOO; 248 int m_SrcWidth = 0; 249 int m_SrcHeight = 0; 250 int m_SrcComponents = 0; 251 int m_SrcBPC = 0; 252 FX_RECT m_clipBox; 253 int m_startX = 0; 254 int m_startY = 0; 255 int m_sizeX = 0; 256 int m_sizeY = 0; 257 int m_TransMethod = -1; 258 int m_SrcPaletteNumber = 0; 259 int m_SrcRow = 0; 260 FXCodec_Format m_SrcFormat = FXCodec_Invalid; 261 int m_SrcPassNumber = 0; 262 size_t m_FrameNumber = 0; 263 size_t m_FrameCur = 0; 264 #ifdef PDF_ENABLE_XFA_GIF 265 int m_GifBgIndex = 0; 266 CFX_GifPalette* m_pGifPalette = nullptr; 267 int32_t m_GifPltNumber = 0; 268 int m_GifTransIndex = -1; 269 FX_RECT m_GifFrameRect; 270 #endif // PDF_ENABLE_XFA_GIF 271 #ifdef PDF_ENABLE_XFA_BMP 272 bool m_BmpIsTopBottom = false; 273 #endif // PDF_ENABLE_XFA_BMP 274 }; 275 276 } // namespace fxcodec 277 278 using ProgressiveDecoder = fxcodec::ProgressiveDecoder; 279 280 #endif // CORE_FXCODEC_PROGRESSIVE_DECODER_H_ 281