2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
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.
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.
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
31 #define LittleLong(a) GINT32_FROM_LE(a)
32 #define LittleShort(a) GINT16_FROM_LE(a)
36 #define Sys_Printf g_FuncTable.m_pfnSysPrintf
37 #define Sys_FPrintf g_FuncTable.m_pfnSysFPrintf
40 ============================================================================
44 ============================================================================
52 unsigned short xmin, ymin, xmax, ymax;
53 unsigned short hres, vres;
54 unsigned char palette[48];
57 unsigned short bytes_per_line;
58 unsigned short palette_type;
60 unsigned char data; // unbounded
64 ============================================================================
68 ============================================================================
70 typedef struct _TargaHeader
72 unsigned char id_length, colormap_type, image_type;
73 unsigned short colormap_index, colormap_length;
74 unsigned char colormap_size;
75 unsigned short x_origin, y_origin, width, height;
76 unsigned char pixel_size, attributes;
80 =========================================================
84 =========================================================
89 unsigned long fileSize;
90 unsigned long reserved0;
91 unsigned long bitmapDataOffset;
92 unsigned long bitmapHeaderSize;
95 unsigned short planes;
96 unsigned short bitsPerPixel;
97 unsigned long compression;
98 unsigned long bitmapDataSize;
101 unsigned long colors;
102 unsigned long importantColors;
103 unsigned char palette[256][4];
106 static void LoadBMP (const char *name, byte ** pic, int *width, int *height)
108 int columns, rows, numPixels;
114 BMPHeader_t bmpHeader;
122 length = vfsLoadFile( (char *)name, (void **)&buffer, 0 );
123 if (length == (unsigned int) -1)
128 bmpHeader.id[0] = *buf_p++;
129 bmpHeader.id[1] = *buf_p++;
130 bmpHeader.fileSize = LittleLong (*(long *) buf_p);
132 bmpHeader.reserved0 = LittleLong (*(long *) buf_p);
134 bmpHeader.bitmapDataOffset = LittleLong (*(long *) buf_p);
136 bmpHeader.bitmapHeaderSize = LittleLong (*(long *) buf_p);
138 bmpHeader.width = LittleLong (*(long *) buf_p);
140 bmpHeader.height = LittleLong (*(long *) buf_p);
142 bmpHeader.planes = LittleShort (*(short *) buf_p);
144 bmpHeader.bitsPerPixel = LittleShort (*(short *) buf_p);
146 bmpHeader.compression = LittleLong (*(long *) buf_p);
148 bmpHeader.bitmapDataSize = LittleLong (*(long *) buf_p);
150 bmpHeader.hRes = LittleLong (*(long *) buf_p);
152 bmpHeader.vRes = LittleLong (*(long *) buf_p);
154 bmpHeader.colors = LittleLong (*(long *) buf_p);
156 bmpHeader.importantColors = LittleLong (*(long *) buf_p);
159 memcpy (bmpHeader.palette, buf_p, sizeof (bmpHeader.palette));
161 if (bmpHeader.bitsPerPixel == 8)
164 if (bmpHeader.id[0] != 'B' && bmpHeader.id[1] != 'M')
166 Sys_Printf ("LoadBMP: only Windows-style BMP files supported (%s)\n", name);
169 if (bmpHeader.fileSize != length)
171 Sys_Printf ("LoadBMP: header size does not match file size (%d vs. %d) (%s)\n",
172 bmpHeader.fileSize, length, name);
175 if (bmpHeader.compression != 0)
177 Sys_Printf ("LoadBMP: only uncompressed BMP files supported (%s)\n", name);
180 if (bmpHeader.bitsPerPixel < 8)
182 Sys_Printf ("LoadBMP: monochrome and 4-bit BMP files not supported (%s)\n", name);
186 columns = bmpHeader.width;
187 rows = bmpHeader.height;
190 numPixels = columns * rows;
197 bmpRGBA = reinterpret_cast < unsigned char *>(g_malloc (numPixels * 4));
201 for (row = rows - 1; row >= 0; row--)
203 pixbuf = bmpRGBA + row * columns * 4;
205 for (column = 0; column < columns; column++)
207 unsigned char red, green, blue, alpha;
209 unsigned short shortPixel;
211 switch (bmpHeader.bitsPerPixel)
215 *pixbuf++ = bmpHeader.palette[palIndex][2];
216 *pixbuf++ = bmpHeader.palette[palIndex][1];
217 *pixbuf++ = bmpHeader.palette[palIndex][0];
221 shortPixel = *(unsigned short *) pixbuf;
223 *pixbuf++ = (shortPixel & (31 << 10)) >> 7;
224 *pixbuf++ = (shortPixel & (31 << 5)) >> 2;
225 *pixbuf++ = (shortPixel & (31)) << 3;
248 Sys_Printf ("LoadBMP: illegal pixel_size '%d' in file '%s'\n", bmpHeader.bitsPerPixel,
258 vfsFreeFile (buffer);
264 =================================================================
268 =================================================================
279 #define DECODEPCX( b, d, r ) d=*b++;if((d&0xC0)==0xC0){r=d&0x3F;d=*b++;}else{r=1;}
281 static void LoadPCX( const char *filename, byte **pic, byte **palette, int *width, int *height )
287 int dataByte, runLength;
292 len = vfsLoadFile (filename, (void **)&raw, 0);
294 Error( "LoadPCX: Couldn't read %s", filename );
297 /* parse the PCX file */
301 pcx->xmin = LittleShort(pcx->xmin);
302 pcx->ymin = LittleShort(pcx->ymin);
303 pcx->xmax = LittleShort(pcx->xmax);
304 pcx->ymax = LittleShort(pcx->ymax);
305 pcx->hres = LittleShort(pcx->hres);
306 pcx->vres = LittleShort(pcx->vres);
307 pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
308 pcx->palette_type = LittleShort(pcx->palette_type);
310 if (pcx->manufacturer != 0x0a
312 || pcx->encoding != 1
313 || pcx->bits_per_pixel != 8
316 Error ("Bad pcx file %s", filename);
320 *palette = (byte *)malloc(768);
321 memcpy (*palette, (byte *)pcx + len - 768, 768);
325 *width = pcx->xmax+1;
327 *height = pcx->ymax+1;
332 out = (byte *)malloc ( (pcx->ymax+1) * (pcx->xmax+1) );
334 Error( "LoadPCX: couldn't allocate");
339 /* RR2DO2: pcx fix */
340 lsize = pcx->color_planes * pcx->bytes_per_line;
342 /* go scanline by scanline */
343 for( y = 0; y <= pcx->ymax; y++, pix += pcx->xmax + 1 )
346 for( x=0; x <= pcx->xmax; )
349 DECODEPCX( raw, dataByte, runLength );
350 while( runLength-- > 0 )
351 pix[ x++ ] = dataByte;
354 /* RR2DO2: discard any other data */
357 DECODEPCX( raw, dataByte, runLength );
360 while( runLength-- > 0 )
365 if( raw - (byte *) pcx > len)
366 Error( "PCX file %s was malformed", filename );
375 static void LoadPCX32 (const char *filename, byte ** pic, int *width, int *height)
382 LoadPCX (filename, &pic8, &palette, width, height);
389 c = (*width) * (*height);
390 pic32 = *pic = reinterpret_cast < unsigned char *>(g_malloc (4 * c));
391 for (i = 0; i < c; i++)
394 pic32[0] = palette[p * 3];
395 pic32[1] = palette[p * 3 + 1];
396 pic32[2] = palette[p * 3 + 2];
406 =========================================================
410 TTimo: added code to get rid of alphachannel from prefs or ignore it if completely empty
411 was required since Radiant is using alpha channel when binding the textures for proper curry operation
412 can be fully turned off from the prefs though
413 =========================================================
421 void LoadTGA (const char *name, byte ** pic, int *width, int *height)
423 int columns, rows, numPixels;
428 TargaHeader targa_header;
436 int nLen = vfsLoadFile( (char *)name, (void **)&buffer, 0 );
442 targa_header.id_length = *buf_p++;
443 targa_header.colormap_type = *buf_p++;
444 targa_header.image_type = *buf_p++;
446 targa_header.colormap_index = LittleShort (*(short *) buf_p);
448 targa_header.colormap_length = LittleShort (*(short *) buf_p);
450 targa_header.colormap_size = *buf_p++;
451 targa_header.x_origin = LittleShort (*(short *) buf_p);
453 targa_header.y_origin = LittleShort (*(short *) buf_p);
455 targa_header.width = LittleShort (*(short *) buf_p);
457 targa_header.height = LittleShort (*(short *) buf_p);
459 targa_header.pixel_size = *buf_p++;
460 targa_header.attributes = *buf_p++;
462 bool bAlphaOK = false;
464 if (targa_header.image_type != 2 && targa_header.image_type != 10 && targa_header.image_type != 3)
466 Sys_Printf ("LoadTGA: TGA type %d not supported\n", targa_header.image_type);
467 Sys_Printf ("LoadTGA: Only type 2 (RGB), 3 (gray), and 10 (RGB) TGA images supported\n");
471 if (targa_header.colormap_type != 0)
473 Sys_Printf ("LoadTGA: colormaps not supported\n");
477 if ((targa_header.pixel_size != 32 && targa_header.pixel_size != 24)
478 && targa_header.image_type != 3)
480 Sys_Printf ("LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
484 columns = targa_header.width;
485 rows = targa_header.height;
486 numPixels = columns * rows;
493 targa_rgba = reinterpret_cast < unsigned char *>(g_malloc (numPixels * 4));
496 if (targa_header.id_length != 0)
497 buf_p += targa_header.id_length; // skip TARGA image comment
499 if (targa_header.image_type == 2 || targa_header.image_type == 3)
501 // Uncompressed RGB or gray scale image
502 for (row = rows - 1; row >= 0; row--)
504 pixbuf = targa_rgba + row * columns * 4;
505 for (column = 0; column < columns; column++)
507 unsigned char red, green, blue, alphabyte;
508 switch (targa_header.pixel_size)
533 alphabyte = *buf_p++;
534 // detect if the whole alpha channel is 0
540 *pixbuf++ = alphabyte;
543 Sys_Printf ("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size,
555 if (targa_header.pixel_size == 32)
556 Sys_FPrintf (SYS_WRN, "WARNING: %s has empty alpha channel\n", name);
557 // disable the alpha value
558 for (row = rows - 1; row >= 0; row--)
560 pixbuf = targa_rgba + row * columns * 4;
561 for (column = 0; column < columns; column++)
570 else if (targa_header.image_type == 10)
571 { // Runlength encoded RGB images
572 unsigned char red, green, blue, alphabyte, packetHeader, packetSize, j;
579 for (row = rows - 1; row >= 0; row--)
581 pixbuf = targa_rgba + row * columns * 4;
582 for (column = 0; column < columns;)
584 packetHeader = *buf_p++;
585 packetSize = 1 + (packetHeader & 0x7f);
586 if (packetHeader & 0x80)
587 { // run-length packet
588 switch (targa_header.pixel_size)
600 alphabyte = *buf_p++;
601 // detect if the whole alpha channel is 0
606 Sys_Printf ("LoadTGA: illegal pixel_size '%d' in file '%s'\n", targa_header.pixel_size,
614 for (j = 0; j < packetSize; j++)
619 *pixbuf++ = alphabyte;
621 if (column == columns)
622 { // run spans across rows
628 pixbuf = targa_rgba + row * columns * 4;
633 { // non run-length packet
634 for (j = 0; j < packetSize; j++)
636 switch (targa_header.pixel_size)
651 alphabyte = *buf_p++;
652 // detect if the whole alpha channel is 0
658 *pixbuf++ = alphabyte;
661 Sys_Printf ("LoadTGA: illegal pixel_size '%d' in file '%s'\n",
662 targa_header.pixel_size, name);
669 if (column == columns)
670 { // pixel packet run spans across rows
676 pixbuf = targa_rgba + row * columns * 4;
686 if (targa_header.pixel_size == 32)
687 Sys_FPrintf (SYS_WRN, "WARNING: %s has empty alpha channel\n", name);
688 // disable the alpha value
689 for (row = rows - 1; row >= 0; row--)
691 pixbuf = targa_rgba + row * columns * 4;
692 for (column = 0; column < columns; column++)
703 // vertically flipped
704 if ( (targa_header.attributes & (1<<5)) ) {
706 for (row = 0; row < .5f * rows; row++)
708 for (column = 0; column < columns; column++)
710 flip = *( (int*)targa_rgba + row * columns + column);
711 *( (int*)targa_rgba + row * columns + column) = *( (int*)targa_rgba + ( ( rows - 1 ) - row ) * columns + column );
712 *( (int*)targa_rgba + ( ( rows - 1 ) - row ) * columns + column ) = flip;
717 vfsFreeFile (buffer);
720 //===================================================================
726 Loads any of the supported image types into a cannonical
730 void LoadImage (const char *name, byte ** pic, int *width, int *height)
743 if (!g_strcasecmp (name + len - 4, ".tga"))
745 LoadTGA (name, pic, width, height);
747 else if (!g_strcasecmp (name + len - 4, ".pcx"))
749 LoadPCX32 (name, pic, width, height);
751 else if (!g_strcasecmp (name + len - 4, ".bmp"))
753 LoadBMP (name, pic, width, height);
756 else if (!g_strcasecmp (name + len - 4, ".jpg"))
758 LoadJPG (name, pic, width, height);