OutputDIB Class Reference

Contains functions to write a DIB to a Windows BMP in segments, optionally with compression, optionally converting from one depth to another. To use: Open a CCFile for write. Call StartFile to write out the header. Call WriteBlock to write out each block of the bitmap, starting from low memory. When you're done, call TidyUp. More...

#include <outptdib.h>

Inheritance diagram for OutputDIB:

OutputGIF OutputPNG List of all members.

Public Member Functions

 OutputDIB ()
 Default constructor for the class. Just sets up the pointers to our buffers that may be used to be null so that the TidyUp function can do its job.
virtual ~OutputDIB ()
virtual BOOL StartFile (CCLexFile *File, LPBITMAPINFOHEADER lpHeader, LPLOGPALETTE Palette, UINT32 OutputDepth, DWORD CompressionType, UINT32 FinalHeight, INT32 ExportSize, BOOL SecondPass=FALSE, UINT32 DitherType=XARADITHER_ORDERED_GREY)
 Get ready to write a bmp to disk, maybe in chunks showing a progress bar as we write it. Currently supports:- source depth = 32, destintaiotn depth = 32, 24, 8, 4, 1 source depth = 8, destintaiotn depth = 8.
virtual BOOL StartFile (LPBITMAPINFOHEADER lpHeader, LPLOGPALETTE Palette, UINT32 OutputDepth, DWORD CompressionType, UINT32 FinalHeight, INT32 ExportSize, UINT32 DitherType=XARADITHER_ORDERED_GREY)
 Stub function to be inherited over.
virtual BOOL WriteBlock (UINT32 YPos, UINT32 Height, LPBYTE BlockStart, UINT32 InputBPP=32, INT32 ProgressOffset=0)
 Writes a chunk of bitmap data to the device. Assumes a progress hourglass is required and the caller has started an hourglass with a size of 100 and will end it. Notes: Originally this routine assumed that it was being given a 32bpp bmp, but using the InputBPP param it will now handle 8bpp bmps as well...
BOOL SetUpBlock (size_t *pBufSize, size_t *pChunkHeight, DIBConvert **pDoConvert, FNPTR_SCANLINE *pConvertFn)
 Gets the next chunk of bitmap data ready to be written out via the Accusoft or other external filters. Notes: This routine will currently handle conversions from 32->32, 32->24, 32->8 and now 8->8.
virtual BOOL SetUpInfoHeader (const LPBITMAPINFOHEADER lpHeader, const UINT32 OutputDepth, const DWORD CompressionType, const UINT32 FinalHeight, INT32 *)
 Set up the information header for the DIB.
virtual BOOL TidyUp ()
 When everything has been done via WriteBlock, call this to update the header etc. The caller is responsible for closing the file. The class CANNOT be used for further output until StartFile is called again.
void AlterExportPalette (LPLOGPALETTE pPalette)
 Copies information from the palette object passed in to OutputPalette. This is used when the user has changed a colour using the bitmap preview dialog's palette control.
virtual LPBITMAPINFO GetDestBitmapInfo (void)
 Stub function to complete inheritance hierarchy.
virtual LPBYTE GetDestBitmapBits (void)
 Stub function to complete inheritance hierarchy.

Static Public Member Functions

static BOOL GetNextBlock (UINT32 YPos, UINT32 Height, LPBYTE BlockStart, LPBYTE *Buffer, INT32 *CurrentBlockSize, INT32 *CurrentStartYPos, UINT32 *WrittenSoFar)
 Gets the next chunk of bitmap data ready to be written out via the Accusoft or other external filters. SetUpExport is used to set up everything before this fucntion is called. OutputForward determines the direction of export, set up in SetUpExport.
static BOOL SetUpForNextStrip (LPBYTE StartOfBytes, UINT32 StripHeight)
 Gets the class variables ready for the first/next strip of the render region as we are rendering in strips. Scope: Public Static.
static void PokePaletteEntry (LPLOGPALETTE Palette, INT32 *index, BYTE red, BYTE green, BYTE blue)
 Puts the required value of rgb into the specified palette entry.
static void FixBlackAndWhitePalette (LPLOGPALETTE Palette)
 Corrects the first two palette entries to be a correct Gavin black and white palette.
static void Fix16ColourPalette (LPLOGPALETTE Palette)
 Corrects the first 16 palette entries to be a correct Gavin 16 colour palette.

Protected Attributes

UINT32 SourceBitmapDepth
FilePos StartPos
CCLexFileOutputFile
LPLOGPALETTE OutputPalette
UINT32 Dither
INT32 CurrentExportSize

Static Protected Attributes

static BITMAPINFOHEADER BitmapInfo
static INT32 HeightWritten = 0L
static INT32 HeightWanted = 0L
static LPBITMAPINFO lpBitmap
static LPBITMAPINFOHEADER lpBitmapInfo
static LPBYTE ExportBuffer = NULL
static DIBConvertDoExportConvert
static FNPTR_SCANLINE ExportConvertFn = NULL
static size_t ExportSourceWidth = 0
static size_t ExportDestWidth = 0
static LPBYTE ExportData = NULL
static INT32 CurrentYPos = 0
static size_t ExportChunkHeight = 0
static BOOL OutputForward = FALSE
static UINT32 CurrentStripSize = 0
static BOOL IsFirstStrip = TRUE

Detailed Description

Contains functions to write a DIB to a Windows BMP in segments, optionally with compression, optionally converting from one depth to another. To use: Open a CCFile for write. Call StartFile to write out the header. Call WriteBlock to write out each block of the bitmap, starting from low memory. When you're done, call TidyUp.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/8/94

Definition at line 122 of file outptdib.h.


Constructor & Destructor Documentation

OutputDIB::OutputDIB  ) 
 

Default constructor for the class. Just sets up the pointers to our buffers that may be used to be null so that the TidyUp function can do its job.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/8/94
See also:
OutputDIB::TidyUp

Definition at line 148 of file outptdib.cpp.

