• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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