OutputGIF Class Reference

Contains functions to write a DIB to a GIF in segments, optionally with compression, optionally converting from one depth to another. To use: Open a CCLexFile 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. Similar to OutputDIB but strangely enough writes the data as a GIF instead of a BMP or via the AccusoftFilters. More...

#include <outptgif.h>

Inheritance diagram for OutputGIF:

OutputDIB List of all members.

Public Member Functions

 OutputGIF ()
 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 ~OutputGIF ()
virtual BOOL StartFile (LPBITMAPINFOHEADER lpHeader, LPLOGPALETTE Palette, UINT32 OutputDepth, DWORD CompressionType, UINT32 FinalHeight, INT32 ExportSize, UINT32 DitherType)
 Prepare to start the export of a GIF.
virtual BOOL ReStartFile (LOGPALETTE *pNewPal)
 Called to reset output before outputing another in a run of multiple images.
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...
virtual BOOL SetUpInfoHeader (const LPBITMAPINFOHEADER lpHeader, const UINT32 OutputDepth, const DWORD CompressionType, const UINT32 LIneWidth, const UINT32 FinalHeight, INT32 *PalSize)
 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.
BOOL OutputGifFileHeader (CCLexFile *File, LPBITMAPINFOHEADER pInfo, BOOL Enhanced, INT32 TransColour, LPLOGPALETTE pPalette=NULL, LPRGBQUAD pQuadPalette=NULL)
 Output a GIF file header for the specified bitmap to the file.
BOOL OutputGifFileHeader (CCLexFile *File, BOOL Enhanced, INT32 TransColour)
 Writes out the file header for the cached bitmap within this class.
BOOL OutputGifImageExtensionHeader (CCLexFile *File, BOOL InterlaceState, INT32 TransparentColour, UINT32 Delay, UINT32 RestoreType)
 Output a GIF image header for the specified bitmap to the file.
BOOL OutputGifImageBits (CCLexFile *File, LPBYTE pBlockStart, BOOL Interlace, BOOL LocalColourTable, BaseCamelotFilter *pFilter=NULL, UINT32 NewWidth=0, UINT32 NewHeight=0, UINT32 LeftOffset=0, UINT32 TopOffset=0, LPRGBQUAD pDestPalette=NULL, UINT32 PaletteColourDepth=0, UINT32 NewBitsPerPixel=0)
 Output the actual bits of a bitmap as compressed GIF data. Assumes that a header has already been output, possibly using OutputGifHeader. Assumes that all the data is present. The GIF specifcation allows us to output the next bitmap in an animation such that it is a subregion of a previous image. In this case we need to specify a new width and height plus a left and top offset.
BOOL OutputGifTerminator (CCLexFile *File)
 Outputs the GIF terminator sequence.
BOOL OutputAnimationControl (CCLexFile *File, unsigned short Repeats)
 Outputs a Netscape Animation Control block into the GIF file NOTE Must be inserted after file header but before image data.
virtual LPBITMAPINFO GetDestBitmapInfo (void)
 Access function to DestBitmapInfo.
virtual LPBYTE GetDestBitmapBits (void)
 Access function to DestBitmapBytes.
INT32 GetColourDepth (INT32 NumberOfColours)
 Converts the number of colours given into the colour depth that is required to output that number. This is not restricted to the colour depths of Window's DIBs i.e. 8, 4 and 1 but can be any colour depth less than 8 bpps.

Protected Types

typedef unsigned char char_type

Protected Member Functions

void CompressBlockToFile (LPBYTE Buffer, INT32 init_bits)
 Compress the specified bitmap out to the file specified in the class variable OutputFile. Assumes that variables such as Width, Height, WidthOfLine have been set up by the caller from the bitmap we are about to compress. This is done by the usual calling function of this OutputGifBits and OutputGifHeader.
void OutputCode (code_int code)
 Output the given code. This assumes that chars are 8 bits long. It maintains a GIFBITS character INT32 buffer (so that 8 codes will fit in it exactly). When the buffer fills up empty it and start over.
void ClearBlock ()
 Clear out the hash table for block compress.
void ClearHashTable (count_int hsize)
 reset the code table back to the default values
void CharacterInit ()
 Set up the 'byte output' routine.
void OutputCharacter (INT32 c)
 Add a character to the end of the current packet, and if it is 254 characters, flush the packet to disk.
void FlushCharacters ()
 Flush the packet to disk, and reset the accumulator (class variable a_count).
INT32 GIFNextPixel ()
 -Return the next pixel from the image using the class variables curx, cury as the current positions and afterwards moving them to the next positions. Takes into account if interlacing is on.
void BumpPixel ()
 Bump the class variables 'curx' and 'cury' to point to the next pixel taking into account interlacing if it is on.

Protected Attributes

LPBITMAPINFO DestBitmapInfo
LPBYTE DestBitmapBytes
LPBYTE pNextStrip
BaseCamelotFilterpCamFilter
INT32 Width
INT32 Height
INT32 curx
INT32 cury
INT32 CurrentLine
INT32 CountDown
BOOL InterlacingOn
INT32 Pass
WORD BitsPerPixel
INT32 InitCodeSize
INT32 Background
LPBYTE DataBuffer
UINT32 WidthOfLine
INT32 n_bits
code_int maxcode
count_int htab [5003]
unsigned short codetab [5003]
code_int free_ent
INT32 clear_flg
INT32 offset
INT32 in_count
INT32 out_count
INT32 g_init_bits
INT32 ClearCode
INT32 EOFCode
UINT32 cur_accum
INT32 cur_bits
INT32 a_count
char accum [256]

Detailed Description

Contains functions to write a DIB to a GIF in segments, optionally with compression, optionally converting from one depth to another. To use: Open a CCLexFile 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. Similar to OutputDIB but strangely enough writes the data as a GIF instead of a BMP or via the AccusoftFilters.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/4/95
See also:
OutputDIB;

Definition at line 142 of file outptgif.h.


Member Typedef Documentation

typedef unsigned char OutputGIF::char_type [protected]
 

Definition at line 206 of file outptgif.h.


Constructor & Destructor Documentation

OutputGIF::OutputGIF  ) 
 

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:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/4/95
See also:
OutputGIF::TidyUp

OutputDIB;

Definition at line 129 of file outptgif.cpp.

00130 {
00131     OutputFile = NULL;
00132     lpBitmap = NULL;
00133     ExportBuffer = NULL;
00134     DoExportConvert = NULL;
00135     OutputForward = FALSE;
00136 
00137     DestBitmapInfo = NULL;
00138     DestBitmapBytes = NULL;
00139 
00140     InterlacingOn = FALSE;
00141 
00142     pCamFilter = NULL;
00143 }

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

Definition at line 147 of file outptgif.h.

00147 {}


Member Function Documentation

void OutputGIF::BumpPixel  )  [protected]
 

Bump the class variables 'curx' and 'cury' to point to the next pixel taking into account interlacing if it is on.

Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 1696 of file outptgif.cpp.

