• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_LGIF_FX_GIF_H_
8 #define CORE_FXCODEC_LGIF_FX_GIF_H_
9 
10 #include <setjmp.h>
11 #include <vector>
12 
13 #include "core/fxcrt/fx_basic.h"
14 
15 #define GIF_SIGNATURE "GIF"
16 #define GIF_SIG_EXTENSION 0x21
17 #define GIF_SIG_IMAGE 0x2C
18 #define GIF_SIG_TRAILER 0x3B
19 #define GIF_BLOCK_GCE 0xF9
20 #define GIF_BLOCK_PTE 0x01
21 #define GIF_BLOCK_CE 0xFE
22 #define GIF_BLOCK_AE 0xFF
23 #define GIF_BLOCK_TERMINAL 0x00
24 #define GIF_MAX_LZW_CODE 4096
25 #define GIF_DATA_BLOCK 255
26 #define GIF_MAX_ERROR_SIZE 256
27 #define GIF_D_STATUS_SIG 0x01
28 #define GIF_D_STATUS_TAIL 0x02
29 #define GIF_D_STATUS_EXT 0x03
30 #define GIF_D_STATUS_EXT_AE 0x04
31 #define GIF_D_STATUS_EXT_CE 0x05
32 #define GIF_D_STATUS_EXT_GCE 0x06
33 #define GIF_D_STATUS_EXT_PTE 0x07
34 #define GIF_D_STATUS_EXT_UNE 0x08
35 #define GIF_D_STATUS_IMG_INFO 0x09
36 #define GIF_D_STATUS_IMG_DATA 0x0A
37 #pragma pack(1)
38 typedef struct tagGifGF {
39   uint8_t pal_bits : 3;
40   uint8_t sort_flag : 1;
41   uint8_t color_resolution : 3;
42   uint8_t global_pal : 1;
43 } GifGF;
44 typedef struct tagGifLF {
45   uint8_t pal_bits : 3;
46   uint8_t reserved : 2;
47   uint8_t sort_flag : 1;
48   uint8_t interlace : 1;
49   uint8_t local_pal : 1;
50 } GifLF;
51 typedef struct tagGifHeader {
52   char signature[3];
53   char version[3];
54 } GifHeader;
55 typedef struct tagGifLSD {
56   uint16_t width;
57   uint16_t height;
58   uint8_t global_flag;
59   uint8_t bc_index;
60   uint8_t pixel_aspect;
61 } GifLSD;
62 typedef struct tagGifImageInfo {
63   uint16_t left;
64   uint16_t top;
65   uint16_t width;
66   uint16_t height;
67 
68   uint8_t local_flag;
69 } GifImageInfo;
70 typedef struct tagGifCEF {
71   uint8_t transparency : 1;
72   uint8_t user_input : 1;
73   uint8_t disposal_method : 3;
74   uint8_t reserved : 3;
75 } GifCEF;
76 typedef struct tagGifGCE {
77   uint8_t block_size;
78   uint8_t gce_flag;
79   uint16_t delay_time;
80   uint8_t trans_index;
81 } GifGCE;
82 typedef struct tagGifPTE {
83   uint8_t block_size;
84   uint16_t grid_left;
85   uint16_t grid_top;
86   uint16_t grid_width;
87   uint16_t grid_height;
88 
89   uint8_t char_width;
90   uint8_t char_height;
91 
92   uint8_t fc_index;
93   uint8_t bc_index;
94 } GifPTE;
95 typedef struct tagGifAE {
96   uint8_t block_size;
97   uint8_t app_identify[8];
98   uint8_t app_authentication[3];
99 } GifAE;
100 typedef struct tagGifPalette { uint8_t r, g, b; } GifPalette;
101 #pragma pack()
102 typedef struct tagGifImage {
103   GifGCE* image_gce_ptr;
104   GifPalette* local_pal_ptr;
105   GifImageInfo* image_info_ptr;
106   uint8_t image_code_size;
107   uint32_t image_data_pos;
108   uint8_t* image_row_buf;
109   int32_t image_row_num;
110 } GifImage;
111 
112 typedef struct tagGifPlainText {
113   GifGCE* gce_ptr;
114   GifPTE* pte_ptr;
115   CFX_ByteString* string_ptr;
116 } GifPlainText;
117 
118 class CGifLZWDecoder {
119  public:
120   struct tag_Table {
121     uint16_t prefix;
122     uint8_t suffix;
123   };
124 
125   explicit CGifLZWDecoder(FX_CHAR* error_ptr);
126   ~CGifLZWDecoder();
127 
128   void InitTable(uint8_t code_len);
129   int32_t Decode(uint8_t* des_buf, uint32_t& des_size);
130   void Input(uint8_t* src_buf, uint32_t src_size);
131   uint32_t GetAvailInput();
132 
133  private:
134   void ClearTable();
135   void AddCode(uint16_t prefix_code, uint8_t append_char);
136   void DecodeString(uint16_t code);
137 
138   uint8_t code_size;
139   uint8_t code_size_cur;
140   uint16_t code_clear;
141   uint16_t code_end;
142   uint16_t code_next;
143   uint8_t code_first;
144   uint8_t stack[GIF_MAX_LZW_CODE];
145   uint16_t stack_size;
146   tag_Table code_table[GIF_MAX_LZW_CODE];
147   uint16_t code_old;
148 
149   uint8_t* next_in;
150   uint32_t avail_in;
151 
152   uint8_t bits_left;
153   uint32_t code_store;
154 
155   FX_CHAR* err_msg_ptr;
156 };
157 
158 class CGifLZWEncoder {
159  public:
160   struct tag_Table {
161     uint16_t prefix;
162     uint8_t suffix;
163   };
164 
165   CGifLZWEncoder();
166   ~CGifLZWEncoder();
167 
168   void Start(uint8_t code_len,
169              const uint8_t* src_buf,
170              uint8_t*& dst_buf,
171              uint32_t& offset);
172   bool Encode(const uint8_t* src_buf,
173               uint32_t src_len,
174               uint8_t*& dst_buf,
175               uint32_t& dst_len,
176               uint32_t& offset);
177   void Finish(uint8_t*& dst_buf, uint32_t& dst_len, uint32_t& offset);
178 
179  private:
180   void ClearTable();
181   bool LookUpInTable(const uint8_t* buf, uint32_t& offset, uint8_t& bit_offset);
182   void EncodeString(uint32_t index,
183                     uint8_t*& dst_buf,
184                     uint32_t& dst_len,
185                     uint32_t& offset);
186   void WriteBlock(uint8_t*& dst_buf, uint32_t& dst_len, uint32_t& offset);
187 
188   jmp_buf jmp;
189   uint32_t src_offset;
190   uint8_t src_bit_offset;
191   uint8_t src_bit_cut;
192   uint32_t src_bit_num;
193   uint8_t code_size;
194   uint16_t code_clear;
195   uint16_t code_end;
196   uint16_t index_num;
197   uint8_t bit_offset;
198   uint8_t index_bit_cur;
199   uint8_t index_buf[GIF_DATA_BLOCK];
200   uint8_t index_buf_len;
201   tag_Table code_table[GIF_MAX_LZW_CODE];
202   uint16_t table_cur;
203 };
204 
205 typedef struct tag_gif_decompress_struct gif_decompress_struct;
206 typedef gif_decompress_struct* gif_decompress_struct_p;
207 typedef gif_decompress_struct_p* gif_decompress_struct_pp;
208 static const int32_t s_gif_interlace_step[4] = {8, 8, 4, 2};
209 struct tag_gif_decompress_struct {
210   jmp_buf jmpbuf;
211   FX_CHAR* err_ptr;
212   void (*gif_error_fn)(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg);
213   void* context_ptr;
214   int width;
215   int height;
216   GifPalette* global_pal_ptr;
217   int32_t global_pal_num;
218   uint8_t global_sort_flag;
219   uint8_t global_color_resolution;
220 
221   uint8_t bc_index;
222   uint8_t pixel_aspect;
223   CGifLZWDecoder* img_decoder_ptr;
224   uint32_t img_row_offset;
225   uint32_t img_row_avail_size;
226   uint8_t img_pass_num;
227   std::vector<GifImage*>* img_ptr_arr_ptr;
228   uint8_t* (*gif_ask_buf_for_pal_fn)(gif_decompress_struct_p gif_ptr,
229                                      int32_t pal_size);
230   uint8_t* next_in;
231   uint32_t avail_in;
232   int32_t decode_status;
233   uint32_t skip_size;
234   void (*gif_record_current_position_fn)(gif_decompress_struct_p gif_ptr,
235                                          uint32_t* cur_pos_ptr);
236   void (*gif_get_row_fn)(gif_decompress_struct_p gif_ptr,
237                          int32_t row_num,
238                          uint8_t* row_buf);
239   bool (*gif_get_record_position_fn)(gif_decompress_struct_p gif_ptr,
240                                      uint32_t cur_pos,
241                                      int32_t left,
242                                      int32_t top,
243                                      int32_t width,
244                                      int32_t height,
245                                      int32_t pal_num,
246                                      void* pal_ptr,
247                                      int32_t delay_time,
248                                      bool user_input,
249                                      int32_t trans_index,
250                                      int32_t disposal_method,
251                                      bool interlace);
252   CFX_ByteString* cmt_data_ptr;
253   GifGCE* gce_ptr;
254   std::vector<GifPlainText*>* pt_ptr_arr_ptr;
255 };
256 typedef struct tag_gif_compress_struct gif_compress_struct;
257 typedef gif_compress_struct* gif_compress_struct_p;
258 typedef gif_compress_struct_p* gif_compress_struct_pp;
259 struct tag_gif_compress_struct {
260   const uint8_t* src_buf;
261   uint32_t src_pitch;
262   uint32_t src_width;
263   uint32_t src_row;
264   uint32_t cur_offset;
265   uint32_t frames;
266   GifHeader* header_ptr;
267   GifLSD* lsd_ptr;
268   GifPalette* global_pal;
269   uint16_t gpal_num;
270   GifPalette* local_pal;
271   uint16_t lpal_num;
272   GifImageInfo* image_info_ptr;
273   CGifLZWEncoder* img_encoder_ptr;
274 
275   uint8_t* cmt_data_ptr;
276   uint32_t cmt_data_len;
277   GifGCE* gce_ptr;
278   GifPTE* pte_ptr;
279   const uint8_t* pte_data_ptr;
280   uint32_t pte_data_len;
281 };
282 
283 void gif_error(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg);
284 void gif_warn(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg);
285 gif_decompress_struct_p gif_create_decompress();
286 void gif_destroy_decompress(gif_decompress_struct_pp gif_ptr_ptr);
287 gif_compress_struct_p gif_create_compress();
288 void gif_destroy_compress(gif_compress_struct_pp gif_ptr_ptr);
289 int32_t gif_read_header(gif_decompress_struct_p gif_ptr);
290 int32_t gif_get_frame(gif_decompress_struct_p gif_ptr);
291 int32_t gif_get_frame_num(gif_decompress_struct_p gif_ptr);
292 int32_t gif_decode_extension(gif_decompress_struct_p gif_ptr);
293 int32_t gif_decode_image_info(gif_decompress_struct_p gif_ptr);
294 void gif_takeover_gce_ptr(gif_decompress_struct_p gif_ptr,
295                           GifGCE** gce_ptr_ptr);
296 int32_t gif_load_frame(gif_decompress_struct_p gif_ptr, int32_t frame_num);
297 uint8_t* gif_read_data(gif_decompress_struct_p gif_ptr,
298                        uint8_t** des_buf_pp,
299                        uint32_t data_size);
300 void gif_decoding_failure_at_tail_cleanup(gif_decompress_struct_p gif_ptr,
301                                           GifImage* gif_image_ptr);
302 void gif_save_decoding_status(gif_decompress_struct_p gif_ptr, int32_t status);
303 void gif_input_buffer(gif_decompress_struct_p gif_ptr,
304                       uint8_t* src_buf,
305                       uint32_t src_size);
306 uint32_t gif_get_avail_input(gif_decompress_struct_p gif_ptr,
307                              uint8_t** avail_buf_ptr);
308 void interlace_buf(const uint8_t* buf, uint32_t width, uint32_t height);
309 bool gif_encode(gif_compress_struct_p gif_ptr,
310                 uint8_t*& dst_buf,
311                 uint32_t& dst_len);
312 
313 #endif  // CORE_FXCODEC_LGIF_FX_GIF_H_
314