@@ -124,6 +124,7 @@ int IMG_InitJPG()
124
124
125
125
return 0 ;
126
126
}
127
+
127
128
void IMG_QuitJPG ()
128
129
{
129
130
if ( lib .loaded == 0 ) {
@@ -337,89 +338,106 @@ static void output_no_message(j_common_ptr cinfo)
337
338
(void )cinfo ;
338
339
}
339
340
340
- /* Load a JPEG type image from an SDL datasource */
341
- SDL_Surface * IMG_LoadJPG_RW (SDL_RWops * src )
342
- {
343
- Sint64 start ;
341
+ struct loadjpeg_vars {
342
+ const char * error ;
343
+ SDL_Surface * surface ;
344
344
struct jpeg_decompress_struct cinfo ;
345
- JSAMPROW rowptr [1 ];
346
- SDL_Surface * surface = NULL ;
347
345
struct my_error_mgr jerr ;
346
+ };
348
347
349
- if ( !src ) {
350
- /* The error message has been set in SDL_RWFromFile */
351
- return NULL ;
352
- }
353
- start = SDL_RWtell (src );
354
-
355
- if ( (IMG_Init (IMG_INIT_JPG ) & IMG_INIT_JPG ) == 0 ) {
356
- return NULL ;
357
- }
348
+ /* Load a JPEG type image from an SDL datasource */
349
+ static SDL_bool LIBJPEG_LoadJPG_RW (SDL_RWops * src , struct loadjpeg_vars * vars )
350
+ {
351
+ JSAMPROW rowptr [1 ];
358
352
359
353
/* Create a decompression structure and load the JPEG header */
360
- cinfo .err = lib .jpeg_std_error (& jerr .errmgr );
361
- jerr .errmgr .error_exit = my_error_exit ;
362
- jerr .errmgr .output_message = output_no_message ;
363
- #ifdef _MSC_VER
364
- #pragma warning(disable:4611) /* warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable */
365
- #endif
366
- if (setjmp (jerr .escape )) {
354
+ vars -> cinfo .err = lib .jpeg_std_error (& vars -> jerr .errmgr );
355
+ vars -> jerr .errmgr .error_exit = my_error_exit ;
356
+ vars -> jerr .errmgr .output_message = output_no_message ;
357
+ if (setjmp (vars -> jerr .escape )) {
367
358
/* If we get here, libjpeg found an error */
368
- lib .jpeg_destroy_decompress (& cinfo );
369
- if ( surface != NULL ) {
370
- SDL_FreeSurface (surface );
371
- }
372
- SDL_RWseek (src , start , RW_SEEK_SET );
373
- IMG_SetError ("JPEG loading error" );
374
- return NULL ;
359
+ lib .jpeg_destroy_decompress (& vars -> cinfo );
360
+ vars -> error = "JPEG loading error" ;
361
+ return SDL_FALSE ;
375
362
}
376
363
377
- lib .jpeg_create_decompress (& cinfo );
378
- jpeg_SDL_RW_src (& cinfo , src );
379
- lib .jpeg_read_header (& cinfo , TRUE);
364
+ lib .jpeg_create_decompress (& vars -> cinfo );
365
+ jpeg_SDL_RW_src (& vars -> cinfo , src );
366
+ lib .jpeg_read_header (& vars -> cinfo , TRUE);
380
367
381
- if ( cinfo .num_components == 4 ) {
368
+ if ( vars -> cinfo .num_components == 4 ) {
382
369
/* Set 32-bit Raw output */
383
- cinfo .out_color_space = JCS_CMYK ;
384
- cinfo .quantize_colors = FALSE;
385
- lib .jpeg_calc_output_dimensions (& cinfo );
370
+ vars -> cinfo .out_color_space = JCS_CMYK ;
371
+ vars -> cinfo .quantize_colors = FALSE;
372
+ lib .jpeg_calc_output_dimensions (& vars -> cinfo );
386
373
387
374
/* Allocate an output surface to hold the image */
388
- surface = SDL_CreateRGBSurfaceWithFormat (0 , cinfo .output_width , cinfo .output_height , 0 , SDL_PIXELFORMAT_BGRA32 );
375
+ vars -> surface = SDL_CreateRGBSurfaceWithFormat (0 , vars -> cinfo .output_width , vars -> cinfo .output_height , 0 , SDL_PIXELFORMAT_BGRA32 );
389
376
} else {
390
377
/* Set 24-bit RGB output */
391
- cinfo .out_color_space = JCS_RGB ;
392
- cinfo .quantize_colors = FALSE;
378
+ vars -> cinfo .out_color_space = JCS_RGB ;
379
+ vars -> cinfo .quantize_colors = FALSE;
393
380
#ifdef FAST_JPEG
394
- cinfo .scale_num = 1 ;
395
- cinfo .scale_denom = 1 ;
396
- cinfo .dct_method = JDCT_FASTEST ;
397
- cinfo .do_fancy_upsampling = FALSE;
381
+ vars -> cinfo .scale_num = 1 ;
382
+ vars -> cinfo .scale_denom = 1 ;
383
+ vars -> cinfo .dct_method = JDCT_FASTEST ;
384
+ vars -> cinfo .do_fancy_upsampling = FALSE;
398
385
#endif
399
- lib .jpeg_calc_output_dimensions (& cinfo );
386
+ lib .jpeg_calc_output_dimensions (& vars -> cinfo );
400
387
401
388
/* Allocate an output surface to hold the image */
402
- surface = SDL_CreateRGBSurfaceWithFormat (0 , cinfo .output_width , cinfo .output_height , 0 , SDL_PIXELFORMAT_RGB24 );
389
+ vars -> surface = SDL_CreateRGBSurfaceWithFormat (0 , vars -> cinfo .output_width , vars -> cinfo .output_height , 0 , SDL_PIXELFORMAT_RGB24 );
403
390
}
404
391
405
- if ( surface == NULL ) {
406
- lib .jpeg_destroy_decompress (& cinfo );
407
- SDL_RWseek (src , start , RW_SEEK_SET );
408
- IMG_SetError ("Out of memory" );
409
- return NULL ;
392
+ if (!vars -> surface ) {
393
+ lib .jpeg_destroy_decompress (& vars -> cinfo );
394
+ return SDL_FALSE ;
410
395
}
411
396
412
397
/* Decompress the image */
413
- lib .jpeg_start_decompress (& cinfo );
414
- while ( cinfo .output_scanline < cinfo .output_height ) {
415
- rowptr [0 ] = (JSAMPROW )(Uint8 * )surface -> pixels +
416
- cinfo .output_scanline * surface -> pitch ;
417
- lib .jpeg_read_scanlines (& cinfo , rowptr , (JDIMENSION ) 1 );
398
+ lib .jpeg_start_decompress (& vars -> cinfo );
399
+ while (vars -> cinfo .output_scanline < vars -> cinfo .output_height ) {
400
+ rowptr [0 ] = (JSAMPROW )(Uint8 * )vars -> surface -> pixels +
401
+ vars -> cinfo .output_scanline * vars -> surface -> pitch ;
402
+ lib .jpeg_read_scanlines (& vars -> cinfo , rowptr , (JDIMENSION ) 1 );
403
+ }
404
+ lib .jpeg_finish_decompress (& vars -> cinfo );
405
+ lib .jpeg_destroy_decompress (& vars -> cinfo );
406
+
407
+ return SDL_TRUE ;
408
+ }
409
+
410
+ SDL_Surface * IMG_LoadJPG_RW (SDL_RWops * src )
411
+ {
412
+ Sint64 start ;
413
+ struct loadjpeg_vars vars ;
414
+
415
+ if (!src ) {
416
+ /* The error message has been set in SDL_RWFromFile */
417
+ return NULL ;
418
+ }
419
+
420
+ if ((IMG_Init (IMG_INIT_JPG ) & IMG_INIT_JPG ) == 0 ) {
421
+ return NULL ;
422
+ }
423
+
424
+ start = SDL_RWtell (src );
425
+ SDL_zero (vars );
426
+
427
+ if (LIBJPEG_LoadJPG_RW (src , & vars )) {
428
+ return vars .surface ;
429
+ }
430
+
431
+ /* this may clobber a set error if seek fails: don't care. */
432
+ SDL_RWseek (src , start , RW_SEEK_SET );
433
+ if (vars .surface ) {
434
+ SDL_FreeSurface (vars .surface );
435
+ }
436
+ if (vars .error ) {
437
+ IMG_SetError ("%s" , vars .error );
418
438
}
419
- lib .jpeg_finish_decompress (& cinfo );
420
- lib .jpeg_destroy_decompress (& cinfo );
421
439
422
- return ( surface ) ;
440
+ return NULL ;
423
441
}
424
442
425
443
#define OUTPUT_BUFFER_SIZE 4096
0 commit comments