01697 {
01698     // Bump the current X position
01699     ++curx;
01700 
01701     // If we are at the end of a scan line, set curx back to the beginning
01702     // If we are interlaced, bump the cury to the appropriate spot,
01703     // otherwise, just increment it.
01704     if( curx == Width )
01705     {
01706         // Reset x to start of next line
01707         curx = 0;
01708         
01709         CurrentLine++;
01710         
01711         // If Interlacing off then just increment the line we are on
01712         if( !InterlacingOn )
01713             ++cury;
01714         else
01715         {
01716             // Otherwise get the next interlaced line in the sequence
01717             // Use the same style of code that we use for import in GIFUtil
01718             switch (Pass)
01719             {
01720                 case 0:
01721                 case 1:
01722                     cury += 8;
01723                     break;
01724                 case 2:
01725                     cury += 4;
01726                     break;
01727                 case 3:
01728                     cury += 2;
01729                     break;
01730             }
01731 
01732             while (cury >= Height && Pass <= 3)
01733             {
01734                 ++Pass;
01735                 switch (Pass)
01736                 {
01737                     case 1:
01738                         cury = 4;
01739                         break;
01740                     case 2:
01741                         cury = 2;
01742                         break;
01743                     case 3:
01744                         cury = 1;
01745                         break;
01746                     default:
01747                         cury = 0;
01748                         break;
01749                 }
01750             }
01751         }
01752     
01753         // Show a progress bar
01754         if (pCamFilter == NULL)
01755         {
01756             // Andy, 13-12-00: We don't want another progress bar if we're exporting
01757             //ContinueSlowJob( (INT32)(100 * CurrentLine/(Height)) );
01758         }
01759         else
01760             pCamFilter->IncProgressBarCount(1);
01761     }
01762 }

void OutputGIF::CharacterInit  )  [protected]
 

Set up the 'byte output' routine.

Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 1511 of file outptgif.cpp.

01512 {
01513     a_count = 0;        // set accumlator to zero
01514 }

void OutputGIF::ClearBlock  )  [protected]
 

Clear out the hash table for block compress.

Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 1441 of file outptgif.cpp.

01442 {
01443     ClearHashTable( (count_int) hsize );
01444     free_ent = ClearCode + 2;
01445     clear_flg = 1;
01446 
01447     OutputCode( (code_int)ClearCode );
01448 }

void OutputGIF::ClearHashTable count_int  hsize  )  [protected]
 

reset the code table back to the default values

Parameters:
hsize size of the maximum code size [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 1461 of file outptgif.cpp.

01462 {
01463     // These used to have register in front of them
01464     count_int *htab_p = htab + hsize;
01465     INT32 i;
01466     INT32 m1 = -1;
01467 
01468     i = hsize - 16;
01469     do
01470     {
01471         *(htab_p - 16) = m1;
01472         *(htab_p - 15) = m1;
01473         *(htab_p - 14) = m1;
01474         *(htab_p - 13) = m1;
01475         *(htab_p - 12) = m1;
01476         *(htab_p - 11) = m1;
01477         *(htab_p - 10) = m1;
01478         *(htab_p - 9) = m1;
01479         *(htab_p - 8) = m1;
01480         *(htab_p - 7) = m1;
01481         *(htab_p - 6) = m1;
01482         *(htab_p - 5) = m1;
01483         *(htab_p - 4) = m1;
01484         *(htab_p - 3) = m1;
01485         *(htab_p - 2) = m1;
01486         *(htab_p - 1) = m1;
01487         htab_p -= 16;
01488     } while ((i -= 16) >= 0);
01489 
01490     for ( i += 16; i > 0; --i )
01491         *--htab_p = m1;
01492 }

void OutputGIF::CompressBlockToFile LPBYTE  Buffer,
INT32  init_bits
[protected]
 

Compress the specified bitmap out to the file specified in the class variable OutputFile. Assumes that variables such as Width, Height, WidthOfLine have been set up by the caller from the bitmap we are about to compress. This is done by the usual calling function of this OutputGifBits and OutputGifHeader.

Parameters:
Buffer pointer to the bits to be compressed [INPUTS] init_bits initial number of bits
- [OUTPUTS]
See also:
OutputGIF::OutputGifHeader; OutputGIF::OutputGifBits;

Definition at line 1255 of file outptgif.cpp.

01256 {
01257     // These used to have register before them
01258     INT32       fcode;
01259     code_int    i;  //= 0;
01260     INT32       c;
01261     code_int    ent;
01262     code_int    disp;
01263     code_int    hsize_reg;
01264     INT32       hshift;
01265 
01266     // Note the passed in buffer and size in our class variables
01267     DataBuffer  = Buffer;
01268 
01269     // Calculate number of bits we are expecting
01270     CountDown   = (INT32)Width * (INT32)Height;
01271 
01272     // Work out the word/byte rounded line width rather than the pixel width
01273     WidthOfLine = DIBUtil::ScanlineSize( Width, BitsPerPixel );
01274 
01275     // Set up the globals:  g_init_bits - initial number of bits
01276     g_init_bits = init_bits;
01277 
01278     // Set up the necessary values
01279     offset      = 0;
01280     out_count   = 0;
01281     clear_flg   = 0;
01282     in_count    = 1;
01283     maxcode     = MAXCODE(n_bits = init_bits);
01284     ClearCode   = (1 << (init_bits - 1));
01285     EOFCode     = ClearCode + 1;
01286     free_ent    = ClearCode + 2;
01287 
01288     // Indicate which pass we are on (if interlace)
01289     Pass        = 0;
01290 
01291     // Set up the current x and y position
01292     curx        = 0;
01293     cury        = 0;
01294     CurrentLine = 0;
01295 
01296     cur_accum   = 0;
01297     cur_bits    = 0;
01298 
01299     CharacterInit();    // a_count = 0;
01300 
01301     ent = GIFNextPixel();
01302 
01303     hshift = 0;
01304     for ( fcode = (INT32) hsize;  fcode < 65536L; fcode *= 2L )
01305         ++hshift;
01306     hshift = 8 - hshift;                // set hash code range bound
01307 
01308     // clear hash table
01309     hsize_reg = hsize;
01310     ClearHashTable( (count_int) hsize_reg); 
01311 
01312     OutputCode( (code_int)ClearCode );
01313 
01314     while ( (c = GIFNextPixel()) != EOF )
01315     {
01316         ++in_count;
01317 
01318         fcode = (INT32) (((INT32) c << maxbits) + ent);
01319         i = (((code_int)c << hshift) ^ ent);    // xor hashing
01320 
01321         if ( HashTabOf(i) == fcode )
01322         {
01323             ent = CodeTabOf(i);
01324             continue;
01325         }
01326         else if ( (INT32)HashTabOf(i) < 0 )      // empty slot
01327             goto nomatch;
01328 
01329         disp = hsize_reg - i;                   // secondary hash (after G. Knott)
01330         if ( i == 0 )
01331             disp = 1;
01332             
01333 probe:
01334         if ( (i -= disp) < 0 )
01335             i += hsize_reg;
01336 
01337         if ( HashTabOf(i) == fcode )
01338         {
01339             ent = CodeTabOf(i);
01340             continue;
01341         }
01342         if ( (INT32)HashTabOf(i) > 0 )
01343             goto probe;
01344             
01345 nomatch:
01346         OutputCode( (code_int) ent );
01347         ++out_count;
01348         ent = c;
01349         if ( free_ent < maxmaxcode )
01350         {
01351             CodeTabOf(i) = free_ent++; /* code -> hashtable */
01352             HashTabOf(i) = fcode;
01353         }
01354         else
01355             ClearBlock();
01356     }
01357     // Put out the final code.
01358     OutputCode( (code_int) ent );
01359     ++out_count;
01360     OutputCode( (code_int) EOFCode );
01361 }

void OutputGIF::FlushCharacters  )  [protected]
 

Flush the packet to disk, and reset the accumulator (class variable a_count).

Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 1546 of file outptgif.cpp.

01547 {
01548     if( a_count > 0 )
01549     {
01550         OutputFile->put( a_count );
01551         OutputFile->write( &accum, a_count);
01552         a_count = 0;
01553     }
01554 }

INT32 OutputGIF::GetColourDepth INT32  NumberOfColours  ) 
 

Converts the number of colours given into the colour depth that is required to output that number. This is not restricted to the colour depths of Window's DIBs i.e. 8, 4 and 1 but can be any colour depth less than 8 bpps.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/5/97
Parameters:
NumberOfColours The number of colours in the palette of the bitmap [INPUTS]
- [OUTPUTS]
Returns:
The colour depth

Definition at line 773 of file outptgif.cpp.

