DIBUtil Class Reference

Contains static functions for handy DIB manipulation. Never instantiate one of these. That would be silly. More...

#include <dibutil.h>

List of all members.

Static Public Member Functions

static UINT32 ScanlineSize (UINT32 Width, UINT32 Depth)
 Used in calculating bitmap memory requirements. Based on Gavin's code in GDraw_SetDIBitmap, which it had better agree with!
static UINT32 ScanlineBytes (UINT32 Width, UINT32 Depth)
 Used in calculating offsets along scanlines. NOTE! Differs from ScanlineSize in that it DOES NOT word align the result!!!
static BOOL PlotDeepDIB (wxDC *phDC, LPBITMAPINFO lpBitmapInfo, LPBYTE lpBits, INT32, INT32, INT32, INT32, INT32, INT32, BitmapConvertHint, HPALETTE=NULL)
 Plot a deep DIB on a device which does not understand deep DIBs. Works by converting to a 24-bit DIB in slices. The DIB must be using the 'standard' RGB arrangements. If this is called on a non-True Colour device then it will take a very very long time, as 24->8 GDI conversions are terribly slow, unless CONVHINT_SCREEN8/4 is used.
static BOOL CanReadFromFile (const BitmapInfo *pInfo)
 To check to see if a .bmp file can be read into memory using ReadFromFile. At present, ReadFromFile only likes 8- & 24- & 32-bit BMPs and so we must tell the caller that this is the case. This is for the old OS/2 1.0 style BMPs. Scope: Static.
static BOOL CanReadFromFile (const LPBITMAPCOREHEADER pCoreHeader)
 To check to see if a .bmp file can be read into memory using ReadFromFile. At present, ReadFromFile only likes 8- & 24- & 32-bit BMPs and so we must tell the caller that this is the case. This is for the old OS/2 1.0 style BMPs. Scope: Static.
static BOOL CanReadFromFile (const LPBITMAPINFOHEADER pInfoHeader)
 To check to see if a .bmp file can be read into memory using ReadFromFile. At present, ReadFromFile only likes 8- & 24- & 32-bit BMPs and so we must tell the caller that this is the case. This is for the Win 3.0+ style BMPs. Scope: Static.
static BOOL ReadFromFile (CCLexFile *, LPBITMAPINFO *Info, LPBYTE *Bits, BOOL=TRUE, String_64 *ProgressString=NULL, BaseCamelotFilter *pFilter=NULL)
 Read a .bmp file into memory. ONLY READS 8- & 24- & 32-bit BMPs currently***. Errors on 16-bit builds*** A progress hourglass can be shown if required.
static BOOL WriteToFile (CCLexFile *, LPBITMAPINFO Info, LPBYTE Bits, String_64 *ProgressString=NULL, BOOL WriteHeader=TRUE, BaseCamelotFilter *pFilter=NULL)
 Write a bitmap in memory straight out to file with now rendering or conversion. Errors on 16-bit builds*** A progress hourglass can be shown if required. This function is used by the save bitmap button on the bitmap gallery. All other bitmap export uses the OutputDIB class instead as this copes with using a render region and converting from 32 to the destination format. (caller should close file).
static BOOL WriteToFile (CCLexFile *, LPBYTE Bits, UINT32 Width, UINT32 Height, UINT32 Depth, String_64 *ProgressString=NULL)
 Generates a BITMAPINFO structor and then saves out the DIB.
static void Convert16to24 (INT32 PixelWidth, LPBYTE InputBits, LPBYTE OutputBits)
static void Convert32to24 (INT32 PixelWidth, LPBYTE InputBits, LPBYTE OutputBits)
static void Convert32to24Alpha (INT32 PixelWidth, LPBYTE InputBits, LPBYTE OutputBits, COLORREF Colour)
static void Convert32to32 (INT32 PixelWidth, LPBYTE InputBits, LPBYTE OutputBits)
static void Convert8to8 (INT32 PixelWidth, LPBYTE InputBits, LPBYTE OutputBits)
static HPALETTE MakeIdentityPalette (PALETTEENTRY aRGB[], INT32 nColors)
static BitmapConvertHint CalcConvertHint (DWORD ScreenBPP, wxDC *pTestHDC)
 Determines RGB arrangements for 15/16-bit devices which is needed during dithering in those modes. User is responsible for preserving the state of the pixel at 0,0 if required. Returns CONVHINT_NONE if an error occurs.
static DWORD GetGavinBlitFormat (DWORD ScreenBPP, DWORD BitmapBPP, BitmapConvertHint ScreenHint)
 Determines, from the given inputs, what number should be passed to Gavin routines SetSolidColour and SetUpBitmap (the BPP and BitmapFormat params) in order to get the best possible result (and/or to ensure no dithering occurs). Generally, this is only needed in 16bpp screen modes, but may be called at any time, as it returns safe defaults if not in 16bpp.
static BOOL MakeTransparentBitmap (LPBITMAPINFO pPseudoColourInfo, LPBYTE pPseudoColourBits, LPBITMAPINFO pMonochromeInfo, LPBYTE pMonochromeBits, const BYTE TransCol)
 Applies the monochrome bitmap as a mask to a bitmap, setting pixels in the to the image to the TransColour if the equivelent pixel in the mask is not set.
static BOOL MakeBitmapMask (LPBITMAPINFO pPseudoColourInfo, LPBYTE pPseudoColourBits, LPBITMAPINFO pMonochromeInfo, LPBYTE pMonochromeBits, const BYTE TransCol)
 Makes the monochrome bitmap (created with) into a mask for displaying the Pseudocolour bitmap. The mask must be 8bpp instead of the implied of 1bpp as applying it as a transparency requires this.
static BOOL MakeBitmapSmaller (UINT32 OldWidth, UINT32 OldHeight, UINT32 BaseX, UINT32 BaseY, UINT32 NewWidth, UINT32 NewHeight, UINT32 BPP, LPBYTE pBits)
 Resizes a bitmap.
static BOOL Init ()
 Reads our prefs.
static UINT32 CalcPaletteSize (UINT32 Depth, bool bUsingBitFields, UINT32 UsedColours=0)
static BOOL CopyBitmap (LPBITMAPINFO pSourceInfo, LPBYTE pSourceBits, LPBITMAPINFO *pDestInfo, LPBYTE *pDestBits)
static BOOL CopyEntireBitmap (LPBITMAPINFO pSourceInfo, LPBYTE pSourceBits, LPBITMAPINFO *pDestInfo, LPBYTE *pDestBits)
 Allocates a new DIB information header block and bits data and copies the source bitmap data across to the new bitmap. At present, just copies the actual bits data, the header will be the defaults plus width, height and colour depth. Not interested in the palette and other information stored in the bitmap info header. Same as CopyBitmap but actually copies the rest of the data as well. This includes:- Palette information Header information Bits information.
static BOOL CopyPalette (LPRGBQUAD pSourcePalette, LPRGBQUAD pDestPalette, UINT32 NumberOfColours)
 Copy a palette from a bitmap which has been duplicated and so has the same colour depth and number of palette entries, to a destination bitmap. Assumes palettes already allocated as part of the duplication process.
static KernelBitmapCopyKernelBitmap (KernelBitmap *pKernelBitmap, BOOL IsTemp=FALSE)
 Allocates a new CWxBitmap and KernelBitmap pointing to it. Note these are completely new versions containing the same data as the old ones.
static BOOL CountColoursUsed (BITMAPINFO *pInfo, BYTE *pBits, UINT32 **pResultsArray)
 Counts the usage for each palette index in the bitmap. NOTE: Caller is responsible for CCFreeing the results array.
static INT32 FindLeastUsedColour (BITMAPINFO *pInfo, UINT32 *pResultsArray)
 Takes the results from DIBUtil::CountColoursUsed and works out which colour is the best one to use as a transparent colour by finding the least used. NOTE: Caller is responsible for CCFreeing the results array.
static BOOL CopyBitmapSection (LPBITMAPINFO pSourceInfo, LPBYTE pSourceBits, LPBITMAPINFO pDestInfo, LPBYTE pDestBits, INT32 SourceTop, INT32 SourceLeft)
 To copy a section of the source bitmap to the destination. Note that unlike the other copy functions in this file the destination header must in not allocated so you must do it yourself. Likewise palette info.
static BOOL Optimal4bppPaletteInitialise_1stPass ()
static BOOL Optimal4bppPaletteInitialise_2ndPass ()
static BOOL GenOptimal4bppPaletteStats_1stPass (RGBQUAD *pBitmap, size_t Size)
static BOOL GenOptimal4bppPaletteStats_2ndPass (RGBQUAD *pBitmap, size_t Size)
static BOOL GenOptimal4bppPalette (PLOGPALETTE pPalette, const size_t MaxColours)
static size_t GetOptimal8bppPaletteWorkspaceSize ()
static BOOL Optimal8bppPaletteInitialise (INT32 *Stats)
static BOOL GenOptimal8bppPaletteStats (INT32 *Stats, RGBQUAD *pBitmap, size_t Size)
static BOOL GenOptimal8bppPalette (INT32 *Stats, PLOGPALETTE pPalette, const size_t MaxColours)
static size_t GetOptimalPaletteWorkspaceSize ()
 Returns size of workspace required by optimal palette routines.
static BOOL OptimalPaletteInitialise (void *Stats)
 Initialises workspace required by optimal palette routines. Stats should have INT32 size of GetOptimalPaletteWorkspaceSize().
static BOOL ExactPaletteInitialise (LPLOGPALETTE pExactPalette)
static BOOL GenOptimalPaletteStats (void *Stats, RGBQUAD *pBitmap, size_t Size)
 The purpose of this function is to build a table of statistics about one or more bitmaps prior to calling GenOptimalPalette.
static BOOL GenOptimalPalette (void *Stats, PLOGPALETTE pPalette, const size_t MaxColours)
 The purpose of this function is to generate an optimal palette suitable for the bitmaps for which statistics have previously been generated.
static BOOL GenGreyscalePalette (LPRGBQUAD lpPalette, const size_t PaletteSize)
 Generate a greyscale palette for a greyscale DIB.
static BOOL Convert24to8 (LPBITMAPINFO pSourceInfo, LPBYTE pSourceBits, LPBITMAPINFO *pDestInfo, LPBYTE *pDestBits, RGBTRIPLE *pPalette, UINT32 NumberOfPaletteEntries)
 Generate an 8 bit form of a bitmap from a 24 bit form using the given palette.
static BOOL Convert32to8 (LPBITMAPINFO pSourceInfo, LPBYTE pSourceBits, LPBITMAPINFO *pDestInfo, LPBYTE *pDestBits, RGBTRIPLE *pPalette, UINT32 NumberOfPaletteEntries)
 Generate an 8 bit form of a bitmap from a 32 bit form using the given palette.
static BOOL Convert8to32 (LPBITMAPINFO pSourceInfo, LPBYTE pSourceBits, RGBQUAD *pPalette, LPBITMAPINFO pDestInfo, LPBYTE pDestBits)
 Generates a 32bit form of the input 8bit bitmap, note that the destination bitmapinfo and bitmap must be allocated prior to this function.
static OILBitmapCreate8bppGreyscaleBitmap (KernelBitmap *pSrcBitmap)
 Designed to be used to create an 8bpp greyscale bitmap from a 24bpp, 4bpp or 1bpp bitmaps.
static BOOL ConvertTo8Greyscale (LPBITMAPINFO pSourceInfo, LPBYTE pSourceBits, LPBITMAPINFO *ppDestInfo, LPBYTE *ppDestBits)
 Generates an 8bpp greyscale bitmap from the given 1bpp, 4bpp or 8bpp bitmap.
static BOOL GenGreyscalePaletteTriple (RGBTRIPLE *pPalette, const size_t PaletteSize)
 Generate a packed greyscale palette for a greyscale DIB.
static BOOL GenerateDifferenceBitmap (LPBITMAPINFO pPreviousInfo, LPBYTE pPreviousBits, LPBITMAPINFO pCurrentInfo, LPBYTE pCurrentBits, LPBITMAPINFO *ppDestInfo, LPBYTE *ppDestBits, INT32 TransColour, BOOL *pFoundBadOverlay=NULL)
static BOOL GenerateSubRegionBitmap (LPBITMAPINFO pSourceInfo, LPBYTE pSourceBits, LPBITMAPINFO *ppDestInfo, LPBYTE *ppDestBits, INT32 TransColour, UINT32 *pLeftOffset, UINT32 *pTopOffset)
static LPLOGPALETTE AllocateLogPalette (const UINT32 PaletteSize)
 To allocate a LOGPALETTE ready for use. The caller is responsible for cleaning up the memmory allocation.
static LPLOGPALETTE CopyBitmapPaletteIntoLogPalette (KernelBitmap *pBitmap)
 To allocate a LOGPALETTE and then copy the palette from inside the bitmap across to the LOGPALETTE. The caller is responsible for cleaning up the memmory allocation.
static BOOL IsGreyscaleBitmap (KernelBitmap *pKB)
 Determines whether or not a bitmap is 32bpp.
static BOOL IsGreyscaleBitmap (OILBitmap *pOilBmp)
 Determines whether or not a bitmap is 32bpp.
static BOOL CalculateNumberOfColoursInBitmap (LPLOGPALETTE pExactPalette, RGBQUAD *pBitmap, size_t Size)
static void InvertAlpha (LPBITMAPINFO lpBitmapInfo, LPBYTE lpBits)
 Camelot uses a different transparency scheme to the rest of the world, in that 255 is clear, and 0 is opaque. Until the rest of the world catches up, it's necessary to invert the alpha channel to make exported files compatible with other programs.
static void MakeAlphaIntoGreyscale (LPBITMAPINFO lpBitmapInfo, LPBYTE lpBits)
 Camelot uses a different transparency scheme to the rest of the world, in that 255 is clear, and 0 is opaque. Until the rest of the world catches up, it's necessary to invert the alpha channel to make exported files compatible with other programs.


Detailed Description

Contains static functions for handy DIB manipulation. Never instantiate one of these. That would be silly.

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

Definition at line 164 of file dibutil.h.


Member Function Documentation

LPLOGPALETTE DIBUtil::AllocateLogPalette const UINT32  PaletteSize  )  [static]
 

To allocate a LOGPALETTE ready for use. The caller is responsible for cleaning up the memmory allocation.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
03/07/97
Parameters:
The number of entries in the palette [INPUTS]
Returns:
A pointer to the allocated LOGPALETTE or null.

Definition at line 4681 of file dibutil.cpp.

04682 {
04683     ERROR2IF(PaletteSize == 0 || PaletteSize > 256,NULL,"AllocateLogPalette Bad PaletteSize");
04684 
04685     LPLOGPALETTE pPalette = NULL;
04686     const size_t TotalPal = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * PaletteSize );
04687     pPalette = (LPLOGPALETTE)CCMalloc( TotalPal );
04688     if (pPalette == NULL)
04689         return NULL;
04690 
04691     pPalette->palNumEntries     = PaletteSize;
04692     pPalette->palVersion        = 0x300;
04693     return pPalette;
04694 }

BitmapConvertHint DIBUtil::CalcConvertHint DWORD  ScreenBPP,
wxDC *  pDC
[static]
 

Determines RGB arrangements for 15/16-bit devices which is needed during dithering in those modes. User is responsible for preserving the state of the pixel at 0,0 if required. Returns CONVHINT_NONE if an error occurs.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> (Rewrote Andy's original function)
Date:
4/7/95 (21/2/95)
Parameters:
ScreenBPP - Indicates the output BPP for which the hint is required [INPUTS] hDC - should be a device that supports SetPixel. (May be NULL if ScreenBPP is less than 16)
Returns:
Suitable value for hinting in bitmap conversions. (CONVHINT_SCREEN4 or _SCREEN8, or any of the 16 or 24 bit CONVHINT_FINAL? values)
See also:
BitmapConvertHint; DIBUtil::GetGavinBlitFormat

Definition at line 2038 of file dibutil.cpp.

02039 {
02040     switch(ScreenBPP)
02041     {
02042         case 4:
02043             return(CONVHINT_SCREEN4);
02044 
02045         case 8:
02046             return(CONVHINT_SCREEN8);
02047 
02048         case 16:
02049         case 24:
02050         case 32:
02051             // Drop through to the code below to determine a proper 16/24bpp hint
02052             // (Note: Some cards say they are 24bpp when in fact they're 16bpp, so we must
02053             // do this for both values)
02054             break;
02055 
02056         default:
02057             ERROR2(CONVHINT_NONE, "Unknown output screen BPP");
02058     }
02059 
02060     // Writes all 256 values to each gun, and counts the number of different values which are 
02061     // returned - i.e. a 5 bit gun cannot return more than 32 values
02062     BYTE LastValue[3] = {0, 0, 0};
02063     BYTE     Count[3] = {0, 0, 0};
02064     wxMemoryDC  memdc;
02065     wxBitmap    bitmap( 1, 1 );
02066     memdc.SelectObject( bitmap );
02067     for ( UINT32 Value=0x00; Value<0x100; Value++ )
02068     {
02069         wxColour colour;
02070         memdc.SetPen(wxPen(wxColour(Value,Value,Value)));
02071         memdc.DrawPoint(0,0);
02072         memdc.GetPixel(0,0,&colour);
02073         if ( colour.Red()!=LastValue[0] )
02074         {
02075             LastValue[0] = colour.Red();
02076             Count[0]++;
02077         }
02078         if ( colour.Green()!=LastValue[1] )
02079         {
02080             LastValue[1] = colour.Green();
02081             Count[1]++;
02082         }
02083         if ( colour.Blue()!=LastValue[2] )
02084         {
02085             LastValue[2] = colour.Blue();
02086             Count[2]++;
02087         }
02088     }
02089     memdc.SelectObject( wxNullBitmap );
02090 
02091     // Now determine how many bits would be needed to store the number of values we generated
02092     // for each gun. Note that this code will return (eg) 5 bits for all values between 17-32 inclusive
02093     for (INT32 Gun = 0; Gun < 3; Gun++)
02094     {
02095         INT32 BitPos = 0;
02096         while (Count[Gun] > 0)
02097         {
02098             BitPos++;
02099             Count[Gun] /= 2;
02100         }
02101         Count[Gun] = BitPos;
02102     }
02103 
02104     TRACEALL( wxT("16bpp RGB gun configuration auto-detected as %ld.%ld.%ld\n"),
02105                 Count[0], Count[1], Count[2]);
02106 
02107     // OK. Now determine the enum constant which represents this configuration (if any)
02108     switch(Count[0])
02109     {
02110         case 5:
02111             if (Count[2] == 5)
02112             {
02113                 if (Count[1] == 5)
02114                     return(CONVHINT_FINAL555);
02115                 
02116                 if (Count[1] == 6)
02117                     return(CONVHINT_FINAL565);
02118             }
02119             break;
02120 
02121         case 6:
02122             if (Count[1] == 5 && Count[2] == 5)
02123                 return(CONVHINT_FINAL655);
02124 
02125             if (Count[1] == 6 && Count[2] == 4)
02126                 return(CONVHINT_FINAL664);
02127             break;
02128 
02129         case 8:
02130             if (Count[1] == 8 && Count[2] == 8)
02131                 return(CONVHINT_FINAL24);
02132             break;
02133     }
02134 
02135     // Nope. It's an unknown signature. We'll just have to try 555 and hope for the best
02136     TRACEALL( wxT("Unknown 16bpp RGB gun configuration (%ld.%ld.%ld). Defaulting to CONVHINT_NONE\n"),
02137                 Count[0], Count[1], Count[2]);
02138     return(CONVHINT_NONE);
02139 }

UINT32 DIBUtil::CalcPaletteSize UINT32  Depth,
bool  bUsingBitFields,
UINT32  UsedColours = 0
[static]
 

Definition at line 2680 of file dibutil.cpp.

02681 {
02682     ERROR3IF((bUsingBitFields && (Depth != 16 || Depth != 32)), "Invalid use of DIBUtil::CalcPaletteSize()");
02683 
02684     // Calculate the size of the DIB data
02685     UINT32 extras = 0;
02686     switch (Depth)
02687     {
02688         case 1:
02689             if (UsedColours > 0 && UsedColours <= 2)
02690                 extras = UsedColours;
02691             else
02692                 extras = 2;
02693             break;
02694         case 4:
02695             if (UsedColours > 0 && UsedColours <= 16)
02696                 extras = UsedColours;
02697             else
02698                 extras = 16;
02699             break;
02700         case 8:
02701             if (UsedColours > 0 && UsedColours <= 256)
02702                 extras = UsedColours;
02703             else
02704                 extras = 256;
02705             break;
02706         case 16:
02707         case 32:
02708             if (bUsingBitFields)
02709                 extras = 3;
02710             break;
02711     }
02712     ERROR3IF(extras == 0 && Depth != 16 && Depth != 24 && Depth != 32, "Unsupported DIB depth!");
02713 
02714     return(extras * sizeof(RGBQUAD));
02715 }

BOOL DIBUtil::CalculateNumberOfColoursInBitmap LPLOGPALETTE  pExactPalette,
RGBQUAD pBitmap,
size_t  Size
[static]
 

Definition at line 3476 of file dibutil.cpp.

03477 {
03478     ERROR3IF(pExactPalette == NULL, "NULL palette pointer passed to DIBUtil::CalculateNumberOfColoursInBitmap");
03479     if (pExactPalette == NULL)
03480         return FALSE;
03481 
03482     ERROR3IF(pBitmap == NULL, "NULL Bitmap pointer passed to DIBUtil::CalculateNumberOfColoursInBitmap");
03483     if (pBitmap == NULL)
03484         return FALSE;
03485 
03486     ERROR3IF(Size == 0, "Bad size passed to DIBUtil::CalculateNumberOfColoursInBitmap");
03487     if (Size == 0)
03488         return FALSE;
03489 
03490 //  return ::CalculateNumberOfColoursInBitmap( pExactPalette, pBitmap, Size );
03491     ASSERT(0);
03492     return FALSE;
03493 }

BOOL DIBUtil::CanReadFromFile const LPBITMAPINFOHEADER  pInfoHeader  )  [static]
 

To check to see if a .bmp file can be read into memory using ReadFromFile. At present, ReadFromFile only likes 8- & 24- & 32-bit BMPs and so we must tell the caller that this is the case. This is for the Win 3.0+ style BMPs. Scope: Static.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
2/2/95
Parameters:
LPBITMAPFILEINFO points to a bitmap info structure to look at. [INPUTS]
- [OUTPUTS]
Returns:
TRUE if ReadFromFile will cope with it, FALSE otherwise.
See also:
DIBUtil::ReadFromFile;

Definition at line 1096 of file dibutil.cpp.

01097 {
01098 ERROR2IF(pInfoHeader==NULL,FALSE,"CanReadFromFile InfoHeader pointer is null");
01099     BOOL Understand = FALSE;
01100 
01101     // Check the depth in the supplied info header to see if we like it or not
01102     INT32 Depth = pInfoHeader->biBitCount;
01103 TRACEUSER( "Neville", wxT("DIBUtil::CanReadFromFile Win 3.0+ type depth = %d\n"), Depth );
01104     if (Depth == 32)
01105         Understand = TRUE;      // it is one of our 32bpp bmp so we definitely like it
01106     else
01107         Understand = FALSE;     // Not sure that we can cope with this
01108 
01109     return Understand;
01110 }

