IMG_jpg.c
changeset 143 e01fee7bdf3b
parent 123 1f7908a9cabb
child 146 aaa5876f41ab
     1.1 --- a/IMG_jpg.c	Fri May 12 02:58:31 2006 +0000
     1.2 +++ b/IMG_jpg.c	Fri May 12 05:08:03 2006 +0000
     1.3 @@ -38,6 +38,133 @@
     1.4  /* Define this for quicker (but less perfect) JPEG identification */
     1.5  #define FAST_IS_JPEG
     1.6  
     1.7 +static struct {
     1.8 +	int loaded;
     1.9 +	void *handle;
    1.10 +	void (*jpeg_calc_output_dimensions) (j_decompress_ptr cinfo);
    1.11 +	void (*jpeg_CreateDecompress) (j_decompress_ptr cinfo, int version, size_t structsize);
    1.12 +	void (*jpeg_destroy_decompress) (j_decompress_ptr cinfo);
    1.13 +	boolean (*jpeg_finish_decompress) (j_decompress_ptr cinfo);
    1.14 +	int (*jpeg_read_header) (j_decompress_ptr cinfo, boolean require_image);
    1.15 +	JDIMENSION (*jpeg_read_scanlines) (j_decompress_ptr cinfo, JSAMPARRAY scanlines, JDIMENSION max_lines);
    1.16 +	boolean (*jpeg_resync_to_restart) (j_decompress_ptr cinfo, int desired);
    1.17 +	boolean (*jpeg_start_decompress) (j_decompress_ptr cinfo);
    1.18 +	struct jpeg_error_mgr * (*jpeg_std_error) (struct jpeg_error_mgr * err);
    1.19 +} lib;
    1.20 +
    1.21 +#ifdef LOAD_JPG_DYNAMIC
    1.22 +int IMG_InitJPG()
    1.23 +{
    1.24 +	if ( lib.loaded == 0 ) {
    1.25 +		lib.handle = SDL_LoadObject(LOAD_JPG_DYNAMIC);
    1.26 +		if ( lib.handle == NULL ) {
    1.27 +			return -1;
    1.28 +		}
    1.29 +		lib.jpeg_calc_output_dimensions =
    1.30 +			(void (*) (j_decompress_ptr))
    1.31 +			SDL_LoadFunction(lib.handle, "jpeg_calc_output_dimensions");
    1.32 +		if ( lib.jpeg_calc_output_dimensions == NULL ) {
    1.33 +			SDL_UnloadObject(lib.handle);
    1.34 +			return -1;
    1.35 +		}
    1.36 +		lib.jpeg_CreateDecompress = 
    1.37 +			(void (*) (j_decompress_ptr, int, size_t))
    1.38 +			SDL_LoadFunction(lib.handle, "jpeg_CreateDecompress");
    1.39 +		if ( lib.jpeg_CreateDecompress == NULL ) {
    1.40 +			SDL_UnloadObject(lib.handle);
    1.41 +			return -1;
    1.42 +		}
    1.43 +		lib.jpeg_destroy_decompress = 
    1.44 +			(void (*) (j_decompress_ptr))
    1.45 +			SDL_LoadFunction(lib.handle, "jpeg_destroy_decompress");
    1.46 +		if ( lib.jpeg_destroy_decompress == NULL ) {
    1.47 +			SDL_UnloadObject(lib.handle);
    1.48 +			return -1;
    1.49 +		}
    1.50 +		lib.jpeg_finish_decompress = 
    1.51 +			(boolean (*) (j_decompress_ptr))
    1.52 +			SDL_LoadFunction(lib.handle, "jpeg_finish_decompress");
    1.53 +		if ( lib.jpeg_finish_decompress == NULL ) {
    1.54 +			SDL_UnloadObject(lib.handle);
    1.55 +			return -1;
    1.56 +		}
    1.57 +		lib.jpeg_read_header = 
    1.58 +			(int (*) (j_decompress_ptr, boolean))
    1.59 +			SDL_LoadFunction(lib.handle, "jpeg_read_header");
    1.60 +		if ( lib.jpeg_read_header == NULL ) {
    1.61 +			SDL_UnloadObject(lib.handle);
    1.62 +			return -1;
    1.63 +		}
    1.64 +		lib.jpeg_read_scanlines = 
    1.65 +			(JDIMENSION (*) (j_decompress_ptr, JSAMPARRAY, JDIMENSION))
    1.66 +			SDL_LoadFunction(lib.handle, "jpeg_read_scanlines");
    1.67 +		if ( lib.jpeg_read_scanlines == NULL ) {
    1.68 +			SDL_UnloadObject(lib.handle);
    1.69 +			return -1;
    1.70 +		}
    1.71 +		lib.jpeg_resync_to_restart = 
    1.72 +			(boolean (*) (j_decompress_ptr, int))
    1.73 +			SDL_LoadFunction(lib.handle, "jpeg_resync_to_restart");
    1.74 +		if ( lib.jpeg_resync_to_restart == NULL ) {
    1.75 +			SDL_UnloadObject(lib.handle);
    1.76 +			return -1;
    1.77 +		}
    1.78 +		lib.jpeg_start_decompress = 
    1.79 +			(boolean (*) (j_decompress_ptr))
    1.80 +			SDL_LoadFunction(lib.handle, "jpeg_start_decompress");
    1.81 +		if ( lib.jpeg_start_decompress == NULL ) {
    1.82 +			SDL_UnloadObject(lib.handle);
    1.83 +			return -1;
    1.84 +		}
    1.85 +		lib.jpeg_std_error = 
    1.86 +			(struct jpeg_error_mgr * (*) (struct jpeg_error_mgr *))
    1.87 +			SDL_LoadFunction(lib.handle, "jpeg_std_error");
    1.88 +		if ( lib.jpeg_std_error == NULL ) {
    1.89 +			SDL_UnloadObject(lib.handle);
    1.90 +			return -1;
    1.91 +		}
    1.92 +	}
    1.93 +	++lib.loaded;
    1.94 +
    1.95 +	return 0;
    1.96 +}
    1.97 +void IMG_QuitJPG()
    1.98 +{
    1.99 +	if ( lib.loaded == 0 ) {
   1.100 +		return;
   1.101 +	}
   1.102 +	if ( lib.loaded == 1 ) {
   1.103 +		SDL_UnloadObject(lib.handle);
   1.104 +	}
   1.105 +	--lib.loaded;
   1.106 +}
   1.107 +#else
   1.108 +int IMG_InitJPG()
   1.109 +{
   1.110 +	if ( lib.loaded == 0 ) {
   1.111 +		lib.jpeg_calc_output_dimensions = jpeg_calc_output_dimensions;
   1.112 +		lib.jpeg_CreateDecompress = jpeg_CreateDecompress;
   1.113 +		lib.jpeg_destroy_decompress = jpeg_destroy_decompress;
   1.114 +		lib.jpeg_finish_decompress = jpeg_finish_decompress;
   1.115 +		lib.jpeg_read_header = jpeg_read_header;
   1.116 +		lib.jpeg_read_scanlines = jpeg_read_scanlines;
   1.117 +		lib.jpeg_resync_to_restart = jpeg_resync_to_restart;
   1.118 +		lib.jpeg_start_decompress = jpeg_start_decompress;
   1.119 +		lib.jpeg_std_error = jpeg_std_error;
   1.120 +	}
   1.121 +	++lib.loaded;
   1.122 +}
   1.123 +void IMG_QuitJPG()
   1.124 +{
   1.125 +	if ( lib.loaded == 0 ) {
   1.126 +		return;
   1.127 +	}
   1.128 +	if ( lib.loaded == 1 ) {
   1.129 +	}
   1.130 +	--lib.loaded;
   1.131 +}
   1.132 +#endif /* LOAD_JPG_DYNAMIC */
   1.133 +
   1.134  /* See if an image is contained in a data source */
   1.135  int IMG_isJPG(SDL_RWops *src)
   1.136  {
   1.137 @@ -210,7 +337,7 @@
   1.138    src->pub.init_source = init_source;
   1.139    src->pub.fill_input_buffer = fill_input_buffer;
   1.140    src->pub.skip_input_data = skip_input_data;
   1.141 -  src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
   1.142 +  src->pub.resync_to_restart = lib.jpeg_resync_to_restart; /* use default method */
   1.143    src->pub.term_source = term_source;
   1.144    src->ctx = ctx;
   1.145    src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
   1.146 @@ -248,30 +375,35 @@
   1.147  	}
   1.148  	start = SDL_RWtell(src);
   1.149  
   1.150 +	if ( IMG_InitJPG() < 0 ) {
   1.151 +		return NULL;
   1.152 +	}
   1.153 +
   1.154  	/* Create a decompression structure and load the JPEG header */
   1.155 -	cinfo.err = jpeg_std_error(&jerr.errmgr);
   1.156 +	cinfo.err = lib.jpeg_std_error(&jerr.errmgr);
   1.157  	jerr.errmgr.error_exit = my_error_exit;
   1.158  	jerr.errmgr.output_message = output_no_message;
   1.159  	if(setjmp(jerr.escape)) {
   1.160  		/* If we get here, libjpeg found an error */
   1.161 -		jpeg_destroy_decompress(&cinfo);
   1.162 +		lib.jpeg_destroy_decompress(&cinfo);
   1.163  		if ( surface != NULL ) {
   1.164  			SDL_FreeSurface(surface);
   1.165  		}
   1.166  		SDL_RWseek(src, start, SEEK_SET);
   1.167 +		IMG_QuitJPG();
   1.168  		IMG_SetError("JPEG loading error");
   1.169  		return NULL;
   1.170  	}
   1.171  
   1.172 -	jpeg_create_decompress(&cinfo);
   1.173 +	lib.jpeg_create_decompress(&cinfo);
   1.174  	jpeg_SDL_RW_src(&cinfo, src);
   1.175 -	jpeg_read_header(&cinfo, TRUE);
   1.176 +	lib.jpeg_read_header(&cinfo, TRUE);
   1.177  
   1.178  	if(cinfo.num_components == 4) {
   1.179  		/* Set 32-bit Raw output */
   1.180  		cinfo.out_color_space = JCS_CMYK;
   1.181  		cinfo.quantize_colors = FALSE;
   1.182 -		jpeg_calc_output_dimensions(&cinfo);
   1.183 +		lib.jpeg_calc_output_dimensions(&cinfo);
   1.184  
   1.185  		/* Allocate an output surface to hold the image */
   1.186  		surface = SDL_AllocSurface(SDL_SWSURFACE,
   1.187 @@ -291,7 +423,7 @@
   1.188  		cinfo.dct_method = JDCT_FASTEST;
   1.189  		cinfo.do_fancy_upsampling = FALSE;
   1.190  #endif
   1.191 -		jpeg_calc_output_dimensions(&cinfo);
   1.192 +		lib.jpeg_calc_output_dimensions(&cinfo);
   1.193  
   1.194  		/* Allocate an output surface to hold the image */
   1.195  		surface = SDL_AllocSurface(SDL_SWSURFACE,
   1.196 @@ -305,21 +437,24 @@
   1.197  	}
   1.198  
   1.199  	if ( surface == NULL ) {
   1.200 -		jpeg_destroy_decompress(&cinfo);
   1.201 +		lib.jpeg_destroy_decompress(&cinfo);
   1.202  		SDL_RWseek(src, start, SEEK_SET);
   1.203 +		IMG_QuitJPG();
   1.204  		IMG_SetError("Out of memory");
   1.205  		return NULL;
   1.206  	}
   1.207  
   1.208  	/* Decompress the image */
   1.209 -	jpeg_start_decompress(&cinfo);
   1.210 +	lib.jpeg_start_decompress(&cinfo);
   1.211  	while ( cinfo.output_scanline < cinfo.output_height ) {
   1.212  		rowptr[0] = (JSAMPROW)(Uint8 *)surface->pixels +
   1.213  		                    cinfo.output_scanline * surface->pitch;
   1.214 -		jpeg_read_scanlines(&cinfo, rowptr, (JDIMENSION) 1);
   1.215 +		lib.jpeg_read_scanlines(&cinfo, rowptr, (JDIMENSION) 1);
   1.216  	}
   1.217 -	jpeg_finish_decompress(&cinfo);
   1.218 -	jpeg_destroy_decompress(&cinfo);
   1.219 +	lib.jpeg_finish_decompress(&cinfo);
   1.220 +	lib.jpeg_destroy_decompress(&cinfo);
   1.221 +
   1.222 +	IMG_QuitJPG();
   1.223  
   1.224  	return(surface);
   1.225  }