00774 {
00775     INT32 ColourDepth = 8;
00776     if (NumberOfColours <= 2)
00777         // Changed by Craig Hamilton 14/9/00.
00778         ColourDepth = 1;
00779         // End changed.
00780     else if (NumberOfColours <= 4)
00781         ColourDepth = 2;
00782     else if (NumberOfColours <= 8)
00783         ColourDepth = 3;
00784     else if (NumberOfColours <= 16)
00785         ColourDepth = 4;
00786     else if (NumberOfColours <= 32)
00787         ColourDepth = 5;
00788     else if (NumberOfColours <= 64)
00789         ColourDepth = 6;
00790     else if (NumberOfColours <= 128)
00791         ColourDepth = 7;
00792     else if (NumberOfColours <= 256)
00793         ColourDepth = 8;
00794 
00795     return ColourDepth;
00796 }

LPBYTE OutputGIF::GetDestBitmapBits void   )  [virtual]
 

Access function to DestBitmapBytes.

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:
A pointer to the bitmap itself.

Reimplemented from OutputDIB.

Definition at line 753 of file outptgif.cpp.

00754 {
00755     return DestBitmapBytes;
00756 }

LPBITMAPINFO OutputGIF::GetDestBitmapInfo void   )  [virtual]
 

Access function to DestBitmapInfo.

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:
A pointer to the bitmap information structure.

Reimplemented from OutputDIB.

Definition at line 736 of file outptgif.cpp.

00737 {
00738     return DestBitmapInfo;
00739 }

INT32 OutputGIF::GIFNextPixel  )  [protected]
 

-Return the next pixel from the image using the class variables curx, cury as the current positions and afterwards moving them to the next positions. Takes into account if interlacing is on.

Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
the value of the specified pixel or 0 if badly specified

Definition at line 1607 of file outptgif.cpp.

01608 {
01609     INT32 Pixel;
01610 
01611     // First, check whether we have done all the pixels in the image
01612     if( CountDown == 0 )
01613         return EOF;
01614 
01615     // Decrement our pixel count
01616     --CountDown;
01617 
01618     //r = GetPixel(curx, cury);
01619     if ( !(((cury < 0) || (cury >= Height)) || ((curx < 0) || (curx >= Width))) && DataBuffer )
01620     {
01621         // Our DIBs are the wrong way up so we must output the data from the last 
01622         // line of the image and go up to the start
01623         // -1 as height = 1 .. Height whereas y goes from 0 .. Height - 1
01624         // Use the word/byte rounded line width rather than the pixel width
01625         // always compresses a byte regardless of colour depth. 
01626         switch (BitsPerPixel)
01627         {
01628             case 8:
01629                 {
01630                     // If 8 bpp then just use the whole byte straight
01631                     LPBYTE pData = DataBuffer + curx + ((Height - 1 - cury)  * WidthOfLine);
01632                     Pixel = *(pData);
01633                 }
01634                 break;
01635 
01636             case 4:
01637                 {
01638                     // 4bpp so we must get the high or low nibble. This will be dependent on
01639                     // whether we are on an odd or even pixel. So test the LSBit of the curx,
01640                     // if set we will be odd. Only move onto next byte every other pixel hence
01641                     // curx/2.
01642                     LPBYTE pData = DataBuffer + curx/2 + ((Height - 1 - cury)  * WidthOfLine);
01643                     Pixel = *(pData);
01644                     if (curx & 1)
01645                         Pixel = (Pixel & 0x0F);         // take low nibble 
01646                     else
01647                         Pixel = (Pixel & 0xF0) >> 4;    // take top nibble 
01648                 }
01649                 break;
01650             case 1:
01651                 {
01652                     // 1bpp - pixels are stored in bits.
01653                     LPBYTE pData = DataBuffer + curx/8 + ((Height - 1 - cury)  * WidthOfLine);
01654                     BYTE Mask = 0x80 >> (curx % 8);
01655                     if (((*pData) & Mask) == 0)
01656                         Pixel = 0;
01657                     else
01658                         Pixel = 1;
01659                 }
01660                 break;
01661             default:
01662                 ERROR3("Unknown export depth");
01663                 Pixel = 0;  // bad bpp but should not get here
01664             }
01665     }
01666     else
01667     {
01668         ERROR3("Something bad has happened");
01669         Pixel = 0;
01670     }
01671     
01672     // Move the curx, cury to the next pixel on the image taking into account interlacing
01673     BumpPixel();
01674 
01675     // Check that the pixel is not outside of the allowed range
01676     // If it is then what do we do with it? Set it 0 for now.
01677     ERROR3IF(Pixel >= ClearCode,"Trying to output pixel >= ClearCode");
01678     if (Pixel >= ClearCode)
01679         Pixel = 0;
01680 
01681     return Pixel;
01682 }

BOOL OutputGIF::OutputAnimationControl CCLexFile File,
unsigned short  Repeats
 

Outputs a Netscape Animation Control block into the GIF file NOTE Must be inserted after file header but before image data.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/6/96
Parameters:
File - file to output to [INPUTS]
- [OUTPUTS]
Returns:
TRUE if worked, FALSE if failed

Definition at line 686 of file outptgif.cpp.

00687 {
00688     ERROR2IF(File==NULL,FALSE,"OutputGIF::OutputAnimationControl File pointer is null");
00689 
00690     BOOL OldThrowingState = File->SetThrowExceptions( TRUE );
00691     BOOL OldReportingState = File->SetReportErrors( FALSE );
00692     try
00693     {
00694         // Generate the Netscape Extension block
00695         BYTE Block[19];
00696         Block[0] = 0x21;    // GIF extension code
00697         Block[1] = 0xFF;    // Application extension
00698         Block[2] = 0x0B;    // Length of application string
00699         memcpy(Block+3, "NETSCAPE2.0", 0x0B);   // Application string
00700         Block[14] = 0x03;   // Length of data sub-block
00701         Block[15] = 0x01;   // ??
00702         Block[16] = Repeats & 0xFF; // Low byte of repeats
00703         Block[17] = Repeats >> 8;   // High byte of repeats
00704         Block[18] = 0;      // Terminator
00705 
00706         File->write(Block, 19);
00707 
00708         File->SetThrowExceptions( OldThrowingState );
00709         File->SetReportErrors( OldReportingState );
00710 
00711         return TRUE;
00712     }
00713     catch(...)
00714     {
00715         File->SetThrowExceptions( OldThrowingState );
00716         File->SetReportErrors( OldReportingState );
00717 
00718         return FALSE;
00719     }
00720 
00721     ERROR2( FALSE, "Escaped exception clause somehow" );
00722 }   

void OutputGIF::OutputCharacter INT32  c  )  [protected]
 

Add a character to the end of the current packet, and if it is 254 characters, flush the packet to disk.

Parameters:
c character to add to the output stream [INPUTS]
- [OUTPUTS]
Returns:
-

Definition at line 1528 of file outptgif.cpp.

01529 {
01530     accum[ a_count++ ] = c;
01531     if( a_count >= 255 )        // was 254 until 16/4/97 - Gavin suggested tweak
01532         FlushCharacters();
01533 }

void OutputGIF::OutputCode code_int  code  )  [protected]
 

Output the given code. This assumes that chars are 8 bits long. It maintains a GIFBITS character INT32 buffer (so that 8 codes will fit in it exactly). When the buffer fills up empty it and start over.

Parameters:
code A n_bits-bit integer. If == -1, then EOF. [INPUTS] This assumes that n_bits =< (INT32)wordsize - 1.
Outputs code to the file. [OUTPUTS]

Definition at line 1377 of file outptgif.cpp.