00149 {
00150     OutputFile = NULL;
00151     lpBitmap = NULL;
00152     ExportBuffer = NULL;
00153     DoExportConvert = NULL;
00154     OutputForward = FALSE;
00155     CurrentStripSize = 0;
00156     IsFirstStrip = TRUE;
00157     OutputPalette = NULL;
00158 }

virtual OutputDIB::~OutputDIB  )  [inline, virtual]
 

Definition at line 127 of file outptdib.h.

00127 {}


Member Function Documentation

void OutputDIB::AlterExportPalette LPLOGPALETTE  pPalette  ) 
 

Copies information from the palette object passed in to OutputPalette. This is used when the user has changed a colour using the bitmap preview dialog's palette control.

Author:
Alex_Price (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/07/99
Parameters:
pPalette - Palette information that we want to copy from [INPUTS]
Returns:
-

Definition at line 207 of file outptdib.cpp.

00208 {
00209     if (pPalette == NULL)
00210         return;
00211 /*
00212     // actually it appears it is safe to let this be filled in later if we havent got
00213     // an output palette yet
00214 
00215     // if we dont have an output palette we may as well create one now
00216     if (OutputPalette==NULL)
00217     {
00218         const size_t TotalPal = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * 256 );
00219         OutputPalette = (LPLOGPALETTE)CCMalloc( TotalPal );
00220         OutputPalette->palNumEntries = 256;
00221     }
00222 */  if (OutputPalette==NULL)
00223         return;
00224 
00225     INT32 PreviousNoOfEntries = OutputPalette->palNumEntries;
00226 
00227     INT32 Colours = OutputPalette->palNumEntries;
00228     for( INT32 j=0;j<Colours;j++)
00229     {
00230         // Set all the colours to 'non-renderable' first
00231         OutputPalette->palPalEntry[j].peFlags = 255;
00232     }
00233 
00234     Colours = pPalette->palNumEntries;
00235 
00236     INT32 i = 0;
00237     for(; i < Colours; i++ )
00238     {
00239         //  Copy the colour over to the correct place in OutputPalette
00240         OutputPalette->palPalEntry[i].peRed     = pPalette->palPalEntry[i].peRed;
00241         OutputPalette->palPalEntry[i].peGreen   = pPalette->palPalEntry[i].peGreen;
00242         OutputPalette->palPalEntry[i].peBlue    = pPalette->palPalEntry[i].peBlue;
00243 
00244         //  Indicate that we want to use the colour in rendering the image
00245         OutputPalette->palPalEntry[i].peFlags = pPalette->palPalEntry[i].peFlags;
00246     }
00247 
00248     for(; i < PreviousNoOfEntries; i++ )
00249     {
00250         //  excess colours are black
00251         OutputPalette->palPalEntry[i].peRed     = 0;
00252         OutputPalette->palPalEntry[i].peGreen   = 0;
00253         OutputPalette->palPalEntry[i].peBlue    = 0;
00254 
00255         //  Indicate that we dont want to use the colour in rendering the image
00256         OutputPalette->palPalEntry[i].peFlags = 255;
00257     }
00258 }

void OutputDIB::Fix16ColourPalette LPLOGPALETTE  Palette  )  [static]
 

Corrects the first 16 palette entries to be a correct Gavin 16 colour palette.

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

Definition at line 343 of file outptdib.cpp.

00344 {
00345     Palette->palNumEntries = 16;
00346 
00347     INT32 i = 0;
00348     // Bit more tricky this one, Gavin uses a fixed 16 colour palette           
00349     PokePaletteEntry(Palette, &i, 0x00, 0x00, 0x00); // black
00350     PokePaletteEntry(Palette, &i, 0x80, 0x00, 0x00); // brown
00351     PokePaletteEntry(Palette, &i, 0x00, 0x80, 0x00); // Half green
00352     PokePaletteEntry(Palette, &i, 0x80, 0x80, 0x00); // Half browny (red/green)
00353     PokePaletteEntry(Palette, &i, 0x00, 0x00, 0x80); // Dark blue
00354     PokePaletteEntry(Palette, &i, 0x80, 0x00, 0x80); // Mauve
00355     PokePaletteEntry(Palette, &i, 0x00, 0x80, 0x80); // greeny/blue
00356     PokePaletteEntry(Palette, &i, 0x80, 0x80, 0x80); // mid grey
00357 
00358     PokePaletteEntry(Palette, &i, 0xc0, 0xc0, 0xc0); // light grey
00359     PokePaletteEntry(Palette, &i, 0xff, 0x00, 0x00); // red
00360     PokePaletteEntry(Palette, &i, 0x00, 0xff, 0x00); // green
00361     PokePaletteEntry(Palette, &i, 0xff, 0xff, 0x00); // yellow
00362     PokePaletteEntry(Palette, &i, 0x00, 0x00, 0xff); // blue
00363     PokePaletteEntry(Palette, &i, 0xff, 0x00, 0xff); // magenta
00364     PokePaletteEntry(Palette, &i, 0x00, 0xff, 0xff); // cyan
00365     PokePaletteEntry(Palette, &i, 0xff, 0xff, 0xff); // white
00366 }   

void OutputDIB::FixBlackAndWhitePalette LPLOGPALETTE  Palette  )  [static]
 

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:
5/4/95
Parameters:
Palette palette to write to. [INPUTS]
- [OUTPUTS]
Returns:
-
See also:
OutputDIB::StartFile; OutputDIB::StartExport;

Definition at line 310 of file outptdib.cpp.

00311 {
00312     Palette->palNumEntries = 2;
00313 
00314     INT32 i = 0;
00315 PORTNOTE("BmapPrevDlg", "Removed use of bitmap preview dialog");
00316 #ifndef EXCLUDE_FROM_XARALX
00317     if( BmapPrevDlg::GetNumberOfTransparentColours() > 0 )
00318     {
00319         PokePaletteEntry(Palette, &i, 0xff, 0xff, 0xff);
00320         PokePaletteEntry(Palette, &i, 0x00, 0x00, 0x00);
00321     }
00322     else
00323 #endif
00324     {
00325         PokePaletteEntry(Palette, &i, 0x00, 0x00, 0x00);
00326         PokePaletteEntry(Palette, &i, 0xff, 0xff, 0xff);
00327     }
00328 }