BOOL DIBUtil::CanReadFromFile const LPBITMAPCOREHEADER  pCoreHeader  )  [static]
 

To check to see if a .bmp file can be read into memory using ReadFromFile. At present, ReadFromFile only likes 8- & 24- & 32-bit BMPs and so we must tell the caller that this is the case. This is for the old OS/2 1.0 style BMPs. Scope: Static.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
2/2/95
Parameters:
LPBITMAPCOREHEADER points to a bitmap info structure to look at. [INPUTS]
- [OUTPUTS]
Returns:
TRUE if ReadFromFile will cope with it, FALSE otherwise.
See also:
DIBUtil::ReadFromFile;

Definition at line 1062 of file dibutil.cpp.

01063 {
01064 ERROR2IF(pCoreHeader==NULL,FALSE,"CanReadFromFile CoreHeader pointer is null");
01065     BOOL Understand = FALSE;
01066 
01067     // Check the depth in the supplied info header to see if we like it or not
01068     INT32 Depth = pCoreHeader->bcBitCount;
01069 TRACEUSER( "Neville", wxT("DIBUtil::CanReadFromFile OS/2 type depth = %d\n"), Depth );
01070     if (Depth == 32)
01071         Understand = TRUE;      // it is one of our 32bpp bmp so we definitely like it
01072     else
01073         Understand = FALSE;     // Not sure that we can cope with this
01074 
01075     return Understand;
01076 }

BOOL DIBUtil::CanReadFromFile const BitmapInfo pInfo  )  [static]
 

To check to see if a .bmp file can be read into memory using ReadFromFile. At present, ReadFromFile only likes 8- & 24- & 32-bit BMPs and so we must tell the caller that this is the case. This is for the old OS/2 1.0 style BMPs. Scope: Static.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
2/2/95
Parameters:
pInfo points to a kernel (BitmapInfo) bitmap info structure to look at. [INPUTS]
- [OUTPUTS]
Returns:
TRUE if ReadFromFile will cope with it, FALSE otherwise.
See also:
DIBUtil::ReadFromFile;

Definition at line 1028 of file dibutil.cpp.

01029 {
01030 ERROR2IF(pInfo==NULL,FALSE,"CanReadFromFile BitmapInfo pointer is null");
01031     BOOL Understand = FALSE;
01032 
01033     // Check the depth in the supplied info header to see if we like it or not
01034     INT32 Depth = pInfo->PixelDepth;
01035 TRACEUSER( "Neville", wxT("DIBUtil::CanReadFromFile depth = %d\n"), Depth );
01036     if (Depth == 32)
01037         Understand = TRUE;      // it is one of our 32bpp bmp so we definitely like it
01038     else
01039         Understand = FALSE;     // Not sure that we can cope with this
01040 
01041     return Understand;
01042 }

void DIBUtil::Convert16to24 INT32  PixelWidth,
LPBYTE  InputBits,
LPBYTE  OutputBits
[static]
 

Definition at line 507 of file dibutil.cpp.

00508 {
00509     LPWORD Source = (LPWORD)InputBits;
00510 
00511     while (PixelWidth--)
00512     {
00513         const WORD Data = *Source++;
00514         
00515         // get five-bit RGB values, which we then double-up just like Quickdraw does
00516         // to get an 8-bit result
00517         const BYTE Blue = Data & 0x1F;
00518         *OutputBits++ = EXPAND(Blue);
00519 
00520         const BYTE Green = (Data>>5) & 0x1F;
00521         *OutputBits++ = EXPAND(Green);
00522 
00523         const BYTE Red = (Data>>10) & 0x1F;
00524         *OutputBits++ = EXPAND(Red);
00525     }
00526 }

BOOL DIBUtil::Convert24to8 LPBITMAPINFO  pSourceInfo,
LPBYTE  pSourceBits,
LPBITMAPINFO pDestInfo,
LPBYTE pDestBits,
RGBTRIPLE pPalette,
UINT32  NumberOfPaletteEntries
[static]
 

Generate an 8 bit form of a bitmap from a 24 bit form using the given palette.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/9/96
Parameters:
pSourceInfo - A information header for the bitmap to be copied [INPUTS] pSourceBits - the actual bits for the bitmap to be copied pPalette - pointer to the palette in RGBTIPLE format to use when converting NumberOfPaletteEntries - entries in this palette
pDestInfo - pointer to the copied information block [OUTPUTS] pDestBits - pointer ot the copied bits data
Returns:
True if copied ok, false otherwise

Definition at line 3671 of file dibutil.cpp.

03674 {
03675     // In case of early set these return pointers to NULL
03676     *pDestInfo = NULL;
03677     *pDestBits = NULL;
03678 
03679     ERROR2IF(pSourceInfo == NULL || pSourceBits == NULL, FALSE, "DIBUtil::Convert24to8 bad source bitmap");
03680     ERROR2IF(pPalette == NULL || NumberOfPaletteEntries == 0, FALSE, "DIBUtil::Convert24to8 bad palette info");
03681 
03682     // Get a pointer to the useful bitmap header information for things like the size of the
03683     // bitmap and colour depth. 
03684     LPBITMAPINFOHEADER pSourceInfoHeader = &(pSourceInfo->bmiHeader); 
03685 
03686     ERROR2IF(pSourceInfoHeader->biBitCount != 24,FALSE,"DIBUtil::Convert24to8 bad source depth");
03687 
03688     // Try and allocate the detsination bitmap to be the same size and colour depth as the source
03689     *pDestInfo = AllocDIB( pSourceInfoHeader->biWidth, pSourceInfoHeader->biHeight,
03690                            8, pDestBits );
03691 
03692     // failed to allocate the bitmap so return false.
03693     if (*pDestInfo == NULL || *pDestBits == NULL )
03694         return FALSE;
03695 
03696     LPBITMAPINFOHEADER pDestInfoHeader = &((*pDestInfo)->bmiHeader); 
03697     
03698     // We will need the palette in LOGPALETTE for use in the conversion
03699     // We must allocate the palette to be the maximum size as otherwise people like Gavin
03700     // blow up
03701     LPLOGPALETTE pLogPalette = NULL;
03702     const UINT32 MaxColours = 256;
03703     pLogPalette = DIBUtil::AllocateLogPalette(MaxColours);
03704     if (pLogPalette == NULL)
03705         return FALSE;
03706 
03707     // Now copy the RGBTRIPLE palette into this and into the destination bitmap
03708     // Get a pointer to the palette in the destination bitmap
03709     LPRGBQUAD lpPalette = NULL;
03710     lpPalette = &((*pDestInfo)->bmiColors[0]);  // pointer to colours table
03711     //pLogPalette->palVersion = 0x300;
03712     pLogPalette->palNumEntries = NumberOfPaletteEntries;
03713     RGBTRIPLE *pPal = pPalette;
03714     for (UINT32 i = 0; i < NumberOfPaletteEntries; i++)
03715     {
03716         lpPalette->rgbRed = pPal->rgbtRed;
03717         pLogPalette->palPalEntry[i].peRed = pPal->rgbtRed;
03718         lpPalette->rgbGreen = pPal->rgbtGreen;
03719         pLogPalette->palPalEntry[i].peGreen = pPal->rgbtGreen;
03720         lpPalette->rgbBlue = pPal->rgbtBlue;
03721         pLogPalette->palPalEntry[i].peBlue = pPal->rgbtBlue;
03722         pLogPalette->palPalEntry[i].peFlags = 0x00;
03723         lpPalette->rgbReserved = 0x00;
03724         lpPalette++;
03725         pPal++;
03726     }
03727     // Fill in all other entries as black and do not use
03728     for (UINT32 i = NumberOfPaletteEntries; i < MaxColours; i++)
03729     {
03730         pLogPalette->palPalEntry[i].peRed   = 0x00;
03731         pLogPalette->palPalEntry[i].peGreen = 0x00;
03732         pLogPalette->palPalEntry[i].peBlue  = 0x00;
03733         pLogPalette->palPalEntry[i].peFlags = 0xFF;     // mark as do not use
03734         lpPalette->rgbRed       = 0x00;
03735         lpPalette->rgbGreen     = 0x00;
03736         lpPalette->rgbBlue      = 0x00;
03737         lpPalette->rgbReserved  = 0xFF; // mark as do not use
03738         lpPalette++;
03739     }
03740 
03741     UINT32 DitherType = XARADITHER_NONE;    // request no dithering
03742     DIBConvert *pDoConvert = NULL;      // the convert DIB
03743 
03744     // Do some conversion using the DIBConvert class
03745     pDoConvert = DIBConvert::Create( pSourceInfoHeader->biBitCount, pDestInfoHeader->biBitCount,
03746                                      pSourceInfoHeader->biWidth, pLogPalette,  DitherType);
03747     // If this fails then exit now
03748     if (pDoConvert == NULL)
03749     {
03750         if (pLogPalette)
03751             CCFree(pLogPalette);
03752         return FALSE;
03753     }
03754     
03755     // Do the actual conversion process
03756     INT32 ChunkHeight = 16;     // We will do the conversion in chunks, in case we ask for dithering
03757     INT32 Height = pSourceInfoHeader->biHeight;
03758     INT32 SourceWidth = DIBUtil::ScanlineSize( pSourceInfoHeader->biWidth, pSourceInfoHeader->biBitCount ) * ChunkHeight;
03759     INT32 DestWidth = DIBUtil::ScanlineSize( pDestInfoHeader->biWidth, pDestInfoHeader->biBitCount ) * ChunkHeight;
03760     BOOL IsFirstStrip = TRUE;           // Whether we are on the first strip or not
03761     INT32 CurrentYPos = 0;              // current line number
03762     LPBYTE SourceData = pSourceBits;    // pointer to the source data
03763     LPBYTE DestData = *pDestBits;       // pointer to the destination data
03764     while (CurrentYPos < Height)
03765     { 
03766         // Work out the size of the export chunk left, normally ExportChunkHeight but
03767         // if at the end of export may be a small strip left.
03768         const UINT32 ThisBit = min( UINT32(Height - CurrentYPos), (UINT32)ChunkHeight );
03769         if (!pDoConvert->Convert( SourceData, DestData, ThisBit, IsFirstStrip ))
03770             return FALSE;                           // stop if conversion failed
03771 
03772         IsFirstStrip = FALSE;               // Done first strip
03773         SourceData  += SourceWidth;         // Move on by a lines worth
03774         DestData    += DestWidth;           // Move on by a lines worth
03775         CurrentYPos += INT32(ThisBit);      // Move down by a strips worth
03776     }
03777     
03778     // Put back the recommended palette by destructing the convert function.
03779     if (pDoConvert)
03780     {
03781         delete pDoConvert;
03782         pDoConvert = NULL;
03783     }   
03784 
03785     if (pLogPalette)
03786     {
03787         CCFree(pLogPalette);
03788         pLogPalette = NULL;
03789     }
03790 
03791     // If we got this far then more than likely we have waht we want
03792     return TRUE;
03793 }

void DIBUtil::Convert32to24 INT32  PixelWidth,
LPBYTE  InputBits,
LPBYTE  OutputBits
[static]
 

Definition at line 529 of file dibutil.cpp.

00530 {
00531     // source form is B,G,R,spare
00532     // dest is B,G,R
00533     // Note: if not little-endian, is this still true?
00534     while (PixelWidth--)
00535     {
00536         OutputBits[0] = InputBits[0];
00537         OutputBits[1] = InputBits[1];
00538         OutputBits[2] = InputBits[2];
00539         OutputBits += 3;
00540         InputBits  += 4;
00541     }
00542 }

void DIBUtil::Convert32to24Alpha INT32  PixelWidth,
LPBYTE  InputBits,
LPBYTE  OutputBits,
COLORREF  Colour
[static]
 

Definition at line 546 of file dibutil.cpp.

00547 {
00548     // source form is B,G,R,spare
00549     // dest is B,G,R
00550     // Note: if not little-endian, is this still true?
00551     const BYTE RedBG = (BYTE)(Colour & 0xFF);
00552     const BYTE GreenBG = (BYTE)((Colour >> 8) & 0xFF);
00553     const BYTE BlueBG = (BYTE)((Colour >> 16) & 0xFF);
00554     
00555     while (PixelWidth--)
00556     {
00557         const BYTE Trans = InputBits[3];
00558         const BYTE Alpha = 255 - Trans;
00559         OutputBits[0] = ((InputBits[0] * Alpha) + (RedBG * Trans)) / 255;
00560         OutputBits[1] = ((InputBits[1] * Alpha) + (GreenBG * Trans)) / 255;
00561         OutputBits[2] = ((InputBits[2] * Alpha) + (BlueBG * Trans)) / 255;
00562         OutputBits += 3;
00563         InputBits  += 4;
00564     }
00565 }

void DIBUtil::Convert32to32 INT32  PixelWidth,
LPBYTE  InputBits,
LPBYTE  OutputBits
[static]
 

Definition at line 569 of file dibutil.cpp.

00570 {
00571     // done as DWORDs for speed
00572     LPDWORD Source = (LPDWORD)InputBits;
00573     LPDWORD Dest = (LPDWORD)OutputBits;
00574     while (PixelWidth--)
00575     {
00576 //      *Dest++ = *Source++ & 0x00FFFFFF; <- MarkH What for? We can deal with 32BMP Alpha channels!
00577         *Dest++ = *Source++;
00578     }
00579 }

BOOL DIBUtil::Convert32to8 LPBITMAPINFO  pSourceInfo,
LPBYTE  pSourceBits,
LPBITMAPINFO pDestInfo,
LPBYTE pDestBits,
RGBTRIPLE pPalette,
UINT32  NumberOfPaletteEntries
[static]
 

Generate an 8 bit form of a bitmap from a 32 bit form using the given palette.

Author:
Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/2005
Parameters:
pSourceInfo - A information header for the bitmap to be copied [INPUTS] pSourceBits - the actual bits for the bitmap to be copied pPalette - pointer to the palette in RGBTIPLE format to use when converting NumberOfPaletteEntries - entries in this palette
pDestInfo - pointer to the copied information block [OUTPUTS] pDestBits - pointer ot the copied bits data
Returns:
True if copied ok, false otherwise

Definition at line 3817 of file dibutil.cpp.

03820 {
03821     // In case of early set these return pointers to NULL
03822     *pDestInfo = NULL;
03823     *pDestBits = NULL;
03824 
03825     ERROR2IF(pSourceInfo == NULL || pSourceBits == NULL, FALSE, "DIBUtil::Convert32to8 bad source bitmap");
03826     ERROR2IF(pPalette == NULL || NumberOfPaletteEntries == 0, FALSE, "DIBUtil::Convert32to8 bad palette info");
03827 
03828     // Get a pointer to the useful bitmap header information for things like the size of the
03829     // bitmap and colour depth. 
03830     LPBITMAPINFOHEADER pSourceInfoHeader = &(pSourceInfo->bmiHeader); 
03831 
03832     ERROR2IF(pSourceInfoHeader->biBitCount != 32,FALSE,"DIBUtil::Convert32to8 bad source depth");
03833 
03834     // Try and allocate the detsination bitmap to be the same size and colour depth as the source
03835     *pDestInfo = AllocDIB( pSourceInfoHeader->biWidth, pSourceInfoHeader->biHeight,
03836                            8, pDestBits );
03837 
03838     // failed to allocate the bitmap so return false.
03839     if (*pDestInfo == NULL || *pDestBits == NULL )
03840         return FALSE;
03841 
03842     LPBITMAPINFOHEADER pDestInfoHeader = &((*pDestInfo)->bmiHeader); 
03843     
03844     // We will need the palette in LOGPALETTE for use in the conversion
03845     // We must allocate the palette to be the maximum size as otherwise people like Gavin
03846     // blow up
03847     LPLOGPALETTE pLogPalette = NULL;
03848     const UINT32 MaxColours = 256;
03849     pLogPalette = DIBUtil::AllocateLogPalette(MaxColours);
03850     if (pLogPalette == NULL)
03851         return FALSE;
03852 
03853     // Now copy the RGBTRIPLE palette into this and into the destination bitmap
03854     // Get a pointer to the palette in the destination bitmap
03855     LPRGBQUAD lpPalette = NULL;
03856     lpPalette = &((*pDestInfo)->bmiColors[0]);  // pointer to colours table
03857     //pLogPalette->palVersion = 0x300;
03858     pLogPalette->palNumEntries = NumberOfPaletteEntries;
03859     RGBTRIPLE *pPal = pPalette;
03860     for (UINT32 i = 0; i < NumberOfPaletteEntries; i++)
03861     {
03862         lpPalette->rgbRed = pPal->rgbtRed;
03863         pLogPalette->palPalEntry[i].peRed = pPal->rgbtRed;
03864         lpPalette->rgbGreen = pPal->rgbtGreen;
03865         pLogPalette->palPalEntry[i].peGreen = pPal->rgbtGreen;
03866         lpPalette->rgbBlue = pPal->rgbtBlue;
03867         pLogPalette->palPalEntry[i].peBlue = pPal->rgbtBlue;
03868         pLogPalette->palPalEntry[i].peFlags = 0x00;
03869         lpPalette->rgbReserved = 0x00;
03870         lpPalette++;
03871         pPal++;
03872     }
03873     // Fill in all other entries as black and do not use
03874     for (UINT32 i = NumberOfPaletteEntries; i < MaxColours; i++)
03875     {
03876         pLogPalette->palPalEntry[i].peRed   = 0x00;
03877         pLogPalette->palPalEntry[i].peGreen = 0x00;
03878         pLogPalette->palPalEntry[i].peBlue  = 0x00;
03879         pLogPalette->palPalEntry[i].peFlags = 0xFF;     // mark as do not use
03880         lpPalette->rgbRed       = 0x00;
03881         lpPalette->rgbGreen     = 0x00;
03882         lpPalette->rgbBlue      = 0x00;
03883         lpPalette->rgbReserved  = 0xFF; // mark as do not use
03884         lpPalette++;
03885     }
03886 
03887     UINT32 DitherType = XARADITHER_NONE;    // request no dithering
03888     DIBConvert *pDoConvert = NULL;      // the convert DIB
03889 
03890     // Do some conversion using the DIBConvert class
03891     pDoConvert = DIBConvert::Create( pSourceInfoHeader->biBitCount, pDestInfoHeader->biBitCount,
03892                                      pSourceInfoHeader->biWidth, pLogPalette,  DitherType);
03893     // If this fails then exit now
03894     if (pDoConvert == NULL)
03895     {
03896         if (pLogPalette)
03897             CCFree(pLogPalette);
03898         return FALSE;
03899     }
03900     
03901     // Do the actual conversion process
03902     INT32 ChunkHeight = 16;     // We will do the conversion in chunks, in case we ask for dithering
03903     INT32 Height = pSourceInfoHeader->biHeight;
03904     INT32 SourceWidth = DIBUtil::ScanlineSize( pSourceInfoHeader->biWidth, pSourceInfoHeader->biBitCount ) * ChunkHeight;
03905     INT32 DestWidth = DIBUtil::ScanlineSize( pDestInfoHeader->biWidth, pDestInfoHeader->biBitCount ) * ChunkHeight;
03906     BOOL IsFirstStrip = TRUE;           // Whether we are on the first strip or not
03907     INT32 CurrentYPos = 0;              // current line number
03908     LPBYTE SourceData = pSourceBits;    // pointer to the source data
03909     LPBYTE DestData = *pDestBits;       // pointer to the destination data
03910     while (CurrentYPos < Height)
03911     { 
03912         // Work out the size of the export chunk left, normally ExportChunkHeight but
03913         // if at the end of export may be a small strip left.
03914         const UINT32 ThisBit = min( UINT32(Height - CurrentYPos), (UINT32)ChunkHeight );
03915         if (!pDoConvert->Convert( SourceData, DestData, ThisBit, IsFirstStrip ))
03916             return FALSE;                           // stop if conversion failed
03917 
03918         IsFirstStrip = FALSE;               // Done first strip
03919         SourceData  += SourceWidth;         // Move on by a lines worth
03920         DestData    += DestWidth;           // Move on by a lines worth
03921         CurrentYPos += INT32(ThisBit);      // Move down by a strips worth
03922     }
03923     
03924     // Put back the recommended palette by destructing the convert function.
03925     if (pDoConvert)
03926     {
03927         delete pDoConvert;
03928         pDoConvert = NULL;
03929     }   
03930 
03931     if (pLogPalette)
03932     {
03933         CCFree(pLogPalette);
03934         pLogPalette = NULL;
03935     }
03936 
03937     // If we got this far then more than likely we have waht we want
03938     return TRUE;
03939 }

BOOL DIBUtil::Convert8to32 LPBITMAPINFO  pSourceInfo,
LPBYTE  pSourceBits,
RGBQUAD pPalette,
LPBITMAPINFO  pDestInfo,
LPBYTE  pDestBits
[static]
 

Generates a 32bit form of the input 8bit bitmap, note that the destination bitmapinfo and bitmap must be allocated prior to this function.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
Date:
14/2/2000
Parameters:
pSourceInfo - A information header for the bitmap to be copied [INPUTS] pSourceBits - the actual bits for the bitmap to be copied pPalette - pointer to the palette pDestInfo - pointer to an ALLOCATED bitmapinfo structure pDestBits - pointer to an ALLOCATED 32bit bitmap
pDestInfo - pointer to the copied information block [OUTPUTS] pDestBits - pointer ot the copied bits data
Returns:
True if copied ok, false otherwise

Definition at line 3966 of file dibutil.cpp.

03968 {
03969     ERROR2IF(pSourceBits == NULL, FALSE, "NULL source bitmap");
03970     ERROR2IF(pSourceInfo == NULL, FALSE, "NULL source info");
03971     ERROR2IF(pDestInfo == NULL, FALSE, "NULL destination info");
03972     ERROR2IF(pDestBits == NULL, FALSE, "Null destination bitmap");
03973     
03974     // most info will be the same so memcpy is the quickest way
03975     //memcpy(pSourceInfo, pDestInfo, sizeof(BITMAPINFO));
03976 
03977     // these will all be the same
03978     pDestInfo->bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
03979     pDestInfo->bmiHeader.biWidth         = pSourceInfo->bmiHeader.biWidth;
03980     pDestInfo->bmiHeader.biHeight        = pSourceInfo->bmiHeader.biHeight;
03981     pDestInfo->bmiHeader.biPlanes        = pSourceInfo->bmiHeader.biPlanes;
03982     pDestInfo->bmiHeader.biCompression   = pSourceInfo->bmiHeader.biCompression;
03983     pDestInfo->bmiHeader.biXPelsPerMeter = pSourceInfo->bmiHeader.biXPelsPerMeter;
03984     pDestInfo->bmiHeader.biYPelsPerMeter = pSourceInfo->bmiHeader.biYPelsPerMeter;
03985     pDestInfo->bmiHeader.biClrImportant  = 0;
03986 
03987     // get the size of the new bitmap
03988     INT32 size = pDestInfo->bmiHeader.biWidth *  pDestInfo->bmiHeader.biHeight * 4;
03989     
03990     //these will be different from source
03991     pDestInfo->bmiHeader.biBitCount         = 32;
03992     pDestInfo->bmiHeader.biSizeImage        = size;
03993     pDestInfo->bmiHeader.biClrUsed          = 0;
03994 
03995 
03996     // convert from 8 bit to 32 bit
03997     INT32 bmpsize = pSourceInfo->bmiHeader.biWidth * pSourceInfo->bmiHeader.biHeight;
03998     INT32 padding = pSourceInfo->bmiHeader.biWidth % 4;
03999     if (padding)
04000         padding = 4 - padding;
04001 
04002     LPBYTE pSource = pSourceBits;
04003     LPBYTE pDest = pDestBits;
04004     for (INT32 i = 0; i < bmpsize; i ++)
04005     {
04006         if (i && i % pSourceInfo->bmiHeader.biWidth == 0)
04007             pSource += padding;
04008         *pDest = pPalette[*pSource].rgbBlue; 
04009         pDest++;
04010         *pDest = pPalette[*pSource].rgbGreen; 
04011         pDest++;
04012         *pDest = pPalette[*pSource].rgbRed; 
04013         pDest++;
04014         *pDest = pPalette[*pSource].rgbReserved;
04015         pDest++;
04016         pSource++;
04017     }
04018     return TRUE;
04019 
04020 }

