#include <outptdib.h>
Inheritance diagram for OutputDIB:
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 |
CCLexFile * | OutputFile |
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 DIBConvert * | DoExportConvert |
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 |
Definition at line 122 of file outptdib.h.
|
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.
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 }
|
|
Definition at line 127 of file outptdib.h.
|
|
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.
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 }
|
|
Corrects the first 16 palette entries to be a correct Gavin 16 colour palette.
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 }
|
|
Corrects the first two palette entries to be a correct Gavin black and white palette.
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 }
|
|
Stub function to complete inheritance hierarchy.
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 }
|
|
Stub function to complete inheritance hierarchy.
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 }
|
|
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.
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 }
|
|
Puts the required value of rgb into the specified palette entry.
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 }
|
|
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.
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 }
|
|
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)
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 }
|
|
Set up the information header for the DIB.
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 }
|
|
Stub function to be inherited over.
Reimplemented in OutputGIF, and OutputPNG. Definition at line 488 of file outptdib.cpp. 00495 { 00496 return FALSE; 00497 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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...
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 }
|
|
Definition at line 174 of file outptdib.h. |
|
Definition at line 198 of file outptdib.h. |
|
Definition at line 197 of file outptdib.h. |
|
Definition at line 193 of file outptdib.h. |
|
Definition at line 178 of file outptdib.h. |
|
Definition at line 188 of file outptdib.h. |
|
Definition at line 187 of file outptdib.h. |
|
Definition at line 194 of file outptdib.h. |
|
Definition at line 189 of file outptdib.h. |
|
Definition at line 192 of file outptdib.h. |
|
Definition at line 191 of file outptdib.h. |
|
Definition at line 190 of file outptdib.h. |
|
Definition at line 182 of file outptdib.h. |
|
Definition at line 181 of file outptdib.h. |
|
Definition at line 200 of file outptdib.h. |
|
Definition at line 185 of file outptdib.h. |
|
Definition at line 186 of file outptdib.h. |
|
Definition at line 173 of file outptdib.h. |
|
Definition at line 196 of file outptdib.h. |
|
Definition at line 176 of file outptdib.h. |
|
Definition at line 171 of file outptdib.h. |
|
Definition at line 172 of file outptdib.h. |