1

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
yhenon
  • 4,111
  • 1
  • 18
  • 34
  • 1
    Can you somehow check if the GIF may be malformed? – Jongware Oct 22 '15 at 21:02
  • Thanks for your input. I've tested with multiple gifs, including some from the internet + some that come with giflib, so I don't think that's the issue here. – yhenon Oct 22 '15 at 21:04
  • 1
    having lots of .'s and ->'s in the same statement can confuse matters. Could you try examining the validity of gif->SavedImages[0], then only if that is valid, dereferencing RasterBits[0]? – Jimmy Oct 22 '15 at 21:06
  • Thanks Jimmy, please see my edit. – yhenon Oct 22 '15 at 21:09
  • 1
    Can you post a link to an online GIF on which this code fails? (I don't think you can use the standard "upload-your-image", I think it translates everything to PNG!) – Jongware Oct 22 '15 at 21:09
  • 1
    I've added some link to gifs in my post. – yhenon Oct 22 '15 at 21:15
  • Your code seems fine. [Have you tried version 4](https://stackoverflow.com/a/16893150/865719) ? – maddouri Oct 24 '15 at 21:42
  • Let me look into that. This seems like a rather significant bug for such an old codebase though. – yhenon Oct 24 '15 at 21:48

1 Answers1

1

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.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • Thanks Sam. I'm rather confident that this is a bug in giflib now. Works for me in 4.1.1 but fails in 5.1.6. I've submitted a bug report to the giflib project: http://sourceforge.net/p/giflib/bugs/68/ – yhenon Oct 25 '15 at 16:58