void DIBUtil::Convert8to8 INT32  PixelWidth,
LPBYTE  InputBits,
LPBYTE  OutputBits
[static]
 

Definition at line 583 of file dibutil.cpp.

00584 {
00585     LPBYTE Source = (LPBYTE)InputBits;
00586     LPBYTE Dest = (LPBYTE)OutputBits;
00587     while (PixelWidth--)
00588     {
00589         *Dest++ = *Source++;
00590     }
00591 }

BOOL DIBUtil::ConvertTo8Greyscale LPBITMAPINFO  pSourceInfo,
LPBYTE  pSourceBits,
LPBITMAPINFO ppDestInfo,
LPBYTE ppDestBits
[static]
 

Generates an 8bpp greyscale bitmap from the given 1bpp, 4bpp or 8bpp bitmap.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
30/1/97
Parameters:
pSourceInfo - A information header for the bitmap to be copied [INPUTS] pSourceBits - the actual bits for the bitmap to be copied
pDestInfo - pointer to the 8bpp greyscale information block [OUTPUTS] pDestBits - pointer ot the 8bpp greyscale bits data
Returns:
True if copied ok, false otherwise

Definition at line 4039 of file dibutil.cpp.

04041 {
04042     if (pSourceInfo == NULL || pSourceBits == NULL || ppDestInfo == NULL || ppDestBits == NULL)
04043     {
04044         ERROR3("Null parameters");
04045         return FALSE;
04046     }
04047 
04048     // Get useful source bitmap info
04049     UINT32 Width   = pSourceInfo->bmiHeader.biWidth;
04050     UINT32 Height  = pSourceInfo->bmiHeader.biHeight;
04051     UINT32 Depth     = pSourceInfo->bmiHeader.biBitCount;
04052 
04053     // Calc number of colours in the palette
04054     UINT32 NumCols = 0;
04055     switch (Depth)
04056     {
04057         case 1: NumCols = 2;  break;
04058         case 4: NumCols = 16; break;
04059         case 8: NumCols = 256; break;
04060         case 16: break;
04061         case 24: break;
04062         case 32: break;
04063         default:
04064             ERROR3("Routine can't cope");
04065             return FALSE;
04066             break;
04067     }
04068 
04069     // Create the destination 8bpp bitmap, & check it all worked
04070     *ppDestInfo = AllocDIB(Width,Height, 8, ppDestBits);
04071     if (*ppDestInfo == NULL || *ppDestBits == NULL)
04072         return FALSE;
04073 
04074     // We need a lookup table that maps the give bitmap's palette to the 256 greyscale palette
04075     BYTE LookUp[256];
04076 
04077     if (NumCols > 0)
04078     {
04079         // Generate the greyscale lookup table.
04080         for (UINT32 i=0;i < NumCols;i++)
04081         {
04082             // Get the RGB components of this palette entry
04083             double R = pSourceInfo->bmiColors[i].rgbRed;
04084             double G = pSourceInfo->bmiColors[i].rgbGreen;
04085             double B = pSourceInfo->bmiColors[i].rgbBlue;
04086 
04087             // Calculate the intensity of the palette entry - this maps onto a greyscale palette entry
04088             BYTE C = BYTE((R * 0.305) + (G * 0.586) + (B * 0.109));
04089 
04090             // For each pixel that references palette entry 'i', map it onto greyscale palette entry 'C'
04091             LookUp[i] = C;
04092         }
04093     }
04094 
04095     // Calc number of bytes in each scan line
04096     UINT32 SourceScanLineLength = DIBUtil::ScanlineSize(Width,Depth);
04097     UINT32 DestScanLineLength   = DIBUtil::ScanlineSize(Width,8);
04098 
04099     // Run through the pixels of the source, and create the pixels of the destination
04100     UINT32 x,y ;
04101     BYTE* pSourcePixel = pSourceBits ;
04102     BYTE*   pDestPixel = *ppDestBits ;
04103     switch (Depth)
04104     {
04105     case 1:
04106         for ( y = 0; y < Height; y++ )
04107         {
04108             BYTE* pSource = pSourcePixel ;
04109             BYTE Pixel;
04110             BYTE SourceBitMask = 0x80;
04111             for ( x = 0; x < Width; x++ )
04112             {
04113                 // If the current bit is set, the pixel is 1, else 0
04114                 if (*pSource & SourceBitMask)
04115                     Pixel = 1;
04116                 else
04117                     Pixel = 0;
04118                 // Look up the greyscale byte value for the 'Pixel' entry in the source palette
04119                 pDestPixel[x] = LookUp[Pixel];
04120                 SourceBitMask >>= 1;        // Shift mask for next bit
04121                 if (SourceBitMask==0)
04122                 {
04123                     // Got last bit out of that byte, so reset mask and inc ptr to next byte
04124                     SourceBitMask = 0x80;
04125                     pSource++;
04126                 }
04127             }
04128             pSourcePixel += SourceScanLineLength ;
04129               pDestPixel +=   DestScanLineLength ;
04130         }
04131         break ;
04132 
04133     case 4:
04134         for ( y = 0; y < Height; y++ )
04135         {
04136             BYTE* pSource = pSourcePixel ;
04137             for ( x=0 ; x<Width ; x+=2 )
04138             {
04139                 // Look up the greyscale byte value for the pixel entries in the source palette
04140                 pDestPixel[x  ] = LookUp[*pSource >> 4] ;
04141                 pDestPixel[x+1] = LookUp[*pSource & 0xF] ;
04142                 pSource++;
04143             }
04144             pSourcePixel += SourceScanLineLength ;
04145               pDestPixel +=   DestScanLineLength ;
04146         }
04147         break ;
04148 
04149     case 8:
04150         for ( y=0 ; y<Height ; y++ )
04151         {
04152             // Look up the greyscale byte values for the pixel entries in the source palette
04153             for ( x=0 ; x<Width ; x++ )
04154                 pDestPixel[x] = LookUp[pSourcePixel[x]];
04155             pSourcePixel += SourceScanLineLength ;
04156               pDestPixel +=   DestScanLineLength ;
04157         }
04158         break ;
04159 
04160     case 16:
04161         for ( y=0 ; y<Height ; y++ )
04162         {
04163             WORD* pSrc = (WORD*)pSourcePixel;
04164             // Convert the pixel to greyscale and store
04165             for ( x=0 ; x<Width ; x++ )
04166             {
04167                 // 16bpp pixel value is pSrc[x]
04168                 BYTE Grey = 0xFF;
04169                 pDestPixel[x] = Grey;
04170                 pSrc++;
04171             }
04172             pSourcePixel += SourceScanLineLength ;
04173               pDestPixel +=   DestScanLineLength ;
04174         }
04175         break;
04176 
04177     case 24:
04178         for ( y=0 ; y<Height ; y++ )
04179         {
04180             BYTE* pSrc = pSourcePixel;
04181             // Convert the pixel to greyscale and store
04182             for ( x=0 ; x<Width ; x++ )
04183             {
04184                 // 24bpp pixel is 
04185                 BYTE Grey = (pSrc[2] * 78 + pSrc[1] * 150 + pSrc[0] * 28) >> 8;
04186                 pDestPixel[x] = Grey;
04187                 pSrc += 3;
04188             }
04189             pSourcePixel += SourceScanLineLength ;
04190               pDestPixel +=   DestScanLineLength ;
04191         }
04192         break;
04193 
04194     case 32:
04195         for ( y=0 ; y<Height ; y++ )
04196         {
04197             // Convert the pixels to greyscale as if they are rendered on a white 
04198             // background and store
04199             BGRT* pSrc = (BGRT*)pSourcePixel;
04200             for ( x=0 ; x<Width ; x++ )
04201             {
04202                 const BYTE Trans = pSrc->Transparency;
04203                 const BYTE Alpha = 255 - Trans;
04204                 BYTE Grey = (pSrc->Red * 78 + pSrc->Green * 150 + pSrc->Blue * 28) >> 8;
04205                 pDestPixel[x] = ((Grey * Alpha) + (255 * Trans)) / 255;
04206                 pSrc++;
04207             }
04208             pSourcePixel += SourceScanLineLength ;
04209               pDestPixel +=   DestScanLineLength ;
04210         }
04211         break;
04212     }
04213 
04214 //  BOOL ok = GenGreyscalePalette((*ppDestInfo)->bmiColors,256);
04215 
04216     return TRUE;
04217 }

BOOL DIBUtil::CopyBitmap LPBITMAPINFO  pSourceInfo,
LPBYTE  pSourceBits,
LPBITMAPINFO pDestInfo,
LPBYTE pDestBits
[static]
 

Definition at line 2750 of file dibutil.cpp.

02752 {
02753     // In case of early set these return pointers to NULL
02754     *pDestInfo = NULL;
02755     *pDestBits = NULL;
02756 
02757     ERROR2IF(pSourceInfo == NULL || pSourceBits == NULL, FALSE, "DIBUtil::CopyBitmap bad source bitmap");
02758 
02759     // Get a pointer to the useful bitmap header information for things like the size of the
02760     // bitmap and colour depth. 
02761     LPBITMAPINFOHEADER pSourceInfoHeader = &(pSourceInfo->bmiHeader); 
02762     DWORD biCompression = pSourceInfoHeader->biCompression;
02763 
02764     // Try and allocate the detsination bitmap to be the same size and colour depth as the source
02765     *pDestInfo = AllocDIB( pSourceInfoHeader->biWidth, pSourceInfoHeader->biHeight,
02766                            pSourceInfoHeader->biBitCount,
02767                            pDestBits );
02768 
02769     (*pDestInfo)->bmiHeader.biCompression = biCompression;
02770 
02771     // failed to allocate the bitmap so return false.
02772     if (*pDestInfo == NULL || *pDestBits == NULL )
02773         return FALSE;
02774     
02775     // Now copy the data from the source to the destination
02776     DWORD BitmapSize = pSourceInfo->bmiHeader.biSizeImage;
02777 #ifdef _DEBUG
02778     DebugMemCopy(*pDestBits, pSourceBits, BitmapSize);
02779 #else
02780     memcpy(*pDestBits, pSourceBits, BitmapSize);
02781 #endif
02782 
02783 
02784 //  LPBYTE A = pDestBMBytes;
02785 //  LPBYTE B = pBMBytes;
02786 //  for (INT32 y = 0; y < pBMInfoHeader->biHeight; y++)
02787 //  {
02788 //      for (INT32 x = 0; x < pBMInfoHeader->biWidth; x++)
02789 //      {
02790 //          *(A++) = *(B++);
02791 //      }
02792 //      A=(LPBYTE)( (((DWORD)(A))+3) & ~ 3); // word align
02793 //      B=(LPBYTE)( (((DWORD)(B))+3) & ~ 3); // word align
02794 //  }
02795 
02796     return TRUE;
02797 }   

LPLOGPALETTE DIBUtil::CopyBitmapPaletteIntoLogPalette KernelBitmap pBitmap  )  [static]
 

To allocate a LOGPALETTE and then copy the palette from inside the bitmap across to the LOGPALETTE. The caller is responsible for cleaning up the memmory allocation.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/07/97
Parameters:
The bitmap to copy the palette from [INPUTS]
Returns:
A pointer to the allocated LOGPALETTE or null.

Definition at line 4710 of file dibutil.cpp.

04711 {
04712     ERROR2IF(pBitmap == NULL,NULL,"CopyBitmapPaletteIntoLogPalette Bad bitmap");
04713 
04714     LPRGBQUAD       pPal    = pBitmap->GetPaletteForBitmap();
04715     UINT32          Bpp     = pBitmap->GetBPP();
04716     UINT32          PaletteSize = 1U<<Bpp;
04717     LPLOGPALETTE    pLogPal = NULL;
04718 
04719     // Bitmaps with more than 256 colours in usually do not require a palette
04720     if (Bpp > 8 || pPal == NULL)
04721     {
04722         ERROR2(NULL,"CopyBitmapPaletteIntoLogPalette bitmap has no palette");
04723         //return NULL;
04724     }
04725 
04726     pLogPal = DIBUtil::AllocateLogPalette(PaletteSize);
04727     if (pLogPal == NULL)
04728         return NULL;
04729     
04730     UINT32          ColoursInPal    = pBitmap->GetNumPaletteEntries();
04731     UINT32          ColoursInLogPal = pLogPal->palNumEntries;
04732     PALETTEENTRY*   pPaletteEntry   = pLogPal->palPalEntry;
04733     for (UINT32 i = 0; i < ColoursInLogPal; i++)
04734     {
04735         if (i > ColoursInPal)
04736         {
04737             // Force any unused colours to be do not use black
04738             pPaletteEntry[i].peBlue     = 0;
04739             pPaletteEntry[i].peGreen    = 0;
04740             pPaletteEntry[i].peRed      = 0;
04741 
04742             pPaletteEntry[i].peFlags    = 0xFF;
04743         }
04744         else
04745         {
04746             pPaletteEntry[i].peBlue     = pPal[i].rgbBlue;
04747             pPaletteEntry[i].peGreen    = pPal[i].rgbGreen;
04748             pPaletteEntry[i].peRed      = pPal[i].rgbRed;
04749 
04750             pPaletteEntry[i].peFlags    = 0x00;
04751         }
04752     }
04753 
04754     // Now fill in the actually number of palette entries
04755     // We must allocate the palette to be full sized as otherwise GDraw/CDraw will
04756     // more than likely fall over.
04757     pLogPal->palNumEntries = ColoursInPal;
04758 
04759     return pLogPal;
04760 }

BOOL DIBUtil::CopyBitmapSection LPBITMAPINFO  pSourceInfo,
LPBYTE  pSourceBits,
LPBITMAPINFO  pDestInfo,
LPBYTE  pDestBits,
INT32  SourceTop,
INT32  SourceLeft
[static]
 

To copy a section of the source bitmap to the destination. Note that unlike the other copy functions in this file the destination header must in not allocated so you must do it yourself. Likewise palette info.

Author:
Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> Altered by Phil to clip sensibly 13/05/2004
Date:
24/11/99
Parameters:
pSourceInfo - A information header for the bitmap to be copied [INPUTS] pSourceBits - the actual bits for the bitmap to be copied pDestInfo - An information header for the bitmap to be copied to pDestBits - An initialised bitmap to be copied into SourceTop - the y value of the the top left part of the section to be copied SourceLeft - the x value of the top left part of the section to be copied
pDestInfo - pointer to the copied information block [OUTPUTS] pDestBits - pointer ot the copied bits data
Returns:
True if copied ok, false otherwise
See also:
DIBUtil::CopyBitmap; PhotoShopPlugIn::Apply;

Definition at line 3026 of file dibutil.cpp.

03029 {
03030 //TRACEUSER( "Phil", _T("CopyBitmapSection Source %d, %d, Dest %d %d\n"), pSourceInfo->bmiHeader.biWidth, pSourceInfo->bmiHeader.biHeight, pDestInfo->bmiHeader.biWidth, pDestInfo->bmiHeader.biHeight);
03031 //TRACEUSER( "Phil", _T("CopyBitmapSection Source Compression %x\n"), pSourceInfo->bmiHeader.biCompression);
03032     if (pSourceInfo == NULL || pSourceBits == NULL || 
03033         pDestInfo == NULL || pDestBits == NULL)
03034     {
03035         ERROR3("One of the input pointers is NULL");
03036         return FALSE;
03037     }
03038 
03039     if (pSourceInfo->bmiHeader.biBitCount<8 || pDestInfo->bmiHeader.biBitCount<8)
03040     {
03041         ERROR3("This routine can't handle bit depths < 1 byte per pixel (no masking)");
03042         return FALSE;
03043     }
03044 
03045     if (pSourceInfo->bmiHeader.biBitCount != pDestInfo->bmiHeader.biBitCount)
03046     {
03047         ERROR3("This routine can't handle differing src and dest bit depths");
03048         return FALSE;
03049     }
03050 
03051     // Clip the dest rectangle against the source rectangle
03052     INT32 CopyWidth = pDestInfo->bmiHeader.biWidth;
03053     INT32 CopyHeight = pDestInfo->bmiHeader.biHeight;
03054     LPBYTE pDest = pDestBits;
03055     if (SourceLeft<0)
03056     {
03057         CopyWidth += SourceLeft;    // Subtract left offset from width to copy
03058         pDest += ScanlineBytes(-SourceLeft, pDestInfo->bmiHeader.biBitCount);
03059         SourceLeft = 0;
03060     }
03061     if (SourceTop<0)
03062     {
03063         CopyHeight += SourceTop;    // Subtract top offset from height to copy
03064         pDest += ScanlineSize(pDestInfo->bmiHeader.biWidth, pDestInfo->bmiHeader.biBitCount) * -SourceTop;
03065         SourceTop = 0;
03066     }
03067     if ((SourceLeft+CopyWidth) > pSourceInfo->bmiHeader.biWidth)
03068     {
03069         CopyWidth = (pSourceInfo->bmiHeader.biWidth - SourceLeft);
03070     }
03071     if ((SourceTop+CopyHeight) > pSourceInfo->bmiHeader.biHeight)
03072     {
03073         CopyHeight = (pSourceInfo->bmiHeader.biHeight - SourceTop);
03074     }
03075 
03076     // Check whether the clipping has left anything worth rendering...
03077     if (CopyWidth<=0 || CopyHeight<=0)
03078     {
03079         TRACEUSER("Phil", wxT("CopyBitmapSection clipped to NULL rectangle\n") );
03080         return TRUE;
03081     }
03082     
03083     // first move the source pointer to the correct location
03084     INT32 LeftOffset = ScanlineBytes(SourceLeft, pSourceInfo->bmiHeader.biBitCount);
03085     INT32 SourceScanlineBytes = ScanlineSize(pSourceInfo->bmiHeader.biWidth, pSourceInfo->bmiHeader.biBitCount);
03086 
03087     LPBYTE pSource = pSourceBits + LeftOffset;
03088     pSource += SourceScanlineBytes * SourceTop;
03089 
03090     // we are going to have to iterate through the sourcebitmap scanline by scanline and copy the
03091     // section that we want.  First work out how many bytes we want per scanline
03092 
03093     INT32 DestScanlineBytes = ScanlineSize(pDestInfo->bmiHeader.biWidth, pDestInfo->bmiHeader.biBitCount);
03094     INT32 CopyBytes = ScanlineBytes(CopyWidth, pSourceInfo->bmiHeader.biBitCount);
03095     for (INT32 Count = 0; Count < CopyHeight; Count++)
03096     {
03097         memcpy(pDest, pSource, CopyBytes);
03098 
03099         // move the destination pointer up by one scanline
03100         pDest += DestScanlineBytes;
03101         pSource += SourceScanlineBytes;
03102     }
03103 
03104     // If we have a 24-bit bitmap, no alpha channel, make sure we haven't inadvertently blitted
03105     // in a bunch of alpha values
03106     // Das ist eine Uber-bodge...
03107     if (pDestInfo->bmiHeader.biCompression == BI_RGB && pDestInfo->bmiHeader.biBitCount==32)
03108     {
03109         LPDWORD pBits = (LPDWORD) pDestBits;
03110         for (UINT32 i=0; i<pDestInfo->bmiHeader.biSizeImage; i+=sizeof(DWORD))
03111         {
03112             *pBits &= 0x00FFFFFF;
03113             pBits++;
03114         }
03115     }
03116     
03117     // if we have an 8 bit bitmap then copy the palette also
03118     if (pDestInfo->bmiHeader.biBitCount == 8 &&
03119         pSourceInfo->bmiHeader.biBitCount == 8)
03120     {
03121         for (INT32 i = 0; i < 256; i++)
03122             pDestInfo->bmiColors[i] = pSourceInfo->bmiColors[i];
03123     }
03124 
03125     return TRUE;
03126 }

BOOL DIBUtil::CopyEntireBitmap LPBITMAPINFO  pSourceInfo,
LPBYTE  pSourceBits,
LPBITMAPINFO pDestInfo,
LPBYTE pDestBits
[static]
 

Allocates a new DIB information header block and bits data and copies the source bitmap data across to the new bitmap. At present, just copies the actual bits data, the header will be the defaults plus width, height and colour depth. Not interested in the palette and other information stored in the bitmap info header. Same as CopyBitmap but actually copies the rest of the data as well. This includes:- Palette information Header information Bits information.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/12/96
Parameters:
pSourceInfo - A information header for the bitmap to be copied [INPUTS] pSourceBits - the actual bits for the bitmap to be copied
pDestInfo - pointer to the copied information block [OUTPUTS] pDestBits - pointer ot the copied bits data
Returns:
True if copied ok, false otherwise
See also:
DIBUtil::CopyBitmap; PhotoShopPlugIn::Apply;

Definition at line 2828 of file dibutil.cpp.

