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