BasePMFilter Class Reference

Provides most of the the handling for the PPM, PGM and PBM filters. More...

#include <ppmfiltr.h>

Inheritance diagram for BasePMFilter:

BaseBitmapFilter BitmapFilter Filter ListItem CCObject SimpleCCObject PBMFilter PGMFilter PPMFilter List of all members.

Public Member Functions

 BasePMFilter ()
 Constructor for an BasePMFilter object. The object should be initialised before use.
BOOL Init ()
 Initialise an BasePMFilter object.
virtual INT32 HowCompatible (PathName &Filename, ADDR HeaderStart, UINT32 HeaderSize, UINT32 FileSize)
 Determine if this filter can load the specified file.
virtual BOOL ReadFromFile (OILBitmap *pOilBitmap)
 Determine if this filter can load the specified file.Actually does the process of reading a bitmap from a file. Inherited classes override this to read in different file formats.
virtual BOOL IsThisBppOk (UINT32 Bpp)
 Check if this Bitmap filter can cope with saving at this Bpp/Colour depth.

Protected Member Functions

BOOL ReadFromFile (CCLexFile *File, LPBITMAPINFO *Info, LPBYTE *Bits, String_64 *ProgressString=NULL)
 Reads a ppm, pgm or pbm file into memory decompressing it as it goes. Errors on 16-bit builds*** A progress hourglass can be shown if required.
BOOL ReadASCIIFromFile (CCLexFile *pLexFile, LPBYTE pBits, INT32 Width, INT32 Height, INT32 ColoursPerRGB, INT32 BitsPerRGB, INT32 WidthOfLine, String_64 *ProgressString=NULL, BOOL Forwards=TRUE)
 Reads a bitmap data for the ppm, pgm or pbm file into memory. Assumes data is in ascii format. A progress hourglass can be shown if required.
BOOL ReadBinaryFromFile (CCLexFile *pFile, LPBYTE pBits, INT32 Width, INT32 Height, INT32 ColoursPerRGB, INT32 BitsPerRGB, INT32 WidthOfLine, String_64 *ProgressString=NULL, BOOL Forwards=TRUE)
 Reads a bitmap data for the ppm, pgm or pbm file into memory. Assumes data is in binary format. A progress hourglass can be shown if required.
void PokePaletteEntry (LPRGBQUAD *Palette, BYTE red, BYTE green, BYTE blue)
 Puts the required value of rgb into the specified palette entry.
void MakeGreyScalePalette (LPRGBQUAD Palette)
 Makes up a greyscale palette for the specified palette.
void Make16GreyScalePalette (LPRGBQUAD Palette)
 Makes up a greyscale palette for the specified palette.
void MakeBlackAndWhitePalette (LPRGBQUAD Palette)
 Corrects the first two palette entries to be a correct Gavin black and white palette.
virtual BOOL CheckString (TCHAR *pHeader)
 To see if the header of a PBM file is correct or not. Baseclass version so should not be used.
virtual BOOL ReadDataIntoBitmap (INT32 Number, INT32 *Count, LPBYTE *pData, BOOL *NextPixel)
 Place the number read in into the specified place in the bitmap. Baseclass version, should not be called.

Protected Attributes

PMFileType TypeOfPPM
INT32 PPMHowCompatible
INT32 x
INT32 y
INT32 TotalWidth
INT32 TotalHeight
INT32 TotalWidthOfLine
INT32 RGBColours
INT32 RGBBits
INT32 PixelCounter
INT32 Red
INT32 Green
INT32 Blue
BYTE Bits

Private Member Functions

 CC_DECLARE_DYNAMIC (BasePMFilter)

Detailed Description

Provides most of the the handling for the PPM, PGM and PBM filters.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95

Definition at line 133 of file ppmfiltr.h.


Constructor & Destructor Documentation

BasePMFilter::BasePMFilter  ) 
 

Constructor for an BasePMFilter object. The object should be initialised before use.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
See also:
BasePMFilter::Init

Definition at line 497 of file ppmfiltr.cpp.

00497                            : BaseBitmapFilter()
00498 {
00499     // Make ourselves look like a PPM filter, even though we shouldn't be seen
00500     ImportMsgID = _R(IDN_IMPORTMSG_PPM);
00501     Flags.CanImport = FALSE;
00502     Flags.CanExport = FALSE;
00503     FilterID = FILTERID_PPM;
00504 
00505     ExportRegion = NULL;
00506     ExportMsgID = _R(IDN_EXPORTMSG_PPM);            // "Preparing PPM file..."
00507 
00508     ExportingMsgID = _R(IDN_EXPORTINGMSG_PPM);      // "Exporting PPM file..."
00509 
00510 //  CurrentSelection = DRAWING;
00511 }


Member Function Documentation

BasePMFilter::CC_DECLARE_DYNAMIC BasePMFilter   )  [private]
 

BOOL BasePMFilter::CheckString TCHAR pHeader  )  [protected, virtual]
 

To see if the header of a PBM file is correct or not. Baseclass version so should not be used.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
Returns:
TRUE if the filter reckonises the string, FALSE otherwise.
See also:
BasePMFilter::HowCompatible;

Reimplemented in PPMFilter, PGMFilter, and PBMFilter.

Definition at line 556 of file ppmfiltr.cpp.

00557 {
00558     ERROR2(FALSE,"BasePMFilter::ReadDataIntoBitmap calling baseclass version!");
00559     return FALSE;
00560 }

INT32 BasePMFilter::HowCompatible PathName Filename,
ADDR  HeaderStart,
UINT32  HeaderSize,
UINT32  FileSize
[virtual]
 

Determine if this filter can load the specified file.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
Parameters:
Filename - name of the file. [INPUTS] HeaderStart - Address of the first few bytes of the file. HeaderSize - the number of bytes in the header pointed to by FileStart. FileSize - the size of the whole file, in bytes.
Returns:
0 => Not a PPM file. 10 => It is a PPM file.