01378 {
01379     cur_accum &= masks[ cur_bits ];
01380 
01381     if( cur_bits > 0 )
01382         cur_accum |= ((INT32)code << cur_bits);
01383     else
01384         cur_accum = code;
01385 
01386     cur_bits += n_bits;
01387 
01388     while( cur_bits >= 8 )
01389     {
01390         OutputCharacter( (UINT32)(cur_accum & 0xff) );
01391         cur_accum >>= 8;
01392         cur_bits -= 8;
01393     }
01394 
01395     // If the next entry is going to be too big for the code size, then increase it,
01396     // if possible.
01397     if ( free_ent > maxcode || clear_flg )
01398     {
01399         if( clear_flg )
01400         {
01401             maxcode = MAXCODE(n_bits = g_init_bits);
01402             clear_flg = 0;
01403         }
01404         else
01405         {
01406             ++n_bits;
01407             if ( n_bits == maxbits )
01408                 maxcode = maxmaxcode;
01409             else
01410                 maxcode = MAXCODE(n_bits);
01411         }
01412     }
01413 
01414     if( code == EOFCode )
01415     {
01416         // At EOF, write the rest of the buffer.
01417         while( cur_bits > 0 )
01418         {
01419             OutputCharacter( (UINT32)(cur_accum & 0xff) );
01420             cur_accum >>= 8;
01421             cur_bits -= 8;
01422         }
01423 
01424         FlushCharacters();
01425 
01426         OutputFile->flush();
01427     }
01428 }

BOOL OutputGIF::OutputGifFileHeader CCLexFile File,
BOOL  Enhanced,
INT32  TransColour
 

Writes out the file header for the cached bitmap within this class.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
12/6/96
Parameters:
File - output file object [INPUTS] Enhanced - TRUE if enhanced GIF features are required (eg transpacency) TransColour - the index of the transparent colour (-1 for no transparency)
- [OUTPUTS]
Returns:
TRUE if worked, FALSE if failed
See also:
OutputGIF::OutputGifFileHeader (the other one)

Definition at line 418 of file outptgif.cpp.

00419 {
00420     return OutputGifFileHeader(File, &(DestBitmapInfo->bmiHeader), Enhanced, TransColour, OutputPalette);
00421 }

BOOL OutputGIF::OutputGifFileHeader CCLexFile File,
LPBITMAPINFOHEADER  pInfo,
BOOL  Enhanced,
INT32  TransColour,
LPLOGPALETTE  pPalette = NULL,
LPRGBQUAD  pQuadPalette = NULL
 

Output a GIF file header for the specified bitmap to the file.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/4/95
Parameters:
File file to output to [INPUTS] pInfo pointer to the bitmap info header Enhanced TRUE if useing advanced GIF features such as transparency or animation TransColour The transparent index or -1 if no transparency pPalette pointer to a palette in LOGPALETTE form (defaults to NULL) OR pQuadPalette pointer to a palette in RGBQUAD form (defaults to NULL)
- [OUTPUTS]
Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)

Errors: Calls SetError on FALSE returns.

See also:
OutputGIF::StartFile; OutputGIF::WriteBlock; OutputGIF::TidyUp Scope: static

Definition at line 445 of file outptgif.cpp.

00446 {
00447     ERROR2IF(File==NULL,FALSE,"OutputGIF::OutputGifHeader File pointer is null");
00448     ERROR2IF(pInfo==NULL,FALSE,"OutputGIF::OutputGifHeader BitmapInfo pointer is null");
00449     ERROR2IF(pPalette==NULL && pQuadPalette==NULL,FALSE,"OutputGIF::OutputGifHeader Bitmap palette pointer is null");
00450 
00451     // Note file in our class variable as used by all the low level routines
00452     OutputFile = File;
00453 
00454     // Must set the exception throwing flag to True and force reporting of errors to False.
00455     // This means that the caller must report an error if the function returns False.
00456     // Any calls to CCFile::GotError will now throw a file exception and should fall into
00457     // the catch handler at the end of the function.
00458     // Replaces the goto's that handled this before.
00459     BOOL OldThrowingState = File->SetThrowExceptions( TRUE );
00460     BOOL OldReportingState = File->SetReportErrors( FALSE );
00461 
00462     try
00463     {
00464         // Set up the class variables
00465         // First the width/height of the bitmap
00466         Width = pInfo->biWidth;
00467         Height = pInfo->biHeight;
00468         INT32 PalSize = pInfo->biClrUsed;
00469         // Translate this into a bits per pixel which is not limited to 8, 4 and 1.
00470         INT32 ColourDepth = GetColourDepth(PalSize);
00471         // ColourDepth will be rounded to nearest power of two so need to output
00472         // that many palette entries
00473         INT32 NewPalSize = 1 << ColourDepth;
00474         InitCodeSize = ColourDepth;
00475 
00476         BitsPerPixel = pInfo->biBitCount;
00477 
00478         TRACEUSER( "Neville", _T("OutputGifFileHeader - Colour depth = %d\n"),ColourDepth);
00479 
00480         // Write out the unique GIF header
00481         GIFINFOHEADER Header;
00482         if (Enhanced)
00483             memcpy(Header.giName, "GIF89a", 6); 
00484         else
00485             memcpy(Header.giName, "GIF87a", 6); 
00486             
00487         // Indicate that there is a global colour map
00488         BYTE Flags = 0;
00489         // global colour table flag, colour resoltion sort flag and 
00490         // size of global colour table
00491         if ((pPalette || pQuadPalette) && (PalSize > 0))
00492             Flags  = 0x80;                  // Flag there is a colour map
00493         // 3 bit colour resolution value = number of bits per primary colour - 1
00494         Flags |= ((BitsPerPixel - 1) & 0x07) << 4;  // OR in the colour resolution
00495         // 3 bit size of global colour table = number of bits - 1
00496         Flags |= (ColourDepth - 1) & 0x07;  // OR in global colour table size
00497 
00498         Header.giWidth      = (WORD)Width;
00499         Header.giHeight     = (WORD)Height;
00500         Header.giFlags      = Flags;
00501         Header.giBackground = TransColour==-1 ? 0 : TransColour;
00502         Header.giAspect     = 0;
00503         // This is really sizeof(GIFINFOHEADER) but this returns 14 instead of 13
00504         // as it rounds to the nearest word boundary
00505         const size_t HeaderSize = sizeof(char)* 6 + sizeof(WORD) * 2 + sizeof(BYTE) * 3;
00506         File->write( &Header, HeaderSize );
00507 
00508         if (pQuadPalette && NewPalSize > 0)
00509         {
00510             // Palette supplied in RGBQUAD form 
00511             // write it to disk in GIFRGBTRIPLE format
00512             GIFRGBTRIPLE TempRGB;
00513             for (INT32 i = 0; i < NewPalSize; i++)
00514             {
00515                 // If we are using transparency then bodge the transparent colour to
00516                 // be White. Otherwise, if we load it back it then we could have a strange
00517                 // colour being shown as we don't support transparency on loading.
00518                 if (TransColour >= 0 && i == TransColour)
00519                 {
00520                     // Make transparent colour white
00521                     TempRGB.grgbtRed    = 0xFF;
00522                     TempRGB.grgbtGreen  = 0xFF;
00523                     TempRGB.grgbtBlue   = 0xFF;
00524                 }
00525                 else if (i > PalSize)
00526                 {
00527                     // Make blank palette entries black
00528                     TempRGB.grgbtRed    = 0x00;
00529                     TempRGB.grgbtGreen  = 0x00;
00530                     TempRGB.grgbtBlue   = 0x00;
00531                 }
00532                 else
00533                 {
00534                     TempRGB.grgbtRed    = pQuadPalette->rgbRed;
00535                     TempRGB.grgbtGreen  = pQuadPalette->rgbGreen;
00536                     TempRGB.grgbtBlue   = pQuadPalette->rgbBlue;
00537                 }
00538                 
00539                 File->write( &TempRGB, sizeof(GIFRGBTRIPLE) );
00540                 // skip to the next palette entry
00541                 pQuadPalette++;
00542             }
00543         }
00544         else if (pPalette && NewPalSize > 0)
00545         {
00546             // Palette supplied in LOGPALETTE form 
00547             // write it to disk in GIFRGBTRIPLE format
00548             GIFRGBTRIPLE TempRGB;
00549             for (INT32 i = 0; i < NewPalSize; i++)
00550             {
00551                 // If we are using transparency then bodge the transparent colour to
00552                 // be White. Otherwise, if we load it back it then we could have a strange
00553                 // colour being shown as we don't support transparency on loading.
00554                 if (TransColour >= 0 && i == TransColour)
00555                 {
00556                     // Make transparent colour white
00557                     TempRGB.grgbtRed    = 0xFF;
00558                     TempRGB.grgbtGreen  = 0xFF;
00559                     TempRGB.grgbtBlue   = 0xFF;
00560                 }
00561                 else if (i > PalSize)
00562                 {
00563                     // Make blank palette entries black
00564                     TempRGB.grgbtRed    = 0x00;
00565                     TempRGB.grgbtGreen  = 0x00;
00566                     TempRGB.grgbtBlue   = 0x00;
00567                 }
00568                 else
00569                 {
00570                     TempRGB.grgbtRed    = pPalette->palPalEntry[i].peRed;
00571                     TempRGB.grgbtGreen  = pPalette->palPalEntry[i].peGreen;
00572                     TempRGB.grgbtBlue   = pPalette->palPalEntry[i].peBlue;
00573                 }
00574                 File->write( &TempRGB, sizeof(GIFRGBTRIPLE) );
00575             }
00576         }
00577         else
00578             ERROR3("OutputGIF::OutputGifHeader No palette specified");
00579 
00580         // Must set the exception throwing and reporting flags back to their entry states
00581         File->SetThrowExceptions( OldThrowingState );
00582         File->SetReportErrors( OldReportingState );
00583 
00584         // er, we seem to have finished OK so say so
00585         return TRUE;
00586     }
00587     catch(...)
00588     {
00589         // catch our form of a file exception
00590         TRACE( _T("OutputGIF::OutputGifHeader CC catch handler\n"));
00591 
00592         // Must set the exception throwing and reporting flags back to their entry states
00593         File->SetThrowExceptions( OldThrowingState );
00594         File->SetReportErrors( OldReportingState );
00595 
00596         return FALSE;
00597     }
00598 
00599     ERROR2( FALSE, "Escaped exception clause somehow" );
00600 }   

