IMG.c
author Sam Lantinga <slouken@lokigames.com>
Thu, 10 Aug 2000 06:05:39 +0000
changeset 0 76be7dab668c
child 4 b1bb33e907f8
permissions -rw-r--r--
Initial revision
     1 /*
     2     IMGLIB:  An example image loading library for use with SDL
     3     Copyright (C) 1999  Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Library General Public
     7     License as published by the Free Software Foundation; either
     8     version 2 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Library General Public License for more details.
    14 
    15     You should have received a copy of the GNU Library General Public
    16     License along with this library; if not, write to the Free
    17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    18 
    19     Sam Lantinga
    20     5635-34 Springhouse Dr.
    21     Pleasanton, CA 94588 (USA)
    22     slouken@devolution.com
    23 */
    24 
    25 /* A simple library to load images of various formats as SDL surfaces */
    26 
    27 #include <stdio.h>
    28 #include <string.h>
    29 #include <ctype.h>
    30 
    31 #include "SDL_image.h"
    32 
    33 /* Table of image detection and loading functions */
    34 static struct {
    35 	char *type;
    36 	int (*is)(SDL_RWops *src);
    37 	SDL_Surface *(*load)(SDL_RWops *src);
    38 } supported[] = {
    39         /* keep magicless formats first (denoted by is==NULL) */
    40 	{ "TGA", NULL,      IMG_LoadTGA_RW },
    41 	{ "BMP", IMG_isBMP, IMG_LoadBMP_RW },
    42 	{ "PPM", IMG_isPPM, IMG_LoadPPM_RW },
    43 	{ "PCX", IMG_isPCX, IMG_LoadPCX_RW },
    44 	{ "GIF", IMG_isGIF, IMG_LoadGIF_RW },
    45 	{ "JPG", IMG_isJPG, IMG_LoadJPG_RW },
    46 	{ "TIF", IMG_isTIF, IMG_LoadTIF_RW },
    47 	{ "PNG", IMG_isPNG, IMG_LoadPNG_RW },
    48 };
    49 
    50 /* Does the alpha value correspond to transparency or opacity?
    51    Default: transparency
    52 */
    53 int IMG_invert_alpha = 0;
    54 
    55 /* Load an image from a file */
    56 SDL_Surface *IMG_Load(const char *file)
    57 {
    58     SDL_RWops *src = SDL_RWFromFile(file, "rb");
    59     char *ext = strrchr(file, '.');
    60     if(ext)
    61 	ext++;
    62     return IMG_LoadTyped_RW(src, 1, ext);
    63 }
    64 
    65 /* Load an image from an SDL datasource (for compatibility) */
    66 SDL_Surface *IMG_Load_RW(SDL_RWops *src, int freesrc)
    67 {
    68     return IMG_LoadTyped_RW(src, freesrc, NULL);
    69 }
    70 
    71 /* Portable case-insensitive string compare function */
    72 static int string_equals(const char *str1, const char *str2)
    73 {
    74 	while ( *str1 && *str2 ) {
    75 		if ( toupper((unsigned char)*str1) !=
    76 		     toupper((unsigned char)*str2) )
    77 			break;
    78 		++str1;
    79 		++str2;
    80 	}
    81 	return (!*str1 && !*str2);
    82 }
    83 
    84 /* Load an image from an SDL datasource, optionally specifying the type */
    85 SDL_Surface *IMG_LoadTyped_RW(SDL_RWops *src, int freesrc, char *type)
    86 {
    87 	int i, start;
    88 	SDL_Surface *image;
    89 
    90 	/* Make sure there is something to do.. */
    91 	if ( src == NULL ) {
    92 		return(NULL);
    93 	}
    94 
    95 	/* See whether or not this data source can handle seeking */
    96 	if ( SDL_RWseek(src, 0, SEEK_CUR) < 0 ) {
    97 		IMG_SetError("Can't seek in this data source");
    98 		return(NULL);
    99 	}
   100 
   101 	/* Detect the type of image being loaded */
   102 	start = SDL_RWtell(src);
   103 	image = NULL;
   104 	for ( i=0; supported[i].type && !image; ++i ) {
   105 	        if( (supported[i].is
   106 		     && (SDL_RWseek(src, start, SEEK_SET),
   107 			 supported[i].is(src)))
   108 		    || (type && string_equals(type, supported[i].type))) {
   109 #ifdef DEBUG_IMGLIB
   110 			fprintf(stderr, "IMGLIB: Loading image as %s\n",
   111 							supported[i].type);
   112 #endif
   113 			SDL_RWseek(src, start, SEEK_SET);
   114 			image = supported[i].load(src);
   115 			break;
   116 		}
   117 	}
   118 
   119 	/* Clean up, check for errors, and return */
   120 	if ( freesrc ) {
   121 		SDL_RWclose(src);
   122 	}
   123 	if ( image == NULL ) {
   124 		IMG_SetError("Unsupported image format");
   125 	}
   126 	return(image);
   127 }
   128 
   129 /* Invert the alpha of a surface for use with OpenGL
   130    If you want to use a surface loaded with this library as an OpenGL texture,
   131    set invart_alpha to 1.  If you want to use it with SDL alpha blit routines,
   132    set it to 0.
   133    This function returns the old alpha inversion value.
   134 
   135    Currently this is is only used by the PNG and TGA loaders.
   136  */
   137 int IMG_InvertAlpha(int on)
   138 {
   139 	int old_alpha_value;
   140 
   141 	old_alpha_value = IMG_invert_alpha;
   142 	IMG_invert_alpha = on;
   143 	return(old_alpha_value);
   144 }
   145