#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=0; row--) { pixbuf = targa_rgba + row*columns*4; for(column=0; column=0; row--) { pixbuf = targa_rgba + row*columns*4; for(column=0; column0) row--; else goto breakOut; pixbuf = targa_rgba + row*columns*4; } } } else { // non run-length packet for(j=0; j0) 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>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=0; y--) { tgabufferptr = tgabuffer + y*width*bytesperpixel; for (x=0; x>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); }