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