Board index » cppbuilder » Decoding PCX image

Decoding PCX image


2004-11-23 08:00:32 AM
cppbuilder90
Hi,
I have a problem converting PCX to bitmap. Most of the time my code decode the pcx image correctly. Some other time the image decoded would get destorted. Sometime, all of the image is distorted and something only a portion. Does anyone here have expereienced with this? My code is blow. thanks.
bool __fastcall TTCLGraphicRegionForm::ProcessPCXData(AnsiString GraphicFileName)
{
unsigned int ImageWidth = 0;
unsigned int ImageHeight = 0;
unsigned int ScanLineLength = 0;
unsigned int LinePaddingSize = 0;
//unsigned char byte, runvalue;
Byte byte, runvalue;
int index = 0;
int BufferSize = 0;
int runcount, total = 0;
char *Buffer;
Byte *ptr;
FILE *fp = NULL;
DWORD NumToRead;
bool Status = false;
unsigned char TempBuffer[500];
if ((fp = fopen( GraphicFileName.c_str(), "r" )) == NULL)
{
sprintf(TempBuffer, "Open file failed! File: %s", GraphicFileName.c_str());
Application->MessageBox(TempBuffer, "Error!", MB_OK);
return Status;
}
if(fread(&pcx, sizeof(char), sizeof(PCXHEADER), fp) != sizeof(PCXHEADER))
{
Application->MessageBox("Error Reading file!", "Error!", MB_OK);
fclose(fp);
return Status;
}
// Check for Error
if((pcx.Identifier != 0x0A) && (pcx.BitsPerPixel != 0x01) &&
(pcx.NumBitPlanes != 0x01) && (pcx.PaletteType != 1))
{
Application->MessageBox("Incorrect PCX format, Only take monochrome PCX!", "Error!", MB_OK);
fclose(fp);
return Status;
}
ImageWidth = pcx.XEnd - pcx.XStart + 1; // Width of image in pixels
ImageHeight = pcx.YEnd - pcx.YStart + 1; // Length of image in scan lines
ScanLineLength = pcx.NumBitPlanes * pcx.BytesPerLine;
LinePaddingSize = ((pcx.BytesPerLine * pcx.NumBitPlanes) *
(8 / pcx.BitsPerPixel)) - ((pcx.XEnd - pcx.XStart) + 1); // in pixels
BufferSize = ScanLineLength;
Buffer = new char[ScanLineLength + 1];
Image1->Picture = NULL;
Image1->AutoSize = true;
Image1->Picture->Bitmap->Width = ImageWidth;
Image1->Picture->Bitmap->Height = ImageHeight;
Image1->Picture->Bitmap->PixelFormat = pf1bit;
Image1->AutoSize = false;
for(int i = 0; i < ImageHeight; i++)
{
index = 0;
do
{
byte = (Byte) getc(fp);
if ((byte & 0xC0) == 0xC0)
{
runcount = byte & 0x3F;
runvalue = (Byte) getc(fp);
}
else
{
runcount = 1;
runvalue = byte;
}
// Write the pixels run to the buffer
for( total += runcount; // Update total
runcount && index < BufferSize; // Don't read past buffer
runcount--, index++) // Update counters
{
Buffer[index] = runvalue; // Assign value to buffer
}
} while(index < BufferSize); // Read to the end of buffer
ptr = (Byte*) Image1->Picture->Bitmap->ScanLine[i];
for (int x = 0; x < BufferSize; x++)
{
ptr[x] = (Byte)Buffer[x];
}
}
GraphicLoadedFlag = true;
fclose(fp);
delete Buffer;
Status = true;
return Status;
}
 
 

Re:Decoding PCX image

Try forcing the file to be opened in binary mode:
if ((fp = fopen( GraphicFileName.c_str(), "rb" )) == NULL)
^
Also, when checking for file type, remember, the opposite of
A && B && C && D is !A || !B || !C || !D
So, if you want to guarantee
pcx.Identifier == 0x0A && pcx.BitsPerPixel == 0x01 &&
pcx.NumBitPlanes == 0x01 && pcx.PaletteType == 1
you should use:
// Check for Error
if((pcx.Identifier != 0x0A) || (pcx.BitsPerPixel != 0x01) ||
(pcx.NumBitPlanes != 0x01) || (pcx.PaletteType != 1))
(The way you're currently checking, you'll mistakenly
try to work with an 8 bits per pixel, 0 pallete type file
as if it were a monochrome one.)
Regards
Eudy
 

Re:Decoding PCX image

Eudy Silva <eudy@.com.br>wrote:
Quote
Try forcing the file to be opened in binary mode:
if ((fp = fopen( GraphicFileName.c_str(), "rb" )) == NULL)
^

Also, when checking for file type, remember, the opposite of
A && B && C && D is !A || !B || !C || !D

So, if you want to guarantee
pcx.Identifier == 0x0A && pcx.BitsPerPixel == 0x01 &&
pcx.NumBitPlanes == 0x01 && pcx.PaletteType == 1

you should use:
// Check for Error
if((pcx.Identifier != 0x0A) || (pcx.BitsPerPixel != 0x01) ||
(pcx.NumBitPlanes != 0x01) || (pcx.PaletteType != 1))

(The way you're currently checking, you'll mistakenly
try to work with an 8 bits per pixel, 0 pallete type file
as if it were a monochrome one.)

Regards

Eudy
WOOOHOOOOOO!!!!! Thanks Eudy. That works. I did realize that you have to open the file in binary mode. Stupid me.
 

{smallsort}

Re:Decoding PCX image

Quote
WOOOHOOOOOO!!!!! Thanks Eudy. That works. I did realize that you have to open the file in binary mode. Stupid me.
Ooopss. I mean I didn't realize that I have to open the file in binary mode.
Thanks again. I would never think about that.