Reimplemented from Filter.

Definition at line 581 of file ppmfiltr.cpp.

00583 {
00584 TRACEUSER( "Neville", _T("BasePMFilter::HowCompatible"));   
00585     // We need to remember what we thought of this file in our class variable.
00586     // So, set it to a nice default value at the start.
00587     PPMHowCompatible = 0;
00588 
00589     // Check that we've got enough data to do our check
00590     if (HeaderSize < 4)
00591     {
00592         // Not enough data - ignore this file.
00593         return 0;
00594     }
00595 
00596     // copy four chars in to make TCHARs
00597     TCHAR pHeader[4];
00598     INT32 i;
00599     for (i=0; i<4 ; i++)
00600         pHeader[i]=(TCHAR)(((char *) HeaderStart)[i]);
00601 
00602     if ( CheckString(pHeader) )
00603     {
00604         // finding PPM, PGM or PBM should be good enough to determine that there is
00605         // a high chance that this is the right file.
00606 
00607         // Remember what we thought in our class variable.
00608         PPMHowCompatible = 10;
00609     }
00610     else
00611     {
00612         // No PPM signature - we don't want this file.
00613         PPMHowCompatible = 0;
00614     }
00615                 
00616 TRACEUSER( "Neville", _T("BasePMFilter::HowCompatible returning = %d\n"),PPMHowCompatible);
00617     // Return the found value to the caller.
00618     return PPMHowCompatible;
00619 }

BOOL BasePMFilter::Init void   )  [virtual]
 

Initialise an BasePMFilter object.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
Returns:
TRUE if the filter was initialised ok, FALSE otherwise.

Errors: Will fail if not enough memory to initialise.

See also:
EPSStack

Reimplemented from BaseBitmapFilter.

Reimplemented in PPMFilter, PGMFilter, and PBMFilter.

Definition at line 526 of file ppmfiltr.cpp.

00527 {
00528     // Make ourselves look like a PPM filter, even though we shouldn't be seen
00529 
00530     // Get the OILFilter object
00531     pOILFilter = new PPMOILFilter(this);
00532     if (pOILFilter==NULL)
00533         return FALSE;
00534 
00535     // Load the description strings
00536     FilterName.Load(_R(IDN_PPM_FILTERNAME));
00537     FilterInfo.Load(_R(IDN_PPM_FILTERINFO));
00538 
00539     // All ok
00540     return TRUE;
00541 }

BOOL BasePMFilter::IsThisBppOk UINT32  Bpp  )  [virtual]
 

Check if this Bitmap filter can cope with saving at this Bpp/Colour depth.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
Parameters:
Bpp or Colour depth. [INPUTS]
Returns:
TRUE if this filter can cope with this colour depth, FALSE otherwise.
See also:
OpMenuExport::DoWithParam;

Reimplemented from BaseBitmapFilter.

Definition at line 1828 of file ppmfiltr.cpp.

01829 {
01830     return (Bpp == 1 || Bpp == 4 || Bpp == 8 || Bpp == 24);
01831 }

void BasePMFilter::Make16GreyScalePalette LPRGBQUAD  Palette  )  [protected]
 

Makes up a greyscale palette for the specified palette.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
Parameters:
Palette palette to write to. [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 1202 of file ppmfiltr.cpp.

01203 {
01204     if (Palette)
01205     {
01206         INT32 Value = 0;
01207         LPRGBQUAD Pal = Palette;
01208 
01209         // Poke a greyscale palette into the specified palette
01210         for (INT32 i = 0; i < 16 ; i++)
01211         {
01212             Value = (i * 256)/16;       
01213             PokePaletteEntry(&Pal, Value, Value, Value);
01214         }
01215     }
01216 }   

void BasePMFilter::MakeBlackAndWhitePalette LPRGBQUAD  Palette  )  [protected]
 

Corrects the first two palette entries to be a correct Gavin black and white palette.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
Parameters:
Palette palette to write to. [INPUTS]
- [OUTPUTS]
Returns:
-
See also:
OutputDIB::StartFile; OutputDIB::StartExport;

Definition at line 1232 of file ppmfiltr.cpp.

01233 {
01234     if (Palette)
01235     {
01236         LPRGBQUAD Pal = Palette;
01237 
01238         PokePaletteEntry(&Pal, 0xff, 0xff, 0xff);
01239         PokePaletteEntry(&Pal, 0x00, 0x00, 0x00);
01240     }
01241 }   

void BasePMFilter::MakeGreyScalePalette LPRGBQUAD  Palette  )  [protected]
 

