summaryrefslogtreecommitdiff
path: root/core/fxcodec/gif/cfx_gifcontext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fxcodec/gif/cfx_gifcontext.cpp')
-rw-r--r--core/fxcodec/gif/cfx_gifcontext.cpp98
1 files changed, 60 insertions, 38 deletions
diff --git a/core/fxcodec/gif/cfx_gifcontext.cpp b/core/fxcodec/gif/cfx_gifcontext.cpp
index 09e8753ca0..28bcad9ceb 100644
--- a/core/fxcodec/gif/cfx_gifcontext.cpp
+++ b/core/fxcodec/gif/cfx_gifcontext.cpp
@@ -67,43 +67,10 @@ bool CFX_GifContext::GetRecordPosition(uint32_t cur_pos,
}
CFX_GifDecodeStatus CFX_GifContext::ReadHeader() {
- uint32_t skip_size_org = skip_size_;
- CFX_GifHeader* gif_header = nullptr;
- if (!ReadData(reinterpret_cast<uint8_t**>(&gif_header), 6))
- return CFX_GifDecodeStatus::Unfinished;
-
- if (strncmp(gif_header->signature, GIF_SIGNATURE, 3) != 0 ||
- gif_header->version[0] != '8' || gif_header->version[2] != 'a')
- return CFX_GifDecodeStatus::Error;
-
- CFX_GifLocalScreenDescriptor* gif_lsd = nullptr;
- if (!ReadData(reinterpret_cast<uint8_t**>(&gif_lsd), 7)) {
- skip_size_ = skip_size_org;
- return CFX_GifDecodeStatus::Unfinished;
- }
-
- if (gif_lsd->global_flags.global_pal) {
- global_pal_exp_ = gif_lsd->global_flags.pal_bits;
- uint32_t global_pal_size = unsigned(2 << global_pal_exp_) * 3u;
- uint8_t* global_pal = nullptr;
- if (!ReadData(&global_pal, global_pal_size)) {
- skip_size_ = skip_size_org;
- return CFX_GifDecodeStatus::Unfinished;
- }
-
- global_sort_flag_ = gif_lsd->global_flags.sort_flag;
- global_color_resolution_ = gif_lsd->global_flags.color_resolution;
- global_palette_.resize(global_pal_size / 3);
- memcpy(global_palette_.data(), global_pal, global_pal_size);
- }
-
- width_ = static_cast<int>(
- FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&gif_lsd->width)));
- height_ = static_cast<int>(
- FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&gif_lsd->height)));
- bc_index_ = gif_lsd->bc_index;
- pixel_aspect_ = gif_lsd->pixel_aspect;
- return CFX_GifDecodeStatus::Success;
+ CFX_GifDecodeStatus status = ReadGifSignature();
+ if (status != CFX_GifDecodeStatus::Success)
+ return status;
+ return ReadLogicalScreenDescriptor();
}
CFX_GifDecodeStatus CFX_GifContext::GetFrame() {
@@ -383,7 +350,15 @@ int32_t CFX_GifContext::GetFrameNum() const {
}
uint8_t* CFX_GifContext::ReadData(uint8_t** des_buf_pp, uint32_t data_size) {
- if (avail_in_ < skip_size_ + data_size)
+ if (!next_in_)
+ return nullptr;
+ if (avail_in_ <= skip_size_)
+ return nullptr;
+ if (!des_buf_pp)
+ return nullptr;
+ if (data_size == 0)
+ return nullptr;
+ if (avail_in_ - skip_size_ < data_size)
return nullptr;
*des_buf_pp = next_in_ + skip_size_;
@@ -391,6 +366,53 @@ uint8_t* CFX_GifContext::ReadData(uint8_t** des_buf_pp, uint32_t data_size) {
return *des_buf_pp;
}
+CFX_GifDecodeStatus CFX_GifContext::ReadGifSignature() {
+ CFX_GifHeader* header = nullptr;
+ uint32_t skip_size_org = skip_size_;
+ if (!ReadData(reinterpret_cast<uint8_t**>(&header), 6)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+
+ if (strncmp(header->signature, kGifSignature87, 6) != 0 &&
+ strncmp(header->signature, kGifSignature89, 6) != 0)
+ return CFX_GifDecodeStatus::Error;
+
+ return CFX_GifDecodeStatus::Success;
+}
+
+CFX_GifDecodeStatus CFX_GifContext::ReadLogicalScreenDescriptor() {
+ CFX_GifLocalScreenDescriptor* lsd = nullptr;
+ uint32_t skip_size_org = skip_size_;
+ if (!ReadData(reinterpret_cast<uint8_t**>(&lsd), 7)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+
+ if (lsd->global_flags.global_pal) {
+ uint32_t global_pal_size = unsigned(2 << lsd->global_flags.pal_bits) * 3u;
+ uint8_t* global_pal = nullptr;
+ if (!ReadData(&global_pal, global_pal_size)) {
+ skip_size_ = skip_size_org;
+ return CFX_GifDecodeStatus::Unfinished;
+ }
+
+ global_pal_exp_ = lsd->global_flags.pal_bits;
+ global_sort_flag_ = lsd->global_flags.sort_flag;
+ global_color_resolution_ = lsd->global_flags.color_resolution;
+ global_palette_.resize(global_pal_size / 3);
+ memcpy(global_palette_.data(), global_pal, global_pal_size);
+ }
+
+ width_ = static_cast<int>(
+ FXWORD_GET_MSBFIRST(reinterpret_cast<uint8_t*>(&lsd->width)));
+ height_ = static_cast<int>(
+ FXWORD_GET_MSBFIRST(reinterpret_cast<uint8_t*>(&lsd->height)));
+ bc_index_ = lsd->bc_index;
+ pixel_aspect_ = lsd->pixel_aspect;
+ return CFX_GifDecodeStatus::Success;
+}
+
void CFX_GifContext::SaveDecodingStatus(int32_t status) {
decode_status_ = status;
next_in_ += skip_size_;