LPBYTE OutputDIB::GetDestBitmapBits void   )  [virtual]
 

Stub function to complete inheritance hierarchy.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/6/00
Parameters:
pPalette - Palette information that we want to copy from [INPUTS]
Returns:
NULL

Reimplemented in OutputGIF, and OutputPNG.

Definition at line 290 of file outptdib.cpp.

00291 {
00292     // This function should never be called, so return NULL.
00293     return NULL;
00294 }

LPBITMAPINFO OutputDIB::GetDestBitmapInfo void   )  [virtual]
 

Stub function to complete inheritance hierarchy.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/6/00
Parameters:
pPalette - Palette information that we want to copy from [INPUTS]
Returns:
NULL

Reimplemented in OutputGIF, and OutputPNG.

Definition at line 272 of file outptdib.cpp.

00273 {
00274     // This function should never be called, so return NULL.
00275     return NULL;
00276 }

BOOL OutputDIB::GetNextBlock UINT32  YPos,
UINT32  Height,
LPBYTE  BlockStart,
LPBYTE Buffer,
INT32 *  CurrentBlockSize,
INT32 *  CurrentStartYPos,
UINT32 WrittenSoFar
[static]
 

Gets the next chunk of bitmap data ready to be written out via the Accusoft or other external filters. SetUpExport is used to set up everything before this fucntion is called. OutputForward determines the direction of export, set up in SetUpExport.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/11/94
Parameters:
YPos pixel co-ord of the chunk of DIB we are about to write out [INPUTS] (0 = bottom, increasing as it goes up). Height height in pixels of this chunk BlockStart the start address of the bytes of this chunk
Buffer pointer to the returned buffer filled up with DIB bytes [OUTPUTS] CurrentBlockSize current size of the block being rendered CurrentStartYPos current position of the start of this block of data WrittenSoFar the amount of the bitmap written to date
Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)

Errors: Calls SetError on FALSE returns.

See also:
OutputDIB::WriteBlock; OutputDIB::SetUpExport; Scope: Public

Definition at line 1014 of file outptdib.cpp.

01017 {
01018     // Get the next block ready for export a line at a time
01019     *Buffer = NULL;             // Just in case of early random exit set this to NULL
01020     *CurrentBlockSize = 0;      // Just in case of early random exit set this to 0
01021 
01022     // Convert the next strip 
01023     if ( DoExportConvert )
01024     {
01025 //TRACEUSER( "Neville", _T("GetNextBlock DoExportConvert\n"));
01026         // 8 bpp, 4bpp and 1bpp export
01027         ERROR2IF(ExportData < BlockStart, FALSE, "GetNextBlock ExportData < BlockStart");
01028         ERROR2IF(Height - CurrentYPos < 0, FALSE, "GetNextBlock Height - CurrentYPos < 0");
01029         // Work out the size of the export chunk left, normally ExportChunkHeight but
01030         // if at the end of export may be a small strip left.
01031         const size_t ThisBit = min( (INT32)(Height - CurrentYPos), (INT32)ExportChunkHeight );
01032         if (!DoExportConvert->Convert( ExportData, ExportBuffer, ThisBit, IsFirstStrip ))
01033             return FALSE;                           // stop if conversion failed
01034 
01035         IsFirstStrip = FALSE;
01036 
01037         // We have in ExportData a size of data block = ThisBit * ExportDestWidth
01038         // On last strip may be less than ExportChunkHeight in depth 
01039         CurrentYPos += ThisBit;                     // Move down by a strips worth
01040 
01041         if (OutputForward)
01042         {
01043             ExportData += ExportSourceWidth;        // Move on by a lines worth
01044         }
01045         else
01046         {
01047             if ((Height - CurrentYPos) < ExportChunkHeight )
01048                 ExportData = BlockStart;                // On last strip so do from start
01049             else
01050                 ExportData -= ExportSourceWidth;        // Move on by a lines worth
01051             if (ExportData < BlockStart)                // Just in case test
01052                 ExportData = BlockStart;                
01053         }
01054 
01055         // Set up return variables
01056         *Buffer = ExportBuffer;                     // return our new buffer to the caller
01057         *CurrentBlockSize = ThisBit;                // return size of this block
01058         *CurrentStartYPos = CurrentYPos;            // return current start of strip
01059         
01060         HeightWritten += ThisBit;                   // remember we wrote this lot
01061     }
01062     // now the bytes (this is crying out for a virtual function or two)
01063     else if ( ExportConvertFn && ExportBuffer )
01064     {
01065         // 24 bpp convert
01066 //TRACEUSER( "Neville", _T("GetNextBlock Do export via convert function\n"));
01067         ERROR2IF(ExportData < BlockStart, FALSE, "GetNextBlock ExportData < BlockStart");
01068         // write data via conversion function
01069         ExportConvertFn( BitmapInfo.biWidth, ExportData, ExportBuffer );
01070 
01071         if (OutputForward)
01072         {
01073             // We have in ExportBuffer an amount of BuffSize worth of data
01074             ExportData += ExportSourceWidth;
01075             CurrentYPos -= ExportChunkHeight;
01076         }
01077         else
01078         {
01079             // We have in ExportBuffer an amount of BuffSize worth of data
01080             ExportData -= ExportSourceWidth;
01081             CurrentYPos += ExportChunkHeight;
01082         }
01083 
01084         // Set up return variables
01085         *Buffer = ExportBuffer;                     // return our new buffer to the caller
01086         *CurrentBlockSize = ExportChunkHeight;      // return size of this block
01087         *CurrentStartYPos = CurrentYPos;            // return current start of strip
01088 
01089         HeightWritten += ExportChunkHeight;         // remember we wrote this lot
01090     
01091     }
01092     else
01093     {
01094 //TRACEUSER( "Neville", _T("GetNextBlock all in one go\n"));
01095         // Write it all out in one go, 32bpp export
01096         // We have in the DIB at BlockStart an amount of BitmapInfo.biSizeImage worth of data
01097         // Set up return variables
01098         *Buffer = BlockStart;                       // return our new buffer to the caller
01099         *CurrentBlockSize = BitmapInfo.biSizeImage; // return size of this block
01100 
01101         HeightWritten += Height;                    // remember we wrote this lot
01102     }
01103 
01104     // Return the amount of data written so far  
01105     *WrittenSoFar = HeightWritten;
01106 
01107     return TRUE;
01108 }