Makes up a greyscale palette for the specified palette.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
Parameters:
Palette palette to write to. [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 1176 of file ppmfiltr.cpp.

01177 {
01178     if (Palette)
01179     {
01180         LPRGBQUAD Pal = Palette;
01181          
01182         // Poke a greyscale palette into the specified palette
01183         for (INT32 i = 0; i < 256 ; i++)
01184         {
01185             PokePaletteEntry(&Pal, i, i, i);
01186         }
01187     }
01188 }   

void BasePMFilter::PokePaletteEntry LPRGBQUAD Palette,
BYTE  red,
BYTE  green,
BYTE  blue
[protected]
 

Puts the required value of rgb into the specified palette entry.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
Parameters:
Palette palette to write to. [INPUTS] red red value to enter into palette entry green green value to enter into palette entry blue blue value to enter into palette entry
index incremented by one [OUTPUTS]
Returns:
-
See also:
BasePMFilter::MakeGreyScalePalette;

BasePMFilter::MakeBlackAndWhitePalette;

Definition at line 1152 of file ppmfiltr.cpp.

01153 {
01154     if (Palette && (*Palette))
01155     {
01156         (*Palette)->rgbRed = red;   
01157         (*Palette)->rgbGreen = green;   
01158         (*Palette)->rgbBlue = blue; 
01159         // increment the counter and return it
01160         (*Palette) ++;  
01161     }
01162 }   

BOOL BasePMFilter::ReadASCIIFromFile CCLexFile pLexFile,
LPBYTE  pBits,
INT32  Width,
INT32  Height,
INT32  ColoursPerRGB,
INT32  BitsPerRGB,
INT32  WidthOfLine,
String_64 ProgressString = NULL,
BOOL  Forwards = TRUE
[protected]
 

Reads a bitmap data for the ppm, pgm or pbm file into memory. Assumes data is in ascii format. A progress hourglass can be shown if required.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
Parameters:
pLexFile An opened CCLexFile that can be read from, already set up to [INPUTS] be lexed and at the position to read in the first item of ascii data defining the bitmap bits. pBits Pointer to where to put the bytes of data Width Read in width of the bitmap Height Read in height of the bitmap (together define size of data to read in) ColoursPerRGB Read in number of colours per RGB component BitsPerRGB Calculated number of bits per RGB component WidthOfLine Is the actual rounded width of the line in pixels ProgressString Allows the user to specify whether they require a progress hourglass or not. If NULL then none is shown, otherwise an progress bar is shown using the text supplied. Defaults to NULL i.e. no progress bar. Forwards True if want data placed in bitmap top to bottom, otherwise put it in from bottom to top.
Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)

Errors: Calls SetError on FALSE returns. Scope: Static, Public

See also:
BasePMFilter::ReadFromFile;

Definition at line 1278 of file ppmfiltr.cpp.

01282 {
01283     ERROR2IF(pLexFile == NULL,FALSE,"PPMFilter::ReadASCIIFromFile bad file pointer");
01284     ERROR2IF(pBits == NULL,FALSE,"PPMFilter::ReadASCIIFromFile bad bitmap data pointer");
01285     ERROR2IF(Width == 0,FALSE,"PPMFilter::ReadASCIIFromFile bad Width");
01286     ERROR2IF(Height == 0,FALSE,"PPMFilter::ReadASCIIFromFile bad Height");
01287     ERROR2IF(ColoursPerRGB == 0,FALSE,"PPMFilter::ReadASCIIFromFile bad ColoursPerRGB");
01288     ERROR2IF(BitsPerRGB == 0,FALSE,"PPMFilter::ReadASCIIFromFile bad BitsPerRGB");
01289 
01290     // read in the rest of the header data
01291     BOOL finished = FALSE;
01292     BOOL ok = TRUE; 
01293 
01294     // Token buffer remains constant until lexer deinitialisation
01295     const TCHAR* TokenBuf = pLexFile->GetTokenBuf();
01296     PpmTokenIndex Token;
01297 
01298     // number of bits already written to byte (only relevant for <8bpp images)
01299     INT32 Count     = 0;
01300 
01301     Red         = 0;
01302     Green       = 0;
01303     Blue        = 0;
01304     Bits        = 0;
01305 
01306     x           = 0;
01307     // (ChrisG 24/01/01) start at the last line if we're going backwards, otherwise start 
01308     //  at the beginning.
01309     if (Forwards)
01310         y = 0;
01311     else
01312         y = Height - 1;
01313 
01314     TotalWidth          = Width;
01315     TotalHeight         = Height;
01316     TotalWidthOfLine    = WidthOfLine;
01317     RGBColours          = ColoursPerRGB;
01318     RGBBits             = BitsPerRGB;
01319 
01320     INT32 Number    = 0; 
01321 
01322     LPBYTE pData;
01323 //  BYTE value  = 0;
01324 
01325     BOOL NextPixel = TRUE;
01326 
01327     // (ChrisG 24/01/01) Start at the beginning if going forwards, or the end if going 
01328     //  backwards, 
01329     if (Forwards)
01330         pData = pBits;
01331     else
01332         pData = pBits + (y * WidthOfLine);
01333 
01334     while (ok && !finished)
01335     {
01336         // Grab a token
01337         ok = pLexFile->GetSimpleToken();
01338 
01339         LexTokenType TokenType = pLexFile->GetTokenType();
01340 
01341         switch (TokenType)
01342         {
01343             case TOKEN_NORMAL:
01344                 {
01345                     Token = FindToken(TokenBuf);
01346 
01347                     switch (Token)
01348                     {
01349                         case TOKEN_NONE:
01350                             {
01351                                 // Must be one of the header numbers
01352                                 ok = (camSscanf(TokenBuf,_T("%d"),&Number) == 1);
01353 
01354                                 // Call the correct filters function to put the data into the bitmap itself
01355                                 // in its own unique way, so long as we haven't failed already.
01356                                 ok = ok && ReadDataIntoBitmap(Number, &Count, &pData, &NextPixel);
01357 
01358                                 // As a read might be part of a pixel or not, e.g. the R of a 24 bit pixel,
01359                                 // the recipient of the function call is allowed to say when we are at the next pixel
01360                                 if (NextPixel)
01361                                 {
01362                                     // Increment the required byte number, if at end of line
01363                                     // go to the start of the next
01364                                     x++;
01365                                     if (x >= Width)
01366                                     {
01367                                         x = 0;
01368 
01369                                         if (Forwards)
01370                                         {
01371                                             // Increment the current line number, if at end of lines
01372                                             // then we have supposedly read in all the data
01373                                             y++;
01374                                             if (y >= Height)
01375                                                 finished = TRUE;
01376                                             
01377                                             // Update the progress system, if required
01378                                             if (ProgressString != NULL)
01379                                                 ContinueSlowJob((INT32)(100*y/Height));
01380                                         }
01381                                         else                
01382                                         {
01383                                             // Decrement the current line number, if past first line
01384                                             // then we have supposedly read in all the data
01385                                             y--;
01386                                             if (y < 0)
01387                                                 finished = TRUE;
01388                                             
01389                                             // Update the progress system, if required
01390                                             if (ProgressString != NULL)
01391                                                 ContinueSlowJob((INT32)(100*(Height - y)/Height));
01392                                         }
01393 
01394                                         // (ChrisG 24/01/01) if we're halfway through a byte, pad the 
01395                                         //  remainder with zeroes before writing it out.
01396                                         while ((Count != 0) && (ok == TRUE))
01397                                         {
01398                                             ok = ok && ReadDataIntoBitmap(0, &Count, &pData, &NextPixel);
01399                                         }
01400 
01401                                         // realign the data pointer to the line start to 
01402                                         // account for word aligning of line starts.
01403                                         pData = pBits + (y * WidthOfLine);
01404                                     }
01405                                 }
01406                             }
01407                             break;
01408                                                                                                 
01409                         default:
01410                             // Flag a bad token so that we stop parsing this line
01411                             ok = FALSE;
01412                             TRACEUSER( "Neville", _T("PPM: Didn't expect to get this token ('%s')\n"),TokenBuf);
01413                             break;
01414                     }
01415                 }
01416                 break;
01417 
01418             default:
01419                 // bad token so stop parsing this line
01420                 TRACEUSER( "Neville", _T("PPM: Unexpected token - %s\n"),TokenBuf);
01421                 ok = FALSE;
01422                 break;
01423         }
01424     }
01425         
01426     return TRUE;
01427 }   

