7 // note: pal must be 32bit color
8 void Image_Copy8bitRGBA(byte *in, byte *out, int pixels, int *pal)
10 int *iout = (void *)out;
46 void Image_CopyRGBAGamma(byte *in, byte *out, int pixels)
50 out[0] = qgamma[in[0]];
51 out[1] = qgamma[in[1]];
52 out[2] = qgamma[in[2]];
61 =================================================================
65 =================================================================
74 unsigned short xmin,ymin,xmax,ymax;
75 unsigned short hres,vres;
76 unsigned char palette[48];
79 unsigned short bytes_per_line;
80 unsigned short palette_type;
82 unsigned data; // unbounded
90 byte* LoadPCX (FILE *f, int matchwidth, int matchheight)
94 byte *pix, *image_rgba;
96 int dataByte, runLength;
100 // parse the PCX file
102 fread (&pcxbuf, 1, sizeof(pcxbuf), f);
106 if (pcx->manufacturer != 0x0a
108 || pcx->encoding != 1
109 || pcx->bits_per_pixel != 8
113 Con_Printf ("Bad pcx file\n");
117 if (matchwidth && (pcx->xmax+1) != matchwidth)
119 if (matchheight && (pcx->ymax+1) != matchheight)
123 fseek (f, -768, SEEK_END);
124 fread (palette, 1, 768, f);
126 fseek (f, sizeof(pcxbuf) - 4, SEEK_SET);
128 count = (pcx->xmax+1) * (pcx->ymax+1);
129 image_rgba = malloc( count * 4);
131 for (y=0 ; y<=pcx->ymax ; y++)
133 pix = image_rgba + 4*y*(pcx->xmax+1);
134 for (x=0 ; x<=pcx->xmax ; )
138 if((dataByte & 0xC0) == 0xC0)
140 runLength = dataByte & 0x3F;
146 while(runLength-- > 0)
148 pix[0] = palette[dataByte*3];
149 pix[1] = palette[dataByte*3+1];
150 pix[2] = palette[dataByte*3+2];
158 image_width = pcx->xmax+1;
159 image_height = pcx->ymax+1;
164 =========================================================
168 =========================================================
171 typedef struct _TargaHeader {
172 unsigned char id_length, colormap_type, image_type;
173 unsigned short colormap_index, colormap_length;
174 unsigned char colormap_size;
175 unsigned short x_origin, y_origin, width, height;
176 unsigned char pixel_size, attributes;
180 TargaHeader targa_header;
182 int fgetLittleShort (FILE *f)
189 return (short)(b1 + b2*256);
192 int fgetLittleLong (FILE *f)
201 return b1 + (b2<<8) + (b3<<16) + (b4<<24);
210 byte* LoadTGA (FILE *fin, int matchwidth, int matchheight)
212 int columns, rows, numPixels;
217 targa_header.id_length = fgetc(fin);
218 targa_header.colormap_type = fgetc(fin);
219 targa_header.image_type = fgetc(fin);
221 targa_header.colormap_index = fgetLittleShort(fin);
222 targa_header.colormap_length = fgetLittleShort(fin);
223 targa_header.colormap_size = fgetc(fin);
224 targa_header.x_origin = fgetLittleShort(fin);
225 targa_header.y_origin = fgetLittleShort(fin);
226 targa_header.width = fgetLittleShort(fin);
227 targa_header.height = fgetLittleShort(fin);
228 if (matchwidth && targa_header.width != matchwidth)
230 if (matchheight && targa_header.height != matchheight)
232 targa_header.pixel_size = fgetc(fin);
233 targa_header.attributes = fgetc(fin);
235 if (targa_header.image_type!=2
236 && targa_header.image_type!=10)
237 Host_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
239 if (targa_header.colormap_type !=0
240 || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
241 Host_Error ("LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
243 columns = targa_header.width;
244 rows = targa_header.height;
245 numPixels = columns * rows;
247 image_rgba = malloc (numPixels*4);
249 if (targa_header.id_length != 0)
250 fseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment
252 if (targa_header.image_type==2) { // Uncompressed, RGB images
253 for(row=rows-1; row>=0; row--) {
254 pixbuf = image_rgba + row*columns*4;
255 for(column=0; column<columns; column++) {
256 unsigned char red = 0,green = 0,blue = 0,alphabyte = 0;
257 switch (targa_header.pixel_size) {
272 alphabyte = getc(fin);
276 *pixbuf++ = alphabyte;
282 else if (targa_header.image_type==10) { // Runlength encoded RGB images
283 unsigned char red = 0,green = 0,blue = 0,alphabyte = 0,packetHeader,packetSize,j;
284 for(row=rows-1; row>=0; row--) {
285 pixbuf = image_rgba + row*columns*4;
286 for(column=0; column<columns; ) {
287 packetHeader=getc(fin);
288 packetSize = 1 + (packetHeader & 0x7f);
289 if (packetHeader & 0x80) { // run-length packet
290 switch (targa_header.pixel_size) {
301 alphabyte = getc(fin);
305 for(j=0;j<packetSize;j++) {
311 if (column==columns) { // run spans across rows
317 pixbuf = image_rgba + row*columns*4;
321 else { // non run-length packet
322 for(j=0;j<packetSize;j++) {
323 switch (targa_header.pixel_size) {
337 alphabyte = getc(fin);
341 *pixbuf++ = alphabyte;
345 if (column==columns) { // pixel packet run spans across rows
351 pixbuf = image_rgba + row*columns*4;
361 image_width = columns;
371 byte* LoadLMP (FILE *f, int matchwidth, int matchheight)
376 // parse the very complicated header *chuckle*
377 width = fgetLittleLong(f);
378 height = fgetLittleLong(f);
379 if ((unsigned) width > 4096 || (unsigned) height > 4096)
380 Host_Error("LoadLMP: invalid size\n");
381 if (matchwidth && width != matchwidth)
383 if (matchheight && height != matchheight)
386 image_rgba = malloc(width*height*4);
387 fread(image_rgba + width*height*3, 1, width*height, f);
390 Image_Copy8bitRGBA(image_rgba + width*height*3, image_rgba, width*height, d_8to24table);
392 image_height = height;
396 byte* loadimagepixels (char* filename, qboolean complain, int matchwidth, int matchheight)
399 char basename[128], name[128];
400 byte *image_rgba, *c;
401 COM_StripExtension(filename, basename); // strip the extension to allow TGA skins on Q2 models despite the .pcx in the skin name
402 // replace *'s with +, so commandline utils don't get confused when dealing with the external files
410 sprintf (name, "textures/%s.tga", basename);
411 COM_FOpenFile (name, &f, true);
413 return LoadTGA (f, matchwidth, matchheight);
414 sprintf (name, "textures/%s.pcx", basename);
415 COM_FOpenFile (name, &f, true);
417 return LoadPCX (f, matchwidth, matchheight);
418 sprintf (name, "%s.tga", basename);
419 COM_FOpenFile (name, &f, true);
421 return LoadTGA (f, matchwidth, matchheight);
422 sprintf (name, "%s.pcx", basename);
423 COM_FOpenFile (name, &f, true);
425 return LoadPCX (f, matchwidth, matchheight);
426 sprintf (name, "%s.lmp", basename);
427 COM_FOpenFile (name, &f, true);
429 return LoadLMP (f, matchwidth, matchheight);
430 if ((image_rgba = W_GetTexture(basename, matchwidth, matchheight)))
432 COM_StripExtension(filename, basename); // do it again with a * this time
433 if ((image_rgba = W_GetTexture(basename, matchwidth, matchheight)))
436 Con_Printf ("Couldn't load %s.tga or .pcx\n", filename);
440 int loadtextureimage (char* filename, int matchwidth, int matchheight, qboolean complain, qboolean mipmap)
444 if (!(data = loadimagepixels (filename, complain, matchwidth, matchheight)))
446 texnum = GL_LoadTexture (filename, image_width, image_height, data, mipmap, true, 4);
450 if (texnum >= 0) // specific texnum, not cached
452 glBindTexture(GL_TEXTURE_2D, texnum);
453 GL_Upload32 (data, image_width, image_height, mipmap, true);
457 else // any texnum, cached
459 texnum = GL_LoadTexture (filename, image_width, image_height, data, mipmap, true, 4);