void OutputDIB::PokePaletteEntry LPLOGPALETTE  Palette,
INT32 *  index,
BYTE  red,
BYTE  green,
BYTE  blue
[static]
 

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

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
3/4/95
Parameters:
Palette palette to write to. [INPUTS] index address of variable holding palette entry to write to 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:
OutputDIB::StartFile;

Definition at line 178 of file outptdib.cpp.

00179 {
00180     Palette->palPalEntry[*index].peRed = red;   
00181     Palette->palPalEntry[*index].peGreen = green;   
00182     Palette->palPalEntry[*index].peBlue = blue; 
00183     Palette->palPalEntry[*index].peFlags = 0;
00184     // increment the counter and return it
00185     (*index) ++;    
00186 }

BOOL OutputDIB::SetUpBlock size_t *  pBufSize,
size_t *  pChunkHeight,
DIBConvert **  pDoConvert,
FNPTR_SCANLINE pConvertFn
 

Gets the next chunk of bitmap data ready to be written out via the Accusoft or other external filters. Notes: This routine will currently handle conversions from 32->32, 32->24, 32->8 and now 8->8.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/11/94
Parameters:
[INPUTS] 
pBufSize pointer to a size_t which gives the buffer size required for this [OUTPUTS] output depth. pChunkHeight pointer to a size_t which gives the size of chunk required for this output depth. pDoConvert pointer to a pointer to a dib convert class for this depth. pConvertFn pointer to a convert function pointer
Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)

Errors: Calls SetError on FALSE returns. Scope: Public

Definition at line 1223 of file outptdib.cpp.

01225 {
01226     BOOL Problems = FALSE;
01227 
01228     switch (SourceBitmapDepth)
01229     {
01230         case 32:
01231         {
01232             switch (BitmapInfo.biBitCount)
01233             {
01234                 case 32:
01235                     {
01236                         // real 32-bit BMPs here
01237                         // our 'filter' zeros the transparency bits
01238                         *pConvertFn = DIBUtil::Convert32to32;
01239                         *pBufSize = DIBUtil::ScanlineSize( BitmapInfo.biWidth, 32 );
01240                     }
01241                     break;
01242                 case 24:
01243                     {
01244                         // convert 32-bit BMPs to 24-bit ones so things can read them
01245                         *pConvertFn = DIBUtil::Convert32to24;                           // 32->24
01246                         *pBufSize = DIBUtil::ScanlineSize( BitmapInfo.biWidth, 24 );    // size of 24-bit scanline
01247                     }
01248                     break;
01249                 case 8:
01250                     {
01251                         // 32->8 we do in bigger chunks because of dithering
01252                         *pDoConvert = DIBConvert::Create( SourceBitmapDepth, 8, BitmapInfo.biWidth, OutputPalette, Dither );
01253                         if (*pDoConvert==NULL)
01254                         {
01255                             ENSURE(FALSE, "DIBConvert::Create returned NULL");
01256                             return FALSE;
01257                         }
01258                         *pChunkHeight = 16;
01259                         *pBufSize = DIBUtil::ScanlineSize( BitmapInfo.biWidth, 8 ) * (*pChunkHeight);
01260                     }
01261                     break;
01262                 case 4:
01263                     {
01264                         // 32->4 we do in bigger chunks because of dithering
01265                         *pDoConvert = DIBConvert::Create( SourceBitmapDepth, 4, BitmapInfo.biWidth, OutputPalette, Dither );
01266                         if (*pDoConvert==NULL)
01267                         {
01268                             ENSURE(FALSE, "DIBConvert::Create returned NULL");
01269                             return FALSE;
01270                         }
01271                         *pChunkHeight = 16;
01272                         *pBufSize = DIBUtil::ScanlineSize( BitmapInfo.biWidth, 4 ) * (*pChunkHeight);
01273                     }
01274                     break;
01275                 case 1:
01276                     {
01277                         // 32->1 we do in bigger chunks because of dithering
01278                         *pDoConvert = DIBConvert::Create( SourceBitmapDepth, 1, BitmapInfo.biWidth, OutputPalette, Dither );
01279                         if (*pDoConvert==NULL)
01280                         {
01281                             ENSURE(FALSE, "DIBConvert::Create returned NULL");
01282                             return FALSE;
01283                         }
01284                         *pChunkHeight = 16;
01285                         *pBufSize = DIBUtil::ScanlineSize( BitmapInfo.biWidth, 1 ) * (*pChunkHeight);
01286                     }
01287                     break;
01288                 default:
01289                     Problems = TRUE;
01290                     break;
01291             }
01292             break;
01293         }
01294         case 8:
01295             if (BitmapInfo.biBitCount==8)
01296             {
01297                 // real 8-bit BMPs here
01298                 // we basically just do a memory copy from source to dest
01299                 *pConvertFn = DIBUtil::Convert8to8;
01300                 *pBufSize = DIBUtil::ScanlineSize( BitmapInfo.biWidth, 8 );
01301                 break;
01302 
01303             }
01304             Problems = TRUE;
01305             break;
01306 
01307         default:
01308             Problems = TRUE;
01309             break;
01310     }
01311 
01312     if(Problems)
01313     {
01314         Error::SetError( _R(IDE_FORMATNOTSUPPORTED) );
01315         return FALSE;
01316     }
01317 
01318     return TRUE;
01319 }

