【问题标题】:Error when decoding a gif using giflib使用 giflib 解码 gif 时出错
【发布时间】:2016-01-22 07:14:41
【问题描述】:

我正在尝试使用 giflib 解码 .gif 文件。以下代码导致最后一行出现段错误(输出宽度/高度正确)。

GifFileType* gif = DGifOpenFileName(filename.c_str(), &errCode);
if (gif == NULL) {
    std::cout << "Failed to open .gif, return error with type " << errCode << std::endl;
    return false;
}

int slurpReturn = DGifSlurp(gif);
if (slurpReturn != GIF_OK) {
    std::cout << "Failed to read .gif file" << std::endl;
    return false;
}

std::cout << "Opened .gif with width/height = " << gif->SWidth << " " << gif->SHeight << std::endl;
std::cout <<  gif->SavedImages[0].RasterBits[0] << std::endl;

输出:

 Opened .gif with width/height = 921 922
 zsh: segmentation fault (core dumped)  ./bin/testgiflib

据我了解,giflib 应该填充 gif->SavedImages。但调用 DGifSlurp() 后为 NULL。

任何想法都将不胜感激。

编辑

我根据 cmets 中的建议添加了以下代码行:

if (gif->SavedImages == NULL) {
    std::cout <<"SavedImages is NULL" << std::endl;
}

打印该行,表示SavedImages为NULL。

EDIT2

出现此问题的一些 gif(请注意,我无法让它在任何 gif 上工作):

https://upload.wikimedia.org/wikipedia/en/3/39/Specialist_Science_Logo.gif

 GIF image data, version 89a, 921 x 922

https://upload.wikimedia.org/wikipedia/commons/2/25/Nasa-logo.gif

 GIF image data, version 87a, 1008 x 863

【问题讨论】:

  • 您能以某种方式检查 GIF 是否格式错误?
  • 感谢您的意见。我已经用多个 gif 进行了测试,包括一些来自互联网 + 一些来自 giflib,所以我认为这不是这里的问题。
  • 在同一个语句中有很多 .'s 和 ->'s 会混淆问题。您能否尝试检查 gif->SavedImages[0] 的有效性,然后仅在有效的情况下取消引用 RasterBits[0]?
  • 您能否发布一个指向此代码失败的在线 GIF 的链接? (我认为您不能使用标准的“上传您的图像”,我认为它将所有内容都转换为 PNG!)
  • 我在帖子中添加了一些 gif 链接。

标签: c++ giflib


【解决方案1】:

前言:看起来在我的 giflib 版本 4.1.6 中,DGifOpenFileName() 函数只接受文件名参数,并且不返回错误代码,这是一个无关紧要的细节。

在调整 API 更改并添加必要的包含后,我编译并执行了以下完整的独立测试程序:

#include <gif_lib.h>
#include <iostream>

int main()
{
    GifFileType* gif = DGifOpenFileName("Specialist_Science_Logo.gif");

    if (gif == NULL) {
        std::cout << "Failed to open .gif, return error with type " << std::endl;
        return false;
    }

    int slurpReturn = DGifSlurp(gif);
    if (slurpReturn != GIF_OK) {
        std::cout << "Failed to read .gif file" << std::endl;
        return false;
    }

    std::cout << "Opened .gif with width/height = " << gif->SWidth << " " << gif->SHeight << std::endl;
    std::cout <<  (int)gif->SavedImages[0].RasterBits[0] << std::endl;
}

除了头文件的存在、DGifOpenFilename() 签名略有不同以及我将第二个输出行的值转换为显式(int) 的调整之外,这与您的代码相同。此外,代码已更改为显式打开 Specialist_Science_Logo.gif 文件,这是您遇到问题的 GIF 图像文件之一。

此代码在 Fedora x86-64、giflib 4.1.6、gcc 5.5.1 上成功执行,没有任何问题。

使用valgrind 检测示例代码未发现任何内存访问违规。

由此,我得出结论,显示的代码没有任何问题。显示的代码显然是一个更大的应用程序的摘录。该错误存在于此应用程序的其他地方,或者可能是 giflib 本身,并且仅在此处出现。

【讨论】:

  • 谢谢山姆。我相当有信心这是 giflib 现在的一个错误。在 4.1.1 中为我工作,但在 5.1.6 中失败。我已经向 giflib 项目提交了错误报告:sourceforge.net/p/giflib/bugs/68
猜你喜欢
  • 1970-01-01
  • 2016-10-23
  • 2013-05-02
  • 2011-07-24
  • 2013-08-21
  • 1970-01-01
  • 2015-10-28
  • 1970-01-01
  • 2017-05-26
相关资源
最近更新 更多