• 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 #include "core/fxcodec/lgif/fx_gif.h"
8 
9 #include "core/fxcodec/lbmp/fx_bmp.h"
10 #include "third_party/base/stl_util.h"
11 
Input(uint8_t * src_buf,uint32_t src_size)12 void CGifLZWDecoder::Input(uint8_t* src_buf, uint32_t src_size) {
13   next_in = src_buf;
14   avail_in = src_size;
15 }
16 
GetAvailInput()17 uint32_t CGifLZWDecoder::GetAvailInput() {
18   return avail_in;
19 }
20 
CGifLZWDecoder(FX_CHAR * error_ptr)21 CGifLZWDecoder::CGifLZWDecoder(FX_CHAR* error_ptr)
22     : code_size(0),
23       code_size_cur(0),
24       code_clear(0),
25       code_end(0),
26       code_next(0),
27       code_first(0),
28       stack_size(0),
29       code_old(0),
30       next_in(nullptr),
31       avail_in(0),
32       bits_left(0),
33       code_store(0),
34       err_msg_ptr(error_ptr) {}
35 
~CGifLZWDecoder()36 CGifLZWDecoder::~CGifLZWDecoder() {}
37 
InitTable(uint8_t code_len)38 void CGifLZWDecoder::InitTable(uint8_t code_len) {
39   code_size = code_len;
40   ASSERT(code_size < 32);
41   code_clear = 1 << code_size;
42   code_end = code_clear + 1;
43   bits_left = 0;
44   code_store = 0;
45   next_in = nullptr;
46   avail_in = 0;
47   stack_size = 0;
48   code_first = 0;
49   ClearTable();
50 }
ClearTable()51 void CGifLZWDecoder::ClearTable() {
52   code_size_cur = code_size + 1;
53   code_next = code_end + 1;
54   code_old = (uint16_t)-1;
55   FXSYS_memset(code_table, 0, sizeof(tag_Table) * GIF_MAX_LZW_CODE);
56   FXSYS_memset(stack, 0, GIF_MAX_LZW_CODE);
57   for (uint16_t i = 0; i < code_clear; i++) {
58     code_table[i].suffix = (uint8_t)i;
59   }
60 }
DecodeString(uint16_t code)61 void CGifLZWDecoder::DecodeString(uint16_t code) {
62   stack_size = 0;
63   while (true) {
64     ASSERT(code <= code_next);
65     if (code < code_clear || code > code_next) {
66       break;
67     }
68     stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = code_table[code].suffix;
69     code = code_table[code].prefix;
70   }
71   stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = (uint8_t)code;
72   code_first = (uint8_t)code;
73 }
AddCode(uint16_t prefix_code,uint8_t append_char)74 void CGifLZWDecoder::AddCode(uint16_t prefix_code, uint8_t append_char) {
75   if (code_next == GIF_MAX_LZW_CODE) {
76     return;
77   }
78   code_table[code_next].prefix = prefix_code;
79   code_table[code_next].suffix = append_char;
80   if (++code_next < GIF_MAX_LZW_CODE) {
81     if (code_next >> code_size_cur) {
82       code_size_cur++;
83     }
84   }
85 }
Decode(uint8_t * des_buf,uint32_t & des_size)86 int32_t CGifLZWDecoder::Decode(uint8_t* des_buf, uint32_t& des_size) {
87   if (des_size == 0) {
88     return 3;
89   }
90   uint32_t i = 0;
91   if (stack_size != 0) {
92     if (des_size < stack_size) {
93       FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], des_size);
94       stack_size -= (uint16_t)des_size;
95       return 3;
96     }
97     FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], stack_size);
98     des_buf += stack_size;
99     i += stack_size;
100     stack_size = 0;
101   }
102   uint16_t code = 0;
103   while (i <= des_size && (avail_in > 0 || bits_left >= code_size_cur)) {
104     if (code_size_cur > 12) {
105       if (err_msg_ptr) {
106         FXSYS_strncpy(err_msg_ptr, "Code Length Out Of Range",
107                       GIF_MAX_ERROR_SIZE - 1);
108       }
109       return 0;
110     }
111     if (avail_in > 0) {
112       if (bits_left > 31) {
113         if (err_msg_ptr)
114           FXSYS_strncpy(err_msg_ptr, "Decode Error", GIF_MAX_ERROR_SIZE - 1);
115         return 0;
116       }
117       pdfium::base::CheckedNumeric<uint32_t> safe_code = *next_in++;
118       safe_code <<= bits_left;
119       safe_code |= code_store;
120       if (!safe_code.IsValid()) {
121         if (err_msg_ptr) {
122           FXSYS_strncpy(err_msg_ptr, "Code Store Out Of Range",
123                         GIF_MAX_ERROR_SIZE - 1);
124         }
125         return 0;
126       }
127       code_store = safe_code.ValueOrDie();
128       avail_in--;
129       bits_left += 8;
130     }
131     while (bits_left >= code_size_cur) {
132       code = (uint16_t)code_store & ((1 << code_size_cur) - 1);
133       code_store >>= code_size_cur;
134       bits_left -= code_size_cur;
135       if (code == code_clear) {
136         ClearTable();
137         continue;
138       } else if (code >= code_end) {
139         des_size = i;
140         return 1;
141       } else {
142         if (code_old != (uint16_t)-1) {
143           if (code_next < GIF_MAX_LZW_CODE) {
144             if (code == code_next) {
145               AddCode(code_old, code_first);
146               DecodeString(code);
147             } else if (code > code_next) {
148               if (err_msg_ptr) {
149                 FXSYS_strncpy(err_msg_ptr, "Decode Error, Out Of Range",
150                               GIF_MAX_ERROR_SIZE - 1);
151               }
152               return 0;
153             } else {
154               DecodeString(code);
155               uint8_t append_char = stack[GIF_MAX_LZW_CODE - stack_size];
156               AddCode(code_old, append_char);
157             }
158           }
159         } else {
160           DecodeString(code);
161         }
162         code_old = code;
163         if (i + stack_size > des_size) {
164           FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size],
165                        des_size - i);
166           stack_size -= (uint16_t)(des_size - i);
167           return 3;
168         }
169         FXSYS_memcpy(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size],
170                      stack_size);
171         des_buf += stack_size;
172         i += stack_size;
173         stack_size = 0;
174       }
175     }
176   }
177   if (avail_in == 0) {
178     des_size = i;
179     return 2;
180   }
181   return 0;
182 }
gif_grow_buf(uint8_t * & dst_buf,uint32_t & dst_len,uint32_t size)183 static bool gif_grow_buf(uint8_t*& dst_buf, uint32_t& dst_len, uint32_t size) {
184   if (dst_len < size) {
185     uint32_t len_org = dst_len;
186     while (dst_buf && dst_len < size) {
187       dst_len <<= 1;
188       // TODO(thestig): Probably should be a try-realloc here.
189       dst_buf = FX_Realloc(uint8_t, dst_buf, dst_len);
190     }
191     if (!dst_buf) {
192       dst_len = size;
193       dst_buf = FX_Realloc(uint8_t, dst_buf, dst_len);
194     }
195     FXSYS_memset(dst_buf + len_org, 0, dst_len - len_org);
196     return !!dst_buf;
197   }
198   return true;
199 }
gif_cut_index(uint8_t & val,uint32_t index,uint8_t index_bit,uint8_t index_bit_use,uint8_t bit_use)200 static inline void gif_cut_index(uint8_t& val,
201                                  uint32_t index,
202                                  uint8_t index_bit,
203                                  uint8_t index_bit_use,
204                                  uint8_t bit_use) {
205   uint32_t cut = ((1 << (index_bit - index_bit_use)) - 1) << index_bit_use;
206   val |= ((index & cut) >> index_bit_use) << bit_use;
207 }
gif_cut_buf(const uint8_t * buf,uint32_t & offset,uint8_t bit_cut,uint8_t & bit_offset,uint32_t & bit_num)208 static inline uint8_t gif_cut_buf(const uint8_t* buf,
209                                   uint32_t& offset,
210                                   uint8_t bit_cut,
211                                   uint8_t& bit_offset,
212                                   uint32_t& bit_num) {
213   if (bit_cut != 8) {
214     uint16_t index = 0;
215     index |= ((1 << bit_cut) - 1) << (7 - bit_offset);
216     uint8_t ret = ((index & buf[offset]) >> (7 - bit_offset));
217     bit_offset += bit_cut;
218     if (bit_offset >= 8) {
219       if (bit_offset > 8) {
220         ret |= ((index & (buf[offset + 1] << 8)) >> 8);
221       }
222       bit_offset -= 8;
223       offset++;
224     }
225     bit_num += bit_cut;
226     return ret;
227   }
228   bit_num += bit_cut;
229   return buf[offset++];
230 }
CGifLZWEncoder()231 CGifLZWEncoder::CGifLZWEncoder() {
232   FXSYS_memset(this, 0, sizeof(CGifLZWEncoder));
233 }
~CGifLZWEncoder()234 CGifLZWEncoder::~CGifLZWEncoder() {}
ClearTable()235 void CGifLZWEncoder::ClearTable() {
236   index_bit_cur = code_size + 1;
237   index_num = code_end + 1;
238   table_cur = code_end + 1;
239   for (uint16_t i = 0; i < GIF_MAX_LZW_CODE; i++) {
240     code_table[i].prefix = 0;
241     code_table[i].suffix = 0;
242   }
243 }
Start(uint8_t code_len,const uint8_t * src_buf,uint8_t * & dst_buf,uint32_t & offset)244 void CGifLZWEncoder::Start(uint8_t code_len,
245                            const uint8_t* src_buf,
246                            uint8_t*& dst_buf,
247                            uint32_t& offset) {
248   code_size = code_len + 1;
249   ASSERT(code_size < 32);
250   src_bit_cut = code_size;
251   if (code_len == 0) {
252     src_bit_cut = 1;
253     code_size = 2;
254   }
255   code_clear = 1 << code_size;
256   code_end = code_clear + 1;
257   dst_buf[offset++] = code_size;
258   bit_offset = 0;
259   ClearTable();
260   src_offset = 0;
261   src_bit_offset = 0;
262   src_bit_num = 0;
263   code_table[index_num].prefix = gif_cut_buf(src_buf, src_offset, src_bit_cut,
264                                              src_bit_offset, src_bit_num);
265   code_table[index_num].suffix = gif_cut_buf(src_buf, src_offset, src_bit_cut,
266                                              src_bit_offset, src_bit_num);
267 }
WriteBlock(uint8_t * & dst_buf,uint32_t & dst_len,uint32_t & offset)268 void CGifLZWEncoder::WriteBlock(uint8_t*& dst_buf,
269                                 uint32_t& dst_len,
270                                 uint32_t& offset) {
271   if (!gif_grow_buf(dst_buf, dst_len, offset + GIF_DATA_BLOCK + 1)) {
272     longjmp(jmp, 1);
273   }
274   dst_buf[offset++] = index_buf_len;
275   FXSYS_memcpy(&dst_buf[offset], index_buf, index_buf_len);
276   offset += index_buf_len;
277   FXSYS_memset(index_buf, 0, GIF_DATA_BLOCK);
278   index_buf_len = 0;
279 }
EncodeString(uint32_t index,uint8_t * & dst_buf,uint32_t & dst_len,uint32_t & offset)280 void CGifLZWEncoder::EncodeString(uint32_t index,
281                                   uint8_t*& dst_buf,
282                                   uint32_t& dst_len,
283                                   uint32_t& offset) {
284   uint8_t index_bit_use;
285   index_bit_use = 0;
286   if (index_buf_len == GIF_DATA_BLOCK) {
287     WriteBlock(dst_buf, dst_len, offset);
288   }
289   gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, index_bit_use,
290                 bit_offset);
291   if (index_bit_cur <= (8 - bit_offset)) {
292     bit_offset += index_bit_cur;
293   } else if (index_bit_cur <= (16 - bit_offset)) {
294     index_bit_use += (8 - bit_offset);
295     bit_offset = 0;
296     index_buf_len++;
297     if (index_buf_len == GIF_DATA_BLOCK) {
298       WriteBlock(dst_buf, dst_len, offset);
299     }
300     gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, index_bit_use,
301                   bit_offset);
302     bit_offset = index_bit_cur - index_bit_use;
303   } else {
304     index_bit_use += (8 - bit_offset);
305     bit_offset = 0;
306     index_buf_len++;
307     if (index_buf_len == GIF_DATA_BLOCK) {
308       WriteBlock(dst_buf, dst_len, offset);
309     }
310     gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, index_bit_use,
311                   bit_offset);
312     index_bit_use += 8;
313     bit_offset = 0;
314     index_buf_len++;
315     if (index_buf_len == GIF_DATA_BLOCK) {
316       WriteBlock(dst_buf, dst_len, offset);
317     }
318     gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, index_bit_use,
319                   bit_offset);
320     bit_offset = index_bit_cur - index_bit_use;
321   }
322   if (bit_offset == 8) {
323     bit_offset = 0;
324     index_buf_len++;
325     if (index_buf_len == GIF_DATA_BLOCK) {
326       WriteBlock(dst_buf, dst_len, offset);
327     }
328   }
329   if (index == code_end) {
330     index_buf_len++;
331     WriteBlock(dst_buf, dst_len, offset);
332   }
333   if (index_num++ >> index_bit_cur) {
334     index_bit_cur++;
335   }
336 }
Encode(const uint8_t * src_buf,uint32_t src_len,uint8_t * & dst_buf,uint32_t & dst_len,uint32_t & offset)337 bool CGifLZWEncoder::Encode(const uint8_t* src_buf,
338                             uint32_t src_len,
339                             uint8_t*& dst_buf,
340                             uint32_t& dst_len,
341                             uint32_t& offset) {
342   uint8_t suffix;
343   if (setjmp(jmp)) {
344     return false;
345   }
346   while (src_bit_num < src_len) {
347     if (!LookUpInTable(src_buf, src_offset, src_bit_offset)) {
348       EncodeString(code_table[index_num].prefix, dst_buf, dst_len, offset);
349       if (index_num == GIF_MAX_LZW_CODE) {
350         suffix = code_table[index_num - 1].suffix;
351         EncodeString(code_clear, dst_buf, dst_len, offset);
352         ClearTable();
353         code_table[index_num].prefix = suffix;
354         code_table[index_num].suffix = gif_cut_buf(
355             src_buf, src_offset, src_bit_cut, src_bit_offset, src_bit_num);
356       } else {
357         code_table[index_num].prefix = code_table[index_num - 1].suffix;
358         code_table[index_num].suffix = gif_cut_buf(
359             src_buf, src_offset, src_bit_cut, src_bit_offset, src_bit_num);
360       }
361     }
362   }
363   src_offset = 0;
364   src_bit_offset = 0;
365   src_bit_num = 0;
366   return true;
367 }
LookUpInTable(const uint8_t * buf,uint32_t & offset,uint8_t & out_bit_offset)368 bool CGifLZWEncoder::LookUpInTable(const uint8_t* buf,
369                                    uint32_t& offset,
370                                    uint8_t& out_bit_offset) {
371   for (uint16_t i = table_cur; i < index_num; i++) {
372     if (code_table[i].prefix == code_table[index_num].prefix &&
373         code_table[i].suffix == code_table[index_num].suffix) {
374       code_table[index_num].prefix = i;
375       code_table[index_num].suffix =
376           gif_cut_buf(buf, offset, src_bit_cut, out_bit_offset, src_bit_num);
377       table_cur = i;
378       return true;
379     }
380   }
381   table_cur = code_end + 1;
382   return false;
383 }
Finish(uint8_t * & dst_buf,uint32_t & dst_len,uint32_t & offset)384 void CGifLZWEncoder::Finish(uint8_t*& dst_buf,
385                             uint32_t& dst_len,
386                             uint32_t& offset) {
387   EncodeString(code_table[index_num].prefix, dst_buf, dst_len, offset);
388   EncodeString(code_end, dst_buf, dst_len, offset);
389   bit_offset = 0;
390   ClearTable();
391 }
gif_create_decompress()392 gif_decompress_struct_p gif_create_decompress() {
393   gif_decompress_struct_p gif_ptr = FX_Alloc(gif_decompress_struct, 1);
394   FXSYS_memset(gif_ptr, 0, sizeof(gif_decompress_struct));
395   gif_ptr->decode_status = GIF_D_STATUS_SIG;
396   gif_ptr->img_ptr_arr_ptr = new std::vector<GifImage*>;
397   gif_ptr->cmt_data_ptr = new CFX_ByteString;
398   gif_ptr->pt_ptr_arr_ptr = new std::vector<GifPlainText*>;
399   return gif_ptr;
400 }
gif_destroy_decompress(gif_decompress_struct_pp gif_ptr_ptr)401 void gif_destroy_decompress(gif_decompress_struct_pp gif_ptr_ptr) {
402   if (!gif_ptr_ptr || !*gif_ptr_ptr)
403     return;
404 
405   gif_decompress_struct_p gif_ptr = *gif_ptr_ptr;
406   *gif_ptr_ptr = nullptr;
407   FX_Free(gif_ptr->global_pal_ptr);
408   delete gif_ptr->img_decoder_ptr;
409   if (gif_ptr->img_ptr_arr_ptr) {
410     size_t size_img_arr = gif_ptr->img_ptr_arr_ptr->size();
411     for (size_t i = 0; i < size_img_arr; i++) {
412       GifImage* p = (*gif_ptr->img_ptr_arr_ptr)[i];
413       FX_Free(p->image_info_ptr);
414       FX_Free(p->image_gce_ptr);
415       FX_Free(p->image_row_buf);
416       if (p->local_pal_ptr && p->local_pal_ptr != gif_ptr->global_pal_ptr) {
417         FX_Free(p->local_pal_ptr);
418       }
419       FX_Free(p);
420     }
421     gif_ptr->img_ptr_arr_ptr->clear();
422     delete gif_ptr->img_ptr_arr_ptr;
423   }
424   delete gif_ptr->cmt_data_ptr;
425   FX_Free(gif_ptr->gce_ptr);
426   if (gif_ptr->pt_ptr_arr_ptr) {
427     size_t size_pt_arr = gif_ptr->pt_ptr_arr_ptr->size();
428     for (size_t i = 0; i < size_pt_arr; i++) {
429       GifPlainText* p = (*gif_ptr->pt_ptr_arr_ptr)[i];
430       FX_Free(p->gce_ptr);
431       FX_Free(p->pte_ptr);
432       delete p->string_ptr;
433       FX_Free(p);
434     }
435     gif_ptr->pt_ptr_arr_ptr->clear();
436     delete gif_ptr->pt_ptr_arr_ptr;
437   }
438   FX_Free(gif_ptr);
439 }
gif_create_compress()440 gif_compress_struct_p gif_create_compress() {
441   gif_compress_struct_p gif_ptr = FX_Alloc(gif_compress_struct, 1);
442   FXSYS_memset(gif_ptr, 0, sizeof(gif_compress_struct));
443   gif_ptr->img_encoder_ptr = new CGifLZWEncoder;
444   gif_ptr->header_ptr = FX_Alloc(GifHeader, 1);
445   if (!gif_ptr->header_ptr) {
446     delete (gif_ptr->img_encoder_ptr);
447     FX_Free(gif_ptr);
448     return nullptr;
449   }
450   FXSYS_memcpy(gif_ptr->header_ptr->signature, GIF_SIGNATURE, 3);
451   FXSYS_memcpy(gif_ptr->header_ptr->version, "89a", 3);
452   gif_ptr->lsd_ptr = FX_Alloc(GifLSD, 1);
453   if (!gif_ptr->lsd_ptr) {
454     FX_Free(gif_ptr->header_ptr);
455     delete (gif_ptr->img_encoder_ptr);
456     FX_Free(gif_ptr);
457     return nullptr;
458   }
459   FXSYS_memset(gif_ptr->lsd_ptr, 0, sizeof(GifLSD));
460   gif_ptr->image_info_ptr = FX_Alloc(GifImageInfo, 1);
461   if (!gif_ptr->image_info_ptr) {
462     FX_Free(gif_ptr->lsd_ptr);
463     FX_Free(gif_ptr->header_ptr);
464     delete (gif_ptr->img_encoder_ptr);
465     FX_Free(gif_ptr);
466     return nullptr;
467   }
468   FXSYS_memset(gif_ptr->image_info_ptr, 0, sizeof(GifImageInfo));
469   gif_ptr->gce_ptr = FX_Alloc(GifGCE, 1);
470   if (!gif_ptr->gce_ptr) {
471     FX_Free(gif_ptr->image_info_ptr);
472     FX_Free(gif_ptr->lsd_ptr);
473     FX_Free(gif_ptr->header_ptr);
474     delete (gif_ptr->img_encoder_ptr);
475     FX_Free(gif_ptr);
476     return nullptr;
477   }
478   gif_ptr->pte_ptr = FX_Alloc(GifPTE, 1);
479   if (!gif_ptr->pte_ptr) {
480     FX_Free(gif_ptr->gce_ptr);
481     FX_Free(gif_ptr->image_info_ptr);
482     FX_Free(gif_ptr->lsd_ptr);
483     FX_Free(gif_ptr->header_ptr);
484     delete (gif_ptr->img_encoder_ptr);
485     FX_Free(gif_ptr);
486     return nullptr;
487   }
488   FXSYS_memset(gif_ptr->pte_ptr, 0, sizeof(GifPTE));
489   gif_ptr->pte_ptr->block_size = 12;
490   return gif_ptr;
491 }
gif_destroy_compress(gif_compress_struct_pp gif_ptr_ptr)492 void gif_destroy_compress(gif_compress_struct_pp gif_ptr_ptr) {
493   if (!gif_ptr_ptr || !*gif_ptr_ptr)
494     return;
495 
496   gif_compress_struct_p gif_ptr = *gif_ptr_ptr;
497   *gif_ptr_ptr = nullptr;
498   FX_Free(gif_ptr->header_ptr);
499   FX_Free(gif_ptr->lsd_ptr);
500   FX_Free(gif_ptr->global_pal);
501   FX_Free(gif_ptr->image_info_ptr);
502   FX_Free(gif_ptr->local_pal);
503   delete gif_ptr->img_encoder_ptr;
504   FX_Free(gif_ptr->gce_ptr);
505   FX_Free(gif_ptr->cmt_data_ptr);
506   FX_Free(gif_ptr->pte_ptr);
507   FX_Free(gif_ptr);
508 }
gif_error(gif_decompress_struct_p gif_ptr,const FX_CHAR * err_msg)509 void gif_error(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg) {
510   if (gif_ptr && gif_ptr->gif_error_fn) {
511     gif_ptr->gif_error_fn(gif_ptr, err_msg);
512   }
513 }
gif_warn(gif_decompress_struct_p gif_ptr,const FX_CHAR * err_msg)514 void gif_warn(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg) {}
gif_read_header(gif_decompress_struct_p gif_ptr)515 int32_t gif_read_header(gif_decompress_struct_p gif_ptr) {
516   if (!gif_ptr)
517     return 0;
518 
519   uint32_t skip_size_org = gif_ptr->skip_size;
520   ASSERT(sizeof(GifHeader) == 6);
521   GifHeader* gif_header_ptr = nullptr;
522   if (!gif_read_data(gif_ptr, (uint8_t**)&gif_header_ptr, 6))
523     return 2;
524 
525   if (FXSYS_strncmp(gif_header_ptr->signature, GIF_SIGNATURE, 3) != 0 ||
526       gif_header_ptr->version[0] != '8' || gif_header_ptr->version[2] != 'a') {
527     gif_error(gif_ptr, "Not A Gif Image");
528     return 0;
529   }
530   ASSERT(sizeof(GifLSD) == 7);
531   GifLSD* gif_lsd_ptr = nullptr;
532   if (!gif_read_data(gif_ptr, (uint8_t**)&gif_lsd_ptr, 7)) {
533     gif_ptr->skip_size = skip_size_org;
534     return 2;
535   }
536   if (((GifGF*)&gif_lsd_ptr->global_flag)->global_pal) {
537     gif_ptr->global_pal_num = 2
538                               << ((GifGF*)&gif_lsd_ptr->global_flag)->pal_bits;
539     ASSERT(sizeof(GifPalette) == 3);
540     int32_t global_pal_size = gif_ptr->global_pal_num * 3;
541     uint8_t* global_pal_ptr = nullptr;
542     if (!gif_read_data(gif_ptr, &global_pal_ptr, global_pal_size)) {
543       gif_ptr->skip_size = skip_size_org;
544       return 2;
545     }
546     gif_ptr->global_sort_flag = ((GifGF*)&gif_lsd_ptr->global_flag)->sort_flag;
547     gif_ptr->global_color_resolution =
548         ((GifGF*)&gif_lsd_ptr->global_flag)->color_resolution;
549     FX_Free(gif_ptr->global_pal_ptr);
550     gif_ptr->global_pal_ptr = (GifPalette*)FX_Alloc(uint8_t, global_pal_size);
551     FXSYS_memcpy(gif_ptr->global_pal_ptr, global_pal_ptr, global_pal_size);
552   }
553   gif_ptr->width = (int)GetWord_LSBFirst((uint8_t*)&gif_lsd_ptr->width);
554   gif_ptr->height = (int)GetWord_LSBFirst((uint8_t*)&gif_lsd_ptr->height);
555   gif_ptr->bc_index = gif_lsd_ptr->bc_index;
556   gif_ptr->pixel_aspect = gif_lsd_ptr->pixel_aspect;
557   return 1;
558 }
gif_get_frame(gif_decompress_struct_p gif_ptr)559 int32_t gif_get_frame(gif_decompress_struct_p gif_ptr) {
560   if (!gif_ptr)
561     return 0;
562 
563   int32_t ret = 1;
564   while (true) {
565     switch (gif_ptr->decode_status) {
566       case GIF_D_STATUS_TAIL:
567         return 1;
568       case GIF_D_STATUS_SIG: {
569         uint8_t* sig_ptr = nullptr;
570         if (!gif_read_data(gif_ptr, &sig_ptr, 1))
571           return 2;
572 
573         switch (*sig_ptr) {
574           case GIF_SIG_EXTENSION:
575             gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT);
576             continue;
577           case GIF_SIG_IMAGE:
578             gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_INFO);
579             continue;
580           case GIF_SIG_TRAILER:
581             gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL);
582             return 1;
583           default:
584             if (gif_ptr->avail_in) {
585               gif_warn(gif_ptr, "The Gif File has non_standard Tag!");
586               gif_save_decoding_status(gif_ptr, GIF_D_STATUS_SIG);
587               continue;
588             }
589             gif_warn(gif_ptr, "The Gif File Doesn't have Trailer Tag!");
590             return 1;
591         }
592       }
593       case GIF_D_STATUS_EXT: {
594         uint8_t* ext_ptr = nullptr;
595         if (!gif_read_data(gif_ptr, &ext_ptr, 1))
596           return 2;
597 
598         switch (*ext_ptr) {
599           case GIF_BLOCK_CE:
600             gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_CE);
601             continue;
602           case GIF_BLOCK_GCE:
603             gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_GCE);
604             continue;
605           case GIF_BLOCK_PTE:
606             gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_PTE);
607             continue;
608           default: {
609             int32_t status = GIF_D_STATUS_EXT_UNE;
610             if (*ext_ptr == GIF_BLOCK_PTE) {
611               status = GIF_D_STATUS_EXT_PTE;
612             }
613             gif_save_decoding_status(gif_ptr, status);
614             continue;
615           }
616         }
617       }
618       case GIF_D_STATUS_IMG_INFO: {
619         ret = gif_decode_image_info(gif_ptr);
620         if (ret != 1) {
621           return ret;
622         }
623         continue;
624       }
625       case GIF_D_STATUS_IMG_DATA: {
626         uint8_t* data_size_ptr = nullptr;
627         uint8_t* data_ptr = nullptr;
628         uint32_t skip_size_org = gif_ptr->skip_size;
629         if (!gif_read_data(gif_ptr, &data_size_ptr, 1))
630           return 2;
631 
632         while (*data_size_ptr != GIF_BLOCK_TERMINAL) {
633           if (!gif_read_data(gif_ptr, &data_ptr, *data_size_ptr)) {
634             gif_ptr->skip_size = skip_size_org;
635             return 2;
636           }
637           gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA);
638           skip_size_org = gif_ptr->skip_size;
639           if (!gif_read_data(gif_ptr, &data_size_ptr, 1))
640             return 2;
641         }
642         gif_save_decoding_status(gif_ptr, GIF_D_STATUS_SIG);
643         continue;
644       }
645       default: {
646         ret = gif_decode_extension(gif_ptr);
647         if (ret != 1) {
648           return ret;
649         }
650         continue;
651       }
652     }
653   }
654   return 1;
655 }
gif_takeover_gce_ptr(gif_decompress_struct_p gif_ptr,GifGCE ** gce_ptr_ptr)656 void gif_takeover_gce_ptr(gif_decompress_struct_p gif_ptr,
657                           GifGCE** gce_ptr_ptr) {
658   *gce_ptr_ptr = nullptr;
659   if (gif_ptr->gce_ptr && gce_ptr_ptr) {
660     *gce_ptr_ptr = gif_ptr->gce_ptr;
661     gif_ptr->gce_ptr = nullptr;
662   }
663 }
gif_decode_extension(gif_decompress_struct_p gif_ptr)664 int32_t gif_decode_extension(gif_decompress_struct_p gif_ptr) {
665   uint8_t* data_size_ptr = nullptr;
666   uint8_t* data_ptr = nullptr;
667   uint32_t skip_size_org = gif_ptr->skip_size;
668   switch (gif_ptr->decode_status) {
669     case GIF_D_STATUS_EXT_CE: {
670       if (!gif_read_data(gif_ptr, &data_size_ptr, 1)) {
671         gif_ptr->skip_size = skip_size_org;
672         return 2;
673       }
674       gif_ptr->cmt_data_ptr->clear();
675       while (*data_size_ptr != GIF_BLOCK_TERMINAL) {
676         uint8_t data_size = *data_size_ptr;
677         if (!gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) ||
678             !gif_read_data(gif_ptr, &data_size_ptr, 1)) {
679           gif_ptr->skip_size = skip_size_org;
680           return 2;
681         }
682         *(gif_ptr->cmt_data_ptr) +=
683             CFX_ByteString((const FX_CHAR*)data_ptr, data_size);
684       }
685     } break;
686     case GIF_D_STATUS_EXT_PTE: {
687       ASSERT(sizeof(GifPTE) == 13);
688       GifPTE* gif_pte_ptr = nullptr;
689       if (!gif_read_data(gif_ptr, (uint8_t**)&gif_pte_ptr, 13)) {
690         return 2;
691       }
692       GifPlainText* gif_pt_ptr = FX_Alloc(GifPlainText, 1);
693       FXSYS_memset(gif_pt_ptr, 0, sizeof(GifPlainText));
694       gif_takeover_gce_ptr(gif_ptr, &gif_pt_ptr->gce_ptr);
695       gif_pt_ptr->pte_ptr = FX_Alloc(GifPTE, 1);
696       gif_pt_ptr->string_ptr = new CFX_ByteString;
697       gif_pt_ptr->pte_ptr->block_size = gif_pte_ptr->block_size;
698       gif_pt_ptr->pte_ptr->grid_left =
699           GetWord_LSBFirst((uint8_t*)&gif_pte_ptr->grid_left);
700       gif_pt_ptr->pte_ptr->grid_top =
701           GetWord_LSBFirst((uint8_t*)&gif_pte_ptr->grid_top);
702       gif_pt_ptr->pte_ptr->grid_width =
703           GetWord_LSBFirst((uint8_t*)&gif_pte_ptr->grid_width);
704       gif_pt_ptr->pte_ptr->grid_height =
705           GetWord_LSBFirst((uint8_t*)&gif_pte_ptr->grid_height);
706       gif_pt_ptr->pte_ptr->char_width = gif_pte_ptr->char_width;
707       gif_pt_ptr->pte_ptr->char_height = gif_pte_ptr->char_height;
708       gif_pt_ptr->pte_ptr->fc_index = gif_pte_ptr->fc_index;
709       gif_pt_ptr->pte_ptr->bc_index = gif_pte_ptr->bc_index;
710       if (!gif_read_data(gif_ptr, &data_size_ptr, 1)) {
711         gif_ptr->skip_size = skip_size_org;
712         if (gif_pt_ptr) {
713           FX_Free(gif_pt_ptr->gce_ptr);
714           FX_Free(gif_pt_ptr->pte_ptr);
715           delete gif_pt_ptr->string_ptr;
716           FX_Free(gif_pt_ptr);
717         }
718         return 2;
719       }
720       while (*data_size_ptr != GIF_BLOCK_TERMINAL) {
721         uint8_t data_size = *data_size_ptr;
722         if (!gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) ||
723             !gif_read_data(gif_ptr, &data_size_ptr, 1)) {
724           gif_ptr->skip_size = skip_size_org;
725           if (gif_pt_ptr) {
726             FX_Free(gif_pt_ptr->gce_ptr);
727             FX_Free(gif_pt_ptr->pte_ptr);
728             delete gif_pt_ptr->string_ptr;
729             FX_Free(gif_pt_ptr);
730           }
731           return 2;
732         }
733         *(gif_pt_ptr->string_ptr) +=
734             CFX_ByteString((const FX_CHAR*)data_ptr, data_size);
735       }
736       gif_ptr->pt_ptr_arr_ptr->push_back(gif_pt_ptr);
737     } break;
738     case GIF_D_STATUS_EXT_GCE: {
739       ASSERT(sizeof(GifGCE) == 5);
740       GifGCE* gif_gce_ptr = nullptr;
741       if (!gif_read_data(gif_ptr, (uint8_t**)&gif_gce_ptr, 6))
742         return 2;
743 
744       if (!gif_ptr->gce_ptr)
745         gif_ptr->gce_ptr = FX_Alloc(GifGCE, 1);
746       gif_ptr->gce_ptr->block_size = gif_gce_ptr->block_size;
747       gif_ptr->gce_ptr->gce_flag = gif_gce_ptr->gce_flag;
748       gif_ptr->gce_ptr->delay_time =
749           GetWord_LSBFirst((uint8_t*)&gif_gce_ptr->delay_time);
750       gif_ptr->gce_ptr->trans_index = gif_gce_ptr->trans_index;
751     } break;
752     default: {
753       if (gif_ptr->decode_status == GIF_D_STATUS_EXT_PTE) {
754         FX_Free(gif_ptr->gce_ptr);
755         gif_ptr->gce_ptr = nullptr;
756       }
757       if (!gif_read_data(gif_ptr, &data_size_ptr, 1))
758         return 2;
759 
760       while (*data_size_ptr != GIF_BLOCK_TERMINAL) {
761         if (!gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) ||
762             !gif_read_data(gif_ptr, &data_size_ptr, 1)) {
763           gif_ptr->skip_size = skip_size_org;
764           return 2;
765         }
766       }
767     }
768   }
769   gif_save_decoding_status(gif_ptr, GIF_D_STATUS_SIG);
770   return 1;
771 }
gif_decode_image_info(gif_decompress_struct_p gif_ptr)772 int32_t gif_decode_image_info(gif_decompress_struct_p gif_ptr) {
773   if (gif_ptr->width == 0 || gif_ptr->height == 0) {
774     gif_error(gif_ptr, "No Image Header Info");
775     return 0;
776   }
777   uint32_t skip_size_org = gif_ptr->skip_size;
778   ASSERT(sizeof(GifImageInfo) == 9);
779   GifImageInfo* gif_img_info_ptr = nullptr;
780   if (!gif_read_data(gif_ptr, (uint8_t**)&gif_img_info_ptr, 9))
781     return 2;
782 
783   GifImage* gif_image_ptr = FX_Alloc(GifImage, 1);
784   FXSYS_memset(gif_image_ptr, 0, sizeof(GifImage));
785   gif_image_ptr->image_info_ptr = FX_Alloc(GifImageInfo, 1);
786   gif_image_ptr->image_info_ptr->left =
787       GetWord_LSBFirst((uint8_t*)&gif_img_info_ptr->left);
788   gif_image_ptr->image_info_ptr->top =
789       GetWord_LSBFirst((uint8_t*)&gif_img_info_ptr->top);
790   gif_image_ptr->image_info_ptr->width =
791       GetWord_LSBFirst((uint8_t*)&gif_img_info_ptr->width);
792   gif_image_ptr->image_info_ptr->height =
793       GetWord_LSBFirst((uint8_t*)&gif_img_info_ptr->height);
794   gif_image_ptr->image_info_ptr->local_flag = gif_img_info_ptr->local_flag;
795   if (gif_image_ptr->image_info_ptr->left +
796               gif_image_ptr->image_info_ptr->width >
797           gif_ptr->width ||
798       gif_image_ptr->image_info_ptr->top +
799               gif_image_ptr->image_info_ptr->height >
800           gif_ptr->height) {
801     FX_Free(gif_image_ptr->image_info_ptr);
802     FX_Free(gif_image_ptr->image_row_buf);
803     FX_Free(gif_image_ptr);
804     gif_error(gif_ptr, "Image Data Out Of LSD, The File May Be Corrupt");
805     return 0;
806   }
807   GifLF* gif_img_info_lf_ptr = (GifLF*)&gif_img_info_ptr->local_flag;
808   if (gif_img_info_lf_ptr->local_pal) {
809     ASSERT(sizeof(GifPalette) == 3);
810     int32_t loc_pal_size = (2 << gif_img_info_lf_ptr->pal_bits) * 3;
811     uint8_t* loc_pal_ptr = nullptr;
812     if (!gif_read_data(gif_ptr, &loc_pal_ptr, loc_pal_size)) {
813       gif_ptr->skip_size = skip_size_org;
814       FX_Free(gif_image_ptr->image_info_ptr);
815       FX_Free(gif_image_ptr->image_row_buf);
816       FX_Free(gif_image_ptr);
817       return 2;
818     }
819     gif_image_ptr->local_pal_ptr =
820         (GifPalette*)gif_ptr->gif_ask_buf_for_pal_fn(gif_ptr, loc_pal_size);
821     if (gif_image_ptr->local_pal_ptr) {
822       FXSYS_memcpy((uint8_t*)gif_image_ptr->local_pal_ptr, loc_pal_ptr,
823                    loc_pal_size);
824     }
825   }
826   uint8_t* code_size_ptr = nullptr;
827   if (!gif_read_data(gif_ptr, &code_size_ptr, 1)) {
828     gif_ptr->skip_size = skip_size_org;
829     FX_Free(gif_image_ptr->image_info_ptr);
830     FX_Free(gif_image_ptr->local_pal_ptr);
831     FX_Free(gif_image_ptr->image_row_buf);
832     FX_Free(gif_image_ptr);
833     return 2;
834   }
835   gif_image_ptr->image_code_size = *code_size_ptr;
836   gif_ptr->gif_record_current_position_fn(gif_ptr,
837                                           &gif_image_ptr->image_data_pos);
838   gif_image_ptr->image_data_pos += gif_ptr->skip_size;
839   gif_takeover_gce_ptr(gif_ptr, &gif_image_ptr->image_gce_ptr);
840   gif_ptr->img_ptr_arr_ptr->push_back(gif_image_ptr);
841   gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA);
842   return 1;
843 }
gif_load_frame(gif_decompress_struct_p gif_ptr,int32_t frame_num)844 int32_t gif_load_frame(gif_decompress_struct_p gif_ptr, int32_t frame_num) {
845   if (!gif_ptr || frame_num < 0 ||
846       frame_num >= pdfium::CollectionSize<int>(*gif_ptr->img_ptr_arr_ptr)) {
847     return 0;
848   }
849   uint8_t* data_size_ptr = nullptr;
850   uint8_t* data_ptr = nullptr;
851   uint32_t skip_size_org = gif_ptr->skip_size;
852   GifImage* gif_image_ptr = (*gif_ptr->img_ptr_arr_ptr)[frame_num];
853   uint32_t gif_img_row_bytes = gif_image_ptr->image_info_ptr->width;
854   if (gif_img_row_bytes == 0) {
855     gif_error(gif_ptr, "Error Invalid Number of Row Bytes");
856     return 0;
857   }
858   if (gif_ptr->decode_status == GIF_D_STATUS_TAIL) {
859     if (gif_image_ptr->image_row_buf) {
860       FX_Free(gif_image_ptr->image_row_buf);
861       gif_image_ptr->image_row_buf = nullptr;
862     }
863     gif_image_ptr->image_row_buf = FX_Alloc(uint8_t, gif_img_row_bytes);
864     GifGCE* gif_img_gce_ptr = gif_image_ptr->image_gce_ptr;
865     int32_t loc_pal_num =
866         ((GifLF*)&gif_image_ptr->image_info_ptr->local_flag)->local_pal
867             ? (2 << ((GifLF*)&gif_image_ptr->image_info_ptr->local_flag)
868                         ->pal_bits)
869             : 0;
870     gif_ptr->avail_in = 0;
871     if (!gif_img_gce_ptr) {
872       bool bRes = gif_ptr->gif_get_record_position_fn(
873           gif_ptr, gif_image_ptr->image_data_pos,
874           gif_image_ptr->image_info_ptr->left,
875           gif_image_ptr->image_info_ptr->top,
876           gif_image_ptr->image_info_ptr->width,
877           gif_image_ptr->image_info_ptr->height, loc_pal_num,
878           gif_image_ptr->local_pal_ptr, 0, 0, -1, 0,
879           (bool)((GifLF*)&gif_image_ptr->image_info_ptr->local_flag)
880               ->interlace);
881       if (!bRes) {
882         FX_Free(gif_image_ptr->image_row_buf);
883         gif_image_ptr->image_row_buf = nullptr;
884         gif_error(gif_ptr, "Error Read Record Position Data");
885         return 0;
886       }
887     } else {
888       bool bRes = gif_ptr->gif_get_record_position_fn(
889           gif_ptr, gif_image_ptr->image_data_pos,
890           gif_image_ptr->image_info_ptr->left,
891           gif_image_ptr->image_info_ptr->top,
892           gif_image_ptr->image_info_ptr->width,
893           gif_image_ptr->image_info_ptr->height, loc_pal_num,
894           gif_image_ptr->local_pal_ptr,
895           (int32_t)gif_image_ptr->image_gce_ptr->delay_time,
896           (bool)((GifCEF*)&gif_image_ptr->image_gce_ptr->gce_flag)->user_input,
897           ((GifCEF*)&gif_image_ptr->image_gce_ptr->gce_flag)->transparency
898               ? (int32_t)gif_image_ptr->image_gce_ptr->trans_index
899               : -1,
900           (int32_t)((GifCEF*)&gif_image_ptr->image_gce_ptr->gce_flag)
901               ->disposal_method,
902           (bool)((GifLF*)&gif_image_ptr->image_info_ptr->local_flag)
903               ->interlace);
904       if (!bRes) {
905         FX_Free(gif_image_ptr->image_row_buf);
906         gif_image_ptr->image_row_buf = nullptr;
907         gif_error(gif_ptr, "Error Read Record Position Data");
908         return 0;
909       }
910     }
911     if (gif_image_ptr->image_code_size >= 32) {
912       FX_Free(gif_image_ptr->image_row_buf);
913       gif_image_ptr->image_row_buf = nullptr;
914       gif_error(gif_ptr, "Error Invalid Code Size");
915       return 0;
916     }
917     if (!gif_ptr->img_decoder_ptr)
918       gif_ptr->img_decoder_ptr = new CGifLZWDecoder(gif_ptr->err_ptr);
919     gif_ptr->img_decoder_ptr->InitTable(gif_image_ptr->image_code_size);
920     gif_ptr->img_row_offset = 0;
921     gif_ptr->img_row_avail_size = 0;
922     gif_ptr->img_pass_num = 0;
923     gif_image_ptr->image_row_num = 0;
924     gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA);
925   }
926   CGifLZWDecoder* img_decoder_ptr = gif_ptr->img_decoder_ptr;
927   if (gif_ptr->decode_status == GIF_D_STATUS_IMG_DATA) {
928     if (!gif_read_data(gif_ptr, &data_size_ptr, 1))
929       return 2;
930 
931     if (*data_size_ptr != GIF_BLOCK_TERMINAL) {
932       if (!gif_read_data(gif_ptr, &data_ptr, *data_size_ptr)) {
933         gif_ptr->skip_size = skip_size_org;
934         return 2;
935       }
936       img_decoder_ptr->Input(data_ptr, *data_size_ptr);
937       gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA);
938       gif_ptr->img_row_offset += gif_ptr->img_row_avail_size;
939       gif_ptr->img_row_avail_size = gif_img_row_bytes - gif_ptr->img_row_offset;
940       int32_t ret = img_decoder_ptr->Decode(
941           gif_image_ptr->image_row_buf + gif_ptr->img_row_offset,
942           gif_ptr->img_row_avail_size);
943       if (ret == 0) {
944         gif_decoding_failure_at_tail_cleanup(gif_ptr, gif_image_ptr);
945         return 0;
946       }
947       while (ret != 0) {
948         if (ret == 1) {
949           gif_ptr->gif_get_row_fn(gif_ptr, gif_image_ptr->image_row_num,
950                                   gif_image_ptr->image_row_buf);
951           FX_Free(gif_image_ptr->image_row_buf);
952           gif_image_ptr->image_row_buf = nullptr;
953           gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL);
954           return 1;
955         }
956         if (ret == 2) {
957           ASSERT(img_decoder_ptr->GetAvailInput() == 0);
958           skip_size_org = gif_ptr->skip_size;
959           if (!gif_read_data(gif_ptr, &data_size_ptr, 1))
960             return 2;
961 
962           if (*data_size_ptr != GIF_BLOCK_TERMINAL) {
963             if (!gif_read_data(gif_ptr, &data_ptr, *data_size_ptr)) {
964               gif_ptr->skip_size = skip_size_org;
965               return 2;
966             }
967             img_decoder_ptr->Input(data_ptr, *data_size_ptr);
968             gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA);
969             gif_ptr->img_row_offset += gif_ptr->img_row_avail_size;
970             gif_ptr->img_row_avail_size =
971                 gif_img_row_bytes - gif_ptr->img_row_offset;
972             ret = img_decoder_ptr->Decode(
973                 gif_image_ptr->image_row_buf + gif_ptr->img_row_offset,
974                 gif_ptr->img_row_avail_size);
975           }
976         }
977         if (ret == 3) {
978           if (((GifLF*)&gif_image_ptr->image_info_ptr->local_flag)->interlace) {
979             gif_ptr->gif_get_row_fn(gif_ptr, gif_image_ptr->image_row_num,
980                                     gif_image_ptr->image_row_buf);
981             gif_image_ptr->image_row_num +=
982                 s_gif_interlace_step[gif_ptr->img_pass_num];
983             if (gif_image_ptr->image_row_num >=
984                 (int32_t)gif_image_ptr->image_info_ptr->height) {
985               gif_ptr->img_pass_num++;
986               if (gif_ptr->img_pass_num == FX_ArraySize(s_gif_interlace_step)) {
987                 gif_decoding_failure_at_tail_cleanup(gif_ptr, gif_image_ptr);
988                 return 0;
989               }
990               gif_image_ptr->image_row_num =
991                   s_gif_interlace_step[gif_ptr->img_pass_num] / 2;
992             }
993           } else {
994             gif_ptr->gif_get_row_fn(gif_ptr, gif_image_ptr->image_row_num++,
995                                     gif_image_ptr->image_row_buf);
996           }
997           gif_ptr->img_row_offset = 0;
998           gif_ptr->img_row_avail_size = gif_img_row_bytes;
999           ret = img_decoder_ptr->Decode(
1000               gif_image_ptr->image_row_buf + gif_ptr->img_row_offset,
1001               gif_ptr->img_row_avail_size);
1002         }
1003         if (ret == 0) {
1004           gif_decoding_failure_at_tail_cleanup(gif_ptr, gif_image_ptr);
1005           return 0;
1006         }
1007       }
1008     }
1009     gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL);
1010   }
1011   gif_error(gif_ptr, "Decode Image Data Error");
1012   return 0;
1013 }
gif_decoding_failure_at_tail_cleanup(gif_decompress_struct_p gif_ptr,GifImage * gif_image_ptr)1014 void gif_decoding_failure_at_tail_cleanup(gif_decompress_struct_p gif_ptr,
1015                                           GifImage* gif_image_ptr) {
1016   FX_Free(gif_image_ptr->image_row_buf);
1017   gif_image_ptr->image_row_buf = nullptr;
1018   gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL);
1019   gif_error(gif_ptr, "Decode Image Data Error");
1020 }
gif_save_decoding_status(gif_decompress_struct_p gif_ptr,int32_t status)1021 void gif_save_decoding_status(gif_decompress_struct_p gif_ptr, int32_t status) {
1022   gif_ptr->decode_status = status;
1023   gif_ptr->next_in += gif_ptr->skip_size;
1024   gif_ptr->avail_in -= gif_ptr->skip_size;
1025   gif_ptr->skip_size = 0;
1026 }
gif_read_data(gif_decompress_struct_p gif_ptr,uint8_t ** des_buf_pp,uint32_t data_size)1027 uint8_t* gif_read_data(gif_decompress_struct_p gif_ptr,
1028                        uint8_t** des_buf_pp,
1029                        uint32_t data_size) {
1030   if (!gif_ptr || gif_ptr->avail_in < gif_ptr->skip_size + data_size)
1031     return nullptr;
1032 
1033   *des_buf_pp = gif_ptr->next_in + gif_ptr->skip_size;
1034   gif_ptr->skip_size += data_size;
1035   return *des_buf_pp;
1036 }
gif_input_buffer(gif_decompress_struct_p gif_ptr,uint8_t * src_buf,uint32_t src_size)1037 void gif_input_buffer(gif_decompress_struct_p gif_ptr,
1038                       uint8_t* src_buf,
1039                       uint32_t src_size) {
1040   gif_ptr->next_in = src_buf;
1041   gif_ptr->avail_in = src_size;
1042   gif_ptr->skip_size = 0;
1043 }
gif_get_avail_input(gif_decompress_struct_p gif_ptr,uint8_t ** avail_buf_ptr)1044 uint32_t gif_get_avail_input(gif_decompress_struct_p gif_ptr,
1045                              uint8_t** avail_buf_ptr) {
1046   if (avail_buf_ptr) {
1047     *avail_buf_ptr = nullptr;
1048     if (gif_ptr->avail_in > 0) {
1049       *avail_buf_ptr = gif_ptr->next_in;
1050     }
1051   }
1052   return gif_ptr->avail_in;
1053 }
gif_get_frame_num(gif_decompress_struct_p gif_ptr)1054 int32_t gif_get_frame_num(gif_decompress_struct_p gif_ptr) {
1055   return pdfium::CollectionSize<int32_t>(*gif_ptr->img_ptr_arr_ptr);
1056 }
gif_write_header(gif_compress_struct_p gif_ptr,uint8_t * & dst_buf,uint32_t & dst_len)1057 static bool gif_write_header(gif_compress_struct_p gif_ptr,
1058                              uint8_t*& dst_buf,
1059                              uint32_t& dst_len) {
1060   if (gif_ptr->cur_offset) {
1061     return true;
1062   }
1063   dst_len = sizeof(GifHeader) + sizeof(GifLSD) + sizeof(GifGF);
1064   dst_buf = FX_TryAlloc(uint8_t, dst_len);
1065   if (!dst_buf)
1066     return false;
1067 
1068   FXSYS_memset(dst_buf, 0, dst_len);
1069   FXSYS_memcpy(dst_buf, gif_ptr->header_ptr, sizeof(GifHeader));
1070   gif_ptr->cur_offset += sizeof(GifHeader);
1071   SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->lsd_ptr->width);
1072   gif_ptr->cur_offset += 2;
1073   SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->lsd_ptr->height);
1074   gif_ptr->cur_offset += 2;
1075   dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->global_flag;
1076   dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->bc_index;
1077   dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->pixel_aspect;
1078   if (gif_ptr->global_pal) {
1079     uint16_t size = sizeof(GifPalette) * gif_ptr->gpal_num;
1080     if (!gif_grow_buf(dst_buf, dst_len, gif_ptr->cur_offset + size)) {
1081       return false;
1082     }
1083     FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->global_pal, size);
1084     gif_ptr->cur_offset += size;
1085   }
1086   return true;
1087 }
interlace_buf(const uint8_t * buf,uint32_t pitch,uint32_t height)1088 void interlace_buf(const uint8_t* buf, uint32_t pitch, uint32_t height) {
1089   std::vector<uint8_t*> pass[4];
1090   uint32_t row = 0;
1091   uint8_t* temp;
1092   while (row < height) {
1093     size_t j;
1094     if (row % 8 == 0) {
1095       j = 0;
1096     } else if (row % 4 == 0) {
1097       j = 1;
1098     } else if (row % 2 == 0) {
1099       j = 2;
1100     } else {
1101       j = 3;
1102     }
1103     temp = FX_Alloc(uint8_t, pitch);
1104     FXSYS_memcpy(temp, &buf[pitch * row], pitch);
1105     pass[j].push_back(temp);
1106     row++;
1107   }
1108   for (size_t i = 0, row = 0; i < 4; i++) {
1109     for (size_t j = 0; j < pass[i].size(); j++, row++) {
1110       FXSYS_memcpy((uint8_t*)&buf[pitch * row], pass[i][j], pitch);
1111       FX_Free(pass[i][j]);
1112     }
1113   }
1114 }
gif_write_block_data(const uint8_t * src_buf,uint32_t src_len,uint8_t * & dst_buf,uint32_t & dst_len,uint32_t & dst_offset)1115 static void gif_write_block_data(const uint8_t* src_buf,
1116                                  uint32_t src_len,
1117                                  uint8_t*& dst_buf,
1118                                  uint32_t& dst_len,
1119                                  uint32_t& dst_offset) {
1120   uint32_t src_offset = 0;
1121   while (src_len > GIF_DATA_BLOCK) {
1122     dst_buf[dst_offset++] = GIF_DATA_BLOCK;
1123     FXSYS_memcpy(&dst_buf[dst_offset], &src_buf[src_offset], GIF_DATA_BLOCK);
1124     dst_offset += GIF_DATA_BLOCK;
1125     src_offset += GIF_DATA_BLOCK;
1126     src_len -= GIF_DATA_BLOCK;
1127   }
1128   dst_buf[dst_offset++] = (uint8_t)src_len;
1129   FXSYS_memcpy(&dst_buf[dst_offset], &src_buf[src_offset], src_len);
1130   dst_offset += src_len;
1131 }
gif_write_data(gif_compress_struct_p gif_ptr,uint8_t * & dst_buf,uint32_t & dst_len)1132 static bool gif_write_data(gif_compress_struct_p gif_ptr,
1133                            uint8_t*& dst_buf,
1134                            uint32_t& dst_len) {
1135   if (!gif_grow_buf(dst_buf, dst_len, gif_ptr->cur_offset + GIF_DATA_BLOCK)) {
1136     return false;
1137   }
1138   if (FXSYS_memcmp(gif_ptr->header_ptr->version, "89a", 3) == 0) {
1139     dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION;
1140     dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_GCE;
1141     gif_ptr->gce_ptr->block_size = 4;
1142     dst_buf[gif_ptr->cur_offset++] = gif_ptr->gce_ptr->block_size;
1143     gif_ptr->gce_ptr->gce_flag = 0;
1144     dst_buf[gif_ptr->cur_offset++] = gif_ptr->gce_ptr->gce_flag;
1145     gif_ptr->gce_ptr->delay_time = 10;
1146     SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset,
1147                      gif_ptr->gce_ptr->delay_time);
1148     gif_ptr->cur_offset += 2;
1149     gif_ptr->gce_ptr->trans_index = 0;
1150     dst_buf[gif_ptr->cur_offset++] = gif_ptr->gce_ptr->trans_index;
1151     dst_buf[gif_ptr->cur_offset++] = 0;
1152   }
1153   dst_buf[gif_ptr->cur_offset++] = GIF_SIG_IMAGE;
1154   SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset,
1155                    gif_ptr->image_info_ptr->left);
1156   gif_ptr->cur_offset += 2;
1157   SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->image_info_ptr->top);
1158   gif_ptr->cur_offset += 2;
1159   SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset,
1160                    gif_ptr->image_info_ptr->width);
1161   gif_ptr->cur_offset += 2;
1162   SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset,
1163                    gif_ptr->image_info_ptr->height);
1164   gif_ptr->cur_offset += 2;
1165   GifLF& lf = (GifLF&)gif_ptr->image_info_ptr->local_flag;
1166   dst_buf[gif_ptr->cur_offset++] = gif_ptr->image_info_ptr->local_flag;
1167   if (gif_ptr->local_pal) {
1168     uint32_t pal_size = sizeof(GifPalette) * gif_ptr->lpal_num;
1169     if (!gif_grow_buf(dst_buf, dst_len, pal_size + gif_ptr->cur_offset)) {
1170       return false;
1171     }
1172     FXSYS_memcpy(&dst_buf[gif_ptr->cur_offset], gif_ptr->local_pal, pal_size);
1173     gif_ptr->cur_offset += pal_size;
1174   }
1175   if (lf.interlace) {
1176     interlace_buf(gif_ptr->src_buf, gif_ptr->src_pitch,
1177                   gif_ptr->image_info_ptr->height);
1178   }
1179   uint8_t code_bit = lf.pal_bits;
1180   if (lf.local_pal == 0) {
1181     GifGF& gf = (GifGF&)gif_ptr->lsd_ptr->global_flag;
1182     code_bit = gf.pal_bits;
1183   }
1184   if (code_bit >= 31)
1185     return false;
1186   gif_ptr->img_encoder_ptr->Start(code_bit, gif_ptr->src_buf, dst_buf,
1187                                   gif_ptr->cur_offset);
1188   uint32_t i;
1189   for (i = 0; i < gif_ptr->src_row; i++) {
1190     if (!gif_ptr->img_encoder_ptr->Encode(
1191             &gif_ptr->src_buf[i * gif_ptr->src_pitch],
1192             gif_ptr->src_width * (code_bit + 1), dst_buf, dst_len,
1193             gif_ptr->cur_offset)) {
1194       return false;
1195     }
1196   }
1197   gif_ptr->img_encoder_ptr->Finish(dst_buf, dst_len, gif_ptr->cur_offset);
1198   dst_buf[gif_ptr->cur_offset++] = 0;
1199   if (FXSYS_memcmp(gif_ptr->header_ptr->version, "89a", 3) == 0 &&
1200       gif_ptr->cmt_data_ptr) {
1201     dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION;
1202     dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_CE;
1203     gif_write_block_data(gif_ptr->cmt_data_ptr, gif_ptr->cmt_data_len, dst_buf,
1204                          dst_len, gif_ptr->cur_offset);
1205     dst_buf[gif_ptr->cur_offset++] = 0;
1206   }
1207   if (FXSYS_memcmp(gif_ptr->header_ptr->version, "89a", 3) == 0 &&
1208       gif_ptr->pte_data_ptr) {
1209     dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION;
1210     dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_PTE;
1211     dst_buf[gif_ptr->cur_offset++] = gif_ptr->pte_ptr->block_size;
1212     SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset,
1213                      gif_ptr->pte_ptr->grid_left);
1214     gif_ptr->cur_offset += 2;
1215     SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->pte_ptr->grid_top);
1216     gif_ptr->cur_offset += 2;
1217     SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset,
1218                      gif_ptr->pte_ptr->grid_width);
1219     gif_ptr->cur_offset += 2;
1220     SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset,
1221                      gif_ptr->pte_ptr->grid_height);
1222     gif_ptr->cur_offset += 2;
1223     SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset,
1224                      gif_ptr->pte_ptr->char_width);
1225     gif_ptr->cur_offset += 2;
1226     SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset,
1227                      gif_ptr->pte_ptr->char_height);
1228     gif_ptr->cur_offset += 2;
1229     SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->pte_ptr->fc_index);
1230     gif_ptr->cur_offset += 2;
1231     SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->pte_ptr->bc_index);
1232     gif_ptr->cur_offset += 2;
1233     gif_write_block_data(gif_ptr->pte_data_ptr, gif_ptr->pte_data_len, dst_buf,
1234                          dst_len, gif_ptr->cur_offset);
1235     gif_ptr->cur_offset += gif_ptr->pte_data_len;
1236     dst_buf[gif_ptr->cur_offset++] = 0;
1237   }
1238   dst_buf[gif_ptr->cur_offset++] = GIF_SIG_TRAILER;
1239   return true;
1240 }
gif_encode(gif_compress_struct_p gif_ptr,uint8_t * & dst_buf,uint32_t & dst_len)1241 bool gif_encode(gif_compress_struct_p gif_ptr,
1242                 uint8_t*& dst_buf,
1243                 uint32_t& dst_len) {
1244   if (!gif_write_header(gif_ptr, dst_buf, dst_len)) {
1245     return false;
1246   }
1247   uint32_t cur_offset = gif_ptr->cur_offset;
1248   bool res = true;
1249   if (gif_ptr->frames) {
1250     gif_ptr->cur_offset--;
1251   }
1252   if (!gif_write_data(gif_ptr, dst_buf, dst_len)) {
1253     gif_ptr->cur_offset = cur_offset;
1254     res = false;
1255   }
1256   dst_len = gif_ptr->cur_offset;
1257   dst_buf[dst_len - 1] = GIF_SIG_TRAILER;
1258   if (res) {
1259     gif_ptr->frames++;
1260   }
1261   return res;
1262 }
1263