7 void Image_GammaRemapRGB(byte *in, byte *out, int pixels, byte *gammar, byte *gammag, byte *gammab)
11 out[0] = gammar[in[0]];
12 out[1] = gammag[in[1]];
13 out[2] = gammab[in[2]];
19 // note: pal must be 32bit color
20 void Image_Copy8bitRGBA(byte *in, byte *out, int pixels, int *pal)
22 int *iout = (void *)out;
57 void Image_CopyRGBAGamma(byte *in, byte *out, int pixels)
61 out[0] = texgamma[in[0]];
62 out[1] = texgamma[in[1]];
63 out[2] = texgamma[in[2]];
72 =================================================================
76 =================================================================
85 unsigned short xmin,ymin,xmax,ymax;
86 unsigned short hres,vres;
87 unsigned char palette[48];
90 unsigned short bytes_per_line;
91 unsigned short palette_type;
100 byte* LoadPCX (byte *f, int matchwidth, int matchheight)
103 byte *palette, *a, *b, *image_rgba, *fin, *pbuf, *enddata;
104 int x, y, x2, dataByte;
106 if (loadsize < sizeof(pcx) + 768)
108 Con_Printf ("Bad pcx file\n");
115 memcpy(&pcx, fin, sizeof(pcx));
118 // LordHavoc: big-endian support ported from QF newtree
119 pcx.xmax = LittleShort (pcx.xmax);
120 pcx.xmin = LittleShort (pcx.xmin);
121 pcx.ymax = LittleShort (pcx.ymax);
122 pcx.ymin = LittleShort (pcx.ymin);
123 pcx.hres = LittleShort (pcx.hres);
124 pcx.vres = LittleShort (pcx.vres);
125 pcx.bytes_per_line = LittleShort (pcx.bytes_per_line);
126 pcx.palette_type = LittleShort (pcx.palette_type);
128 if (pcx.manufacturer != 0x0a || pcx.version != 5 || pcx.encoding != 1 || pcx.bits_per_pixel != 8 || pcx.xmax > 320 || pcx.ymax > 256)
130 Con_Printf ("Bad pcx file\n");
135 if (matchwidth && (pcx.xmax+1) != matchwidth)
140 if (matchheight && (pcx.ymax+1) != matchheight)
146 image_width = pcx.xmax+1;
147 image_height = pcx.ymax+1;
149 palette = f + loadsize - 768;
151 image_rgba = qmalloc(image_width*image_height*4);
154 Con_Printf("LoadPCX: not enough memory for %i by %i image\n", image_width, image_height);
158 pbuf = image_rgba + image_width*image_height*3;
161 for (y = 0;y < image_height && fin < enddata;y++)
163 a = pbuf + y * image_width;
164 for (x = 0;x < image_width && fin < enddata;)
171 x2 = x + (dataByte & 0x3F);
173 if (x2 > image_width)
174 x2 = image_width; // technically an error
181 while(x < image_width)
188 for(x = 0;x < image_width*image_height;x++)
202 =========================================================
206 =========================================================
209 typedef struct _TargaHeader
211 unsigned char id_length, colormap_type, image_type;
212 unsigned short colormap_index, colormap_length;
213 unsigned char colormap_size;
214 unsigned short x_origin, y_origin, width, height;
215 unsigned char pixel_size, attributes;
219 TargaHeader targa_header;
227 byte* LoadTGA (byte *f, int matchwidth, int matchheight)
229 int columns, rows, row, column;
230 byte *pixbuf, *image_rgba, *fin, *enddata;
237 targa_header.id_length = f[0];
238 targa_header.colormap_type = f[1];
239 targa_header.image_type = f[2];
241 targa_header.colormap_index = f[3] + f[4] * 256;
242 targa_header.colormap_length = f[5] + f[6] * 256;
243 targa_header.colormap_size = f[7];
244 targa_header.x_origin = f[8] + f[9] * 256;
245 targa_header.y_origin = f[10] + f[11] * 256;
246 targa_header.width = f[12] + f[13] * 256;
247 targa_header.height = f[14] + f[15] * 256;
248 if (matchwidth && targa_header.width != matchwidth)
253 if (matchheight && targa_header.height != matchheight)
258 targa_header.pixel_size = f[16];
259 targa_header.attributes = f[17];
261 if (targa_header.image_type != 2 && targa_header.image_type != 10)
263 Con_Printf ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
268 if (targa_header.colormap_type != 0 || (targa_header.pixel_size != 32 && targa_header.pixel_size != 24))
270 Con_Printf ("LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
275 enddata = f + loadsize;
277 columns = targa_header.width;
278 rows = targa_header.height;
280 image_rgba = qmalloc(columns * rows * 4);
283 Con_Printf ("LoadTGA: not enough memory for %i by %i image\n", columns, rows);
289 if (targa_header.id_length != 0)
290 fin += targa_header.id_length; // skip TARGA image comment
292 if (targa_header.image_type == 2)
294 // Uncompressed, RGB images
295 for(row = rows - 1;row >= 0;row--)
297 pixbuf = image_rgba + row*columns*4;
298 for(column = 0;column < columns;column++)
300 switch (targa_header.pixel_size)
303 if (fin + 3 > enddata)
312 if (fin + 4 > enddata)
324 else if (targa_header.image_type==10)
326 // Runlength encoded RGB images
327 unsigned char red = 0, green = 0, blue = 0, alphabyte = 0, packetHeader, packetSize, j;
328 for(row = rows - 1;row >= 0;row--)
330 pixbuf = image_rgba + row * columns * 4;
331 for(column = 0;column < columns;)
335 packetHeader = *fin++;
336 packetSize = 1 + (packetHeader & 0x7f);
337 if (packetHeader & 0x80)
340 switch (targa_header.pixel_size)
343 if (fin + 3 > enddata)
351 if (fin + 4 > enddata)
360 for(j = 0;j < packetSize;j++)
365 *pixbuf++ = alphabyte;
367 if (column == columns)
369 // run spans across rows
375 pixbuf = image_rgba + row * columns * 4;
381 // non run-length packet
382 for(j = 0;j < packetSize;j++)
384 switch (targa_header.pixel_size)
387 if (fin + 3 > enddata)
396 if (fin + 4 > enddata)
406 if (column == columns)
408 // pixel packet run spans across rows
414 pixbuf = image_rgba + row * columns * 4;
424 image_width = columns;
435 byte* LoadLMP (byte *f, int matchwidth, int matchheight)
442 Con_Printf("LoadLMP: invalid LMP file\n");
447 // parse the very complicated header *chuckle*
448 width = f[0] + f[1] * 256 + f[2] * 65536 + f[3] * 16777216;
449 height = f[4] + f[5] * 256 + f[6] * 65536 + f[7] * 16777216;
450 if ((unsigned) width > 4096 || (unsigned) height > 4096)
452 Con_Printf("LoadLMP: invalid size\n");
456 if (matchwidth && width != matchwidth)
461 if (matchheight && height != matchheight)
467 if (loadsize < 8 + width * height)
469 Con_Printf("LoadLMP: invalid LMP file\n");
475 image_height = height;
477 image_rgba = qmalloc(image_width * image_height * 4);
480 Con_Printf("LoadLMP: not enough memory for %i by %i image\n", image_width, image_height);
484 Image_Copy8bitRGBA(f + 8, image_rgba, image_width * image_height, d_8to24table);
489 void Image_StripImageExtension (char *in, char *out)
492 end = in + strlen(in);
496 if (strcmp(temp, ".tga") == 0 || strcmp(temp, ".pcx") == 0 || strcmp(temp, ".lmp") == 0)
506 byte* loadimagepixels (char* filename, qboolean complain, int matchwidth, int matchheight)
509 char basename[256], name[256];
511 Image_StripImageExtension(filename, basename); // strip .tga, .pcx and .lmp extensions to allow replacement by other types
512 // replace *'s with #, so commandline utils don't get confused when dealing with the external files
513 for (c = basename;*c;c++)
516 sprintf (name, "textures/%s.tga", basename);
517 f = COM_LoadMallocFile(name, true);
519 return LoadTGA (f, matchwidth, matchheight);
520 sprintf (name, "textures/%s.pcx", basename);
521 f = COM_LoadMallocFile(name, true);
523 return LoadPCX (f, matchwidth, matchheight);
524 sprintf (name, "%s.tga", basename);
525 f = COM_LoadMallocFile(name, true);
527 return LoadTGA (f, matchwidth, matchheight);
528 sprintf (name, "%s.pcx", basename);
529 f = COM_LoadMallocFile(name, true);
531 return LoadPCX (f, matchwidth, matchheight);
532 sprintf (name, "%s.lmp", basename);
533 f = COM_LoadMallocFile(name, true);
535 return LoadLMP (f, matchwidth, matchheight);
537 Con_Printf ("Couldn't load %s.tga, .pcx, .lmp\n", filename);
541 int image_makemask (byte *in, byte *out, int size)
545 for (i = 0;i < size;i++)
547 out[0] = out[1] = out[2] = 255;
557 byte* loadimagepixelsmask (char* filename, qboolean complain, int matchwidth, int matchheight)
560 in = data = loadimagepixels(filename, complain, matchwidth, matchheight);
563 if (image_makemask(data, data, image_width * image_height))
564 return data; // some transparency
568 return NULL; // all opaque
572 rtexture_t *loadtextureimage (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache)
576 if (!(data = loadimagepixels (filename, complain, matchwidth, matchheight)))
578 rt = R_LoadTexture (filename, image_width, image_height, data, TEXF_ALPHA | TEXF_RGBA | (mipmap ? TEXF_MIPMAP : 0) | (mipmap ? TEXF_PRECACHE : 0));
583 rtexture_t *loadtextureimagemask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache)
587 if (!(data = loadimagepixelsmask (filename, complain, matchwidth, matchheight)))
589 rt = R_LoadTexture (filename, image_width, image_height, data, TEXF_ALPHA | TEXF_RGBA | (mipmap ? TEXF_MIPMAP : 0) | (mipmap ? TEXF_PRECACHE : 0));
594 rtexture_t *image_masktex;
595 rtexture_t *loadtextureimagewithmask (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap, qboolean precache)
601 image_masktex = NULL;
602 if (!(data = loadimagepixels (filename, complain, matchwidth, matchheight)))
604 rt = R_LoadTexture (filename, image_width, image_height, data, TEXF_ALPHA | TEXF_RGBA | (mipmap ? TEXF_MIPMAP : 0) | (mipmap ? TEXF_PRECACHE : 0));
605 count = image_makemask(data, data, image_width * image_height);
608 filename2 = qmalloc(strlen(filename) + 6);
609 sprintf(filename2, "%s_mask", filename);
610 image_masktex = R_LoadTexture (filename2, image_width, image_height, data, TEXF_ALPHA | TEXF_RGBA | (mipmap ? TEXF_MIPMAP : 0) | (mipmap ? TEXF_PRECACHE : 0));
617 void Image_WriteTGARGB_preflipped (char *filename, int width, int height, byte *data)
619 byte *buffer, *in, *out, *end;
621 buffer = qmalloc(width*height*3 + 18);
623 memset (buffer, 0, 18);
624 buffer[2] = 2; // uncompressed type
625 buffer[12] = (width >> 0) & 0xFF;
626 buffer[13] = (width >> 8) & 0xFF;
627 buffer[14] = (height >> 0) & 0xFF;
628 buffer[15] = (height >> 8) & 0xFF;
629 buffer[16] = 24; // pixel size
634 end = in + width*height*3;
635 for (;in < end;in += 3)
641 COM_WriteFile (filename, buffer, width*height*3 + 18 );
646 void Image_WriteTGARGB (char *filename, int width, int height, byte *data)
649 byte *buffer, *in, *out, *end;
651 buffer = qmalloc(width*height*3 + 18);
653 memset (buffer, 0, 18);
654 buffer[2] = 2; // uncompressed type
655 buffer[12] = (width >> 0) & 0xFF;
656 buffer[13] = (width >> 8) & 0xFF;
657 buffer[14] = (height >> 0) & 0xFF;
658 buffer[15] = (height >> 8) & 0xFF;
659 buffer[16] = 24; // pixel size
661 // swap rgb to bgr and flip upside down
663 for (y = height - 1;y >= 0;y--)
665 in = data + y * width * 3;
666 end = in + width * 3;
667 for (;in < end;in += 3)
674 COM_WriteFile (filename, buffer, width*height*3 + 18 );
679 void Image_WriteTGARGBA (char *filename, int width, int height, byte *data)
682 byte *buffer, *in, *out, *end;
684 buffer = qmalloc(width*height*4 + 18);
686 memset (buffer, 0, 18);
687 buffer[2] = 2; // uncompressed type
688 buffer[12] = (width >> 0) & 0xFF;
689 buffer[13] = (width >> 8) & 0xFF;
690 buffer[14] = (height >> 0) & 0xFF;
691 buffer[15] = (height >> 8) & 0xFF;
692 buffer[16] = 32; // pixel size
694 // swap rgba to bgra and flip upside down
696 for (y = height - 1;y >= 0;y--)
698 in = data + y * width * 4;
699 end = in + width * 4;
700 for (;in < end;in += 4)
708 COM_WriteFile (filename, buffer, width*height*4 + 18 );
713 qboolean Image_CheckAlpha(byte *data, int size, qboolean rgba)
719 for (end = data + size * 4, data += 3;data < end;data += 4)
725 // color 255 is transparent
726 for (end = data + size;data < end;data++)