1 /*
2    Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4 
5    This file is part of GtkRadiant.
6 
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11 
12    GtkRadiant is distributed in the hope that it will be useful,
13    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 GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21 
22 // imagelib.c
23 
24 #include "inout.h"
25 #include "cmdlib.h"
26 #include "etclib.h"
27 #include "imagelib.h"
28 #include "vfs.h"
29 
fgetLittleShort(FILE * f)30 int fgetLittleShort( FILE *f ){
31 	byte b1, b2;
32 
33 	b1 = fgetc( f );
34 	b2 = fgetc( f );
35 
36 	return (short)( b1 + b2 * 256 );
37 }
38 
fgetLittleLong(FILE * f)39 int fgetLittleLong( FILE *f ){
40 	byte b1, b2, b3, b4;
41 
42 	b1 = fgetc( f );
43 	b2 = fgetc( f );
44 	b3 = fgetc( f );
45 	b4 = fgetc( f );
46 
47 	return b1 + ( b2 << 8 ) + ( b3 << 16 ) + ( b4 << 24 );
48 }
49 
bufLittleShort(byte * buf,int len,int * pos)50 int bufLittleShort( byte *buf, int len, int *pos ){
51 	byte b1, b2;
52 
53 	if ( ( len - *pos ) < 2 ) {
54 		Error( "Unexpected buffer end" );
55 	}
56 
57 	b1 = buf[*pos]; *pos += 1;
58 	b2 = buf[*pos]; *pos += 1;
59 
60 	return (short)( b1 + b2 * 256 );
61 }
62 
bufLittleLong(byte * buf,int len,int * pos)63 int bufLittleLong( byte *buf, int len, int *pos ){
64 	byte b1, b2, b3, b4;
65 
66 	if ( ( len - *pos ) < 4 ) {
67 		Error( "Unexpected buffer end" );
68 	}
69 
70 	b1 = buf[*pos]; *pos += 1;
71 	b2 = buf[*pos]; *pos += 1;
72 	b3 = buf[*pos]; *pos += 1;
73 	b4 = buf[*pos]; *pos += 1;
74 
75 	return b1 + ( b2 << 8 ) + ( b3 << 16 ) + ( b4 << 24 );
76 }
77 
78 
79 /*
80    ============================================================================
81 
82                         LBM STUFF
83 
84    ============================================================================
85  */
86 
87 
88 typedef unsigned char UBYTE;
89 //conflicts with windows typedef short			WORD;
90 typedef unsigned short UWORD;
91 typedef long LONG;
92 
93 typedef enum
94 {
95 	ms_none,
96 	ms_mask,
97 	ms_transcolor,
98 	ms_lasso
99 } mask_t;
100 
101 typedef enum
102 {
103 	cm_none,
104 	cm_rle1
105 } compress_t;
106 
107 typedef struct
108 {
109 	UWORD w,h;
110 	short x,y;
111 	UBYTE nPlanes;
112 	UBYTE masking;
113 	UBYTE compression;
114 	UBYTE pad1;
115 	UWORD transparentColor;
116 	UBYTE xAspect,yAspect;
117 	short pageWidth,pageHeight;
118 } bmhd_t;
119 
120 extern bmhd_t bmhd;                         // will be in native byte order
121 
122 
123 
124 #define FORMID ( 'F' + ( 'O' << 8 ) + ( (int)'R' << 16 ) + ( (int)'M' << 24 ) )
125 #define ILBMID ( 'I' + ( 'L' << 8 ) + ( (int)'B' << 16 ) + ( (int)'M' << 24 ) )
126 #define PBMID  ( 'P' + ( 'B' << 8 ) + ( (int)'M' << 16 ) + ( (int)' ' << 24 ) )
127 #define BMHDID ( 'B' + ( 'M' << 8 ) + ( (int)'H' << 16 ) + ( (int)'D' << 24 ) )
128 #define BODYID ( 'B' + ( 'O' << 8 ) + ( (int)'D' << 16 ) + ( (int)'Y' << 24 ) )
129 #define CMAPID ( 'C' + ( 'M' << 8 ) + ( (int)'A' << 16 ) + ( (int)'P' << 24 ) )
130 
131 
132 bmhd_t bmhd;
133 
Align(int l)134 int    Align( int l ){
135 	if ( l & 1 ) {
136 		return l + 1;
137 	}
138 	return l;
139 }
140 
141 
142 
143 /*
144    ================
145    LBMRLEdecompress
146 
147    Source must be evenly aligned!
148    ================
149  */
LBMRLEDecompress(byte * source,byte * unpacked,int bpwidth)150 byte  *LBMRLEDecompress( byte *source,byte *unpacked, int bpwidth ){
151 	int count;
152 	byte b,rept;
153 
154 	count = 0;
155 
156 	do
157 	{
158 		rept = *source++;
159 
160 		if ( rept > 0x80 ) {
161 			rept = ( rept ^ 0xff ) + 2;
162 			b = *source++;
163 			memset( unpacked,b,rept );
164 			unpacked += rept;
165 		}
166 		else if ( rept < 0x80 ) {
167 			rept++;
168 			memcpy( unpacked,source,rept );
169 			unpacked += rept;
170 			source += rept;
171 		}
172 		else{
173 			rept = 0;               // rept of 0x80 is NOP
174 
175 		}
176 		count += rept;
177 
178 	} while ( count < bpwidth );
179 
180 	if ( count > bpwidth ) {
181 		Error( "Decompression exceeded width!\n" );
182 	}
183 
184 
185 	return source;
186 }
187 
188 
189 /*
190    =================
191    LoadLBM
192    =================
193  */
LoadLBM(const char * filename,byte ** picture,byte ** palette)194 void LoadLBM( const char *filename, byte **picture, byte **palette ){
195 	byte    *LBMbuffer, *picbuffer, *cmapbuffer;
196 	int y;
197 	byte    *LBM_P, *LBMEND_P;
198 	byte    *pic_p;
199 	byte    *body_p;
200 
201 	int formtype,formlength;
202 	int chunktype,chunklength;
203 
204 // qiet compiler warnings
205 	picbuffer = NULL;
206 	cmapbuffer = NULL;
207 
208 //
209 // load the LBM
210 //
211 	LoadFile( filename, (void **)&LBMbuffer );
212 
213 //
214 // parse the LBM header
215 //
216 	LBM_P = LBMbuffer;
217 	if ( *(int *)LBMbuffer != LittleLong( FORMID ) ) {
218 		Error( "No FORM ID at start of file!\n" );
219 	}
220 
221 	LBM_P += 4;
222 	formlength = BigLong( *(int *)LBM_P );
223 	LBM_P += 4;
224 	LBMEND_P = LBM_P + Align( formlength );
225 
226 	formtype = LittleLong( *(int *)LBM_P );
227 
228 	if ( formtype != ILBMID && formtype != PBMID ) {
229 		Error( "Unrecognized form type: %c%c%c%c\n", formtype & 0xff
230 			   ,( formtype >> 8 ) & 0xff,( formtype >> 16 ) & 0xff,( formtype >> 24 ) & 0xff );
231 	}
232 
233 	LBM_P += 4;
234 
235 //
236 // parse chunks
237 //
238 
239 	while ( LBM_P < LBMEND_P )
240 	{
241 		chunktype = LBM_P[0] + ( LBM_P[1] << 8 ) + ( LBM_P[2] << 16 ) + ( LBM_P[3] << 24 );
242 		LBM_P += 4;
243 		chunklength = LBM_P[3] + ( LBM_P[2] << 8 ) + ( LBM_P[1] << 16 ) + ( LBM_P[0] << 24 );
244 		LBM_P += 4;
245 
246 		switch ( chunktype )
247 		{
248 		case BMHDID:
249 			memcpy( &bmhd,LBM_P,sizeof( bmhd ) );
250 			bmhd.w = BigShort( bmhd.w );
251 			bmhd.h = BigShort( bmhd.h );
252 			bmhd.x = BigShort( bmhd.x );
253 			bmhd.y = BigShort( bmhd.y );
254 			bmhd.pageWidth = BigShort( bmhd.pageWidth );
255 			bmhd.pageHeight = BigShort( bmhd.pageHeight );
256 			break;
257 
258 		case CMAPID:
259 			cmapbuffer = safe_malloc( 768 );
260 			memset( cmapbuffer, 0, 768 );
261 			memcpy( cmapbuffer, LBM_P, chunklength );
262 			break;
263 
264 		case BODYID:
265 			body_p = LBM_P;
266 
267 			pic_p = picbuffer = safe_malloc( bmhd.w * bmhd.h );
268 			if ( formtype == PBMID ) {
269 				//
270 				// unpack PBM
271 				//
272 				for ( y = 0 ; y < bmhd.h ; y++, pic_p += bmhd.w )
273 				{
274 					if ( bmhd.compression == cm_rle1 ) {
275 						body_p = LBMRLEDecompress( (byte *)body_p
276 												   , pic_p, bmhd.w );
277 					}
278 					else if ( bmhd.compression == cm_none ) {
279 						memcpy( pic_p,body_p,bmhd.w );
280 						body_p += Align( bmhd.w );
281 					}
282 				}
283 
284 			}
285 			else
286 			{
287 				//
288 				// unpack ILBM
289 				//
290 				Error( "%s is an interlaced LBM, not packed", filename );
291 			}
292 			break;
293 		}
294 
295 		LBM_P += Align( chunklength );
296 	}
297 
298 	free( LBMbuffer );
299 
300 	*picture = picbuffer;
301 
302 	if ( palette ) {
303 		*palette = cmapbuffer;
304 	}
305 }
306 
307 
308 /*
309    ============================================================================
310 
311                             WRITE LBM
312 
313    ============================================================================
314  */
315 
316 /*
317    ==============
318    WriteLBMfile
319    ==============
320  */
WriteLBMfile(const char * filename,byte * data,int width,int height,byte * palette)321 void WriteLBMfile( const char *filename, byte *data,
322 				   int width, int height, byte *palette ){
323 	byte    *lbm, *lbmptr;
324 	int    *formlength, *bmhdlength, *cmaplength, *bodylength;
325 	int length;
326 	bmhd_t basebmhd;
327 
328 	lbm = lbmptr = safe_malloc( width * height + 1000 );
329 
330 //
331 // start FORM
332 //
333 	*lbmptr++ = 'F';
334 	*lbmptr++ = 'O';
335 	*lbmptr++ = 'R';
336 	*lbmptr++ = 'M';
337 
338 	formlength = (int*)lbmptr;
339 	lbmptr += 4;                      // leave space for length
340 
341 	*lbmptr++ = 'P';
342 	*lbmptr++ = 'B';
343 	*lbmptr++ = 'M';
344 	*lbmptr++ = ' ';
345 
346 //
347 // write BMHD
348 //
349 	*lbmptr++ = 'B';
350 	*lbmptr++ = 'M';
351 	*lbmptr++ = 'H';
352 	*lbmptr++ = 'D';
353 
354 	bmhdlength = (int *)lbmptr;
355 	lbmptr += 4;                      // leave space for length
356 
357 	memset( &basebmhd,0,sizeof( basebmhd ) );
358 	basebmhd.w = BigShort( (short)width );
359 	basebmhd.h = BigShort( (short)height );
360 	basebmhd.nPlanes = BigShort( 8 );
361 	basebmhd.xAspect = BigShort( 5 );
362 	basebmhd.yAspect = BigShort( 6 );
363 	basebmhd.pageWidth = BigShort( (short)width );
364 	basebmhd.pageHeight = BigShort( (short)height );
365 
366 	memcpy( lbmptr,&basebmhd,sizeof( basebmhd ) );
367 	lbmptr += sizeof( basebmhd );
368 
369 	length = lbmptr - (byte *)bmhdlength - 4;
370 	*bmhdlength = BigLong( length );
371 	if ( length & 1 ) {
372 		*lbmptr++ = 0;          // pad chunk to even offset
373 
374 	}
375 //
376 // write CMAP
377 //
378 	*lbmptr++ = 'C';
379 	*lbmptr++ = 'M';
380 	*lbmptr++ = 'A';
381 	*lbmptr++ = 'P';
382 
383 	cmaplength = (int *)lbmptr;
384 	lbmptr += 4;                      // leave space for length
385 
386 	memcpy( lbmptr,palette,768 );
387 	lbmptr += 768;
388 
389 	length = lbmptr - (byte *)cmaplength - 4;
390 	*cmaplength = BigLong( length );
391 	if ( length & 1 ) {
392 		*lbmptr++ = 0;          // pad chunk to even offset
393 
394 	}
395 //
396 // write BODY
397 //
398 	*lbmptr++ = 'B';
399 	*lbmptr++ = 'O';
400 	*lbmptr++ = 'D';
401 	*lbmptr++ = 'Y';
402 
403 	bodylength = (int *)lbmptr;
404 	lbmptr += 4;                      // leave space for length
405 
406 	memcpy( lbmptr,data,width * height );
407 	lbmptr += width * height;
408 
409 	length = lbmptr - (byte *)bodylength - 4;
410 	*bodylength = BigLong( length );
411 	if ( length & 1 ) {
412 		*lbmptr++ = 0;          // pad chunk to even offset
413 
414 	}
415 //
416 // done
417 //
418 	length = lbmptr - (byte *)formlength - 4;
419 	*formlength = BigLong( length );
420 	if ( length & 1 ) {
421 		*lbmptr++ = 0;          // pad chunk to even offset
422 
423 	}
424 //
425 // write output file
426 //
427 	SaveFile( filename, lbm, lbmptr - lbm );
428 	free( lbm );
429 }
430 
431 
432 /*
433    ============================================================================
434 
435    LOAD PCX
436 
437    ============================================================================
438  */
439 
440 typedef struct
441 {
442 	char manufacturer;
443 	char version;
444 	char encoding;
445 	char bits_per_pixel;
446 	unsigned short xmin,ymin,xmax,ymax;
447 	unsigned short hres,vres;
448 	unsigned char palette[48];
449 	char reserved;
450 	char color_planes;
451 	unsigned short bytes_per_line;
452 	unsigned short palette_type;
453 	char filler[58];
454 	unsigned char data;             // unbounded
455 } pcx_t;
456 
457 
458 /*
459    ==============
460    LoadPCX
461    ==============
462  */
463 
464 /* RR2DO2 */
465 #define DECODEPCX( b, d, r ) d = *b++; if ( ( d & 0xC0 ) == 0xC0 ) {r = d & 0x3F; d = *b++; }else{r = 1; }
466 
LoadPCX(const char * filename,byte ** pic,byte ** palette,int * width,int * height)467 void LoadPCX( const char *filename, byte **pic, byte **palette, int *width, int *height ){
468 	byte    *raw;
469 	pcx_t   *pcx;
470 	int x, y, lsize;
471 	int len;
472 	int dataByte, runLength;
473 	byte    *out, *pix;
474 
475 
476 	/* load the file */
477 	len = vfsLoadFile( filename, (void **)&raw, 0 );
478 	if ( len == -1 ) {
479 		Error( "LoadPCX: Couldn't read %s", filename );
480 	}
481 
482 
483 	/* parse the PCX file */
484 	pcx = (pcx_t *)raw;
485 	raw = &pcx->data;
486 
487 	pcx->xmin = LittleShort( pcx->xmin );
488 	pcx->ymin = LittleShort( pcx->ymin );
489 	pcx->xmax = LittleShort( pcx->xmax );
490 	pcx->ymax = LittleShort( pcx->ymax );
491 	pcx->hres = LittleShort( pcx->hres );
492 	pcx->vres = LittleShort( pcx->vres );
493 	pcx->bytes_per_line = LittleShort( pcx->bytes_per_line );
494 	pcx->palette_type = LittleShort( pcx->palette_type );
495 
496 	if ( pcx->manufacturer != 0x0a
497 		 || pcx->version != 5
498 		 || pcx->encoding != 1
499 		 || pcx->bits_per_pixel != 8
500 		 || pcx->xmax >= 640
501 		 || pcx->ymax >= 480 ) {
502 		Error( "Bad pcx file %s", filename );
503 	}
504 
505 	if ( palette ) {
506 		*palette = safe_malloc( 768 );
507 		memcpy( *palette, (byte *)pcx + len - 768, 768 );
508 	}
509 
510 	if ( width ) {
511 		*width = pcx->xmax + 1;
512 	}
513 	if ( height ) {
514 		*height = pcx->ymax + 1;
515 	}
516 
517 	if ( !pic ) {
518 		return;
519 	}
520 
521 	out = safe_malloc( ( pcx->ymax + 1 ) * ( pcx->xmax + 1 ) );
522 	if ( !out ) {
523 		Error( "LoadPCX: couldn't allocate" );
524 	}
525 
526 	*pic = out;
527 	pix = out;
528 
529 	/* RR2DO2: pcx fix  */
530 	lsize = pcx->color_planes * pcx->bytes_per_line;
531 
532 	/* go scanline by scanline */
533 	for ( y = 0; y <= pcx->ymax; y++, pix += pcx->xmax + 1 )
534 	{
535 		/* do a scanline */
536 		runLength = 0;
537 		for ( x = 0; x <= pcx->xmax; )
538 		{
539 			/* RR2DO2 */
540 			DECODEPCX( raw, dataByte, runLength );
541 			while ( runLength-- > 0 )
542 				pix[ x++ ] = dataByte;
543 		}
544 
545 		/* RR2DO2: discard any other data */
546 		while ( x < lsize )
547 		{
548 			DECODEPCX( raw, dataByte, runLength );
549 			x++;
550 		}
551 		while ( runLength-- > 0 )
552 			x++;
553 	}
554 
555 	/* validity check */
556 	if ( raw - (byte *) pcx > len ) {
557 		Error( "PCX file %s was malformed", filename );
558 	}
559 	free( pcx );
560 }
561 
562 
563 
564 /*
565    ==============
566    WritePCXfile
567    ==============
568  */
WritePCXfile(const char * filename,byte * data,int width,int height,byte * palette)569 void WritePCXfile( const char *filename, byte *data,
570 				   int width, int height, byte *palette ){
571 	int i, j, length;
572 	pcx_t   *pcx;
573 	byte        *pack;
574 
575 	pcx = safe_malloc( width * height * 2 + 1000 );
576 	memset( pcx, 0, sizeof( *pcx ) );
577 
578 	pcx->manufacturer = 0x0a;   // PCX id
579 	pcx->version = 5;           // 256 color
580 	pcx->encoding = 1;      // uncompressed
581 	pcx->bits_per_pixel = 8;        // 256 color
582 	pcx->xmin = 0;
583 	pcx->ymin = 0;
584 	pcx->xmax = LittleShort( (short)( width - 1 ) );
585 	pcx->ymax = LittleShort( (short)( height - 1 ) );
586 	pcx->hres = LittleShort( (short)width );
587 	pcx->vres = LittleShort( (short)height );
588 	pcx->color_planes = 1;      // chunky image
589 	pcx->bytes_per_line = LittleShort( (short)width );
590 	pcx->palette_type = LittleShort( 1 );     // not a grey scale
591 
592 	// pack the image
593 	pack = &pcx->data;
594 
595 	for ( i = 0 ; i < height ; i++ )
596 	{
597 		for ( j = 0 ; j < width ; j++ )
598 		{
599 			if ( ( *data & 0xc0 ) != 0xc0 ) {
600 				*pack++ = *data++;
601 			}
602 			else
603 			{
604 				*pack++ = 0xc1;
605 				*pack++ = *data++;
606 			}
607 		}
608 	}
609 
610 	// write the palette
611 	*pack++ = 0x0c; // palette ID byte
612 	for ( i = 0 ; i < 768 ; i++ )
613 		*pack++ = *palette++;
614 
615 // write output file
616 	length = pack - (byte *)pcx;
617 	SaveFile( filename, pcx, length );
618 
619 	free( pcx );
620 }
621 
622 /*
623    ============================================================================
624 
625    LOAD BMP
626 
627    ============================================================================
628  */
629 
630 
631 /*
632 
633    // we can't just use these structures, because
634    // compiler structure alignment will not be portable
635    // on this unaligned stuff
636 
637    typedef struct tagBITMAPFILEHEADER { // bmfh
638         WORD    bfType;				// BM
639         DWORD   bfSize;
640         WORD    bfReserved1;
641         WORD    bfReserved2;
642         DWORD   bfOffBits;
643    } BITMAPFILEHEADER;
644 
645    typedef struct tagBITMAPINFOHEADER{ // bmih
646    DWORD  biSize;
647    LONG   biWidth;
648    LONG   biHeight;
649    WORD   biPlanes;
650    WORD   biBitCount
651    DWORD  biCompression;
652    DWORD  biSizeImage;
653    LONG   biXPelsPerMeter;
654    LONG   biYPelsPerMeter;
655    DWORD  biClrUsed;
656    DWORD  biClrImportant;
657    } BITMAPINFOHEADER;
658 
659    typedef struct tagBITMAPINFO { // bmi
660    BITMAPINFOHEADER bmiHeader;
661    RGBQUAD          bmiColors[1];
662    } BITMAPINFO;
663 
664    typedef struct tagBITMAPCOREHEADER { // bmch
665         DWORD   bcSize;
666         WORD    bcWidth;
667         WORD    bcHeight;
668         WORD    bcPlanes;
669         WORD    bcBitCount;
670    } BITMAPCOREHEADER;
671 
672    typedef struct _BITMAPCOREINFO {    // bmci
673         BITMAPCOREHEADER  bmciHeader;
674         RGBTRIPLE         bmciColors[1];
675    } BITMAPCOREINFO;
676 
677  */
678 
679 /*
680    ==============
681    LoadBMP
682    ==============
683  */
LoadBMP(const char * filename,byte ** pic,byte ** palette,int * width,int * height)684 void LoadBMP( const char *filename, byte **pic, byte **palette, int *width, int *height ){
685 	byte  *out;
686 	int i;
687 	int bfOffBits;
688 	int structSize;
689 	int bcWidth;
690 	int bcHeight;
691 	int bcPlanes;
692 	int bcBitCount;
693 	byte bcPalette[1024];
694 	qboolean flipped;
695 	byte *in;
696 	int len, pos = 0;
697 
698 	len = vfsLoadFile( filename, (void **)&in, 0 );
699 	if ( len == -1 ) {
700 		Error( "Couldn't read %s", filename );
701 	}
702 
703 	i = bufLittleShort( in, len, &pos );
704 	if ( i != 'B' + ( 'M' << 8 ) ) {
705 		Error( "%s is not a bmp file", filename );
706 	}
707 
708 	/* bfSize = */ bufLittleLong( in, len, &pos );
709 	bufLittleShort( in, len, &pos );
710 	bufLittleShort( in, len, &pos );
711 	bfOffBits = bufLittleLong( in, len, &pos );
712 
713 	// the size will tell us if it is a
714 	// bitmapinfo or a bitmapcore
715 	structSize = bufLittleLong( in, len, &pos );
716 	if ( structSize == 40 ) {
717 		// bitmapinfo
718 		bcWidth = bufLittleLong( in, len, &pos );
719 		bcHeight = bufLittleLong( in, len, &pos );
720 		bcPlanes = bufLittleShort( in, len, &pos );
721 		bcBitCount = bufLittleShort( in, len, &pos );
722 
723 		pos += 24;
724 
725 		if ( palette ) {
726 			memcpy( bcPalette, in + pos, 1024 );
727 			pos += 1024;
728 			*palette = safe_malloc( 768 );
729 
730 			for ( i = 0 ; i < 256 ; i++ )
731 			{
732 				( *palette )[i * 3 + 0] = bcPalette[i * 4 + 2];
733 				( *palette )[i * 3 + 1] = bcPalette[i * 4 + 1];
734 				( *palette )[i * 3 + 2] = bcPalette[i * 4 + 0];
735 			}
736 		}
737 	}
738 	else if ( structSize == 12 ) {
739 		// bitmapcore
740 		bcWidth = bufLittleShort( in, len, &pos );
741 		bcHeight = bufLittleShort( in, len, &pos );
742 		bcPlanes = bufLittleShort( in, len, &pos );
743 		bcBitCount = bufLittleShort( in, len, &pos );
744 
745 		if ( palette ) {
746 			memcpy( bcPalette, in + pos, 768 );
747 			pos += 768;
748 			*palette = safe_malloc( 768 );
749 
750 			for ( i = 0 ; i < 256 ; i++ ) {
751 				( *palette )[i * 3 + 0] = bcPalette[i * 3 + 2];
752 				( *palette )[i * 3 + 1] = bcPalette[i * 3 + 1];
753 				( *palette )[i * 3 + 2] = bcPalette[i * 3 + 0];
754 			}
755 		}
756 	}
757 	else {
758 		Error( "%s had strange struct size", filename );
759 	}
760 
761 	if ( bcPlanes != 1 ) {
762 		Error( "%s was not a single plane image", filename );
763 	}
764 
765 	if ( bcBitCount != 8 ) {
766 		Error( "%s was not an 8 bit image", filename );
767 	}
768 
769 	if ( bcHeight < 0 ) {
770 		bcHeight = -bcHeight;
771 		flipped = qtrue;
772 	}
773 	else {
774 		flipped = qfalse;
775 	}
776 
777 	if ( width ) {
778 		*width = bcWidth;
779 	}
780 	if ( height ) {
781 		*height = bcHeight;
782 	}
783 
784 	if ( !pic ) {
785 		free( in );
786 		return;
787 	}
788 
789 	out = safe_malloc( bcWidth * bcHeight );
790 	*pic = out;
791 	pos = bfOffBits;
792 
793 	if ( flipped ) {
794 		for ( i = 0 ; i < bcHeight ; i++ ) {
795 			memcpy( out + bcWidth * ( bcHeight - 1 - i ), in + pos, bcWidth );
796 			pos += bcWidth;
797 		}
798 	}
799 	else {
800 		memcpy( out, in + pos, bcWidth * bcHeight );
801 		pos += bcWidth * bcHeight;
802 	}
803 
804 	free( in );
805 }
806 
807 
808 /*
809    ============================================================================
810 
811    LOAD IMAGE
812 
813    ============================================================================
814  */
815 
816 /*
817    ==============
818    Load256Image
819 
820    Will load either an lbm or pcx, depending on extension.
821    Any of the return pointers can be NULL if you don't want them.
822    ==============
823  */
Load256Image(const char * name,byte ** pixels,byte ** palette,int * width,int * height)824 void Load256Image( const char *name, byte **pixels, byte **palette, int *width, int *height ){
825 	char ext[128];
826 
827 	ExtractFileExtension( name, ext );
828 	if ( !Q_stricmp( ext, "lbm" ) ) {
829 		LoadLBM( name, pixels, palette );
830 		if ( width ) {
831 			*width = bmhd.w;
832 		}
833 		if ( height ) {
834 			*height = bmhd.h;
835 		}
836 	}
837 	else if ( !Q_stricmp( ext, "pcx" ) ) {
838 		LoadPCX( name, pixels, palette, width, height );
839 	}
840 	else if ( !Q_stricmp( ext, "bmp" ) ) {
841 		LoadBMP( name, pixels, palette, width, height );
842 	}
843 	else{
844 		Error( "%s doesn't have a known image extension", name );
845 	}
846 }
847 
848 
849 /*
850    ==============
851    Save256Image
852 
853    Will save either an lbm or pcx, depending on extension.
854    ==============
855  */
Save256Image(const char * name,byte * pixels,byte * palette,int width,int height)856 void Save256Image( const char *name, byte *pixels, byte *palette,
857 				   int width, int height ){
858 	char ext[128];
859 
860 	ExtractFileExtension( name, ext );
861 	if ( !Q_stricmp( ext, "lbm" ) ) {
862 		WriteLBMfile( name, pixels, width, height, palette );
863 	}
864 	else if ( !Q_stricmp( ext, "pcx" ) ) {
865 		WritePCXfile( name, pixels, width, height, palette );
866 	}
867 	else{
868 		Error( "%s doesn't have a known image extension", name );
869 	}
870 }
871 
872 
873 
874 
875 /*
876    ============================================================================
877 
878    TARGA IMAGE
879 
880    ============================================================================
881  */
882 
883 typedef struct _TargaHeader {
884 	unsigned char id_length, colormap_type, image_type;
885 	unsigned short colormap_index, colormap_length;
886 	unsigned char colormap_size;
887 	unsigned short x_origin, y_origin, width, height;
888 	unsigned char pixel_size, attributes;
889 } TargaHeader;
890 
TargaError(TargaHeader * t,const char * message)891 void TargaError( TargaHeader *t, const char *message ){
892 	Sys_Printf( "%s\n:TargaHeader:\nuint8 id_length = %i;\nuint8 colormap_type = %i;\nuint8 image_type = %i;\nuint16 colormap_index = %i;\nuint16 colormap_length = %i;\nuint8 colormap_size = %i;\nuint16 x_origin = %i;\nuint16 y_origin = %i;\nuint16 width = %i;\nuint16 height = %i;\nuint8 pixel_size = %i;\nuint8 attributes = %i;\n", message, t->id_length, t->colormap_type, t->image_type, t->colormap_index, t->colormap_length, t->colormap_size, t->x_origin, t->y_origin, t->width, t->height, t->pixel_size, t->attributes );
893 }
894 
895 /*
896    =============
897    LoadTGABuffer
898    =============
899  */
LoadTGABuffer(const byte * f,const byte * enddata,byte ** pic,int * width,int * height)900 void LoadTGABuffer( const byte *f, const byte *enddata, byte **pic, int *width, int *height ){
901 	int x, y, row_inc, compressed, readpixelcount, red, green, blue, alpha, runlen, pindex, alphabits, image_width, image_height;
902 	byte *pixbuf, *image_rgba;
903 	const byte *fin;
904 	unsigned char *p;
905 	TargaHeader targa_header;
906 	unsigned char palette[256 * 4];
907 
908 	*pic = NULL;
909 
910 	// abort if it is too small to parse
911 	if ( enddata - f < 19 ) {
912 		return;
913 	}
914 
915 	targa_header.id_length = f[0];
916 	targa_header.colormap_type = f[1];
917 	targa_header.image_type = f[2];
918 
919 	targa_header.colormap_index = f[3] + f[4] * 256;
920 	targa_header.colormap_length = f[5] + f[6] * 256;
921 	targa_header.colormap_size = f[7];
922 	targa_header.x_origin = f[8] + f[9] * 256;
923 	targa_header.y_origin = f[10] + f[11] * 256;
924 	targa_header.width = image_width = f[12] + f[13] * 256;
925 	targa_header.height = image_height = f[14] + f[15] * 256;
926 
927 	targa_header.pixel_size = f[16];
928 	targa_header.attributes = f[17];
929 
930 	// advance to end of header
931 	fin = f + 18;
932 
933 	// skip TARGA image comment (usually 0 bytes)
934 	fin += targa_header.id_length;
935 
936 	// read/skip the colormap if present (note: according to the TARGA spec it
937 	// can be present even on truecolor or greyscale images, just not used by
938 	// the image data)
939 	if ( targa_header.colormap_type ) {
940 		if ( targa_header.colormap_length > 256 ) {
941 			TargaError( &targa_header, "LoadTGA: only up to 256 colormap_length supported\n" );
942 			return;
943 		}
944 		if ( targa_header.colormap_index ) {
945 			TargaError( &targa_header, "LoadTGA: colormap_index not supported\n" );
946 			return;
947 		}
948 		if ( targa_header.colormap_size == 24 ) {
949 			for ( x = 0; x < targa_header.colormap_length; x++ )
950 			{
951 				palette[x * 4 + 2] = *fin++;
952 				palette[x * 4 + 1] = *fin++;
953 				palette[x * 4 + 0] = *fin++;
954 				palette[x * 4 + 3] = 255;
955 			}
956 		}
957 		else if ( targa_header.colormap_size == 32 ) {
958 			for ( x = 0; x < targa_header.colormap_length; x++ )
959 			{
960 				palette[x * 4 + 2] = *fin++;
961 				palette[x * 4 + 1] = *fin++;
962 				palette[x * 4 + 0] = *fin++;
963 				palette[x * 4 + 3] = *fin++;
964 			}
965 		}
966 		else
967 		{
968 			TargaError( &targa_header, "LoadTGA: Only 32 and 24 bit colormap_size supported\n" );
969 			return;
970 		}
971 	}
972 
973 	// check our pixel_size restrictions according to image_type
974 	if ( targa_header.image_type == 2 || targa_header.image_type == 10 ) {
975 		if ( targa_header.pixel_size != 24 && targa_header.pixel_size != 32 ) {
976 			TargaError( &targa_header, "LoadTGA: only 24bit and 32bit pixel sizes supported for type 2 and type 10 images\n" );
977 			return;
978 		}
979 	}
980 	else if ( targa_header.image_type == 1 || targa_header.image_type == 9 ) {
981 		if ( targa_header.pixel_size != 8 ) {
982 			TargaError( &targa_header, "LoadTGA: only 8bit pixel size for type 1, 3, 9, and 11 images supported\n" );
983 			return;
984 		}
985 	}
986 	else if ( targa_header.image_type == 3 || targa_header.image_type == 11 ) {
987 		if ( targa_header.pixel_size != 8 ) {
988 			TargaError( &targa_header, "LoadTGA: only 8bit pixel size for type 1, 3, 9, and 11 images supported\n" );
989 			return;
990 		}
991 	}
992 	else
993 	{
994 		TargaError( &targa_header, "LoadTGA: Only type 1, 2, 3, 9, 10, and 11 targa RGB images supported" );
995 		return;
996 	}
997 
998 	if ( targa_header.attributes & 0x10 ) {
999 		TargaError( &targa_header, "LoadTGA: origin must be in top left or bottom left, top right and bottom right are not supported\n" );
1000 		return;
1001 	}
1002 
1003 	// number of attribute bits per pixel, we only support 0 or 8
1004 	alphabits = targa_header.attributes & 0x0F;
1005 	if ( alphabits != 8 && alphabits != 0 ) {
1006 		TargaError( &targa_header, "LoadTGA: only 0 or 8 attribute (alpha) bits supported\n" );
1007 		return;
1008 	}
1009 
1010 	image_rgba = safe_malloc( image_width * image_height * 4 );
1011 	if ( !image_rgba ) {
1012 		Sys_Printf( "LoadTGA: not enough memory for %i by %i image\n", image_width, image_height );
1013 		return;
1014 	}
1015 
1016 	// If bit 5 of attributes isn't set, the image has been stored from bottom to top
1017 	if ( ( targa_header.attributes & 0x20 ) == 0 ) {
1018 		pixbuf = image_rgba + ( image_height - 1 ) * image_width * 4;
1019 		row_inc = -image_width * 4 * 2;
1020 	}
1021 	else
1022 	{
1023 		pixbuf = image_rgba;
1024 		row_inc = 0;
1025 	}
1026 
1027 	compressed = targa_header.image_type == 9 || targa_header.image_type == 10 || targa_header.image_type == 11;
1028 	x = 0;
1029 	y = 0;
1030 	red = green = blue = alpha = 255;
1031 	while ( y < image_height )
1032 	{
1033 		// decoder is mostly the same whether it's compressed or not
1034 		readpixelcount = 1000000;
1035 		runlen = 1000000;
1036 		if ( compressed && fin < enddata ) {
1037 			runlen = *fin++;
1038 			// high bit indicates this is an RLE compressed run
1039 			if ( runlen & 0x80 ) {
1040 				readpixelcount = 1;
1041 			}
1042 			runlen = 1 + ( runlen & 0x7f );
1043 		}
1044 
1045 		while ( ( runlen-- ) && y < image_height )
1046 		{
1047 			if ( readpixelcount > 0 ) {
1048 				readpixelcount--;
1049 				red = green = blue = alpha = 255;
1050 				if ( fin < enddata ) {
1051 					switch ( targa_header.image_type )
1052 					{
1053 					case 1:
1054 					case 9:
1055 						// colormapped
1056 						pindex = *fin++;
1057 						if ( pindex >= targa_header.colormap_length ) {
1058 							pindex = 0; // error
1059 						}
1060 						p = palette + pindex * 4;
1061 						red = p[0];
1062 						green = p[1];
1063 						blue = p[2];
1064 						alpha = p[3];
1065 						break;
1066 					case 2:
1067 					case 10:
1068 						// BGR or BGRA
1069 						blue = *fin++;
1070 						if ( fin < enddata ) {
1071 							green = *fin++;
1072 						}
1073 						if ( fin < enddata ) {
1074 							red = *fin++;
1075 						}
1076 						if ( targa_header.pixel_size == 32 && fin < enddata ) {
1077 							alpha = *fin++;
1078 						}
1079 						break;
1080 					case 3:
1081 					case 11:
1082 						// greyscale
1083 						red = green = blue = *fin++;
1084 						break;
1085 					}
1086 					if ( !alphabits ) {
1087 						alpha = 255;
1088 					}
1089 				}
1090 			}
1091 			*pixbuf++ = red;
1092 			*pixbuf++ = green;
1093 			*pixbuf++ = blue;
1094 			*pixbuf++ = alpha;
1095 			x++;
1096 			if ( x == image_width ) {
1097 				// end of line, advance to next
1098 				x = 0;
1099 				y++;
1100 				pixbuf += row_inc;
1101 			}
1102 		}
1103 	}
1104 
1105 	*pic = image_rgba;
1106 	if ( width ) {
1107 		*width = image_width;
1108 	}
1109 	if ( height ) {
1110 		*height = image_height;
1111 	}
1112 }
1113 
1114 
1115 /*
1116    =============
1117    LoadTGA
1118    =============
1119  */
LoadTGA(const char * name,byte ** pixels,int * width,int * height)1120 void LoadTGA( const char *name, byte **pixels, int *width, int *height ){
1121 	byte            *buffer;
1122 	int nLen;
1123 	//
1124 	// load the file
1125 	//
1126 	nLen = vfsLoadFile( name, (void **)&buffer, 0 );
1127 	if ( nLen == -1 ) {
1128 		Error( "Couldn't read %s", name );
1129 	}
1130 
1131 	LoadTGABuffer( buffer, buffer + nLen, pixels, width, height );
1132 
1133 }
1134 
1135 
1136 /*
1137    ================
1138    WriteTGA
1139    ================
1140  */
WriteTGA(const char * filename,byte * data,int width,int height)1141 void WriteTGA( const char *filename, byte *data, int width, int height ) {
1142 	byte    *buffer;
1143 	int i;
1144 	int c;
1145 	FILE    *f;
1146 
1147 	buffer = safe_malloc( width * height * 4 + 18 );
1148 	memset( buffer, 0, 18 );
1149 	buffer[2] = 2;      // uncompressed type
1150 	buffer[12] = width & 255;
1151 	buffer[13] = width >> 8;
1152 	buffer[14] = height & 255;
1153 	buffer[15] = height >> 8;
1154 	buffer[16] = 32;    // pixel size
1155 
1156 	// swap rgb to bgr
1157 	c = 18 + width * height * 4;
1158 	for ( i = 18 ; i < c ; i += 4 )
1159 	{
1160 		buffer[i] = data[i - 18 + 2];       // blue
1161 		buffer[i + 1] = data[i - 18 + 1];     // green
1162 		buffer[i + 2] = data[i - 18 + 0];     // red
1163 		buffer[i + 3] = data[i - 18 + 3];     // alpha
1164 	}
1165 
1166 	f = fopen( filename, "wb" );
1167 	fwrite( buffer, 1, c, f );
1168 	fclose( f );
1169 
1170 	free( buffer );
1171 }
1172 
WriteTGAGray(const char * filename,byte * data,int width,int height)1173 void WriteTGAGray( const char *filename, byte *data, int width, int height ) {
1174 	byte buffer[18];
1175 	FILE    *f;
1176 
1177 	memset( buffer, 0, 18 );
1178 	buffer[2] = 3;      // uncompressed type
1179 	buffer[12] = width & 255;
1180 	buffer[13] = width >> 8;
1181 	buffer[14] = height & 255;
1182 	buffer[15] = height >> 8;
1183 	buffer[16] = 8; // pixel size
1184 
1185 	f = fopen( filename, "wb" );
1186 	fwrite( buffer, 1, 18, f );
1187 	fwrite( data, 1, width * height, f );
1188 	fclose( f );
1189 }
1190 
1191 /*
1192    ============================================================================
1193 
1194    LOAD32BITIMAGE
1195 
1196    ============================================================================
1197  */
1198 
1199 /*
1200    ==============
1201    Load32BitImage
1202 
1203    Any of the return pointers can be NULL if you don't want them.
1204    ==============
1205  */
Load32BitImage(const char * name,unsigned ** pixels,int * width,int * height)1206 void Load32BitImage( const char *name, unsigned **pixels,  int *width, int *height ){
1207 	char ext[128];
1208 	byte    *palette;
1209 	byte    *pixels8;
1210 	byte    *pixels32;
1211 	int size;
1212 	int i;
1213 	int v;
1214 
1215 	ExtractFileExtension( name, ext );
1216 	if ( !Q_stricmp( ext, "tga" ) ) {
1217 		LoadTGA( name, (byte **)pixels, width, height );
1218 	}
1219 	else {
1220 		Load256Image( name, &pixels8, &palette, width, height );
1221 		if ( !pixels ) {
1222 			return;
1223 		}
1224 		size = *width * *height;
1225 		pixels32 = safe_malloc( size * 4 );
1226 		*pixels = (unsigned *)pixels32;
1227 		for ( i = 0 ; i < size ; i++ ) {
1228 			v = pixels8[i];
1229 			pixels32[i * 4 + 0] = palette[ v * 3 + 0 ];
1230 			pixels32[i * 4 + 1] = palette[ v * 3 + 1 ];
1231 			pixels32[i * 4 + 2] = palette[ v * 3 + 2 ];
1232 			pixels32[i * 4 + 3] = 0xff;
1233 		}
1234 	}
1235 }
1236 
1237 
1238 /*
1239    ============================================================================
1240 
1241    KHRONOS TEXTURE
1242 
1243    ============================================================================
1244  */
1245 
1246 
1247 #define KTX_UINT32_LE( buf ) ( ( unsigned int )( (buf)[0] | ( (buf)[1] << 8 ) | ( (buf)[2] << 16 ) | ( (buf)[3] << 24 ) ) )
1248 #define KTX_UINT32_BE( buf ) ( ( unsigned int )( (buf)[3] | ( (buf)[2] << 8 ) | ( (buf)[1] << 16 ) | ( (buf)[0] << 24 ) ) )
1249 
1250 #define KTX_TYPE_UNSIGNED_BYTE				0x1401
1251 #define KTX_TYPE_UNSIGNED_SHORT_4_4_4_4		0x8033
1252 #define KTX_TYPE_UNSIGNED_SHORT_5_5_5_1		0x8034
1253 #define KTX_TYPE_UNSIGNED_SHORT_5_6_5		0x8363
1254 
1255 #define KTX_FORMAT_ALPHA					0x1906
1256 #define KTX_FORMAT_RGB						0x1907
1257 #define KTX_FORMAT_RGBA						0x1908
1258 #define KTX_FORMAT_LUMINANCE				0x1909
1259 #define KTX_FORMAT_LUMINANCE_ALPHA			0x190A
1260 #define KTX_FORMAT_BGR						0x80E0
1261 #define KTX_FORMAT_BGRA						0x80E1
1262 
1263 #define KTX_FORMAT_ETC1_RGB8				0x8D64
1264 
KTX_DecodeA8(const byte * in,qboolean bigEndian,byte * out)1265 static void KTX_DecodeA8( const byte *in, qboolean bigEndian, byte *out ){
1266 	out[0] = out[1] = out[2] = 0;
1267 	out[3] = in[0];
1268 }
1269 
KTX_DecodeRGB8(const byte * in,qboolean bigEndian,byte * out)1270 static void KTX_DecodeRGB8( const byte *in, qboolean bigEndian, byte *out ){
1271 	out[0] = in[0];
1272 	out[1] = in[1];
1273 	out[2] = in[2];
1274 	out[3] = 255;
1275 }
1276 
KTX_DecodeRGBA8(const byte * in,qboolean bigEndian,byte * out)1277 static void KTX_DecodeRGBA8( const byte *in, qboolean bigEndian, byte *out ){
1278 	out[0] = in[0];
1279 	out[1] = in[1];
1280 	out[2] = in[2];
1281 	out[3] = in[3];
1282 }
1283 
KTX_DecodeL8(const byte * in,qboolean bigEndian,byte * out)1284 static void KTX_DecodeL8( const byte *in, qboolean bigEndian, byte *out ){
1285 	out[0] = out[1] = out[2] = in[0];
1286 	out[3] = 255;
1287 }
1288 
KTX_DecodeLA8(const byte * in,qboolean bigEndian,byte * out)1289 static void KTX_DecodeLA8( const byte *in, qboolean bigEndian, byte *out ){
1290 	out[0] = out[1] = out[2] = in[0];
1291 	out[3] = in[1];
1292 }
1293 
KTX_DecodeBGR8(const byte * in,qboolean bigEndian,byte * out)1294 static void KTX_DecodeBGR8( const byte *in, qboolean bigEndian, byte *out ){
1295 	out[0] = in[2];
1296 	out[1] = in[1];
1297 	out[2] = in[0];
1298 	out[3] = 255;
1299 }
1300 
KTX_DecodeBGRA8(const byte * in,qboolean bigEndian,byte * out)1301 static void KTX_DecodeBGRA8( const byte *in, qboolean bigEndian, byte *out ){
1302 	out[0] = in[2];
1303 	out[1] = in[1];
1304 	out[2] = in[0];
1305 	out[3] = in[3];
1306 }
1307 
KTX_DecodeRGBA4(const byte * in,qboolean bigEndian,byte * out)1308 static void KTX_DecodeRGBA4( const byte *in, qboolean bigEndian, byte *out ){
1309 	unsigned short rgba;
1310 	int r, g, b, a;
1311 
1312 	if ( bigEndian ) {
1313 		rgba = ( in[0] << 8 ) | in[1];
1314 	}
1315 	else {
1316 		rgba = ( in[1] << 8 ) | in[0];
1317 	}
1318 
1319 	r = ( rgba >> 12 ) & 0xf;
1320 	g = ( rgba >> 8 ) & 0xf;
1321 	b = ( rgba >> 4 ) & 0xf;
1322 	a = rgba & 0xf;
1323 	out[0] = ( r << 4 ) | r;
1324 	out[1] = ( g << 4 ) | g;
1325 	out[2] = ( b << 4 ) | b;
1326 	out[3] = ( a << 4 ) | a;
1327 }
1328 
KTX_DecodeRGBA5(const byte * in,qboolean bigEndian,byte * out)1329 static void KTX_DecodeRGBA5( const byte *in, qboolean bigEndian, byte *out ){
1330 	unsigned short rgba;
1331 	int r, g, b;
1332 
1333 	if ( bigEndian ) {
1334 		rgba = ( in[0] << 8 ) | in[1];
1335 	}
1336 	else {
1337 		rgba = ( in[1] << 8 ) | in[0];
1338 	}
1339 
1340 	r = ( rgba >> 11 ) & 0x1f;
1341 	g = ( rgba >> 6 ) & 0x1f;
1342 	b = ( rgba >> 1 ) & 0x1f;
1343 	out[0] = ( r << 3 ) | ( r >> 2 );
1344 	out[1] = ( g << 3 ) | ( g >> 2 );
1345 	out[2] = ( b << 3 ) | ( b >> 2 );
1346 	out[3] = ( rgba & 1 ) * 255;
1347 }
1348 
KTX_DecodeRGB5(const byte * in,qboolean bigEndian,byte * out)1349 static void KTX_DecodeRGB5( const byte *in, qboolean bigEndian, byte *out ){
1350 	unsigned short rgba;
1351 	int r, g, b;
1352 
1353 	if ( bigEndian ) {
1354 		rgba = ( in[0] << 8 ) | in[1];
1355 	}
1356 	else {
1357 		rgba = ( in[1] << 8 ) | in[0];
1358 	}
1359 
1360 	r = ( rgba >> 11 ) & 0x1f;
1361 	g = ( rgba >> 5 ) & 0x3f;
1362 	b = rgba & 0x1f;
1363 	out[0] = ( r << 3 ) | ( r >> 2 );
1364 	out[1] = ( g << 2 ) | ( g >> 4 );
1365 	out[2] = ( b << 3 ) | ( b >> 2 );
1366 	out[3] = 255;
1367 }
1368 
1369 typedef struct
1370 {
1371 	unsigned int type;
1372 	unsigned int format;
1373 	unsigned int pixelSize;
1374 	void ( *decode )( const byte *in, qboolean bigEndian, byte *out );
1375 } KTX_UncompressedFormat_t;
1376 
1377 static const KTX_UncompressedFormat_t KTX_UncompressedFormats[] =
1378 {
1379 	{ KTX_TYPE_UNSIGNED_BYTE, KTX_FORMAT_ALPHA, 1, KTX_DecodeA8 },
1380 	{ KTX_TYPE_UNSIGNED_BYTE, KTX_FORMAT_RGB, 3, KTX_DecodeRGB8 },
1381 	{ KTX_TYPE_UNSIGNED_BYTE, KTX_FORMAT_RGBA, 4, KTX_DecodeRGBA8 },
1382 	{ KTX_TYPE_UNSIGNED_BYTE, KTX_FORMAT_LUMINANCE, 1, KTX_DecodeL8 },
1383 	{ KTX_TYPE_UNSIGNED_BYTE, KTX_FORMAT_LUMINANCE_ALPHA, 2, KTX_DecodeLA8 },
1384 	{ KTX_TYPE_UNSIGNED_BYTE, KTX_FORMAT_BGR, 3, KTX_DecodeBGR8 },
1385 	{ KTX_TYPE_UNSIGNED_BYTE, KTX_FORMAT_BGRA, 4, KTX_DecodeBGRA8 },
1386 	{ KTX_TYPE_UNSIGNED_SHORT_4_4_4_4, KTX_FORMAT_RGBA, 2, KTX_DecodeRGBA4 },
1387 	{ KTX_TYPE_UNSIGNED_SHORT_5_5_5_1, KTX_FORMAT_RGBA, 2, KTX_DecodeRGBA5 },
1388 	{ KTX_TYPE_UNSIGNED_SHORT_5_6_5, KTX_FORMAT_RGB, 2, KTX_DecodeRGB5 },
1389 	{ 0, 0, 0, NULL }
1390 };
1391 
KTX_DecodeETC1(const byte * in,size_t inSize,unsigned int width,unsigned int height,byte * out)1392 static qboolean KTX_DecodeETC1( const byte* in, size_t inSize, unsigned int width, unsigned int height, byte* out ){
1393 	unsigned int y, stride = width * 4;
1394 	byte rgba[64];
1395 
1396 	if ( inSize < ( ( ( ( width + 3 ) & ~3 ) * ( ( height + 3 ) & ~3 ) ) >> 1 ) ) {
1397 		return qfalse;
1398 	}
1399 
1400 	for ( y = 0; y < height; y += 4, out += stride * 4 )
1401 	{
1402 		byte *p;
1403 		unsigned int x, blockrows;
1404 
1405 		blockrows = height - y;
1406 		if ( blockrows > 4 ) {
1407 			blockrows = 4;
1408 		}
1409 
1410 		p = out;
1411 		for ( x = 0; x < width; x += 4, p += 16 )
1412 		{
1413 			unsigned int blockrowsize, blockrow;
1414 
1415 			ETC_DecodeETC1Block( in, rgba, qtrue );
1416 			in += 8;
1417 
1418 			blockrowsize = width - x;
1419 			if ( blockrowsize > 4 ) {
1420 				blockrowsize = 4;
1421 			}
1422 			blockrowsize *= 4;
1423 			for ( blockrow = 0; blockrow < blockrows; blockrow++ )
1424 			{
1425 				memcpy( p + blockrow * stride, rgba + blockrow * 16, blockrowsize );
1426 			}
1427 		}
1428 	}
1429 
1430 	return qtrue;
1431 }
1432 
1433 #define KTX_HEADER_UINT32( buf ) ( bigEndian ? KTX_UINT32_BE( buf ) : KTX_UINT32_LE( buf ) )
1434 
LoadKTXBufferFirstImage(const byte * buffer,size_t bufSize,byte ** pic,int * picWidth,int * picHeight)1435 void LoadKTXBufferFirstImage( const byte *buffer, size_t bufSize, byte **pic, int *picWidth, int *picHeight ){
1436 	unsigned int type, format, width, height, imageOffset;
1437 	byte *pixels;
1438 
1439 	if ( bufSize < 64 ) {
1440 		Error( "LoadKTX: Image doesn't have a header" );
1441 	}
1442 
1443 	if ( memcmp( buffer, "\xABKTX 11\xBB\r\n\x1A\n", 12 ) ) {
1444 		Error( "LoadKTX: Image has the wrong identifier" );
1445 	}
1446 
1447 	qboolean bigEndian = ( buffer[4] == 4 );
1448 
1449 	type = KTX_HEADER_UINT32( buffer + 16 );
1450 	if ( type ) {
1451 		format = KTX_HEADER_UINT32( buffer + 32 );
1452 	}
1453 	else {
1454 		format = KTX_HEADER_UINT32( buffer + 28 );
1455 	}
1456 
1457 	width = KTX_HEADER_UINT32( buffer + 36 );
1458 	height = KTX_HEADER_UINT32( buffer + 40 );
1459 	if ( !width ) {
1460 		Error( "LoadKTX: Image has zero width" );
1461 	}
1462 	if ( !height ) {
1463 		height = 1;
1464 	}
1465 	if ( picWidth ) {
1466 		*picWidth = width;
1467 	}
1468 	if ( picHeight ) {
1469 		*picHeight = height;
1470 	}
1471 
1472 	imageOffset = 64 + KTX_HEADER_UINT32( buffer + 60 ) + 4;
1473 	if ( bufSize < imageOffset ) {
1474 		Error( "LoadKTX: No image in the file" );
1475 	}
1476 	buffer += imageOffset;
1477 	bufSize -= imageOffset;
1478 
1479 	pixels = safe_malloc( width * height * 4 );
1480 	*pic = pixels;
1481 
1482 	if ( type ) {
1483 		const KTX_UncompressedFormat_t *ktxFormat = KTX_UncompressedFormats;
1484 		unsigned int pixelSize;
1485 		unsigned int inRowLength, inPadding;
1486 		unsigned int y;
1487 
1488 		while ( ktxFormat->type )
1489 		{
1490 			if ( ktxFormat->type == type && ktxFormat->format == format ) {
1491 				break;
1492 			}
1493 			ktxFormat++;
1494 		}
1495 		if ( !ktxFormat->type ) {
1496 			Error( "LoadKTX: Image has an unsupported pixel type 0x%X or format 0x%X", type, format );
1497 		}
1498 
1499 		pixelSize = ktxFormat->pixelSize;
1500 		inRowLength = width * pixelSize;
1501 		inPadding = ( ( inRowLength + 3 ) & ~3 ) - inRowLength;
1502 
1503 		if ( bufSize < height * ( inRowLength + inPadding ) ) {
1504 			Error( "LoadKTX: Image is truncated" );
1505 		}
1506 
1507 		for ( y = 0; y < height; y++ )
1508 		{
1509 			unsigned int x;
1510 			for ( x = 0; x < width; x++, buffer += pixelSize, pixels += 4 )
1511 			{
1512 				ktxFormat->decode( buffer, bigEndian, pixels );
1513 			}
1514 			buffer += inPadding;
1515 		}
1516 	}
1517 	else {
1518 		qboolean decoded = qfalse;
1519 
1520 		switch ( format )
1521 		{
1522 		case KTX_FORMAT_ETC1_RGB8:
1523 			decoded = KTX_DecodeETC1( buffer, bufSize, width, height, pixels );
1524 			break;
1525 		default:
1526 			Error( "LoadKTX: Image has an unsupported compressed format format 0x%X", format );
1527 			break;
1528 		}
1529 
1530 		if ( !decoded ) {
1531 			Error( "LoadKTX: Image is truncated" );
1532 		}
1533 	}
1534 }
1535