BOOL OutputGIF::OutputGifImageBits CCLexFile File,
LPBYTE  pBlockStart,
BOOL  Interlace,
BOOL  LocalColourTable,
BaseCamelotFilter pFilter = NULL,
UINT32  NewWidth = 0,
UINT32  NewHeight = 0,
UINT32  LeftOffset = 0,
UINT32  TopOffset = 0,
LPRGBQUAD  pDestPalette = NULL,
UINT32  PaletteColourDepth = 0,
UINT32  NewBitsPerPixel = 0
 

Output the actual bits of a bitmap as compressed GIF data. Assumes that a header has already been output, possibly using OutputGifHeader. Assumes that all the data is present. The GIF specifcation allows us to output the next bitmap in an animation such that it is a subregion of a previous image. In this case we need to specify a new width and height plus a left and top offset.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/4/95
Parameters:
File pointer to file to output to [INPUTS] pBlockStart actual bitmap data to write out Interlace TRUE if image should be interlaced LocalColourTable True if need to specify a local colour table, False if the global one is all that is required pFilter is an alternative way of handling the progress bar, assume the progress bar has been start and just call the IncProgressBarCount in BaseCamelotFilter to do the progress bar update. Defaults to NULL i.e. no progress bar. NewWidth The new width of this bitmap, defaults to 0 meaning none NewHeight The new height of this bitmap, defaults to 0 meaning none LeftOffset The offset of this bitmap from the left hand side, defaults to 0 TopOffset The offset of this bitmap from the top hand side, defaults to 0 pDestPalette The local palette to output NumberOfPalColours The number of colours in this local palette NewBitsPerPixel The new bits per pixel of the bitmap, defaults to 0 meaning none
- [OUTPUTS]
Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)

Errors: Calls SetError on FALSE returns.

See also:
OutputGIF::OutputGifHeader; SeeAlo: OutputGIF::StartFile; OutputGIF::WriteBlock; OutputGIF::TidyUp Scope: static
Note: If we use the NewWidth and NewHeight input variables then we must ALWAYS input the height and width of the bitmap.

Definition at line 842 of file outptgif.cpp.