BOOL OutputDIB::SetUpForNextStrip LPBYTE  StartOfBytes,
UINT32  StripHeight
[static]
 

Gets the class variables ready for the first/next strip of the render region as we are rendering in strips. Scope: Public Static.

static BOOL OutputDIB::SetUpForNextStrip(LPBYTE StartOfBytes, UINT32 StripHeight)

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
15/5/95
Parameters:
StartOfBytes start of the actual bitmap data (bits) [INPUTS] StripHeight height of this strip
- [OUTPUTS]
Returns:
TRUE if worked, FALSE if failed

Definition at line 1126 of file outptdib.cpp.

01127 {
01128     // We have rendered the next strip into the render region so reset everything back
01129     // to start outputting this strip instead of the old one
01130     CurrentStripSize = StripHeight;
01131 //TRACEUSER( "Neville", _T("OutputDIB::SetUpForNextStrip StripHeight=%d\n"),StripHeight);
01132 //TRACEUSER( "Neville", _T("OutputDIB::SetUpForNextStrip HeightWritten=%d\n"),HeightWritten);
01133      
01134     // Now get the actual data ready
01135     if ( DoExportConvert )
01136     {
01137 //TRACEUSER( "Neville", _T("OutputDIB::SetUpForNextStrip DoExportConvert\n"));
01138         // 8bpp, 4bpp and 1bpp conversion
01139         UINT32 LineWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, 32 );
01140         ExportSourceWidth =  LineWidth * ExportChunkHeight;
01141         ExportDestWidth   = DIBUtil::ScanlineSize( BitmapInfo.biWidth, BitmapInfo.biBitCount );
01142 
01143         if (OutputForward)
01144         {
01145             // Set up the pointer to the first block of DIB bytes to export
01146             // In this forward direction it is the start of the first strip of the DIB
01147             ExportData = StartOfBytes;
01148         }
01149         else
01150         {
01151             // Set up the pointer to the first block of DIB bytes to export
01152             // Which is the start of the last strip of the DIB
01153             ExportData = StartOfBytes + ((StripHeight * LineWidth) - ExportSourceWidth);
01154         }
01155     }
01156     // now the bytes (this is crying out for a virtual function or two)
01157     else if ( ExportConvertFn && ExportBuffer )
01158     {
01159 //TRACEUSER( "Neville", _T("OutputDIB::SetUpForNextStrip Do via convert function to ExportBuffer\n"));
01160         // 24 bpp convert
01161         ExportSourceWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, 32 );
01162 
01163         if (OutputForward)
01164         {
01165             // Set up the pointer to the first block of DIB bytes to export
01166             // In this forward direction it is the start of the first strip of the DIB
01167             ExportData = StartOfBytes;
01168         }
01169         else
01170         {
01171             // Set up the pointer to the first block of DIB bytes to export
01172             // Which is the start of the last strip of the DIB
01173             ExportData = StartOfBytes + ((StripHeight - 1) * ExportSourceWidth);
01174         }
01175     }
01176     else
01177     {
01178 //TRACEUSER( "Neville", _T("OutputDIB::SetUpForNextStrip Do all in one go\n"));
01179         // We will write it all in one go
01180         ExportData = StartOfBytes;      // pointer to the DIB bytes
01181     }
01182 //TRACEUSER( "Neville", _T("ExportSourceWidth = %d\n"),ExportSourceWidth);
01183 //TRACEUSER( "Neville", _T("ExportDestWidth = %d\n"),ExportDestWidth);
01184 
01185     // Just in case the initial block is smaller than the usual output depth and hence
01186     // we will be trying to export data to before the start of the block. A quick check
01187     // is in order.
01188     if (ExportData < StartOfBytes)              // Just in case 
01189         ExportData = StartOfBytes;              
01190 
01191     // Set up the starting parameters of the export operation.
01192     // Remember we have to export from the end of the DIB up to the start otherwise
01193     // the output will be upside down.
01194     CurrentYPos = 0;                    // size of DIB in scan lines
01195 
01196     return TRUE;
01197 }   

BOOL OutputDIB::SetUpInfoHeader const LPBITMAPINFOHEADER  lpHeader,
const UINT32  OutputDepth,
const DWORD  CompressionType,
const UINT32  FinalHeight,
INT32 *  pPalSize
[virtual]
 

Set up the information header for the DIB.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/11/94
Parameters:
lpHeader contains width & DPI of source & dest. biHeight & depth ignored. [INPUTS] OutputDepth depth of bitmap required on disk CompressionType BI_RGB only supported (or CC_BMPTYPE for 32-bit with trans) FinalHeight output of entire bitmap on disk
pPalSize pointer to an integer PalSize variable which is the palette size [OUTPUTS]
Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)

Errors: Calls SetError on FALSE returns.

See also:
OutputDIB::StartFile; OutputDIB::WriteBlock; OutputDIB::TidyUp Scope: Public

Definition at line 520 of file outptdib.cpp.

