IMG_xv.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 08 Dec 2008 00:27:32 +0000
changeset 186 5fbbeabf647f
parent 154 201cc5c1b373
child 236 cce1251de477
permissions -rw-r--r--
Updated copyright date
     1 /*
     2     SDL_image:  An example image loading library for use with SDL
     3     Copyright (C) 1997-2009 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 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     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 /* This is a XV thumbnail image file loading framework */
    24 
    25 #include <stdio.h>
    26 #include <string.h>
    27 
    28 #include "SDL_image.h"
    29 
    30 #ifdef LOAD_XV
    31 
    32 static int get_line(SDL_RWops *src, char *line, int size)
    33 {
    34 	while ( size > 0 ) {
    35 		if ( SDL_RWread(src, line, 1, 1) <= 0 ) {
    36 			return -1;
    37 		}
    38 		if ( *line == '\r' ) {
    39 			continue;
    40 		}
    41 		if ( *line == '\n' ) {
    42 			*line = '\0';
    43 			return 0;
    44 		}
    45 		++line;
    46 		--size;
    47 	}
    48 	/* Out of space for the line */
    49 	return -1;
    50 }
    51 
    52 static int get_header(SDL_RWops *src, int *w, int *h)
    53 {
    54 	char line[1024];
    55 
    56 	*w = 0;
    57 	*h = 0;
    58 
    59 	/* Check the header magic */
    60 	if ( (get_line(src, line, sizeof(line)) < 0) ||
    61 	     (memcmp(line, "P7 332", 6) != 0) ) {
    62 		return -1;
    63 	}
    64 
    65 	/* Read the header */
    66 	while ( get_line(src, line, sizeof(line)) == 0 ) {
    67 		if ( memcmp(line, "#BUILTIN:", 9) == 0 ) {
    68 			/* Builtin image, no data */
    69 			break;
    70 		}
    71 		if ( memcmp(line, "#END_OF_COMMENTS", 16) == 0 ) {
    72 			if ( get_line(src, line, sizeof(line)) == 0 ) {
    73 				sscanf(line, "%d %d", w, h);
    74 				if ( *w >= 0 && *h >= 0 ) {
    75 					return 0;
    76 				}
    77 			}
    78 			break;
    79 		}
    80 	}
    81 	/* No image data */
    82 	return -1;
    83 }
    84 
    85 /* See if an image is contained in a data source */
    86 int IMG_isXV(SDL_RWops *src)
    87 {
    88 	int start;
    89 	int is_XV;
    90 	int w, h;
    91 
    92 	if ( !src )
    93 		return 0;
    94 	start = SDL_RWtell(src);
    95 	is_XV = 0;
    96 	if ( get_header(src, &w, &h) == 0 ) {
    97 		is_XV = 1;
    98 	}
    99 	SDL_RWseek(src, start, SEEK_SET);
   100 	return(is_XV);
   101 }
   102 
   103 /* Load a XV thumbnail image from an SDL datasource */
   104 SDL_Surface *IMG_LoadXV_RW(SDL_RWops *src)
   105 {
   106 	int start;
   107 	const char *error = NULL;
   108 	SDL_Surface *surface = NULL;
   109 	int w, h;
   110 	Uint8 *pixels;
   111 
   112 	if ( !src ) {
   113 		/* The error message has been set in SDL_RWFromFile */
   114 		return NULL;
   115 	}
   116 	start = SDL_RWtell(src);
   117 
   118 	/* Read the header */
   119 	if ( get_header(src, &w, &h) < 0 ) {
   120 		error = "Unsupported image format";
   121 		goto done;
   122 	}
   123 
   124 	/* Create the 3-3-2 indexed palette surface */
   125 	surface = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, 0xe0, 0x1c, 0x03, 0);
   126 	if ( surface == NULL ) {
   127 		error = "Out of memory";
   128 		goto done;
   129 	}
   130 
   131 	/* Load the image data */
   132 	for ( pixels = (Uint8 *)surface->pixels; h > 0; --h ) {
   133 		if ( SDL_RWread(src, pixels, w, 1) <= 0 ) {
   134 			error = "Couldn't read image data";
   135 			goto done;
   136 		}
   137 		pixels += surface->pitch;
   138 	}
   139 
   140 done:
   141 	if ( error ) {
   142 		SDL_RWseek(src, start, SEEK_SET);
   143 		if ( surface ) {
   144 			SDL_FreeSurface(surface);
   145 			surface = NULL;
   146 		}
   147 		IMG_SetError(error);
   148 	}
   149 	return surface;
   150 }
   151 
   152 #else
   153 
   154 /* See if an image is contained in a data source */
   155 int IMG_isXV(SDL_RWops *src)
   156 {
   157 	return(0);
   158 }
   159 
   160 /* Load a XXX type image from an SDL datasource */
   161 SDL_Surface *IMG_LoadXV_RW(SDL_RWops *src)
   162 {
   163 	return(NULL);
   164 }
   165 
   166 #endif /* LOAD_XV */