149 lines
4.6 KiB
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;
|
|
} |