02830 {
02831     // In case of early set these return pointers to NULL
02832     *pDestInfo = NULL;
02833     *pDestBits = NULL;
02834 
02835     ERROR2IF(pSourceInfo == NULL || pSourceBits == NULL, FALSE, "DIBUtil::CopyBitmap bad source bitmap");
02836 
02837     // Get a pointer to the useful bitmap header information for things like the size of the
02838     // bitmap and colour depth. 
02839     LPBITMAPINFOHEADER pSourceInfoHeader = &(pSourceInfo->bmiHeader); 
02840 
02841     // Try and allocate the detsination bitmap to be the same size and colour depth as the source
02842     *pDestInfo = AllocDIB( pSourceInfoHeader->biWidth, pSourceInfoHeader->biHeight,
02843                            pSourceInfoHeader->biBitCount,
02844                            pDestBits );
02845 
02846     // failed to allocate the bitmap so return false.
02847     if (*pDestInfo == NULL || *pDestBits == NULL )
02848         return FALSE;
02849     
02850     // Now copy the data from the source to the destination
02851     DWORD BitmapSize = pSourceInfo->bmiHeader.biSizeImage;
02852     memcpy(*pDestBits, pSourceBits, BitmapSize);
02853 
02854     // The older slower way of doing that
02855 //  LPBYTE A = *pDestBits;
02856 //  LPBYTE B = pSourceBits;
02857 //  for (INT32 y = 0; y < pSourceInfoHeader->biHeight; y++)
02858 //  {
02859 //      for (INT32 x = 0; x < pSourceInfoHeader->biWidth; x++)
02860 //      {
02861 //          *(A++) = *(B++);
02862 //      }
02863 //      A=(LPBYTE)( (((DWORD)(A))+3) & ~ 3); // word align
02864 //      B=(LPBYTE)( (((DWORD)(B))+3) & ~ 3); // word align
02865 //  }
02866 
02867     // Ensure remaining info header entries are correct
02868     LPBITMAPINFOHEADER pDestInfoHeader = &((*pDestInfo)->bmiHeader); 
02869     pDestInfoHeader->biPlanes           = pSourceInfoHeader->biPlanes;
02870     pDestInfoHeader->biCompression      = pSourceInfoHeader->biCompression;
02871     pDestInfoHeader->biXPelsPerMeter    = pSourceInfoHeader->biXPelsPerMeter;
02872     pDestInfoHeader->biYPelsPerMeter    = pSourceInfoHeader->biYPelsPerMeter;
02873     pDestInfoHeader->biClrImportant     = pSourceInfoHeader->biClrImportant;
02874     pDestInfoHeader->biClrUsed          = pSourceInfoHeader->biClrUsed;
02875 
02876     LPRGBQUAD pSourcePalette = &(pSourceInfo->bmiColors[0]);
02877     LPRGBQUAD pDestPalette = &((*pDestInfo)->bmiColors[0]);
02878     UINT32 NumberOfColours = pSourceInfoHeader->biClrUsed;
02879     // If we have zero colours on a bitmap which is 8bpp or less then this is bad.
02880     // This should be translated as the maximum number of colours allowed
02881     if (pSourceInfoHeader->biBitCount <= 8 && NumberOfColours == 0)
02882         NumberOfColours = 1 << pSourceInfoHeader->biBitCount;
02883     CopyPalette(pSourcePalette, pDestPalette, NumberOfColours);
02884 
02885     return TRUE;
02886 }   

KernelBitmap * DIBUtil::CopyKernelBitmap KernelBitmap pKernelBitmap,
BOOL  IsTemp = FALSE
[static]
 

Allocates a new CWxBitmap and KernelBitmap pointing to it. Note these are completely new versions containing the same data as the old ones.

Author:
Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/5/95
Parameters:
pKernelBitmap - A kernel bitmap to copy [INPUTS] IsTemp - TRUE means only create the bitmap as temporary and hence don't show in bitmap gallery FALSE means create properly and show in bitmap gallery (default)
- [OUTPUTS]
Returns:
Pointer to newly allocated KernelBitmap structure
Deleting the KernelBitmap will handle the other stuff ok...

Notes: Most of the code in camelot assumes that the OILBitmap is always in memory, so creating a new kernelbitmap would just pop in a pointer to the OILBitmap. This is bad when thumbnails come into the equation since these come and go like no tomorrow...

This should really be popped in dibutils at some point in the 'I want a big rebuild'ing future... Used to be in SGLibOil but moved 30/6/95 by Neville as required for transparent GIF import.

Definition at line 2956 of file dibutil.cpp.

02957 {
02958     OILBitmap *pOilBitmap = pKernelBitmap->ActualBitmap;
02959     ERROR3IF(pOilBitmap == NULL, "Unattached kernel bitmap found!");
02960     CWxBitmap* pWBitmap = (CWxBitmap*)pOilBitmap;
02961     LPBITMAPINFO Info = pWBitmap->BMInfo;
02962     LPBYTE Bytes = pWBitmap->BMBytes;
02963     ERROR3IF(Info == NULL, "Bitmap info is null - oh god !");
02964     ERROR3IF(Info->bmiHeader.biSizeImage == 0, "Bitmap data size is zero - I'm about to screw up");
02965 
02966     LPBITMAPINFO NewInfo = NULL;
02967 
02968     LPBYTE NewBytes = NULL;
02969     NewInfo = AllocDIB(Info->bmiHeader.biWidth, Info->bmiHeader.biHeight, Info->bmiHeader.biBitCount, &NewBytes);
02970 
02971     if (NewInfo == NULL || NewBytes == NULL)
02972     {
02973         ERROR3("Couldn't allocate enough memory for new CWxBitmap");
02974         return(NULL);
02975     }
02976 
02977     UINT32 PalSize = CalcPaletteSize(pWBitmap->GetBPP(), Info->bmiHeader.biCompression == BI_BITFIELDS);
02978     DWORD HeaderSize = Info->bmiHeader.biSize + PalSize;
02979     DWORD BitmapSize = Info->bmiHeader.biSizeImage;
02980 
02981     // Copy the DIB into the block of memory (copy the header and body separately as they
02982     // may not lie in contiguous memory)
02983     memcpy(NewInfo, Info, HeaderSize);
02984     memcpy(NewBytes, Bytes, BitmapSize);
02985 
02986     CWxBitmap *NewCWxBitmap = new CWxBitmap(NewInfo, NewBytes);
02987     ERROR3IF(NewCWxBitmap == NULL, "NULL CWxBitmap created");
02988 
02989     // Create the associated kernel object to go with the oil object
02990     KernelBitmap *TheKBToReturn = new KernelBitmap((OILBitmap *)NewCWxBitmap, IsTemp);
02991 
02992     return TheKBToReturn;
02993 }

BOOL DIBUtil::CopyPalette LPRGBQUAD  pSourcePalette,
LPRGBQUAD  pDestPalette,
UINT32  NumberOfColours
[static]
 

Copy a palette from a bitmap which has been duplicated and so has the same colour depth and number of palette entries, to a destination bitmap. Assumes palettes already allocated as part of the duplication process.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
18/12/96
Parameters:
pSourcePalette - the source palette in RGBQUAD form [INPUTS] pDestPalette - the destination palette in RGBQUAD form NumberOfColours - number of palette entries to copy
Returns:
True if copied correctly, False otherwise.
See also:
DIBUtil::CopyEntireBitmap;

Definition at line 2905 of file dibutil.cpp.

02906 {
02907     // Check if there is any palette information to copy, if not just return
02908     if (pSourcePalette == NULL || pDestPalette == NULL || NumberOfColours == 0)
02909         return TRUE;
02910 
02911     for (UINT32 i = 0; i < NumberOfColours; i++)
02912     {
02913         pDestPalette->rgbBlue       = pSourcePalette->rgbBlue;
02914         pDestPalette->rgbGreen      = pSourcePalette->rgbGreen;
02915         pDestPalette->rgbRed        = pSourcePalette->rgbRed;
02916         pDestPalette->rgbReserved   = pSourcePalette->rgbReserved;
02917         pDestPalette++;
02918         pSourcePalette++;
02919     }
02920 
02921     return TRUE;
02922 }

BOOL DIBUtil::CountColoursUsed BITMAPINFO pInfo,
BYTE *  pBits,
UINT32 **  pResultsArray
[static]
 

Counts the usage for each palette index in the bitmap. NOTE: Caller is responsible for CCFreeing the results array.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/6/96
Parameters:
pInfo Pointer to a BITMAPINFO describing the bitmap [INPUTS] pBits Pointer to the bitmap bits
pResultsArray Allocated and filled in with results [OUTPUTS]
Returns:
TRUE/FALSE for success/failure

Definition at line 3140 of file dibutil.cpp.

03141 {
03142     ERROR2IF(pInfo==NULL || pBits==NULL, FALSE, "NULL entry param");
03143     ERROR3IF(*pResultsArray != NULL, "pResultsArray was not NULL (are you leaking memory?)");
03144 
03145     // Claim and initalise the results array.
03146     const UINT32 NumColours = 1 << pInfo->bmiHeader.biBitCount;
03147     ERROR2IF(NumColours>256, FALSE, "DIBUtil::CountColoursUsed only handles palletted DIBs");
03148     *pResultsArray = (UINT32*) CCMalloc(NumColours*sizeof(UINT32));
03149     if (*pResultsArray == NULL)
03150         return FALSE;
03151     memset(*pResultsArray, 0, NumColours*sizeof(UINT32));
03152 
03153     // Calculate the length of a scanline in bytes as they are word aligned.
03154     UINT32 ScanLineLength = 0;
03155     switch (pInfo->bmiHeader.biBitCount)
03156     {
03157         case 8:
03158             ScanLineLength = ((pInfo->bmiHeader.biWidth+3)/4)*4;
03159             break;
03160         case 4:
03161             ScanLineLength = ((pInfo->bmiHeader.biWidth+7)/8)*4;
03162             break;
03163         case 1:
03164             ScanLineLength = ((pInfo->bmiHeader.biWidth+31)/32)*4;
03165             break;
03166         default:
03167             ERROR2(FALSE, "Unknown depth");
03168     }
03169 
03170     // Run through the pixels, incrementing the counters
03171     for (INT32 y = 0; y < pInfo->bmiHeader.biHeight; y++)
03172     {
03173         BYTE* pCurrentPixel = pBits + y*ScanLineLength;
03174         BYTE CurrentBitMask = 0x80;
03175 
03176         for (INT32 x = 0; x < pInfo->bmiHeader.biWidth; x++)
03177         {
03178             switch (pInfo->bmiHeader.biBitCount)
03179             {
03180                 case 8:
03181                     // simple - one pixel per byte
03182                     (*pResultsArray)[(*pCurrentPixel)]++;
03183                     pCurrentPixel++;
03184                     break;
03185 
03186                 case 4:
03187                     // Two pixels per byte
03188                     if (x%2 == 0)
03189                     {
03190                         (*pResultsArray)[((*pCurrentPixel) >> 4)]++;
03191                     }
03192                     else
03193                     {
03194                         (*pResultsArray)[((*pCurrentPixel) & 0xF)]++;
03195                         pCurrentPixel++;
03196                     }
03197                     break;
03198 
03199                 case 1:
03200                     // Tricker - one pixel per bit.
03201                     if ((*pCurrentPixel) & CurrentBitMask)
03202                         (*pResultsArray)[1]++;
03203                     else
03204                         (*pResultsArray)[0]++;
03205 
03206                     if (CurrentBitMask == 1)
03207                     {
03208                         CurrentBitMask = 0x80;
03209                         pCurrentPixel++;
03210                     }
03211                     else
03212                         CurrentBitMask = CurrentBitMask >> 1;
03213                     break;
03214 
03215                 default:
03216                     ERROR2(FALSE, "Unknown depth");
03217             }
03218         }
03219     }
03220 
03221     return TRUE;
03222 }

OILBitmap * DIBUtil::Create8bppGreyscaleBitmap KernelBitmap pSrcBitmap  )  [static]
 

Designed to be used to create an 8bpp greyscale bitmap from a 24bpp, 4bpp or 1bpp bitmaps.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/1/97
Parameters:
pSrcBitmap = ptr to a kernel bitmap [INPUTS]
Returns:
ptr to an Oil bitmap containing an 8bpp greyscale image
It will do nothing if the bitmap is already an 8bpp bitmap. In this case you should copy the kernel bitmap and call GenerateGreyscaleTable() on the copy.

Definition at line 4236 of file dibutil.cpp.

04237 {
04238     OILBitmap* pOilBitmap = pSrcBitmap->GetActualBitmap();
04239     ERROR2IF(pOilBitmap == NULL,NULL,"null OIL bitmap present!");
04240 
04241     // Try to import bitmap as usual binary BMP file.
04242     CWxBitmap* pCWxBitmap = (CWxBitmap*)pOilBitmap;
04243     ERROR2IF(pCWxBitmap == NULL,NULL,"null WINOIL bitmap present!");
04244     
04245     LPBITMAPINFO pSourceInfo    = pCWxBitmap->BMInfo;
04246     LPBYTE pSourceBits          = pCWxBitmap->BMBytes;
04247     
04248     LPBITMAPINFO pDestInfo      = NULL;
04249     LPBYTE pDestBits            = NULL;
04250 
04251     BOOL ok = FALSE;
04252 
04253     switch (pSrcBitmap->GetBPP())
04254     {
04255         case 1:
04256         case 4:
04257         case 8:
04258         case 24:
04259         case 32:
04260             ok = ConvertTo8Greyscale(pSourceInfo, pSourceBits, &pDestInfo, &pDestBits);
04261             break;
04262 
04263         default:
04264             ERROR3("How many bits? No chance mate");
04265             return NULL;
04266             break;
04267     }
04268 
04269     OILBitmap* pResultBitmap = NULL;
04270 
04271     if (ok)
04272     {
04273         // Create a new CWxBitmap to contain this data
04274         pResultBitmap = (OILBitmap*) new CWxBitmap(pDestInfo, pDestBits);
04275         if (pResultBitmap == NULL)
04276             FreeDIB( pDestInfo, pDestBits );
04277     }
04278 
04279     return pResultBitmap;
04280 }

BOOL DIBUtil::ExactPaletteInitialise LPLOGPALETTE  pExactPalette  )  [static]
 

Definition at line 3336 of file dibutil.cpp.

03337 {
03338     ERROR3IF(pExactPalette == NULL, "NULL pointer passed to DIBUtil::ExactPaletteInitialise");
03339     if (pExactPalette == NULL)
03340         return FALSE;
03341 
03342 //  ::ExactPaletteInitialise( pExactPalette );  
03343 //  return TRUE;
03344     ASSERT(0);
03345     return FALSE;
03346 
03347 }

INT32 DIBUtil::FindLeastUsedColour BITMAPINFO pInfo,
UINT32 pResultsArray
[static]
 

Takes the results from DIBUtil::CountColoursUsed and works out which colour is the best one to use as a transparent colour by finding the least used. NOTE: Caller is responsible for CCFreeing the results array.

> static INT32 DIBUtil::FindLeastUsedColour(BITMAPINFO* pInfo, UINT32* pResultsArray)

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> from Will code
Date:
19/8/97
Parameters:
pInfo Pointer to a BITMAPINFO describing the bitmap [INPUTS] pResultsArray filled in with results from CountColoursUsed
Returns:
The index of the transparent colour to use

Definition at line 3239 of file dibutil.cpp.

03240 {
03241     ERROR2IF(pInfo == NULL || pResultsArray == NULL, -1, "NULL entry param");
03242     INT32 TransIndex = -1;
03243 
03244     INT32 MinIndex = 0;
03245 
03246     // Attempt to find an unused colour in the results array
03247     INT32 Bpp = pInfo->bmiHeader.biBitCount;
03248     INT32 MaxColours = 1 << Bpp;
03249     for (INT32 loop = 0; loop < MaxColours; loop++)
03250     {
03251         if (pResultsArray[loop] == 0 && TransIndex == -1)   // For consistancy use the first available index
03252             TransIndex = loop;
03253         if (pResultsArray[loop] < pResultsArray[MinIndex])
03254             MinIndex = loop;
03255     }
03256 
03257     if (TransIndex == -1)
03258     {
03259         // Make white transparent for 1bpp images
03260         if (Bpp == 1)
03261             TransIndex = 1;
03262         else
03263             TransIndex = MinIndex;
03264     }
03265 
03266     return TransIndex;
03267 }

BOOL DIBUtil::GenerateDifferenceBitmap LPBITMAPINFO  pPreviousInfo,
LPBYTE  pPreviousBits,
LPBITMAPINFO  pCurrentInfo,
LPBYTE  pCurrentBits,
LPBITMAPINFO ppDestInfo,
LPBYTE ppDestBits,
INT32  TransColour,
BOOL *  pFoundBadOverlay = NULL
[static]
 

Definition at line 4310 of file dibutil.cpp.

04314 {
04315     ERROR2IF(pPreviousInfo == NULL || pPreviousBits == NULL,FALSE,"GenerateDifferenceBitmap Bad previous pointers!" );
04316     ERROR2IF(pCurrentInfo == NULL || pCurrentBits == NULL,FALSE,"GenerateDifferenceBitmap Bad current pointers!" );
04317     ERROR2IF(ppDestInfo == NULL || ppDestBits == NULL,FALSE,"GenerateDifferenceBitmap Bad destination pointers!" );
04318 
04319     if (TransColour < 0 || TransColour > 256)
04320     {
04321         TRACEUSER( "Neville", wxT("GenerateDifferenceBitmap Bad transparent colour\n") );
04322         // return TRUE so that we do not fail
04323         return TRUE;
04324     }
04325 
04326     // Get useful source bitmap info
04327     UINT32 Width   = pPreviousInfo->bmiHeader.biWidth;
04328     UINT32 Height  = pPreviousInfo->bmiHeader.biHeight;
04329     UINT32 Depth     = pPreviousInfo->bmiHeader.biBitCount;
04330 
04331     // Get useful destination bitmap info
04332     UINT32 CurrentWidth   = pCurrentInfo->bmiHeader.biWidth;
04333     UINT32 CurrentHeight  = pCurrentInfo->bmiHeader.biHeight;
04334     UINT32 CurrentDepth  = pCurrentInfo->bmiHeader.biBitCount;
04335 
04336     // We can only check bitmaps that are the same size and colour depth
04337     if (Width != CurrentWidth || Height != CurrentHeight || Depth != CurrentDepth)
04338     {
04339         TRACEUSER("Neville", wxT("GenerateDifferenceBitmap Source and destination bitmaps different sizes and/or depths\n") );
04340         // return TRUE so that we do not fail
04341         return TRUE;
04342     }
04343 
04344     // At present, can only check bitmaps that are 8bpp
04345     if (Depth != 8)
04346     { 
04347         TRACEUSER( "Neville", wxT("GenerateDifferenceBitmap Bitmap colour depth is not supported\n") );
04348         // return TRUE so that we do not fail
04349         return TRUE;
04350     }
04351 
04352     // We need to allocate the destination bitmap, so go and do that now
04353     // The easiest way is to produce an exact copy of the present bitmap
04354     BOOL ok = DIBUtil::CopyEntireBitmap(pCurrentInfo, pCurrentBits, ppDestInfo, ppDestBits);
04355     // If this failed then get out now
04356     if (!ok || *ppDestInfo == NULL || *ppDestBits == NULL)
04357         return FALSE;
04358 
04359     UINT32 ScanLineSize     = DIBUtil::ScanlineSize( Width, Depth );
04360     LPBYTE pPreviousData    = pPreviousBits;
04361     LPBYTE pCurrentData     = pCurrentBits;
04362     LPBYTE pDestData        = *ppDestBits;
04363     BOOL BadOverlay         = FALSE;
04364     for (UINT32 y = 0; y < Height && !BadOverlay; y++)
04365     {
04366         for (UINT32 x = 0; x < Width && !BadOverlay; x++)
04367         {
04368             // If the source and destination pixels are the same then
04369             // set the destination pixel to be the transparent colour
04370             if (pPreviousData[x] == pCurrentData[x])
04371                 pDestData[x] = TransColour & 0xFF;
04372             // If the current frame has a transparent pixel and we have a 
04373             // non-transparent pixel in the previous frame then we must
04374             // stop and use a replace background type
04375             else if (pCurrentData[x] == (TransColour & 0xFF))
04376             {
04377                 BadOverlay = TRUE;
04378                 break;
04379             }
04380         }
04381 
04382         // move onto the next scanline in each bitmap
04383         pPreviousData   += ScanLineSize;
04384         pCurrentData    += ScanLineSize;
04385         pDestData       += ScanLineSize;
04386     }
04387 
04388     // return the state of the bad overlay to the caller if they required it
04389     if (pFoundBadOverlay)
04390     {
04391         *pFoundBadOverlay = BadOverlay;
04392         
04393         if (BadOverlay)
04394         {
04395             // remove the diff bitmap
04396             if (*ppDestInfo && *ppDestBits)
04397             {
04398                 FreeDIB(*ppDestInfo, *ppDestBits);
04399                 *ppDestInfo = NULL;
04400                 *ppDestBits = NULL;
04401             }
04402         }
04403     }
04404 
04405     // everything went ok
04406     return TRUE;
04407 }

BOOL DIBUtil::GenerateSubRegionBitmap LPBITMAPINFO  pSourceInfo,
LPBYTE  pSourceBits,
LPBITMAPINFO ppDestInfo,
LPBYTE ppDestBits,
INT32  TransColour,
UINT32 pLeftOffset,
UINT32 pTopOffset
[static]
 

Definition at line 4435 of file dibutil.cpp.