BOOL BasePMFilter::ReadBinaryFromFile CCLexFile pFile,
LPBYTE  pBits,
INT32  Width,
INT32  Height,
INT32  ColoursPerRGB,
INT32  BitsPerRGB,
INT32  WidthOfLine,
String_64 ProgressString = NULL,
BOOL  Forwards = TRUE
[protected]
 

Reads a bitmap data for the ppm, pgm or pbm file into memory. Assumes data is in binary format. A progress hourglass can be shown if required.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
Parameters:
pFile An opened CCFile that can be read from, already set up to [INPUTS] the position to read in the first item of binary data. pBits Pointer to where to put the bytes of data Width Read in width of the bitmap Height Read in height of the bitmap (together define size of data to read in) ColoursPerRGB Read in number of colours per RGB component BitsPerRGB Calculated number of bits per RGB component WidthOfLine Is the actual rounded width of the line in pixels ProgressString Allows the user to specify whether they require a progress hourglass or not. If NULL then none is shown, otherwise an progress bar is shown using the text supplied. Defaults to NULL i.e. no progress bar. Forwards True if want data placed in bitmap top to bottom, otherwise put it in from bottom to top.
Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)

Errors: Calls SetError on FALSE returns. Scope: Static, Public

See also:
BasePMFilter::ReadFromFile;

Definition at line 1463 of file ppmfiltr.cpp.

01467 {
01468     ERROR2IF(pFile == NULL,FALSE,"PPMFilter::ReadBinaryFromFile bad file pointer");
01469     ERROR2IF(pBits == NULL,FALSE,"PPMFilter::ReadBinaryFromFile bad bitmap data pointer");
01470     ERROR2IF(Width == 0,FALSE,"PPMFilter::ReadBinaryFromFile bad Width");
01471     ERROR2IF(Height == 0,FALSE,"PPMFilter::ReadBinaryFromFile bad Height");
01472     ERROR2IF(ColoursPerRGB == 0,FALSE,"PPMFilter::ReadBinaryFromFile bad ColoursPerRGB");
01473     ERROR2IF(BitsPerRGB == 0,FALSE,"PPMFilter::ReadBinaryFromFile bad BitsPerRGB");
01474 
01475     // read in the rest of the bitmap data
01476     BOOL finished = FALSE;
01477     BOOL ok = TRUE; 
01478 
01479     INT32 Count     = 0;
01480 
01481     Red         = 0;
01482     Green       = 0;
01483     Blue        = 0;
01484     Bits        = 0;
01485 
01486     x           = 0;
01487     y           = 0;
01488     if (!Forwards)
01489         y = Height;
01490 
01491     TotalWidth          = Width;
01492     TotalHeight         = Height;
01493     TotalWidthOfLine    = WidthOfLine;
01494     RGBColours          = ColoursPerRGB;
01495     RGBBits             = BitsPerRGB;
01496             
01497     INT32 Number        = 0; 
01498     TCHAR chr;
01499 
01500     BOOL NextPixel  = TRUE;
01501 
01502     LPBYTE pData    = pBits;
01503 
01504     while (ok && !finished)
01505     {
01506         // Grab a token
01507         pFile->read(&chr);
01508         
01509         Number = (INT32)chr;
01510 
01511         // Call the correct filters function to put the data into the bitmap itself
01512         // in its own unique way
01513         ok = ReadDataIntoBitmap((INT32)Number, &Count, &pData, &NextPixel);
01514 
01515         // As a read might be part of a pixel or not, e.g. the R of a 24 bit pixel,
01516         // the recipient of the function call is allowed to say when we are at the next pixel
01517         if (NextPixel)
01518         {
01519             // Increment the required byte number, if at end of line
01520             // go to the start of the next
01521             x = x + PixelCounter;
01522             if (x >= Width)
01523             {
01524                 x = 0;
01525 
01526                 if (Forwards)
01527                 {
01528                     // Increment the current line number, if at end of lines
01529                     // then we have supposedly read in all the data
01530                     y++;
01531                     if (y >= Height)
01532                         finished = TRUE;
01533                     
01534                     // Update the progress system, if required
01535                     if (ProgressString != NULL)
01536                         ContinueSlowJob((INT32)(100*y/Height));
01537                 }
01538                 else                
01539                 {
01540                     // Decrement the current line number, if at first line
01541                     // then we have supposedly read in all the data
01542                     y--;
01543                     if (y <= 0)
01544                         finished = TRUE;
01545                     
01546                     // Update the progress system, if required
01547                     if (ProgressString != NULL)
01548                         ContinueSlowJob((INT32)(100*(Height - y)/Height));
01549                 }
01550 
01551                 // realign the data pointer to the line start to 
01552                 // account for word aligning of line starts
01553                 pData = pBits + y * WidthOfLine;
01554             }
01555         }
01556     }
01557 
01558     return TRUE;
01559 }   

