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