04438 {
04439     ERROR2IF(pSourceInfo == NULL || pSourceBits == NULL,FALSE,"GenerateSubRegionBitmap Bad source pointers!" );
04440     ERROR2IF(ppDestInfo == NULL || ppDestBits == NULL,FALSE,"GenerateSubRegionBitmap Bad destination pointers!" );
04441     ERROR2IF(pLeftOffset == NULL || pTopOffset == NULL,FALSE,"GenerateSubRegionBitmap Bad offset pointers!" );
04442 
04443     if (TransColour < 0 || TransColour > 255)
04444     {
04445         TRACEUSER( "Neville", wxT("GenerateSubRegionBitmap Bad transparent colour\n") );
04446         // return TRUE so that we do not fail
04447         return TRUE;
04448     }
04449 
04450     // Get useful source bitmap info
04451     UINT32 Width   = pSourceInfo->bmiHeader.biWidth;
04452     UINT32 Height  = pSourceInfo->bmiHeader.biHeight;
04453     UINT32 Depth     = pSourceInfo->bmiHeader.biBitCount;
04454 
04455     // At present, can only check bitmaps that are 8bpp
04456     if (Depth != 8)
04457     {
04458         TRACEUSER( "Neville", wxT("GenerateSubRegionBitmap Bitmap colour depth is not supported\n") );
04459         // return TRUE so that we do not fail
04460         return TRUE;
04461     }
04462 
04463     UINT32 ScanLineSize     = DIBUtil::ScanlineSize( Width, Depth );
04464 
04465     //-------------
04466     // Scan through from the left hand side finding any columns that we can remove
04467     // Start in an illegal position so we can note any changes
04468     INT32 LeftMostData = -1;
04469     LPBYTE pSourceData  = pSourceBits;
04470     LPBYTE pPixel = NULL;
04471     BOOL FoundClearColumn = TRUE;
04472     for (UINT32 x = 0; x < Width; x++)
04473     {
04474         for (UINT32 y = 0; y < Height; y++)
04475         {
04476             // Check the next pixel in sequence
04477             pPixel = pSourceData + y * ScanLineSize + x;
04478             // If the pixel is not transparent then stop the search now
04479             if (*pPixel != (TransColour & 0xFF))
04480             {
04481                 FoundClearColumn = FALSE;
04482                 break;
04483             }
04484         }
04485         
04486         // If we found a full clear column then note this as a new left hand position
04487         // and move onto the next
04488         if (FoundClearColumn)
04489             LeftMostData = x;
04490         else
04491             break;
04492     }
04493 
04494     //-------------
04495     // Scan through from the right hand side finding any columns that we can remove
04496     // Start in an illegal position so we can note any changes
04497     UINT32 RightMostData = Width;
04498     pSourceData = pSourceBits;
04499     FoundClearColumn = TRUE;
04500     for( UINT32 x = Width - 1; x >= 0 ; x-- )
04501     {
04502         for (UINT32 y = 0; y < Height; y++)
04503         {
04504             // Check the next pixel in sequence
04505             pPixel = pSourceData + y * ScanLineSize + x;
04506             // If the pixel is not transparent then stop the search now
04507             if (*pPixel != (TransColour & 0xFF))
04508             {
04509                 FoundClearColumn = FALSE;
04510                 break;
04511             }
04512         }
04513         
04514         // If we found a full clear column then note this as a new right hand position
04515         // and move onto the next
04516         if (FoundClearColumn)
04517             RightMostData = x;
04518         else
04519             break;
04520     }
04521 
04522     //-------------
04523     // Scan through from the top finding any rows that we can remove
04524     // Start in an illegal position so we can note any changes
04525     // REMEMBER bitmaps are stored from bottom line downwards in memory 
04526     INT32 TopMostData = -1;
04527     pSourceData = pSourceBits + (Height - 1) * ScanLineSize;
04528     BOOL FoundClearRow = TRUE;
04529     for (UINT32 y = 0; y < Height; y++)
04530     {
04531         for (UINT32 x = 0; x < Width; x++)
04532         {
04533             // If the pixel is not transparent then stop the search now
04534             if (pSourceData[x] != (TransColour & 0xFF))
04535             {
04536                 FoundClearRow = FALSE;
04537                 break;
04538             }
04539         }
04540 
04541         // If we found a full clear column then note this as a new top position
04542         // and move onto the next
04543         if (FoundClearRow)
04544             TopMostData = y;
04545         else
04546             break;
04547 
04548         // move onto the next scanline in each bitmap
04549         pSourceData -= ScanLineSize;
04550     }
04551 
04552     //-------------
04553     // Scan through from the bottom finding any rows that we can remove
04554     // Start in an illegal position so we can note any changes
04555     UINT32 BottomMostData = Height;
04556     pSourceData = pSourceBits;
04557     FoundClearRow = TRUE;
04558     for (UINT32 y = Height - 1; y >= 0; y--)
04559     {
04560         for (UINT32 x = 0; x < Width; x++)
04561         {
04562             // If the pixel is not transparent then stop the search now
04563             if (pSourceData[x] != (TransColour & 0xFF))
04564             {
04565                 FoundClearRow = FALSE;
04566                 break;
04567             }
04568         }
04569 
04570         // If we found a full clear row then note this as a new bottom hand position
04571         // and move onto the next
04572         if (FoundClearRow)
04573             BottomMostData = y;
04574         else
04575             break;
04576 
04577         // move onto the next scanline in each bitmap
04578         pSourceData += ScanLineSize;
04579     }
04580 
04581     TRACEUSER("Neville", wxT("width = %d, left offset = %d, right offset = %d\n"), Width, LeftMostData,RightMostData);
04582     TRACEUSER("Neville", wxT("height = %d, top offset = %d, bottom offset = %d\n"), Height, TopMostData,BottomMostData);
04583 
04584     // We have detected that we can sub-region this bitmap
04585     if (LeftMostData >= 0 || RightMostData < Width || TopMostData >= 0 || BottomMostData < Height)
04586     {
04587         UINT32 LeftOffset = 0;
04588         if (LeftMostData > 0)
04589             LeftOffset = LeftMostData;
04590         UINT32 RightOffset = Width - 1;
04591         if (RightMostData < Width - 1)
04592             RightOffset = RightMostData;
04593         // sanity check to see if the offsets are crossed over
04594         if (RightOffset < LeftOffset)
04595             RightOffset = LeftOffset;
04596 
04597         UINT32 TopOffset = 0;
04598         if (TopMostData > 0)
04599             TopOffset = TopMostData;
04600         UINT32 BottomOffset = Height - 1;
04601         if (BottomMostData < Height - 1)
04602             BottomOffset = BottomMostData;
04603         // sanity check to see if the offsets are crossed over
04604         if (BottomOffset < TopOffset)
04605             BottomOffset = TopOffset;
04606 
04607         UINT32 NewWidth = RightOffset - LeftOffset + 1;
04608         UINT32 NewHeight = BottomOffset - TopOffset + 1;
04609 
04610         TRACEUSER("Neville", wxT("Creating sub-region bitmap new height = %d, new width = %d\n"), NewWidth,NewHeight);
04611 
04612         // Create the new sized bitmap && check it all worked
04613         LPBYTE pBits = NULL;
04614         LPBITMAPINFO pInfo = AllocDIB(NewWidth, NewHeight, Depth, &pBits);
04615         if (pInfo == NULL || pBits == NULL)
04616             return FALSE;
04617 
04618         // Ensure remaining info header entries are correct
04619         LPBITMAPINFOHEADER pSourceInfoHeader = &(pSourceInfo->bmiHeader);
04620         LPBITMAPINFOHEADER pDestInfoHeader  = &(pInfo->bmiHeader); 
04621         pDestInfoHeader->biPlanes           = pSourceInfoHeader->biPlanes;
04622         pDestInfoHeader->biCompression      = pSourceInfoHeader->biCompression;
04623         pDestInfoHeader->biXPelsPerMeter    = pSourceInfoHeader->biXPelsPerMeter;
04624         pDestInfoHeader->biYPelsPerMeter    = pSourceInfoHeader->biYPelsPerMeter;
04625         pDestInfoHeader->biClrImportant     = pSourceInfoHeader->biClrImportant;
04626         pDestInfoHeader->biClrUsed          = pSourceInfoHeader->biClrUsed;
04627 
04628         // Ensure that the palette information is copied across
04629         LPRGBQUAD pSourcePalette = &(pSourceInfo->bmiColors[0]);
04630         LPRGBQUAD pDestPalette = &(pInfo->bmiColors[0]);
04631         UINT32 NumberOfColours = pSourceInfoHeader->biClrUsed; 
04632         // If we have zero colours on a bitmap which is 8bpp or less then this is bad.
04633         // This should be translated as the maximum number of colours allowed
04634         if (pSourceInfoHeader->biBitCount <= 8 && NumberOfColours == 0)
04635             NumberOfColours = 1 << pSourceInfoHeader->biBitCount;
04636         CopyPalette(pSourcePalette, pDestPalette, NumberOfColours);
04637 
04638         // Now copy the bitmap data across to the new bitmap
04639         UINT32 DestScanLineSize = DIBUtil::ScanlineSize(NewWidth, Depth);
04640         // Move the pointers to the top of the bitmaps in memory
04641         LPBYTE pSourceData = pSourceBits + (Height - 1) * ScanLineSize;
04642         LPBYTE pDestData = pBits + (NewHeight - 1) * DestScanLineSize;
04643         for (UINT32 y = TopOffset; y <= BottomOffset; y++)
04644         {
04645             LPBYTE pThisSourceData  = pSourceData - (y * ScanLineSize) + LeftOffset;
04646             LPBYTE pThisDestData    = pDestData - ((y - TopOffset) * DestScanLineSize);
04647             memcpy(pThisDestData, pThisSourceData, NewWidth);
04648         }
04649 
04650         // remove the old bitmap
04651         if (*ppDestInfo && *ppDestBits)
04652             FreeDIB(*ppDestInfo, *ppDestBits);
04653         
04654         // return the new bitmap to the caller
04655         *ppDestInfo = pInfo;
04656         *ppDestBits = pBits;
04657 
04658         // return the left and top most positions to the caller
04659         *pLeftOffset = LeftOffset;
04660         *pTopOffset = TopOffset;
04661         TRACEUSER( "Neville",wxT("Creating sub-region bitmap left offset = %d, top offset = %d\n"),LeftOffset,TopOffset);
04662     }
04663     
04664     return TRUE;
04665 }

BOOL DIBUtil::GenGreyscalePalette LPRGBQUAD  lpPalette,
const size_t  PaletteSize
[static]
 

Generate a greyscale palette for a greyscale DIB.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/05/96
Parameters:
PaletteSize number of palette entries that need generating [INPUTS] lpPalette pointer to the palette defined in the DIB
Returns:
True if worked ok, False otherwise.

Definition at line 3585 of file dibutil.cpp.

03586 {
03587     ERROR2IF(lpPalette == NULL,FALSE,"PNGUtil::GenerateGreyPalette no lpPalette present");
03588     ERROR2IF(PaletteSize <= 0,FALSE,"PNGUtil::GenerateGreyPalette no PNG palette entries present");
03589 
03590     // Work out the value we require per step so on a:-
03591     //  256 colour palette we can have 256 steps of 1
03592     //  16 colour palette we have 16 steps of 16 (16 * 16 = 256)
03593     INT32                   inc = INT32(256 / PaletteSize);
03594     INT32                   value = 0;
03595     for( size_t i = 0; i < PaletteSize; i++ )
03596     {
03597         lpPalette->rgbBlue = value;
03598         lpPalette->rgbGreen = value;
03599         lpPalette->rgbRed = value;
03600         lpPalette->rgbReserved = 0;
03601         lpPalette++;
03602         value += inc;
03603         if (value > 255)
03604             value = 255;
03605     }
03606     
03607     return TRUE;
03608 }

BOOL DIBUtil::GenGreyscalePaletteTriple RGBTRIPLE pPalette,
const size_t  PaletteSize
[static]
 

Generate a packed greyscale palette for a greyscale DIB.

Author:
Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
Date:
29/1/97
Parameters:
PaletteSize number of palette entries that need generating [INPUTS] pPalette pointer to the palette defined in the DIB
Returns:
True if worked ok, False otherwise.
Based on Neville's routine DIBUtil::GenGreyscalePalette WEBSTER - markn 29/1/97

Definition at line 3627 of file dibutil.cpp.

03628 {
03629     ERROR2IF(pPalette == NULL,FALSE,"PNGUtil::GenerateGreyPalette no pPalette present");
03630     ERROR2IF(PaletteSize <= 0,FALSE,"PNGUtil::GenerateGreyPalette no PNG palette entries present");
03631 
03632     // Work out the value we require per step so on a:-
03633     //  256 colour palette we can have 256 steps of 1
03634     //  16 colour palette we have 16 steps of 16 (16 * 16 = 256)
03635     INT32 inc = INT32(256/PaletteSize);
03636     INT32 value = 0;
03637     for (size_t i = 0; i < PaletteSize; i++ )
03638     {
03639         pPalette->rgbtBlue = value;
03640         pPalette->rgbtGreen = value;
03641         pPalette->rgbtRed = value;
03642         pPalette++;
03643         value += inc;
03644         if (value > 255)
03645             value = 255;
03646     }
03647     
03648     return TRUE;
03649 }

BOOL DIBUtil::GenOptimal4bppPalette PLOGPALETTE  pPalette,
const size_t  MaxColours
[static]
 

Definition at line 3525 of file dibutil.cpp.

03526 {
03527 //  ::GenOptimal4bppPalette( pPalette, MaxColours );
03528 
03529     return TRUE;
03530 }

BOOL DIBUtil::GenOptimal4bppPaletteStats_1stPass RGBQUAD pBitmap,
size_t  Size
[static]
 

Definition at line 3511 of file dibutil.cpp.

03512 {
03513 //  ::GenOptimal4bppPaletteStats_1stPass( pBitmap, Size );
03514 
03515     return TRUE;
03516 }

BOOL DIBUtil::GenOptimal4bppPaletteStats_2ndPass RGBQUAD pBitmap,
size_t  Size
[static]
 

Definition at line 3518 of file dibutil.cpp.

03519 {
03520 //  ::GenOptimal4bppPaletteStats_2ndPass( pBitmap, Size );
03521 
03522     return TRUE;
03523 }

BOOL DIBUtil::GenOptimal8bppPalette INT32 *  Stats,
PLOGPALETTE  pPalette,
const size_t  MaxColours
[static]
 

Definition at line 3560 of file dibutil.cpp.

03561 {
03562 //  ::GenOptimal8bppPalette( Stats, pPalette, MaxColours );
03563     ASSERT(FALSE);
03564 
03565     return TRUE;
03566 }

BOOL DIBUtil::GenOptimal8bppPaletteStats INT32 *  Stats,
RGBQUAD pBitmap,
size_t  Size
[static]
 

Definition at line 3552 of file dibutil.cpp.

03553 {
03554 //  ::GenOptimal8bppPaletteStats( Stats,  pBitmap, Size );
03555     ASSERT(FALSE);
03556 
03557     return TRUE;
03558 }

BOOL DIBUtil::GenOptimalPalette void *  Stats,
PLOGPALETTE  pPalette,
const size_t  MaxColours
[static]
 

The purpose of this function is to generate an optimal palette suitable for the bitmaps for which statistics have previously been generated.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/5/96
Parameters:
Stats should have size of GetOptimal8bppPaletteWorkspaceSize() and should [INPUTS] have been initialised by a previous call to Optimal8bppPaletteInitialise and then setup by one or more calls to GenOptimal8bppPaletteStats.
pPalette should point at a logical palette. If the number of entries is greater than MaxColours then the remaining palette entries will be cleared to black.

MaxColours is the maximum number of colours to place into the palette. Note that the remaining colours are cleared to black. Sensible values would be

256 - Full 8bpp palette 255 - Allow room for a transparency colour 252 - Allow room for the four windows colours 251 - Allow room for a transparency colour and the four windows colours.

16 - Full 4bpp palette 15 - Allow room for a transparency colour

2 - 1bpp palette 1 - 1bpp palette with transparency

Note also that if more than 236 colours are added to the 8bpp palette then windows will not be able to correct display the palette on an 8bpp display since it will not be able to realize all the palette entries.

Parameters:
An optimal palette is generated using the Stats provided [OUTPUTS]
Returns:
TRUE if all ok
This function just calls gavins C code in 'winoil.cpp'.

See also:
DIBUtil::GenOptimalPaletteStats

Definition at line 3453 of file dibutil.cpp.

03454 {
03455     ERROR3IF(Stats == NULL, "NULL Stats pointer passed to DIBUtil::GenOptimalPalette");
03456     if (Stats == NULL)
03457         return FALSE;
03458 
03459     ERROR3IF(pPalette == NULL, "NULL Palette pointer passed to DIBUtil::GenOptimalPalette");
03460     if (pPalette == NULL)
03461         return FALSE;
03462 
03463     // the old call
03464     //::GenOptimalPalette( Stats, pPalette, MaxColours );
03465     // used to do this in one go.
03466     // The new call bellow splits this into two functions where the later one can be called
03467     // agian on its own later to reduce the number of colours
03468     //::GenOptimalPalette( Stats );
03469     //::GetOptimalPalette( pPalette, MaxColours );
03470     ASSERT(FALSE);
03471 
03472     return TRUE;
03473 }

BOOL DIBUtil::GenOptimalPaletteStats void *  Stats,
RGBQUAD pBitmap,
size_t  Size
[static]
 

The purpose of this function is to build a table of statistics about one or more bitmaps prior to calling GenOptimalPalette.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/5/96
Parameters:
Stats should have INT32 size of GetOptimalPaletteWorkspaceSize() and should [INPUTS] have been initialised by a previous call to OptimalPaletteInitialise.
pBitmap points to an RGB bitmap of length Size.

Parameters:
Stats table is updated to reflect the colours in the bitmap given [OUTPUTS]
Returns:
TRUE if all ok
One or more bitmaps can be processed a strip at a time by multple calls to this function, or each bitmap may be processed by a single call.

This function just calls gavins C code in 'winoil.cpp'.

See also:
DIBUtil::GenOptimalPalette

Definition at line 3379 of file dibutil.cpp.

03380 {
03381     ERROR3IF(Stats == NULL, "NULL Stats pointer passed to DIBUtil::GenOptimalPaletteStats");
03382     if (Stats == NULL)
03383         return FALSE;
03384 
03385     ERROR3IF(pBitmap == NULL, "NULL Bitmap pointer passed to DIBUtil::GenOptimalPaletteStats");
03386     if (pBitmap == NULL)
03387         return FALSE;
03388 
03389     ERROR3IF(Size == 0, "Bad size passed to DIBUtil::GenOptimalPaletteStats");
03390     if (Size == 0)
03391         return FALSE;
03392 
03393 //  ::GenOptimalPaletteStats( Stats, pBitmap, Size );
03394     ASSERT(FALSE);
03395 
03396     return TRUE;
03397 }

DWORD DIBUtil::GetGavinBlitFormat DWORD  ScreenBPP,
DWORD  BitmapBPP,
BitmapConvertHint  ScreenHint
[static]
 

Determines, from the given inputs, what number should be passed to Gavin routines SetSolidColour and SetUpBitmap (the BPP and BitmapFormat params) in order to get the best possible result (and/or to ensure no dithering occurs). Generally, this is only needed in 16bpp screen modes, but may be called at any time, as it returns safe defaults if not in 16bpp.

Author:
Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/7/95
Parameters:
ScreenBPP - The depth of the screen/bitmap we'll be plotting to [INPUTS] BitmapBPP - The depth of the Gavin bitmap we're plotting to ScreenHint - The conversion hint as returned by DIBUtil::CalcConvertHint
Returns:
An approprite hinting value for use. This will default to 2 (555 hint) if a better hint can't be found.

Definition at line 2166 of file dibutil.cpp.

02167 {
02168     BOOL Transparent = (BitmapBPP == 32);
02169 
02170     if (Transparent)
02171     {
02172         // Otherwise, we use the ConvertHint value to determine a suitable Gavin Format value
02173         switch (ScreenHint)
02174         {
02175             case CONVHINT_FINAL565:
02176                 return(0);
02177 
02178             case CONVHINT_FINAL655:
02179                 return(1);
02180 
02181             case CONVHINT_FINAL555:
02182             case CONVHINT_FINAL16:      // Unknown 16 bit mode - default to 555 hint
02183                 return(2);
02184 
02185             case CONVHINT_FINAL664:
02186                 return(3);
02187 
02188             case CONVHINT_SCREEN4:
02189             case CONVHINT_SCREEN8:
02190             case CONVHINT_FINAL24:
02191             case CONVHINT_NONE:
02192             default:
02193                 // Drop through to the default return value (2)
02194                 break;
02195         }
02196     }
02197 
02198     return(2);
02199 }

size_t DIBUtil::GetOptimal8bppPaletteWorkspaceSize  )  [static]
 

Definition at line 3533 of file dibutil.cpp.

03534 {
03535 //  return ::GetOptimal8bppPaletteWorkspaceSize();
03536     ASSERT(FALSE);
03537     return 0;
03538 }

size_t DIBUtil::GetOptimalPaletteWorkspaceSize  )  [static]
 

Returns size of workspace required by optimal palette routines.

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/5/96
Parameters:
- [INPUTS]
- [OUTPUTS]
Returns:
Size of workspace required
This function just calls gavins C code in 'winoil.cpp'.

See also:
DIBUtil::OptimalPaletteInitialise

Definition at line 3292 of file dibutil.cpp.

03293 {
03294 //  return ::GetOptimalPaletteWorkspaceSize();
03295     ASSERT(FALSE);
03296     return 0;
03297 }

BOOL DIBUtil::Init void   )  [static]
 

Reads our prefs.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/4/95
Parameters:
None [INPUTS]
None [OUTPUTS]
Returns:
TRUE if worked ok else FALSE & error set
See also:
- Scope: Static

Definition at line 2653 of file dibutil.cpp.

02654 {
02655     return
02656         Camelot.DeclareSection( wxT("DisplayKludges"), 10)
02657         && Camelot.DeclarePref(NULL, wxT("RenderDirection4"),  &RenderDirection4, FALSE, TRUE )
02658         && Camelot.DeclarePref(NULL, wxT("RenderDirection8"),  &RenderDirection8, FALSE, TRUE )
02659         && Camelot.DeclarePref(NULL, wxT("RenderDirection16"), &RenderDirection16, FALSE, TRUE )
02660         && Camelot.DeclarePref(NULL, wxT("RenderDirection24"), &RenderDirection24, FALSE, TRUE )
02661         && Camelot.DeclarePref(NULL, wxT("SubbandConversionSize"), &SubbandConversionSize, 0x200, 0x1000000);
02662 }

void DIBUtil::InvertAlpha LPBITMAPINFO  lpBitmapInfo,
LPBYTE  lpBits
[static]
 

Camelot uses a different transparency scheme to the rest of the world, in that 255 is clear, and 0 is opaque. Until the rest of the world catches up, it's necessary to invert the alpha channel to make exported files compatible with other programs.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/6/00 (moved here by Phil 06/02/2004)

Definition at line 4837 of file dibutil.cpp.

04838 {
04839     // Only 32 bpp bitmaps have an alpha channel.
04840     if ( lpBitmapInfo->bmiHeader.biBitCount == 32 )
04841     {
04842         // Cast the pointer into a DWORD.
04843         DWORD *lpRGBA = reinterpret_cast<DWORD*> ( lpBits );
04844 
04845         // If we`re exporting a 32Bit BMP then we need to make sure that we convert the
04846         // Alpha channel to Transparency! i.e. invert it!
04847         for ( UINT32 i = 0; i < lpBitmapInfo->bmiHeader.biSizeImage; i+=4 )
04848         {
04849             // XORing the bitmap's RGBA values with Oxff000000 will invert the alpha channel
04850             // bits.
04851             *lpRGBA ^= 0xff000000;
04852             lpRGBA ++;
04853         }
04854     }
04855 }

BOOL DIBUtil::IsGreyscaleBitmap OILBitmap pOilBmp  )  [static]
 

Determines whether or not a bitmap is 32bpp.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/01/95
Parameters:
pKB the bitmap to operate on [INPUTS]
None [OUTPUTS]
Returns:
TRUE if a 8bit GS bitmap else FALSE

Errors: None Scope: Public

See also:
BfxALU::MakeGreyscale, BFXALU::MakeGreyscale32to8 Note: Transferred from bfxalu 10/11/97 Neville
This routine returns false if the bitmap is not a correctly formed 8 bpp bitmap. It does not return or set errors

Definition at line 4810 of file dibutil.cpp.

04811 {
04812     if ( (!pOilBmp) || (!pOilBmp->IsKindOf(CC_RUNTIME_CLASS(CWxBitmap))) )
04813         return FALSE;
04814 
04815     BITMAPINFOHEADER * pBMI=&(((CWxBitmap *)pOilBmp)->BMInfo->bmiHeader);
04816     if ((pBMI->biBitCount!=8) || (pBMI->biClrUsed!=0x100)) return FALSE;
04817     DWORD * pPal = (DWORD *)(void *)(pBMI +1 /*ptr arith*/);
04818     for (DWORD x=0; x<0x100; x++) if ((pPal[x]&0x00ffffff) != (x|(x<<8)|(x<<16))) return FALSE;
04819     return TRUE;
04820 }

BOOL DIBUtil::IsGreyscaleBitmap KernelBitmap pKB  )  [static]
 

Determines whether or not a bitmap is 32bpp.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
28/01/95
Parameters:
pKB the bitmap to operate on [INPUTS]
None [OUTPUTS]
Returns:
TRUE if a 8bit GS bitmap else FALSE

Errors: None Scope: Public

See also:
BfxALU::MakeGreyscale, BFXALU::MakeGreyscale32to8 Note: Transferred from bfxalu 10/11/97 Neville
This routine returns false if the bitmap is not a correctly formed 8 bpp bitmap. It does not return or set errors

Definition at line 4782 of file dibutil.cpp.

04783 {
04784     if ( (!pKB) || (!pKB->ActualBitmap) )
04785         return FALSE;
04786 
04787     return IsGreyscaleBitmap(pKB->ActualBitmap);
04788 }

void DIBUtil::MakeAlphaIntoGreyscale LPBITMAPINFO  lpBitmapInfo,
LPBYTE  lpBits
[static]
 