BOOL BasePMFilter::ReadDataIntoBitmap INT32  Number,
INT32 *  Count,
LPBYTE pData,
BOOL *  NextPixel
[protected, virtual]
 

Place the number read in into the specified place in the bitmap. Baseclass version, should not be called.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
Parameters:
Number value read in; [INPUTS]
Count can be used to distinquish between R, G and B data (can be incremented) [OUTPUTS] pData place to store the data (can be incremented)
Returns:
TRUE if everything went ok, FALSE otherwise.
See also:
BasePMFilter::ReadBinaryFromFile; BasePMFilterReadASCIIFromFile;

Reimplemented in PPMFilter, PGMFilter, and PBMFilter.

Definition at line 1579 of file ppmfiltr.cpp.

01580 {
01581     ERROR2(FALSE,"BasePMFilter::ReadDataIntoBitmap calling baseclass version!");
01582     return FALSE;   
01583 }

BOOL BasePMFilter::ReadFromFile CCLexFile pLexFile,
LPBITMAPINFO Info,
LPBYTE Bits,
String_64 ProgressString = NULL
[protected]
 

Reads a ppm, pgm or pbm file into memory decompressing it as it goes. Errors on 16-bit builds*** A progress hourglass can be shown if required.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
Parameters:
A opened CCFile that can be read from. It should be positioned at the [INPUTS] start. Caller is responsible for closing it. The file needs to be in Binary mode. ProgressString allows the user to specify whether they require a progress hourglass or not. If NULL then none is shown, otherwise an progress bar is shown using the text supplied. Defaults to NULL i.e. no progress bar.
Info points to a new LPBITMAPINFO struct and Bits points to the bytes. [OUTPUTS] These can be freed up with FreeDIB.
Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)

Errors: Calls SetError on FALSE returns. Scope: Public

See also:
BasePMFilter::ReadFromFile; DIBUtil::ReadFromFile; AccusoftFilters::ReadFromFile;

Definition at line 707 of file ppmfiltr.cpp.