00523 {
00524     if (
00525         (CompressionType != BI_RGB) &&                  // uncompressed is OK
00526         (CompressionType != CC_BMPTYPE)                 // so is RGBT
00527        )
00528     {
00529         // cannot do compression yet
00530         Error::SetError( _R(IDE_FORMATNOTSUPPORTED) );
00531         return FALSE;
00532     }
00533 
00534     // Fix up our copy of the header sohat it corresponds to the actual required one
00535     BitmapInfo.biCompression = CompressionType;     // fixup compression type
00536     BitmapInfo.biHeight = FinalHeight;              // fixup height to be true height
00537     BitmapInfo.biBitCount = OutputDepth;
00538 
00539     SourceBitmapDepth = lpHeader->biBitCount;
00540 
00541     const WORD DestDepth = BitmapInfo.biBitCount;
00542     UINT32 LineWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, OutputDepth );
00543 
00544     // source bitmap not necessarily same as required file depth
00545     // make sure we can handle conversion
00546     BOOL FormatOK = FALSE;
00547 
00548     switch (SourceBitmapDepth)
00549     {
00550         case 32:
00551             {
00552                 switch (DestDepth)
00553                 {
00554                     case 32:
00555                         {
00556                             // 32->32 might use our special type CC_BMPTYPE
00557                             FormatOK = TRUE;
00558                         }
00559                         break;
00560                     case 24:
00561                         {
00562                             // 32->24 bit is fine
00563                             if (CompressionType==BI_RGB)
00564                             {
00565                                 // might be BITFIELDs for rendering purposes
00566                                 BitmapInfo.biCompression = BI_RGB;
00567                                 BitmapInfo.biBitCount = 24;
00568                                 FormatOK = TRUE;
00569                             }
00570                         }
00571                         break;
00572                     case 8:
00573                         {
00574                             // 32->8 is OK
00575                             FormatOK = TRUE;
00576                             *pPalSize = 256;
00577                         }
00578                         break;
00579                     case 4:
00580                         {
00581                             // 32->4 is OK
00582                             FormatOK = TRUE;
00583                             *pPalSize = 16;
00584                         }
00585                         break;
00586                     case 1:
00587                         {
00588                             // 32->1 is OK
00589                             FormatOK = TRUE;
00590                             *pPalSize = 2;
00591                         }
00592                         break;
00593                     default:
00594                         // other source formats here
00595                         break;
00596                 }
00597                 
00598             }
00599             break;
00600         case 8:
00601             if (DestDepth==8)
00602             {
00603                 // 8->8 is OK
00604                 FormatOK = TRUE;
00605                 *pPalSize = 256;
00606             }
00607             break;
00608         default:
00609             // other source formats here
00610             break;
00611     }
00612 
00613     if (!FormatOK)
00614     {
00615         Error::SetError( _R(IDE_FORMATNOTSUPPORTED) );
00616         return FALSE;
00617     }
00618 
00619     BitmapInfo.biSizeImage = LineWidth * FinalHeight;
00620 
00621     return TRUE;
00622 }

BOOL OutputDIB::StartFile LPBITMAPINFOHEADER  lpHeader,
LPLOGPALETTE  Palette,
UINT32  OutputDepth,
DWORD  CompressionType,
UINT32  FinalHeight,
INT32  ExportSize,
UINT32  DitherType = XARADITHER_ORDERED_GREY
[virtual]
 

Stub function to be inherited over.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/6/00
Parameters:
All are meaningless. [INPUTS]
Returns:
FALSE.

Reimplemented in OutputGIF, and OutputPNG.

Definition at line 488 of file outptdib.cpp.

00495 {
00496     return FALSE;
00497 }

BOOL OutputDIB::StartFile CCLexFile File,
LPBITMAPINFOHEADER  lpHeader,
LPLOGPALETTE  Palette,
UINT32  OutputDepth,
DWORD  CompressionType,
UINT32  FinalHeight,
INT32  ExportSize,
BOOL  SecondPass = FALSE,
UINT32  DitherType = XARADITHER_ORDERED_GREY
[virtual]
 

Get ready to write a bmp to disk, maybe in chunks showing a progress bar as we write it. Currently supports:- source depth = 32, destintaiotn depth = 32, 24, 8, 4, 1 source depth = 8, destintaiotn depth = 8.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/8/94
Parameters:
File opened file we can write to. [INPUTS] lpHeader contains width & DPI of source & dest. biHeight & depth ignored. Palette pointer to bmiColor struct, or NULL if not used (can be temporary) OutputDepth depth of bitmap required on disk CompressionType BI_RGB only supported (or CC_BMPTYPE for 32-bit with trans) FinalHeight output of entire bitmap on disk ExportSize The set progress bar size SecondPass Flag for whether it is a second pass export render. (Used by GIF export only at present). Defaults to False.
Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)

Errors: Calls SetError on FALSE returns.

See also:
OutputDIB::WriteBlock; OutputDIB::TidyUp

OutputGIF::StartFile; Scope: Public

Definition at line 398 of file outptdib.cpp.

00402 {
00403     // remember input args
00404     OutputFile = File;
00405     StartPos = OutputFile->tell();                      // remember where in the file this starts
00406     BitmapInfo = *lpHeader;                             // take a copy of user's header
00407     OutputPalette = NULL;                               // our form of the palette, if required
00408 
00409     HeightWritten = 0;                                  // our count of the bitmap lines written
00410     CurrentExportSize = ExportSize;                     // size set up for the progress bar
00411     HeightWanted = FinalHeight;                         // the actual height of the export required
00412 
00413     INT32 PalSize = 0;                                  // how many entries in palette
00414 
00415     // Remember which dithering type to use
00416     Dither = DitherType;
00417 
00418     IsFirstStrip = TRUE;
00419 
00420     // Set up the information header for the dib
00421     if ( !SetUpInfoHeader(lpHeader, OutputDepth, CompressionType, FinalHeight, &PalSize) )
00422         return FALSE;                                   // SetError already called 
00423 
00424     // BITMAPFILEHEADER goes first
00425     BITMAPFILEHEADER Header;
00426 
00427     Header.bfType = ('M'<<8) | 'B';
00428     Header.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
00429                     sizeof(RGBQUAD)*PalSize + BitmapInfo.biSizeImage;
00430     Header.bfReserved1 = 0;
00431     Header.bfReserved2 = 0;
00432     Header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
00433                         sizeof(RGBQUAD)*PalSize;
00434 
00435     OutputFile->write( &Header, sizeof(Header) );
00436 
00437 
00438     // then a local BITMAPINFOHEADER
00439 
00440     OutputFile->write( &BitmapInfo, sizeof(BITMAPINFOHEADER) );
00441 
00442     // then the RGBQUAD palette
00443     if (PalSize)
00444     {
00445         ERROR2IF(Palette == NULL,FALSE,"StartFile has a NULL Palette when one is required");
00446         // make a copy of the palette for possible later use
00447         const size_t TotalPal = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * PalSize );
00448         OutputPalette = (LPLOGPALETTE)CCMalloc( TotalPal );
00449         if (OutputPalette==NULL)
00450             return FALSE;
00451 
00452         // Take a copy of that palette
00453         memcpy( OutputPalette, Palette, TotalPal );
00454 
00455         // write it to disk in RGBQUAD format
00456         RGBQUAD TempRGB;
00457         TempRGB.rgbReserved = 0;
00458         for (INT32 i=0; i<PalSize; i++)
00459         {
00460             TempRGB.rgbRed = OutputPalette->palPalEntry[i].peRed;
00461             TempRGB.rgbGreen = OutputPalette->palPalEntry[i].peGreen;
00462             TempRGB.rgbBlue = OutputPalette->palPalEntry[i].peBlue;
00463             OutputFile->write( &TempRGB, sizeof(RGBQUAD) );
00464         }
00465     }
00466 
00467     return !OutputFile->bad();
00468 }