Camelot uses a different transparency scheme to the rest of the world, in that 255 is clear, and 0 is opaque. Until the rest of the world catches up, it's necessary to invert the alpha channel to make exported files compatible with other programs.

Author:
Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
Date:
27/6/00 (moved here by Phil 06/02/2004)

Definition at line 4871 of file dibutil.cpp.

04872 {
04873     // Only 32 bpp bitmaps have an alpha channel.
04874     if ( lpBitmapInfo->bmiHeader.biBitCount == 32 )
04875     {
04876         // Cast the pointer into a DWORD.
04877         DWORD *lpRGBA = reinterpret_cast<DWORD*> ( lpBits );
04878 
04879         // If we`re exporting a 32Bit BMP then we need to make sure that we convert the
04880         // Alpha channel to Transparency! i.e. invert it!
04881         for ( UINT32 i = 0; i < lpBitmapInfo->bmiHeader.biSizeImage; i+=4 )
04882         {
04883             // Multiply the alpha value by 0x010101 puts it in each of R, G and B
04884             *lpRGBA = 0x010101 * (*lpRGBA>>24);
04885             lpRGBA ++;
04886         }
04887     }
04888 }

BOOL DIBUtil::MakeBitmapMask LPBITMAPINFO  pPseudoColourInfo,
LPBYTE  pPseudoColourBits,
LPBITMAPINFO  pMonochromeInfo,
LPBYTE  pMonochromeBits,
const BYTE  TransCol
[static]
 

Makes the monochrome bitmap (created with) into a mask for displaying the Pseudocolour bitmap. The mask must be 8bpp instead of the implied of 1bpp as applying it as a transparency requires this.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/4/95
Parameters:
pPseudoColourInfo the info header for the image with transparent colour in [INPUTS] pPseudoColourBits the bits for the image with transparent col in pMonochromeColourInfo the info header for the image to make into the mask pMonochromeColourBits the bits for the image to make into the mask Transparency the oclour to use for transparent
Returns:
True if converted it ok.
See also:
- Scope: Static

Definition at line 2487 of file dibutil.cpp.

02490 {
02491     //const BYTE TransCol = GIF_TRANS_COLOUR;
02492 
02493     ERROR2IF(pPseudoColourInfo==NULL || pPseudoColourBits==NULL, FALSE, "DIBUtil::MakeBitmapMask missing psuedo colour bitmap");
02494     ERROR2IF(pMonochromeInfo==NULL || pMonochromeBits==NULL, FALSE, "DIBUtil::MakeBitmapMask missing monochrome bitmap");
02495     
02496     BITMAPINFOHEADER * pABMI=&(pPseudoColourInfo->bmiHeader);
02497     BITMAPINFOHEADER * pBBMI=&(pMonochromeInfo->bmiHeader);
02498     LPBYTE pABytes=pPseudoColourBits;
02499     LPBYTE pBBytes=pMonochromeBits;
02500 
02501     ERROR2IF(pABMI->biBitCount != 8, FALSE, "DIBUtil::MakeBitmapMask PseudoColour bitmap not 8BPP");
02502     ERROR2IF(pBBMI->biBitCount != 8, FALSE, "DIBUtil::MakeBitmapMask Monochrome not 8BPP");
02503     ERROR2IF((pABMI->biWidth != pBBMI->biWidth) || (pABMI->biHeight != pBBMI->biHeight), FALSE,
02504                 "DIBUtil::MakeBitmapMask needs identically sized bitmaps and that's not what you've given it.");
02505     
02506     LPBYTE A=pABytes;
02507     LPBYTE B=pBBytes;
02508     //
02509     // Gavin: I've not tested the following code change, so if there are problems,
02510     // revert to the old code.
02511     //
02512 #if 1
02513     for (INT32 y = 0; y < pABMI->biHeight; y++)
02514     {
02515         for (INT32 x = 0; x < pABMI->biWidth; x++)
02516             B[x] = -(A[x]==TransCol) ;
02517         A += pABMI->biWidth ;
02518         B += pABMI->biWidth ;
02519         A = (LPBYTE)( (((DWORD_PTR)(A))+3) & ~ 3); // word align
02520         B = (LPBYTE)( (((DWORD_PTR)(B))+3) & ~ 3); // word align
02521     }
02522 #else
02523     memset(B, 0, pBBMI->biSizeImage); // blank the mask
02524     
02525     for (INT32 y = 0; y < pABMI->biHeight; y++)
02526     {
02527         //INT32 bbit = 7;
02528         for (INT32 x = 0; x < pABMI->biWidth; x++)
02529         {
02530             // Change == to != if the mask comes out the wrong way around.
02531             if ((*(A++))==TransCol)
02532                 (*B) = 0xFF;
02533 
02534             // Monochrome mask code
02535             //  (*B)|=1<<bbit;
02536             //if (!(bbit--))
02537             //{
02538             //  B++;
02539             //  bbit=7;
02540             //}
02541             B++;
02542         }
02543         A=(LPBYTE)( (((DWORD)(A))+3) & ~ 3); // word align
02544         B=(LPBYTE)( (((DWORD)(B))+3) & ~ 3); // word align
02545         //B=(LPBYTE)( (((DWORD)(B))+((bbit==7)?3:4)) & ~ 3); // word align
02546     }
02547 #endif
02548     ERROR3IF( (((DWORD_PTR)A-(DWORD_PTR)pABytes)!=pABMI->biSizeImage), "Alex got his other algorithm wrong in one way");
02549     ERROR3IF( (((DWORD_PTR)B-(DWORD_PTR)pBBytes)!=pBBMI->biSizeImage), "Alex got his other algorithm wrong in another way");
02550 
02551     // Bet noone has thought to give the mono bitmap a palette yet
02552     RGBQUAD * Palette= pMonochromeInfo->bmiColors;
02553 //  ERROR2IF((pBBMI->biClrUsed < 2), FALSE, "DIBUtil::MakeBitmapMask not passed a large enough mono palette");
02554 //  Palette[0].rgbRed=Palette[0].rgbBlue=Palette[0].rgbGreen=0;
02555 //  Palette[1].rgbRed=Palette[1].rgbBlue=Palette[1].rgbGreen=255;
02556 
02557     // Must ensure white is white and black is black!
02558     ERROR2IF((pBBMI->biClrUsed < 256), FALSE, "DIBUtil::MakeBitmapMask not passed a large enough mono palette");
02559     Palette[0].rgbRed=Palette[0].rgbBlue=Palette[0].rgbGreen=0;
02560     Palette[255].rgbRed=Palette[255].rgbBlue=Palette[255].rgbGreen=255;
02561 
02562     return TRUE;
02563 }

BOOL DIBUtil::MakeBitmapSmaller UINT32  OldWidth,
UINT32  OldHeight,
UINT32  BaseX,
UINT32  BaseY,
UINT32  NewWidth,
UINT32  NewHeight,
UINT32  BPP,
LPBYTE  pBits
[static]
 

Resizes a bitmap.

Author:
Alex_Bligh (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/4/95
Parameters:
OldWidth,OldHeight = the old height of the bitmap [INPUTS] BaseX, BaseY = the coordinates in the old bitmap that map to (0,0) in the new bitmap NewWidth, NewHeight = the new height of the bitmap BPP = bits per pixel (must be 8, 16 or 32)
pBits altered [OUTPUTS]
Returns:
TRUE if converted it ok else FALSE & error set
See also:
- Scope: Static
This means that the rectangle (BaseX, BaseY) - (BaseX+NewWidth, BaseY+NewHeight) form the o/p bitmap. A ReAlloc can be performed after this call. The rect is inclusive/exclusive.

Definition at line 2588 of file dibutil.cpp.

02590 {
02591     ERROR2IF(!pBits, FALSE, "DIBUtil::MakeBitmapSmaller would really appreciate a bitmap");
02592     ERROR2IF((BPP!=8) && (BPP!=16) && (BPP!=32), FALSE, "DIBUtil::MakeBitmapSmaller passed invalid BPP");
02593     ERROR2IF(OldWidth<NewWidth, FALSE, "DIBUtil::MakeBitmapSmaller thinks you are making the bitmap wider");
02594     ERROR2IF(OldHeight<NewHeight, FALSE, "DIBUtil::MakeBitmapSmaller thinks you are making the bitmap taller");
02595 
02596     ERROR2IF((BaseX>OldWidth) || (BaseY>OldHeight), FALSE, "DIBUtil::MakeBitmapSmaller passed bad Base");
02597     ERROR2IF((BaseX+NewWidth>OldWidth) || (BaseY+NewHeight>OldHeight), FALSE, "DIBUtil::MakeBitmapSmaller passed bad rect");
02598     // as these are unsighned all we have to do is check against zero
02599     ERROR2IF(!OldWidth || !NewWidth || !OldHeight || !NewHeight, FALSE, "DIBUtil::MakeBitmapSmaller passed bad width/height");
02600 
02601     UINT32 OldWidthR=OldWidth;
02602     UINT32 NewWidthR=NewWidth; // with wastage values
02603     UINT32 BPPShift=2;
02604 
02605     switch (BPP)
02606     {
02607         case 8:
02608             OldWidthR=(OldWidth+3)&~3;
02609             NewWidthR=(NewWidth+3)&~3;
02610             BPPShift=0;
02611             break;
02612         case 16:
02613             OldWidthR=(OldWidth+1)&~1;
02614             NewWidthR=(NewWidth+1)&~1;
02615             BPPShift=1;
02616             break;
02617         case 32:
02618         default:
02619             break;
02620     }
02621 
02622 
02623     UINT32 NewByteW = DIBUtil::ScanlineSize(NewWidth, BPP); 
02624     UINT32 OldByteW = DIBUtil::ScanlineSize(OldWidth, BPP); 
02625 
02626     LPBYTE pSrc=pBits+OldByteW*BaseY+(BaseX<<BPPShift);
02627     LPBYTE pDest=pBits;
02628     
02629     for (UINT32 y=0; y<NewHeight; y++)
02630     {
02631         memcpy(pDest, pSrc, NewByteW);
02632         pDest+=NewByteW;
02633         pSrc+=OldByteW; 
02634     }
02635     return TRUE;
02636 }

HPALETTE DIBUtil::MakeIdentityPalette PALETTEENTRY  aRGB[],
INT32  nColors
[static]
 

Definition at line 2009 of file dibutil.cpp.

02010 {
02011     ClearSystemPalette();
02012     return CreateIdentityPalette( aRGB, nColors );
02013 }

BOOL DIBUtil::MakeTransparentBitmap LPBITMAPINFO  pPseudoColourInfo,
LPBYTE  pPseudoColourBits,
LPBITMAPINFO  pMonochromeInfo,
LPBYTE  pMonochromeBits,
const BYTE  TransColour
[static]
 

Applies the monochrome bitmap as a mask to a bitmap, setting pixels in the to the image to the TransColour if the equivelent pixel in the mask is not set.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> (from Alex code)
Date:
22/5/96
Parameters:
pPseudoColourInfo The info header for the image we're applying the mask to. [INPUTS] pPseudoColourBits The bits for the image we want to apply the mask to. pMonochromeInfo The info header for the mask image. pMonochromeBits The bits for the image mask. TransColour The index of the transparent colour.
Returns:
TRUE/FALSE for success/failure.
See also:
- Scope: Static

Definition at line 2227 of file dibutil.cpp.

02232 {
02233     // Get the number of transparent colours used from the bitmap preview dialogue.
02234 PORTNOTE("dialog","Removed BmapPrevDlg usage")
02235 #ifndef EXCLUDE_FROM_XARALX
02236     INT32 NumberOfTransparentColours = BmapPrevDlg::GetNumberOfTransparentColours();
02237 #endif
02238     // Do we want to make the background transparent?
02239     BOOL bHaveBackground = FALSE;
02240 
02241     // If there is a transparent colour, then set the flag to indicate that there's
02242     // a transparent background used.
02243 PORTNOTE("dialog","Removed BmapPrevDlg usage")
02244 #ifndef EXCLUDE_FROM_XARALX
02245     for ( INT32 j=0; j < NumberOfTransparentColours; j++ )
02246     {
02247         if ( BmapPrevDlg::GetTransparentColour ( j ) == TransColour )
02248         {
02249             bHaveBackground = TRUE;
02250             break;
02251         }
02252     }
02253 #endif
02254 
02255     // Parameter checks
02256     ERROR2IF ( pPseudoColourInfo == NULL || pPseudoColourBits == NULL, FALSE,
02257                "DIBUtil::MakeTransparentBitmap missing psuedo colour bitmap" );
02258     ERROR2IF ( pMonochromeInfo   == NULL || pMonochromeBits   == NULL, FALSE,
02259                "DIBUtil::MakeTransparentBitmap missing monochrome bitmap" );
02260     
02261     BITMAPINFOHEADER* pImageBMI = &( pPseudoColourInfo->bmiHeader );
02262     BITMAPINFOHEADER* pMaskBMI  = &( pMonochromeInfo->bmiHeader );
02263 
02264     ERROR2IF ( pMaskBMI->biBitCount != 1, FALSE,
02265                "DIBUtil::MakeTransparentBitmap Monochrome not 1BPP");
02266     ERROR2IF ( ( pImageBMI->biWidth != pMaskBMI->biWidth ) ||
02267                ( pImageBMI->biHeight != pMaskBMI->biHeight ), FALSE,
02268                "DIBUtil::MakeTransparentBitmap hasn't been passed identical bitmaps." );
02269     
02270     BYTE* pImagePixel   = pPseudoColourBits;
02271     BYTE* pMaskPixel    = pMonochromeBits;
02272 
02273     switch (pImageBMI->biBitCount)
02274     {
02275     case 8:
02276         {
02277             // Pixels in the image are one per byte
02278             for (INT32 y = 0; y < pImageBMI->biHeight; y++)
02279             {
02280                 // The monochrome bitmap uses one bit per pixel to store the mask data,
02281                 // and bbit is used to extract the bit representing the current pixel.
02282                 INT32 bbit = 7;
02283 
02284                 for (INT32 x = 0; x < pImageBMI->biWidth; x++)
02285                 {
02286                     // If the mask contains a bit corresponding to the current pixel,
02287                     // the mask is set for this point, so set the current colour to
02288                     // match the transparent colour.
02289                     if( bHaveBackground && ( ( *pMaskPixel ) & ( 1 << bbit ) ) )
02290                     {
02291                         *pImagePixel = TransColour;
02292                     }
02293 
02294                     // Otherwise compare the pixel to the transparent colours. If
02295                     // they're the same then replace the colour's index with the
02296                     // transparency index.
02297                     else
02298                     {
02299 PORTNOTE("dialog","Removed BmapPrevDlg usage")
02300 #ifndef EXCLUDE_FROM_XARALX
02301                         for ( INT32 i=0; i < NumberOfTransparentColours; i++ )
02302                         {
02303                             if ( *pImagePixel == BmapPrevDlg::GetTransparentColour ( i ) )
02304                             {
02305                                 *pImagePixel = TransColour;
02306 
02307                                 // Finished looking for this pixel.
02308                                 break;
02309                             }
02310                         }
02311 #endif
02312                     }
02313 
02314                     // Increment the image pointer.
02315                     pImagePixel++;
02316 
02317                     // Increment the mask pointer.
02318                     if (!(bbit--))
02319                     {
02320                         pMaskPixel++;
02321                         bbit = 7;
02322                     }
02323                 }
02324 
02325                 // Each scanline is word-aligned so adjust the pointers.
02326                 pImagePixel = reinterpret_cast<LPBYTE> ( ( reinterpret_cast<DWORD_PTR>
02327                               ( pImagePixel ) + 3 ) & ~3 );
02328                 pMaskPixel  = reinterpret_cast<LPBYTE> ( ( reinterpret_cast<DWORD_PTR>
02329                               ( pMaskPixel ) + ( ( bbit==7 ) ? 3 : 4 ) ) & ~3 );
02330             }
02331         }
02332 
02333         ERROR3IF ( static_cast<DWORD> ( pImagePixel - pPseudoColourBits )
02334                    != pImageBMI->biSizeImage,
02335                    "Missed image pixels");
02336 
02337         break;
02338 
02339     case 4 :
02340         {
02341             // Pixels in the image are two per byte
02342             ERROR3IF(TransColour > 15, "Trans Colour was out of the 4bpp range");
02343             const BYTE RealTransColour = min( TransColour, BYTE(15) );
02344             const INT32 ScanlineWidth = DIBUtil::ScanlineSize(pImageBMI->biWidth, 4);
02345 
02346             for (INT32 y = 0; y < pImageBMI->biHeight; y++)
02347             {
02348                 INT32 bbit = 7;
02349                 BYTE* ScanLineStart = pImagePixel;
02350                 for (INT32 x = 0; x < pImageBMI->biWidth; x++)
02351                 {
02352                     // pixel is in either lower or upper nibble
02353                     BYTE UpperNibble = (*pImagePixel) >> 4;
02354                     BYTE LowerNibble = (*pImagePixel) & 0xF;
02355 //                  BYTE Pixel = (x%2 == 0) ? UpperNibble : LowerNibble;
02356                     if ((*pMaskPixel) & (1<<bbit))
02357                     {
02358                         if (x%2 == 0)
02359                             *pImagePixel = (RealTransColour << 4) | LowerNibble;
02360                         else
02361                             *pImagePixel = (UpperNibble << 4) | RealTransColour;
02362                     }
02363                     
02364 PORTNOTE("dialog","Removed BmapPrevDlg usage")
02365 #ifndef EXCLUDE_FROM_XARALX
02366                     for( INT32 i=0; i < NumberOfTransparentColours; i++ )
02367                     {
02368                         //  Go through all the transparent colours. If the bitmap is using one
02369                         //  of these colours, then change its value to the transparent colour.
02370                         if( Pixel == BmapPrevDlg::GetTransparentColour( i ) )
02371                         {
02372                             if (x%2 == 0)
02373                                 *pImagePixel = (RealTransColour << 4) | LowerNibble;
02374                             else
02375                                 *pImagePixel = (UpperNibble << 4) | RealTransColour;
02376                             //  Finished looking for this pixel.
02377                             i = NumberOfTransparentColours;
02378                         } 
02379                     }
02380 #endif
02381 
02382                     if (x%2==1)
02383                         pImagePixel++;
02384 
02385                     if (!(bbit--))
02386                     {
02387                         pMaskPixel++;
02388                         bbit = 7;
02389                     }
02390                 }
02391                 // Each scanline is word-aligned so adjust the pointers
02392                 pImagePixel = ScanLineStart+ScanlineWidth;
02393                 pMaskPixel = LPBYTE( ( (DWORD_PTR(pMaskPixel)) + ( ( bbit == 7 ) ? 3 : 4 ) ) & ~ 3 );
02394             }
02395         }
02396 
02397         ERROR3IF ( static_cast<DWORD> ( pImagePixel - pPseudoColourBits )
02398                    != pImageBMI->biSizeImage,
02399                    "Missed image pixels");
02400 
02401         break;
02402 
02403     case 1 :
02404         {
02405             const INT32 MonoScanlineWidth = DIBUtil::ScanlineSize ( pImageBMI->biWidth, 1 );
02406 
02407             // One pixel = one bit so we can apply the mask via bitwise operations
02408             for (INT32 loop = 0; loop < MonoScanlineWidth*pImageBMI->biHeight; loop++)
02409             {
02410                 //  Go through all the transparent colours. If the bitmap is using one
02411                 //  of these colours, then change its value to the transparent colour.
02412                 
02413 PORTNOTE("dialog","Removed BmapPrevDlg usage")
02414 #ifndef EXCLUDE_FROM_XARALX
02415                 if( NumberOfTransparentColours == 2 )
02416                 {
02417                     pPseudoColourBits[loop] = 0;
02418                 }
02419                 else if( NumberOfTransparentColours == 1 )
02420                 {
02421                     if( BmapPrevDlg::m_bIsOrderedDither )
02422                     {
02423                         if( BmapPrevDlg::GetTransparentColour( 0 ) == 1 )
02424                         {
02425                             pPseudoColourBits[loop] = pPseudoColourBits[loop];
02426                         }
02427                         else //  Colour #1 is the transparent one.
02428                         {
02429                             if( pPseudoColourBits[loop] > 0 )
02430                                 pPseudoColourBits[loop] = 255 - pPseudoColourBits[loop];
02431                             else
02432                                 pPseudoColourBits[loop] = 255;
02433                         }
02434                     }
02435                     else
02436                     {
02437                         if( BmapPrevDlg::GetTransparentColour( 0 ) == 0 )
02438                         {
02439                             pPseudoColourBits[loop] = pPseudoColourBits[loop];
02440                         }
02441                         else //  Colour #1 is the transparent one.
02442                         {
02443                             if( pPseudoColourBits[loop] > 0 )
02444                                 pPseudoColourBits[loop] = 255 - pPseudoColourBits[loop];
02445                             else
02446                                 pPseudoColourBits[loop] = 255;
02447                         }
02448                     }
02449                 }
02450 #endif
02451             }
02452         }
02453 
02454         break;
02455 
02456     default:
02457         ERROR2(FALSE, "DIBUtil::MakeTransparentBitmap PseudoColour bitmap not 8/4/1 BPP");
02458     }
02459 
02460     return TRUE;
02461 }

BOOL DIBUtil::Optimal4bppPaletteInitialise_1stPass  )  [static]
 

Definition at line 3497 of file dibutil.cpp.

03498 {
03499 //  ::Optimal4bppPaletteInitialise_1stPass();
03500 
03501     return TRUE;
03502 }

BOOL DIBUtil::Optimal4bppPaletteInitialise_2ndPass  )  [static]
 

Definition at line 3504 of file dibutil.cpp.

03505 {
03506 //  ::Optimal4bppPaletteInitialise_2ndPass();
03507 
03508     return TRUE;
03509 }

BOOL DIBUtil::Optimal8bppPaletteInitialise INT32 *  Stats  )  [static]
 

Definition at line 3540 of file dibutil.cpp.

03541 {
03542     ERROR3IF(Stats == NULL, "NULL pointer passed to DIBUtil::OptimalPaletteInitialise");
03543     if (Stats == NULL)
03544         return FALSE;
03545 
03546 //  ::Optimal8bppPaletteInitialise( Stats );
03547     ASSERT(FALSE);
03548 
03549     return TRUE;
03550 }

BOOL DIBUtil::OptimalPaletteInitialise void *  Stats  )  [static]
 

Initialises workspace required by optimal palette routines. Stats should have INT32 size of GetOptimalPaletteWorkspaceSize().

Author:
Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/5/96
Parameters:
Stats,pointer to stats table to initialise [INPUTS] Use GetOptimalPaletteWorkspaceSize() to create this pointer
Memory pointed to be 'Stats' is initialised [OUTPUTS]
Returns:
TRUE if all ok
This function just calls gavins C code in 'winoil.cpp'.

See also:
DIBUtil::GetOptimalPaletteWorkspaceSize

Definition at line 3323 of file dibutil.cpp.

03324 {
03325     ERROR3IF(Stats == NULL, "NULL pointer passed to DIBUtil::OptimalPaletteInitialise");
03326     if (Stats == NULL)
03327         return FALSE;
03328 
03329 //  ::OptimalPaletteInitialise( Stats );
03330     
03331     ASSERT(FALSE);
03332     return TRUE;
03333 }

