#include <dibutil.h>
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 KernelBitmap * | CopyKernelBitmap (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 OILBitmap * | Create8bppGreyscaleBitmap (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. |
Definition at line 164 of file dibutil.h.
|
To allocate a LOGPALETTE ready for use. The caller is responsible for cleaning up the memmory allocation.
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 }
|
|
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.
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 }
|
|
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 }
|
|
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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 }
|
|
Generate an 8 bit form of a bitmap from a 24 bit form using the given palette.
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 }
|
|
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 }
|
|
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 }
|
|
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 }
|
|
Generate an 8 bit form of a bitmap from a 32 bit form using the given palette.
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 }
|
|
Generates a 32bit form of the input 8bit bitmap, note that the destination bitmapinfo and bitmap must be allocated prior to this function.
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 }
|
|
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 }
|
|
Generates an 8bpp greyscale bitmap from the given 1bpp, 4bpp or 8bpp bitmap.
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 }
|
|
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
Allocates a new CWxBitmap and KernelBitmap pointing to it. Note these are completely new versions containing the same data as the old ones.
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 }
|
|
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.
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 }
|
|
Counts the usage for each palette index in the bitmap. NOTE: Caller is responsible for CCFreeing the results array.
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 }
|
|
Designed to be used to create an 8bpp greyscale bitmap from a 24bpp, 4bpp or 1bpp bitmaps.
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 }
|
|
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 }
|
|
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)
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 }
|
|
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 }
|
|
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 }
|
|
Generate a greyscale palette for a greyscale DIB.
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 }
|
|
Generate a packed greyscale palette for a greyscale DIB.
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 }
|
|
Definition at line 3525 of file dibutil.cpp. 03526 { 03527 // ::GenOptimal4bppPalette( pPalette, MaxColours ); 03528 03529 return TRUE; 03530 }
|
|
Definition at line 3511 of file dibutil.cpp. 03512 { 03513 // ::GenOptimal4bppPaletteStats_1stPass( pBitmap, Size ); 03514 03515 return TRUE; 03516 }
|
|
Definition at line 3518 of file dibutil.cpp. 03519 { 03520 // ::GenOptimal4bppPaletteStats_2ndPass( pBitmap, Size ); 03521 03522 return TRUE; 03523 }
|
|
Definition at line 3560 of file dibutil.cpp. 03561 { 03562 // ::GenOptimal8bppPalette( Stats, pPalette, MaxColours ); 03563 ASSERT(FALSE); 03564 03565 return TRUE; 03566 }
|
|
Definition at line 3552 of file dibutil.cpp. 03553 { 03554 // ::GenOptimal8bppPaletteStats( Stats, pBitmap, Size ); 03555 ASSERT(FALSE); 03556 03557 return TRUE; 03558 }
|
|
The purpose of this function is to generate an optimal palette suitable for the bitmaps for which statistics have previously been generated.
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.
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 }
|
|
The purpose of this function is to build a table of statistics about one or more bitmaps prior to calling GenOptimalPalette.
This function just calls gavins C code in 'winoil.cpp'.
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 }
|
|
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.
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 }
|
|
Definition at line 3533 of file dibutil.cpp. 03534 { 03535 // return ::GetOptimal8bppPaletteWorkspaceSize(); 03536 ASSERT(FALSE); 03537 return 0; 03538 }
|
|
Returns size of workspace required by optimal palette routines.
Definition at line 3292 of file dibutil.cpp. 03293 { 03294 // return ::GetOptimalPaletteWorkspaceSize(); 03295 ASSERT(FALSE); 03296 return 0; 03297 }
|
|
Reads our prefs.
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 }
|
|
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.
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 }
|
|
Determines whether or not a bitmap is 32bpp.
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 }
|
|
Determines whether or not a bitmap is 32bpp.
Definition at line 4782 of file dibutil.cpp. 04783 { 04784 if ( (!pKB) || (!pKB->ActualBitmap) ) 04785 return FALSE; 04786 04787 return IsGreyscaleBitmap(pKB->ActualBitmap); 04788 }
|
|
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.
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 }
|
|
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.
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 }
|
|
Resizes a bitmap.
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 }
|
|
Definition at line 2009 of file dibutil.cpp. 02010 { 02011 ClearSystemPalette(); 02012 return CreateIdentityPalette( aRGB, nColors ); 02013 }
|
|
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.
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 }
|
|
Definition at line 3497 of file dibutil.cpp. 03498 { 03499 // ::Optimal4bppPaletteInitialise_1stPass(); 03500 03501 return TRUE; 03502 }
|
|
Definition at line 3504 of file dibutil.cpp. 03505 { 03506 // ::Optimal4bppPaletteInitialise_2ndPass(); 03507 03508 return TRUE; 03509 }
|
|
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 }
|
|
Initialises workspace required by optimal palette routines. Stats should have INT32 size of 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 }
|
|
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.
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 }
|
|
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.
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 }
|
|
Used in calculating offsets along scanlines. NOTE! Differs from ScanlineSize in that it DOES NOT word align the result!!!
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 }
|
|
Used in calculating bitmap memory requirements. Based on Gavin's code in GDraw_SetDIBitmap, which it had better agree with!
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 }
|
|
Generates a BITMAPINFO structor and then saves out the DIB.
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 }
|
|
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).
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 }
|