From 9f04be1e7acd0508aaddbe194ab41e637e642f19 Mon Sep 17 00:00:00 2001 From: Simon McVittie 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 --- 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)