8 =================================================================
12 =================================================================
21 unsigned short xmin,ymin,xmax,ymax;
22 unsigned short hres,vres;
23 unsigned char palette[48];
26 unsigned short bytes_per_line;
27 unsigned short palette_type;
29 unsigned data; // unbounded
37 byte* LoadPCX (FILE *f, int matchwidth, int matchheight)
41 byte *pix, *image_rgba;
43 int dataByte, runLength;
49 fread (&pcxbuf, 1, sizeof(pcxbuf), f);
53 if (pcx->manufacturer != 0x0a
56 || pcx->bits_per_pixel != 8
60 Con_Printf ("Bad pcx file\n");
64 if (matchwidth && (pcx->xmax+1) != matchwidth)
66 if (matchheight && (pcx->ymax+1) != matchheight)
70 fseek (f, -768, SEEK_END);
71 fread (palette, 1, 768, f);
73 fseek (f, sizeof(pcxbuf) - 4, SEEK_SET);
75 count = (pcx->xmax+1) * (pcx->ymax+1);
76 image_rgba = malloc( count * 4);
78 for (y=0 ; y<=pcx->ymax ; y++)
80 pix = image_rgba + 4*y*(pcx->xmax+1);
81 for (x=0 ; x<=pcx->xmax ; )
85 if((dataByte & 0xC0) == 0xC0)
87 runLength = dataByte & 0x3F;
93 while(runLength-- > 0)
95 pix[0] = palette[dataByte*3];
96 pix[1] = palette[dataByte*3+1];
97 pix[2] = palette[dataByte*3+2];
104 image_width = pcx->xmax+1;
105 image_height = pcx->ymax+1;
110 =========================================================
114 =========================================================
117 typedef struct _TargaHeader {
118 unsigned char id_length, colormap_type, image_type;
119 unsigned short colormap_index, colormap_length;
120 unsigned char colormap_size;
121 unsigned short x_origin, y_origin, width, height;
122 unsigned char pixel_size, attributes;
126 TargaHeader targa_header;
128 int fgetLittleShort (FILE *f)
135 return (short)(b1 + b2*256);
138 int fgetLittleLong (FILE *f)
147 return b1 + (b2<<8) + (b3<<16) + (b4<<24);
156 byte* LoadTGA (FILE *fin, int matchwidth, int matchheight)
158 int columns, rows, numPixels;
163 targa_header.id_length = fgetc(fin);
164 targa_header.colormap_type = fgetc(fin);
165 targa_header.image_type = fgetc(fin);
167 targa_header.colormap_index = fgetLittleShort(fin);
168 targa_header.colormap_length = fgetLittleShort(fin);
169 targa_header.colormap_size = fgetc(fin);
170 targa_header.x_origin = fgetLittleShort(fin);
171 targa_header.y_origin = fgetLittleShort(fin);
172 targa_header.width = fgetLittleShort(fin);
173 targa_header.height = fgetLittleShort(fin);
174 if (matchwidth && targa_header.width != matchwidth)
176 if (matchheight && targa_header.height != matchheight)
178 targa_header.pixel_size = fgetc(fin);
179 targa_header.attributes = fgetc(fin);
181 if (targa_header.image_type!=2
182 && targa_header.image_type!=10)
183 Host_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n");
185 if (targa_header.colormap_type !=0
186 || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
187 Host_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
189 columns = targa_header.width;
190 rows = targa_header.height;
191 numPixels = columns * rows;
193 image_rgba = malloc (numPixels*4);
195 if (targa_header.id_length != 0)
196 fseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment
198 if (targa_header.image_type==2) { // Uncompressed, RGB images
199 for(row=rows-1; row>=0; row--) {
200 pixbuf = image_rgba + row*columns*4;
201 for(column=0; column<columns; column++) {
202 unsigned char red = 0,green = 0,blue = 0,alphabyte = 0;
203 switch (targa_header.pixel_size) {
218 alphabyte = getc(fin);
222 *pixbuf++ = alphabyte;
228 else if (targa_header.image_type==10) { // Runlength encoded RGB images
229 unsigned char red = 0,green = 0,blue = 0,alphabyte = 0,packetHeader,packetSize,j;
230 for(row=rows-1; row>=0; row--) {
231 pixbuf = image_rgba + row*columns*4;
232 for(column=0; column<columns; ) {
233 packetHeader=getc(fin);
234 packetSize = 1 + (packetHeader & 0x7f);
235 if (packetHeader & 0x80) { // run-length packet
236 switch (targa_header.pixel_size) {
247 alphabyte = getc(fin);
251 for(j=0;j<packetSize;j++) {
257 if (column==columns) { // run spans across rows
263 pixbuf = image_rgba + row*columns*4;
267 else { // non run-length packet
268 for(j=0;j<packetSize;j++) {
269 switch (targa_header.pixel_size) {
283 alphabyte = getc(fin);
287 *pixbuf++ = alphabyte;
291 if (column==columns) { // pixel packet run spans across rows
297 pixbuf = image_rgba + row*columns*4;
307 image_width = columns;
312 byte* loadimagepixels (char* filename, qboolean complain, int matchwidth, int matchheight)
315 char basename[128], name[128];
317 COM_StripExtension(filename, basename); // strip the extension to allow TGA skins on Q2 models despite the .pcx in the skin name
318 sprintf (name, "textures/%s.tga", basename);
319 COM_FOpenFile (name, &f, true);
321 return LoadTGA (f, matchwidth, matchheight);
322 sprintf (name, "textures/%s.pcx", basename);
323 COM_FOpenFile (name, &f, true);
325 return LoadPCX (f, matchwidth, matchheight);
326 sprintf (name, "%s.tga", basename);
327 COM_FOpenFile (name, &f, true);
329 return LoadTGA (f, matchwidth, matchheight);
330 sprintf (name, "%s.pcx", basename);
331 COM_FOpenFile (name, &f, true);
333 return LoadPCX (f, matchwidth, matchheight);
334 if ((image_rgba = W_GetTexture(basename, matchwidth, matchheight)))
337 Con_Printf ("Couldn't load %s.tga or .pcx\n", filename);
341 int loadtextureimage (int texnum, char* filename, qboolean complain, int matchwidth, int matchheight)
344 if (!(data = loadimagepixels (filename, complain, matchwidth, matchheight)))
346 if (texnum >= 0) // specific texnum, not cached
348 glBindTexture(GL_TEXTURE_2D, texnum);
349 GL_Upload32 (data, image_width, image_height, true, true);
353 else // any texnum, cached
355 texnum = GL_LoadTexture (filename, image_width, image_height, data, true, true, 4);