From 9f04be1e7acd0508aaddbe194ab41e637e642f19 Mon Sep 17 00:00:00 2001
From: Simon McVittie <[EMAIL REDACTED]>
Date: Mon, 11 Mar 2024 17:34:43 +0000
Subject: [PATCH] JPEG: Factor out the middle of IMG_SaveJPG_RW_jpeglib
No functional change intended. We'll need to use setjmp() in this
function in a subsequent commit, so ensure that its state doesn't
include any local variables that are used both "above" and "below"
the stack level at which we will call setjmp().
Signed-off-by: Simon McVittie <smcv@collabora.com>
---
src/IMG_jpg.c | 72 ++++++++++++++++++++++++++++++---------------------
1 file changed, 43 insertions(+), 29 deletions(-)
diff --git a/src/IMG_jpg.c b/src/IMG_jpg.c
index 41e89aca..2bc0a969 100644
--- a/src/IMG_jpg.c
+++ b/src/IMG_jpg.c
@@ -477,15 +477,52 @@ static void jpeg_SDL_RW_dest(j_compress_ptr cinfo, SDL_RWops *ctx)
dest->pub.free_in_buffer = OUTPUT_BUFFER_SIZE;
}
+struct savejpeg_vars
+{
+ struct jpeg_compress_struct cinfo;
+ struct my_error_mgr jerr;
+};
+
+static int JPEG_SaveJPEG_RW(struct savejpeg_vars *vars, SDL_Surface *jpeg_surface, SDL_RWops *dst, int quality)
+{
+ /* Create a compression structure and load the JPEG header */
+ vars->cinfo.err = lib.jpeg_std_error(&vars->jerr.errmgr);
+ vars->jerr.errmgr.error_exit = my_error_exit;
+ vars->jerr.errmgr.output_message = output_no_message;
+
+ lib.jpeg_create_compress(&vars->cinfo);
+ jpeg_SDL_RW_dest(&vars->cinfo, dst);
+
+ vars->cinfo.image_width = jpeg_surface->w;
+ vars->cinfo.image_height = jpeg_surface->h;
+ vars->cinfo.in_color_space = JCS_RGB;
+ vars->cinfo.input_components = 3;
+
+ lib.jpeg_set_defaults(&vars->cinfo);
+ lib.jpeg_set_quality(&vars->cinfo, quality, TRUE);
+ lib.jpeg_start_compress(&vars->cinfo, TRUE);
+
+ while (vars->cinfo.next_scanline < vars->cinfo.image_height) {
+ JSAMPROW row_pointer[1];
+ int offset = vars->cinfo.next_scanline * jpeg_surface->pitch;
+
+ row_pointer[0] = ((Uint8*)jpeg_surface->pixels) + offset;
+ lib.jpeg_write_scanlines(&vars->cinfo, row_pointer, 1);
+ }
+
+ lib.jpeg_finish_compress(&vars->cinfo);
+ lib.jpeg_destroy_compress(&vars->cinfo);
+ return 0;
+}
+
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 */
+ struct savejpeg_vars vars;
static const Uint32 jpg_format = SDL_PIXELFORMAT_RGB24;
- struct jpeg_compress_struct cinfo;
- struct my_error_mgr jerr;
- JSAMPROW row_pointer[1];
SDL_Surface* jpeg_surface = surface;
+ int ret;
if (!IMG_Init(IMG_INIT_JPG)) {
return -1;
@@ -499,36 +536,13 @@ static int IMG_SaveJPG_RW_jpeglib(SDL_Surface *surface, SDL_RWops *dst, int qual
}
}
- /* Create a decompression structure and load the JPEG header */
- cinfo.err = lib.jpeg_std_error(&jerr.errmgr);
- jerr.errmgr.error_exit = my_error_exit;
- jerr.errmgr.output_message = output_no_message;
-
- lib.jpeg_create_compress(&cinfo);
- jpeg_SDL_RW_dest(&cinfo, dst);
-
- cinfo.image_width = jpeg_surface->w;
- cinfo.image_height = jpeg_surface->h;
- cinfo.in_color_space = JCS_RGB;
- cinfo.input_components = 3;
-
- lib.jpeg_set_defaults(&cinfo);
- lib.jpeg_set_quality(&cinfo, quality, TRUE);
- lib.jpeg_start_compress(&cinfo, TRUE);
-
- while (cinfo.next_scanline < cinfo.image_height) {
- int offset = cinfo.next_scanline * jpeg_surface->pitch;
- row_pointer[0] = ((Uint8*)jpeg_surface->pixels) + offset;
- lib.jpeg_write_scanlines(&cinfo, row_pointer, 1);
- }
-
- lib.jpeg_finish_compress(&cinfo);
- lib.jpeg_destroy_compress(&cinfo);
+ SDL_zero(vars);
+ ret = JPEG_SaveJPEG_RW(&vars, jpeg_surface, dst, quality);
if (jpeg_surface != surface) {
SDL_FreeSurface(jpeg_surface);
}
- return 0;
+ return ret;
}
#elif defined(USE_STBIMAGE)