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