00847 {
00848     ERROR2IF(File==NULL,FALSE,"OutputGIF::OutputGifHeader File pointer is null");
00849     ERROR2IF(pBlockStart==NULL,FALSE,"OutputGIF::OutputGifHeader BitmapInfo pointer is null");
00850 
00851     // Note file in our class variable as used by all the low level routines
00852     OutputFile = File;
00853     InterlacingOn = Interlace;
00854 
00855     // Set up our pointer to the alternative way of handling the progress bar
00856     // If it is the NULL default then do not use.
00857     pCamFilter = pFilter;
00858 
00859     if (NewWidth > 0 && NewHeight > 0)
00860     {
00861         // Set the statics to the new values. If we use this method then we must ALWAYS input
00862         // the height and width of the bitmap.
00863         Width = NewWidth;
00864         Height = NewHeight;
00865     }
00866 
00867     ERROR3IF(NewBitsPerPixel > 8,"Bad BPP in OutputGifImageBits");
00868     if (NewBitsPerPixel > 0 && NewBitsPerPixel <= 8)
00869         BitsPerPixel = NewBitsPerPixel;
00870 
00871     // Must set the exception throwing flag to True and force reporting of errors to False.
00872     // This means that the caller must report an error if the function returns False.
00873     // Any calls to CCFile::GotError will now throw a file exception and should fall into
00874     // the catch handler at the end of the function.
00875     // Replaces the goto's that handled this before.
00876     BOOL OldThrowingState = File->SetThrowExceptions( TRUE );
00877     BOOL OldReportingState = File->SetReportErrors( FALSE );
00878 
00879     try
00880     {
00881         // Write an Image separator
00882         File->put(0x2C);
00883 
00884         // The initial code size
00885         if( BitsPerPixel <= 1 )
00886             InitCodeSize = 2;
00887         else
00888             InitCodeSize = BitsPerPixel;
00889 
00890         UINT32 ColourDepth = 1;
00891         
00892         if (pDestPalette && PaletteColourDepth > 0)
00893         {
00894             // Translate the number of colours into a bits per pixel which is not limited to 8, 4 and 1.
00895             ColourDepth = GetColourDepth(PaletteColourDepth);
00896             InitCodeSize = ColourDepth;
00897         }
00898         else
00899         {
00900             // Direct saving a bitmap has this set to null
00901             //ERROR3IF(DestBitmapInfo == NULL,"Bad DestBitmapInfo in OutputGifImageBits");
00902             if (DestBitmapInfo)
00903             {
00904                 ColourDepth = DestBitmapInfo->bmiHeader.biBitCount;
00905                 InitCodeSize = GetColourDepth(DestBitmapInfo->bmiHeader.biClrUsed);
00906             }
00907             else
00908                 ColourDepth = BitsPerPixel;
00909         }
00910 
00911         // Sanity check on the code size
00912         if (InitCodeSize > 8)
00913             InitCodeSize = 8;
00914         if (InitCodeSize < 2)
00915             InitCodeSize = 2;
00916 
00917         TRACEUSER( "Neville", _T("OutputGifImageBits - Colour depth = %d\n"),ColourDepth);
00918         
00919         // Write the Image header
00920         GIFIMAGEBLOCK ImageHeader;
00921         ImageHeader.gibLeft     = (WORD)LeftOffset; // Left Offset defaults to zero
00922         ImageHeader.gibTop      = (WORD)TopOffset;  // Top Offset defaults to zero
00923         ImageHeader.gibWidth    = (WORD)Width;
00924         ImageHeader.gibDepth    = (WORD)Height;
00925         // Flags consists of:-
00926         //  Local Color Table Flag        1 Bit
00927         //  Interlace Flag                1 Bit
00928         //  Sort Flag                     1 Bit
00929         //  Reserved                      2 Bits
00930         //  Size of Local Color Table     3 Bits
00931         ImageHeader.gibFlags    = (LocalColourTable ? 0x80 : 0) | (Interlace ? 0x40 : 0) | 
00932                                                 (LocalColourTable ? (ColourDepth - 1) : 0);
00933         File->write(&ImageHeader, 9);
00934 
00935         // Save the local colour table - it follows straight on
00936         if (LocalColourTable)
00937         {
00938             if (pDestPalette && PaletteColourDepth > 0)
00939             {
00940                 TRACEUSER( "Neville", _T("OutputGifImageBits - Output local palette table (Extended)\n"));
00941                 // Somebody supplied a palette in RGBQUAD form for us to output so do so.
00942                 // write it to disk in GIFRGBTRIPLE format
00943                 GIFRGBTRIPLE TempRGB;
00944                 for (INT32 loop = 0; loop < ((1 << ColourDepth)); loop++)
00945                 {
00946                     TempRGB.grgbtRed    = pDestPalette->rgbRed;
00947                     TempRGB.grgbtGreen  = pDestPalette->rgbGreen;
00948                     TempRGB.grgbtBlue   = pDestPalette->rgbBlue;
00949                     pDestPalette++;
00950 
00951                     File->write( &TempRGB, sizeof(GIFRGBTRIPLE) );
00952                 }
00953             }
00954             else if (OutputPalette && ColourDepth > 0)
00955             {
00956                 TRACEUSER( "Neville", _T("OutputGifImageBits - Output local palette table\n"));
00957                 //ERROR3IF(OutputPalette == NULL,"Bad OutputPalette in OutputGifImageBits")
00958                 // Use the palette stored inside the DestBitmapInfo and OutputPalette class variables
00959                 GIFRGBTRIPLE TempRGB;
00960                 for (INT32 loop = 0; loop < ((1 << ColourDepth)); loop++)
00961                 {
00962                     TempRGB.grgbtRed    = OutputPalette->palPalEntry[loop].peRed;
00963                     TempRGB.grgbtGreen  = OutputPalette->palPalEntry[loop].peGreen;
00964                     TempRGB.grgbtBlue   = OutputPalette->palPalEntry[loop].peBlue;
00965 
00966                     File->write( &TempRGB, sizeof(GIFRGBTRIPLE) );
00967                 }
00968             }
00969             else
00970                 ERROR3("Trying to output local palette when none specified!");
00971         }
00972 
00973         // Write out the initial code size
00974         File->put( InitCodeSize );
00975 
00976         // It is now ready to go and put that data onto the disc
00977         // so wait for the bitmap data to be prepared
00978 
00979         // Go and actually compress the data
00980         CompressBlockToFile( pBlockStart, InitCodeSize + 1 );
00981 
00982         // Write out a Zero-length packet (to end the series)
00983         File->put( 0 );
00984 
00985         // Must set the exception throwing and reporting flags back to their entry states
00986         File->SetThrowExceptions( OldThrowingState );
00987         File->SetReportErrors( OldReportingState );
00988 
00989         return TRUE;
00990     }
00991 
00992     catch(...)
00993     {
00994         // catch our form of a file exception
00995         TRACE( _T("OutputGIF::OutputGifHeader CC catch handler\n"));
00996 
00997         // Must set the exception throwing and reporting flags back to their entry states
00998         File->SetThrowExceptions( OldThrowingState );
00999         File->SetReportErrors( OldReportingState );
01000 
01001         return FALSE;
01002     }
01003 
01004     ERROR2( FALSE, "Escaped exception clause somehow" );
01005 }   

BOOL OutputGIF::OutputGifImageExtensionHeader CCLexFile File,
BOOL  InterlaceState,
INT32  TransparentColour,
UINT32  Delay,
UINT32  RestoreType
 

Output a GIF image header for the specified bitmap to the file.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> - from Neville code
Date:
14/6/96
Parameters:
File file to output to [INPUTS] InterlaceState TRUE if image should be interlaced TransparentColour index of transparent colour or -1 for no transparency Delay Delay in millseconds between this frame and the previous one RestoreType GIF image restore type (0-3)
- [OUTPUTS]
Returns:
TRUE if worked, FALSE if failed

Definition at line 618 of file outptgif.cpp.

00619 {
00620     ERROR2IF(File==NULL,FALSE,"OutputGIF::OutputGifHeader File pointer is null");
00621     ERROR3IF(RestoreType > 3, "Unknown GIF image restore type");
00622 
00623     // Note file in our class variable as used by all the low level routines
00624     OutputFile = File;
00625     InterlacingOn = InterlaceState;
00626 
00627     UINT32 TranspFlag = (TransparentColour >= 0) ? 1 : 0;
00628 
00629     // Must set the exception throwing flag to True and force reporting of errors to False.
00630     // This means that the caller must report an error if the function returns False.
00631     // Any calls to CCFile::GotError will now throw a file exception and should fall into
00632     // the catch handler at the end of the function.
00633     // Replaces the goto's that handled this before.
00634     BOOL OldThrowingState = File->SetThrowExceptions( TRUE );
00635     BOOL OldReportingState = File->SetReportErrors( FALSE );
00636     try
00637     {
00638         GIFTRANSBLOCK TransBlock;
00639         TransBlock.gtbBlockStart    = EXTENSIONBLOCK;
00640         TransBlock.gtbIdentifier    = TRANSPARENTBLOCK;
00641         TransBlock.gtbBlockSize     = 4;
00642         TransBlock.gtbFlags         = TranspFlag | ((RestoreType & 0x03) << 2);
00643         TransBlock.gtbDelay         = Delay;            // 
00644         TransBlock.gtbTransparency  = TranspFlag ? TransparentColour : 0;
00645         TransBlock.gtbTerminator    = 0;
00646 
00647         // This is really sizeof(GIFTRANSBLOCK) but this returns 14 instead of 13
00648         // as it rounds to the nearest word boundary
00649         const size_t TransBlockSize = sizeof(WORD) * 1 + sizeof(BYTE) * 6;
00650         File->write( &TransBlock, TransBlockSize );
00651 
00652         // Must set the exception throwing and reporting flags back to their entry states
00653         File->SetThrowExceptions( OldThrowingState );
00654         File->SetReportErrors( OldReportingState );
00655 
00656         return TRUE;
00657     }
00658     catch(...)
00659     {
00660         // catch our form of a file exception
00661         TRACE( _T("OutputGIF::OutputGifHeader CC catch handler\n"));
00662 
00663         // Must set the exception throwing and reporting flags back to their entry states
00664         File->SetThrowExceptions( OldThrowingState );
00665         File->SetReportErrors( OldReportingState );
00666 
00667         return FALSE;
00668     }
00669 
00670     ERROR2( FALSE, "Escaped exception clause somehow" );
00671 }   

BOOL OutputGIF::OutputGifTerminator CCLexFile File  ) 
 

Outputs the GIF terminator sequence.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/4/95
Parameters:
File pointer to file to output to [INPUTS]
- [OUTPUTS]
Returns:
TRUE if worked, FALSE if failed

Definition at line 1020 of file outptgif.cpp.

01021 {
01022     ERROR2IF(File==NULL,FALSE,"OutputGIF::OutputGifTerminator File pointer is null");
01023 
01024     BOOL OldThrowingState = File->SetThrowExceptions( TRUE );
01025     BOOL OldReportingState = File->SetReportErrors( FALSE );
01026 
01027     try
01028     {
01029         // Write the GIF file terminator
01030         File->put( ';' );
01031 
01032         // Must set the exception throwing and reporting flags back to their entry states
01033         File->SetThrowExceptions( OldThrowingState );
01034         File->SetReportErrors( OldReportingState );
01035 
01036         // er, we seem to have finished OK so say so
01037         return TRUE;
01038     }
01039 
01040     catch(...)
01041     {
01042         // Must set the exception throwing and reporting flags back to their entry states
01043         File->SetThrowExceptions( OldThrowingState );
01044         File->SetReportErrors( OldReportingState );
01045 
01046         return FALSE;
01047     }
01048 
01049     ERROR2( FALSE, "Escaped exception clause somehow" );
01050 }

BOOL OutputGIF::ReStartFile LOGPALETTE pNewPal  )  [virtual]
 

Called to reset output before outputing another in a run of multiple images.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/6/96
Parameters:
pNewPal - New (optimised) palette to use [INPUTS]
Returns:
TRUE if worked, FALSE if failed
See also:
OutputGIF::StartFile

Definition at line 291 of file outptgif.cpp.

00292 {
00293     // Reset member variables
00294     IsFirstStrip = TRUE;
00295     HeightWritten = 0;
00296     pNextStrip = DestBitmapBytes;   
00297 
00298     if (pNewPal!=NULL)
00299     {
00300         ERROR2IF(OutputPalette==NULL, FALSE, "No output palette");
00301         ERROR3IF(pNewPal->palNumEntries != OutputPalette->palNumEntries, "Different sized palettes");
00302 
00303         const size_t PalSize = sizeof(PALETTEENTRY) * pNewPal->palNumEntries-1;
00304         memcpy( OutputPalette->palPalEntry, pNewPal->palPalEntry, PalSize );
00305     }
00306     
00307     return TRUE;
00308 }

BOOL OutputGIF::SetUpInfoHeader const LPBITMAPINFOHEADER  lpHeader,
const UINT32  OutputDepth,
const DWORD  CompressionType,
const UINT32  LineWidth,
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) LineWidth destination line width 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:
OutputGIF::StartFile; OutputGIF::WriteBlock; OutputGIF::TidyUp Scope: Public

Definition at line 333 of file outptgif.cpp.

00335 {
00336     SourceBitmapDepth = lpHeader->biBitCount;
00337     BitmapInfo.biBitCount = OutputDepth;
00338 
00339     const WORD DestDepth = BitmapInfo.biBitCount;
00340 
00341     // source bitmap not necessarily same as required file depth
00342     // make sure we can handle conversion
00343     BOOL FormatOK = FALSE;
00344 
00345     switch (SourceBitmapDepth)
00346     {
00347         case 32:
00348             {
00349                 switch (DestDepth)
00350                 {
00351                     case 8:
00352                         {
00353                             // 32->8 is OK
00354                             FormatOK = TRUE;
00355                             *pPalSize = 256;
00356                         }
00357                         break;
00358                     case 4:
00359                         {
00360                             // 32->4 is OK
00361                             FormatOK = TRUE;
00362                             *pPalSize = 16;
00363                         }
00364                         break;
00365                     case 1:
00366                         {
00367                             // 32->1 is OK
00368                             FormatOK = TRUE;
00369                             *pPalSize = 2;
00370                         }
00371                         break;
00372                     default:
00373                         // other source formats here
00374                         break;
00375                 }
00376                 
00377             }
00378             break;
00379         case 8:
00380             if (DestDepth==8)
00381             {
00382                 // 8->8 is OK
00383                 FormatOK = TRUE;
00384                 *pPalSize = 256;
00385             }
00386             break;
00387         default:
00388             // other source formats here
00389             break;
00390     }
00391 
00392     if (!FormatOK)
00393     {
00394         Error::SetError( _R(IDE_FORMATNOTSUPPORTED) );
00395         return FALSE;
00396     }
00397 
00398     BitmapInfo.biSizeImage = LineWidth * FinalHeight;
00399 
00400     return TRUE;
00401 }

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

Prepare to start the export of a GIF.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
5/6/96
Parameters:
lpHeader contains width & DPI of source & dest. biHeight & depth ignored. [INPUTS] Palette pointer to bmiColor struct, or NULL if not used (can be temporary) OutputDepth depth of bitmap required on disk CompressionType in this case is used to pass in the transparency and interlace information as GIFs are always compressed. Passed in as a number between 0 .. 3 which maps onto the TI_GIF filter types.
FinalHeight output of entire bitmap on disk ExportSize The set progress bar size DitherType

Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)
See also:
OutputGIF::WriteBlock; OutputGIF::TidyUp

Reimplemented from OutputDIB.

Definition at line 192 of file outptgif.cpp.

00199 {
00200     ERROR2IF( lpHeader==NULL, FALSE, "NULL lpHeader param");
00201     ERROR2IF( Palette==NULL, FALSE, "NULL Palette param");
00202 
00203     // Set member variables
00204     if (DestBitmapInfo && DestBitmapBytes)
00205     {
00206         FreeDIB( DestBitmapInfo, DestBitmapBytes );
00207         DestBitmapInfo = NULL;
00208         DestBitmapBytes = NULL; 
00209     }
00210 
00211     if (OutputPalette)
00212     {
00213         CCFree(OutputPalette);
00214         OutputPalette = NULL;
00215     }
00216 
00217     IsFirstStrip = TRUE;
00218     HeightWritten = 0;
00219 
00220     // remember input args
00221     BitmapInfo = *lpHeader;                             // take a copy of user's header
00222     CurrentExportSize = ExportSize;                     // size set up for the progress bar
00223     HeightWanted = FinalHeight;                         // the actual height of the export required
00224     Dither = DitherType;
00225 
00226     // We will need to have the entire image present before writing out so that we can
00227     // cope with interlacing and transparency, so create that DIB
00228     // Set up the information header for the dib which we hold during export
00229     UINT32 LineWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, OutputDepth );
00230     INT32 PalSize = 0;          
00231     BOOL ok = SetUpInfoHeader(lpHeader, OutputDepth, CompressionType, LineWidth, FinalHeight, &PalSize);
00232 
00233     // Claim memory for the bitmap
00234     if (ok)
00235     {
00236         DestBitmapInfo = AllocDIB( BitmapInfo.biWidth, FinalHeight, OutputDepth, &DestBitmapBytes );
00237         ok = (DestBitmapInfo != NULL) && (DestBitmapBytes != NULL);
00238     }
00239     
00240     // Transfer across the required other bits of info
00241     if (ok)
00242     {
00243         DestBitmapInfo->bmiHeader.biXPelsPerMeter = BitmapInfo.biXPelsPerMeter;
00244         DestBitmapInfo->bmiHeader.biYPelsPerMeter = BitmapInfo.biYPelsPerMeter;
00245         DestBitmapInfo->bmiHeader.biClrUsed = PalSize;
00246     }
00247 
00248     // Point the place to put the next strip of data at the start ready for the first strip
00249     pNextStrip = DestBitmapBytes;   
00250     
00251     // Take a copy of the palette
00252     if (ok)
00253     {
00254         const size_t TotalPal = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * PalSize );
00255         OutputPalette = (LPLOGPALETTE)CCMalloc( TotalPal );
00256         if (OutputPalette != NULL)
00257             memcpy( OutputPalette, Palette, TotalPal );
00258         else
00259             ok = FALSE;
00260     }
00261 
00262     // Clean up if an error happened
00263     if (!ok)
00264     {
00265         // Free up the DIB that we have just created
00266         FreeDIB( DestBitmapInfo, DestBitmapBytes );
00267         DestBitmapInfo = NULL;
00268         DestBitmapBytes = NULL; 
00269         if (OutputPalette != NULL)
00270         {
00271             CCFree(OutputPalette);
00272             OutputPalette = NULL;
00273         }
00274     }
00275 
00276     return ok;
00277 }

