This repository has been archived on 2022-06-27. You can view files and clone it, but cannot push or open issues or pull requests.
Xash3DArchive/ripper/conv_pcximage.c

149 lines
4.6 KiB
C

//=======================================================================
// Copyright XashXT Group 2007 ©
// conv_pcximage.c - convert pcximages
//=======================================================================
#include "ripper.h"
#include "pal_utils.h"
bool PCX_ConvertImage( const char *name, char *buffer, int filesize )
{
pcx_t pcx;
uint *trans;
int s, i, p, x, y, x2, dataByte;
byte *pix, *pbuf, *palette, *fin, *enddata;
rgbdata_t pic;
fin = buffer;
Mem_Copy(&pcx, fin, sizeof(pcx));
fin += sizeof(pcx);
// probably it's not pcx file
if (pcx.manufacturer != 0x0a || pcx.version != 5 || pcx.encoding != 1 ) return false;
if (filesize < (int)sizeof(pcx) + 768)
{
MsgWarn("ConvPCX: file (%s) have invalid size\n", name );
return false;
}
memset( &pic, 0, sizeof(pic));
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);
pic.width = pcx.xmax + 1 - pcx.xmin;
pic.height = pcx.ymax + 1 - pcx.ymin;
if( pcx.bits_per_pixel != 8 || pcx.manufacturer != 0x0a || pcx.version != 5 || pcx.encoding != 1)
{
MsgWarn("ConvPCX: (%s) have illegal pixel size '%d'\n", name, pcx.bits_per_pixel );
return false;
}
if(pic.width > 512 || pic.height > 512 || pic.width <= 0 || pic.height <= 0)
{
MsgWarn( "ConvPCX: (%s) dimensions out of range [%dx%d]\n", name, pic.width, pic.height );
return false;
}
palette = buffer + filesize - 768;
pic.numLayers = 1;
pic.numMips = 1;
pic.type = PF_RGBA_32;
s = pic.width * pic.height;
pic.size = s * 4;
pbuf = (byte *)Mem_Alloc( zonepool, s );
pic.buffer = (byte *)Mem_Alloc( zonepool, pic.size );
trans = (uint *)pic.buffer;
enddata = palette;
for (y = 0; y < pic.height && fin < enddata; y++)
{
pix = pbuf + y * pic.width;
for (x = 0; x < pic.width && fin < enddata;)
{
dataByte = *fin++;
if(dataByte >= 0xC0)
{
if(fin >= enddata) break;
x2 = x + (dataByte & 0x3F);
dataByte = *fin++;
if (x2 > pic.width) x2 = pic.width; // technically an error
while(x < x2) pix[x++] = dataByte;
}
else pix[x++] = dataByte;
}
// the number of bytes per line is always forced to an even number
fin += pcx.bytes_per_line - pic.width;
while(x < pic.width) pix[x++] = 0;
}
Conv_GetPalettePCX( palette );
// convert to rgba
for (i = 0; i < s; i++)
{
p = pbuf[i];
if (p == 255)
{
pic.flags |= IMAGE_HAS_ALPHA; // found alpha channel
((byte *)&trans[i])[0] = ((byte *)&d_currentpal[0])[0];
((byte *)&trans[i])[1] = ((byte *)&d_currentpal[0])[1];
((byte *)&trans[i])[2] = ((byte *)&d_currentpal[0])[2];
((byte *)&trans[i])[3] = ((byte *)&d_currentpal[p])[3];
}
else trans[i] = d_currentpal[p];
}
Mem_Free( pbuf ); // free compressed image
FS_StripExtension( (char *)name );
FS_SaveImage( va("%s/%s.tga", gs_gamedir, name ), &pic ); // save converted image
Mem_Free( pic.buffer ); // release buffer
return true;
}
/*
============
ConvPCX
============
*/
bool ConvPCX( const char *name, char *buffer, int filesize )
{
string picname, path;
FS_FileBase( name, picname );
if(!com.strnicmp("num", picname, 3 ))
com.snprintf( path, MAX_STRING, "graphics/fonts/%s", picname );
else if(!com.strnicmp("anum", picname, 4 ))
com.snprintf( path, MAX_STRING, "graphics/fonts/%s", picname );
else if(!com.strnicmp("conchars", picname, 8 ))
com.snprintf( path, MAX_STRING, "graphics/fonts/%s", picname );
else if(!com.strnicmp("a_", picname, 2 ))
com.snprintf( path, MAX_STRING, "graphics/hud/%s", picname );
else if(!com.strnicmp("p_", picname, 2 ))
com.snprintf( path, MAX_STRING, "graphics/hud/%s", picname );
else if(!com.strnicmp("k_", picname, 2 ))
com.snprintf( path, MAX_STRING, "graphics/hud/%s", picname );
else if(!com.strnicmp("i_", picname, 2 ))
com.snprintf( path, MAX_STRING, "graphics/hud/%s", picname );
else if(!com.strnicmp("w_", picname, 2 ))
com.snprintf( path, MAX_STRING, "graphics/hud/%s", picname );
else if(!com.strnicmp("m_", picname, 2 ))
com.snprintf( path, MAX_STRING, "graphics/menu/%s", picname );
else if(!com.strnicmp("m_", picname, 2 ))
com.snprintf( path, MAX_STRING, "graphics/menu/%s", picname );
else com.snprintf( path, MAX_STRING, "graphics/common/%s", picname );
if(PCX_ConvertImage( path, buffer, filesize ))
{
Msg("%s\n", name ); // echo to console about current image
return true;
}
return false;
}