iout[0] = pal[in[0]];
}
-extern byte qgamma[];
void Image_CopyRGBAGamma(byte *in, byte *out, int pixels)
{
while (pixels--)
pcx = &pcxbuf;
- if (pcx->manufacturer != 0x0a
- || pcx->version != 5
- || pcx->encoding != 1
- || pcx->bits_per_pixel != 8
- || pcx->xmax > 320
- || pcx->ymax > 256)
+ // LordHavoc: big-endian support ported from QF newtree
+ pcx->xmax = LittleShort (pcx->xmax);
+ pcx->xmin = LittleShort (pcx->xmin);
+ pcx->ymax = LittleShort (pcx->ymax);
+ pcx->ymin = LittleShort (pcx->ymin);
+ pcx->hres = LittleShort (pcx->hres);
+ pcx->vres = LittleShort (pcx->vres);
+ pcx->bytes_per_line = LittleShort (pcx->bytes_per_line);
+ pcx->palette_type = LittleShort (pcx->palette_type);
+
+ if (pcx->manufacturer != 0x0a || pcx->version != 5 || pcx->encoding != 1 || pcx->bits_per_pixel != 8 || pcx->xmax > 320 || pcx->ymax > 256)
{
Con_Printf ("Bad pcx file\n");
return NULL;
fseek (f, sizeof(pcxbuf) - 4, SEEK_SET);
count = (pcx->xmax+1) * (pcx->ymax+1);
- image_rgba = malloc( count * 4);
+ image_rgba = qmalloc( count * 4);
for (y=0 ; y<=pcx->ymax ; y++)
{
{
runLength = dataByte & 0x3F;
dataByte = fgetc(f);
+ if (runLength)
+ {
+ x += runLength;
+ while(runLength--)
+ {
+ pix[0] = palette[dataByte*3];
+ pix[1] = palette[dataByte*3+1];
+ pix[2] = palette[dataByte*3+2];
+ pix[3] = 255;
+ pix += 4;
+ }
+ }
}
else
- runLength = 1;
-
- while(runLength-- > 0)
{
+ x++;
pix[0] = palette[dataByte*3];
pix[1] = palette[dataByte*3+1];
pix[2] = palette[dataByte*3+2];
pix[3] = 255;
pix += 4;
- x++;
}
+
}
}
fclose(f);
rows = targa_header.height;
numPixels = columns * rows;
- image_rgba = malloc (numPixels*4);
+ image_rgba = qmalloc(numPixels*4);
if (targa_header.id_length != 0)
fseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment
if (matchheight && height != matchheight)
return NULL;
- image_rgba = malloc(width*height*4);
+ image_rgba = qmalloc(width*height*4);
fread(image_rgba + width*height*3, 1, width*height, f);
fclose(f);
return image_rgba;
}
+void Image_StripImageExtension (char *in, char *out)
+{
+ char *end, *temp;
+ end = in + strlen(in);
+ if ((end - in) >= 4)
+ {
+ temp = end - 4;
+ if (strcmp(temp, ".tga") == 0 || strcmp(temp, ".pcx") == 0 || strcmp(temp, ".lmp") == 0)
+ end = temp;
+ while (in < end)
+ *out++ = *in++;
+ *out++ = 0;
+ }
+ else
+ strcpy(out, in);
+}
+
byte* loadimagepixels (char* filename, qboolean complain, int matchwidth, int matchheight)
{
FILE *f;
- char basename[128], name[128];
+ char basename[256], name[256];
byte *image_rgba, *c;
- COM_StripExtension(filename, basename); // strip the extension to allow TGA skins on Q2 models despite the .pcx in the skin name
- // replace *'s with +, so commandline utils don't get confused when dealing with the external files
- c = basename;
- while (*c)
- {
+ Image_StripImageExtension(filename, basename); // strip .tga, .pcx and .lmp extensions to allow replacement by other types
+ // replace *'s with #, so commandline utils don't get confused when dealing with the external files
+ for (c = basename;*c;c++)
if (*c == '*')
- *c = '+';
- c++;
- }
+ *c = '#';
sprintf (name, "textures/%s.tga", basename);
COM_FOpenFile (name, &f, true);
if (f)
return data; // some transparency
else
{
- free(data);
+ qfree(data);
return NULL; // all opaque
}
}
if (!(data = loadimagepixels (filename, complain, matchwidth, matchheight)))
return 0;
texnum = GL_LoadTexture (filename, image_width, image_height, data, mipmap, true, 4);
- free(data);
+ qfree(data);
return texnum;
}
if (!(data = loadimagepixelsmask (filename, complain, matchwidth, matchheight)))
return 0;
texnum = GL_LoadTexture (filename, image_width, image_height, data, mipmap, true, 4);
- free(data);
+ qfree(data);
return texnum;
}
count = image_makemask(data, data, image_width * image_height);
if (count)
{
- filename2 = malloc(strlen(filename) + 6);
+ filename2 = qmalloc(strlen(filename) + 6);
sprintf(filename2, "%s_mask", filename);
image_masktexnum = GL_LoadTexture (filename2, image_width, image_height, data, mipmap, true, 4);
- free(filename2);
+ qfree(filename2);
}
- free(data);
+ qfree(data);
return texnum;
}
+
+void Image_WriteTGARGB_preflipped (char *filename, int width, int height, byte *data)
+{
+ byte *buffer, *in, *out, *end;
+
+ buffer = qmalloc(width*height*3 + 18);
+
+ memset (buffer, 0, 18);
+ buffer[2] = 2; // uncompressed type
+ buffer[12] = (width >> 0) & 0xFF;
+ buffer[13] = (width >> 8) & 0xFF;
+ buffer[14] = (height >> 0) & 0xFF;
+ buffer[15] = (height >> 8) & 0xFF;
+ buffer[16] = 24; // pixel size
+
+ // swap rgb to bgr
+ in = data;
+ out = buffer + 18;
+ end = in + width*height*3;
+ for (;in < end;in += 3)
+ {
+ *out++ = in[2];
+ *out++ = in[1];
+ *out++ = in[0];
+ }
+ COM_WriteFile (filename, buffer, width*height*3 + 18 );
+
+ qfree(buffer);
+}
+
+void Image_WriteTGARGB (char *filename, int width, int height, byte *data)
+{
+ int y;
+ byte *buffer, *in, *out, *end;
+
+ buffer = qmalloc(width*height*3 + 18);
+
+ memset (buffer, 0, 18);
+ buffer[2] = 2; // uncompressed type
+ buffer[12] = (width >> 0) & 0xFF;
+ buffer[13] = (width >> 8) & 0xFF;
+ buffer[14] = (height >> 0) & 0xFF;
+ buffer[15] = (height >> 8) & 0xFF;
+ buffer[16] = 24; // pixel size
+
+ // swap rgb to bgr and flip upside down
+ out = buffer + 18;
+ for (y = height - 1;y >= 0;y--)
+ {
+ in = data + y * width * 3;
+ end = in + width * 3;
+ for (;in < end;in += 3)
+ {
+ *out++ = in[2];
+ *out++ = in[1];
+ *out++ = in[0];
+ }
+ }
+ COM_WriteFile (filename, buffer, width*height*3 + 18 );
+
+ qfree(buffer);
+}
+
+void Image_WriteTGARGBA (char *filename, int width, int height, byte *data)
+{
+ int y;
+ byte *buffer, *in, *out, *end;
+
+ buffer = qmalloc(width*height*4 + 18);
+
+ memset (buffer, 0, 18);
+ buffer[2] = 2; // uncompressed type
+ buffer[12] = (width >> 0) & 0xFF;
+ buffer[13] = (width >> 8) & 0xFF;
+ buffer[14] = (height >> 0) & 0xFF;
+ buffer[15] = (height >> 8) & 0xFF;
+ buffer[16] = 32; // pixel size
+
+ // swap rgba to bgra and flip upside down
+ out = buffer + 18;
+ for (y = height - 1;y >= 0;y--)
+ {
+ in = data + y * width * 4;
+ end = in + width * 4;
+ for (;in < end;in += 4)
+ {
+ *out++ = in[2];
+ *out++ = in[1];
+ *out++ = in[0];
+ *out++ = in[3];
+ }
+ }
+ COM_WriteFile (filename, buffer, width*height*4 + 18 );
+
+ qfree(buffer);
+}