BOOL OutputDIB::TidyUp  )  [virtual]
 

When everything has been done via WriteBlock, call this to update the header etc. The caller is responsible for closing the file. The class CANNOT be used for further output until StartFile is called again.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/8/94
Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)

Errors: Calls SetError on FALSE returns. Scope: Public

Reimplemented in OutputGIF, and OutputPNG.

Definition at line 1336 of file outptdib.cpp.

01337 {
01338     BOOL Result = TRUE;
01339 
01340     if(OutputFile != NULL)
01341     {
01342         // Check that what we wrote was what was required in terms of number of lines
01343         // used to use BitmapInfo.biHeight but this may now be the height of a strip
01344 #ifdef _BATCHING         
01345         if ( HeightWritten != HeightWanted )
01346         {
01347             TRACEUSER( "Martin", _T("OutputDIB::TidyUp HeightReqd = %d  HeightWritten = %d\n"),
01348                 HeightWanted,HeightWritten);
01349         }
01350 #else   //cos this goes off
01351         ERROR3IF( HeightWritten != HeightWanted, "Wrote wrong amount of bitmap to disk");
01352 #endif
01353 
01354         // could do fixups into the header here etc when using compression
01355         Result = !OutputFile->bad();
01356 
01357         OutputFile = NULL;                              // stop usage until StartFile time
01358 
01359         // If 8, 4, 1bpp export then put back the recommended palette by destructing the
01360         // convert function.
01361         if (DoExportConvert)
01362         {
01363             delete DoExportConvert;
01364             DoExportConvert = NULL;
01365         }   
01366     }
01367 
01368     // Free up the bitmap info if present.
01369     // This contains the info header and palette
01370     if (lpBitmap)
01371     {
01372         CCFree(lpBitmap);
01373         lpBitmap = NULL;
01374     }
01375 
01376     // Free up the output palette buffer if present
01377     if (OutputPalette)
01378     {
01379         CCFree(OutputPalette);
01380         OutputPalette = NULL;
01381     }
01382 
01383     // Free up the export buffer if present
01384     if (ExportBuffer)
01385     {
01386         CCFree(ExportBuffer);
01387         ExportBuffer = NULL;
01388     }
01389 
01390     return Result;
01391 }

BOOL OutputDIB::WriteBlock UINT32  YPos,
UINT32  Height,
LPBYTE  BlockStart,
UINT32  InputBPP = 32,
INT32  ProgressOffset = 0
[virtual]
 

Writes a chunk of bitmap data to the device. Assumes a progress hourglass is required and the caller has started an hourglass with a size of 100 and will end it. Notes: Originally this routine assumed that it was being given a 32bpp bmp, but using the InputBPP param it will now handle 8bpp bmps as well...

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/8/94
Parameters:
YPos pixel co-ord of the chunk of DIB we are about to write out (0=bottom, [INPUTS] increasing as it goes up). Height height in pixels of this chunk BlockStart the start address of the bytes of this chunk (optional) InputBPP BPP of the input image (assumed 32 by default - 8 also works) ProgressOffset value to add to value passed to ContinueSlowJob (default 0).
Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)

Errors: Calls SetError on FALSE returns. Scope: Public

Reimplemented in OutputGIF, and OutputPNG.

Definition at line 648 of file outptdib.cpp.

