1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #include "sys/platform.h"
30 
31 #include "renderer/tr_local.h"
32 
33 #include "renderer/Image.h"
34 
35 #include <jpeglib.h>
36 #include <jerror.h>
37 
38 /*
39 
40 This file only has a single entry point:
41 
42 void R_LoadImage( const char *name, byte **pic, int *width, int *height, bool makePowerOf2 );
43 
44 */
45 
46 /*
47 ================
48 R_WriteTGA
49 ================
50 */
R_WriteTGA(const char * filename,const byte * data,int width,int height,bool flipVertical)51 void R_WriteTGA( const char *filename, const byte *data, int width, int height, bool flipVertical ) {
52 	byte	*buffer;
53 	int		i;
54 	int		bufferSize = width*height*4 + 18;
55 	int     imgStart = 18;
56 
57 	buffer = (byte *)Mem_Alloc( bufferSize );
58 	memset( buffer, 0, 18 );
59 	buffer[2] = 2;		// uncompressed type
60 	buffer[12] = width&255;
61 	buffer[13] = width>>8;
62 	buffer[14] = height&255;
63 	buffer[15] = height>>8;
64 	buffer[16] = 32;	// pixel size
65 	if ( !flipVertical ) {
66 		buffer[17] = (1<<5);	// flip bit, for normal top to bottom raster order
67 	}
68 
69 	// swap rgb to bgr
70 	for ( i=imgStart ; i<bufferSize ; i+=4 ) {
71 		buffer[i] = data[i-imgStart+2];		// blue
72 		buffer[i+1] = data[i-imgStart+1];		// green
73 		buffer[i+2] = data[i-imgStart+0];		// red
74 		buffer[i+3] = data[i-imgStart+3];		// alpha
75 	}
76 
77 	fileSystem->WriteFile( filename, buffer, bufferSize );
78 
79 	Mem_Free (buffer);
80 }
81 
82 
83 /*
84 ================
85 R_WritePalTGA
86 ================
87 */
R_WritePalTGA(const char * filename,const byte * data,const byte * palette,int width,int height,bool flipVertical)88 void R_WritePalTGA( const char *filename, const byte *data, const byte *palette, int width, int height, bool flipVertical ) {
89 	byte	*buffer;
90 	int		i;
91 	int		bufferSize = (width * height) + (256 * 3) + 18;
92 	int     palStart = 18;
93 	int     imgStart = 18 + (256 * 3);
94 
95 	buffer = (byte *)Mem_Alloc( bufferSize );
96 	memset( buffer, 0, 18 );
97 	buffer[1] = 1;		// color map type
98 	buffer[2] = 1;		// uncompressed color mapped image
99 	buffer[5] = 0;		// number of palette entries (lo)
100 	buffer[6] = 1;		// number of palette entries (hi)
101 	buffer[7] = 24;		// color map bpp
102 	buffer[12] = width&255;
103 	buffer[13] = width>>8;
104 	buffer[14] = height&255;
105 	buffer[15] = height>>8;
106 	buffer[16] = 8;	// pixel size
107 	if ( !flipVertical ) {
108 		buffer[17] = (1<<5);	// flip bit, for normal top to bottom raster order
109 	}
110 
111 	// store palette, swapping rgb to bgr
112 	for ( i=palStart ; i<imgStart ; i+=3 ) {
113 		buffer[i] = palette[i-palStart+2];		// blue
114 		buffer[i+1] = palette[i-palStart+1];		// green
115 		buffer[i+2] = palette[i-palStart+0];		// red
116 	}
117 
118 	// store the image data
119 	for ( i=imgStart ; i<bufferSize ; i++ ) {
120 		buffer[i] = data[i-imgStart];
121 	}
122 
123 	fileSystem->WriteFile( filename, buffer, bufferSize );
124 
125 	Mem_Free (buffer);
126 }
127 
128 
129 static void LoadBMP( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp );
130 static void LoadTGA( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp );
131 static void LoadJPG( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp );
132 
133 
134 /*
135 ========================================================================
136 
137 PCX files are used for 8 bit images
138 
139 ========================================================================
140 */
141 
142 typedef struct {
143 	char	manufacturer;
144 	char	version;
145 	char	encoding;
146 	char	bits_per_pixel;
147 	unsigned short	xmin,ymin,xmax,ymax;
148 	unsigned short	hres,vres;
149 	unsigned char	palette[48];
150 	char	reserved;
151 	char	color_planes;
152 	unsigned short	bytes_per_line;
153 	unsigned short	palette_type;
154 	char	filler[58];
155 	unsigned char	data;			// unbounded
156 } pcx_t;
157 
158 
159 /*
160 ========================================================================
161 
162 TGA files are used for 24/32 bit images
163 
164 ========================================================================
165 */
166 
167 typedef struct _TargaHeader {
168 	unsigned char	id_length, colormap_type, image_type;
169 	unsigned short	colormap_index, colormap_length;
170 	unsigned char	colormap_size;
171 	unsigned short	x_origin, y_origin, width, height;
172 	unsigned char	pixel_size, attributes;
173 } TargaHeader;
174 
175 
176 
177 /*
178 =========================================================
179 
180 BMP LOADING
181 
182 =========================================================
183 */
184 typedef struct
185 {
186 	char id[2];
187 	unsigned int fileSize;
188 	unsigned int reserved0;
189 	unsigned int bitmapDataOffset;
190 	unsigned int bitmapHeaderSize;
191 	unsigned int width;
192 	unsigned int height;
193 	unsigned short planes;
194 	unsigned short bitsPerPixel;
195 	unsigned int compression;
196 	unsigned int bitmapDataSize;
197 	unsigned int hRes;
198 	unsigned int vRes;
199 	unsigned int colors;
200 	unsigned int importantColors;
201 	unsigned char palette[256][4];
202 } BMPHeader_t;
203 
204 /*
205 ==============
206 LoadBMP
207 ==============
208 */
LoadBMP(const char * name,byte ** pic,int * width,int * height,ID_TIME_T * timestamp)209 static void LoadBMP( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp )
210 {
211 	int		columns, rows, numPixels;
212 	byte	*pixbuf;
213 	int		row, column;
214 	byte	*buf_p;
215 	byte	*buffer;
216 	int		length;
217 	BMPHeader_t bmpHeader;
218 	byte		*bmpRGBA;
219 
220 	if ( !pic ) {
221 		fileSystem->ReadFile ( name, NULL, timestamp );
222 		return;	// just getting timestamp
223 	}
224 
225 	*pic = NULL;
226 
227 	//
228 	// load the file
229 	//
230 	length = fileSystem->ReadFile( name, (void **)&buffer, timestamp );
231 	if ( !buffer ) {
232 		return;
233 	}
234 
235 	buf_p = buffer;
236 
237 	bmpHeader.id[0] = *buf_p++;
238 	bmpHeader.id[1] = *buf_p++;
239 	bmpHeader.fileSize = LittleInt( * ( int * ) buf_p );
240 	buf_p += 4;
241 	bmpHeader.reserved0 = LittleInt( * ( int * ) buf_p );
242 	buf_p += 4;
243 	bmpHeader.bitmapDataOffset = LittleInt( * ( int * ) buf_p );
244 	buf_p += 4;
245 	bmpHeader.bitmapHeaderSize = LittleInt( * ( int * ) buf_p );
246 	buf_p += 4;
247 	bmpHeader.width = LittleInt( * ( int * ) buf_p );
248 	buf_p += 4;
249 	bmpHeader.height = LittleInt( * ( int * ) buf_p );
250 	buf_p += 4;
251 	bmpHeader.planes = LittleShort( * ( short * ) buf_p );
252 	buf_p += 2;
253 	bmpHeader.bitsPerPixel = LittleShort( * ( short * ) buf_p );
254 	buf_p += 2;
255 	bmpHeader.compression = LittleInt( * ( int * ) buf_p );
256 	buf_p += 4;
257 	bmpHeader.bitmapDataSize = LittleInt( * ( int * ) buf_p );
258 	buf_p += 4;
259 	bmpHeader.hRes = LittleInt( * ( int * ) buf_p );
260 	buf_p += 4;
261 	bmpHeader.vRes = LittleInt( * ( int * ) buf_p );
262 	buf_p += 4;
263 	bmpHeader.colors = LittleInt( * ( int * ) buf_p );
264 	buf_p += 4;
265 	bmpHeader.importantColors = LittleInt( * ( int * ) buf_p );
266 	buf_p += 4;
267 
268 	memcpy( bmpHeader.palette, buf_p, sizeof( bmpHeader.palette ) );
269 
270 	if ( bmpHeader.bitsPerPixel == 8 )
271 		buf_p += 1024;
272 
273 	if ( bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M' )
274 	{
275 		common->Error( "LoadBMP: only Windows-style BMP files supported (%s)\n", name );
276 	}
277 	if ( bmpHeader.fileSize != length )
278 	{
279 		common->Error( "LoadBMP: header size does not match file size (%u vs. %d) (%s)\n", bmpHeader.fileSize, length, name );
280 	}
281 	if ( bmpHeader.compression != 0 )
282 	{
283 		common->Error( "LoadBMP: only uncompressed BMP files supported (%s)\n", name );
284 	}
285 	if ( bmpHeader.bitsPerPixel < 8 )
286 	{
287 		common->Error( "LoadBMP: monochrome and 4-bit BMP files not supported (%s)\n", name );
288 	}
289 
290 	columns = bmpHeader.width;
291 	rows = bmpHeader.height;
292 	if ( rows < 0 )
293 		rows = -rows;
294 	numPixels = columns * rows;
295 
296 	if ( width )
297 		*width = columns;
298 	if ( height )
299 		*height = rows;
300 
301 	bmpRGBA = (byte *)R_StaticAlloc( numPixels * 4 );
302 	*pic = bmpRGBA;
303 
304 
305 	for ( row = rows-1; row >= 0; row-- )
306 	{
307 		pixbuf = bmpRGBA + row*columns*4;
308 
309 		for ( column = 0; column < columns; column++ )
310 		{
311 			unsigned char red, green, blue, alpha;
312 			int palIndex;
313 			unsigned short shortPixel;
314 
315 			switch ( bmpHeader.bitsPerPixel )
316 			{
317 			case 8:
318 				palIndex = *buf_p++;
319 				*pixbuf++ = bmpHeader.palette[palIndex][2];
320 				*pixbuf++ = bmpHeader.palette[palIndex][1];
321 				*pixbuf++ = bmpHeader.palette[palIndex][0];
322 				*pixbuf++ = 0xff;
323 				break;
324 			case 16:
325 				shortPixel = * ( unsigned short * ) pixbuf;
326 				pixbuf += 2;
327 				*pixbuf++ = ( shortPixel & ( 31 << 10 ) ) >> 7;
328 				*pixbuf++ = ( shortPixel & ( 31 << 5 ) ) >> 2;
329 				*pixbuf++ = ( shortPixel & ( 31 ) ) << 3;
330 				*pixbuf++ = 0xff;
331 				break;
332 
333 			case 24:
334 				blue = *buf_p++;
335 				green = *buf_p++;
336 				red = *buf_p++;
337 				*pixbuf++ = red;
338 				*pixbuf++ = green;
339 				*pixbuf++ = blue;
340 				*pixbuf++ = 255;
341 				break;
342 			case 32:
343 				blue = *buf_p++;
344 				green = *buf_p++;
345 				red = *buf_p++;
346 				alpha = *buf_p++;
347 				*pixbuf++ = red;
348 				*pixbuf++ = green;
349 				*pixbuf++ = blue;
350 				*pixbuf++ = alpha;
351 				break;
352 			default:
353 				common->Error( "LoadBMP: illegal pixel_size '%d' in file '%s'\n", bmpHeader.bitsPerPixel, name );
354 				break;
355 			}
356 		}
357 	}
358 
359 	fileSystem->FreeFile( buffer );
360 
361 }
362 
363 
364 /*
365 =================================================================
366 
367 PCX LOADING
368 
369 =================================================================
370 */
371 
372 
373 /*
374 ==============
375 LoadPCX
376 ==============
377 */
LoadPCX(const char * filename,byte ** pic,byte ** palette,int * width,int * height,ID_TIME_T * timestamp)378 static void LoadPCX ( const char *filename, byte **pic, byte **palette, int *width, int *height,
379 					 ID_TIME_T *timestamp ) {
380 	byte	*raw;
381 	pcx_t	*pcx;
382 	int		x, y;
383 	int		len;
384 	int		dataByte, runLength;
385 	byte	*out, *pix;
386 	int		xmax, ymax;
387 
388 	if ( !pic ) {
389 		fileSystem->ReadFile( filename, NULL, timestamp );
390 		return;	// just getting timestamp
391 	}
392 
393 	*pic = NULL;
394 	*palette = NULL;
395 
396 	//
397 	// load the file
398 	//
399 	len = fileSystem->ReadFile( filename, (void **)&raw, timestamp );
400 	if (!raw) {
401 		return;
402 	}
403 
404 	//
405 	// parse the PCX file
406 	//
407 	pcx = (pcx_t *)raw;
408 	raw = &pcx->data;
409 
410 	xmax = LittleShort(pcx->xmax);
411 	ymax = LittleShort(pcx->ymax);
412 
413 	if (pcx->manufacturer != 0x0a
414 		|| pcx->version != 5
415 		|| pcx->encoding != 1
416 		|| pcx->bits_per_pixel != 8
417 		|| xmax >= 1024
418 		|| ymax >= 1024)
419 	{
420 		common->Printf( "Bad pcx file %s (%i x %i) (%i x %i)\n", filename, xmax+1, ymax+1, pcx->xmax, pcx->ymax);
421 		return;
422 	}
423 
424 	out = (byte *)R_StaticAlloc( (ymax+1) * (xmax+1) );
425 
426 	*pic = out;
427 
428 	pix = out;
429 
430 	if (palette)
431 	{
432 		*palette = (byte *)R_StaticAlloc(768);
433 		memcpy (*palette, (byte *)pcx + len - 768, 768);
434 	}
435 
436 	if (width)
437 		*width = xmax+1;
438 	if (height)
439 		*height = ymax+1;
440 // FIXME: use bytes_per_line here?
441 
442 	for (y=0 ; y<=ymax ; y++, pix += xmax+1)
443 	{
444 		for (x=0 ; x<=xmax ; )
445 		{
446 			dataByte = *raw++;
447 
448 			if((dataByte & 0xC0) == 0xC0)
449 			{
450 				runLength = dataByte & 0x3F;
451 				dataByte = *raw++;
452 			}
453 			else
454 				runLength = 1;
455 
456 			while(runLength-- > 0)
457 				pix[x++] = dataByte;
458 		}
459 
460 	}
461 
462 	if ( raw - (byte *)pcx > len)
463 	{
464 		common->Printf( "PCX file %s was malformed", filename );
465 		R_StaticFree (*pic);
466 		*pic = NULL;
467 	}
468 
469 	fileSystem->FreeFile( pcx );
470 }
471 
472 
473 /*
474 ==============
475 LoadPCX32
476 ==============
477 */
LoadPCX32(const char * filename,byte ** pic,int * width,int * height,ID_TIME_T * timestamp)478 static void LoadPCX32 ( const char *filename, byte **pic, int *width, int *height, ID_TIME_T *timestamp) {
479 	byte	*palette;
480 	byte	*pic8;
481 	int		i, c, p;
482 	byte	*pic32;
483 
484 	if ( !pic ) {
485 		fileSystem->ReadFile( filename, NULL, timestamp );
486 		return;	// just getting timestamp
487 	}
488 	LoadPCX (filename, &pic8, &palette, width, height, timestamp);
489 	if (!pic8) {
490 		*pic = NULL;
491 		return;
492 	}
493 
494 	c = (*width) * (*height);
495 	pic32 = *pic = (byte *)R_StaticAlloc(4 * c );
496 	for (i = 0 ; i < c ; i++) {
497 		p = pic8[i];
498 		pic32[0] = palette[p*3];
499 		pic32[1] = palette[p*3 + 1];
500 		pic32[2] = palette[p*3 + 2];
501 		pic32[3] = 255;
502 		pic32 += 4;
503 	}
504 
505 	R_StaticFree( pic8 );
506 	R_StaticFree( palette );
507 }
508 
509 /*
510 =========================================================
511 
512 TARGA LOADING
513 
514 =========================================================
515 */
516 
517 /*
518 =============
519 LoadTGA
520 =============
521 */
LoadTGA(const char * name,byte ** pic,int * width,int * height,ID_TIME_T * timestamp)522 static void LoadTGA( const char *name, byte **pic, int *width, int *height, ID_TIME_T *timestamp ) {
523 	int		columns, rows, numPixels, fileSize, numBytes;
524 	byte	*pixbuf;
525 	int		row, column;
526 	byte	*buf_p;
527 	byte	*buffer;
528 	TargaHeader	targa_header;
529 	byte		*targa_rgba;
530 
531 	if ( !pic ) {
532 		fileSystem->ReadFile( name, NULL, timestamp );
533 		return;	// just getting timestamp
534 	}
535 
536 	*pic = NULL;
537 
538 	//
539 	// load the file
540 	//
541 	fileSize = fileSystem->ReadFile( name, (void **)&buffer, timestamp );
542 	if ( !buffer ) {
543 		return;
544 	}
545 
546 	buf_p = buffer;
547 
548 	targa_header.id_length = *buf_p++;
549 	targa_header.colormap_type = *buf_p++;
550 	targa_header.image_type = *buf_p++;
551 
552 	targa_header.colormap_index = LittleShort ( *(short *)buf_p );
553 	buf_p += 2;
554 	targa_header.colormap_length = LittleShort ( *(short *)buf_p );
555 	buf_p += 2;
556 	targa_header.colormap_size = *buf_p++;
557 	targa_header.x_origin = LittleShort ( *(short *)buf_p );
558 	buf_p += 2;
559 	targa_header.y_origin = LittleShort ( *(short *)buf_p );
560 	buf_p += 2;
561 	targa_header.width = LittleShort ( *(short *)buf_p );
562 	buf_p += 2;
563 	targa_header.height = LittleShort ( *(short *)buf_p );
564 	buf_p += 2;
565 	targa_header.pixel_size = *buf_p++;
566 	targa_header.attributes = *buf_p++;
567 
568 	if ( targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3 ) {
569 		common->Error( "LoadTGA( %s ): Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n", name );
570 	}
571 
572 	if ( targa_header.colormap_type != 0 ) {
573 		common->Error( "LoadTGA( %s ): colormaps not supported\n", name );
574 	}
575 
576 	if ( ( targa_header.pixel_size != 32 && targa_header.pixel_size != 24 ) && targa_header.image_type != 3 ) {
577 		common->Error( "LoadTGA( %s ): Only 32 or 24 bit images supported (no colormaps)\n", name );
578 	}
579 
580 	if ( targa_header.image_type == 2 || targa_header.image_type == 3 ) {
581 		numBytes = targa_header.width * targa_header.height * ( targa_header.pixel_size >> 3 );
582 		if ( numBytes > fileSize - 18 - targa_header.id_length ) {
583 			common->Error( "LoadTGA( %s ): incomplete file\n", name );
584 		}
585 	}
586 
587 	columns = targa_header.width;
588 	rows = targa_header.height;
589 	numPixels = columns * rows;
590 
591 	if ( width ) {
592 		*width = columns;
593 	}
594 	if ( height ) {
595 		*height = rows;
596 	}
597 
598 	targa_rgba = (byte *)R_StaticAlloc(numPixels*4);
599 	*pic = targa_rgba;
600 
601 	if ( targa_header.id_length != 0 ) {
602 		buf_p += targa_header.id_length;  // skip TARGA image comment
603 	}
604 
605 	if ( targa_header.image_type == 2 || targa_header.image_type == 3 )
606 	{
607 		// Uncompressed RGB or gray scale image
608 		for( row = rows - 1; row >= 0; row-- )
609 		{
610 			pixbuf = targa_rgba + row*columns*4;
611 			for( column = 0; column < columns; column++)
612 			{
613 				unsigned char red,green,blue,alphabyte;
614 				switch( targa_header.pixel_size )
615 				{
616 
617 				case 8:
618 					blue = *buf_p++;
619 					green = blue;
620 					red = blue;
621 					*pixbuf++ = red;
622 					*pixbuf++ = green;
623 					*pixbuf++ = blue;
624 					*pixbuf++ = 255;
625 					break;
626 
627 				case 24:
628 					blue = *buf_p++;
629 					green = *buf_p++;
630 					red = *buf_p++;
631 					*pixbuf++ = red;
632 					*pixbuf++ = green;
633 					*pixbuf++ = blue;
634 					*pixbuf++ = 255;
635 					break;
636 				case 32:
637 					blue = *buf_p++;
638 					green = *buf_p++;
639 					red = *buf_p++;
640 					alphabyte = *buf_p++;
641 					*pixbuf++ = red;
642 					*pixbuf++ = green;
643 					*pixbuf++ = blue;
644 					*pixbuf++ = alphabyte;
645 					break;
646 				default:
647 					common->Error( "LoadTGA( %s ): illegal pixel_size '%d'\n", name, targa_header.pixel_size );
648 					break;
649 				}
650 			}
651 		}
652 	}
653 	else if ( targa_header.image_type == 10 ) {   // Runlength encoded RGB images
654 		unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
655 
656 		red = 0;
657 		green = 0;
658 		blue = 0;
659 		alphabyte = 0xff;
660 
661 		for( row = rows - 1; row >= 0; row-- ) {
662 			pixbuf = targa_rgba + row*columns*4;
663 			for( column = 0; column < columns; ) {
664 				packetHeader= *buf_p++;
665 				packetSize = 1 + (packetHeader & 0x7f);
666 				if ( packetHeader & 0x80 ) {        // run-length packet
667 					switch( targa_header.pixel_size ) {
668 						case 24:
669 								blue = *buf_p++;
670 								green = *buf_p++;
671 								red = *buf_p++;
672 								alphabyte = 255;
673 								break;
674 						case 32:
675 								blue = *buf_p++;
676 								green = *buf_p++;
677 								red = *buf_p++;
678 								alphabyte = *buf_p++;
679 								break;
680 						default:
681 							common->Error( "LoadTGA( %s ): illegal pixel_size '%d'\n", name, targa_header.pixel_size );
682 							break;
683 					}
684 
685 					for( j = 0; j < packetSize; j++ ) {
686 						*pixbuf++=red;
687 						*pixbuf++=green;
688 						*pixbuf++=blue;
689 						*pixbuf++=alphabyte;
690 						column++;
691 						if ( column == columns ) { // run spans across rows
692 							column = 0;
693 							if ( row > 0) {
694 								row--;
695 							}
696 							else {
697 								goto breakOut;
698 							}
699 							pixbuf = targa_rgba + row*columns*4;
700 						}
701 					}
702 				}
703 				else {                            // non run-length packet
704 					for( j = 0; j < packetSize; j++ ) {
705 						switch( targa_header.pixel_size ) {
706 							case 24:
707 									blue = *buf_p++;
708 									green = *buf_p++;
709 									red = *buf_p++;
710 									*pixbuf++ = red;
711 									*pixbuf++ = green;
712 									*pixbuf++ = blue;
713 									*pixbuf++ = 255;
714 									break;
715 							case 32:
716 									blue = *buf_p++;
717 									green = *buf_p++;
718 									red = *buf_p++;
719 									alphabyte = *buf_p++;
720 									*pixbuf++ = red;
721 									*pixbuf++ = green;
722 									*pixbuf++ = blue;
723 									*pixbuf++ = alphabyte;
724 									break;
725 							default:
726 								common->Error( "LoadTGA( %s ): illegal pixel_size '%d'\n", name, targa_header.pixel_size );
727 								break;
728 						}
729 						column++;
730 						if ( column == columns ) { // pixel packet run spans across rows
731 							column = 0;
732 							if ( row > 0 ) {
733 								row--;
734 							}
735 							else {
736 								goto breakOut;
737 							}
738 							pixbuf = targa_rgba + row*columns*4;
739 						}
740 					}
741 				}
742 			}
743 			breakOut: ;
744 		}
745 	}
746 
747 	if ( (targa_header.attributes & (1<<5)) ) {			// image flp bit
748 		R_VerticalFlip( *pic, *width, *height );
749 	}
750 
751 	fileSystem->FreeFile( buffer );
752 }
753 
754 /*
755 =============
756 LoadJPG
757 =============
758 */
LoadJPG(const char * filename,unsigned char ** pic,int * width,int * height,ID_TIME_T * timestamp)759 static void LoadJPG( const char *filename, unsigned char **pic, int *width, int *height, ID_TIME_T *timestamp ) {
760   /* This struct contains the JPEG decompression parameters and pointers to
761    * working space (which is allocated as needed by the JPEG library).
762    */
763   struct jpeg_decompress_struct cinfo;
764   /* We use our private extension JPEG error handler.
765    * Note that this struct must live as long as the main JPEG parameter
766    * struct, to avoid dangling-pointer problems.
767    */
768   /* This struct represents a JPEG error handler.  It is declared separately
769    * because applications often want to supply a specialized error handler
770    * (see the second half of this file for an example).  But here we just
771    * take the easy way out and use the standard error handler, which will
772    * print a message on stderr and call exit() if compression fails.
773    * Note that this struct must live as long as the main JPEG parameter
774    * struct, to avoid dangling-pointer problems.
775    */
776   struct jpeg_error_mgr jerr;
777   /* More stuff */
778   JSAMPARRAY buffer;		/* Output row buffer */
779   int row_stride;		/* physical row width in output buffer */
780   unsigned char *out;
781   byte	*fbuffer;
782   byte  *bbuf;
783 
784   /* In this example we want to open the input file before doing anything else,
785    * so that the setjmp() error recovery below can assume the file is open.
786    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
787    * requires it in order to read binary files.
788    */
789 
790 	// JDC: because fill_input_buffer() blindly copies INPUT_BUF_SIZE bytes,
791 	// we need to make sure the file buffer is padded or it may crash
792   if ( pic ) {
793 	*pic = NULL;		// until proven otherwise
794   }
795 
796 	int len;
797 	idFile *f;
798 
799 	f = fileSystem->OpenFileRead( filename );
800 	if ( !f ) {
801 		return;
802 	}
803 	len = f->Length();
804 	if ( timestamp ) {
805 		*timestamp = f->Timestamp();
806 	}
807 	if ( !pic ) {
808 		fileSystem->CloseFile( f );
809 		return;	// just getting timestamp
810 	}
811 	fbuffer = (byte *)Mem_ClearedAlloc( len + 4096 );
812 	f->Read( fbuffer, len );
813 	fileSystem->CloseFile( f );
814 
815   /* Step 1: allocate and initialize JPEG decompression object */
816 
817   /* We have to set up the error handler first, in case the initialization
818    * step fails.  (Unlikely, but it could happen if you are out of memory.)
819    * This routine fills in the contents of struct jerr, and returns jerr's
820    * address which we place into the link field in cinfo.
821    */
822   cinfo.err = jpeg_std_error(&jerr);
823 
824   /* Now we can initialize the JPEG decompression object. */
825   jpeg_create_decompress(&cinfo);
826 
827   /* Step 2: specify data source (eg, a file) */
828 
829   jpeg_mem_src(&cinfo, fbuffer, len);
830 
831   /* Step 3: read file parameters with jpeg_read_header() */
832 
833   (void) jpeg_read_header(&cinfo, (boolean)true);
834   /* We can ignore the return value from jpeg_read_header since
835    *   (a) suspension is not possible with the stdio data source, and
836    *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
837    * See libjpeg.doc for more info.
838    */
839 
840   /* Step 4: set parameters for decompression */
841 
842   /* In this example, we don't need to change any of the defaults set by
843    * jpeg_read_header(), so we do nothing here.
844    */
845 
846   /* Step 5: Start decompressor */
847 
848   (void) jpeg_start_decompress(&cinfo);
849   /* We can ignore the return value since suspension is not possible
850    * with the stdio data source.
851    */
852 
853   /* We may need to do some setup of our own at this point before reading
854    * the data.  After jpeg_start_decompress() we have the correct scaled
855    * output image dimensions available, as well as the output colormap
856    * if we asked for color quantization.
857    * In this example, we need to make an output work buffer of the right size.
858    */
859   /* JSAMPLEs per row in output buffer */
860   row_stride = cinfo.output_width * cinfo.output_components;
861 
862   if (cinfo.output_components!=4) {
863 		common->DWarning( "JPG %s is unsupported color depth (%d)",
864 			filename, cinfo.output_components);
865   }
866   out = (byte *)R_StaticAlloc(cinfo.output_width*cinfo.output_height*4);
867 
868   *pic = out;
869   *width = cinfo.output_width;
870   *height = cinfo.output_height;
871 
872   /* Step 6: while (scan lines remain to be read) */
873   /*           jpeg_read_scanlines(...); */
874 
875   /* Here we use the library's state variable cinfo.output_scanline as the
876    * loop counter, so that we don't have to keep track ourselves.
877    */
878   while (cinfo.output_scanline < cinfo.output_height) {
879 	/* jpeg_read_scanlines expects an array of pointers to scanlines.
880 	 * Here the array is only one element long, but you could ask for
881 	 * more than one scanline at a time if that's more convenient.
882 	 */
883 	bbuf = ((out+(row_stride*cinfo.output_scanline)));
884 	buffer = &bbuf;
885 	(void) jpeg_read_scanlines(&cinfo, buffer, 1);
886   }
887 
888   // clear all the alphas to 255
889   {
890 	  int	i, j;
891 		byte	*buf;
892 
893 		buf = *pic;
894 
895 	  j = cinfo.output_width * cinfo.output_height * 4;
896 	  for ( i = 3 ; i < j ; i+=4 ) {
897 		  buf[i] = 255;
898 	  }
899   }
900 
901   /* Step 7: Finish decompression */
902 
903   (void) jpeg_finish_decompress(&cinfo);
904   /* We can ignore the return value since suspension is not possible
905    * with the stdio data source.
906    */
907 
908   /* Step 8: Release JPEG decompression object */
909 
910   /* This is an important step since it will release a good deal of memory. */
911   jpeg_destroy_decompress(&cinfo);
912 
913   /* After finish_decompress, we can close the input file.
914    * Here we postpone it until after no more JPEG errors are possible,
915    * so as to simplify the setjmp error logic above.  (Actually, I don't
916    * think that jpeg_destroy can do an error exit, but why assume anything...)
917    */
918   Mem_Free( fbuffer );
919 
920   /* At this point you may want to check to see whether any corrupt-data
921    * warnings occurred (test whether jerr.pub.num_warnings is nonzero).
922    */
923 
924   /* And we're done! */
925 }
926 
927 //===================================================================
928 
929 /*
930 =================
931 R_LoadImage
932 
933 Loads any of the supported image types into a cannonical
934 32 bit format.
935 
936 Automatically attempts to load .jpg files if .tga files fail to load.
937 
938 *pic will be NULL if the load failed.
939 
940 Anything that is going to make this into a texture would use
941 makePowerOf2 = true, but something loading an image as a lookup
942 table of some sort would leave it in identity form.
943 
944 It is important to do this at image load time instead of texture load
945 time for bump maps.
946 
947 Timestamp may be NULL if the value is going to be ignored
948 
949 If pic is NULL, the image won't actually be loaded, it will just find the
950 timestamp.
951 =================
952 */
R_LoadImage(const char * cname,byte ** pic,int * width,int * height,ID_TIME_T * timestamp,bool makePowerOf2)953 void R_LoadImage( const char *cname, byte **pic, int *width, int *height, ID_TIME_T *timestamp, bool makePowerOf2 ) {
954 	idStr name = cname;
955 
956 	if ( pic ) {
957 		*pic = NULL;
958 	}
959 	if ( timestamp ) {
960 		*timestamp = FILE_NOT_FOUND_TIMESTAMP;
961 	}
962 	if ( width ) {
963 		*width = 0;
964 	}
965 	if ( height ) {
966 		*height = 0;
967 	}
968 
969 	name.DefaultFileExtension( ".tga" );
970 
971 	if (name.Length()<5) {
972 		return;
973 	}
974 
975 	name.ToLower();
976 	idStr ext;
977 	name.ExtractFileExtension( ext );
978 
979 	if ( ext == "tga" ) {
980 		LoadTGA( name.c_str(), pic, width, height, timestamp );            // try tga first
981 		if ( ( pic && *pic == 0 ) || ( timestamp && *timestamp == FILE_NOT_FOUND_TIMESTAMP ) ) {
982 			name.StripFileExtension();
983 			name.DefaultFileExtension( ".jpg" );
984 			LoadJPG( name.c_str(), pic, width, height, timestamp );
985 		}
986 	} else if ( ext == "pcx" ) {
987 		LoadPCX32( name.c_str(), pic, width, height, timestamp );
988 	} else if ( ext == "bmp" ) {
989 		LoadBMP( name.c_str(), pic, width, height, timestamp );
990 	} else if ( ext == "jpg" ) {
991 		LoadJPG( name.c_str(), pic, width, height, timestamp );
992 	}
993 
994 	if ( ( width && *width < 1 ) || ( height && *height < 1 ) ) {
995 		if ( pic && *pic ) {
996 			R_StaticFree( *pic );
997 			*pic = 0;
998 		}
999 	}
1000 
1001 	//
1002 	// convert to exact power of 2 sizes
1003 	//
1004 	if ( pic && *pic && makePowerOf2 ) {
1005 		int		w, h;
1006 		int		scaled_width, scaled_height;
1007 		byte	*resampledBuffer;
1008 
1009 		w = *width;
1010 		h = *height;
1011 
1012 		for (scaled_width = 1 ; scaled_width < w ; scaled_width<<=1)
1013 			;
1014 		for (scaled_height = 1 ; scaled_height < h ; scaled_height<<=1)
1015 			;
1016 
1017 		if ( scaled_width != w || scaled_height != h ) {
1018 			if ( globalImages->image_roundDown.GetBool() && scaled_width > w ) {
1019 				scaled_width >>= 1;
1020 			}
1021 			if ( globalImages->image_roundDown.GetBool() && scaled_height > h ) {
1022 				scaled_height >>= 1;
1023 			}
1024 
1025 			resampledBuffer = R_ResampleTexture( *pic, w, h, scaled_width, scaled_height );
1026 			R_StaticFree( *pic );
1027 			*pic = resampledBuffer;
1028 			*width = scaled_width;
1029 			*height = scaled_height;
1030 		}
1031 	}
1032 }
1033 
1034 
1035 /*
1036 =======================
1037 R_LoadCubeImages
1038 
1039 Loads six files with proper extensions
1040 =======================
1041 */
R_LoadCubeImages(const char * imgName,cubeFiles_t extensions,byte * pics[6],int * outSize,ID_TIME_T * timestamp)1042 bool R_LoadCubeImages( const char *imgName, cubeFiles_t extensions, byte *pics[6], int *outSize, ID_TIME_T *timestamp ) {
1043 	int		i, j;
1044 	const char	*cameraSides[6] =  { "_forward.tga", "_back.tga", "_left.tga", "_right.tga",
1045 		"_up.tga", "_down.tga" };
1046 	const char	*axisSides[6] =  { "_px.tga", "_nx.tga", "_py.tga", "_ny.tga",
1047 		"_pz.tga", "_nz.tga" };
1048 	const char	**sides;
1049 	char	fullName[MAX_IMAGE_NAME];
1050 	int		width, height, size = 0;
1051 
1052 	if ( extensions == CF_CAMERA ) {
1053 		sides = cameraSides;
1054 	} else {
1055 		sides = axisSides;
1056 	}
1057 
1058 	// FIXME: precompressed cube map files
1059 	if ( pics ) {
1060 		memset( pics, 0, 6*sizeof(pics[0]) );
1061 	}
1062 	if ( timestamp ) {
1063 		*timestamp = 0;
1064 	}
1065 
1066 	for ( i = 0 ; i < 6 ; i++ ) {
1067 		idStr::snPrintf( fullName, sizeof( fullName ), "%s%s", imgName, sides[i] );
1068 
1069 		ID_TIME_T thisTime;
1070 		if ( !pics ) {
1071 			// just checking timestamps
1072 			R_LoadImageProgram( fullName, NULL, &width, &height, &thisTime );
1073 		} else {
1074 			R_LoadImageProgram( fullName, &pics[i], &width, &height, &thisTime );
1075 		}
1076 		if ( thisTime == FILE_NOT_FOUND_TIMESTAMP ) {
1077 			break;
1078 		}
1079 		if ( i == 0 ) {
1080 			size = width;
1081 		}
1082 		if ( width != size || height != size ) {
1083 			common->Warning( "Mismatched sizes on cube map '%s'", imgName );
1084 			break;
1085 		}
1086 		if ( timestamp ) {
1087 			if ( thisTime > *timestamp ) {
1088 				*timestamp = thisTime;
1089 			}
1090 		}
1091 		if ( pics && extensions == CF_CAMERA ) {
1092 			// convert from "camera" images to native cube map images
1093 			switch( i ) {
1094 			case 0:	// forward
1095 				R_RotatePic( pics[i], width);
1096 				break;
1097 			case 1:	// back
1098 				R_RotatePic( pics[i], width);
1099 				R_HorizontalFlip( pics[i], width, height );
1100 				R_VerticalFlip( pics[i], width, height );
1101 				break;
1102 			case 2:	// left
1103 				R_VerticalFlip( pics[i], width, height );
1104 				break;
1105 			case 3:	// right
1106 				R_HorizontalFlip( pics[i], width, height );
1107 				break;
1108 			case 4:	// up
1109 				R_RotatePic( pics[i], width);
1110 				break;
1111 			case 5: // down
1112 				R_RotatePic( pics[i], width);
1113 				break;
1114 			}
1115 		}
1116 	}
1117 
1118 	if ( i != 6 ) {
1119 		// we had an error, so free everything
1120 		if ( pics ) {
1121 			for ( j = 0 ; j < i ; j++ ) {
1122 				R_StaticFree( pics[j] );
1123 			}
1124 		}
1125 
1126 		if ( timestamp ) {
1127 			*timestamp = 0;
1128 		}
1129 		return false;
1130 	}
1131 
1132 	if ( outSize ) {
1133 		*outSize = size;
1134 	}
1135 	return true;
1136 }
1137