00709 {
00710     ERROR2IF(pLexFile == NULL,FALSE,"BasePMFilter::ReadFromFile bad file pointer");
00711     ERROR2IF(Info == NULL,FALSE,"BasePMFilter::ReadFromFile bad bitmap info pointer");
00712     ERROR2IF(Bits == NULL,FALSE,"BasePMFilter::ReadFromFile bad bitmap data pointer");
00713 
00714     *Info = NULL;       // in case of early exit
00715     *Bits = NULL;
00716 
00717     // place to store the global palette, if present, for later use
00718 //  LPRGBQUAD lpGlobalPalette       = NULL; // pointer to temporary palette store
00719 //  INT32 GlobalPaletteSize             = 0;    // size of the global palette found  
00720 /*
00721     // See if we are capable of parsing this, must be at least a LexFile.
00722     // Check for DiskFile as derived off LexFile and required for binary reads
00723     if (!File->IS_KIND_OF(CCDiskFile)) return FALSE;
00724     CCLexFile* pLexFile = (CCLexFile*) File;
00725 */
00726     // Must set the exception throwing flag to True and force reporting of errors to False.
00727     // This means that the caller must report an error if the function returns False.
00728     // Any calls to CCFile::GotError will now throw a file exception and should fall into
00729     // the catch handler at the end of the function.
00730     BOOL OldThrowingState = pLexFile->SetThrowExceptions( TRUE );
00731     BOOL OldReportingState = pLexFile->SetReportErrors( FALSE );
00732 
00733     // If the caller has specified a string then assume they require a progress bar
00734     // Start it up.
00735     if (ProgressString != NULL) BeginSlowJob(100, FALSE, ProgressString);
00736 
00737     try
00738     {
00739         // A ppm file consists of:-
00740         // - A "magic number" for identifying the file type. A ppm file's magic
00741         //   number is the two characters "P3".
00742         //
00743         // - Whitespace (blanks, TABs, CRs, LFs).
00744         //
00745         // - A width, formatted as ASCII characters in decimal.
00746         //
00747         // - Whitespace.
00748         //
00749         // - A height, again in ASCII decimal.
00750         //
00751         // - Whitespace.
00752         //
00753         // - The maximum color-component value, again in ASCII decimal.
00754         //
00755         // - Whitespace.
00756         //
00757         // - Width * height pixels, each three ASCII decimal values  between  0  and
00758         //   the  specified  maximum  value,  starting at the top-left corner of the
00759         //   pixmap, proceeding in normal English reading order.  The  three  values
00760         //   for each pixel represent red, green, and blue, respectively; a value of
00761         //   0 means that color is off, and the maximum value means  that  color  is
00762         //   maxxed out.
00763         //
00764         // - Characters from a "#" to the next end-of-line are ignored (comments).
00765         //
00766         // - No line should be longer than 70 characters.
00767         //
00768         // Here is an example of a small pixmap in this format:
00769         // P3
00770         // # feep.ppm
00771         // 4 4
00772         // 15
00773         //  0  0  0    0  0  0    0  0  0   15  0 15
00774         //  0  0  0    0 15  7    0  0  0    0  0  0
00775         //  0  0  0    0  0  0    0 15  7    0  0  0
00776         // 15  0 15    0  0  0    0  0  0    0  0  0
00777 
00778         // Alternatively, P6 means binary data follow the header
00779         // PGM and PBM are just variations on this theme with different unique numbers and
00780         // the numbers are intepreted differently.
00781         BOOL finished = FALSE;
00782         BOOL ok = TRUE; 
00783 
00784         // Set the type to an illegal state until we recognise the file
00785         TypeOfPPM = PPM_BAD;
00786 
00787         // Initialise lexing routines, and aspects of the lexer
00788         ok = pLexFile->InitLexer();
00789         pLexFile->SetDelimiters("\r\n");            // Set token delimiting characters
00790         pLexFile->SetCommentMarker('#');            // Set comment marker char
00791         pLexFile->SetWhitespace(" \t");         // Set whitespace chars
00792         pLexFile->SetStringDelimiters("\"\"");  // Set string delimiters
00793 
00794         // Token buffer remains constant until lexer deinitialisation
00795         const TCHAR* TokenBuf = pLexFile->GetTokenBuf();
00796         
00797         INT32   Width           = 0;    // Width of bitmap  
00798         INT32 Height            = 0;    // Height of bitmap 
00799         INT32 BitsPerPixel  = 0;    // ColorResolution; // Colour depth required
00800         INT32 BitsPerRGB        = 0;    // Number of bits present per RGB component
00801         INT32 ColoursPerRGB     = 0;    // For PGM number of colours present in the image per RGB component
00802                                     // For PGM will be for number of greyscales
00803                                     // For PBM is not present       
00804         INT32 NumberOfColours = 0;  // Number of colours present, 3 for PPM, 1 for PBM and PGM
00805         INT32 MaxCount      = 3;    // Number of items in the header, usually three
00806     
00807         // default to 1 pixel per number read
00808         PixelCounter = 1;
00809         
00810         // Grab a token
00811         ok = pLexFile->GetSimpleToken();
00812 
00813         // Should be P3 or P6
00814         PpmTokenIndex Token;
00815 
00816         if (ok)
00817         {
00818             // Find out the type of the token
00819             // Look the token up in our table
00820             Token = FindToken(TokenBuf);
00821 
00822             switch (Token)
00823             {
00824                 case TOKEN_PPM_ASCII:
00825                     // Correct file header found so note the type
00826                     TypeOfPPM = PPM_ASCII;
00827                     NumberOfColours = 3;    // RGB
00828                     break;
00829 
00830                 case TOKEN_PPM_BINARY:
00831                     // Correct file header found so note the type
00832                     TypeOfPPM = PPM_BINARY;
00833                     NumberOfColours = 3;   // RGB
00834                     break;
00835 
00836                 case TOKEN_PGM_ASCII:
00837                     // Correct file header found so note the type
00838                     TypeOfPPM = PGM_ASCII;
00839                     NumberOfColours = 1;   // greyscale
00840                     break;
00841 
00842                 case TOKEN_PGM_BINARY:
00843                     // Correct file header found so note the type
00844                     TypeOfPPM = PGM_BINARY;
00845                     NumberOfColours = 1;   // greyscale
00846                     break;
00847 
00848                 case TOKEN_PBM_ASCII:
00849                     // Correct file header found so note the type
00850                     TypeOfPPM = PBM_ASCII;
00851                     MaxCount = 2;
00852                     ColoursPerRGB = 1;
00853                     NumberOfColours = 1;   // B & W
00854                     break;
00855 
00856                 case TOKEN_PBM_BINARY:
00857                     // Correct file header found so note the type
00858                     TypeOfPPM = PBM_BINARY;
00859                     MaxCount = 2;
00860                     ColoursPerRGB = 1;
00861                     NumberOfColours = 1;   // B & W
00862                     // if in binary mode we get 8 pixels per number read
00863                     PixelCounter = 8;
00864                     break;
00865 
00866                 default:
00867                     TRACEUSER( "Neville", _T("BasePMFilter: Unexpected token - %s\n"),TokenBuf);
00868                     ok = FALSE;
00869                     break;
00870             }
00871         }
00872         else
00873             pLexFile->GotError( _R(IDE_BADFORMAT) );
00874 
00875         // read in the rest of the header data
00876 
00877         INT32 Count = 0;
00878         
00879         while (ok && !finished && Count < MaxCount)
00880         {
00881             // Grab a token
00882             ok = pLexFile->GetSimpleToken();
00883 
00884             //if (!ok)
00885             //  File->GotError( _R(IDE_BADFORMAT) );
00886 
00887             LexTokenType TokenType = pLexFile->GetTokenType();
00888 
00889             switch (TokenType)
00890             {
00891                 case TOKEN_NORMAL:
00892                     {
00893                         Token = FindToken(TokenBuf);
00894                         switch (Token)
00895                         {
00896                             case TOKEN_NONE:
00897                                 {
00898                                     // Must be one of the header numbers
00899                                     INT32 Number; 
00900                                     ok = (camSscanf(TokenBuf,_T("%d"),&Number) == 1);
00901 
00902                                     // Now work out what to do with this
00903                                     switch (Count)
00904                                     {
00905                                         case 0:
00906                                             Width = Number;
00907                                             break;
00908 
00909                                         case 1:
00910                                             Height = Number;
00911                                             break;
00912 
00913                                         case 2:
00914                                             ColoursPerRGB = Number;
00915                                             break;
00916 
00917                                         default:
00918                                             // Flag a bad token so that we stop parsing this line
00919                                             ok = FALSE;
00920                                             TRACEUSER( "Neville", _T("BasePMFilter: Didn't expect to get this number ('%s')\n"), TokenBuf);
00921                                             break;
00922                                     }
00923                                     
00924                                     // Increment our count and see if we have enough info yet
00925                                     Count++;
00926                                     if (Count == MaxCount)
00927                                         finished = TRUE;
00928                                 }
00929                                 break;
00930                                                                                                     
00931                             default:
00932                                 // Flag a bad token so that we stop parsing this line
00933                                 ok = FALSE;
00934                                 TRACEUSER( "Neville", _T("BasePMFilter: Didn't expect to get this token ('%s')\n"),TokenBuf);
00935                                 break;
00936                         }
00937                     }
00938                     break;
00939 
00940                 default:
00941                     // bad token so stop parsing this line
00942                     TRACEUSER( "Neville", _T("BasePMFilter: Unexpected token - %s\n"),TokenBuf);
00943                     ok = FALSE;
00944                     break;
00945             }
00946         }
00947         
00948 TRACEUSER( "Neville", _T("Width = %d Height = %d\n"), Width, Height);
00949 TRACEUSER( "Neville", _T("ColoursPerRGB = %d\n"), ColoursPerRGB);
00950 
00951         if (Width > 0 && Height > 0 && ColoursPerRGB > 0)
00952         {
00953             // Allocate the space that we require for this bitmap
00954             // Sanity checks on the file that we have been asked to load.
00955             
00956             // Now work out what to do with this
00957             switch (NumberOfColours)
00958             {
00959                 case 3:
00960                     // RGB
00961                     // Bits per pixel = 3 * ColoursPerRGB.
00962                     // So 1bpp is impossible with PPM files, use pbm instead
00963                     if (ColoursPerRGB > 2 && ColoursPerRGB <= 255)
00964                     {
00965                         BitsPerPixel = 24;
00966                         BitsPerRGB = 8; 
00967                     }
00968                     
00969                     if (ColoursPerRGB > 1 && ColoursPerRGB <= 2)
00970                     {
00971                         BitsPerPixel = 8;
00972                         BitsPerRGB = 2; 
00973                     }
00974                     
00975                     if (ColoursPerRGB > 0 && ColoursPerRGB <= 1)
00976                     {
00977                         BitsPerPixel = 4;
00978                         BitsPerRGB = 1; 
00979                     }
00980                     break;
00981 
00982                 case 1:
00983                     // Greyscale or B & W
00984                     if (ColoursPerRGB > 15 && ColoursPerRGB <= 255)
00985                     {
00986                         BitsPerPixel = 8;
00987                         BitsPerRGB = 8; 
00988                     }
00989                     
00990                     if (ColoursPerRGB > 1 && ColoursPerRGB <= 15)
00991                     {
00992                         BitsPerPixel = 4;
00993                         BitsPerRGB = 4; 
00994                     }
00995 
00996                     if (ColoursPerRGB > 0 && ColoursPerRGB <= 1)
00997                     {
00998                         BitsPerPixel = 1;
00999                         BitsPerRGB = 1;
01000                     }
01001                     break;
01002 
01003                 default:
01004                     // Stop parsing as something bad has gone wrong
01005                     TRACEUSER( "Neville", _T("BasePMFilter::ReadFromFile bad NumberOfColours %d\n"),NumberOfColours);
01006                     pLexFile->GotError( _R(IDE_BADFORMAT) );
01007                     break;
01008             }
01009 
01010 TRACEUSER( "Neville", _T("BitsPerPixel = %d\n"), BitsPerPixel);
01011 
01012             if (
01013                 (BitsPerPixel != 24) && (BitsPerPixel != 8) &&
01014                 (BitsPerPixel != 4) && (BitsPerPixel != 1)
01015                )
01016                 pLexFile->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01017 
01018             // we know what sort of bitmap we are - lets allocate a new LPBITMAPINFO and some bytes
01019             *Info = AllocDIB( Width, Height, BitsPerPixel, Bits, NULL );
01020 
01021             if (*Info == NULL || *Bits == NULL)
01022                 pLexFile->GotError( _R(IDS_OUT_OF_MEMORY) );
01023             
01024             // If necessary, poke in a correct palette
01025             switch (BitsPerPixel)
01026             {
01027                 case 8:
01028                     // Make them all greyscale for now as we should only encounter this
01029                     // on PGMs
01030                     MakeGreyScalePalette((*Info)->bmiColors);               
01031                     break;
01032                 case 4:
01033                     Make16GreyScalePalette((*Info)->bmiColors);             
01034                     break;
01035                 case 1:
01036                     MakeBlackAndWhitePalette((*Info)->bmiColors);               
01037                     break;
01038             }
01039 
01040 
01041             // Work out the word/byte rounded line width rather than the pixel width
01042             INT32 WidthOfLine = DIBUtil::ScanlineSize( Width, BitsPerPixel );
01043 
01044             switch (TypeOfPPM)
01045             {
01046                 case PPM_ASCII:
01047                 case PGM_ASCII:
01048                 case PBM_ASCII:
01049                     {
01050                         // Read in the ASCII form of the bitmap data
01051                         // Pass in the lex file form of the file pointer
01052                         ok = ReadASCIIFromFile(pLexFile, *Bits, Width, Height,
01053                                                 ColoursPerRGB, BitsPerRGB, WidthOfLine,
01054                                                 ProgressString, FALSE);
01055                     }
01056                     break;
01057 
01058                 case PPM_BINARY:
01059                 case PGM_BINARY:
01060                 case PBM_BINARY:
01061                     {
01062                         // First, as we want to read in in binary mode, turn the lexer off
01063                         pLexFile->DeinitLexer();
01064 
01065                         // If first byte in binary data is &FF then eof() will have been set
01066                         // and so a random exception will be thrown. Hence, force all bits to
01067                         // be set good.  
01068                         // Nuke any existing open error states that might exist
01069                         // This can cause a random error as when if the first binary byte
01070                         // is an 0xFF, then the eof() bit is more than likely set. This will
01071                         // then throw a random, file does not exist, error on the next read.
01072                         // If we do this we force it into a known state.
01073                         pLexFile->SetGoodState();
01074 
01075                         // Read in the ASCII form of the bitmap data.
01076                         ok = ReadBinaryFromFile(pLexFile, *Bits, Width, Height,
01077                                                 ColoursPerRGB, BitsPerRGB, WidthOfLine,
01078                                                 ProgressString, FALSE);
01079                     }
01080                 
01081                     break;
01082 
01083                 default:
01084                     TRACEUSER( "Neville", _T("BasePMFilter: Bad PPM format\n"));
01085                     pLexFile->GotError( _R(IDE_BADFORMAT) );
01086                     break;
01087             }
01088         }       
01089 
01090 
01091         // If we reach here and the bitmap allocations are still null then no valid image
01092         // was found and so we should error now.
01093         // Might have just been a GIF file with extension tags in and no images!
01094         if (*Info == NULL || *Bits == NULL) pLexFile->GotError( _R(IDE_BADFORMAT) );
01095 
01096         // We are now finished with the lexer
01097         pLexFile->DeinitLexer();
01098 
01099         // If started, then stop then progress bar
01100         if (ProgressString != NULL) EndSlowJob();
01101 
01102         // Must set the exception throwing and reporting flags back to their entry states
01103         pLexFile->SetThrowExceptions( OldThrowingState );
01104         pLexFile->SetReportErrors( OldReportingState );
01105 
01106         // er, we seem to have finished OK so say so
01107         return TRUE;
01108     }
01109 
01110     catch( CFileException )
01111     {
01112         // catch our form of a file exception
01113         TRACEUSER( "Neville", _T("PPMFilter::ReadFromFile CC catch handler\n"));
01114 
01115         FreeDIB( *Info, *Bits );                            // free any alloced memory
01116         *Info = NULL;                                       // and NULL the pointers
01117         *Bits = NULL;
01118         
01119         // We are now finished with the lexer
01120         pLexFile->DeinitLexer();
01121 
01122         // If started, then stop then progress bar
01123         if (ProgressString != NULL) EndSlowJob();
01124 
01125         // Must set the exception throwing and reporting flags back to their entry states
01126         pLexFile->SetThrowExceptions( OldThrowingState );
01127         pLexFile->SetReportErrors( OldReportingState );
01128         return FALSE;
01129     }
01130     
01131 
01132     ERROR2( FALSE, "Escaped exception clause somehow" );
01133 }