BOOL DIBUtil::PlotDeepDIB wxDC *  pDC,
LPBITMAPINFO  lpBitmapInfo,
LPBYTE  lpBits,
INT32  Left,
INT32  Top,
INT32  Width,
INT32  Height,
INT32  SourceLeft,
INT32  SourceTop,
BitmapConvertHint  Hint,
HPALETTE  hPal = NULL
[static]
 

Plot a deep DIB on a device which does not understand deep DIBs. Works by converting to a 24-bit DIB in slices. The DIB must be using the 'standard' RGB arrangements. If this is called on a non-True Colour device then it will take a very very long time, as 24->8 GDI conversions are terribly slow, unless CONVHINT_SCREEN8/4 is used.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
9/6/94
Parameters:
lpBitmapInfo must point to a 16- or 32-bpp DIB. [INPUTS] Using Hint means you can get better dithering hPal only required when CONVHINT_SCREEN8/4
- [OUTPUTS]
Returns:
TRUE if worked, FALSE if failed (due to lack of memory). Error will be set.

Errors: Will ENSURE if not correct depth. Calls SetError on FALSE returns. Scope: Static

Definition at line 626 of file dibutil.cpp.

00627 {
00628     PORTNOTETRACE("other","DIBUtil::PlotDeepDIB - do nothing");
00629 #ifndef EXCLUDE_FROM_XARALX
00630     const WORD BitmapDepth = lpBitmapInfo->bmiHeader.biBitCount;
00631 
00632     ERROR2IF( BitmapDepth!=16 && BitmapDepth!=32, FALSE, "Wrong depth deep bitmap" );   
00633 
00634     INT32 DitherMode = 0;
00635     BOOL UseGavin = FALSE;
00636     UINT32 TempBitmapDepth = 24;
00637 
00638     // We use Gavin for 32->24 (for 16) so we can dither. We use us for 16->24 (cos its simple)
00639     if (BitmapDepth==32)
00640     {
00641         // 32->24 is us because it is easy.
00642         // 32->24 for 16 is Gavin, dither according to the hint
00643         switch (Hint)
00644         {
00645         case CONVHINT_NONE:
00646             // no hint means we do it
00647             break;
00648         case CONVHINT_PRINTER:
00649             // we assume printer is 24-bit, so that's easy
00650             break;
00651         case CONVHINT_FINAL24:
00652             // final output 24-bit means no dithering so we do it - not any more
00653             DitherMode=8;
00654             UseGavin=TRUE;
00655             break;
00656         case CONVHINT_FINAL16:
00657             DitherMode = 2; //0;                            // default to 565 - now 555
00658             UseGavin = TRUE;
00659             break;
00660         case CONVHINT_FINAL555:
00661             DitherMode = 2;
00662             UseGavin = TRUE;
00663             break;
00664         case CONVHINT_FINAL565:
00665             DitherMode = 0;
00666             UseGavin = TRUE;
00667             break;
00668         case CONVHINT_FINAL655:
00669             DitherMode = 1;
00670             UseGavin = TRUE;
00671             break;
00672         case CONVHINT_FINAL664:
00673             DitherMode = 3;
00674             UseGavin = TRUE;
00675             break;
00676         case CONVHINT_SCREEN8:
00677             DitherMode = 1;
00678             UseGavin = TRUE;
00679             TempBitmapDepth = 8;
00680             break;
00681         case CONVHINT_SCREEN4:
00682             DitherMode = 1;
00683             UseGavin = TRUE;
00684             TempBitmapDepth = 4;
00685             break;
00686         default:
00687             ERROR3( "Strange hint in PlotDeepDIB" );
00688             return FALSE;
00689             break;
00690         }
00691     }
00692 
00693     if (BitmapDepth==16)
00694     {
00695         DitherMode=2;
00696         UseGavin=TRUE; // Forsooth! Gavin can do 16 to 24 bit conversions!
00697     }
00698 
00699     // how many bytes to a source scanline? Don't use Width here, get the real bitmap width
00700     const INT32 ScanlineBytes = ScanlineSize( lpBitmapInfo->bmiHeader.biWidth, BitmapDepth );
00701 
00702     BOOL PlotDownwards = RenderDirection8;
00703 
00704     // We use the hint to determine the screen bits per pixel. Not very reliable but more so than
00705     // TempBitmapDepth (for instance).
00706     switch (Hint)
00707     {
00708     case CONVHINT_SCREEN4:
00709         PlotDownwards = RenderDirection4; break;
00710 
00711     case CONVHINT_PRINTER:
00712         PlotDownwards = FALSE; break;   
00713 
00714     case CONVHINT_FINAL24:
00715         PlotDownwards = RenderDirection24; break;
00716                 
00717     case CONVHINT_FINAL16:
00718     case CONVHINT_FINAL555:
00719     case CONVHINT_FINAL565:
00720     case CONVHINT_FINAL655:
00721     case CONVHINT_FINAL664:
00722         PlotDownwards = RenderDirection16; break;
00723 
00724     case CONVHINT_NONE:
00725     case CONVHINT_SCREEN8:
00726     default:
00727         PlotDownwards = RenderDirection8; break;
00728     }
00729 
00730     // allow for SourceLeft by adjusting address. Will always be DWORD aligned for 32-bit
00731     // DIBs, only WORD aligned for 16-bit ones
00732 
00733     // Unfortunately our source has to be DWORD aligned so fix it up
00734     if ( BitmapDepth==16 && UseGavin && (SourceLeft & 1)!=0 )
00735     {
00736         SourceLeft--;
00737         Left--;
00738         Width++; // DWORD align the plot so lpBits on a DWORD boundary
00739     }
00740 
00741     // allow for X
00742     lpBits += SourceLeft << ( BitmapDepth==16 ? 1 : 2 );
00743     // and allow for Y (remember first scanline in memory is bottom most one)
00744     lpBits += (lpBitmapInfo->bmiHeader.biHeight - ((PlotDownwards?0:Height) + SourceTop) ) * ScanlineBytes;
00745     
00746     // Gavins conversion routine can only do whole bitmaps, so the temp bitmap must be as wide
00747     // as the entire source bitmap
00748     INT32 SliceWidth = UseGavin ? lpBitmapInfo->bmiHeader.biWidth : Width;
00749 
00750     // how many bytes to a destination scanline
00751     const INT32 DestlineBytes = ScanlineSize( SliceWidth, TempBitmapDepth );
00752 
00753     // we want a buffer of a limited maximum. Work out how many scanlines that is.
00754     // (set this to 1 for debugging & even slower plotting)
00755     INT32   SliceHeight = SubbandConversionSize / DestlineBytes;
00756     if (SliceHeight<4)
00757         SliceHeight=4;
00758     else
00759         SliceHeight = (SliceHeight+3) & ~3;
00760 
00761     if (SliceHeight>Height) SliceHeight=Height;
00762 
00763     INT32 OurSliceHeight=SliceHeight; // The height of the 
00764     
00765     if (PlotDownwards)
00766     {
00767         // To get dither alignment correct we want the 1st slice to be the 'left over bit' which
00768         // isn't of height SliceHeight
00769         SliceHeight=Height;
00770         while (OurSliceHeight>SliceHeight) 
00771             OurSliceHeight-=Height;
00772     }
00773 
00774     // allocate a temporary 24-bit DIB. IMPORTANT: Due to the way we frig around with the bitmap
00775     // start address, we must allocate an additional scaline of memory to the source, else he will read past
00776     // the end of the bitmap (because that's actually what we're asking of him). AllocDIB handily
00777     // does this for us
00778     LPBYTE Buffer;
00779     LPBITMAPINFO BufferDIB = AllocDIB( SliceWidth, SliceHeight, TempBitmapDepth, &Buffer, NULL );
00780 
00781     ERROR1IF( BufferDIB==NULL, FALSE, _R(IDS_OUT_OF_MEMORY) );
00782 
00783     INT32 ColourFlag = 0;
00784 
00785     if (TempBitmapDepth<24)
00786     {
00787         // only need to do this once
00788         ColourFlag = GRenderRegion::SetPaletteEntries( BufferDIB, pDC );
00789     }
00790 
00791     // Note that the first scanline of a DIB in memory is the bottom, not the top
00792     INT32 DestY = Top + (PlotDownwards?0:Height);
00793     INT32 ThisSlice;
00794 
00795     FNPTR_SCANLINE ConvertFn = NULL;
00796     INT32 RealHeight = lpBitmapInfo->bmiHeader.biHeight;
00797     
00798     if (!UseGavin)
00799     {
00800         // calculate the correct function pointer
00801         ConvertFn = BitmapDepth==16 ? Convert16to24 : Convert32to24;
00802     }
00803 
00804     // now convert in chunks
00805     while (Height)
00806     {
00807         // how tall is this chunk going to be?
00808         ThisSlice = min(OurSliceHeight, Height);
00809         OurSliceHeight=SliceHeight; // now use strips of the correct size
00810 
00811         if (UseGavin)
00812         {
00813             // have to butcher the  bitmap params (source height restored at the end)
00814             lpBitmapInfo->bmiHeader.biHeight = ThisSlice;
00815             BufferDIB->bmiHeader.biHeight = ThisSlice;
00816             
00817             // then get the man to convert it. We assume a 5-6-5 RGB split for the moment - should
00818             // pass in a parameter to control it at some point. See gdraw.wri for list of alternatives
00819             if (PlotDownwards) lpBits -= ThisSlice * ScanlineBytes;
00820 
00821             GRenderRegion::GetStaticDrawContext()->ConvertBitmap( &lpBitmapInfo->bmiHeader, lpBits,
00822                                                         &BufferDIB->bmiHeader, Buffer, DitherMode );
00823 
00824             if (!PlotDownwards) lpBits += ThisSlice * ScanlineBytes;
00825         
00826         }
00827         else
00828         {
00829             // convert that block of scanlines into 24-bit DIB (also 'upside-down')
00830             LPBYTE ConvertedBuffer = Buffer;
00831             if (PlotDownwards) lpBits -= ThisSlice * ScanlineBytes;
00832             for (INT32 i=0; i<ThisSlice; i++)
00833             {
00834                 ConvertFn( Width, lpBits, ConvertedBuffer );
00835                 lpBits += ScanlineBytes;
00836                 ConvertedBuffer += DestlineBytes;
00837             }
00838             if (PlotDownwards) lpBits -= ThisSlice * ScanlineBytes;
00839         }
00840 
00841         // now plot our baby-DIB
00842 
00843         if (!PlotDownwards) DestY -= ThisSlice;
00844 
00845         if( Hint == CONVHINT_PRINTER )
00846         { 
00847             // printers have to do it this way else they don't half-tone correctly
00848             StretchDIBits( hDC, Left, DestY,                            // Dest top left
00849                             Width, ThisSlice,                       // Dest width/height
00850                             0,0,                                    // Source xy
00851                             Width, ThisSlice,                       // Soruce w/h
00852                             Buffer, BufferDIB,
00853                             DIB_RGB_COLORS,
00854                             SRCCOPY );
00855         }
00856         else if (TempBitmapDepth<24)
00857         {
00858             // output 4/8-bit to screen using most efficient mechanism possible
00859             GRenderRegion::PlotBitmap( hDC, ColourFlag, BufferDIB, Buffer, Left, DestY,
00860                                         Width, ThisSlice, hPal, 0,0 );
00861         }
00862         else
00863         {
00864             INT32 num = SetDIBitsToDevice( hDC, Left, DestY,                            // dest top left
00865                                 Width, ThisSlice,                       // dest w & h
00866                                 0,0,                                    // source
00867                                 0,ThisSlice,                            // scanlines (all)
00868                                 Buffer, BufferDIB,                      // the temp 24-bit DIB
00869                                 DIB_RGB_COLORS );
00870 //GdiFlush();
00871         }
00872 
00873         if (PlotDownwards) DestY += ThisSlice;
00874         Height -= ThisSlice;
00875     }
00876 
00877     if (UseGavin)
00878         lpBitmapInfo->bmiHeader.biHeight = RealHeight;
00879 
00880     FreeDIB( BufferDIB, Buffer );
00881 #endif
00882     return TRUE;
00883 }

BOOL DIBUtil::ReadFromFile CCLexFile File,
LPBITMAPINFO Info,
LPBYTE Bits,
BOOL  ReadHeader = TRUE,
String_64 ProgressString = NULL,
BaseCamelotFilter pFilter = NULL
[static]
 

Read a .bmp file into memory. ONLY READS 8- & 24- & 32-bit BMPs currently***. Errors on 16-bit builds*** A progress hourglass can be shown if required.

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

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

See also:
AccusoftFilters::ReadFromFile;

Definition at line 1144 of file dibutil.cpp.

01146 {
01147     ERROR2IF(File == NULL,FALSE,"DIBUtil::ReadFromFile null File pointer");
01148     ERROR2IF(Info == NULL,FALSE,"DIBUtil::ReadFromFile null Info pointer");
01149     ERROR2IF(Bits == NULL,FALSE,"DIBUtil::ReadFromFile null Bits pointer");
01150 
01151     BITMAPINFOHEADER InfoHeader;
01152     UINT32 Depth;
01153     DWORD BitsSize=0;
01154     INT32 SizeOfHeader = 0;
01155 
01156     *Info = NULL;                                       // in case of early exit
01157     *Bits = NULL;
01158 
01159     // Must set the exception throwing flag to True and force reporting of errors to False.
01160     // This means that the caller must report an error if the function returns False.
01161     // Any calls to CCFile::GotError will now throw a file exception and should fall into
01162     // the catch handler at the end of the function.
01163     // Replaces the goto's that handled this before.
01164     BOOL OldThrowingState = File->SetThrowExceptions( TRUE );
01165     BOOL OldReportingState = File->SetReportErrors( FALSE );
01166 
01167     // If the caller has specified a string then assume they require a progress bar
01168     // Start it up.
01169     if (ProgressString != NULL)
01170     {
01171         BeginSlowJob(100, FALSE, ProgressString);
01172     }
01173 
01174     try
01175     {
01176         if (ReadHeader)
01177         {
01178             BITMAPFILEHEADER Header;
01179 
01180             File->read( &Header, sizeof(Header) );
01181             Header.bfType = LEtoNative(Header.bfType);
01182             Header.bfSize = LEtoNative(UINT32(Header.bfSize));
01183             Header.bfReserved1 = LEtoNative(Header.bfReserved1);
01184             Header.bfReserved2 = LEtoNative(Header.bfReserved2);
01185             Header.bfOffBits = LEtoNative(UINT32(Header.bfOffBits));
01186             
01187             if (File->bad())
01188                 File->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01189 
01190             if (Header.bfType != 0x4D42)                        // "BM" in little-endian format
01191                 File->GotError( _R(IDE_BADFORMAT) );
01192         }
01193 
01194         // some BMPs (eg 256color.bmp) don't have one of these, they have the old OS2 sort
01195         size_t SizeOfRGB=0;
01196 
01197         File->read( &SizeOfHeader, sizeof(INT32) );
01198         SizeOfHeader = LEtoNative(SizeOfHeader);
01199         if ( SizeOfHeader==sizeof(InfoHeader) )
01200         {
01201             // sensible BMP with normal BITMAPINFOHEADER structure
01202             SizeOfRGB = sizeof(RGBQUAD);
01203             File->read( &InfoHeader.biWidth, sizeof(InfoHeader)-sizeof(INT32) );
01204 
01205             InfoHeader.biWidth          = LEtoNative(InfoHeader.biWidth);
01206             InfoHeader.biHeight         = LEtoNative(InfoHeader.biHeight);
01207             InfoHeader.biPlanes         = LEtoNative(InfoHeader.biPlanes);
01208             InfoHeader.biBitCount       = LEtoNative(InfoHeader.biBitCount);
01209             InfoHeader.biCompression    = LEtoNative(UINT32(InfoHeader.biCompression));
01210             InfoHeader.biSizeImage      = LEtoNative(UINT32(InfoHeader.biSizeImage));
01211             InfoHeader.biXPelsPerMeter  = LEtoNative(InfoHeader.biXPelsPerMeter);
01212             InfoHeader.biYPelsPerMeter  = LEtoNative(InfoHeader.biYPelsPerMeter);
01213             InfoHeader.biClrUsed        = LEtoNative(UINT32(InfoHeader.biClrUsed));
01214             InfoHeader.biClrImportant   = LEtoNative(UINT32(InfoHeader.biClrImportant));
01215         }
01216         else if ( SizeOfHeader==sizeof(BITMAPCOREHEADER) )
01217         {
01218             // silly OS2 thing - read in and convert
01219             BITMAPCOREHEADER TempHeader;
01220             File->read( &TempHeader.bcWidth, sizeof(TempHeader)-sizeof(INT32) );
01221 
01222             TempHeader.bcWidth          = LEtoNative(TempHeader.bcWidth);
01223             TempHeader.bcHeight         = LEtoNative(TempHeader.bcHeight);
01224             TempHeader.bcPlanes         = LEtoNative(TempHeader.bcPlanes);
01225             TempHeader.bcBitCount       = LEtoNative(TempHeader.bcBitCount);
01226 
01227             SizeOfRGB = sizeof(RGBTRIPLE);
01228             InfoHeader.biWidth =    TempHeader.bcWidth;
01229             InfoHeader.biHeight =   TempHeader.bcHeight;
01230             InfoHeader.biPlanes =   TempHeader.bcPlanes;
01231             InfoHeader.biBitCount = TempHeader.bcBitCount;
01232             InfoHeader.biCompression = BI_RGB;
01233             InfoHeader.biSizeImage = 0L;
01234             InfoHeader.biXPelsPerMeter = 0L;
01235             InfoHeader.biYPelsPerMeter = 0L;
01236             InfoHeader.biClrImportant = 0;
01237             if (InfoHeader.biBitCount < 24 )
01238                 InfoHeader.biClrUsed = 1<<InfoHeader.biBitCount;
01239             else
01240                 InfoHeader.biClrUsed = 0;
01241         }
01242         else
01243             File->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01244 
01245 
01246         if (File->bad())
01247             File->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01248 
01249         if (InfoHeader.biWidth == 0 || InfoHeader.biHeight == 0 )
01250             File->GotError( _R(IDE_BADFORMAT) );
01251 
01252         if (InfoHeader.biPlanes != 1)
01253             File->GotError( _R(IDE_BADFORMAT) );
01254 
01255         Depth = InfoHeader.biBitCount;
01256 
01257         BOOL Convert16to24 = FALSE;
01258         if (InfoHeader.biBitCount == 16 && InfoHeader.biCompression == BI_BITFIELDS)
01259         {
01260             // we will create a 24bpp bitmap and then convert the data on entry in 24bpp
01261             Depth = 24;
01262             Convert16to24 = TRUE;
01263         }
01264         
01265         // temp kludge code for now - only copes with certain depth bitmaps
01266         if ( (Depth != 1) && (Depth != 4) && (Depth != 8) && (Depth != 24) && (Depth != 32))
01267             File->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01268 
01269         // we know what sort of bitmap we are - lets allocate a new LPBITMAPINFO and some bytes
01270         *Info = AllocDIB( InfoHeader.biWidth, InfoHeader.biHeight, Depth,
01271                             Bits, NULL );
01272 
01273         if (*Info == NULL)
01274             File->GotError( _R(IDS_OUT_OF_MEMORY) );
01275 
01276         // Copy interesting info from the file to the memory DIB
01277 
01278         
01279         // If PelsPerMeter is a dodgy value such as 39 (= very large pixels!)
01280         // then use 0 which means that we will display it at screen resolution.
01281 TRACEUSER( "Neville", _T("DIBUtil::ReadFromFile XPelsPerMeter=%d\n"),InfoHeader.biXPelsPerMeter);
01282 TRACEUSER( "Neville", _T("DIBUtil::ReadFromFile YPelsPerMeter=%d\n"),InfoHeader.biYPelsPerMeter);
01283         if (InfoHeader.biXPelsPerMeter > BaseBitmapFilter::MinPelsPerMeter)
01284         {
01285             (*Info)->bmiHeader.biXPelsPerMeter = InfoHeader.biXPelsPerMeter;
01286             (*Info)->bmiHeader.biYPelsPerMeter = InfoHeader.biYPelsPerMeter;
01287         }
01288         else
01289         {
01290             (*Info)->bmiHeader.biXPelsPerMeter = 0;
01291             (*Info)->bmiHeader.biYPelsPerMeter = 0;
01292         }
01293 
01294         // If the ClrUsed field is zero, put a sensible value in it
01295         // The read in value of ClrUsed also determines the number of palette entries in
01296         // the palette table.
01297         UINT32 PalColours = 0;
01298         if (Depth <= 8)
01299         {
01300             PalColours = InfoHeader.biClrUsed;
01301             // If zero then assume maximum amount of colours
01302             // otherwise, copy the value across into the new header.
01303             if (InfoHeader.biClrUsed == 0)
01304             {
01305                 (*Info)->bmiHeader.biClrUsed = 1<<Depth;
01306                 PalColours = 1<<Depth;
01307             }
01308             else
01309                 (*Info)->bmiHeader.biClrUsed = InfoHeader.biClrUsed;
01310         }
01311 
01312         // read any palette info
01313         switch (Depth)
01314         {
01315             case 1:
01316             case 4:
01317             case 8:
01318                 // read colour palette (Changed by Neville 14/10/97 to read biClrUsed)
01319                 ReadPalette( File, PalColours, SizeOfRGB, (*Info)->bmiColors);
01320                 break;
01321 
01322             case 24:
01323             case 32:
01324                 // 24-bit files sometimes have a 'hint' palette (e.g country.bmp) which
01325                 // we have to throw away (we can't load it cos the bitmap has no space alloced
01326                 // for a colour table)
01327                 if (InfoHeader.biClrUsed)
01328                     File->seekIn( InfoHeader.biClrUsed * SizeOfRGB, ios::cur );
01329                 break;
01330 
01331             default:
01332                 File->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01333         }
01334 
01335         if (File->bad())
01336             File->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01337 
01338         // now read the bitmap data
01339 
01340         UINT32 RedColourMask    = 0;
01341         UINT32 GreenColourMask  = 0;
01342         UINT32 BlueColourMask   = 0;
01343         switch (InfoHeader.biCompression)
01344         {
01345             case BI_RGB:
01346                 BitsSize = (*Info)->bmiHeader.biSizeImage;          // uncompressed
01347                 break;
01348 
01349             case CC_BMPTYPE:
01350                 if (Depth != 32)
01351                     File->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01352                 BitsSize = (*Info)->bmiHeader.biSizeImage;          // uncompressed
01353                 break;
01354 
01355             case BI_RLE8:
01356                 if (!UnpackRle8( File, InfoHeader, *Bits ))
01357                     File->GotError( _R(IDE_BADFORMAT) );
01358                 BitsSize = 0L;                                      // no more to read
01359                 break;
01360 
01361             case BI_BITFIELDS:
01362                 // Read in the three special colour dword masks that follow the header
01363                 BitsSize = (*Info)->bmiHeader.biSizeImage;          // uncompressed
01364                 File->read( &RedColourMask,     sizeof(RedColourMask) );
01365                 File->read( &GreenColourMask,   sizeof(GreenColourMask) );
01366                 File->read( &BlueColourMask,    sizeof(BlueColourMask) );
01367 
01368                 RedColourMask           = LEtoNative(RedColourMask);
01369                 GreenColourMask         = LEtoNative(GreenColourMask);
01370                 BlueColourMask          = LEtoNative(BlueColourMask);
01371 
01372                 if (File->bad())
01373                     File->GotError( _R(IDE_BADFORMAT) );
01374                 TRACEUSER( "Neville", _T("DIBUtil::ReadFromFile BI_BITFIELDS RedColourMask = %d\n"),RedColourMask);
01375                 TRACEUSER( "Neville", _T("DIBUtil::ReadFromFile BI_BITFIELDS GreenColourMask = %d\n"),GreenColourMask);
01376                 TRACEUSER( "Neville", _T("DIBUtil::ReadFromFile BI_BITFIELDS BlueColourMask = %d\n"),BlueColourMask);
01377                 // The 32bpp case is easy. With 16bpp we need to convert to 24bpp
01378                 // We will take the Windows 95 in 32bpp mode such that it expects
01379                 // The blue mask is 0x000000FF, the green mask is 0x0000FF00, and the red mask is 0x00FF0000.
01380                 if (Depth == 32 && RedColourMask != 0xFF0000 && GreenColourMask != 0xFF00 && BlueColourMask != 0xFF)
01381                     File->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01382                 else if (Depth != 24 && Depth != 32)
01383                     File->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01384                 break;
01385 
01386             default:
01387                 File->GotError( _R(IDE_FORMATNOTSUPPORTED) );           // other compression not supported
01388         }
01389 
01390         if (Convert16to24 == TRUE && Depth == 24)
01391         {
01392             // We need to read in a WORD and use the bitfield to convert this into 24 bit RGB data
01393             // and then put this in the 24bpp pixel
01394             // We take the Windows 95 route in that when the biCompression member is BI_BITFIELDS,
01395             // we only support the following 16bpp color masks:
01396             // A 5-5-5 16-bit image, where
01397             //  the blue mask is 0x001F, the green mask is 0x03E0, and the red mask is 0x7C00;
01398             // and a 5-6-5 16-bit image, where
01399             // the blue mask is 0x001F, the green mask is 0x07E0, and the red mask is 0xF800.
01400             WORD Pixel = 0;
01401             INT32 Bshift = 0; // Always 0
01402             if (BlueColourMask != 0x1F) // Covers both 15bpp and 16bpp
01403                 File->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01404 
01405             INT32 Gshift = 0;
01406             if (GreenColourMask == 0x7e0 || GreenColourMask == 0x3e0)
01407                 Gshift = 5;
01408             else
01409                 File->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01410 
01411             INT32 Rshift = 0;
01412             if (RedColourMask == 0x7c00)
01413                 Rshift = 10;
01414             else if (RedColourMask == 0xf800)
01415                 Rshift = 11;
01416             else
01417                 File->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01418 
01419             UINT32 ScanLineWidth = DIBUtil::ScanlineSize(InfoHeader.biWidth, Depth);
01420             LPBYTE pBits = *Bits;
01421             INT32 Height = InfoHeader.biHeight;
01422             INT32 Width = InfoHeader.biWidth;
01423             for (INT32 y = 0; y < Height; y++ )
01424             {
01425                 for (INT32 x = 0; x < Width; x++ )
01426                 {
01427                     // read in the pixel
01428                     File->read( &Pixel, sizeof(Pixel) );
01429                     
01430                     Pixel = LEtoNative(Pixel);
01431                     
01432                     if (File->bad())
01433                         File->GotError( _R(IDE_BADFORMAT) );
01434                     // Convert it into the B G and R components
01435                     UINT32 B = ((Pixel & BlueColourMask) >> Bshift);    // blue component
01436                     UINT32 G = ((Pixel & GreenColourMask) >> Gshift);   // green component
01437                     UINT32 R = ((Pixel & RedColourMask) >> Rshift); // red component;
01438                     // Need to shift the components into the MSBs leaving gap at bottom
01439                     // then fill in the missing LSBs with the required number of MSBs
01440                     pBits[x * 3 + 0] = (B << 3) | (B >> 2);
01441                     if (GreenColourMask == 0x7e0) // 6 bit green
01442                         pBits[x * 3 + 1] = (G << 2) | (G >> 4);
01443                     else
01444                         pBits[x * 3 + 1] = (G << 3) | (G >> 2);
01445                     pBits[x * 3 + 2] = (R << 3) | (R >> 2);
01446                 }
01447                 
01448                 // Move onto the next line
01449                 pBits += ScanLineWidth;
01450                 // Updating the progress bar as we go
01451                 ContinueSlowJob((INT32)((100 * y)/Height));
01452             }
01453         }
01454         // Read the actual bytes, used to do it in one go but we really require some
01455         // progress bar indication so we will do it in chunks.
01456         else if (BitsSize > 0)
01457         {
01458             // If pFilter is NULL and hence not native/web loading then do it in 
01459             // chunks of bytes
01460             if (pFilter == NULL)
01461             {
01462                 if (BitsSize < 1024 || ProgressString == NULL)
01463                 {
01464                     // File very small or no progress bar required, so load in one go
01465                     File->read( *Bits, BitsSize );
01466                 }
01467                 else
01468                 {
01469                     // Load in chunks, for present split into 100 chunks
01470                     DWORD ChunkSize = BitsSize/100;
01471                     DWORD Position = 0;
01472                     LPBYTE pBitInfo = *Bits;
01473                     
01474                     while (Position < BitsSize)
01475                     {
01476                         if ( (BitsSize - Position) > ChunkSize)
01477                             File->read( pBitInfo, ChunkSize );
01478                         else
01479                         {
01480                             ChunkSize = BitsSize - Position;
01481                             File->read( pBitInfo, ChunkSize );
01482                         }
01483                                 
01484                         // Increment our counters/pointers
01485                         Position += ChunkSize;
01486                         pBitInfo += ChunkSize;
01487                         ContinueSlowJob((INT32)(100*Position/BitsSize));
01488                     }
01489                 }
01490             }
01491             else
01492             {
01493                 // Do the reading a scanline at a time
01494                 // This makes progress bar update easier for native/web files
01495                 LPBYTE pBitInfo = *Bits;
01496                 UINT32 ScanLineWidth = DIBUtil::ScanlineSize(InfoHeader.biWidth, Depth);
01497                 UINT32 height = InfoHeader.biHeight; 
01498                 // Ask the filter what the record size for this bitmap is and hence
01499                 // what the allocation we have for progress bar updates are.
01500                 // We will then have to update our progress bar by
01501                 //  current scanline/total number of scanlines * allocation
01502                 // so that we get update by a proportion of the value.
01503                 // We can assume no interlacing as in native/web files this is turned off.
01504                 UINT32 RecordSize = pFilter->GetCurrentRecordSize();
01505                 if (RecordSize == 0)
01506                     RecordSize = 1;
01507                 INT32 UpdateValue = RecordSize/height;
01508                 // For each scaline in the file, read it in and update the progress bar count
01509                 for (UINT32 i = 0; i < height; i++)
01510                 {
01511                     File->read( pBitInfo, ScanLineWidth );
01512                     pBitInfo += ScanLineWidth;
01513                     pFilter->IncProgressBarCount(UpdateValue);
01514                 }
01515             }
01516         }
01517         
01518         // This shouldn't be required any more as the CATCH handler should be invoked
01519         // when problems happen.
01520         if (File->bad())
01521             File->GotError( _R(IDE_FORMATNOTSUPPORTED) );
01522 
01523         if (FAKE_32_TRANS && (Depth==32) && (InfoHeader.biCompression!=CC_BMPTYPE) )
01524         {
01525             // put some fake transparency in on a scanline by scanline basis
01526             LPRGBQUAD Data = (LPRGBQUAD)(*Bits);
01527 //          size_t size = BitsSize;
01528             UINT32 Height = (*Info)->bmiHeader.biHeight;
01529             UINT32 h = Height;
01530             Height /= 2;
01531 
01532             while (h--)
01533             {
01534                 INT32 TValue = (INT32)h - (INT32)Height;
01535                 TValue = abs(TValue);
01536                 TValue = TValue * 0xFF / Height;
01537 
01538                 UINT32 w = (*Info)->bmiHeader.biWidth;
01539                 while (w--)
01540                 {
01541                     Data->rgbReserved = (BYTE)TValue;
01542                     Data++;
01543                 }
01544                 // 32-bit DIBs automatically DWORD aligned
01545             }
01546         }
01547 
01548         // If started, then stop then progress bar
01549         if (ProgressString != NULL)
01550         {
01551             EndSlowJob();
01552         }
01553 
01554         // Must set the exception throwing and reporting flags back to their entry states
01555         File->SetThrowExceptions( OldThrowingState );
01556         File->SetReportErrors( OldReportingState );
01557 
01558         // er, we seem to have finished OK so say so
01559         return TRUE;
01560     }
01561     catch( CFileException )
01562     {
01563         // catch our form of a file exception
01564         TRACE( _T("DIBUtil::ReadFromFile CC catch handler\n"));
01565 
01566         FreeDIB( *Info, *Bits );                            // free any alloced memory
01567         *Info = NULL;                                       // and NULL the pointers
01568         *Bits = NULL;
01569 
01570         // If started, then stop then progress bar
01571         if (ProgressString != NULL)
01572         {
01573             EndSlowJob();
01574         }
01575 
01576         // Must set the exception throwing and reporting flags back to their entry states
01577         File->SetThrowExceptions( OldThrowingState );
01578         File->SetReportErrors( OldReportingState );
01579 
01580         return FALSE;
01581     }
01582 
01583     ERROR2( FALSE, "Escaped exception clause somehow" );
01584 }

