⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 img_tga.c

📁 sdl的image开发包
💻 C
字号:
/*    SDL_image:  An example image loading library for use with SDL    Copyright (C) 1999, 2000, 2001  Sam Lantinga    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    Sam Lantinga    slouken@libsdl.org*//* $Id: IMG_tga.c,v 1.4 2001/12/14 13:02:16 slouken Exp $ */#include <stdlib.h>#include <stdio.h>#include <string.h>#include "SDL_endian.h"#include "SDL_image.h"#ifdef LOAD_TGA/* * A TGA loader for the SDL library * Supports: Reading 8, 15, 16, 24 and 32bpp images, with alpha or colourkey, *           uncompressed or RLE encoded. * * 2000-06-10 Mattias Engdeg錼d <f91-men@nada.kth.se>: initial version * 2000-06-26 Mattias Engdeg錼d <f91-men@nada.kth.se>: read greyscale TGAs * 2000-08-09 Mattias Engdeg錼d <f91-men@nada.kth.se>: alpha inversion removed */struct TGAheader {    Uint8 infolen;		/* length of info field */    Uint8 has_cmap;		/* 1 if image has colormap, 0 otherwise */    Uint8 type;    Uint8 cmap_start[2];	/* index of first colormap entry */    Uint8 cmap_len[2];		/* number of entries in colormap */    Uint8 cmap_bits;		/* bits per colormap entry */    Uint8 yorigin[2];		/* image origin (ignored here) */    Uint8 xorigin[2];    Uint8 width[2];		/* image size */    Uint8 height[2];    Uint8 pixel_bits;		/* bits/pixel */    Uint8 flags;};enum tga_type {    TGA_TYPE_INDEXED = 1,    TGA_TYPE_RGB = 2,    TGA_TYPE_BW = 3,    TGA_TYPE_RLE_INDEXED = 9,    TGA_TYPE_RLE_RGB = 10,    TGA_TYPE_RLE_BW = 11};#define TGA_INTERLEAVE_MASK	0xc0#define TGA_INTERLEAVE_NONE	0x00#define TGA_INTERLEAVE_2WAY	0x40#define TGA_INTERLEAVE_4WAY	0x80#define TGA_ORIGIN_MASK		0x30#define TGA_ORIGIN_LEFT		0x00#define TGA_ORIGIN_RIGHT	0x10#define TGA_ORIGIN_LOWER	0x00#define TGA_ORIGIN_UPPER	0x20/* read/write unaligned little-endian 16-bit ints */#define LE16(p) ((p)[0] + ((p)[1] << 8))#define SETLE16(p, v) ((p)[0] = (v), (p)[1] = (v) >> 8)static void unsupported(void){    IMG_SetError("unsupported TGA format");}/* Load a TGA type image from an SDL datasource */SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src){    struct TGAheader hdr;    int rle = 0;    int alpha = 0;    int indexed = 0;    int grey = 0;    int ckey = -1;    int ncols, w, h;    SDL_Surface *img;    Uint32 rmask, gmask, bmask, amask;    Uint8 *dst;    int i;    int bpp;    int lstep;    Uint32 pixel;    int count, rep;    if(!SDL_RWread(src, &hdr, sizeof(hdr), 1))	goto error;    ncols = LE16(hdr.cmap_len);    switch(hdr.type) {    case TGA_TYPE_RLE_INDEXED:	rle = 1;	/* fallthrough */    case TGA_TYPE_INDEXED:	if(!hdr.has_cmap || hdr.pixel_bits != 8 || ncols > 256)	    goto error;	indexed = 1;	break;    case TGA_TYPE_RLE_RGB:	rle = 1;	/* fallthrough */    case TGA_TYPE_RGB:	indexed = 0;	break;    case TGA_TYPE_RLE_BW:	rle = 1;	/* fallthrough */    case TGA_TYPE_BW:	if(hdr.pixel_bits != 8)	    goto error;	/* Treat greyscale as 8bpp indexed images */	indexed = grey = 1;	break;    default:        unsupported();	return NULL;    }    bpp = (hdr.pixel_bits + 7) >> 3;    rmask = gmask = bmask = amask = 0;    switch(hdr.pixel_bits) {    case 8:	if(!indexed) {	    unsupported();	    return NULL;	}	break;    case 15:    case 16:	/* 15 and 16bpp both seem to use 5 bits/plane. The extra alpha bit	   is ignored for now. */	rmask = 0x7c00;	gmask = 0x03e0;	bmask = 0x001f;	break;    case 32:	alpha = 1;	/* fallthrough */    case 24:	if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {	    int s = alpha ? 0 : 8;	    amask = 0x000000ff >> s;	    rmask = 0x0000ff00 >> s;	    gmask = 0x00ff0000 >> s;	    bmask = 0xff000000 >> s;	} else {	    amask = alpha ? 0xff000000 : 0;	    rmask = 0x00ff0000;	    gmask = 0x0000ff00;	    bmask = 0x000000ff;	}	break;    default:	unsupported();	return NULL;    }    if((hdr.flags & TGA_INTERLEAVE_MASK) != TGA_INTERLEAVE_NONE       || hdr.flags & TGA_ORIGIN_RIGHT) {	unsupported();	return NULL;    }        SDL_RWseek(src, hdr.infolen, SEEK_CUR); /* skip info field */    w = LE16(hdr.width);    h = LE16(hdr.height);    img = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h,			       bpp * 8,			       rmask, gmask, bmask, amask);    if(hdr.has_cmap) {	int palsiz = ncols * ((hdr.cmap_bits + 7) >> 3);	if(indexed && !grey) {	    Uint8 *pal = malloc(palsiz), *p = pal;	    SDL_Color *colors = img->format->palette->colors;	    img->format->palette->ncolors = ncols;	    SDL_RWread(src, pal, palsiz, 1);	    for(i = 0; i < ncols; i++) {		switch(hdr.cmap_bits) {		case 15:		case 16:		    {			Uint16 c = p[0] + (p[1] << 8);			p += 2;			colors[i].r = (c >> 7) & 0xf8;			colors[i].g = (c >> 2) & 0xf8;			colors[i].b = c << 3;		    }		    break;		case 24:		case 32:		    colors[i].b = *p++;		    colors[i].g = *p++;		    colors[i].r = *p++;		    if(hdr.cmap_bits == 32 && *p++ < 128)			ckey = i;		    break;		}	    }	    free(pal);	    if(ckey >= 0)		SDL_SetColorKey(img, SDL_SRCCOLORKEY, ckey);	} else {	    /* skip unneeded colormap */	    SDL_RWseek(src, palsiz, SEEK_CUR);	}    }    if(grey) {	SDL_Color *colors = img->format->palette->colors;	for(i = 0; i < 256; i++)	    colors[i].r = colors[i].g = colors[i].b = i;	img->format->palette->ncolors = 256;    }    if(hdr.flags & TGA_ORIGIN_UPPER) {	lstep = img->pitch;	dst = img->pixels;    } else {	lstep = -img->pitch;	dst = (Uint8 *)img->pixels + (h - 1) * img->pitch;    }    /* The RLE decoding code is slightly convoluted since we can't rely on       spans not to wrap across scan lines */    count = rep = 0;    for(i = 0; i < h; i++) {	if(rle) {	    int x = 0;	    for(;;) {		Uint8 c;		if(count) {		    int n = count;		    if(n > w - x)			n = w - x;		    SDL_RWread(src, dst + x * bpp, n * bpp, 1);		    count -= n;		    x += n;		    if(x == w)			break;		} else if(rep) {		    int n = rep;		    if(n > w - x)			n = w - x;		    rep -= n;		    while(n--) {			memcpy(dst + x * bpp, &pixel, bpp);			x++;		    }		    if(x == w)			break;		}		SDL_RWread(src, &c, 1, 1);		if(c & 0x80) {		    SDL_RWread(src, &pixel, bpp, 1);		    rep = (c & 0x7f) + 1;		} else {		    count = c + 1;		}	    }	} else {	    SDL_RWread(src, dst, w * bpp, 1);	}	if(SDL_BYTEORDER == SDL_BIG_ENDIAN && bpp == 2) {	    /* swap byte order */	    int x;	    Uint16 *p = (Uint16 *)dst;	    for(x = 0; x < w; x++)		p[x] = SDL_Swap16(p[x]);	}	dst += lstep;    }    return img;error:    IMG_SetError("Error reading TGA data");    return NULL;}#else/* dummy TGA load routine */SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src){	return(NULL);}#endif /* LOAD_TGA */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -