Search code examples
c++visual-studio-2010sdl-2sdl-image

Access violation at 0x00000000 Loading PNG File With SDL_image Library


I am using the SDL2 2.0.3 library with the SDL_image library 2.0.0 in Visual C++ 2010 Express. I am utilizing the SDL_image library to load a variety of PNG and JPEG files from a resources folder. While the library initializes without any errors and loads BMP and JPEG files, it breaks when given a PNG file.

"Unhandled exception at 0x00000000 in appname.exe: 0xC0000005: Access violation."

Inside of my texture manager, (an object that stores and manages textures for the program), is a function to load a texture from a given file name string. Here is the code, including the commented line I used before implementing SDL_image to do the loading. It is within the line bitmapSurface = IMG_Load(... that the exception above is thrown.

/**
 * Attempts to load a given image file and reports to the console any failures
 * 
 * @param fileName The exact file name of the resource to be loaded
 * @return The SDL_Texture loaded from the given fileName
 */
SDL_Texture* TextureManager::loadTexture(string fileName)
{
    //Create our surface in RAM
    SDL_Surface *bitmapSurface = NULL;
    //bitmapSurface = SDL_LoadBMP(fileName.c_str()); //OLD METHOD; standard SDL, BMP only
    bitmapSurface = IMG_Load(fileName.c_str());      //NEW METHOD; SDL_image lib, many formats

    //Verify it exists
    if (bitmapSurface == NULL)
        cout << "Image resource not loaded: " << fileName << " Message: " << IMG_GetError() << endl;

    //Create a texture in VRAM from the surface
    SDL_Texture *bitmapTexture = NULL;
    bitmapTexture = SDL_CreateTextureFromSurface(this->renderer, bitmapSurface);

    //Verify it exists
    if (bitmapTexture == NULL)
        cout << "Failed to create texture: " << fileName << endl;

    return bitmapTexture;
}

Call Stack:

    00000000()  
    SDL2_image.dll!6a887a01()   
    [Frames below may be incorrect and/or missing, no symbols loaded for SDL2_image.dll]    
    SDL2.dll!6c77da4b()     
    SDL2_image.dll!6a88792e()   
    SDL2_image.dll!6a881693()   
    SDL2_image.dll!6a8817e9()   
> appname.exe!TextureManager::loadTexture(std::basic_string<char,std::char_traits<char>,std::allocator<char> > fileName)  Line 143 + 0xe bytes  C++
    00daf5e0()  

Here is the constructor for my TextureManager:

/**
 * Creates a new TextureManager with the current SDL_Renderer
 * 
 * @param renderer The current renderer instance of the current graphic window
 */ 
TextureManager::TextureManager(SDL_Renderer* renderer)
{
    //Assign our renderer link
    this->renderer = renderer;

    //Create the vector to hold textures
    this->textures = new vector<Texture*>();

    //SDL_image initialization
    int flags   = IMG_INIT_JPG|IMG_INIT_PNG;
    int initted = IMG_Init(flags); //Use IMG_Quit(); at closing

    if(initted&flags != flags)
    {
        //Handle error
        printf("IMG_Init: Failed to init required jpg and png support!\n");
        printf("IMG_Init: %s\n", IMG_GetError());
    }
    else
    {
        cout << "SDL_Image initialized for JPEG and PNG support" << endl;
    }
}

For your information, I am using Windows 10 x64, which is up to date. Graphics drivers for dual NVidia GTX 550ti are up to date as well. All DLL files (including the pnglib dll) are in the debug folder and do load. If I remove the DLL file from the program, the image fails to load and provides the message as coded above for NULL surfaces. No exceptions occur.

Question summary: Why is this exception thrown, why is it only thrown for PNG files, and how can I trace it when the call stack's details end at my call that appears to work properly? Am I doing something wrong, or is there a configuration step I may have missed?

EDIT: Thanks to @Nandu I have recompiled the DLL SDL_image, and got a better call stack output here:

    00000000()  
> SDL2_image.dll!IMG_LoadPNG_RW(SDL_RWops * src)  Line 375 + 0x11 bytes C
    SDL2_image.dll!IMG_LoadTyped_RW(SDL_RWops * src, int freesrc, const char * type)  Line 193 + 0x12 bytes C
    SDL2_image.dll!IMG_Load(const char * file)  Line 134 + 0xf bytes    C
    appname.exe!TextureManager::loadTexture(std::basic_string<char,std::char_traits<char>,std::allocator<char> > fileName)  Line 143 + 0xe bytes    C++
    appname.exe!TextureManager::loadFromDirectory(std::basic_string<char,std::char_traits<char>,std::allocator<char> > relPath)  Line 117 + 0x73 bytes  C++
    appname.exe!SDL_main(int argc, char * * argv)  Line 31  C++
    appname.exe!main(int argc, char * * argv)  Line 140 + 0xd bytes C
    appname.exe!__tmainCRTStartup()  Line 555 + 0x19 bytes  C
    appname.exe!mainCRTStartup()  Line 371  C
    kernel32.dll!77963744()     
    [Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]  
    ntdll.dll!77c3a064()    
    ntdll.dll!77c3a02f() 

This suggests the problem is occurring on line 374 of IMG_png.c:

 /* Create the PNG loading context structure */
    png_ptr = lib.png_create_read_struct(PNG_LIBPNG_VER_STRING,
                      NULL,NULL,NULL);

VS reports that lib is NULL at this time, which would explain the error! The question becomes, why is it NULL? It seems this code should be doing a check for that, but nonetheless, nobody else seems to having this problem on the almighty internet.


Solution

  • Thank you all very much for you help, but the problem, as usual, was rather obvious! As noted here by @Gigi: SDL_Image IMG_Load fails on png with: "Failed loading libpng16-16.dll:"

    I suggest you try including all the rest - there may be a dependency that you and I are not aware of. In fact I just checked, and libpng requires zlib: libpng.org/pub/png/libpng.html

    I'm not sure why my original search or suggestions didn't bring that post up.

    I originally excluded the DLLs for other file formats I wasn't using (or initializing in my code), but once I included the zlib DLL, bingo. PNGs load exactly as expected.