yhenon
yhenon

Reputation: 4291

Error when decoding a gif using giflib

I'm attempting to decode .gif files using giflib. The following code leads to a segfault on the final line (the output width/height is correct).

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;

Output:

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

As I understand, giflib should populate gif->SavedImages. But it is NULL after calling DGifSlurp().

Any ideas would be appreciated.

EDIT

I've added the following lines of code following a suggestion in comments:

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

The line is printed, indicating that SavedImages is NULL.

EDIT2

Some gifs on which this issue occurs (note that I can't get it to work on any gifs):

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

Upvotes: 1

Views: 1824

Answers (1)

Sam Varshavchik
Sam Varshavchik

Reputation: 118445

Preface: Looks like in my version of giflib, 4.1.6, the DGifOpenFileName() function takes only the filename parameter, and does not return an error code, which is an irrelevant detail.

After adjusting for the API change, and adding the necessary includes, I compiled and executed the following complete, standalone test program:

#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;
}

Except for the presence of the header files, the slightly different DGifOpenFilename() signature, and my tweak to cast the second output line's value to an explicit (int), this is identical to your code. Also, the code was changed to explicitly open the Specialist_Science_Logo.gif file, one of the GIF image files you were having an issue with.

This code executed successfully on Fedora x86-64, giflib 4.1.6, gcc 5.5.1, without any issues.

Instrumenting the sample code with valgrind did not reveal any memory access violations.

From this, I conclude that there is nothing wrong with the shown code. The shown code is obviously an excerpt from a larger application. The bug lies elsewhere in this application, or perhaps giflib itself, and only manifests here.

Upvotes: 1

Related Questions