home *** CD-ROM | disk | FTP | other *** search
-
- // gfxpcx.cpp
- //
- // Copyright (c) 1995 by Toshiaki Tsuji, all rights reserved.
-
- #include "stdgfx.h"
- #include "gfxpcx.h"
-
- PCXFILETOOL::PCXFILETOOL ( FILEHANDLE f ) : IMAGEFILETOOL ( f )
- {
- DataBuffer = NULL;
- } // End of Constructor for PCXFILETOOL
-
- PCXFILETOOL::~PCXFILETOOL ()
- {
- if (DataBuffer!=NULL)
- delete DataBuffer;
- DataBuffer = NULL;
- } // End of Destructor for PCXFILETOOL
-
- BOOLEAN PCXFILETOOL::ReadHeader ()
- {
- BOOLEAN Ok;
-
- File.Seek ( fp, 0, FROM_BEGIN );
-
- Ok = File.Read ( fp, &PCXHeader, 128 );
- if (!Ok)
- return FAILURE;
-
- // Check for valid PCX
- if (PCXHeader.ID!=0x0A)
- return FALSE;
-
- #if defined (__MSBFIRST__)
- SwapWord ( (WORD*)&(PCXHeader.XMin) );
- SwapWord ( (WORD*)&(PCXHeader.YMin) );
- SwapWord ( (WORD*)&(PCXHeader.XMax) );
- SwapWord ( (WORD*)&(PCXHeader.YMax) );
- SwapWord ( (WORD*)&(PCXHeader.XResolution) );
- SwapWord ( (WORD*)&(PCXHeader.YResolution) );
- SwapWord ( (WORD*)&(PCXHeader.BytesPerRow) );
- SwapWord ( (WORD*)&(PCXHeader.PalType) );
- SwapWord ( (WORD*)&(PCXHeader.XScreen) );
- SwapWord ( (WORD*)&(PCXHeader.YScreen) );
- #endif
-
- return TRUE;
- } // End of ReadHeader for PCXFILETOOL
-
- BOOLEAN PCXFILETOOL::ReadImageRow2 ( IMAGE *Image, INT Row )
- {
- INT Count;
- INT RepCount;
- INT Ch;
- INT i;
- BYTE *Buffer;
- INT Size;
-
- Size = PCXHeader.BytesPerRow;
- Count = 0;
- Buffer = Image->SetOffset ( 0, Row );
-
- while (Count<Size)
- {
- Ch = File.GetCh ( fp );
- if (Ch==EOF)
- return FAILURE;
- if (Ch<192)
- RepCount = 1;
- else
- {
- RepCount = Ch - 192;
- Ch = File.GetCh ( fp );
- if (Ch==EOF)
- return FAILURE;
- } // End else
- for (i=0;i<RepCount;i++)
- {
- DataBuffer[Count] = (BYTE)Ch;
- Count++;
- } // End for
- } // End while
-
- INT Bit1;
- INT Off1;
- INT Mask;
- INT Byte;
-
- Off1 = 0;
-
- Mask = (LONG)1<<7;
- for (i=0;i<Image->GetWidth();i++)
- {
- Bit1 = (DataBuffer[Off1+(i)/8]&Mask)&&1;
- Byte = (Bit1<<0);
- Buffer[i] = (BYTE)Byte;
-
- if (Mask==1)
- Mask = (LONG)1<<7;
- else
- Mask >>= 1;
- } // End for
-
- return SUCCESS;
- } // End of ReadImageRow2 for PCXFILETOOL
-
- BOOLEAN PCXFILETOOL::ReadImageRow4 ( IMAGE *Image, INT Row )
- {
- INT Count;
- INT RepCount;
- INT Ch;
- INT i;
- BYTE *Buffer;
- INT Size;
-
- Size = PCXHeader.BytesPerRow*2;
- Count = 0;
- Buffer = Image->SetOffset ( 0, Row );
-
- while (Count<Size)
- {
- Ch = File.GetCh ( fp );
- if (Ch==EOF)
- return FAILURE;
- if (Ch<192)
- RepCount = 1;
- else
- {
- RepCount = Ch - 192;
- Ch = File.GetCh ( fp );
- if (Ch==EOF)
- return FAILURE;
- } // End else
- for (i=0;i<RepCount;i++)
- {
- DataBuffer[Count] = (BYTE)Ch;
- Count++;
- } // End for
- } // End while
-
- INT Bit1,Bit2;
- INT Off1,Off2;
- INT Mask;
- INT Byte;
-
- Off1 = 0;
- Off2 = PCXHeader.BytesPerRow;
-
- Mask = (LONG)1<<7;
- for (i=0;i<Image->GetWidth();i++)
- {
- Bit1 = (DataBuffer[Off1+(i)/8]&Mask)&&1;
- Bit2 = (DataBuffer[Off2+(i)/8]&Mask)&&1;
- Byte = (Bit1<<0)+(Bit2<<1);
- Buffer[i] = (BYTE)Byte;
-
- if (Mask==1)
- Mask = (LONG)1<<7;
- else
- Mask >>= 1;
- } // End for
-
- return SUCCESS;
- } // End of ReadImageRow4 for PCXFILETOOL
-
- BOOLEAN PCXFILETOOL::ReadImageRow16 ( IMAGE *Image, INT Row )
- {
- INT Count;
- INT RepCount;
- INT Ch;
- INT i;
- BYTE *Buffer;
- INT Size;
-
- Size = PCXHeader.BytesPerRow*4;
- Count = 0;
- Buffer = Image->SetOffset ( 0, Row );
-
- while (Count<Size)
- {
- Ch = File.GetCh ( fp );
- if (Ch==EOF)
- return FAILURE;
- if (Ch<192)
- RepCount = 1;
- else
- {
- RepCount = Ch - 192;
- Ch = File.GetCh ( fp );
- if (Ch==EOF)
- return FAILURE;
- } // End else
- for (i=0;i<RepCount;i++)
- {
- DataBuffer[Count] = (BYTE)Ch;
- Count++;
- } // End for
- } // End while
-
- INT Bit1,Bit2,Bit3,Bit4;
- INT Off1,Off2,Off3,Off4;
- INT Mask;
- INT Byte;
-
- Off1 = 0;
- Off2 = PCXHeader.BytesPerRow;
- Off3 = PCXHeader.BytesPerRow*2;
- Off4 = PCXHeader.BytesPerRow*3;
-
- Mask = (LONG)1<<7;
- for (i=0;i<Image->GetWidth();i++)
- {
- Bit1 = (DataBuffer[Off1+(i)/8]&Mask)&&1;
- Bit2 = (DataBuffer[Off2+(i)/8]&Mask)&&1;
- Bit3 = (DataBuffer[Off3+(i)/8]&Mask)&&1;
- Bit4 = (DataBuffer[Off4+(i)/8]&Mask)&&1;
- Byte = (Bit1<<0)+(Bit2<<1)+(Bit3<<2)+(Bit4<<3);
- Buffer[i] = (BYTE)Byte;
-
- if (Mask==1)
- Mask = (LONG)1<<7;
- else
- Mask >>= 1;
- } // End for
-
- return SUCCESS;
- } // End of ReadImageRow16 for PCXFILETOOL
-
- BOOLEAN PCXFILETOOL::ReadImageRow256 ( IMAGE *Image, INT Row )
- {
- INT Count;
- INT RepCount;
- INT Ch;
- INT i;
- BYTE *Buffer;
-
- Count = 0;
- Buffer = Image->SetOffset ( 0, Row );
-
- while (Count<PCXHeader.BytesPerRow)
- {
- Ch = File.GetCh ( fp );
- if (Ch==EOF)
- return FAILURE;
- if (Ch<192)
- RepCount = 1;
- else
- {
- RepCount = Ch - 192;
- Ch = File.GetCh ( fp );
- if (Ch==EOF)
- return FAILURE;
- } // End else
- if (Count<Image->GetWidth())
- {
- for (i=0;i<RepCount;i++)
- {
- Buffer[Count] = (BYTE)Ch;
- Count++;
- } // End for
- } // End for
- else
- {
- for (i=0;i<RepCount;i++)
- {
- Count++;
- } // End for
- } // End for
- } // End while
-
- return SUCCESS;
- } // End of ReadImageRow256 for PCXFILETOOL
-
- BOOLEAN PCXFILETOOL::ReadImage ( IMAGE *Image)
- {
- INT i;
- BOOLEAN Ok;
-
- File.Seek ( fp, 128, FROM_BEGIN );
-
- DataBuffer = NULL;
- DataBuffer = new BYTE[(PCXHeader.BytesPerRow+1)*PCXHeader.NumPlanes];
-
- for (i=0;i<Image->GetHeight();i++)
- {
- if (PCXHeader.BitsPerPixel==8)
- Ok = ReadImageRow256 ( Image, i );
- else if (PCXHeader.NumPlanes==4)
- Ok = ReadImageRow16 ( Image, i );
- else if (PCXHeader.NumPlanes==2)
- Ok = ReadImageRow4 ( Image, i );
- else if (PCXHeader.NumPlanes==1)
- Ok = ReadImageRow2 ( Image, i );
- if (!Ok)
- return FAILURE;
- } // End for
-
- if (DataBuffer!=NULL)
- delete DataBuffer;
- DataBuffer = NULL;
-
- return SUCCESS;
- } // End of ReadImage for PCXFILETOOL
-
- BOOLEAN PCXFILETOOL::ReadPalette ( RGBPALETTE *Pal )
- {
- INT i;
- if (Pal==NULL)
- return SUCCESS;
-
- RGBCOLOR *Entry;
-
- Entry = Pal->GetEntry ();
-
- if (PCXHeader.BitsPerPixel>=8)
- {
- File.Seek ( fp, -768, FROM_END );
- for (i=0;i<256;i++)
- {
- Entry[i].Red = (BYTE)File.GetCh ( fp );
- Entry[i].Green = (BYTE)File.GetCh ( fp );
- Entry[i].Blue = (BYTE)File.GetCh ( fp );
- } // End for
- } // End if
- else
- {
- for (i=0;i<16;i++)
- {
- Entry[i].Red = (BYTE)PCXHeader.Palette[i].Red;
- Entry[i].Red = (BYTE)PCXHeader.Palette[i].Green;
- Entry[i].Red = (BYTE)PCXHeader.Palette[i].Blue;
- } // End for
- } // End else
-
- return SUCCESS;
- } // End of ReadPalette for PCXFILETOOL
-
- BOOLEAN PCXFILETOOL::LoadImage ( IMAGE *Image, RGBPALETTE *Pal )
- {
- BOOLEAN Ok;
-
- if (Image==NULL)
- return FAILURE;
-
- Ok = ReadHeader ();
- if (!Ok)
- return FAILURE;
-
- INT Wd,Ht;
-
- Wd = PCXHeader.XMax - PCXHeader.XMin + 1;
- Ht = PCXHeader.YMax - PCXHeader.YMin + 1;
-
- Ok = Image->Create ( IMAGE_8BIT, Wd, Ht );
- if (!Ok)
- return FAILURE;
-
- Ok = ReadImage ( Image );
- if (!Ok)
- return FAILURE;
-
- Ok = ReadPalette ( Pal );
- if (!Ok)
- return FAILURE;
-
- return SUCCESS;
- } // End of LoadImage for PCXFILETOOL
-
- BOOLEAN PCXFILETOOL::WriteHeader ( INT Wd, INT Ht )
- {
- PCXHeader.ID = 0x0A;
- PCXHeader.Version = 5;
- PCXHeader.Encoding = 1;
- PCXHeader.BitsPerPixel = 8;
- PCXHeader.XMin = 0;
- PCXHeader.YMin = 0;
- PCXHeader.XMax = (SHORT)(Wd-1);
- PCXHeader.YMax = (SHORT)(Ht-1);
- PCXHeader.XResolution = 0;
- PCXHeader.YResolution = 0;
- PCXHeader.Reserved = 0;
- PCXHeader.NumPlanes = 1;
- if (Wd&0x01)
- PCXHeader.BytesPerRow = (SHORT)(Wd+1);
- else
- PCXHeader.BytesPerRow = (SHORT)(Wd);
-
- PCXHeader.PalType = 1;
- PCXHeader.XScreen = 0;
- PCXHeader.YScreen = 0;
-
- #if defined (__MSBFIRST__)
- SwapWord ( (WORD*)&(PCXHeader.XMin) );
- SwapWord ( (WORD*)&(PCXHeader.YMin) );
- SwapWord ( (WORD*)&(PCXHeader.XMax) );
- SwapWord ( (WORD*)&(PCXHeader.YMax) );
- SwapWord ( (WORD*)&(PCXHeader.XResolution) );
- SwapWord ( (WORD*)&(PCXHeader.YResolution) );
- SwapWord ( (WORD*)&(PCXHeader.BytesPerRow) );
- SwapWord ( (WORD*)&(PCXHeader.PalType) );
- SwapWord ( (WORD*)&(PCXHeader.XScreen) );
- SwapWord ( (WORD*)&(PCXHeader.YScreen) );
- #endif
-
- BOOLEAN Ok;
-
- File.Seek ( fp, 0, FROM_BEGIN );
- Ok = File.Write ( fp, &PCXHeader, 128 );
- if (!Ok)
- return FAILURE;
- return SUCCESS;
- } // End of WriteHeader for PCXGILETOOL
-
- BOOLEAN PCXFILETOOL::WriteImageRow256 ( IMAGE *Image, INT Sx, INT Wd, INT WhichRow )
- {
- BYTE *Buffer;
- INT Ch;
- INT Count;
- INT RepCount;
- INT Size;
-
- Size = Wd;
- Buffer = Image->SetOffset ( Sx, WhichRow );
- Count = 0;
-
- while (Count<Size)
- {
- RepCount = 1;
- Ch = Buffer[Count];
- Count++;
- while ((Ch==Buffer[Count])&&(RepCount<63)&&(Count<Size))
- {
- Count++;
- RepCount++;
- } // End if
- if ((Ch<192)&&(RepCount==1))
- {
- File.PutCh ( fp, (CHAR)Ch );
- } // End if
- else
- {
- RepCount += 192;
- File.PutCh ( fp, (CHAR)RepCount );
- File.PutCh ( fp, (CHAR)Ch );
- } // End if
- } // End while
-
- if (Wd<PCXHeader.BytesPerRow)
- File.PutCh ( fp, 0 );
-
- return SUCCESS;
- } // End of WriteImageRow256 for PCXFILETOOL
-
- BOOLEAN PCXFILETOOL::WriteImage ( IMAGE *Image, INT Sx, INT Sy, INT Wd, INT Ht )
- {
- INT i;
- BOOLEAN Ok;
-
- for (i=0;i<Ht;i++)
- {
- Ok = WriteImageRow256 ( Image, Sx, Wd, Sy+i );
- if (!Ok)
- return FAILURE;
- } // End for
- return SUCCESS;
- } // End of WriteImage for PCXFILETOOL
-
- BOOLEAN PCXFILETOOL::WritePalette ( RGBPALETTE *Pal )
- {
- RGBCOLOR *Entry;
-
- File.PutCh ( fp, 0x0C );
-
- if (Pal==NULL)
- {
- return FAILURE;
- } // End if
- else
- {
- Entry = Pal->GetEntry ();
-
- INT i;
- for (i=0;i<256;i++)
- {
- File.PutCh ( fp, Entry[i].Red );
- File.PutCh ( fp, Entry[i].Green );
- File.PutCh ( fp, Entry[i].Blue );
- } // End for
- } // End else
- return SUCCESS;
- } // End of WritePalette for PCXGILETOOL
-
- BOOLEAN PCXFILETOOL::SaveImage ( IMAGE *Image, LONG Sx, LONG Sy,
- LONG Wd, LONG Ht, RGBPALETTE *Pal )
- {
- if (Image==NULL)
- {
- return FAILURE;
- } // End if
-
- BOOLEAN Ok;
-
- Ok = WriteHeader ( Wd, Ht );
- if (!Ok)
- return FAILURE;
-
- Ok = WriteImage ( Image, Sx, Sy, Wd, Ht );
- if (!Ok)
- return FAILURE;
-
- Ok = WritePalette ( Pal );
- if (!Ok)
- return FAILURE;
-
- return SUCCESS;
- } // End of SaveImage for PCXFILETOOL
-
-