BOOL BasePMFilter::ReadFromFile OILBitmap pOilBitmap  )  [virtual]
 

Determine if this filter can load the specified file.Actually does the process of reading a bitmap from a file. Inherited classes override this to read in different file formats.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/11/95
Parameters:
pOilBitmap pointer to the oil bitmap data to be filled in [INPUTS]
Will have filled in BMInfo pointer to the bitmap header to fill in [OUTPUTS] BMBytes pointer to the bitmap data to fill in
Returns:
TRUE if worked, FALSE if failed.

Reimplemented from BaseBitmapFilter.

Definition at line 656 of file ppmfiltr.cpp.

00657 {
00658     ERROR2IF(pOilBitmap == NULL,FALSE,"BasePMFilter::ReadFromFile null OilBitmap pointer");
00659     
00660     // Try to import the bitmap as a PPM file.
00661         
00662     CCLexFile *pImportFile = GetImportFile();
00663     ERROR2IF(pImportFile==NULL,FALSE,"BasePMFilter::ReadFromFile - No import file");
00664 
00665     UINT32 ImportMsgId = GetImportMsgID();      
00666     String_64 ProgressString(ImportMsgId);
00667     ProgressString = GetImportProgressString(pImportFile, ImportMsgId);
00668 
00669     CWxBitmap* pWBitmap = (CWxBitmap*)pOilBitmap;
00670     
00671     LPBITMAPINFO *pInfo = &(pWBitmap->BMInfo);
00672     LPBYTE *pBytes = &(pWBitmap->BMBytes);
00673     
00674     // The PPM filter liked it very much and so use it, showing progress bar
00675     BOOL ok = ReadFromFile(pImportFile, pInfo, pBytes, &ProgressString);
00676 
00677     SetLastBitmap();        // can only import one bitmap at the moment
00678     return ok;
00679 }


