diff options
Diffstat (limited to 'core/fxcodec/lgif/fx_gif.cpp')
-rw-r--r-- | core/fxcodec/lgif/fx_gif.cpp | 484 |
1 files changed, 0 insertions, 484 deletions
diff --git a/core/fxcodec/lgif/fx_gif.cpp b/core/fxcodec/lgif/fx_gif.cpp index ea78259420..6e1c26ed12 100644 --- a/core/fxcodec/lgif/fx_gif.cpp +++ b/core/fxcodec/lgif/fx_gif.cpp @@ -23,168 +23,6 @@ static_assert(sizeof(GifGCE) == 5, "GifGCE should have a size of 5"); static_assert(sizeof(GifHeader) == 6, "GifHeader should have a size of 6"); static_assert(sizeof(GifLSD) == 7, "GifLSD should have a size of 7"); -namespace { - -uint8_t* gif_read_data(CGifContext* context, - uint8_t** des_buf_pp, - uint32_t data_size) { - if (!context || context->avail_in < context->skip_size + data_size) - return nullptr; - - *des_buf_pp = context->next_in + context->skip_size; - context->skip_size += data_size; - return *des_buf_pp; -} - -void gif_save_decoding_status(CGifContext* context, int32_t status) { - context->decode_status = status; - context->next_in += context->skip_size; - context->avail_in -= context->skip_size; - context->skip_size = 0; -} - -GifDecodeStatus gif_decode_extension(CGifContext* context) { - uint8_t* data_size_ptr = nullptr; - uint8_t* data_ptr = nullptr; - uint32_t skip_size_org = context->skip_size; - switch (context->decode_status) { - case GIF_D_STATUS_EXT_CE: { - if (!gif_read_data(context, &data_size_ptr, 1)) { - context->skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - context->cmt_data.clear(); - while (*data_size_ptr != GIF_BLOCK_TERMINAL) { - uint8_t data_size = *data_size_ptr; - if (!gif_read_data(context, &data_ptr, *data_size_ptr) || - !gif_read_data(context, &data_size_ptr, 1)) { - context->skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - context->cmt_data += ByteString(data_ptr, data_size); - } - break; - } - case GIF_D_STATUS_EXT_PTE: { - GifPTE* gif_pte = nullptr; - if (!gif_read_data(context, reinterpret_cast<uint8_t**>(&gif_pte), 13)) - return GifDecodeStatus::Unfinished; - - context->m_GifGCE = nullptr; - if (!gif_read_data(context, &data_size_ptr, 1)) { - context->skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - while (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (!gif_read_data(context, &data_ptr, *data_size_ptr) || - !gif_read_data(context, &data_size_ptr, 1)) { - context->skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - } - break; - } - case GIF_D_STATUS_EXT_GCE: { - GifGCE* gif_gce_ptr = nullptr; - if (!gif_read_data(context, reinterpret_cast<uint8_t**>(&gif_gce_ptr), 6)) - return GifDecodeStatus::Unfinished; - - if (!context->m_GifGCE.get()) - context->m_GifGCE = pdfium::MakeUnique<GifGCE>(); - context->m_GifGCE->block_size = gif_gce_ptr->block_size; - context->m_GifGCE->gce_flag = gif_gce_ptr->gce_flag; - context->m_GifGCE->delay_time = GetWord_LSBFirst( - reinterpret_cast<uint8_t*>(&gif_gce_ptr->delay_time)); - context->m_GifGCE->trans_index = gif_gce_ptr->trans_index; - break; - } - default: { - if (context->decode_status == GIF_D_STATUS_EXT_PTE) - context->m_GifGCE = nullptr; - if (!gif_read_data(context, &data_size_ptr, 1)) - return GifDecodeStatus::Unfinished; - - while (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (!gif_read_data(context, &data_ptr, *data_size_ptr) || - !gif_read_data(context, &data_size_ptr, 1)) { - context->skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - } - } - } - gif_save_decoding_status(context, GIF_D_STATUS_SIG); - return GifDecodeStatus::Success; -} - -GifDecodeStatus gif_decode_image_info(CGifContext* context) { - if (context->width == 0 || context->height == 0) { - context->AddError("No Image Header Info"); - return GifDecodeStatus::Error; - } - uint32_t skip_size_org = context->skip_size; - GifImageInfo* gif_img_info_ptr = nullptr; - if (!gif_read_data(context, reinterpret_cast<uint8_t**>(&gif_img_info_ptr), - 9)) - return GifDecodeStatus::Unfinished; - - auto gif_image = pdfium::MakeUnique<GifImage>(); - gif_image->m_ImageInfo.left = - GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->left)); - gif_image->m_ImageInfo.top = - GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->top)); - gif_image->m_ImageInfo.width = - GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->width)); - gif_image->m_ImageInfo.height = - GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_img_info_ptr->height)); - gif_image->m_ImageInfo.local_flag = gif_img_info_ptr->local_flag; - if (gif_image->m_ImageInfo.left + gif_image->m_ImageInfo.width > - context->width || - gif_image->m_ImageInfo.top + gif_image->m_ImageInfo.height > - context->height) { - context->AddError("Image Data Out Of LSD, The File May Be Corrupt"); - return GifDecodeStatus::Error; - } - GifLF* gif_img_info_lf_ptr = (GifLF*)&gif_img_info_ptr->local_flag; - if (gif_img_info_lf_ptr->local_pal) { - gif_image->local_pallette_exp = gif_img_info_lf_ptr->pal_bits; - int32_t loc_pal_size = (2 << gif_img_info_lf_ptr->pal_bits) * 3; - uint8_t* loc_pal_ptr = nullptr; - if (!gif_read_data(context, &loc_pal_ptr, loc_pal_size)) { - context->skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - gif_image->m_LocalPalettes = std::vector<GifPalette>(loc_pal_size / 3); - std::copy(loc_pal_ptr, loc_pal_ptr + loc_pal_size, - reinterpret_cast<uint8_t*>(gif_image->m_LocalPalettes.data())); - } - uint8_t* code_size_ptr = nullptr; - if (!gif_read_data(context, &code_size_ptr, 1)) { - context->skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - gif_image->image_code_exp = *code_size_ptr; - context->RecordCurrentPosition(&gif_image->image_data_pos); - gif_image->image_data_pos += context->skip_size; - gif_image->m_ImageGCE = nullptr; - if (context->m_GifGCE.get()) { - gif_image->m_ImageGCE = std::move(context->m_GifGCE); - context->m_GifGCE = nullptr; - } - context->m_Images.push_back(std::move(gif_image)); - gif_save_decoding_status(context, GIF_D_STATUS_IMG_DATA); - return GifDecodeStatus::Success; -} - -void gif_decoding_failure_at_tail_cleanup(CGifContext* context, - GifImage* gif_image_ptr) { - gif_image_ptr->m_ImageRowBuf.clear(); - gif_save_decoding_status(context, GIF_D_STATUS_TAIL); - context->AddError("Decode Image Data Error"); -} - -} // namespace - GifImage::GifImage() {} GifImage::~GifImage() {} @@ -369,325 +207,3 @@ GifDecodeStatus CGifLZWDecoder::Decode(uint8_t* des_buf, uint32_t* des_size) { } return GifDecodeStatus::Error; } - -GifDecodeStatus gif_read_header(CGifContext* context) { - if (!context) - return GifDecodeStatus::Error; - - uint32_t skip_size_org = context->skip_size; - GifHeader* gif_header_ptr = nullptr; - if (!gif_read_data(context, reinterpret_cast<uint8_t**>(&gif_header_ptr), 6)) - return GifDecodeStatus::Unfinished; - - if (strncmp(gif_header_ptr->signature, GIF_SIGNATURE, 3) != 0 || - gif_header_ptr->version[0] != '8' || gif_header_ptr->version[2] != 'a') { - context->AddError("Not A Gif Image"); - return GifDecodeStatus::Error; - } - GifLSD* gif_lsd_ptr = nullptr; - if (!gif_read_data(context, reinterpret_cast<uint8_t**>(&gif_lsd_ptr), 7)) { - context->skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - if (reinterpret_cast<GifGF*>(&gif_lsd_ptr->global_flag)->global_pal) { - context->global_pal_exp = - reinterpret_cast<GifGF*>(&gif_lsd_ptr->global_flag)->pal_bits; - int32_t global_pal_size = (2 << context->global_pal_exp) * 3; - uint8_t* global_pal_ptr = nullptr; - if (!gif_read_data(context, &global_pal_ptr, global_pal_size)) { - context->skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - context->global_sort_flag = ((GifGF*)&gif_lsd_ptr->global_flag)->sort_flag; - context->global_color_resolution = - ((GifGF*)&gif_lsd_ptr->global_flag)->color_resolution; - context->m_GlobalPalette.resize(global_pal_size / 3); - memcpy(context->m_GlobalPalette.data(), global_pal_ptr, global_pal_size); - } - context->width = - (int)GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_lsd_ptr->width)); - context->height = - (int)GetWord_LSBFirst(reinterpret_cast<uint8_t*>(&gif_lsd_ptr->height)); - context->bc_index = gif_lsd_ptr->bc_index; - context->pixel_aspect = gif_lsd_ptr->pixel_aspect; - return GifDecodeStatus::Success; -} - -GifDecodeStatus gif_get_frame(CGifContext* context) { - if (!context) - return GifDecodeStatus::Error; - - GifDecodeStatus ret = GifDecodeStatus::Success; - while (true) { - switch (context->decode_status) { - case GIF_D_STATUS_TAIL: - return GifDecodeStatus::Success; - case GIF_D_STATUS_SIG: { - uint8_t* sig_ptr = nullptr; - if (!gif_read_data(context, &sig_ptr, 1)) - return GifDecodeStatus::Unfinished; - - switch (*sig_ptr) { - case GIF_SIG_EXTENSION: - gif_save_decoding_status(context, GIF_D_STATUS_EXT); - continue; - case GIF_SIG_IMAGE: - gif_save_decoding_status(context, GIF_D_STATUS_IMG_INFO); - continue; - case GIF_SIG_TRAILER: - gif_save_decoding_status(context, GIF_D_STATUS_TAIL); - return GifDecodeStatus::Success; - default: - if (context->avail_in) { - // The Gif File has non_standard Tag! - gif_save_decoding_status(context, GIF_D_STATUS_SIG); - continue; - } - // The Gif File Doesn't have Trailer Tag! - return GifDecodeStatus::Success; - } - } - case GIF_D_STATUS_EXT: { - uint8_t* ext_ptr = nullptr; - if (!gif_read_data(context, &ext_ptr, 1)) - return GifDecodeStatus::Unfinished; - - switch (*ext_ptr) { - case GIF_BLOCK_CE: - gif_save_decoding_status(context, GIF_D_STATUS_EXT_CE); - continue; - case GIF_BLOCK_GCE: - gif_save_decoding_status(context, GIF_D_STATUS_EXT_GCE); - continue; - case GIF_BLOCK_PTE: - gif_save_decoding_status(context, GIF_D_STATUS_EXT_PTE); - continue; - default: { - int32_t status = GIF_D_STATUS_EXT_UNE; - if (*ext_ptr == GIF_BLOCK_PTE) { - status = GIF_D_STATUS_EXT_PTE; - } - gif_save_decoding_status(context, status); - continue; - } - } - } - case GIF_D_STATUS_IMG_INFO: { - ret = gif_decode_image_info(context); - if (ret != GifDecodeStatus::Success) - return ret; - - continue; - } - case GIF_D_STATUS_IMG_DATA: { - uint8_t* data_size_ptr = nullptr; - uint8_t* data_ptr = nullptr; - uint32_t skip_size_org = context->skip_size; - if (!gif_read_data(context, &data_size_ptr, 1)) - return GifDecodeStatus::Unfinished; - - while (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (!gif_read_data(context, &data_ptr, *data_size_ptr)) { - context->skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - gif_save_decoding_status(context, GIF_D_STATUS_IMG_DATA); - skip_size_org = context->skip_size; - if (!gif_read_data(context, &data_size_ptr, 1)) - return GifDecodeStatus::Unfinished; - } - gif_save_decoding_status(context, GIF_D_STATUS_SIG); - continue; - } - default: { - ret = gif_decode_extension(context); - if (ret != GifDecodeStatus::Success) - return ret; - break; - } - } - } - return GifDecodeStatus::Success; -} - -GifDecodeStatus gif_load_frame(CGifContext* context, int32_t frame_num) { - if (!context || !pdfium::IndexInBounds(context->m_Images, frame_num)) - return GifDecodeStatus::Error; - - uint8_t* data_size_ptr = nullptr; - uint8_t* data_ptr = nullptr; - uint32_t skip_size_org = context->skip_size; - GifImage* gif_image_ptr = context->m_Images[frame_num].get(); - uint32_t gif_img_row_bytes = gif_image_ptr->m_ImageInfo.width; - if (gif_img_row_bytes == 0) { - context->AddError("Error Invalid Number of Row Bytes"); - return GifDecodeStatus::Error; - } - if (context->decode_status == GIF_D_STATUS_TAIL) { - gif_image_ptr->m_ImageRowBuf.resize(gif_img_row_bytes); - GifGCE* gif_img_gce_ptr = gif_image_ptr->m_ImageGCE.get(); - int32_t loc_pal_num = - ((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->local_pal - ? (2 << ((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->pal_bits) - : 0; - context->avail_in = 0; - GifPalette* pLocalPalette = gif_image_ptr->m_LocalPalettes.empty() - ? nullptr - : gif_image_ptr->m_LocalPalettes.data(); - if (!gif_img_gce_ptr) { - bool bRes = context->GetRecordPosition( - gif_image_ptr->image_data_pos, gif_image_ptr->m_ImageInfo.left, - gif_image_ptr->m_ImageInfo.top, gif_image_ptr->m_ImageInfo.width, - gif_image_ptr->m_ImageInfo.height, loc_pal_num, pLocalPalette, 0, 0, - -1, 0, - (bool)((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->interlace); - if (!bRes) { - gif_image_ptr->m_ImageRowBuf.clear(); - context->AddError("Error Read Record Position Data"); - return GifDecodeStatus::Error; - } - } else { - bool bRes = context->GetRecordPosition( - gif_image_ptr->image_data_pos, gif_image_ptr->m_ImageInfo.left, - gif_image_ptr->m_ImageInfo.top, gif_image_ptr->m_ImageInfo.width, - gif_image_ptr->m_ImageInfo.height, loc_pal_num, pLocalPalette, - (int32_t)gif_image_ptr->m_ImageGCE->delay_time, - (bool)((GifCEF*)&gif_image_ptr->m_ImageGCE->gce_flag)->user_input, - ((GifCEF*)&gif_image_ptr->m_ImageGCE->gce_flag)->transparency - ? (int32_t)gif_image_ptr->m_ImageGCE->trans_index - : -1, - (int32_t)((GifCEF*)&gif_image_ptr->m_ImageGCE->gce_flag) - ->disposal_method, - (bool)((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->interlace); - if (!bRes) { - gif_image_ptr->m_ImageRowBuf.clear(); - context->AddError("Error Read Record Position Data"); - return GifDecodeStatus::Error; - } - } - if (gif_image_ptr->image_code_exp > GIF_MAX_LZW_EXP) { - gif_image_ptr->m_ImageRowBuf.clear(); - context->AddError("Error Invalid Code Size"); - return GifDecodeStatus::Error; - } - if (!context->m_ImgDecoder.get()) - context->m_ImgDecoder = - pdfium::MakeUnique<CGifLZWDecoder>(context->m_szLastError); - context->m_ImgDecoder->InitTable(!gif_image_ptr->m_LocalPalettes.empty() - ? gif_image_ptr->local_pallette_exp - : context->global_pal_exp, - gif_image_ptr->image_code_exp); - context->img_row_offset = 0; - context->img_row_avail_size = 0; - context->img_pass_num = 0; - gif_image_ptr->image_row_num = 0; - gif_save_decoding_status(context, GIF_D_STATUS_IMG_DATA); - } - CGifLZWDecoder* img_decoder_ptr = context->m_ImgDecoder.get(); - if (context->decode_status == GIF_D_STATUS_IMG_DATA) { - if (!gif_read_data(context, &data_size_ptr, 1)) - return GifDecodeStatus::Unfinished; - - if (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (!gif_read_data(context, &data_ptr, *data_size_ptr)) { - context->skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - img_decoder_ptr->Input(data_ptr, *data_size_ptr); - gif_save_decoding_status(context, GIF_D_STATUS_IMG_DATA); - context->img_row_offset += context->img_row_avail_size; - context->img_row_avail_size = gif_img_row_bytes - context->img_row_offset; - GifDecodeStatus ret = img_decoder_ptr->Decode( - gif_image_ptr->m_ImageRowBuf.data() + context->img_row_offset, - &context->img_row_avail_size); - if (ret == GifDecodeStatus::Error) { - gif_decoding_failure_at_tail_cleanup(context, gif_image_ptr); - return GifDecodeStatus::Error; - } - while (ret != GifDecodeStatus::Error) { - if (ret == GifDecodeStatus::Success) { - context->ReadScanline(gif_image_ptr->image_row_num, - gif_image_ptr->m_ImageRowBuf.data()); - gif_image_ptr->m_ImageRowBuf.clear(); - gif_save_decoding_status(context, GIF_D_STATUS_TAIL); - return GifDecodeStatus::Success; - } - if (ret == GifDecodeStatus::Unfinished) { - ASSERT(img_decoder_ptr->GetAvailInput() == 0); - skip_size_org = context->skip_size; - if (!gif_read_data(context, &data_size_ptr, 1)) - return GifDecodeStatus::Unfinished; - - if (*data_size_ptr != GIF_BLOCK_TERMINAL) { - if (!gif_read_data(context, &data_ptr, *data_size_ptr)) { - context->skip_size = skip_size_org; - return GifDecodeStatus::Unfinished; - } - img_decoder_ptr->Input(data_ptr, *data_size_ptr); - gif_save_decoding_status(context, GIF_D_STATUS_IMG_DATA); - context->img_row_offset += context->img_row_avail_size; - context->img_row_avail_size = - gif_img_row_bytes - context->img_row_offset; - ret = img_decoder_ptr->Decode( - gif_image_ptr->m_ImageRowBuf.data() + context->img_row_offset, - &context->img_row_avail_size); - } - } - if (ret == GifDecodeStatus::InsufficientDestSize) { - if (((GifLF*)&gif_image_ptr->m_ImageInfo.local_flag)->interlace) { - context->ReadScanline(gif_image_ptr->image_row_num, - gif_image_ptr->m_ImageRowBuf.data()); - gif_image_ptr->image_row_num += - s_gif_interlace_step[context->img_pass_num]; - if (gif_image_ptr->image_row_num >= - (int32_t)gif_image_ptr->m_ImageInfo.height) { - context->img_pass_num++; - if (context->img_pass_num == FX_ArraySize(s_gif_interlace_step)) { - gif_decoding_failure_at_tail_cleanup(context, gif_image_ptr); - return GifDecodeStatus::Error; - } - gif_image_ptr->image_row_num = - s_gif_interlace_step[context->img_pass_num] / 2; - } - } else { - context->ReadScanline(gif_image_ptr->image_row_num++, - gif_image_ptr->m_ImageRowBuf.data()); - } - context->img_row_offset = 0; - context->img_row_avail_size = gif_img_row_bytes; - ret = img_decoder_ptr->Decode( - gif_image_ptr->m_ImageRowBuf.data() + context->img_row_offset, - &context->img_row_avail_size); - } - if (ret == GifDecodeStatus::Error) { - gif_decoding_failure_at_tail_cleanup(context, gif_image_ptr); - return GifDecodeStatus::Error; - } - } - } - gif_save_decoding_status(context, GIF_D_STATUS_TAIL); - } - context->AddError("Decode Image Data Error"); - return GifDecodeStatus::Error; -} - -void gif_input_buffer(CGifContext* context, - uint8_t* src_buf, - uint32_t src_size) { - context->next_in = src_buf; - context->avail_in = src_size; - context->skip_size = 0; -} - -uint32_t gif_get_avail_input(CGifContext* context, uint8_t** avail_buf_ptr) { - if (avail_buf_ptr) { - *avail_buf_ptr = nullptr; - if (context->avail_in > 0) - *avail_buf_ptr = context->next_in; - } - return context->avail_in; -} - -int32_t gif_get_frame_num(CGifContext* context) { - return pdfium::CollectionSize<int32_t>(context->m_Images); -} |