Erm, just a note to RandomTiger - The PCX file format is as follows:
first comes a header, which would look like this:
typedef struct PCXHEADER {
unsigned char Manufacturer,Version,Encoding,BPP;
unsigned short XMin, YMin, XMax, YMax, HDpi, VDpi;
unsigned char ColorMap[48], Reserved, NPlanes;
unsigned short BytesPerLine, PalInfo, HScrSize, VScrSize;
char fill[54];
} PCXHEADER;
The size of the picture *must* be determined by X/Ymax - X/YMin, since not all PCX savers support HDpi and VDpi, and although I haven't seen a single PCX that didn't have XMin and YMin set to 0, better safe than sorry (Another tiny afterthought: don't forget to add 1 to XMax and YMax (a picture from 0 to 127 is 128 pixels wide)). I also believe that Version should be set to 5, since that's the version used by both 256 color and 24bpp PCXs.
One nasty PCX trap is that BytesPerLine is always even, even if the width of the picture is odd (It seems pretty stupid to keep word alignment in a file, even if it makes sense in memory), but that shouldn't be a problem since texture sizes are powers of two.
A PCX is encoded like so:
If the upper two bits of a byte are set ( if(byte&0xc0) ), then the lower six bytes are the length of an RLE run, and the next byte is data, regardless of wether it's upper bytes are set or not, so an unoptimized loop would look like:
byte = fgetc(PCX);
if (byte&0xc0)
{
byte2 = fgetc(PCX)
for(i=0;i
*image++=byte2;
}
else *image++=byte;
If the PCX is 256 color, the last 768 bytes of the file store the palette.
I have no idea how 4-bit and monochrome PCXs are packed, though, so don't assume anything I said here would apply (except the header), and hope FS2 doesn't use those
Ideally, you'd load the image incrementally into a buffer (In, say, 2kb blocks), and process those. That would be faster than relying on the built-in buffering used by fgetc() (Though I can't admit I checked that on any compiler more recent than Borland C++ 4.10).
Hope this info helps you. I'd do it myself, except that I don't have a C++ Compiler on this system, and I'm too lazy to install one, let alone do the code
Edit: Whoops! That code won't work for a 24-bit PCX (Though FS2 doesn't use those, AFAIK), since they're stored in a planar fasion (Nplanes is set to 3, and each scanline is stored with all reds first, then all blues, then all greens), so you'd need to modify it to get one loop to handle all cases, and it would get pretty nasty with the RLE encoding if you want to do everything single-pass.
The simplest method would be to also add an outer loop that runs from 0 to nplanes-1, and increment the pointer each time by BPP (in the header) instead of 1, so basically after the first pass your memory buffer will be:
[R _ _ R _ _ R _ _ ...]
After the Second:
[R G _ R G _ R G _ ...]
and then
[R G B R G B R G B ...]
that way you could easily use one loop to handle both 8 and 24 bpp images.