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