Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

LBMLIB.CPP (27293B)


      1 /*
      2 ===========================================================================
      3 Copyright (C) 1999-2005 Id Software, Inc.
      4 
      5 This file is part of Quake III Arena source code.
      6 
      7 Quake III Arena source code is free software; you can redistribute it
      8 and/or modify it under the terms of the GNU General Public License as
      9 published by the Free Software Foundation; either version 2 of the License,
     10 or (at your option) any later version.
     11 
     12 Quake III Arena source code is distributed in the hope that it will be
     13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 GNU General Public License for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with Foobar; if not, write to the Free Software
     19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     20 ===========================================================================
     21 */
     22 // lbmlib.c
     23 
     24 #include "stdafx.h"
     25 #include "cmdlib.h"
     26 #include "lbmlib.h"
     27 #include "bmp.h"
     28 #include "pakstuff.h"
     29 #include "jpeglib.h"
     30 
     31 
     32 /*
     33 ============================================================================
     34 
     35 						LBM STUFF
     36 
     37 ============================================================================
     38 */
     39 
     40 
     41 typedef unsigned char	UBYTE;
     42 //conflicts with windows typedef short			WORD;
     43 typedef unsigned short	UWORD;
     44 typedef long			LONG;
     45 
     46 typedef enum
     47 {
     48 	ms_none,
     49 	ms_mask,
     50 	ms_transcolor,
     51 	ms_lasso
     52 } mask_t;
     53 
     54 typedef enum
     55 {
     56 	cm_none,
     57 	cm_rle1
     58 } compress_t;
     59 
     60 typedef struct
     61 {
     62 	UWORD		w,h;
     63 	short		x,y;
     64 	UBYTE		nPlanes;
     65 	UBYTE		masking;
     66 	UBYTE		compression;
     67 	UBYTE		pad1;
     68 	UWORD		transparentColor;
     69 	UBYTE		xAspect,yAspect;
     70 	short		pageWidth,pageHeight;
     71 } bmhd_t;
     72 
     73 extern	bmhd_t	bmhd;						// will be in native byte order
     74 
     75 
     76 
     77 #define FORMID ('F'+('O'<<8)+((int)'R'<<16)+((int)'M'<<24))
     78 #define ILBMID ('I'+('L'<<8)+((int)'B'<<16)+((int)'M'<<24))
     79 #define PBMID  ('P'+('B'<<8)+((int)'M'<<16)+((int)' '<<24))
     80 #define BMHDID ('B'+('M'<<8)+((int)'H'<<16)+((int)'D'<<24))
     81 #define BODYID ('B'+('O'<<8)+((int)'D'<<16)+((int)'Y'<<24))
     82 #define CMAPID ('C'+('M'<<8)+((int)'A'<<16)+((int)'P'<<24))
     83 
     84 
     85 bmhd_t  bmhd;
     86 
     87 int    Align (int l)
     88 {
     89 	if (l&1)
     90 		return l+1;
     91 	return l;
     92 }
     93 
     94 
     95 
     96 /*
     97 ================
     98 LBMRLEdecompress
     99 
    100 Source must be evenly aligned!
    101 ================
    102 */
    103 byte  *LBMRLEDecompress (byte *source,byte *unpacked, int bpwidth)
    104 {
    105 	int     count;
    106 	byte    b,rept;
    107 
    108 	count = 0;
    109 
    110 	do
    111 	{
    112 		rept = *source++;
    113 
    114 		if (rept > 0x80)
    115 		{
    116 			rept = (rept^0xff)+2;
    117 			b = *source++;
    118 			memset(unpacked,b,rept);
    119 			unpacked += rept;
    120 		}
    121 		else if (rept < 0x80)
    122 		{
    123 			rept++;
    124 			memcpy(unpacked,source,rept);
    125 			unpacked += rept;
    126 			source += rept;
    127 		}
    128 		else
    129 			rept = 0;               // rept of 0x80 is NOP
    130 
    131 		count += rept;
    132 
    133 	} while (count<bpwidth);
    134 
    135 	if (count>bpwidth)
    136 		Error ("Decompression exceeded width!\n");
    137 
    138 
    139 	return source;
    140 }
    141 
    142 
    143 /*
    144 =================
    145 LoadLBM
    146 =================
    147 */
    148 void LoadLBM (char *filename, byte **picture, byte **palette)
    149 {
    150 	byte    *LBMbuffer, *picbuffer, *cmapbuffer;
    151 	int             y;
    152 	byte    *LBM_P, *LBMEND_P;
    153 	byte    *pic_p;
    154 	byte    *body_p;
    155 
    156 	int    formtype,formlength;
    157 	int    chunktype,chunklength;
    158 
    159 // qiet compiler warnings
    160 	picbuffer = NULL;
    161 	cmapbuffer = NULL;
    162 
    163 //
    164 // load the LBM
    165 //
    166 	LoadFile (filename, (void **)&LBMbuffer);
    167 
    168   if (LBMbuffer == NULL)
    169   {
    170     return;
    171   }
    172 //
    173 // parse the LBM header
    174 //
    175 	LBM_P = LBMbuffer;
    176 	if ( *(int *)LBMbuffer != LittleLong(FORMID) )
    177 	   Error ("No FORM ID at start of file!\n");
    178 
    179 	LBM_P += 4;
    180 	formlength = BigLong( *(int *)LBM_P );
    181 	LBM_P += 4;
    182 	LBMEND_P = LBM_P + Align(formlength);
    183 
    184 	formtype = LittleLong(*(int *)LBM_P);
    185 
    186 	if (formtype != ILBMID && formtype != PBMID)
    187 		Error ("Unrecognized form type: %c%c%c%c\n", formtype&0xff
    188 		,(formtype>>8)&0xff,(formtype>>16)&0xff,(formtype>>24)&0xff);
    189 
    190 	LBM_P += 4;
    191 
    192 //
    193 // parse chunks
    194 //
    195 
    196 	while (LBM_P < LBMEND_P)
    197 	{
    198 		chunktype = LBM_P[0] + (LBM_P[1]<<8) + (LBM_P[2]<<16) + (LBM_P[3]<<24);
    199 		LBM_P += 4;
    200 		chunklength = LBM_P[3] + (LBM_P[2]<<8) + (LBM_P[1]<<16) + (LBM_P[0]<<24);
    201 		LBM_P += 4;
    202 
    203 		switch ( chunktype )
    204 		{
    205 		case BMHDID:
    206 			memcpy (&bmhd,LBM_P,sizeof(bmhd));
    207 			bmhd.w = BigShort(bmhd.w);
    208 			bmhd.h = BigShort(bmhd.h);
    209 			bmhd.x = BigShort(bmhd.x);
    210 			bmhd.y = BigShort(bmhd.y);
    211 			bmhd.pageWidth = BigShort(bmhd.pageWidth);
    212 			bmhd.pageHeight = BigShort(bmhd.pageHeight);
    213 			break;
    214 
    215 		case CMAPID:
    216 			cmapbuffer = (unsigned char*)malloc (768);
    217 			memset (cmapbuffer, 0, 768);
    218 			memcpy (cmapbuffer, LBM_P, chunklength);
    219 			break;
    220 
    221 		case BODYID:
    222 			body_p = LBM_P;
    223 
    224 			pic_p = picbuffer = (unsigned char*)malloc (bmhd.w*bmhd.h);
    225 			if (formtype == PBMID)
    226 			{
    227 			//
    228 			// unpack PBM
    229 			//
    230 				for (y=0 ; y<bmhd.h ; y++, pic_p += bmhd.w)
    231 				{
    232 					if (bmhd.compression == cm_rle1)
    233 						body_p = LBMRLEDecompress ((byte *)body_p
    234 						, pic_p , bmhd.w);
    235 					else if (bmhd.compression == cm_none)
    236 					{
    237 						memcpy (pic_p,body_p,bmhd.w);
    238 						body_p += Align(bmhd.w);
    239 					}
    240 				}
    241 
    242 			}
    243 			else
    244 			{
    245 			//
    246 			// unpack ILBM
    247 			//
    248 				Error ("%s is an interlaced LBM, not packed", filename);
    249 			}
    250 			break;
    251 		}
    252 
    253 		LBM_P += Align(chunklength);
    254 	}
    255 
    256 	free (LBMbuffer);
    257 
    258 	*picture = picbuffer;
    259 
    260 	if (palette)
    261 		*palette = cmapbuffer;
    262 }
    263 
    264 
    265 /*
    266 ============================================================================
    267 
    268 							WRITE LBM
    269 
    270 ============================================================================
    271 */
    272 
    273 /*
    274 ==============
    275 WriteLBMfile
    276 ==============
    277 */
    278 void WriteLBMfile (char *filename, byte *data,
    279 				   int width, int height, byte *palette)
    280 {
    281 	byte    *lbm, *lbmptr;
    282 	int    *formlength, *bmhdlength, *cmaplength, *bodylength;
    283 	int    length;
    284 	bmhd_t  basebmhd;
    285 
    286 	lbm = lbmptr = (unsigned char*)malloc (width*height+1000);
    287 
    288 //
    289 // start FORM
    290 //
    291 	*lbmptr++ = 'F';
    292 	*lbmptr++ = 'O';
    293 	*lbmptr++ = 'R';
    294 	*lbmptr++ = 'M';
    295 
    296 	formlength = (int*)lbmptr;
    297 	lbmptr+=4;                      // leave space for length
    298 
    299 	*lbmptr++ = 'P';
    300 	*lbmptr++ = 'B';
    301 	*lbmptr++ = 'M';
    302 	*lbmptr++ = ' ';
    303 
    304 //
    305 // write BMHD
    306 //
    307 	*lbmptr++ = 'B';
    308 	*lbmptr++ = 'M';
    309 	*lbmptr++ = 'H';
    310 	*lbmptr++ = 'D';
    311 
    312 	bmhdlength = (int *)lbmptr;
    313 	lbmptr+=4;                      // leave space for length
    314 
    315 	memset (&basebmhd,0,sizeof(basebmhd));
    316 	basebmhd.w = BigShort((short)width);
    317 	basebmhd.h = BigShort((short)height);
    318 	basebmhd.nPlanes = 8;
    319 	basebmhd.xAspect = 5;
    320 	basebmhd.yAspect = 6;
    321 	basebmhd.pageWidth = BigShort((short)width);
    322 	basebmhd.pageHeight = BigShort((short)height);
    323 
    324 	memcpy (lbmptr,&basebmhd,sizeof(basebmhd));
    325 	lbmptr += sizeof(basebmhd);
    326 
    327 	length = lbmptr-(byte *)bmhdlength-4;
    328 	*bmhdlength = BigLong(length);
    329 	if (length&1)
    330 		*lbmptr++ = 0;          // pad chunk to even offset
    331 
    332 //
    333 // write CMAP
    334 //
    335 	*lbmptr++ = 'C';
    336 	*lbmptr++ = 'M';
    337 	*lbmptr++ = 'A';
    338 	*lbmptr++ = 'P';
    339 
    340 	cmaplength = (int *)lbmptr;
    341 	lbmptr+=4;                      // leave space for length
    342 
    343 	memcpy (lbmptr,palette,768);
    344 	lbmptr += 768;
    345 
    346 	length = lbmptr-(byte *)cmaplength-4;
    347 	*cmaplength = BigLong(length);
    348 	if (length&1)
    349 		*lbmptr++ = 0;          // pad chunk to even offset
    350 
    351 //
    352 // write BODY
    353 //
    354 	*lbmptr++ = 'B';
    355 	*lbmptr++ = 'O';
    356 	*lbmptr++ = 'D';
    357 	*lbmptr++ = 'Y';
    358 
    359 	bodylength = (int *)lbmptr;
    360 	lbmptr+=4;                      // leave space for length
    361 
    362 	memcpy (lbmptr,data,width*height);
    363 	lbmptr += width*height;
    364 
    365 	length = lbmptr-(byte *)bodylength-4;
    366 	*bodylength = BigLong(length);
    367 	if (length&1)
    368 		*lbmptr++ = 0;          // pad chunk to even offset
    369 
    370 //
    371 // done
    372 //
    373 	length = lbmptr-(byte *)formlength-4;
    374 	*formlength = BigLong(length);
    375 	if (length&1)
    376 		*lbmptr++ = 0;          // pad chunk to even offset
    377 
    378 //
    379 // write output file
    380 //
    381 	SaveFile (filename, lbm, lbmptr-lbm);
    382 	free (lbm);
    383 }
    384 
    385 /*
    386 ============================================================================
    387 
    388 LOAD PCX
    389 
    390 ============================================================================
    391 */
    392 typedef struct
    393 {
    394     char	manufacturer;
    395     char	version;
    396     char	encoding;
    397     char	bits_per_pixel;
    398     unsigned short	xmin,ymin,xmax,ymax;
    399     unsigned short	hres,vres;
    400     unsigned char	palette[48];
    401     char	reserved;
    402     char	color_planes;
    403     unsigned short	bytes_per_line;
    404     unsigned short	palette_type;
    405     char	filler[58];
    406     unsigned char	data;			// unbounded
    407 } pcx_t;
    408 
    409 /*
    410 ==============
    411 LoadPCX
    412 ==============
    413 */
    414 void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height)
    415 {
    416 	byte	*raw = 0;
    417 	pcx_t	*pcx;
    418 	int		x, y;
    419 	int		len;
    420 	int		dataByte, runLength;
    421 	byte	*out, *pix;
    422 
    423 	if (pic)
    424 		*pic = NULL;
    425 	if (palette)
    426 		*palette = NULL;
    427 	if (width)
    428 		*width = 0;
    429 	if (height)
    430 		*height = 0;
    431 
    432 	//
    433 	// load the file
    434 	//
    435 	len = LoadFile (filename, (void **)&raw);
    436 	if (len == -1)
    437 		return;
    438 
    439 	//
    440 	// parse the PCX file
    441 	//
    442 	pcx = (pcx_t *)raw;
    443 	raw = &pcx->data;
    444 
    445 	pcx->xmin = LittleShort(pcx->xmin);
    446 	pcx->ymin = LittleShort(pcx->ymin);
    447 	pcx->xmax = LittleShort(pcx->xmax);
    448 	pcx->ymax = LittleShort(pcx->ymax);
    449 	pcx->hres = LittleShort(pcx->hres);
    450 	pcx->vres = LittleShort(pcx->vres);
    451 	pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
    452 	pcx->palette_type = LittleShort(pcx->palette_type);
    453 
    454 	if (pcx->manufacturer != 0x0a
    455 		|| pcx->version != 5
    456 		|| pcx->encoding != 1
    457 		|| pcx->bits_per_pixel != 8
    458 		|| pcx->xmax >= 640
    459 		|| pcx->ymax >= 480)
    460 		Error ("Bad pcx file %s", filename);
    461 	
    462 	if (palette)
    463 	{
    464 		*palette = (unsigned char*)malloc(768);
    465 		memcpy (*palette, (byte *)pcx + len - 768, 768);
    466 	}
    467 
    468 	if (width)
    469 		*width = pcx->xmax+1;
    470 	if (height)
    471 		*height = pcx->ymax+1;
    472 
    473 	if (!pic)
    474   {
    475     free(pcx);
    476 		return;
    477   }
    478 
    479 	out = (unsigned char*)malloc ( (pcx->ymax+1) * (pcx->xmax+1) );
    480 	if (!out)
    481 		Error ("Skin_Cache: couldn't allocate");
    482 
    483 	*pic = out;
    484 
    485 	pix = out;
    486 
    487 	for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)
    488 	{
    489 		for (x=0 ; x<=pcx->xmax ; )
    490 		{
    491 			dataByte = *raw++;
    492 
    493 			if((dataByte & 0xC0) == 0xC0)
    494 			{
    495 				runLength = dataByte & 0x3F;
    496 				dataByte = *raw++;
    497 			}
    498 			else
    499 				runLength = 1;
    500 
    501 			while(runLength-- > 0)
    502 				pix[x++] = dataByte;
    503 		}
    504 
    505 	}
    506 
    507 	if ( raw - (byte *)pcx > len)
    508 		Error ("PCX file %s was malformed", filename);
    509 
    510 	free (pcx);
    511 }
    512 /* 
    513 ============== 
    514 WritePCXfile 
    515 ============== 
    516 */ 
    517 void WritePCXfile (char *filename, byte *data, 
    518 				   int width, int height, byte *palette) 
    519 {
    520 	int		i, j, length;
    521 	pcx_t	*pcx;
    522 	byte		*pack;
    523 	  
    524 	pcx = (pcx_t*)malloc (width*height*2+1000);
    525 	memset (pcx, 0, sizeof(*pcx));
    526 
    527 	pcx->manufacturer = 0x0a;	// PCX id
    528 	pcx->version = 5;			// 256 color
    529  	pcx->encoding = 1;		// uncompressed
    530 	pcx->bits_per_pixel = 8;		// 256 color
    531 	pcx->xmin = 0;
    532 	pcx->ymin = 0;
    533 	pcx->xmax = LittleShort((short)(width-1));
    534 	pcx->ymax = LittleShort((short)(height-1));
    535 	pcx->hres = LittleShort((short)width);
    536 	pcx->vres = LittleShort((short)height);
    537 	pcx->color_planes = 1;		// chunky image
    538 	pcx->bytes_per_line = LittleShort((short)width);
    539 	pcx->palette_type = LittleShort(2);		// not a grey scale
    540 
    541 	// pack the image
    542 	pack = &pcx->data;
    543 	
    544 	for (i=0 ; i<height ; i++)
    545 	{
    546 		for (j=0 ; j<width ; j++)
    547 		{
    548 			if ( (*data & 0xc0) != 0xc0)
    549 				*pack++ = *data++;
    550 			else
    551 			{
    552 				*pack++ = 0xc1;
    553 				*pack++ = *data++;
    554 			}
    555 		}
    556 	}
    557 			
    558 	// write the palette
    559 	*pack++ = 0x0c;	// palette ID byte
    560 	for (i=0 ; i<768 ; i++)
    561 		*pack++ = *palette++;
    562 		
    563 // write output file 
    564 	length = pack - (byte *)pcx;
    565 	SaveFile (filename, pcx, length);
    566 
    567 	free (pcx);
    568 } 
    569 
    570 /*
    571 ============================================================================
    572 
    573 LOAD IMAGE
    574 
    575 ============================================================================
    576 */
    577 
    578 /*
    579 ==============
    580 Load256Image
    581 
    582 Will load either an lbm or pcx, depending on extension.
    583 Any of the return pointers can be NULL if you don't want them.
    584 ==============
    585 */
    586 void Load256Image (char *name, byte **pixels, byte **palette,
    587 				   int *width, int *height)
    588 {
    589 	char	ext[128];
    590 	bitmap_t	bmp;
    591 
    592 	ExtractFileExtension (name, ext);
    593 	if (stricmp(ext, "lbm"))
    594 	{
    595 		LoadLBM (name, pixels, palette);
    596 		if (width)
    597 			*width = bmhd.w;
    598 		if (height)
    599 			*height = bmhd.h;
    600 	}
    601 	else if (stricmp (ext, "pcx"))
    602 	{
    603 		LoadPCX (name, pixels, palette, width, height);
    604 	}
    605 	else if (stricmp (ext, "bmp"))
    606 	{
    607 		LoadBMP (name, &bmp);
    608 		if (bmp.palette)
    609 		{
    610 			*palette = (unsigned char*)malloc (768);
    611 			memcpy (*palette, bmp.palette, 768);
    612 		}
    613 		FreeBMP (&bmp);		
    614 	}
    615 	else
    616 		Error ("%s doesn't have a known image extension", name);
    617 }
    618 
    619 
    620 /*
    621 ==============
    622 Save256Image
    623 
    624 Will save either an lbm or pcx, depending on extension.
    625 ==============
    626 */
    627 void Save256Image (char *name, byte *pixels, byte *palette,
    628 				   int width, int height)
    629 {
    630 	char	ext[128];
    631 
    632 	ExtractFileExtension (name, ext);
    633 	if (!strcmp (ext, "lbm"))
    634 	{
    635 		WriteLBMfile (name, pixels, width, height, palette);
    636 	}
    637 	else if (!stricmp (ext, "pcx"))
    638 	{
    639 		WritePCXfile (name, pixels, width, height, palette);
    640 	}
    641 	else
    642 		Error ("%s doesn't have a known image extension", name);
    643 }
    644 
    645 
    646 
    647 /*
    648 ============================================================================
    649 
    650 TARGA IMAGE
    651 
    652 ============================================================================
    653 */
    654 typedef struct _TargaHeader {
    655 	unsigned char 	id_length, colormap_type, image_type;
    656 	unsigned short	colormap_index, colormap_length;
    657 	unsigned char	colormap_size;
    658 	unsigned short	x_origin, y_origin, width, height;
    659 	unsigned char	pixel_size, attributes;
    660 } TargaHeader;
    661 
    662 int fgetLittleShort (FILE *f)
    663 {
    664 	byte	b1, b2;
    665 
    666 	b1 = fgetc(f);
    667 	b2 = fgetc(f);
    668 
    669 	return (short)(b1 + b2*256);
    670 }
    671 
    672 int getLittleShort (byte*& p)
    673 {
    674 	byte	b1, b2;
    675 	b1 = *p++;
    676 	b2 = *p++;
    677 	return (short)(b1 + b2*256);
    678 }
    679 
    680 int getLittleLong (byte*& p)
    681 {
    682 	byte	b1, b2, b3, b4;
    683 
    684 	b1 = *p++;
    685 	b2 = *p++;
    686 	b3 = *p++;
    687 	b4 = *p++;
    688 	return b1 + (b2<<8) + (b3<<16) + (b4<<24);
    689 }
    690 
    691 char getc(byte*& p)
    692 {
    693   return *p++;
    694 }
    695 
    696 /*
    697 =========================================================
    698 
    699 BMP LOADING
    700 
    701 =========================================================
    702 */
    703 typedef struct
    704 {
    705 	char id[2];
    706 	unsigned long fileSize;
    707 	unsigned long reserved0;
    708 	unsigned long bitmapDataOffset;
    709 	unsigned long bitmapHeaderSize;
    710 	unsigned long width;
    711 	unsigned long height;
    712 	unsigned short planes;
    713 	unsigned short bitsPerPixel;
    714 	unsigned long compression;
    715 	unsigned long bitmapDataSize;
    716 	unsigned long hRes;
    717 	unsigned long vRes;
    718 	unsigned long colors;
    719 	unsigned long importantColors;
    720 	unsigned char palette[256][4];
    721 } BMPHeader_t;
    722 
    723 static void LoadBMP( const char *name, byte **pic, int *width, int *height )
    724 {
    725 	int		columns, rows, numPixels;
    726 	byte	*pixbuf;
    727 	int		row, column;
    728 	byte	*buf_p;
    729 	byte	*buffer;
    730 	unsigned int		length;
    731 	BMPHeader_t bmpHeader;
    732 	byte		*bmpRGBA;
    733 
    734 	*pic = NULL;
    735 
    736 	//
    737 	// load the file
    738 	//
    739 	length = LoadFile( ( char * ) name, (void **)&buffer);
    740 	if (length == -1)
    741   {
    742     length = PakLoadAnyFile( (char*)name, (void**)&buffer);
    743     if (length == -1)
    744     {
    745 		  return;
    746     }
    747   }
    748 
    749 	buf_p = buffer;
    750 
    751 	bmpHeader.id[0] = *buf_p++;
    752 	bmpHeader.id[1] = *buf_p++;
    753 	bmpHeader.fileSize = LittleLong( * ( long * ) buf_p );
    754 	buf_p += 4;
    755 	bmpHeader.reserved0 = LittleLong( * ( long * ) buf_p );
    756 	buf_p += 4;
    757 	bmpHeader.bitmapDataOffset = LittleLong( * ( long * ) buf_p );
    758 	buf_p += 4;
    759 	bmpHeader.bitmapHeaderSize = LittleLong( * ( long * ) buf_p );
    760 	buf_p += 4;
    761 	bmpHeader.width = LittleLong( * ( long * ) buf_p );
    762 	buf_p += 4;
    763 	bmpHeader.height = LittleLong( * ( long * ) buf_p );
    764 	buf_p += 4;
    765 	bmpHeader.planes = LittleShort( * ( short * ) buf_p );
    766 	buf_p += 2;
    767 	bmpHeader.bitsPerPixel = LittleShort( * ( short * ) buf_p );
    768 	buf_p += 2;
    769 	bmpHeader.compression = LittleLong( * ( long * ) buf_p );
    770 	buf_p += 4;
    771 	bmpHeader.bitmapDataSize = LittleLong( * ( long * ) buf_p );
    772 	buf_p += 4;
    773 	bmpHeader.hRes = LittleLong( * ( long * ) buf_p );
    774 	buf_p += 4;
    775 	bmpHeader.vRes = LittleLong( * ( long * ) buf_p );
    776 	buf_p += 4;
    777 	bmpHeader.colors = LittleLong( * ( long * ) buf_p );
    778 	buf_p += 4;
    779 	bmpHeader.importantColors = LittleLong( * ( long * ) buf_p );
    780 	buf_p += 4;
    781 
    782 	memcpy( bmpHeader.palette, buf_p, sizeof( bmpHeader.palette ) );
    783 
    784 	if ( bmpHeader.bitsPerPixel == 8 )
    785 		buf_p += 1024;
    786 
    787 	if ( bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M' ) 
    788 	{
    789 		Sys_Printf("LoadBMP: only Windows-style BMP files supported (%s)\n", name );
    790 	}
    791 	if ( bmpHeader.fileSize != length )
    792 	{
    793 		Sys_Printf("LoadBMP: header size does not match file size (%d vs. %d) (%s)\n", bmpHeader.fileSize, length, name );
    794 	}
    795 	if ( bmpHeader.compression != 0 )
    796 	{
    797 		Sys_Printf("LoadBMP: only uncompressed BMP files supported (%s)\n", name );
    798 	}
    799 	if ( bmpHeader.bitsPerPixel < 8 )
    800 	{
    801 		Sys_Printf("LoadBMP: monochrome and 4-bit BMP files not supported (%s)\n", name );
    802 	}
    803 
    804 	columns = bmpHeader.width;
    805 	rows = bmpHeader.height;
    806 	if ( rows < 0 )
    807 		rows = -rows;
    808 	numPixels = columns * rows;
    809 
    810 	if ( width ) 
    811 		*width = columns;
    812 	if ( height )
    813 		*height = rows;
    814 
    815 	bmpRGBA = reinterpret_cast<unsigned char*>(malloc( numPixels * 4 ));
    816 	*pic = bmpRGBA;
    817 
    818 
    819 	for ( row = rows-1; row >= 0; row-- )
    820 	{
    821 		pixbuf = bmpRGBA + row*columns*4;
    822 
    823 		for ( column = 0; column < columns; column++ )
    824 		{
    825 			unsigned char red, green, blue, alpha;
    826 			int palIndex;
    827 			unsigned short shortPixel;
    828 
    829 			switch ( bmpHeader.bitsPerPixel )
    830 			{
    831 			case 8:
    832 				palIndex = *buf_p++;
    833 				*pixbuf++ = bmpHeader.palette[palIndex][2];
    834 				*pixbuf++ = bmpHeader.palette[palIndex][1];
    835 				*pixbuf++ = bmpHeader.palette[palIndex][0];
    836 				*pixbuf++ = 0xff;
    837 				break;
    838 			case 16:
    839 				shortPixel = * ( unsigned short * ) pixbuf;
    840 				pixbuf += 2;
    841 				*pixbuf++ = ( shortPixel & ( 31 << 10 ) ) >> 7;
    842 				*pixbuf++ = ( shortPixel & ( 31 << 5 ) ) >> 2;
    843 				*pixbuf++ = ( shortPixel & ( 31 ) ) << 3;
    844 				*pixbuf++ = 0xff;
    845 				break;
    846 
    847 			case 24:
    848 				blue = *buf_p++;
    849 				green = *buf_p++;
    850 				red = *buf_p++;
    851 				*pixbuf++ = red;
    852 				*pixbuf++ = green;
    853 				*pixbuf++ = blue;
    854 				*pixbuf++ = 255;
    855 				break;
    856 			case 32:
    857 				blue = *buf_p++;
    858 				green = *buf_p++;
    859 				red = *buf_p++;
    860 				alpha = *buf_p++;
    861 				*pixbuf++ = red;
    862 				*pixbuf++ = green;
    863 				*pixbuf++ = blue;
    864 				*pixbuf++ = alpha;
    865 				break;
    866 			default:
    867 				Sys_Printf("LoadBMP: illegal pixel_size '%d' in file '%s'\n", bmpHeader.bitsPerPixel, name );
    868 				break;
    869 			}
    870 		}
    871 	}
    872 
    873 	free( buffer );
    874 
    875 }
    876 
    877 
    878 /*
    879 =================================================================
    880 
    881 PCX LOADING
    882 
    883 =================================================================
    884 */
    885 
    886 
    887 /*
    888 ==============
    889 LoadPCX
    890 ==============
    891 */
    892 static void LoadPCX ( const char *filename, byte **pic, byte **palette, int *width, int *height)
    893 {
    894 	byte	*raw;
    895 	pcx_t	*pcx;
    896 	int		x, y;
    897 	int		len;
    898 	int		dataByte, runLength;
    899 	byte	*out, *pix;
    900 	int		xmax, ymax;
    901 
    902 	*pic = NULL;
    903 	*palette = NULL;
    904 
    905 	//
    906 	// load the file
    907 	//
    908 	len = LoadFile( ( char * ) filename, (void **)&raw);
    909 	if (len == -1) 
    910   {
    911     len = PakLoadAnyFile( (char*)filename, (void**)&raw);
    912     if (len == -1)
    913     {
    914 		  return;
    915     }
    916 	}
    917 
    918 	//
    919 	// parse the PCX file
    920 	//
    921 	pcx = (pcx_t *)raw;
    922 	raw = &pcx->data;
    923 
    924   	xmax = LittleShort(pcx->xmax);
    925     ymax = LittleShort(pcx->ymax);
    926 
    927 	if (pcx->manufacturer != 0x0a
    928 		|| pcx->version != 5
    929 		|| pcx->encoding != 1
    930 		|| pcx->bits_per_pixel != 8
    931 		|| xmax >= 1024
    932 		|| ymax >= 1024)
    933 	{
    934 		Sys_Printf ("Bad pcx file %s (%i x %i) (%i x %i)\n", filename, xmax+1, ymax+1, pcx->xmax, pcx->ymax);
    935 		return;
    936 	}
    937 
    938 	out = reinterpret_cast<unsigned char*>(malloc ( (ymax+1) * (xmax+1) ));
    939 
    940 	*pic = out;
    941 
    942 	pix = out;
    943 
    944 	if (palette)
    945 	{
    946 		*palette = reinterpret_cast<unsigned char*>(malloc(768));
    947 		memcpy (*palette, (byte *)pcx + len - 768, 768);
    948 	}
    949 
    950 	if (width)
    951 		*width = xmax+1;
    952 	if (height)
    953 		*height = ymax+1;
    954 // FIXME: use bytes_per_line here?
    955 
    956 	for (y=0 ; y<=ymax ; y++, pix += xmax+1)
    957 	{
    958 		for (x=0 ; x<=xmax ; )
    959 		{
    960 			dataByte = *raw++;
    961 
    962 			if((dataByte & 0xC0) == 0xC0)
    963 			{
    964 				runLength = dataByte & 0x3F;
    965 				dataByte = *raw++;
    966 			}
    967 			else
    968 				runLength = 1;
    969 
    970 			while(runLength-- > 0)
    971 				pix[x++] = dataByte;
    972 		}
    973 
    974 	}
    975 
    976 	if ( raw - (byte *)pcx > len)
    977 	{
    978 		Sys_Printf ("PCX file %s was malformed", filename);
    979 		free (*pic);
    980 		*pic = NULL;
    981 	}
    982 
    983 	free(pcx);
    984 }
    985 
    986 
    987 /*
    988 ==============
    989 LoadPCX32
    990 ==============
    991 */
    992 static void LoadPCX32 ( const char *filename, byte **pic, int *width, int *height) {
    993 	byte	*palette;
    994 	byte	*pic8;
    995 	int		i, c, p;
    996 	byte	*pic32;
    997 
    998 	LoadPCX (filename, &pic8, &palette, width, height);
    999 	if (!pic8) {
   1000 		*pic = NULL;
   1001 		return;
   1002 	}
   1003 
   1004 	c = (*width) * (*height);
   1005 	pic32 = *pic = reinterpret_cast<unsigned char*>(malloc(4 * c ));
   1006 	for (i = 0 ; i < c ; i++) {
   1007 		p = pic8[i];
   1008 		pic32[0] = palette[p*3];
   1009 		pic32[1] = palette[p*3 + 1];
   1010 		pic32[2] = palette[p*3 + 2];
   1011 		pic32[3] = 255;
   1012 		pic32 += 4;
   1013 	}
   1014 
   1015 	free (pic8);
   1016 	free (palette);
   1017 }
   1018 
   1019 /*
   1020 =========================================================
   1021 
   1022 TARGA LOADING
   1023 
   1024 =========================================================
   1025 */
   1026 
   1027 /*
   1028 =============
   1029 LoadTGA
   1030 =============
   1031 */
   1032 void LoadTGA ( const char *name, byte **pic, int *width, int *height)
   1033 {
   1034 	int		columns, rows, numPixels;
   1035 	byte	*pixbuf;
   1036 	int		row, column;
   1037 	byte	*buf_p;
   1038 	byte	*buffer;
   1039 	TargaHeader	targa_header;
   1040 	byte		*targa_rgba;
   1041 
   1042 	*pic = NULL;
   1043 
   1044 	//
   1045 	// load the file
   1046 	//
   1047 	int nLen = LoadFile ( ( char * ) name, (void **)&buffer);
   1048 	if (nLen == -1) 
   1049   {
   1050     nLen = PakLoadAnyFile((char*)name, (void**)&buffer);
   1051     if (nLen == -1)
   1052     {
   1053 		  return;
   1054     }
   1055 	}
   1056 
   1057 	buf_p = buffer;
   1058 
   1059 	targa_header.id_length = *buf_p++;
   1060 	targa_header.colormap_type = *buf_p++;
   1061 	targa_header.image_type = *buf_p++;
   1062 	
   1063 	targa_header.colormap_index = LittleShort ( *(short *)buf_p );
   1064 	buf_p += 2;
   1065 	targa_header.colormap_length = LittleShort ( *(short *)buf_p );
   1066 	buf_p += 2;
   1067 	targa_header.colormap_size = *buf_p++;
   1068 	targa_header.x_origin = LittleShort ( *(short *)buf_p );
   1069 	buf_p += 2;
   1070 	targa_header.y_origin = LittleShort ( *(short *)buf_p );
   1071 	buf_p += 2;
   1072 	targa_header.width = LittleShort ( *(short *)buf_p );
   1073 	buf_p += 2;
   1074 	targa_header.height = LittleShort ( *(short *)buf_p );
   1075 	buf_p += 2;
   1076 	targa_header.pixel_size = *buf_p++;
   1077 	targa_header.attributes = *buf_p++;
   1078 
   1079 	//++timo debug
   1080 	if (targa_header.pixel_size == 32)
   1081 		Sys_Printf("%s is 32bit\n", name);
   1082 	bool bAlphaOK = false;
   1083 
   1084 	if (targa_header.image_type!=2 
   1085 		&& targa_header.image_type!=10
   1086 		&& targa_header.image_type != 3 ) 
   1087 	{
   1088 		Sys_Printf("LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n");
   1089 	}
   1090 
   1091 	if ( targa_header.colormap_type != 0 )
   1092 	{
   1093 		Sys_Printf("LoadTGA: colormaps not supported\n" );
   1094 	}
   1095 
   1096 	if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 )
   1097 	{
   1098 		Sys_Printf("LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
   1099 	}
   1100 
   1101 	columns = targa_header.width;
   1102 	rows = targa_header.height;
   1103 	numPixels = columns * rows;
   1104 
   1105 	if (width)
   1106 		*width = columns;
   1107 	if (height)
   1108 		*height = rows;
   1109 
   1110 	targa_rgba = reinterpret_cast<unsigned char*>(malloc (numPixels*4));
   1111 	*pic = targa_rgba;
   1112 
   1113 	if (targa_header.id_length != 0)
   1114 		buf_p += targa_header.id_length;  // skip TARGA image comment
   1115 	
   1116 	if ( targa_header.image_type==2 || targa_header.image_type == 3 )
   1117 	{ 
   1118 		// Uncompressed RGB or gray scale image
   1119 		for(row=rows-1; row>=0; row--) 
   1120 		{
   1121 			pixbuf = targa_rgba + row*columns*4;
   1122 			for(column=0; column<columns; column++) 
   1123 			{
   1124 				unsigned char red,green,blue,alphabyte;
   1125 				switch (targa_header.pixel_size) 
   1126 				{
   1127 					
   1128 				case 8:
   1129 					blue = *buf_p++;
   1130 					green = blue;
   1131 					red = blue;
   1132 					*pixbuf++ = red;
   1133 					*pixbuf++ = green;
   1134 					*pixbuf++ = blue;
   1135 					*pixbuf++ = 255;
   1136 					break;
   1137 
   1138 				case 24:
   1139 					blue = *buf_p++;
   1140 					green = *buf_p++;
   1141 					red = *buf_p++;
   1142 					*pixbuf++ = red;
   1143 					*pixbuf++ = green;
   1144 					*pixbuf++ = blue;
   1145 					*pixbuf++ = 255;
   1146 					break;
   1147 				case 32:
   1148 					blue = *buf_p++;
   1149 					green = *buf_p++;
   1150 					red = *buf_p++;
   1151 					alphabyte = *buf_p++;
   1152 					//++timo debug: detect if the whole alpha channel is 0
   1153 					if (alphabyte != 0)
   1154 						bAlphaOK = true;
   1155 					*pixbuf++ = red;
   1156 					*pixbuf++ = green;
   1157 					*pixbuf++ = blue;
   1158 					*pixbuf++ = alphabyte;
   1159 					break;
   1160 				default:
   1161 					Sys_Printf("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
   1162 					break;
   1163 				}
   1164 			}
   1165 		}
   1166 
   1167 		//++timo debug
   1168 		if (bAlphaOK)
   1169 			Sys_Printf("alpha channel OK");
   1170 		else
   1171 			Sys_Printf("empty alpha channel!");
   1172 	}
   1173 	else if (targa_header.image_type==10) {   // Runlength encoded RGB images
   1174 
   1175 		//++timo debug
   1176 		Sys_Printf("runlength encode RGB image");
   1177 
   1178 		unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
   1179 
   1180 		red = 0;
   1181 		green = 0;
   1182 		blue = 0;
   1183 		alphabyte = 0xff;
   1184 
   1185 		for(row=rows-1; row>=0; row--) {
   1186 			pixbuf = targa_rgba + row*columns*4;
   1187 			for(column=0; column<columns; ) {
   1188 				packetHeader= *buf_p++;
   1189 				packetSize = 1 + (packetHeader & 0x7f);
   1190 				if (packetHeader & 0x80) {        // run-length packet
   1191 					switch (targa_header.pixel_size) {
   1192 						case 24:
   1193 								blue = *buf_p++;
   1194 								green = *buf_p++;
   1195 								red = *buf_p++;
   1196 								alphabyte = 255;
   1197 								break;
   1198 						case 32:
   1199 								blue = *buf_p++;
   1200 								green = *buf_p++;
   1201 								red = *buf_p++;
   1202 								alphabyte = *buf_p++;
   1203 								break;
   1204 						default:
   1205 							Sys_Printf("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
   1206 							break;
   1207 					}
   1208 	
   1209 					for(j=0;j<packetSize;j++) {
   1210 						*pixbuf++=red;
   1211 						*pixbuf++=green;
   1212 						*pixbuf++=blue;
   1213 						*pixbuf++=alphabyte;
   1214 						column++;
   1215 						if (column==columns) { // run spans across rows
   1216 							column=0;
   1217 							if (row>0)
   1218 								row--;
   1219 							else
   1220 								goto breakOut;
   1221 							pixbuf = targa_rgba + row*columns*4;
   1222 						}
   1223 					}
   1224 				}
   1225 				else {                            // non run-length packet
   1226 					for(j=0;j<packetSize;j++) {
   1227 						switch (targa_header.pixel_size) {
   1228 							case 24:
   1229 									blue = *buf_p++;
   1230 									green = *buf_p++;
   1231 									red = *buf_p++;
   1232 									*pixbuf++ = red;
   1233 									*pixbuf++ = green;
   1234 									*pixbuf++ = blue;
   1235 									*pixbuf++ = 255;
   1236 									break;
   1237 							case 32:
   1238 									blue = *buf_p++;
   1239 									green = *buf_p++;
   1240 									red = *buf_p++;
   1241 									alphabyte = *buf_p++;
   1242 									*pixbuf++ = red;
   1243 									*pixbuf++ = green;
   1244 									*pixbuf++ = blue;
   1245 									*pixbuf++ = alphabyte;
   1246 									break;
   1247 							default:
   1248 								Sys_Printf("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size, name );
   1249 								break;
   1250 						}
   1251 						column++;
   1252 						if (column==columns) { // pixel packet run spans across rows
   1253 							column=0;
   1254 							if (row>0)
   1255 								row--;
   1256 							else
   1257 								goto breakOut;
   1258 							pixbuf = targa_rgba + row*columns*4;
   1259 						}						
   1260 					}
   1261 				}
   1262 			}
   1263 			breakOut:;
   1264 		}
   1265 	}
   1266 
   1267 	free(buffer);
   1268 }
   1269 
   1270 
   1271 
   1272 
   1273 void LoadJPG( const char *filename, unsigned char **pic, int *width, int *height ) 
   1274 {
   1275   byte	*fbuffer = NULL;
   1276   int nLen = LoadFile( ( char * ) filename, (void **)&fbuffer);
   1277   if (nLen == -1) 
   1278   {
   1279     nLen = PakLoadAnyFile((char*)filename, (void**)&fbuffer);
   1280     if (nLen == -1)
   1281     {
   1282 		  return;
   1283     }
   1284   }
   1285   LoadJPGBuff(fbuffer, pic, width, height);
   1286   free(fbuffer);
   1287 }
   1288 
   1289 //===================================================================
   1290 
   1291 /*
   1292 =================
   1293 LoadImage
   1294 
   1295 Loads any of the supported image types into a cannonical
   1296 32 bit format.
   1297 =================
   1298 */
   1299 void LoadImage( const char *name, byte **pic, int *width, int *height ) 
   1300 {
   1301 	int		len;
   1302 	*pic = NULL;
   1303 	*width = 0;
   1304 	*height = 0;
   1305 
   1306 	len = strlen(name);
   1307 	if (len<5) 
   1308   {
   1309 		return;
   1310 	}
   1311 
   1312 	if ( !stricmp( name+len-4, ".tga" ) ) 
   1313   {
   1314 	  LoadTGA( name, pic, width, height );
   1315 	}
   1316   else if ( !stricmp(name+len-4, ".pcx") ) 
   1317   {
   1318     LoadPCX32( name, pic, width, height );
   1319 	} 
   1320   else if ( !stricmp( name+len-4, ".bmp" ) ) 
   1321   {
   1322 		LoadBMP( name, pic, width, height );
   1323 	} 
   1324   else if ( !stricmp( name+len-4, ".jpg" ) ) 
   1325   {
   1326 		LoadJPG( name, pic, width, height ); 
   1327 	}
   1328 }
   1329