SDL_image: JPEG: Factor out the middle of IMG_SaveJPG_RW_jpeglib (9f04b)

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)