1 // Copyright 2014 PDFium Authors. All rights reserved. 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_PROGRESSIVEDECODER_H_ 8 #define CORE_FXCODEC_PROGRESSIVEDECODER_H_ 9 10 #include <memory> 11 #include <utility> 12 #include <vector> 13 14 #include "core/fxcodec/fx_codec_def.h" 15 #include "core/fxcodec/jpeg/jpegmodule.h" 16 #include "core/fxcrt/fx_memory_wrappers.h" 17 #include "core/fxcrt/fx_system.h" 18 #include "core/fxcrt/retain_ptr.h" 19 #include "core/fxcrt/unowned_ptr.h" 20 #include "core/fxge/fx_dib.h" 21 22 #ifdef PDF_ENABLE_XFA_BMP 23 #include "core/fxcodec/bmp/bmpmodule.h" 24 #endif // PDF_ENABLE_XFA_BMP 25 26 #ifdef PDF_ENABLE_XFA_GIF 27 #include "core/fxcodec/gif/gifmodule.h" 28 #endif // PDF_ENABLE_XFA_GIF 29 30 #ifdef PDF_ENABLE_XFA_PNG 31 #include "core/fxcodec/png/pngmodule.h" 32 #endif // PDF_ENABLE_XFA_PNG 33 34 #ifdef PDF_ENABLE_XFA_TIFF 35 #include "core/fxcodec/tiff/tiffmodule.h" 36 #endif // PDF_ENABLE_XFA_TIFF 37 38 class CFX_DIBitmap; 39 class IFX_SeekableReadStream; 40 41 namespace fxcodec { 42 43 class CFX_DIBAttribute; 44 class ModuleMgr; 45 46 class Dummy {}; // Placeholder to work around C++ syntax issues 47 48 class ProgressiveDecoder : 49 #ifdef PDF_ENABLE_XFA_BMP 50 public BmpModule::Delegate, 51 #endif // PDF_ENABLE_XFA_BMP 52 #ifdef PDF_ENABLE_XFA_GIF 53 public GifModule::Delegate, 54 #endif // PDF_ENABLE_XFA_GIF 55 #ifdef PDF_ENABLE_XFA_PNG 56 public PngModule::Delegate, 57 #endif // PDF_ENABLE_XFA_PNG 58 public Dummy { 59 public: 60 enum FXCodec_Format { 61 FXCodec_Invalid = 0, 62 FXCodec_1bppGray = 0x101, 63 FXCodec_1bppRgb = 0x001, 64 FXCodec_8bppGray = 0x108, 65 FXCodec_8bppRgb = 0x008, 66 FXCodec_Rgb = 0x018, 67 FXCodec_Rgb32 = 0x020, 68 FXCodec_Argb = 0x220, 69 FXCodec_Cmyk = 0x120 70 }; 71 72 explicit ProgressiveDecoder(ModuleMgr* pCodecMgr); 73 virtual ~ProgressiveDecoder(); 74 75 FXCODEC_STATUS LoadImageInfo(const RetainPtr<IFX_SeekableReadStream>& pFile, 76 FXCODEC_IMAGE_TYPE imageType, 77 CFX_DIBAttribute* pAttribute, 78 bool bSkipImageTypeCheck); 79 GetType()80 FXCODEC_IMAGE_TYPE GetType() const { return m_imageType; } GetWidth()81 int32_t GetWidth() const { return m_SrcWidth; } GetHeight()82 int32_t GetHeight() const { return m_SrcHeight; } GetNumComponents()83 int32_t GetNumComponents() const { return m_SrcComponents; } GetBPC()84 int32_t GetBPC() const { return m_SrcBPC; } 85 void SetClipBox(FX_RECT* clip); 86 87 std::pair<FXCODEC_STATUS, size_t> GetFrames(); 88 FXCODEC_STATUS StartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap, 89 int start_x, 90 int start_y, 91 int size_x, 92 int size_y); 93 94 FXCODEC_STATUS ContinueDecode(); 95 96 struct PixelWeight { 97 int m_SrcStart; 98 int m_SrcEnd; 99 int m_Weights[1]; 100 }; 101 102 class CFXCODEC_WeightTable { 103 public: 104 CFXCODEC_WeightTable(); 105 ~CFXCODEC_WeightTable(); 106 107 void Calc(int dest_len, int src_len); GetPixelWeight(int pixel)108 PixelWeight* GetPixelWeight(int pixel) { 109 return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() + 110 (pixel - m_DestMin) * m_ItemSize); 111 } 112 113 int m_DestMin; 114 int m_ItemSize; 115 std::vector<uint8_t> m_pWeightTables; 116 }; 117 118 class CFXCODEC_HorzTable { 119 public: 120 CFXCODEC_HorzTable(); 121 ~CFXCODEC_HorzTable(); 122 123 void Calc(int dest_len, int src_len); GetPixelWeight(int pixel)124 PixelWeight* GetPixelWeight(int pixel) { 125 return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() + 126 pixel * m_ItemSize); 127 } 128 129 int m_ItemSize; 130 std::vector<uint8_t> m_pWeightTables; 131 }; 132 133 class CFXCODEC_VertTable { 134 public: 135 CFXCODEC_VertTable(); 136 ~CFXCODEC_VertTable(); 137 138 void Calc(int dest_len, int src_len); GetPixelWeight(int pixel)139 PixelWeight* GetPixelWeight(int pixel) { 140 return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() + 141 pixel * m_ItemSize); 142 } 143 int m_ItemSize; 144 std::vector<uint8_t> m_pWeightTables; 145 }; 146 147 #ifdef PDF_ENABLE_XFA_PNG 148 // PngModule::Delegate 149 bool PngReadHeader(int width, 150 int height, 151 int bpc, 152 int pass, 153 int* color_type, 154 double* gamma) override; 155 bool PngAskScanlineBuf(int line, uint8_t** pSrcBuf) override; 156 void PngFillScanlineBufCompleted(int pass, int line) override; 157 #endif // PDF_ENABLE_XFA_PNG 158 159 #ifdef PDF_ENABLE_XFA_GIF 160 // GifModule::Delegate 161 void GifRecordCurrentPosition(uint32_t& cur_pos) override; 162 bool GifInputRecordPositionBuf(uint32_t rcd_pos, 163 const FX_RECT& img_rc, 164 int32_t pal_num, 165 CFX_GifPalette* pal_ptr, 166 int32_t delay_time, 167 bool user_input, 168 int32_t trans_index, 169 int32_t disposal_method, 170 bool interlace) override; 171 void GifReadScanline(int32_t row_num, uint8_t* row_buf) override; 172 #endif // PDF_ENABLE_XFA_GIF 173 174 #ifdef PDF_ENABLE_XFA_BMP 175 // BmpModule::Delegate 176 bool BmpInputImagePositionBuf(uint32_t rcd_pos) override; 177 void BmpReadScanline(uint32_t row_num, 178 pdfium::span<const uint8_t> row_buf) override; 179 #endif // PDF_ENABLE_XFA_BMP 180 181 private: 182 #ifdef PDF_ENABLE_XFA_BMP 183 bool BmpReadMoreData(BmpModule* pBmpModule, 184 ModuleIface::Context* pBmpContext, 185 FXCODEC_STATUS& err_status); 186 bool BmpDetectImageTypeInBuffer(CFX_DIBAttribute* pAttribute); 187 FXCODEC_STATUS BmpStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap); 188 FXCODEC_STATUS BmpContinueDecode(); 189 #endif // PDF_ENABLE_XFA_BMP 190 191 #ifdef PDF_ENABLE_XFA_GIF 192 bool GifReadMoreData(GifModule* pGifModule, FXCODEC_STATUS& err_status); 193 bool GifDetectImageTypeInBuffer(); 194 FXCODEC_STATUS GifStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap); 195 FXCODEC_STATUS GifContinueDecode(); 196 void GifDoubleLineResampleVert(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 197 double scale_y, 198 int dest_row); 199 #endif // PDF_ENABLE_XFA_GIF 200 201 #ifdef PDF_ENABLE_XFA_PNG 202 void PngOneOneMapResampleHorz(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 203 int32_t dest_line, 204 uint8_t* src_scan, 205 FXCodec_Format src_format); 206 bool PngDetectImageTypeInBuffer(CFX_DIBAttribute* pAttribute); 207 FXCODEC_STATUS PngStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap); 208 FXCODEC_STATUS PngContinueDecode(); 209 #endif // PDF_ENABLE_XFA_PNG 210 211 #ifdef PDF_ENABLE_XFA_TIFF 212 bool TiffDetectImageTypeFromFile(CFX_DIBAttribute* pAttribute); 213 FXCODEC_STATUS TiffContinueDecode(); 214 #endif // PDF_ENABLE_XFA_TIFF 215 216 bool JpegReadMoreData(JpegModule* pJpegModule, FXCODEC_STATUS& err_status); 217 bool JpegDetectImageTypeInBuffer(CFX_DIBAttribute* pAttribute); 218 FXCODEC_STATUS JpegStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap); 219 FXCODEC_STATUS JpegContinueDecode(); 220 221 bool DetectImageType(FXCODEC_IMAGE_TYPE imageType, 222 CFX_DIBAttribute* pAttribute); 223 bool ReadMoreData(ModuleIface* pModule, 224 ModuleIface::Context* pContext, 225 bool invalidate_buffer, 226 FXCODEC_STATUS& err_status); 227 228 void GetDownScale(int& down_scale); 229 void GetTransMethod(FXDIB_Format dest_format, FXCodec_Format src_format); 230 231 void ReSampleScanline(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 232 int32_t dest_line, 233 uint8_t* src_scan, 234 FXCodec_Format src_format); 235 void Resample(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 236 int32_t src_line, 237 uint8_t* src_scan, 238 FXCodec_Format src_format); 239 void ResampleVert(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 240 double scale_y, 241 int dest_row); 242 void ResampleVertBT(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 243 double scale_y, 244 int dest_row); 245 246 FXCODEC_STATUS m_status = FXCODEC_STATUS_DECODE_FINISH; 247 FXCODEC_IMAGE_TYPE m_imageType = FXCODEC_IMAGE_UNKNOWN; 248 RetainPtr<IFX_SeekableReadStream> m_pFile; 249 RetainPtr<CFX_DIBitmap> m_pDeviceBitmap; 250 UnownedPtr<ModuleMgr> m_pCodecMgr; 251 RetainPtr<CFX_CodecMemory> m_pCodecMemory; 252 std::unique_ptr<uint8_t, FxFreeDeleter> m_pDecodeBuf; 253 std::unique_ptr<FX_ARGB, FxFreeDeleter> m_pSrcPalette; 254 std::unique_ptr<ModuleIface::Context> m_pJpegContext; 255 #ifdef PDF_ENABLE_XFA_BMP 256 std::unique_ptr<ModuleIface::Context> m_pBmpContext; 257 #endif // PDF_ENABLE_XFA_BMP 258 #ifdef PDF_ENABLE_XFA_GIF 259 std::unique_ptr<ModuleIface::Context> m_pGifContext; 260 #endif // PDF_ENABLE_XFA_GIF 261 #ifdef PDF_ENABLE_XFA_PNG 262 std::unique_ptr<ModuleIface::Context> m_pPngContext; 263 #endif // PDF_ENABLE_XFA_PNG 264 #ifdef PDF_ENABLE_XFA_TIFF 265 std::unique_ptr<ModuleIface::Context> m_pTiffContext; 266 #endif // PDF_ENABLE_XFA_TIFF 267 uint32_t m_offSet = 0; 268 int m_ScanlineSize = 0; 269 CFXCODEC_WeightTable m_WeightHorz; 270 CFXCODEC_VertTable m_WeightVert; 271 CFXCODEC_HorzTable m_WeightHorzOO; 272 int m_SrcWidth = 0; 273 int m_SrcHeight = 0; 274 int m_SrcComponents = 0; 275 int m_SrcBPC = 0; 276 FX_RECT m_clipBox; 277 int m_startX = 0; 278 int m_startY = 0; 279 int m_sizeX = 0; 280 int m_sizeY = 0; 281 int m_TransMethod = -1; 282 int m_SrcPaletteNumber = 0; 283 int m_SrcRow = 0; 284 FXCodec_Format m_SrcFormat = FXCodec_Invalid; 285 int m_SrcPassNumber = 0; 286 size_t m_FrameNumber = 0; 287 size_t m_FrameCur = 0; 288 #ifdef PDF_ENABLE_XFA_GIF 289 int m_GifBgIndex = 0; 290 CFX_GifPalette* m_pGifPalette = nullptr; 291 int32_t m_GifPltNumber = 0; 292 int m_GifTransIndex = -1; 293 FX_RECT m_GifFrameRect; 294 bool m_InvalidateGifBuffer = true; 295 #endif // PDF_ENABLE_XFA_GIF 296 #ifdef PDF_ENABLE_XFA_BMP 297 bool m_BmpIsTopBottom = false; 298 #endif // PDF_ENABLE_XFA_BMP 299 }; 300 301 } // namespace fxcodec 302 303 using ProgressiveDecoder = fxcodec::ProgressiveDecoder; 304 305 #endif // CORE_FXCODEC_PROGRESSIVEDECODER_H_ 306