00650 {
00651     FNPTR_SCANLINE ConvertFn = NULL;
00652     LPBYTE Buffer = NULL;
00653     size_t BufSize = 0L;
00654     size_t ChunkHeight = 1;
00655     DIBConvert *DoConvert = NULL;
00656 
00657     // Set up the size and other information for the dib block that we require. This is
00658     // dependent on the export depth or bpp required.
00659     if ( !SetUpBlock( &BufSize, &ChunkHeight, &DoConvert, &ConvertFn ) )
00660         return FALSE;           // Error details already set up
00661 
00662     if (BufSize)
00663     {
00664         Buffer = (LPBYTE)CCMalloc( BufSize );
00665         if (Buffer==NULL)
00666             return FALSE;
00667     }
00668 
00669     if ( DoConvert )
00670     {
00671         // use new classes to do it
00672         // 8bpp, 4bpp and 1bpp conversion
00673         INT32 h = Height;
00674         INT32 count = 0;
00675         LPBYTE Data = BlockStart;
00676         const size_t SourceWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, InputBPP ) * ChunkHeight;
00677         const size_t DestWidth   = DIBUtil::ScanlineSize( BitmapInfo.biWidth, BitmapInfo.biBitCount );
00678 
00679         while (h)
00680         {
00681             ENSURE(h >= 0, "bad looping");
00682 
00683             const size_t ThisBit = min( h, (INT32)ChunkHeight );
00684             if (!DoConvert->Convert( Data, Buffer, ThisBit, IsFirstStrip ))
00685                 break;                              // stop if conversion failed
00686 
00687             IsFirstStrip = FALSE;
00688 
00689             OutputFile->write( Buffer, ThisBit * DestWidth );
00690             if (OutputFile->bad())
00691                 break;                              // stop if file errored
00692             Data += SourceWidth;
00693             h -= ThisBit;
00694 
00695             // now update the progress display, started with CurrentExportSize
00696             // CurrentExport size is now the point to go from in the export
00697             count++;
00698             ContinueSlowJob( (INT32)( ProgressOffset + count ));
00699             //ContinueSlowJob( (INT32)(100*count/(Height)) );
00700         }
00701     }
00702     // now the bytes (this is crying out for a virtual function or two)
00703     else if ( ConvertFn && Buffer )
00704     {
00705         // Write via conversion function
00706         // 24 bpp convert
00707         UINT32 h = Height;
00708         INT32 count = 0;
00709         LPBYTE Data = BlockStart;
00710         const size_t SourceWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, InputBPP );
00711 
00712         while (h)
00713         {
00714             ConvertFn( BitmapInfo.biWidth, Data, Buffer );
00715             OutputFile->write( Buffer, BufSize );
00716             if (OutputFile->bad())
00717                 break;                              // stop if file errored
00718             Data += SourceWidth;
00719             h -= ChunkHeight;
00720 
00721             // now update the progress display, started with CurrentExportSize
00722             // ProgressOffset size is now the point to go from in the export
00723             count++;
00724             ContinueSlowJob( (INT32)( ProgressOffset + count ));
00725             //ContinueSlowJob( (INT32)((CurrentExportSize * count)/Height) );
00726         }
00727     }
00728     else
00729     {
00730         // Write it all out in one go
00731         //OutputFile->write( BlockStart, BitmapInfo.biSizeImage );
00732         // Write the actual bytes out to file. Used to do it in one go but we really
00733         // require some progress bar indication so we will do it in chunks.
00734         DWORD BitsSize = BitmapInfo.biSizeImage; 
00735         if (BitsSize > 0)
00736         {
00737             if (BitsSize < 1024)
00738             {
00739                 // File very small or no progress bar required, so load in one go
00740                 OutputFile->write( BlockStart, BitsSize);
00741             }
00742             else
00743             {
00744                 // Load in chunks, for present split into 100 chunks
00745                 DWORD ChunkSize = BitsSize/100;
00746                 DWORD Position = 0;
00747                 LPBYTE pBitInfo = BlockStart;
00748                 
00749                 while (Position < BitsSize)
00750                 {
00751                     if ( (BitsSize - Position) > ChunkSize)
00752                         OutputFile->write( pBitInfo, ChunkSize);
00753                     else
00754                     {
00755                         ChunkSize = BitsSize - Position;
00756                         OutputFile->write( pBitInfo, ChunkSize);
00757                     }
00758                             
00759                     // Increment our counters/pointers
00760                     Position+=ChunkSize;
00761                     pBitInfo+=ChunkSize;
00762                     // Progress bar started with height of bitmap
00763                     ContinueSlowJob( (INT32)(ProgressOffset + (Height * Position)/BitsSize) );
00764                     //ContinueSlowJob( (INT32)((CurrentExportSize * Position)/BitsSize) );
00765                 }
00766             }
00767         }
00768     }
00769 
00770     // If present, get rid of our export function
00771     if (DoConvert)
00772     {
00773         delete DoConvert;
00774         DoConvert = NULL;
00775     }
00776 
00777     CCFree( Buffer );
00778 
00779     HeightWritten += Height;                        // remember we wrote this lot
00780 
00781     return !OutputFile->bad();
00782 }


Member Data Documentation

BITMAPINFOHEADER OutputDIB::BitmapInfo [static, protected]
 

Definition at line 174 of file outptdib.h.

INT32 OutputDIB::CurrentExportSize [protected]
 

Definition at line 198 of file outptdib.h.

UINT32 OutputDIB::CurrentStripSize = 0 [static, protected]
 

Definition at line 197 of file outptdib.h.

INT32 OutputDIB::CurrentYPos = 0 [static, protected]
 

Definition at line 193 of file outptdib.h.

UINT32 OutputDIB::Dither [protected]
 

Definition at line 178 of file outptdib.h.

DIBConvert * OutputDIB::DoExportConvert [static, protected]
 

Definition at line 188 of file outptdib.h.

LPBYTE OutputDIB::ExportBuffer = NULL [static, protected]
 

Definition at line 187 of file outptdib.h.

size_t OutputDIB::ExportChunkHeight = 0 [static, protected]
 

Definition at line 194 of file outptdib.h.

FNPTR_SCANLINE OutputDIB::ExportConvertFn = NULL [static, protected]
 

Definition at line 189 of file outptdib.h.

LPBYTE OutputDIB::ExportData = NULL [static, protected]
 

Definition at line 192 of file outptdib.h.

size_t OutputDIB::ExportDestWidth = 0 [static, protected]
 

Definition at line 191 of file outptdib.h.

size_t OutputDIB::ExportSourceWidth = 0 [static, protected]
 

Definition at line 190 of file outptdib.h.

INT32 OutputDIB::HeightWanted = 0L [static, protected]
 

Definition at line 182 of file outptdib.h.

INT32 OutputDIB::HeightWritten = 0L [static, protected]
 

Definition at line 181 of file outptdib.h.

BOOL OutputDIB::IsFirstStrip = TRUE [static, protected]
 

Definition at line 200 of file outptdib.h.

LPBITMAPINFO OutputDIB::lpBitmap [static, protected]
 

Definition at line 185 of file outptdib.h.

LPBITMAPINFOHEADER OutputDIB::lpBitmapInfo [static, protected]
 

Definition at line 186 of file outptdib.h.

CCLexFile* OutputDIB::OutputFile [protected]
 

Definition at line 173 of file outptdib.h.

BOOL OutputDIB::OutputForward = FALSE [static, protected]
 

Definition at line 196 of file outptdib.h.

LPLOGPALETTE OutputDIB::OutputPalette [protected]
 

Definition at line 176 of file outptdib.h.

UINT32 OutputDIB::SourceBitmapDepth [protected]
 

Definition at line 171 of file outptdib.h.

FilePos OutputDIB::StartPos [protected]
 

Definition at line 172 of file outptdib.h.


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