BOOL OutputGIF::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 from OutputDIB.

Definition at line 1181 of file outptgif.cpp.

01182 {
01183     // Free up the DIB that we have just created
01184     if (DestBitmapInfo && DestBitmapBytes)
01185     {
01186         FreeDIB( DestBitmapInfo, DestBitmapBytes );
01187         DestBitmapInfo = NULL;
01188         DestBitmapBytes = NULL; 
01189     }
01190 
01191     // Call the baseclass version to do its stuff
01192     const BOOL ok = OutputDIB::TidyUp();
01193 
01194     return ok;
01195 }

BOOL OutputGIF::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:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/4/95
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 from OutputDIB.

Definition at line 1080 of file outptgif.cpp.

01082 {
01083     ERROR2IF(DestBitmapInfo == NULL, FALSE,"OutputGIF::WriteBlock destination bitmap info null");
01084     ERROR2IF(DestBitmapBytes == NULL, FALSE,"OutputGIF::WriteBlock destination bitmap bits null");
01085     ERROR2IF(pNextStrip == NULL, FALSE,"OutputGIF::WriteBlock next strip pointer is null");
01086     
01087     FNPTR_SCANLINE ConvertFn = NULL;
01088     LPBYTE Buffer = NULL;
01089     size_t BufSize = 0L;
01090     size_t ChunkHeight = 1;
01091     DIBConvert *DoConvert = NULL;
01092 
01093     // Set up the size and other information for the dib block that we require. This is
01094     // dependent on the export depth or bpp required.
01095     if ( !SetUpBlock( &BufSize, &ChunkHeight, &DoConvert, &ConvertFn ) )
01096         return FALSE;           // Error details already set up
01097 
01098     if (BufSize)
01099     {
01100         Buffer = (LPBYTE)CCMalloc( BufSize );
01101         if (Buffer==NULL)
01102             return FALSE;
01103     }
01104 
01105     if ( DoConvert )
01106     {
01107         // use new classes to do it
01108         // 8bpp, 4bpp and 1bpp conversion
01109         INT32 h = Height;
01110         INT32 count = 0;
01111         LPBYTE Data = BlockStart;
01112         const size_t SourceWidth = DIBUtil::ScanlineSize( BitmapInfo.biWidth, InputBPP ) * ChunkHeight;
01113         const size_t DestWidth   = DIBUtil::ScanlineSize( BitmapInfo.biWidth, BitmapInfo.biBitCount );
01114 
01115         while (h)
01116         {
01117             ENSURE(h >= 0, "bad looping");
01118 
01119             const size_t ThisBit = min( h, (INT32)ChunkHeight );
01120             if (!DoConvert->Convert( Data, Buffer, ThisBit, IsFirstStrip ))
01121                 break;                              // stop if conversion failed
01122 
01123             IsFirstStrip = FALSE;
01124 
01125             // Copy this block to our destination bitmap
01126             // pNextStrip should be pointing at the next place to copy the data to
01127             memcpy(pNextStrip, Buffer, ThisBit * DestWidth);
01128 
01129             Data += SourceWidth;
01130             h -= ThisBit;
01131             pNextStrip += ThisBit * DestWidth;
01132             
01133             // now update the progress display, started with CurrentExportSize
01134             // CurrentExport size is now the point to go from in the export
01135             count++;
01136             //ContinueSlowJob( (INT32)(ProgressOffset + count) );
01137             //ContinueSlowJob( (INT32)(100*count/(Height)) );
01138         }
01139     }
01140     else if ( ConvertFn && Buffer )
01141     {
01142         // Write via conversion function
01143         // 24 bpp convert
01144         ERROR2(FALSE,"OutputGIF::WriteBlock trying to write using ConvertFunction");
01145     }
01146     else
01147     {
01148         ERROR2(FALSE,"OutputGIF::WriteBlock trying to write in one go");
01149     }
01150 
01151     // If present, get rid of our export function
01152     if (DoConvert)
01153     {
01154         delete DoConvert;
01155         DoConvert = NULL;
01156     }
01157 
01158     CCFree( Buffer );
01159     Buffer = NULL;
01160 
01161     HeightWritten += Height;                        // remember we wrote this lot
01162 
01163     return TRUE;
01164 }


Member Data Documentation

INT32 OutputGIF::a_count [protected]
 

Definition at line 234 of file outptgif.h.

char OutputGIF::accum[256] [protected]
 

Definition at line 235 of file outptgif.h.

INT32 OutputGIF::Background [protected]
 

Definition at line 200 of file outptgif.h.

WORD OutputGIF::BitsPerPixel [protected]
 

Definition at line 198 of file outptgif.h.

INT32 OutputGIF::clear_flg [protected]
 

Definition at line 218 of file outptgif.h.

INT32 OutputGIF::ClearCode [protected]
 

Definition at line 227 of file outptgif.h.

unsigned short OutputGIF::codetab[5003] [protected]
 

Definition at line 212 of file outptgif.h.

INT32 OutputGIF::CountDown [protected]
 

Definition at line 194 of file outptgif.h.

UINT32 OutputGIF::cur_accum [protected]
 

Definition at line 231 of file outptgif.h.

INT32 OutputGIF::cur_bits [protected]
 

Definition at line 232 of file outptgif.h.

INT32 OutputGIF::CurrentLine [protected]
 

Definition at line 193 of file outptgif.h.

INT32 OutputGIF::curx [protected]
 

Definition at line 191 of file outptgif.h.

INT32 OutputGIF::cury [protected]
 

Definition at line 192 of file outptgif.h.

LPBYTE OutputGIF::DataBuffer [protected]
 

Definition at line 202 of file outptgif.h.

LPBYTE OutputGIF::DestBitmapBytes [protected]
 

Definition at line 181 of file outptgif.h.

LPBITMAPINFO OutputGIF::DestBitmapInfo [protected]
 

Definition at line 180 of file outptgif.h.

INT32 OutputGIF::EOFCode [protected]
 

Definition at line 228 of file outptgif.h.

code_int OutputGIF::free_ent [protected]
 

Definition at line 214 of file outptgif.h.

INT32 OutputGIF::g_init_bits [protected]
 

Definition at line 225 of file outptgif.h.

INT32 OutputGIF::Height [protected]
 

Definition at line 190 of file outptgif.h.

count_int OutputGIF::htab[5003] [protected]
 

Definition at line 211 of file outptgif.h.

INT32 OutputGIF::in_count [protected]
 

Definition at line 221 of file outptgif.h.

INT32 OutputGIF::InitCodeSize [protected]
 

Definition at line 199 of file outptgif.h.

BOOL OutputGIF::InterlacingOn [protected]
 

Definition at line 195 of file outptgif.h.

code_int OutputGIF::maxcode [protected]
 

Definition at line 209 of file outptgif.h.

INT32 OutputGIF::n_bits [protected]
 

Definition at line 208 of file outptgif.h.

INT32 OutputGIF::offset [protected]
 

Definition at line 220 of file outptgif.h.

INT32 OutputGIF::out_count [protected]
 

Definition at line 222 of file outptgif.h.

INT32 OutputGIF::Pass [protected]
 

Definition at line 196 of file outptgif.h.

BaseCamelotFilter* OutputGIF::pCamFilter [protected]
 

Definition at line 186 of file outptgif.h.

LPBYTE OutputGIF::pNextStrip [protected]
 

Definition at line 182 of file outptgif.h.

INT32 OutputGIF::Width [protected]
 

Definition at line 189 of file outptgif.h.

UINT32 OutputGIF::WidthOfLine [protected]
 

Definition at line 204 of file outptgif.h.


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