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_CODEC_CCODEC_PROGRESSIVEDECODER_H_ 8 #define CORE_FXCODEC_CODEC_CCODEC_PROGRESSIVEDECODER_H_ 9 10 #include <vector> 11 12 #include "core/fxcodec/codec/icodec_bmpmodule.h" 13 #include "core/fxcodec/codec/icodec_gifmodule.h" 14 #include "core/fxcodec/codec/icodec_pngmodule.h" 15 #include "core/fxcodec/codec/icodec_tiffmodule.h" 16 #include "core/fxcodec/fx_codec_def.h" 17 #include "core/fxcrt/cfx_retain_ptr.h" 18 #include "core/fxcrt/fx_system.h" 19 #include "core/fxge/fx_dib.h" 20 21 class CCodec_JpegModule; 22 class CCodec_ModuleMgr; 23 class CFX_DIBAttribute; 24 class IFX_SeekableReadStream; 25 class IFX_Pause; 26 struct FXJPEG_Context; 27 28 class CCodec_ProgressiveDecoder : public ICodec_BmpModule::Delegate, 29 public ICodec_GifModule::Delegate, 30 public ICodec_PngModule::Delegate { 31 public: 32 enum FXCodec_Format { 33 FXCodec_Invalid = 0, 34 FXCodec_1bppGray = 0x101, 35 FXCodec_1bppRgb = 0x001, 36 FXCodec_8bppGray = 0x108, 37 FXCodec_8bppRgb = 0x008, 38 FXCodec_Rgb = 0x018, 39 FXCodec_Rgb32 = 0x020, 40 FXCodec_Argb = 0x220, 41 FXCodec_Cmyk = 0x120 42 }; 43 44 explicit CCodec_ProgressiveDecoder(CCodec_ModuleMgr* pCodecMgr); 45 virtual ~CCodec_ProgressiveDecoder(); 46 47 FXCODEC_STATUS LoadImageInfo( 48 const CFX_RetainPtr<IFX_SeekableReadStream>& pFile, 49 FXCODEC_IMAGE_TYPE imageType, 50 CFX_DIBAttribute* pAttribute, 51 bool bSkipImageTypeCheck); 52 GetType()53 FXCODEC_IMAGE_TYPE GetType() const { return m_imagType; } GetWidth()54 int32_t GetWidth() const { return m_SrcWidth; } GetHeight()55 int32_t GetHeight() const { return m_SrcHeight; } GetNumComponents()56 int32_t GetNumComponents() const { return m_SrcComponents; } GetBPC()57 int32_t GetBPC() const { return m_SrcBPC; } 58 void SetClipBox(FX_RECT* clip); 59 60 FXCODEC_STATUS GetFrames(int32_t& frames, IFX_Pause* pPause = nullptr); 61 FXCODEC_STATUS StartDecode(CFX_DIBitmap* pDIBitmap, 62 int start_x, 63 int start_y, 64 int size_x, 65 int size_y, 66 int32_t frames = 0, 67 bool bInterpol = true); 68 69 FXCODEC_STATUS ContinueDecode(IFX_Pause* pPause = nullptr); 70 71 struct PixelWeight { 72 int m_SrcStart; 73 int m_SrcEnd; 74 int m_Weights[1]; 75 }; 76 77 class CFXCODEC_WeightTable { 78 public: 79 CFXCODEC_WeightTable(); 80 ~CFXCODEC_WeightTable(); 81 82 void Calc(int dest_len, 83 int dest_min, 84 int dest_max, 85 int src_len, 86 int src_min, 87 int src_max, 88 bool bInterpol); GetPixelWeight(int pixel)89 PixelWeight* GetPixelWeight(int pixel) { 90 return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() + 91 (pixel - m_DestMin) * m_ItemSize); 92 } 93 94 int m_DestMin; 95 int m_ItemSize; 96 std::vector<uint8_t> m_pWeightTables; 97 }; 98 99 class CFXCODEC_HorzTable { 100 public: 101 CFXCODEC_HorzTable(); 102 ~CFXCODEC_HorzTable(); 103 104 void Calc(int dest_len, int src_len, bool bInterpol); GetPixelWeight(int pixel)105 PixelWeight* GetPixelWeight(int pixel) { 106 return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() + 107 pixel * m_ItemSize); 108 } 109 110 int m_ItemSize; 111 std::vector<uint8_t> m_pWeightTables; 112 }; 113 114 class CFXCODEC_VertTable { 115 public: 116 CFXCODEC_VertTable(); 117 ~CFXCODEC_VertTable(); 118 119 void Calc(int dest_len, int src_len); GetPixelWeight(int pixel)120 PixelWeight* GetPixelWeight(int pixel) { 121 return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() + 122 pixel * m_ItemSize); 123 } 124 int m_ItemSize; 125 std::vector<uint8_t> m_pWeightTables; 126 }; 127 128 CFX_RetainPtr<IFX_SeekableReadStream> m_pFile; 129 CCodec_ModuleMgr* m_pCodecMgr; 130 FXJPEG_Context* m_pJpegContext; 131 FXPNG_Context* m_pPngContext; 132 FXGIF_Context* m_pGifContext; 133 FXBMP_Context* m_pBmpContext; 134 CCodec_TiffContext* m_pTiffContext; 135 FXCODEC_IMAGE_TYPE m_imagType; 136 uint32_t m_offSet; 137 uint8_t* m_pSrcBuf; 138 uint32_t m_SrcSize; 139 uint8_t* m_pDecodeBuf; 140 int m_ScanlineSize; 141 CFX_DIBitmap* m_pDeviceBitmap; 142 bool m_bInterpol; 143 CFXCODEC_WeightTable m_WeightHorz; 144 CFXCODEC_VertTable m_WeightVert; 145 CFXCODEC_HorzTable m_WeightHorzOO; 146 int m_SrcWidth; 147 int m_SrcHeight; 148 int m_SrcComponents; 149 int m_SrcBPC; 150 FX_RECT m_clipBox; 151 int m_startX; 152 int m_startY; 153 int m_sizeX; 154 int m_sizeY; 155 int m_TransMethod; 156 FX_ARGB* m_pSrcPalette; 157 int m_SrcPaletteNumber; 158 int m_SrcRow; 159 FXCodec_Format m_SrcFormat; 160 int m_SrcPassNumber; 161 int m_FrameNumber; 162 int m_FrameCur; 163 int m_GifBgIndex; 164 uint8_t* m_pGifPalette; 165 int32_t m_GifPltNumber; 166 int m_GifTransIndex; 167 FX_RECT m_GifFrameRect; 168 bool m_BmpIsTopBottom; 169 FXCODEC_STATUS m_status; 170 171 // ICodec_PngModule::Delegate 172 bool PngReadHeader(int width, 173 int height, 174 int bpc, 175 int pass, 176 int* color_type, 177 double* gamma) override; 178 bool PngAskScanlineBuf(int line, uint8_t*& src_buf) override; 179 void PngFillScanlineBufCompleted(int pass, int line) override; 180 181 // ICodec_GifModule::Delegate 182 void GifRecordCurrentPosition(uint32_t& cur_pos) override; 183 uint8_t* GifAskLocalPaletteBuf(int32_t frame_num, int32_t pal_size) override; 184 bool GifInputRecordPositionBuf(uint32_t rcd_pos, 185 const FX_RECT& img_rc, 186 int32_t pal_num, 187 void* pal_ptr, 188 int32_t delay_time, 189 bool user_input, 190 int32_t trans_index, 191 int32_t disposal_method, 192 bool interlace) override; 193 void GifReadScanline(int32_t row_num, uint8_t* row_buf) override; 194 195 // ICodec_BmpModule::Delegate 196 bool BmpInputImagePositionBuf(uint32_t rcd_pos) override; 197 void BmpReadScanline(int32_t row_num, uint8_t* row_buf) override; 198 199 protected: 200 bool BmpReadMoreData(ICodec_BmpModule* pBmpModule, 201 FXCODEC_STATUS& err_status); 202 bool GifReadMoreData(ICodec_GifModule* pGifModule, 203 FXCODEC_STATUS& err_status); 204 void GifDoubleLineResampleVert(CFX_DIBitmap* pDeviceBitmap, 205 double scale_y, 206 int des_row); 207 void PngOneOneMapResampleHorz(CFX_DIBitmap* pDeviceBitmap, 208 int32_t des_line, 209 uint8_t* src_scan, 210 FXCodec_Format src_format); 211 bool DetectImageType(FXCODEC_IMAGE_TYPE imageType, 212 CFX_DIBAttribute* pAttribute); 213 void GetDownScale(int& down_scale); 214 void GetTransMethod(FXDIB_Format des_format, FXCodec_Format src_format); 215 void ReSampleScanline(CFX_DIBitmap* pDeviceBitmap, 216 int32_t des_line, 217 uint8_t* src_scan, 218 FXCodec_Format src_format); 219 void Resample(CFX_DIBitmap* pDeviceBitmap, 220 int32_t src_line, 221 uint8_t* src_scan, 222 FXCodec_Format src_format); 223 void ResampleVert(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row); 224 bool JpegReadMoreData(CCodec_JpegModule* pJpegModule, 225 FXCODEC_STATUS& err_status); 226 void ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row); 227 }; 228 229 #endif // CORE_FXCODEC_CODEC_CCODEC_PROGRESSIVEDECODER_H_ 230