summaryrefslogtreecommitdiff
path: root/utils/xbox/toollib/piclib.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/xbox/toollib/piclib.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'utils/xbox/toollib/piclib.cpp')
-rw-r--r--utils/xbox/toollib/piclib.cpp557
1 files changed, 557 insertions, 0 deletions
diff --git a/utils/xbox/toollib/piclib.cpp b/utils/xbox/toollib/piclib.cpp
new file mode 100644
index 0000000..fc0101a
--- /dev/null
+++ b/utils/xbox/toollib/piclib.cpp
@@ -0,0 +1,557 @@
+#include "toollib.h"
+#include "piclib.h"
+
+byte_t* g_tgabuffer;
+byte_t* g_tgabuffptr;
+
+/*****************************************************************************
+ TL_LoadPCX
+
+*****************************************************************************/
+void TL_LoadPCX(char* filename, byte_t** pic, byte_t** palette, int* width, int* height)
+{
+ byte_t* raw;
+ pcx_t* pcx;
+ int x;
+ int y;
+ int len;
+ int databyte;
+ int runlength;
+ byte_t* out;
+ byte_t* pix;
+
+ // load the file
+ len = TL_LoadFile(filename,(void **)&raw);
+
+ // parse the PCX file
+ pcx = (pcx_t*)raw;
+ raw = &pcx->data;
+
+ pcx->xmin = TL_LittleShort(pcx->xmin);
+ pcx->ymin = TL_LittleShort(pcx->ymin);
+ pcx->xmax = TL_LittleShort(pcx->xmax);
+ pcx->ymax = TL_LittleShort(pcx->ymax);
+ pcx->hres = TL_LittleShort(pcx->hres);
+ pcx->vres = TL_LittleShort(pcx->vres);
+ pcx->bytes_per_line = TL_LittleShort(pcx->bytes_per_line);
+ pcx->palette_type = TL_LittleShort(pcx->palette_type);
+
+ if (pcx->manufacturer != 0x0a ||
+ pcx->version != 5 ||
+ pcx->encoding != 1 ||
+ pcx->bits_per_pixel != 8 ||
+ pcx->xmax >= 640 ||
+ pcx->ymax >= 480)
+ TL_Error("Bad pcx file %s",filename);
+
+ if (palette)
+ {
+ *palette = (byte_t*)TL_Malloc(768);
+ memcpy(*palette,(byte_t*)pcx + len - 768,768);
+ }
+
+ if (width)
+ *width = pcx->xmax+1;
+
+ if (height)
+ *height = pcx->ymax+1;
+
+ if (!pic)
+ return;
+
+ out = (byte_t*)TL_Malloc((pcx->ymax+1)*(pcx->xmax+1));
+ *pic = out;
+ pix = out;
+
+ for (y=0; y<=pcx->ymax; y++, pix += pcx->xmax+1)
+ {
+ for (x=0; x<=pcx->xmax; )
+ {
+ databyte = *raw++;
+
+ if((databyte & 0xC0) == 0xC0)
+ {
+ runlength = databyte & 0x3F;
+ databyte = *raw++;
+ }
+ else
+ runlength = 1;
+
+ while (runlength-- > 0)
+ pix[x++] = databyte;
+ }
+ }
+
+ if (raw - (byte_t *)pcx > len)
+ TL_Error("PCX file %s was malformed",filename);
+
+ TL_Free(pcx);
+}
+
+/*****************************************************************************
+ TL_SavePCX
+
+*****************************************************************************/
+void TL_SavePCX(char* filename, byte_t* data, int width, int height, byte_t* palette)
+{
+ int i;
+ int j;
+ int length;
+ pcx_t* pcx;
+ byte_t* pack;
+
+ pcx = (pcx_t*)TL_Malloc(width*height*2+1000);
+
+ pcx->manufacturer = 0x0A; // PCX id
+ pcx->version = 5; // 256 color
+ pcx->encoding = 1; // uncompressed
+ pcx->bits_per_pixel = 8; // 256 color
+ pcx->xmin = 0;
+ pcx->ymin = 0;
+ pcx->xmax = TL_LittleShort((short)(width-1));
+ pcx->ymax = TL_LittleShort((short)(height-1));
+ pcx->hres = TL_LittleShort((short)width);
+ pcx->vres = TL_LittleShort((short)height);
+ pcx->color_planes = 1; // chunky image
+ pcx->bytes_per_line = TL_LittleShort((short)width);
+ pcx->palette_type = TL_LittleShort(2); // not a grey scale
+
+ // pack the image
+ pack = &pcx->data;
+
+ for (i=0; i<height; i++)
+ {
+ for (j=0; j<width; j++)
+ {
+ if ((*data & 0xc0) != 0xC0)
+ *pack++ = *data++;
+ else
+ {
+ *pack++ = 0xC1;
+ *pack++ = *data++;
+ }
+ }
+ }
+
+ // write the palette
+ *pack++ = 0x0C;
+ for (i=0; i<768; i++)
+ *pack++ = *palette++;
+
+ // write output file
+ length = pack - (byte_t*)pcx;
+ TL_SaveFile(filename,pcx,length);
+
+ TL_Free(pcx);
+}
+
+/*****************************************************************************
+ TGA_GetByte
+
+*****************************************************************************/
+byte_t TGA_GetByte(void)
+{
+ return (*g_tgabuffptr++);
+}
+
+/*****************************************************************************
+ TGA_GetShort
+
+*****************************************************************************/
+short TGA_GetShort(void)
+{
+ byte_t msb;
+ byte_t lsb;
+
+ lsb = g_tgabuffptr[0];
+ msb = g_tgabuffptr[1];
+
+ g_tgabuffptr += 2;
+
+ return ((msb<<8)|lsb);
+}
+
+/*****************************************************************************
+ TL_LoadTGA
+
+*****************************************************************************/
+void TL_LoadTGA(char* name, byte_t** pixels, int* width, int* height)
+{
+ int columns;
+ int rows;
+ int numPixels;
+ byte_t* pixbuf;
+ int row;
+ int column;
+ byte_t* targa_rgba;
+ tga_t targa_header;
+ byte_t red;
+ byte_t green;
+ byte_t blue;
+ byte_t alphabyte;
+ byte_t packetHeader;
+ byte_t packetSize;
+ byte_t j;
+
+ TL_LoadFile(name,(void**)&g_tgabuffer);
+ g_tgabuffptr = g_tgabuffer;
+
+ /* load unaligned tga data */
+ targa_header.id_length = TGA_GetByte();
+ targa_header.colormap_type = TGA_GetByte();
+ targa_header.image_type = TGA_GetByte();
+ targa_header.colormap_index = TGA_GetShort();
+ targa_header.colormap_length = TGA_GetShort();
+ targa_header.colormap_size = TGA_GetByte();
+ targa_header.x_origin = TGA_GetShort();
+ targa_header.y_origin = TGA_GetShort();
+ targa_header.width = TGA_GetShort();
+ targa_header.height = TGA_GetShort();
+ targa_header.pixel_size = TGA_GetByte();
+ targa_header.attributes = TGA_GetByte();
+
+ if (targa_header.image_type != 2 && targa_header.image_type != 10)
+ TL_Error("TL_LoadTGA: %s - Only type 2 and 10 targa RGB images supported",name);
+
+ if ((targa_header.colormap_type != 0) || (targa_header.pixel_size != 32 && targa_header.pixel_size != 24))
+ TL_Error("TL_LoadTGA: %s - Only 32 or 24 bit images supported (no colormaps)",name);
+
+ columns = targa_header.width;
+ rows = targa_header.height;
+ numPixels = columns * rows;
+
+ if (width)
+ *width = columns;
+ if (height)
+ *height = rows;
+
+ targa_rgba = (byte_t*)TL_Malloc(numPixels*4);
+ *pixels = targa_rgba;
+
+ if (targa_header.id_length != 0)
+ {
+ // skip TARGA image comment
+ g_tgabuffptr += targa_header.id_length;
+ }
+
+ if (targa_header.image_type==2)
+ {
+ // Uncompressed, RGB images
+ for (row=rows-1; row>=0; row--)
+ {
+ pixbuf = targa_rgba + row*columns*4;
+ for(column=0; column<columns; column++)
+ {
+ switch (targa_header.pixel_size)
+ {
+ case 24:
+ blue = TGA_GetByte();
+ green = TGA_GetByte();
+ red = TGA_GetByte();
+ alphabyte = 255;
+ break;
+
+ case 32:
+ blue = TGA_GetByte();
+ green = TGA_GetByte();
+ red = TGA_GetByte();
+ alphabyte = TGA_GetByte();
+ break;
+ }
+
+ *pixbuf++ = red;
+ *pixbuf++ = green;
+ *pixbuf++ = blue;
+ *pixbuf++ = alphabyte;
+
+ }
+ }
+ }
+ else if (targa_header.image_type==10)
+ {
+ // Runlength encoded RGB images
+ for (row=rows-1; row>=0; row--)
+ {
+ pixbuf = targa_rgba + row*columns*4;
+ for(column=0; column<columns; )
+ {
+ packetHeader = TGA_GetByte();
+ packetSize = 1 + (packetHeader & 0x7f);
+ if (packetHeader & 0x80)
+ {
+ // run-length packet
+ switch (targa_header.pixel_size)
+ {
+ case 24:
+ blue = TGA_GetByte();
+ green = TGA_GetByte();
+ red = TGA_GetByte();
+ alphabyte = 255;
+ break;
+
+ case 32:
+ blue = TGA_GetByte();
+ green = TGA_GetByte();
+ red = TGA_GetByte();
+ alphabyte = TGA_GetByte();
+ break;
+ }
+
+ for(j=0; j<packetSize; j++)
+ {
+ *pixbuf++ = red;
+ *pixbuf++ = green;
+ *pixbuf++ = blue;
+ *pixbuf++ = alphabyte;
+ column++;
+
+ if (column==columns)
+ {
+ // run spans across rows
+ column=0;
+ if (row>0)
+ row--;
+ else
+ goto breakOut;
+ pixbuf = targa_rgba + row*columns*4;
+ }
+ }
+ }
+ else
+ {
+ // non run-length packet
+ for(j=0; j<packetSize; j++)
+ {
+ switch (targa_header.pixel_size)
+ {
+ case 24:
+ blue = TGA_GetByte();
+ green = TGA_GetByte();
+ red = TGA_GetByte();
+ alphabyte = 255;
+ break;
+
+ case 32:
+ blue = TGA_GetByte();
+ green = TGA_GetByte();
+ red = TGA_GetByte();
+ alphabyte = TGA_GetByte();
+ break;
+ }
+
+ *pixbuf++ = red;
+ *pixbuf++ = green;
+ *pixbuf++ = blue;
+ *pixbuf++ = alphabyte;
+ column++;
+
+ if (column == columns)
+ {
+ // pixel packet run spans across rows
+ column=0;
+ if (row>0)
+ row--;
+ else
+ goto breakOut;
+ pixbuf = targa_rgba + row*columns*4;
+ }
+ }
+ }
+ }
+breakOut:;
+ }
+ }
+
+ TL_Free(g_tgabuffer);
+}
+
+/*****************************************************************************
+ TL_SaveTGA
+
+ Saves TGA. Supports r/w 16/24/32 bpp.
+*****************************************************************************/
+void TL_SaveTGA(char* filename, byte_t* pixels, int width, int height, int sbpp, int tbpp)
+{
+ int handle;
+ tga_t tga;
+ unsigned short rgba5551;
+ unsigned long rgba8888;
+ int r;
+ int g;
+ int b;
+ int x;
+ int y;
+ int a;
+ byte_t* tgabuffer;
+ byte_t* tgabufferptr;
+ byte_t* rawbufferptr;
+ byte_t* tempbuffer;
+ byte_t* tempbufferptr;
+ int bytesperpixel;
+
+ // all source is upsampled into easy 32 bit rgba8888
+ // and downsampled into tga buffer
+ tempbuffer = (byte_t*)TL_Malloc(width*height*4);
+
+ if (sbpp == 16)
+ {
+ /* source is 16 bit rgba */
+ rawbufferptr = pixels;
+ for (y=0; y<height; y++)
+ {
+ tempbufferptr = tempbuffer + y*width*4;
+ for (x=0; x<width; x++)
+ {
+ rgba5551 = *(unsigned short*)rawbufferptr;
+ r = (rgba5551 & 0xF800)>>11;
+ g = (rgba5551 & 0x07C0)>>6;
+ b = (rgba5551 & 0x003E)>>1;
+ a = (rgba5551 & 0x01);
+ tempbufferptr[0] = (byte_t)(b * (255.0/31.0));
+ tempbufferptr[1] = (byte_t)(g * (255.0/31.0));
+ tempbufferptr[2] = (byte_t)(r * (255.0/31.0));
+ tempbufferptr[3] = (byte_t)(a * 255.0);
+
+ rawbufferptr += sizeof(unsigned short);
+ tempbufferptr += 4;
+ }
+ }
+ }
+ else if (sbpp == 24)
+ {
+ /* source is 24 bit rgba */
+ rawbufferptr = pixels;
+ for (y=0; y<height; y++)
+ {
+ tempbufferptr = tempbuffer + y*width*4;
+ for (x=0; x<width; x++)
+ {
+ tempbufferptr[0] = rawbufferptr[0];
+ tempbufferptr[1] = rawbufferptr[1];
+ tempbufferptr[2] = rawbufferptr[2];
+ tempbufferptr[3] = 255;
+
+ rawbufferptr += 3;
+ tempbufferptr += 4;
+ }
+ }
+ }
+ else if (sbpp == 32)
+ {
+ /* source is 32 bit rgba */
+ memcpy(tempbuffer,pixels,width*height*4);
+ }
+ else
+ TL_Error("TL_SaveTGA: cannot handle source %d bits per pixel",sbpp);
+
+ if (tbpp == 16)
+ bytesperpixel = 2;
+ else if (tbpp == 24)
+ bytesperpixel = 3;
+ else if (tbpp == 32)
+ bytesperpixel = 4;
+ else
+ TL_Error("TL_SaveTGA: cannot handle target %d bits per pixel",tbpp);
+
+ handle = TL_SafeOpenWrite(filename);
+
+ /* write the targa header */
+ tga.id_length = 0;
+ tga.colormap_type = 0;
+ tga.image_type = 2;
+ tga.colormap_index = 0;
+ tga.colormap_length = 0;
+ tga.colormap_size = 0;
+ tga.x_origin = 0;
+ tga.y_origin = 0;
+ tga.width = width;
+ tga.height = height;
+ tga.pixel_size = tbpp;
+ tga.attributes = 0;
+
+ TL_SafeWrite(handle,&tga.id_length,sizeof(tga.id_length));
+ TL_SafeWrite(handle,&tga.colormap_type,sizeof(tga.colormap_type));
+ TL_SafeWrite(handle,&tga.image_type,sizeof(tga.image_type));
+ TL_SafeWrite(handle,&tga.colormap_index,sizeof(tga.colormap_index));
+ TL_SafeWrite(handle,&tga.colormap_length,sizeof(tga.colormap_length));
+ TL_SafeWrite(handle,&tga.colormap_size,sizeof(tga.colormap_size));
+ TL_SafeWrite(handle,&tga.x_origin,sizeof(tga.x_origin));
+ TL_SafeWrite(handle,&tga.y_origin,sizeof(tga.y_origin));
+ TL_SafeWrite(handle,&tga.width,sizeof(tga.width));
+ TL_SafeWrite(handle,&tga.height,sizeof(tga.height));
+ TL_SafeWrite(handle,&tga.pixel_size,sizeof(tga.pixel_size));
+ TL_SafeWrite(handle,&tga.attributes,sizeof(tga.attributes));
+
+ /* tga images are upside down left to right - !@#$% */
+ tgabuffer = (byte_t*)TL_Malloc(width*height*bytesperpixel);
+
+ /* source is 32 bit rgba */
+ rawbufferptr = tempbuffer;
+ for (y=height-1; y>=0; y--)
+ {
+ tgabufferptr = tgabuffer + y*width*bytesperpixel;
+ for (x=0; x<width; x++)
+ {
+ switch (bytesperpixel)
+ {
+ case 2:
+ break;
+
+ case 3:
+ rgba8888 = TL_BigLong(*(unsigned long*)rawbufferptr);
+ r = (rgba8888 & 0xFF000000)>>24;
+ g = (rgba8888 & 0x00FF0000)>>16;
+ b = (rgba8888 & 0x0000FF00)>>8;
+
+ tgabufferptr[0] = b;
+ tgabufferptr[1] = g;
+ tgabufferptr[2] = r;
+ break;
+
+ case 4:
+ rgba8888 = TL_BigLong(*(unsigned long*)rawbufferptr);
+ r = (rgba8888 & 0xFF000000)>>24;
+ g = (rgba8888 & 0x00FF0000)>>16;
+ b = (rgba8888 & 0x0000FF00)>>8;
+ a = rgba8888 & 0xFF;
+
+ tgabufferptr[0] = b;
+ tgabufferptr[1] = g;
+ tgabufferptr[2] = r;
+ tgabufferptr[3] = a;
+ break;
+ }
+
+ rawbufferptr += 4;
+ tgabufferptr += bytesperpixel;
+ }
+ }
+
+ TL_SafeWrite(handle,tgabuffer,width*height*bytesperpixel);
+ close(handle);
+
+ TL_Free(tempbuffer);
+ TL_Free(tgabuffer);
+}
+
+/*****************************************************************************
+ TL_LoadImage
+
+ Loads an image based on extension.
+*****************************************************************************/
+void TL_LoadImage(char* name, byte_t** pixels, byte_t** palette, int* width, int* height)
+{
+ char ext[16];
+
+ TL_GetExtension(name,ext);
+ if (!stricmp(ext,"pcx"))
+ TL_LoadPCX(name,pixels,palette,width,height);
+ else if (!stricmp(ext,"tga"))
+ {
+ TL_LoadTGA(name,pixels,width,height);
+ *palette = NULL;
+ }
+ else
+ TL_Error("TL_LoadImage: unknown image extension %s",ext);
+}
+