Member Data Documentation

BYTE BasePMFilter::Bits [protected]
 

Definition at line 194 of file ppmfiltr.h.

INT32 BasePMFilter::Blue [protected]
 

Definition at line 192 of file ppmfiltr.h.

INT32 BasePMFilter::Green [protected]
 

Definition at line 191 of file ppmfiltr.h.

INT32 BasePMFilter::PixelCounter [protected]
 

Definition at line 188 of file ppmfiltr.h.

INT32 BasePMFilter::PPMHowCompatible [protected]
 

Definition at line 179 of file ppmfiltr.h.

INT32 BasePMFilter::Red [protected]
 

Definition at line 190 of file ppmfiltr.h.

INT32 BasePMFilter::RGBBits [protected]
 

Definition at line 187 of file ppmfiltr.h.

INT32 BasePMFilter::RGBColours [protected]
 

Definition at line 186 of file ppmfiltr.h.

INT32 BasePMFilter::TotalHeight [protected]
 

Definition at line 184 of file ppmfiltr.h.

INT32 BasePMFilter::TotalWidth [protected]
 

Definition at line 183 of file ppmfiltr.h.

INT32 BasePMFilter::TotalWidthOfLine [protected]
 

Definition at line 185 of file ppmfiltr.h.

PMFileType BasePMFilter::TypeOfPPM [protected]
 

Definition at line 176 of file ppmfiltr.h.

INT32 BasePMFilter::x [protected]
 

Definition at line 181 of file ppmfiltr.h.

INT32 BasePMFilter::y [protected]
 

Definition at line 182 of file ppmfiltr.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:50:58 2007 for Camelot by  doxygen 1.4.4