1 // Copyright 2017 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/gif/cfx_gifcontext.h" 8 9 #include <algorithm> 10 #include <utility> 11 12 #include "core/fxcodec/codec/ccodec_gifmodule.h" 13 #include "core/fxcodec/gif/cfx_gif.h" 14 #include "third_party/base/ptr_util.h" 15 #include "third_party/base/stl_util.h" 16 17 namespace { 18 19 const int32_t s_gif_interlace_step[4] = {8, 8, 4, 2}; 20 21 } // namespace 22 23 CFX_GifContext::CFX_GifContext(CCodec_GifModule* gif_module, 24 CCodec_GifModule::Delegate* delegate) 25 : gif_module_(gif_module), 26 delegate_(delegate), 27 global_pal_exp_(0), 28 img_row_offset_(0), 29 img_row_avail_size_(0), 30 avail_in_(0), 31 decode_status_(GIF_D_STATUS_SIG), 32 skip_size_(0), 33 next_in_(nullptr), 34 width_(0), 35 height_(0), 36 bc_index_(0), 37 pixel_aspect_(0), 38 global_sort_flag_(0), 39 global_color_resolution_(0), 40 img_pass_num_(0) {} 41 42 CFX_GifContext::~CFX_GifContext() {} 43 44 void CFX_GifContext::RecordCurrentPosition(uint32_t* cur_pos) { 45 delegate_->GifRecordCurrentPosition(*cur_pos); 46 } 47 48 void CFX_GifContext::ReadScanline(int32_t row_num, uint8_t* row_buf) { 49 delegate_->GifReadScanline(row_num, row_buf); 50 } 51 52 bool CFX_GifContext::GetRecordPosition(uint32_t cur_pos, 53 int32_t left, 54 int32_t top, 55 int32_t width, 56 int32_t height, 57 int32_t pal_num, 58 CFX_GifPalette* pal, 59 int32_t delay_time, 60 bool user_input, 61 int32_t trans_index, 62 int32_t disposal_method, 63 bool interlace) { 64 return delegate_->GifInputRecordPositionBuf( 65 cur_pos, FX_RECT(left, top, left + width, top + height), pal_num, pal, 66 delay_time, user_input, trans_index, disposal_method, interlace); 67 } 68 69 CFX_GifDecodeStatus CFX_GifContext::ReadHeader() { 70 CFX_GifDecodeStatus status = ReadGifSignature(); 71 if (status != CFX_GifDecodeStatus::Success) 72 return status; 73 return ReadLogicalScreenDescriptor(); 74 } 75 76 CFX_GifDecodeStatus CFX_GifContext::GetFrame() { 77 CFX_GifDecodeStatus ret = CFX_GifDecodeStatus::Success; 78 while (true) { 79 switch (decode_status_) { 80 case GIF_D_STATUS_TAIL: 81 return CFX_GifDecodeStatus::Success; 82 case GIF_D_STATUS_SIG: { 83 uint8_t* signature = nullptr; 84 if (!ReadData(&signature, 1)) 85 return CFX_GifDecodeStatus::Unfinished; 86 87 switch (*signature) { 88 case GIF_SIG_EXTENSION: 89 SaveDecodingStatus(GIF_D_STATUS_EXT); 90 continue; 91 case GIF_SIG_IMAGE: 92 SaveDecodingStatus(GIF_D_STATUS_IMG_INFO); 93 continue; 94 case GIF_SIG_TRAILER: 95 SaveDecodingStatus(GIF_D_STATUS_TAIL); 96 return CFX_GifDecodeStatus::Success; 97 default: 98 if (avail_in_) { 99 // The Gif File has non_standard Tag! 100 SaveDecodingStatus(GIF_D_STATUS_SIG); 101 continue; 102 } 103 // The Gif File Doesn't have Trailer Tag! 104 return CFX_GifDecodeStatus::Success; 105 } 106 } 107 case GIF_D_STATUS_EXT: { 108 uint8_t* extension = nullptr; 109 if (!ReadData(&extension, 1)) 110 return CFX_GifDecodeStatus::Unfinished; 111 112 switch (*extension) { 113 case GIF_BLOCK_CE: 114 SaveDecodingStatus(GIF_D_STATUS_EXT_CE); 115 continue; 116 case GIF_BLOCK_GCE: 117 SaveDecodingStatus(GIF_D_STATUS_EXT_GCE); 118 continue; 119 case GIF_BLOCK_PTE: 120 SaveDecodingStatus(GIF_D_STATUS_EXT_PTE); 121 continue; 122 default: { 123 int32_t status = GIF_D_STATUS_EXT_UNE; 124 if (*extension == GIF_BLOCK_PTE) { 125 status = GIF_D_STATUS_EXT_PTE; 126 } 127 SaveDecodingStatus(status); 128 continue; 129 } 130 } 131 } 132 case GIF_D_STATUS_IMG_INFO: { 133 ret = DecodeImageInfo(); 134 if (ret != CFX_GifDecodeStatus::Success) 135 return ret; 136 137 continue; 138 } 139 case GIF_D_STATUS_IMG_DATA: { 140 uint8_t* img_data_size = nullptr; 141 uint8_t* img_data = nullptr; 142 uint32_t skip_size_org = skip_size_; 143 if (!ReadData(&img_data_size, 1)) 144 return CFX_GifDecodeStatus::Unfinished; 145 146 while (*img_data_size != GIF_BLOCK_TERMINAL) { 147 if (!ReadData(&img_data, *img_data_size)) { 148 skip_size_ = skip_size_org; 149 return CFX_GifDecodeStatus::Unfinished; 150 } 151 152 SaveDecodingStatus(GIF_D_STATUS_IMG_DATA); 153 skip_size_org = skip_size_; 154 if (!ReadData(&img_data_size, 1)) 155 return CFX_GifDecodeStatus::Unfinished; 156 } 157 SaveDecodingStatus(GIF_D_STATUS_SIG); 158 continue; 159 } 160 default: { 161 ret = DecodeExtension(); 162 if (ret != CFX_GifDecodeStatus::Success) 163 return ret; 164 break; 165 } 166 } 167 } 168 return CFX_GifDecodeStatus::Success; 169 } 170 171 CFX_GifDecodeStatus CFX_GifContext::LoadFrame(int32_t frame_num) { 172 if (!pdfium::IndexInBounds(images_, frame_num)) 173 return CFX_GifDecodeStatus::Error; 174 175 uint8_t* img_data_size = nullptr; 176 uint8_t* img_data = nullptr; 177 uint32_t skip_size_org = skip_size_; 178 CFX_GifImage* gif_image = images_[static_cast<size_t>(frame_num)].get(); 179 if (gif_image->image_info.height == 0) 180 return CFX_GifDecodeStatus::Error; 181 182 uint32_t gif_img_row_bytes = gif_image->image_info.width; 183 if (gif_img_row_bytes == 0) 184 return CFX_GifDecodeStatus::Error; 185 186 if (decode_status_ == GIF_D_STATUS_TAIL) { 187 gif_image->row_buffer.resize(gif_img_row_bytes); 188 CFX_GifGraphicControlExtension* gif_img_gce = gif_image->image_GCE.get(); 189 int32_t loc_pal_num = 190 gif_image->image_info.local_flags.local_pal 191 ? (2 << gif_image->image_info.local_flags.pal_bits) 192 : 0; 193 avail_in_ = 0; 194 CFX_GifPalette* pLocalPalette = gif_image->local_palettes.empty() 195 ? nullptr 196 : gif_image->local_palettes.data(); 197 if (!gif_img_gce) { 198 bool bRes = GetRecordPosition( 199 gif_image->data_pos, gif_image->image_info.left, 200 gif_image->image_info.top, gif_image->image_info.width, 201 gif_image->image_info.height, loc_pal_num, pLocalPalette, 0, 0, -1, 0, 202 gif_image->image_info.local_flags.interlace); 203 if (!bRes) { 204 gif_image->row_buffer.clear(); 205 return CFX_GifDecodeStatus::Error; 206 } 207 } else { 208 bool bRes = GetRecordPosition( 209 gif_image->data_pos, gif_image->image_info.left, 210 gif_image->image_info.top, gif_image->image_info.width, 211 gif_image->image_info.height, loc_pal_num, pLocalPalette, 212 static_cast<int32_t>(gif_image->image_GCE->delay_time), 213 gif_image->image_GCE->gce_flags.user_input, 214 gif_image->image_GCE->gce_flags.transparency 215 ? static_cast<int32_t>(gif_image->image_GCE->trans_index) 216 : -1, 217 static_cast<int32_t>(gif_image->image_GCE->gce_flags.disposal_method), 218 gif_image->image_info.local_flags.interlace); 219 if (!bRes) { 220 gif_image->row_buffer.clear(); 221 return CFX_GifDecodeStatus::Error; 222 } 223 } 224 225 if (gif_image->code_exp > GIF_MAX_LZW_EXP) { 226 gif_image->row_buffer.clear(); 227 return CFX_GifDecodeStatus::Error; 228 } 229 230 img_row_offset_ = 0; 231 img_row_avail_size_ = 0; 232 img_pass_num_ = 0; 233 gif_image->row_num = 0; 234 SaveDecodingStatus(GIF_D_STATUS_IMG_DATA); 235 } 236 237 if (decode_status_ == GIF_D_STATUS_IMG_DATA) { 238 if (!ReadData(&img_data_size, 1)) 239 return CFX_GifDecodeStatus::Unfinished; 240 241 if (*img_data_size != GIF_BLOCK_TERMINAL) { 242 if (!ReadData(&img_data, *img_data_size)) { 243 skip_size_ = skip_size_org; 244 return CFX_GifDecodeStatus::Unfinished; 245 } 246 247 if (!lzw_decompressor_.get()) 248 lzw_decompressor_ = CFX_LZWDecompressor::Create( 249 !gif_image->local_palettes.empty() ? gif_image->local_pallette_exp 250 : global_pal_exp_, 251 gif_image->code_exp); 252 SaveDecodingStatus(GIF_D_STATUS_IMG_DATA); 253 img_row_offset_ += img_row_avail_size_; 254 img_row_avail_size_ = gif_img_row_bytes - img_row_offset_; 255 CFX_GifDecodeStatus ret = 256 lzw_decompressor_.get() 257 ? lzw_decompressor_->Decode( 258 img_data, *img_data_size, 259 gif_image->row_buffer.data() + img_row_offset_, 260 &img_row_avail_size_) 261 : CFX_GifDecodeStatus::Error; 262 if (ret == CFX_GifDecodeStatus::Error) { 263 DecodingFailureAtTailCleanup(gif_image); 264 return CFX_GifDecodeStatus::Error; 265 } 266 while (ret != CFX_GifDecodeStatus::Error) { 267 if (ret == CFX_GifDecodeStatus::Success) { 268 ReadScanline(gif_image->row_num, gif_image->row_buffer.data()); 269 gif_image->row_buffer.clear(); 270 SaveDecodingStatus(GIF_D_STATUS_TAIL); 271 return CFX_GifDecodeStatus::Success; 272 } 273 if (ret == CFX_GifDecodeStatus::Unfinished) { 274 skip_size_org = skip_size_; 275 if (!ReadData(&img_data_size, 1)) 276 return CFX_GifDecodeStatus::Unfinished; 277 278 if (*img_data_size != GIF_BLOCK_TERMINAL) { 279 if (!ReadData(&img_data, *img_data_size)) { 280 skip_size_ = skip_size_org; 281 return CFX_GifDecodeStatus::Unfinished; 282 } 283 if (!lzw_decompressor_.get()) 284 lzw_decompressor_ = CFX_LZWDecompressor::Create( 285 !gif_image->local_palettes.empty() 286 ? gif_image->local_pallette_exp 287 : global_pal_exp_, 288 gif_image->code_exp); 289 SaveDecodingStatus(GIF_D_STATUS_IMG_DATA); 290 img_row_offset_ += img_row_avail_size_; 291 img_row_avail_size_ = gif_img_row_bytes - img_row_offset_; 292 ret = lzw_decompressor_.get() 293 ? lzw_decompressor_->Decode( 294 img_data, *img_data_size, 295 gif_image->row_buffer.data() + img_row_offset_, 296 &img_row_avail_size_) 297 : CFX_GifDecodeStatus::Error; 298 } 299 } 300 if (ret == CFX_GifDecodeStatus::InsufficientDestSize) { 301 if (gif_image->image_info.local_flags.interlace) { 302 ReadScanline(gif_image->row_num, gif_image->row_buffer.data()); 303 gif_image->row_num += s_gif_interlace_step[img_pass_num_]; 304 if (gif_image->row_num >= 305 static_cast<int32_t>(gif_image->image_info.height)) { 306 img_pass_num_++; 307 if (img_pass_num_ == FX_ArraySize(s_gif_interlace_step)) { 308 DecodingFailureAtTailCleanup(gif_image); 309 return CFX_GifDecodeStatus::Error; 310 } 311 gif_image->row_num = s_gif_interlace_step[img_pass_num_] / 2; 312 } 313 } else { 314 ReadScanline(gif_image->row_num++, gif_image->row_buffer.data()); 315 } 316 img_row_offset_ = 0; 317 img_row_avail_size_ = gif_img_row_bytes; 318 ret = lzw_decompressor_.get() 319 ? lzw_decompressor_->Decode( 320 img_data, *img_data_size, 321 gif_image->row_buffer.data() + img_row_offset_, 322 &img_row_avail_size_) 323 : CFX_GifDecodeStatus::Error; 324 } 325 if (ret == CFX_GifDecodeStatus::Error) { 326 DecodingFailureAtTailCleanup(gif_image); 327 return CFX_GifDecodeStatus::Error; 328 } 329 } 330 } 331 SaveDecodingStatus(GIF_D_STATUS_TAIL); 332 } 333 return CFX_GifDecodeStatus::Error; 334 } 335 336 void CFX_GifContext::SetInputBuffer(uint8_t* src_buf, uint32_t src_size) { 337 next_in_ = src_buf; 338 avail_in_ = src_size; 339 skip_size_ = 0; 340 } 341 342 uint32_t CFX_GifContext::GetAvailInput(uint8_t** avail_buf) const { 343 if (avail_buf) { 344 *avail_buf = nullptr; 345 if (avail_in_ > 0) 346 *avail_buf = next_in_; 347 } 348 return avail_in_; 349 } 350 351 uint8_t* CFX_GifContext::ReadData(uint8_t** des_buf_pp, uint32_t data_size) { 352 if (!next_in_) 353 return nullptr; 354 if (avail_in_ <= skip_size_) 355 return nullptr; 356 if (!des_buf_pp) 357 return nullptr; 358 if (data_size == 0) 359 return nullptr; 360 if (avail_in_ - skip_size_ < data_size) 361 return nullptr; 362 363 *des_buf_pp = next_in_ + skip_size_; 364 skip_size_ += data_size; 365 return *des_buf_pp; 366 } 367 368 CFX_GifDecodeStatus CFX_GifContext::ReadGifSignature() { 369 CFX_GifHeader* header = nullptr; 370 uint32_t skip_size_org = skip_size_; 371 if (!ReadData(reinterpret_cast<uint8_t**>(&header), 6)) { 372 skip_size_ = skip_size_org; 373 return CFX_GifDecodeStatus::Unfinished; 374 } 375 376 if (strncmp(header->signature, kGifSignature87, 6) != 0 && 377 strncmp(header->signature, kGifSignature89, 6) != 0) 378 return CFX_GifDecodeStatus::Error; 379 380 return CFX_GifDecodeStatus::Success; 381 } 382 383 CFX_GifDecodeStatus CFX_GifContext::ReadLogicalScreenDescriptor() { 384 CFX_GifLocalScreenDescriptor* lsd = nullptr; 385 uint32_t skip_size_org = skip_size_; 386 if (!ReadData(reinterpret_cast<uint8_t**>(&lsd), 7)) { 387 skip_size_ = skip_size_org; 388 return CFX_GifDecodeStatus::Unfinished; 389 } 390 391 if (lsd->global_flags.global_pal) { 392 uint32_t palette_count = unsigned(2 << lsd->global_flags.pal_bits); 393 if (lsd->bc_index >= palette_count) 394 return CFX_GifDecodeStatus::Error; 395 bc_index_ = lsd->bc_index; 396 397 uint32_t palette_size = palette_count * 3u; 398 uint8_t* palette = nullptr; 399 if (!ReadData(&palette, palette_size)) { 400 skip_size_ = skip_size_org; 401 return CFX_GifDecodeStatus::Unfinished; 402 } 403 404 global_pal_exp_ = lsd->global_flags.pal_bits; 405 global_sort_flag_ = lsd->global_flags.sort_flag; 406 global_color_resolution_ = lsd->global_flags.color_resolution; 407 global_palette_.resize(palette_count); 408 memcpy(global_palette_.data(), palette, palette_size); 409 } 410 411 width_ = static_cast<int>( 412 FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&lsd->width))); 413 height_ = static_cast<int>( 414 FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&lsd->height))); 415 416 pixel_aspect_ = lsd->pixel_aspect; 417 return CFX_GifDecodeStatus::Success; 418 } 419 420 void CFX_GifContext::SaveDecodingStatus(int32_t status) { 421 decode_status_ = status; 422 next_in_ += skip_size_; 423 avail_in_ -= skip_size_; 424 skip_size_ = 0; 425 } 426 427 CFX_GifDecodeStatus CFX_GifContext::DecodeExtension() { 428 uint8_t* data_size = nullptr; 429 uint8_t* data_buf = nullptr; 430 uint32_t skip_size_org = skip_size_; 431 switch (decode_status_) { 432 case GIF_D_STATUS_EXT_CE: { 433 if (!ReadData(&data_size, 1)) { 434 skip_size_ = skip_size_org; 435 return CFX_GifDecodeStatus::Unfinished; 436 } 437 438 cmt_data_.clear(); 439 while (*data_size != GIF_BLOCK_TERMINAL) { 440 uint8_t block_size = *data_size; 441 if (!ReadData(&data_buf, *data_size) || !ReadData(&data_size, 1)) { 442 skip_size_ = skip_size_org; 443 return CFX_GifDecodeStatus::Unfinished; 444 } 445 446 cmt_data_ += ByteString(data_buf, block_size); 447 } 448 break; 449 } 450 case GIF_D_STATUS_EXT_PTE: { 451 CFX_GifPlainTextExtension* gif_pte = nullptr; 452 if (!ReadData(reinterpret_cast<uint8_t**>(&gif_pte), 13)) 453 return CFX_GifDecodeStatus::Unfinished; 454 455 graphic_control_extension_ = nullptr; 456 if (!ReadData(&data_size, 1)) { 457 skip_size_ = skip_size_org; 458 return CFX_GifDecodeStatus::Unfinished; 459 } 460 461 while (*data_size != GIF_BLOCK_TERMINAL) { 462 if (!ReadData(&data_buf, *data_size) || !ReadData(&data_size, 1)) { 463 skip_size_ = skip_size_org; 464 return CFX_GifDecodeStatus::Unfinished; 465 } 466 } 467 break; 468 } 469 case GIF_D_STATUS_EXT_GCE: { 470 CFX_GifGraphicControlExtension* gif_gce = nullptr; 471 if (!ReadData(reinterpret_cast<uint8_t**>(&gif_gce), 6)) 472 return CFX_GifDecodeStatus::Unfinished; 473 474 if (!graphic_control_extension_.get()) 475 graphic_control_extension_ = 476 pdfium::MakeUnique<CFX_GifGraphicControlExtension>(); 477 graphic_control_extension_->block_size = gif_gce->block_size; 478 graphic_control_extension_->gce_flags = gif_gce->gce_flags; 479 graphic_control_extension_->delay_time = 480 FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&gif_gce->delay_time)); 481 graphic_control_extension_->trans_index = gif_gce->trans_index; 482 break; 483 } 484 default: { 485 if (decode_status_ == GIF_D_STATUS_EXT_PTE) 486 graphic_control_extension_ = nullptr; 487 if (!ReadData(&data_size, 1)) 488 return CFX_GifDecodeStatus::Unfinished; 489 490 while (*data_size != GIF_BLOCK_TERMINAL) { 491 if (!ReadData(&data_buf, *data_size) || !ReadData(&data_size, 1)) { 492 skip_size_ = skip_size_org; 493 return CFX_GifDecodeStatus::Unfinished; 494 } 495 } 496 } 497 } 498 SaveDecodingStatus(GIF_D_STATUS_SIG); 499 return CFX_GifDecodeStatus::Success; 500 } 501 502 CFX_GifDecodeStatus CFX_GifContext::DecodeImageInfo() { 503 if (width_ <= 0 || height_ <= 0) 504 return CFX_GifDecodeStatus::Error; 505 506 uint32_t skip_size_org = skip_size_; 507 CFX_CFX_GifImageInfo* img_info = nullptr; 508 if (!ReadData(reinterpret_cast<uint8_t**>(&img_info), 9)) 509 return CFX_GifDecodeStatus::Unfinished; 510 511 auto gif_image = pdfium::MakeUnique<CFX_GifImage>(); 512 gif_image->image_info.left = 513 FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info->left)); 514 gif_image->image_info.top = 515 FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info->top)); 516 gif_image->image_info.width = 517 FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info->width)); 518 gif_image->image_info.height = 519 FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info->height)); 520 gif_image->image_info.local_flags = img_info->local_flags; 521 if (gif_image->image_info.left + gif_image->image_info.width > width_ || 522 gif_image->image_info.top + gif_image->image_info.height > height_) 523 return CFX_GifDecodeStatus::Error; 524 525 CFX_GifLocalFlags* gif_img_info_lf = &img_info->local_flags; 526 if (gif_img_info_lf->local_pal) { 527 gif_image->local_pallette_exp = gif_img_info_lf->pal_bits; 528 uint32_t loc_pal_size = unsigned(2 << gif_img_info_lf->pal_bits) * 3u; 529 uint8_t* loc_pal = nullptr; 530 if (!ReadData(&loc_pal, loc_pal_size)) { 531 skip_size_ = skip_size_org; 532 return CFX_GifDecodeStatus::Unfinished; 533 } 534 535 gif_image->local_palettes = std::vector<CFX_GifPalette>(loc_pal_size / 3); 536 std::copy(loc_pal, loc_pal + loc_pal_size, 537 reinterpret_cast<uint8_t*>(gif_image->local_palettes.data())); 538 } 539 540 uint8_t* code_size = nullptr; 541 if (!ReadData(&code_size, 1)) { 542 skip_size_ = skip_size_org; 543 return CFX_GifDecodeStatus::Unfinished; 544 } 545 546 gif_image->code_exp = *code_size; 547 RecordCurrentPosition(&gif_image->data_pos); 548 gif_image->data_pos += skip_size_; 549 gif_image->image_GCE = nullptr; 550 if (graphic_control_extension_.get()) { 551 if (graphic_control_extension_->gce_flags.transparency) { 552 // Need to test that the color that is going to be transparent is actually 553 // in the palette being used. 554 if (graphic_control_extension_->trans_index >= 555 2 << (gif_image->local_palettes.empty() 556 ? global_pal_exp_ 557 : gif_image->local_pallette_exp)) 558 return CFX_GifDecodeStatus::Error; 559 } 560 gif_image->image_GCE = std::move(graphic_control_extension_); 561 graphic_control_extension_ = nullptr; 562 } 563 564 images_.push_back(std::move(gif_image)); 565 SaveDecodingStatus(GIF_D_STATUS_IMG_DATA); 566 return CFX_GifDecodeStatus::Success; 567 } 568 569 void CFX_GifContext::DecodingFailureAtTailCleanup(CFX_GifImage* gif_image) { 570 gif_image->row_buffer.clear(); 571 SaveDecodingStatus(GIF_D_STATUS_TAIL); 572 } 573