xref: /aosp_15_r20/external/pdfium/core/fxcodec/progressive_decoder.h (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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