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 <memory> 11 #include <utility> 12 #include <vector> 13 14 #include "core/fxcodec/codec/ccodec_bmpmodule.h" 15 #include "core/fxcodec/codec/ccodec_gifmodule.h" 16 #include "core/fxcodec/codec/ccodec_jpegmodule.h" 17 #include "core/fxcodec/codec/ccodec_pngmodule.h" 18 #include "core/fxcodec/codec/ccodec_tiffmodule.h" 19 #include "core/fxcodec/fx_codec_def.h" 20 #include "core/fxcrt/fx_system.h" 21 #include "core/fxcrt/retain_ptr.h" 22 #include "core/fxcrt/unowned_ptr.h" 23 #include "core/fxge/fx_dib.h" 24 25 class CCodec_ModuleMgr; 26 class CFX_DIBAttribute; 27 class IFX_SeekableReadStream; 28 29 class CCodec_ProgressiveDecoder : public CCodec_BmpModule::Delegate, 30 public CCodec_GifModule::Delegate, 31 public CCodec_PngModule::Delegate { 32 public: 33 enum FXCodec_Format { 34 FXCodec_Invalid = 0, 35 FXCodec_1bppGray = 0x101, 36 FXCodec_1bppRgb = 0x001, 37 FXCodec_8bppGray = 0x108, 38 FXCodec_8bppRgb = 0x008, 39 FXCodec_Rgb = 0x018, 40 FXCodec_Rgb32 = 0x020, 41 FXCodec_Argb = 0x220, 42 FXCodec_Cmyk = 0x120 43 }; 44 45 explicit CCodec_ProgressiveDecoder(CCodec_ModuleMgr* pCodecMgr); 46 virtual ~CCodec_ProgressiveDecoder(); 47 48 FXCODEC_STATUS LoadImageInfo(const 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 std::pair<FXCODEC_STATUS, size_t> GetFrames(); 61 FXCODEC_STATUS StartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap, 62 int start_x, 63 int start_y, 64 int size_x, 65 int size_y); 66 67 FXCODEC_STATUS ContinueDecode(); 68 69 struct PixelWeight { 70 int m_SrcStart; 71 int m_SrcEnd; 72 int m_Weights[1]; 73 }; 74 75 class CFXCODEC_WeightTable { 76 public: 77 CFXCODEC_WeightTable(); 78 ~CFXCODEC_WeightTable(); 79 80 void Calc(int dest_len, 81 int dest_min, 82 int dest_max, 83 int src_len, 84 int src_min, 85 int src_max); GetPixelWeight(int pixel)86 PixelWeight* GetPixelWeight(int pixel) { 87 return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() + 88 (pixel - m_DestMin) * m_ItemSize); 89 } 90 91 int m_DestMin; 92 int m_ItemSize; 93 std::vector<uint8_t> m_pWeightTables; 94 }; 95 96 class CFXCODEC_HorzTable { 97 public: 98 CFXCODEC_HorzTable(); 99 ~CFXCODEC_HorzTable(); 100 101 void Calc(int dest_len, int src_len); GetPixelWeight(int pixel)102 PixelWeight* GetPixelWeight(int pixel) { 103 return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() + 104 pixel * m_ItemSize); 105 } 106 107 int m_ItemSize; 108 std::vector<uint8_t> m_pWeightTables; 109 }; 110 111 class CFXCODEC_VertTable { 112 public: 113 CFXCODEC_VertTable(); 114 ~CFXCODEC_VertTable(); 115 116 void Calc(int dest_len, int src_len); GetPixelWeight(int pixel)117 PixelWeight* GetPixelWeight(int pixel) { 118 return reinterpret_cast<PixelWeight*>(m_pWeightTables.data() + 119 pixel * m_ItemSize); 120 } 121 int m_ItemSize; 122 std::vector<uint8_t> m_pWeightTables; 123 }; 124 125 // CCodec_PngModule::Delegate 126 bool PngReadHeader(int width, 127 int height, 128 int bpc, 129 int pass, 130 int* color_type, 131 double* gamma) override; 132 bool PngAskScanlineBuf(int line, uint8_t** pSrcBuf) override; 133 void PngFillScanlineBufCompleted(int pass, int line) override; 134 135 // CCodec_GifModule::Delegate 136 void GifRecordCurrentPosition(uint32_t& cur_pos) override; 137 bool GifInputRecordPositionBuf(uint32_t rcd_pos, 138 const FX_RECT& img_rc, 139 int32_t pal_num, 140 void* pal_ptr, 141 int32_t delay_time, 142 bool user_input, 143 int32_t trans_index, 144 int32_t disposal_method, 145 bool interlace) override; 146 void GifReadScanline(int32_t row_num, uint8_t* row_buf) override; 147 148 // CCodec_BmpModule::Delegate 149 bool BmpInputImagePositionBuf(uint32_t rcd_pos) override; 150 void BmpReadScanline(uint32_t row_num, 151 const std::vector<uint8_t>& row_buf) override; 152 153 private: 154 bool BmpReadMoreData(CCodec_BmpModule* pBmpModule, 155 FXCODEC_STATUS& err_status); 156 bool GifReadMoreData(CCodec_GifModule* pGifModule, 157 FXCODEC_STATUS& err_status); 158 bool JpegReadMoreData(CCodec_JpegModule* pJpegModule, 159 FXCODEC_STATUS& err_status); 160 void PngOneOneMapResampleHorz(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 161 int32_t des_line, 162 uint8_t* src_scan, 163 FXCodec_Format src_format); 164 bool DetectImageType(FXCODEC_IMAGE_TYPE imageType, 165 CFX_DIBAttribute* pAttribute); 166 bool BmpDetectImageType(CFX_DIBAttribute* pAttribute, uint32_t size); 167 bool JpegDetectImageType(CFX_DIBAttribute* pAttribute, uint32_t size); 168 bool PngDetectImageType(CFX_DIBAttribute* pAttribute, uint32_t size); 169 bool GifDetectImageType(CFX_DIBAttribute* pAttribute, uint32_t size); 170 bool TifDetectImageType(CFX_DIBAttribute* pAttribute, uint32_t size); 171 172 void GetDownScale(int& down_scale); 173 void GetTransMethod(FXDIB_Format des_format, FXCodec_Format src_format); 174 175 void ReSampleScanline(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 176 int32_t des_line, 177 uint8_t* src_scan, 178 FXCodec_Format src_format); 179 void Resample(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 180 int32_t src_line, 181 uint8_t* src_scan, 182 FXCodec_Format src_format); 183 void ResampleVert(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 184 double scale_y, 185 int des_row); 186 void ResampleVertBT(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 187 double scale_y, 188 int des_row); 189 void GifDoubleLineResampleVert(const RetainPtr<CFX_DIBitmap>& pDeviceBitmap, 190 double scale_y, 191 int des_row); 192 193 FXCODEC_STATUS JpegStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap); 194 FXCODEC_STATUS PngStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap); 195 FXCODEC_STATUS GifStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap); 196 FXCODEC_STATUS BmpStartDecode(const RetainPtr<CFX_DIBitmap>& pDIBitmap); 197 198 FXCODEC_STATUS JpegContinueDecode(); 199 FXCODEC_STATUS PngContinueDecode(); 200 FXCODEC_STATUS GifContinueDecode(); 201 FXCODEC_STATUS BmpContinueDecode(); 202 FXCODEC_STATUS TifContinueDecode(); 203 204 RetainPtr<IFX_SeekableReadStream> m_pFile; 205 RetainPtr<CFX_DIBitmap> m_pDeviceBitmap; 206 UnownedPtr<CCodec_ModuleMgr> m_pCodecMgr; 207 std::unique_ptr<CCodec_JpegModule::Context> m_pJpegContext; 208 std::unique_ptr<CCodec_PngModule::Context> m_pPngContext; 209 std::unique_ptr<CCodec_GifModule::Context> m_pGifContext; 210 std::unique_ptr<CCodec_BmpModule::Context> m_pBmpContext; 211 std::unique_ptr<CCodec_TiffModule::Context> m_pTiffContext; 212 FXCODEC_IMAGE_TYPE m_imagType; 213 uint32_t m_offSet; 214 uint8_t* m_pSrcBuf; 215 uint32_t m_SrcSize; 216 uint8_t* m_pDecodeBuf; 217 int m_ScanlineSize; 218 CFXCODEC_WeightTable m_WeightHorz; 219 CFXCODEC_VertTable m_WeightVert; 220 CFXCODEC_HorzTable m_WeightHorzOO; 221 int m_SrcWidth; 222 int m_SrcHeight; 223 int m_SrcComponents; 224 int m_SrcBPC; 225 FX_RECT m_clipBox; 226 int m_startX; 227 int m_startY; 228 int m_sizeX; 229 int m_sizeY; 230 int m_TransMethod; 231 FX_ARGB* m_pSrcPalette; 232 int m_SrcPaletteNumber; 233 int m_SrcRow; 234 FXCodec_Format m_SrcFormat; 235 int m_SrcPassNumber; 236 size_t m_FrameNumber; 237 size_t m_FrameCur; 238 int m_GifBgIndex; 239 uint8_t* m_pGifPalette; 240 int32_t m_GifPltNumber; 241 int m_GifTransIndex; 242 FX_RECT m_GifFrameRect; 243 bool m_BmpIsTopBottom; 244 FXCODEC_STATUS m_status; 245 }; 246 247 #endif // CORE_FXCODEC_CODEC_CCODEC_PROGRESSIVEDECODER_H_ 248