There is a bug in the PCX Loading function of VGFX!

The bug did not occur when I used VGFX in the past,
cause the pcx files which I saved with my old paint
program were..."friendly"...and the function could
read them without any problems.

However the function is not able to load PCX files saved
with todays common paint programs like PSP or Photoshop.
Also I'm not programming in Free Pascal since some years
now so the only thing I can offer you is the PCX Loading
function from my new engine texture loading module written
in C++...

The function is very fast and loads every PCX file available
no matter which paint program created them. But you must
rewrite it into Pascal code yourself ;(
Sorry I have no time to do it...










void Load_PCX(string Datei, string BigDatei)
{
  BigDatei= CharUpper((char *)BigDatei.c_str());
     Datei= CharUpper((char *)Datei.c_str());

  struct PCX_HeaderStructure 
         {   
            byte             Manufacturer;
            byte             Version;
            byte             Encoding;
            byte             BitsPerPixel;
            unsigned short   xmin,ymin;
            unsigned short   xmax,ymax;
            unsigned short   Hdpi,Vdpi;
            byte             Palette[48];
            byte             Reserved;
            byte             ColorPlanes;
            unsigned short   BytesPerLine;
            unsigned short   PalettenInfo;
            unsigned short   H_ScreenSize;
            unsigned short   V_ScreenSize;
            unsigned short   CTM_definedYMax;
            unsigned short   CTM_definedXMax;
            byte             unused[52];
         } PCX_Header;


                                           // Load whole PCX file into memory
 unsigned int  FileSize= 0;
 byte         *FileData= NULL;

 if (BigDatei.length() == 0) FileSize=    File2Mem(Datei         ,(void **)&FileData);
                        else FileSize= BigFile2Mem(Datei,BigDatei,(void **)&FileData);


                                           // Fill PCX header and check for propper PCX format
 memcpy(&PCX_Header,FileData,128);

 if (PCX_Header.Manufacturer!=10) ERRORM("FILE ERROR","Following file contains no valid pcx format :\n\n" + Datei);  

 if (PCX_Header.Encoding    != 1) ERRORM("FILE ERROR","Following pcx file is not compressed :\n\n" + Datei);  

 if (PCX_Header.ColorPlanes != 3) ERRORM("FILE ERROR","Following pcx file contains no valid 24 Bit format :\n\n"+ Datei);  


                                           // Calculate and allocate texture

 Width = PCX_Header.xmax - PCX_Header.xmin + 1;
 Height= PCX_Header.ymax - PCX_Header.ymin + 1;

 bool isOdd= (Width % 2) != 0;

 Init(Width, Height);


                                           // Allocate memory for a single encoded line
 byte        *EncodedLine         = NULL;                  
 unsigned int EncodedLineWidth    = Width + int(isOdd);
 unsigned int EncodedLineByteWidth= EncodedLineWidth << 2;
 AllokSpeicher((void **)&EncodedLine, 0, EncodedLineByteWidth);



                                           // Decode PCX scanlines and copy to texture memory
 unsigned int FilePosition = 128;

 for (int heightLoop= 0; heightLoop < Height; heightLoop++) 
 {
   unsigned int LinePosition = 0;
   unsigned int CurrentPlane = 0;

   memset(EncodedLine, 255, EncodedLineByteWidth);

   while (CurrentPlane < 3)
   {

     if ((FileData[FilePosition] & 192) != 192)               // Copy only one byte
	 { 	   
  	   EncodedLine[(LinePosition++ << 2) + CurrentPlane]= FileData[FilePosition++];

	   if (LinePosition >= EncodedLineWidth)
	   {	   
		 CurrentPlane++;
		 LinePosition= 0;
	   }
	 }
     else                                                     // Copy multiple bytes
	 {
		for (int ColorRepeat= 0; ColorRepeat < (FileData[FilePosition] ^ 192); ColorRepeat++)
		{ 
		  EncodedLine[(LinePosition++ << 2) + CurrentPlane]= FileData[FilePosition + 1];

		  if (LinePosition >= EncodedLineWidth)               // Zu kopierende bytes laufen in folgende planes ber
		  {
			LinePosition= 0;
			if (++CurrentPlane > 2) break;
          }
		}

		FilePosition+= 2;
	 }

   }

   memcpy((void *)(unsigned int(Offset) + heightLoop * (Width << 2)), EncodedLine, EncodedLineByteWidth - (int(isOdd) << 2));
 }


                                             // Free temporary memory
 FreeSpeicher((void **)&FileData,FileSize); 

 FreeSpeicher((void **)&EncodedLine,EncodedLineByteWidth); 
 
}