UINT32 DIBUtil::ScanlineBytes UINT32  Width,
UINT32  Depth
[static]
 

Used in calculating offsets along scanlines. NOTE! Differs from ScanlineSize in that it DOES NOT word align the result!!!

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/3/94
Parameters:
Width in pixels of DIB, Depth of bitmap (1,4,8,16,24,32) [INPUTS]
- [OUTPUTS]
Returns:
Size on bytes of a scanline in that format

Errors: If passed an invalid depth, will ensure and return 0. Scope: Static

Definition at line 464 of file dibutil.cpp.

00465 {
00466     switch (Depth)
00467     {
00468         case 1:
00469             return Width >> 3;
00470         case 2:
00471             return Width >> 2;
00472         case 4:
00473             return Width >> 1;
00474         case 8:
00475             return Width;
00476         case 16:
00477             return Width << 1;
00478         case 24:
00479             ENSURE(FALSE, "Aren't 24-bit bitmaps stored in 32BPP???");
00480             return Width * 3;
00481         case 32:
00482             return Width << 2;
00483         default:
00484             ENSURE(FALSE, "Unknown bitmap depth");
00485             return 0L;
00486     }
00487 }

UINT32 DIBUtil::ScanlineSize UINT32  Width,
UINT32  Depth
[static]
 

Used in calculating bitmap memory requirements. Based on Gavin's code in GDraw_SetDIBitmap, which it had better agree with!

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
4/3/94
Parameters:
Width in pixels of DIB, Depth of bitmap (1,4,8,16,24,32) [INPUTS]
- [OUTPUTS]
Returns:
Size on bytes of a scanline in that format

Errors: If passed an invalid depth, will ensure and return 0. Scope: Static

Definition at line 421 of file dibutil.cpp.

00422 {
00423     switch (Depth)
00424     {
00425         case 1:
00426             return ((Width+31)&~31)>>3;
00427         case 2:
00428             // although Gavin doesn't support 2-bit DIBs, this function does.
00429             return ((Width+15)&~15)>>2;
00430         case 4:
00431             return ((Width+7)&~7)>>1;
00432         case 8:
00433             return ((Width+3)&~3);
00434         case 16:
00435             return ((Width+1)&~1)<<1;
00436         case 24:
00437             // although Gavin doesn't support 24-bit DIBs, this function does.
00438             return ((Width*3)+3)&~3;
00439         case 32:
00440             return Width<<2;
00441         default:
00442             ENSURE(FALSE, "Unknown bitmap depth");
00443             return 0L;
00444     }
00445 }

BOOL DIBUtil::WriteToFile CCLexFile pFile,
LPBYTE  pBits,
UINT32  Width,
UINT32  Height,
UINT32  Depth,
String_64 pProgressString = NULL
[static]
 

Generates a BITMAPINFO structor and then saves out the DIB.

Author:
Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com>
Date:
6/4/96
Parameters:
File An opened CCFile that can be written to. It should be positioned at the [INPUTS] start. Caller is responsible for closing it. The file needs to be in Binary mode. Bits The bitmap data itself ProgressString allows the user to specify whether they require a progress hourglass or not. If NULL then none is shown, otherwise an progress bar is shown using the text supplied. Defaults to NULL i.e. no progress bar. Width The width of the bitmap data in pixels Height The height of the bitmap data in pixels Depth The depth of the bitmap (Only 1 is supported at the mo)
- [OUTPUTS]
Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)

Definition at line 1803 of file dibutil.cpp.

01804 {
01805     ERROR3IF(Depth!=1, "Only 1bpp DIBs supported");
01806     ERROR3IF(Width==0, "Zero width");
01807     ERROR3IF(Height==0, "Zero height");
01808     
01809     // Create a new info
01810     const INT32 NumColours = 1 << Depth;
01811     BITMAPINFO* pBmpInfo = (BITMAPINFO*) CCMalloc (sizeof(BITMAPINFO) + sizeof(RGBQUAD)*NumColours);
01812     if (pBmpInfo == NULL)
01813         return FALSE;
01814 
01815     // Fill in the bitmap info
01816     pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
01817     pBmpInfo->bmiHeader.biWidth = Width;
01818     pBmpInfo->bmiHeader.biHeight = Height;
01819     pBmpInfo->bmiHeader.biPlanes = 1;
01820     pBmpInfo->bmiHeader.biBitCount = Depth;
01821     pBmpInfo->bmiHeader.biCompression = BI_RGB;
01822     pBmpInfo->bmiHeader.biXPelsPerMeter = 0;
01823     pBmpInfo->bmiHeader.biYPelsPerMeter = 0;
01824     pBmpInfo->bmiHeader.biClrImportant = 0;
01825 
01826     // It is these fields at are dependant on the 1bpp ness
01827     pBmpInfo->bmiHeader.biClrUsed = 2;
01828     pBmpInfo->bmiHeader.biSizeImage = Height*(((Width+31)/32)*4);   // Scanlines are word-aligned
01829 
01830     // Generate a black and white palette
01831     pBmpInfo->bmiColors[0].rgbRed = 0x00;   
01832     pBmpInfo->bmiColors[0].rgbGreen = 0x00; 
01833     pBmpInfo->bmiColors[0].rgbBlue = 0x00;  
01834     pBmpInfo->bmiColors[0].rgbReserved = 0;
01835     pBmpInfo->bmiColors[1].rgbRed = 0xff;   
01836     pBmpInfo->bmiColors[1].rgbGreen = 0xff; 
01837     pBmpInfo->bmiColors[1].rgbBlue = 0xff;  
01838     pBmpInfo->bmiColors[1].rgbReserved = 0;
01839 
01840     // Call saving code
01841     BOOL result = DIBUtil::WriteToFile ( pFile, pBmpInfo, pBits, pProgressString );
01842 
01843     CCFree(pBmpInfo);
01844         
01845     return result;
01846 }

BOOL DIBUtil::WriteToFile CCLexFile File,
LPBITMAPINFO  Info,
LPBYTE  Bits,
String_64 ProgressString = NULL,
BOOL  WriteHeader = TRUE,
BaseCamelotFilter pFilter = NULL
[static]
 

Write a bitmap in memory straight out to file with now rendering or conversion. Errors on 16-bit builds*** A progress hourglass can be shown if required. This function is used by the save bitmap button on the bitmap gallery. All other bitmap export uses the OutputDIB class instead as this copes with using a render region and converting from 32 to the destination format. (caller should close file).

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
26/4/95
Parameters:
File An opened CCFile that can be written to. It should be positioned at the [INPUTS] start. Caller is responsible for closing it. The file needs to be in Binary mode. Info BITMAPINFO structure for the dib. Bits The bitmap data itself ProgressString allows the user to specify whether they require a progress hourglass or not. If NULL then none is shown, otherwise an progress bar is shown using the text supplied. Defaults to NULL i.e. no progress bar. WriteHeader TRUE then write a BITMAPFILEHEADER to file FALSE skip writing the BITMAPFILEHEADER to file. Defaults to TRUE. BaseCamelotFilter 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.
- [OUTPUTS]
Returns:
TRUE if worked, FALSE if failed (error will be set accordingly but not reported)

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

See also:
AccusoftFilters::WriteToFile; DIBUtil::ReadFromFile;

Definition at line 1621 of file dibutil.cpp.

01622 {
01623 #ifndef WIN32
01624     Error::SetError( _R(IDE_BADFORMAT) );
01625     return FALSE;
01626 #else
01627     ERROR2IF(File==NULL,FALSE,"DIBUtil::WriteToFile File pointer is null");
01628     ERROR2IF(Info==NULL,FALSE,"DIBUtil::WriteToFile BitmapInfo pointer is null");
01629     ERROR2IF(Bits==NULL,FALSE,"DIBUtil::WriteToFile Bits pointer is null");
01630 
01631     // Must set the exception throwing flag to True and force reporting of errors to False.
01632     // This means that the caller must report an error if the function returns False.
01633     // Any calls to CCFile::GotError will now throw a file exception and should fall into
01634     // the catch handler at the end of the function.
01635     // Replaces the goto's that handled this before.
01636     BOOL OldThrowingState = File->SetThrowExceptions( TRUE );
01637     BOOL OldReportingState = File->SetReportErrors( FALSE );
01638 
01639     // If the caller has specified a string then assume they require a progress bar
01640     // Start it up.
01641     if (ProgressString != NULL)
01642     {
01643         BeginSlowJob(100, FALSE, ProgressString);
01644     }
01645 
01646     try
01647     {
01648         // BITMAPINFO  consists of:-
01649         //      BITMAPINFOHEADER    bmiHeader;
01650         //      RGBQUAD             bmiColors[1];
01651         LPBITMAPINFOHEADER pInfoHeader = &Info->bmiHeader;
01652         ERROR2IF(pInfoHeader==NULL,FALSE,"DIBUtil::WriteToFile BitmapInfoHeader pointer is null");
01653         
01654         // Work out the palette size 
01655         INT32 PalSize = Info->bmiHeader.biClrUsed;      // How many entries in palette
01656 TRACEUSER( "Neville", _T("DIBUtil::WriteToFile PalSize = %d\n"),PalSize);
01657 TRACEUSER( "Neville", _T("DIBUtil::WriteToFile XPelsPerMeter=%d\n"),pInfoHeader->biXPelsPerMeter);
01658 TRACEUSER( "Neville", _T("DIBUtil::WriteToFile YPelsPerMeter=%d\n"),pInfoHeader->biYPelsPerMeter);
01659 
01660         if (WriteHeader)
01661         {
01662             // BITMAPFILEHEADER goes first
01663             BITMAPFILEHEADER Header;
01664 
01665             Header.bfType = ('M'<<8) | 'B';
01666             Header.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
01667                             sizeof(RGBQUAD)*PalSize + pInfoHeader->biSizeImage;
01668             Header.bfReserved1 = 0;
01669             Header.bfReserved2 = 0;
01670             Header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
01671                                 sizeof(RGBQUAD)*PalSize;
01672 
01673             // Write that headerout ot the file
01674             File->write( &Header, sizeof(Header) );
01675         }
01676 
01677         // then a local BITMAPINFOHEADER
01678 
01679         File->write( pInfoHeader, sizeof(BITMAPINFOHEADER) );
01680 
01681         // then the RGBQUAD palette, if there is one
01682         if (PalSize)
01683         {
01684             // Work out the size of the palette that we should be saving
01685             const UINT32 TotalPal = sizeof(PALETTEENTRY) * PalSize;
01686             File->write( Info->bmiColors, TotalPal );
01687         }
01688 
01689         // Now write out the bitmap data itself.
01690         DWORD BitsSize = pInfoHeader->biSizeImage; 
01691 
01692         // Write the actual bytes out to file. Used to do it in one go but we really
01693         // require some progress bar indication so we will do it in chunks.
01694         if (BitsSize > 0)
01695         {
01696             // If pFilter is NULL and hence not native/web loading then do it in 
01697             // chunks of bytes
01698             if (pFilter == NULL)
01699             {
01700                 if (BitsSize < 1024 || ProgressString == NULL)
01701                 {
01702                     // File very small or no progress bar required, so load in one go
01703                     File->write( Bits, BitsSize);
01704                 }
01705                 else
01706                 {
01707                     // Load in chunks, for present split into 100 chunks
01708                     DWORD ChunkSize = BitsSize/100;
01709                     DWORD Position = 0;
01710                     LPBYTE pBitInfo = Bits;
01711                     
01712                     while (Position < BitsSize)
01713                     {
01714                         if ( (BitsSize - Position) > ChunkSize)
01715                             File->write( pBitInfo, ChunkSize);
01716                         else
01717                         {
01718                             ChunkSize = BitsSize - Position;
01719                             File->write( pBitInfo, ChunkSize);
01720                         }
01721                                 
01722                         // Increment our counters/pointers
01723                         Position += ChunkSize;
01724                         pBitInfo += ChunkSize;
01725                         ContinueSlowJob((INT32)(100*Position/BitsSize));
01726                     }
01727                 }
01728             }
01729             else
01730             {
01731                 // Do the reading a scanline at a time
01732                 // This makes progress bar update easier for native/web files
01733                 LPBYTE pBitInfo = Bits;
01734                 UINT32 ScanLineWidth = DIBUtil::ScanlineSize(pInfoHeader->biWidth, pInfoHeader->biBitCount);
01735                 UINT32 height = pInfoHeader->biHeight; 
01736                 // For each scaline in the file, read it in and update the progress bar count
01737                 for (UINT32 i = 0; i < height; i++)
01738                 {
01739                     File->write( pBitInfo, ScanLineWidth );
01740                     pBitInfo += ScanLineWidth;
01741                     pFilter->IncProgressBarCount(1);
01742                 }
01743             }
01744         }
01745 
01746         // If started, then stop then progress bar
01747         if (ProgressString != NULL)
01748         {
01749             EndSlowJob();
01750         }
01751 
01752         // Must set the exception throwing and reporting flags back to their entry states
01753         File->SetThrowExceptions( OldThrowingState );
01754         File->SetReportErrors( OldReportingState );
01755 
01756         // er, we seem to have finished OK so say so
01757         return TRUE;
01758     }
01759     catch( CFileException )
01760     {
01761         // catch our form of a file exception
01762         TRACE( _T("DIBUtil::WriteToFile CC catch handler\n"));
01763 
01764         // If started, then stop then progress bar
01765         if (ProgressString != NULL)
01766         {
01767             EndSlowJob();
01768         }
01769 
01770         // Must set the exception throwing and reporting flags back to their entry states
01771         File->SetThrowExceptions( OldThrowingState );
01772         File->SetReportErrors( OldReportingState );
01773 
01774         return FALSE;
01775     }
01776 
01777     ERROR2( FALSE, "Escaped exception clause somehow" );
01778 
01779 #endif
01780 }


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