[SDL] PNG loading & multiple heaps (WIN2000) - solved

Antonin Hildebrand hildi at atlas.cz
Wed Apr 12 00:06:32 PDT 2000

> Basically the fix involves adding a function the SDL_image API that
> frees a surface created by the IMG_Load functions.

who needs fast solution right now, here comes reparkit:

------------------ add to SDL_image.h
extern DECLSPEC void IMG_FreeSurfacePNG(SDL_Surface *surface);
------------------ cut here

------------------ add to IMG_png.c in section with defined PNG_LOAD
/* Free a surface created by IMG_LoadPNG function only !

   IMG_LoadPNG_RW functions allocates surface pixels this way:
   surface->pixels = malloc(surface->h*surface->pitch);
   other allocations for surface is done by SDL functions

   Under WinNT & Win2000 each module has its own heap.
   All memory allocated in the module must be freed in that module too !

   (surface->pixels) allocation causes that calling SDL_FreeSurface
   on returned surface from IMG_LoadPNG_RW fails.
   SDL_FreeSurface resides in SDL module
   and calls free() on memory allocated
   by IMG_LoadPNG_RW in SDL_image module.

   this is temporary hack, problem occurs only when loading PNGs
   other IMG_LoadXXX code is "heap-safe"
void IMG_FreeSurfacePNG(SDL_Surface *surface)
  /* Deallocate surface memory, which resides in the SDL_images's heap */
  if ( surface->pixels &&
      ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC) ) {
    surface->pixels = NULL;
  /* Free anything that's not NULL, and not the screen surface */
------------------- cut here

my buggy code should be fixed to:
SDL_Surface* LoadImage(SDL_RWops *src)
  SDL_Surface *s;
  SDL_Surface *temp;
  temp = IMG_LoadPNG_RW(src);
  if (!temp) return NULL;
  s = SDL_DisplayFormat(temp);
  IMG_FreeSurfacePNG(temp);                     // here is change
  return s;

works on my W2k
better solution could be letting SDL do pixels allocation instead of
SDL_image's PNG loader

Antonin Hildebrand aka Woid
[hildi at atlas.cz]

More information about the SDL mailing list