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 12 void CGifLZWDecoder::Input(uint8_t* src_buf, uint32_t src_size) { 13 next_in = src_buf; 14 avail_in = src_size; 15 } 16 17 uint32_t CGifLZWDecoder::GetAvailInput() { 18 return avail_in; 19 } 20 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 36 CGifLZWDecoder::~CGifLZWDecoder() {} 37 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 231 CGifLZWEncoder::CGifLZWEncoder() { 232 FXSYS_memset(this, 0, sizeof(CGifLZWEncoder)); 233 } 234 CGifLZWEncoder::~CGifLZWEncoder() {} 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 514 void gif_warn(gif_decompress_struct_p gif_ptr, const FX_CHAR* err_msg) {} 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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