Skip to content

Commit

Permalink
Fixed memory leak when saving PNG and JPG files if SDL_image isn't bu…
Browse files Browse the repository at this point in the history
…ilt with save support
  • Loading branch information
slouken committed Jan 25, 2024
1 parent 5198829 commit d2c7e09
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 170 deletions.
60 changes: 23 additions & 37 deletions src/IMG_jpg.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ static void jpeg_SDL_RW_dest(j_compress_ptr cinfo, SDL_RWops *ctx)
dest->pub.free_in_buffer = OUTPUT_BUFFER_SIZE;
}

static int IMG_SaveJPG_RW_jpeglib(SDL_Surface *surface, SDL_RWops *dst, int freedst, int quality)
static int IMG_SaveJPG_RW_jpeglib(SDL_Surface *surface, SDL_RWops *dst, int quality)
{
/* The JPEG library reads bytes in R,G,B order, so this is the right
* encoding for either endianness */
Expand All @@ -487,22 +487,16 @@ static int IMG_SaveJPG_RW_jpeglib(SDL_Surface *surface, SDL_RWops *dst, int free
struct my_error_mgr jerr;
JSAMPROW row_pointer[1];
SDL_Surface* jpeg_surface = surface;
int result = -1;

if (!dst) {
IMG_SetError("Passed NULL dst");
goto done;
}

if (!IMG_Init(IMG_INIT_JPG)) {
goto done;
return -1;
}

/* Convert surface to format we can save */
if (surface->format->format != jpg_format) {
jpeg_surface = SDL_ConvertSurfaceFormat(surface, jpg_format);
if (!jpeg_surface) {
goto done;
return -1;
}
}

Expand Down Expand Up @@ -535,14 +529,7 @@ static int IMG_SaveJPG_RW_jpeglib(SDL_Surface *surface, SDL_RWops *dst, int free
if (jpeg_surface != surface) {
SDL_DestroySurface(jpeg_surface);
}

result = 0;

done:
if (freedst) {
SDL_RWclose(dst);
}
return result;
return 0;
}

#elif defined(USE_STBIMAGE)
Expand Down Expand Up @@ -694,24 +681,19 @@ static void IMG_SaveJPG_RW_tinyjpeg_callback(void* context, void* data, int size
SDL_RWwrite((SDL_RWops*) context, data, size);
}

static int IMG_SaveJPG_RW_tinyjpeg(SDL_Surface *surface, SDL_RWops *dst, int freedst, int quality)
static int IMG_SaveJPG_RW_tinyjpeg(SDL_Surface *surface, SDL_RWops *dst, int quality)
{
/* The JPEG library reads bytes in R,G,B order, so this is the right
* encoding for either endianness */
static const Uint32 jpg_format = SDL_PIXELFORMAT_RGB24;
SDL_Surface* jpeg_surface = surface;
int result = -1;

if (!dst) {
SDL_SetError("Passed NULL dst");
goto done;
}

/* Convert surface to format we can save */
if (surface->format->format != jpg_format) {
jpeg_surface = SDL_ConvertSurfaceFormat(surface, jpg_format);
if (!jpeg_surface) {
goto done;
return -1;
}
}

Expand Down Expand Up @@ -742,11 +724,6 @@ static int IMG_SaveJPG_RW_tinyjpeg(SDL_Surface *surface, SDL_RWops *dst, int fre
if (result < 0) {
SDL_SetError("tinyjpeg error");
}

done:
if (freedst) {
SDL_RWclose(dst);
}
return result;
}

Expand All @@ -764,22 +741,31 @@ int IMG_SaveJPG(SDL_Surface *surface, const char *file, int quality)

int IMG_SaveJPG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst, int quality)
{
int result = -1;

if (!dst) {
return IMG_SetError("Passed NULL dst");
}

#if SDL_IMAGE_SAVE_JPG
#ifdef USE_JPEGLIB
if ((IMG_Init(IMG_INIT_JPG) & IMG_INIT_JPG) != 0) {
if (IMG_SaveJPG_RW_jpeglib(surface, dst, freedst, quality) == 0) {
return 0;
}
if (result < 0) {
result = IMG_SaveJPG_RW_jpeglib(surface, dst, quality);
}
#endif

#if defined(LOAD_JPG_DYNAMIC) || !defined(WANT_JPEGLIB)
return IMG_SaveJPG_RW_tinyjpeg(surface, dst, freedst, quality);
#else
return -1;
if (result < 0) {
result = IMG_SaveJPG_RW_tinyjpeg(surface, dst, quality);
}
#endif

#else
return IMG_SetError("SDL_image built without JPEG save support");
result = IMG_SetError("SDL_image built without JPEG save support");
#endif

if (freedst) {
SDL_RWclose(dst);
}
return result;
}
Loading

0 comments on commit d2c7e09

Please sign in to comment.