dibutil.cpp File Reference

(r1785/r1694)

#include "camtypes.h"
#include "grndrgn.h"
#include "bitfilt.h"
#include "bitmpinf.h"
#include "progress.h"
#include "tunemem.h"
#include "oilbitmap.h"
#include "gpalopt.h"
#include "hardwaremanager.h"

Go to the source code of this file.

Defines

#define new   CAM_DEBUG_NEW
#define DIB_DEBUG   0
#define EXPAND(x)   ( (x<<3) | (x>>2) )
#define RLE_ESCAPE   0
#define RLE_EOL   0
#define RLE_EOF   1
#define RLE_JMP   2
#define RLE_RUN   3
#define FAKE_32_TRANS   0
#define WRITE_32BIT   0

Functions

LPBITMAPINFO AllocDIB (UINT32 Width, UINT32 Height, UINT32 Depth, LPBYTE *Bits, MemoryBlock *Blk, BOOL UseLimitedHeap)
 Allocate and initialise a Windows DIB. Note biclrUsed is set only for 8-bit and less deep bitmaps, 0 for high-colour ones. biClrImportant is zeroed.
void FreeDIB (LPBITMAPINFO lpInfo, LPBYTE Bits, MemoryBlock *Blk, BOOL UseLimitedHeap)
 Free up a DIB allocated with AllocDIB.
INT32 GetDIBBitsSize (LPBITMAPINFOHEADER bh)
 Give actual mem size allocations made by AllocDIB - more mem is allocated than width * height * Bytes per pix.
static BOOL UnpackRle8 (CCLexFile *File, const BITMAPINFOHEADER &Header, LPBYTE Bits)
static void ReadPalette (CCLexFile *File, INT32 HowMany, size_t SizeOfRGB, LPRGBQUAD Result)
 Read the palette section of a BMP, either in modern format or old OS 2 format. Always ends up in RGBQUAD format. Scope: Static.
HPALETTE CreateIdentityPalette (PALETTEENTRY aRGB[], INT32 nColors)
void ClearSystemPalette (void)
void DebugMemCopy (LPBYTE pDest, LPBYTE pSrc, UINT32 size)
 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.

Variables

static BOOL RenderDirection4 = FALSE
static BOOL RenderDirection8 = FALSE
static BOOL RenderDirection16 = TRUE
static BOOL RenderDirection24 = FALSE
static UINT32 SubbandConversionSize = 0x80000


Define Documentation

#define DIB_DEBUG   0
 

Definition at line 133 of file dibutil.cpp.

#define EXPAND  )     ( (x<<3) | (x>>2) )
 

Definition at line 492 of file dibutil.cpp.

#define FAKE_32_TRANS   0
 

Definition at line 1007 of file dibutil.cpp.

#define new   CAM_DEBUG_NEW
 

Definition at line 129 of file dibutil.cpp.

#define RLE_EOF   1
 

Definition at line 887 of file dibutil.cpp.

#define RLE_EOL   0
 

Definition at line 886 of file dibutil.cpp.

#define RLE_ESCAPE   0
 

Definition at line 885 of file dibutil.cpp.

#define RLE_JMP   2
 

Definition at line 888 of file dibutil.cpp.

#define RLE_RUN   3
 

Definition at line 889 of file dibutil.cpp.

#define WRITE_32BIT   0
 

Definition at line 1851 of file dibutil.cpp.


Function Documentation

LPBITMAPINFO AllocDIB UINT32  Width,
UINT32  Height,
UINT32  Depth,
LPBYTE Bits,
MemoryBlock Blk,
BOOL  UseLimitedHeap
 

Allocate and initialise a Windows DIB. Note biclrUsed is set only for 8-bit and less deep bitmaps, 0 for high-colour ones. biClrImportant is zeroed.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/4/94
Parameters:
Size in pixels of DIB, Depth of bitmap (1,4,8,16,24,32) [INPUTS] UseLimitedHeap - TRUE if we should use the Limited memory allocator
Bits is updated to point to an array of bytes, or NULL if failed. If Blk is [OUTPUTS] not NULL then the bitmap is allocated into it instead of using CCMalloc and Bits will point to that. If Bits is NULL then no memory for the bitmap bytes are allocated, just the bitmap header. Due to GDraw restrictions, we actually allocate an extra 2 bytes plus one scanline.
Returns:
Pointer to suitable BITMAPINFO or NULL if failed.

Errors: If passed an invalid depth, will ensure and return NULL. If passed a zero width or height, it will return a 0x0 bitmap with four bytes allocated for the 'bits'. Scope: Global

See also:
FreeDIB & GetDIBBitsSize
NB NB NB If this changes please ensure mem allocation changes are reflected in GetDIBBitsSize as well.

Definition at line 181 of file dibutil.cpp.

00182 {
00183     LPBITMAPINFO lpInfo;
00184 
00185     ENSURE(Blk==NULL, "Cannot do blks yet");
00186 
00187     INT32 size = DIBUtil::ScanlineSize( Width, Depth ) * Height;
00188     #if DIB_DEBUG
00189     const INT32 dbsize = DIBUtil::ScanlineSize( Width, Depth ) * DIB_DEBUG*2;
00190     if (dbsize<16)
00191         dbsize = 16;
00192     #else
00193     const INT32 dbsize = 0;
00194     #endif
00195 
00196     if (size==0)
00197         size = 4;                                       // in case of zero w or h
00198 
00199     // Get the memory manager
00200     TunedMemory* pTuned = GetTunedMemManager();
00201 
00202     // get the bytes
00203     LPBYTE Bytes = NULL;
00204     if (Bits)
00205     {
00206         // in case of failure
00207         *Bits = NULL;
00208 
00209         // allocate the actual bits of the bitmap first
00210         if (UseLimitedHeap)
00211             Bytes = (LPBYTE) pTuned->LimitedCCMalloc(size + dbsize + EXTRA_GAVIN_BYTES + DIBUtil::ScanlineSize(Width, Depth));
00212         else
00213             Bytes = (LPBYTE)CCMalloc(size + dbsize + EXTRA_GAVIN_BYTES + DIBUtil::ScanlineSize(Width, Depth));
00214 
00215         // See what we got
00216         if (Bytes==NULL)
00217             return NULL;
00218     }
00219 
00220     // we need a BITMAPINFO structure
00221     size_t extras;
00222     INT32 used_cols = 0;
00223 
00224     switch (Depth)
00225     {
00226         case 1:
00227             extras = 2*sizeof(COLORREF);
00228             used_cols = 2;
00229             break;
00230         case 4:
00231             extras = 16*sizeof(COLORREF);
00232             used_cols = 16;
00233             break;
00234         case 8:
00235             extras = 256*sizeof(COLORREF);
00236             used_cols = 256;
00237             break;
00238         case 16:
00239             extras = 3*sizeof(COLORREF);
00240             break;
00241         case 24:
00242             extras = 0;
00243             break;
00244         case 32:
00245             extras = 3*sizeof(COLORREF);
00246             break;
00247         default:
00248             ENSURE(FALSE, "Bad bitmap depth");
00249             return NULL;
00250     }
00251 
00252     // get the bitmap info block
00253     if (UseLimitedHeap)
00254         lpInfo = (LPBITMAPINFO) pTuned->LimitedCCMalloc(sizeof(BITMAPINFO) + extras);
00255     else
00256         lpInfo = (LPBITMAPINFO) CCMalloc(sizeof(BITMAPINFO) + extras);
00257         
00258     // See if it worked
00259     if (lpInfo == NULL)
00260     {
00261         // Free the memory from the appropriate place
00262         if (UseLimitedHeap)
00263             pTuned->LimitedCCFree(Bytes);
00264         else
00265             CCFree(Bytes);
00266 
00267         return NULL;
00268     }
00269 
00270     lpInfo->bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
00271     lpInfo->bmiHeader.biWidth       = Width;
00272     lpInfo->bmiHeader.biHeight      = Height;
00273     lpInfo->bmiHeader.biPlanes      = 1;
00274     lpInfo->bmiHeader.biBitCount    = Depth;
00275     lpInfo->bmiHeader.biCompression = BI_RGB;
00276     lpInfo->bmiHeader.biXPelsPerMeter   = 3780;             // Default to 96 dpi
00277     lpInfo->bmiHeader.biYPelsPerMeter   = 3780;
00278     lpInfo->bmiHeader.biClrUsed         = used_cols;
00279     lpInfo->bmiHeader.biClrImportant    = 0;
00280     lpInfo->bmiHeader.biSizeImage       = size;
00281 
00282     if (extras > 0)
00283     {
00284         memset(&(lpInfo->bmiColors[0]), 0, extras);
00285     }
00286 
00287     if (Bits)
00288     {
00289         #if DIB_DEBUG
00290         const size_t count = DIBUtil::ScanlineSize( Width, Depth ); // bytes per scanline
00291         memset( Bytes, 0x42, count*DIB_DEBUG );                     // top area
00292         memset( Bytes + count * (Height + DIB_DEBUG), 0x42, count*DIB_DEBUG );
00293         Bytes += count * DIB_DEBUG;
00294         PINT32 lpLong = (PINT32) (Bytes-4);
00295         *lpLong = count;                                    // store count
00296         lpLong[-1] = (INT32)(Bytes + count * Height);       // and ptr to end
00297         #endif
00298         *Bits = Bytes;                                      // return for caller
00299     }
00300 
00301     return lpInfo;
00302 }

void ClearSystemPalette void   ) 
 

Definition at line 1962 of file dibutil.cpp.

01963 {
01964     // This isn't particularly friendly to other palette using apps
01965     // so we'll remove it from Ralph...
01966 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX)
01967 
01968     //*** A dummy palette setup
01969     struct
01970     {
01971         WORD Version;
01972         WORD NumberOfEntries;
01973         PALETTEENTRY aEntries[256];
01974     } Palette =
01975     {
01976         0x300,
01977         256
01978     };
01979 
01980     HPALETTE ScreenPalette = 0;
01981     HDC ScreenDC;
01982     INT32 Counter;
01983 
01984     //*** Reset everything in the system palette to black
01985     for(Counter = 0; Counter < 256; Counter++)
01986     {
01987         Palette.aEntries[Counter].peRed = 0;
01988         Palette.aEntries[Counter].peGreen = 0;
01989         Palette.aEntries[Counter].peBlue = 0;
01990 
01991 
01992         Palette.aEntries[Counter].peFlags = PC_NOCOLLAPSE;
01993     }
01994 
01995     //*** Create, select, realize, deselect, and delete the palette
01996     ScreenDC = GetDC(NULL);
01997     ScreenPalette = CreatePalette((LOGPALETTE *)&Palette);
01998     if (ScreenPalette)
01999     {
02000         ScreenPalette = SelectPalette(ScreenDC,ScreenPalette,FALSE);
02001         RealizePalette(ScreenDC);
02002         ScreenPalette = SelectPalette(ScreenDC,ScreenPalette,FALSE);
02003         DeleteObject(ScreenPalette);
02004     }
02005     ReleaseDC(NULL, ScreenDC);
02006 #endif // EXCLUDE_FROM_RALPH, EXCLUDE_FROM_XARALX
02007 }

HPALETTE CreateIdentityPalette PALETTEENTRY  aRGB[],
INT32  nColors
 

Definition at line 1856 of file dibutil.cpp.

01857 {
01858     PORTNOTETRACE("other","CreateIdentityPalette - do nothing - no palette support anymore");
01859 #ifndef EXCLUDE_FROM_XARALX
01860     INT32 i;
01861     struct {
01862         WORD Version;
01863         WORD NumberOfEntries;
01864         PALETTEENTRY aEntries[256];
01865     } Palette =
01866     {
01867         0x300,
01868         256
01869     };
01870 
01871     //*** Just use the screen DC where we need it
01872     wxScreenDC          dc;
01873 
01874     //*** For SYSPAL_NOSTATIC, just copy the color table into
01875     //*** a PALETTEENTRY array and replace the first and last entries
01876     //*** with black and white
01877     if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
01878 
01879     {
01880         //*** Fill in the palette with the given values, marking each
01881         //*** as PC_NOCOLLAPSE
01882         for(i = 0; i < nColors; i++)
01883         {
01884             Palette.aEntries[i].peRed = aRGB[i].peRed;
01885             Palette.aEntries[i].peGreen = aRGB[i].peGreen;
01886             Palette.aEntries[i].peBlue = aRGB[i].peBlue;
01887 //          Palette.aEntries[i].peFlags = PC_NOCOLLAPSE;
01888             Palette.aEntries[i].peFlags = 0;
01889         }
01890 
01891         //*** Mark any unused entries PC_NOCOLLAPSE
01892         for (; i < 256; ++i)
01893         {
01894 //          Palette.aEntries[i].peFlags = PC_NOCOLLAPSE;
01895             Palette.aEntries[i].peFlags = 0;
01896         }
01897 
01898         //*** Make sure the last entry is white
01899         //*** This may replace an entry in the array!
01900         Palette.aEntries[255].peRed = 255;
01901         Palette.aEntries[255].peGreen = 255;
01902         Palette.aEntries[255].peBlue = 255;
01903         Palette.aEntries[255].peFlags = 0;
01904 
01905         //*** And the first is black
01906         //*** This may replace an entry in the array!
01907         Palette.aEntries[0].peRed = 0;
01908         Palette.aEntries[0].peGreen = 0;
01909         Palette.aEntries[0].peBlue = 0;
01910         Palette.aEntries[0].peFlags = 0;
01911 
01912     }
01913     else
01914     //*** For SYSPAL_STATIC, get the twenty static colors into
01915     //*** the array, then fill in the empty spaces with the
01916     //*** given color table
01917     {
01918         INT32 nStaticColors;
01919         INT32 nUsableColors;
01920 
01921         //*** Get the static colors from the system palette
01922         nStaticColors = GetDeviceCaps(hdc, NUMCOLORS);
01923         GetSystemPaletteEntries(hdc, 0, 256, Palette.aEntries);
01924 
01925         //*** Set the peFlags of the lower static colors to zero
01926         nStaticColors = nStaticColors / 2;
01927 
01928         for (i=0; i<nStaticColors; i++)
01929             Palette.aEntries[i].peFlags = 0;
01930 
01931         //*** Fill in the entries from the given color table
01932         nUsableColors = nColors - nStaticColors;
01933         for (; i<nUsableColors; i++)
01934         {
01935             Palette.aEntries[i].peRed = aRGB[i].peRed;
01936             Palette.aEntries[i].peGreen = aRGB[i].peGreen;
01937             Palette.aEntries[i].peBlue = aRGB[i].peBlue;
01938 //          Palette.aEntries[i].peFlags = PC_NOCOLLAPSE;
01939             Palette.aEntries[i].peFlags = 0;
01940         }
01941 
01942         //*** Mark any empty entries as PC_NOCOLLAPSE
01943 
01944         for (; i<256 - nStaticColors; i++)
01945 //          Palette.aEntries[i].peFlags = PC_NOCOLLAPSE;
01946             Palette.aEntries[i].peFlags = 0;
01947 
01948         //*** Set the peFlags of the upper static colors to zero
01949         for (i = 256 - nStaticColors; i<256; i++)
01950             Palette.aEntries[i].peFlags = 0;
01951     }
01952 
01953     //*** Return the palette
01954     return CreatePalette((LOGPALETTE *)&Palette);
01955 #else
01956     return NULL;
01957 #endif
01958 }

void DebugMemCopy LPBYTE  pDest,
LPBYTE  pSrc,
UINT32  size
 

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.

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

Definition at line 2744 of file dibutil.cpp.

02745 {
02746     memcpy(pDest, pSrc, size);
02747 }

void FreeDIB LPBITMAPINFO  lpInfo,
LPBYTE  Bits,
MemoryBlock Blk,
BOOL  UseLimitedHeap
 

Free up a DIB allocated with AllocDIB.

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
13/4/94
Parameters:
Results of AllocDIB. [INPUTS] UseLimitedHeap - TRUE if we should use the Limited heap. Defaults to FALSE
- [OUTPUTS]
Returns:
-

Errors: - Scope: Global

See also:
AllocDIB

Definition at line 321 of file dibutil.cpp.

00322 {
00323     ENSURE(Blk==NULL, "Cannot free blocks");
00324     #if DIB_DEBUG
00325     if (Bits)
00326     {
00327         const size_t count = *(PINT32)(Bits-4);
00328         const LPBYTE endbuf= (LPBYTE)*(PINT32)(Bits-8);
00329         LPBYTE p = Bits - count * DIB_DEBUG;
00330         size_t i = count - 8;
00331         while (i--)
00332         {
00333             if (*p != 0x42)
00334                 ENSURE(FALSE, "top of bitmap corrupted");
00335             p++;
00336         }
00337         p = endbuf;
00338         i = count;
00339         while (i--)
00340         {
00341             if (*p != 0x42)
00342                 ENSURE(FALSE, "bottom of bitmap corrupted");
00343             p++;
00344         }
00345         Bits -= count * DIB_DEBUG;
00346     }
00347     #endif
00348 
00349     // Free the bits
00350     if (UseLimitedHeap)
00351     {
00352         // Get the memory manager
00353         TunedMemory* pTuned = GetTunedMemManager();
00354         pTuned->LimitedCCFree(Bits);
00355         pTuned->LimitedCCFree(lpInfo);
00356     }
00357     else
00358     {
00359         CCFree(Bits);
00360         CCFree(lpInfo);
00361     }
00362 }

INT32 GetDIBBitsSize LPBITMAPINFOHEADER  bh  ) 
 

Give actual mem size allocations made by AllocDIB - more mem is allocated than width * height * Bytes per pix.

Author:
Ilan_Copelyn (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/5/00
Parameters:
lpInfo - LPBITMAPINFO struct returned by AllocDIB [INPUTS]
Returns:
Actual size of bmp memory block allocated by AllocDIB for the bitmap bits described by the bmp header lpInfo

Errors: - Scope: Global

See also:
AllocDIB
NOTES: NB NB Don't use this on a LPBITMAPINFO that was not created by AllocDIB. The calculations are specific to the way AllocDIB allocs mem, so may give you inaccurate results for other bmp buffers

Definition at line 384 of file dibutil.cpp.

00385 {
00386     // Mem calc from Dibutils AllocDIB
00387     // Bytes = (LPBYTE)CCMalloc(size + dbsize + EXTRA_GAVIN_BYTES + DIBUtil::ScanlineSize(Width, Depth));
00388     return bh->biSizeImage;
00389 /*  INT32 size = DIBUtil::ScanlineSize( bh->biWidth, bh->biBitCount ) * bh->biHeight;
00390     #if DIB_DEBUG
00391     const INT32 dbsize = DIBUtil::ScanlineSize( bh->biWidth, bh->biBitCount ) * DIB_DEBUG*2;
00392     if (dbsize<16)
00393         dbsize = 16;
00394     #else
00395     const INT32 dbsize = 0;
00396     #endif
00397 
00398     if (size==0)
00399         size = 4;                                       // in case of zero w or h
00400 
00401     return size + dbsize + EXTRA_GAVIN_BYTES + DIBUtil::ScanlineSize( bh->biWidth, bh->biBitCount );
00402 */
00403 }

static void ReadPalette CCLexFile File,
INT32  HowMany,
size_t  SizeOfRGB,
LPRGBQUAD  Result
[static]
 

Read the palette section of a BMP, either in modern format or old OS 2 format. Always ends up in RGBQUAD format. Scope: Static.

static void ReadPalette( CCLexFile *File, INT32 HowMany, size_t SizeOfRGB, LPRGBQUAD Result )

Author:
Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
Date:
19/8/94
Parameters:
A file, count of how many palette entries there are, and either [INPUTS] sizeof(RGBTRIPLE) or sizeof(RGBQUAD).
Result gets filled in with the palette. [OUTPUTS]
Returns:
-

Definition at line 981 of file dibutil.cpp.

00982 {
00983     // this isn't exactly efficient but it works, is endian-independent and reliable
00984     while (HowMany--)
00985     {
00986         // Read byte by byte so we get endianness right
00987         File->read( &(Result->rgbBlue), sizeof(BYTE));
00988         File->read( &(Result->rgbGreen), sizeof(BYTE));
00989         File->read( &(Result->rgbRed), sizeof(BYTE));
00990         if (SizeOfRGB==sizeof(RGBQUAD))
00991         {   
00992             File->read( &(Result->rgbReserved), sizeof(BYTE));
00993         }
00994         else if (SizeOfRGB==sizeof(RGBTRIPLE))
00995         {
00996             Result->rgbReserved=0;
00997         }
00998         else
00999         {
01000             ENSURE(FALSE, "Strange RGB size if ReadPalette");
01001         }
01002         Result++;
01003     }
01004 }

static BOOL UnpackRle8 CCLexFile File,
const BITMAPINFOHEADER Header,
LPBYTE  Bits
[static]
 

Definition at line 894 of file dibutil.cpp.

00895 {
00896     BYTE    Buffer[2];
00897     BYTE    cnt;
00898     BYTE    b;
00899     WORD    x;
00900     WORD    dx,dy;
00901     DWORD    wWidthBytes;
00902 
00903     wWidthBytes = Header.biWidth+3 & ~3;
00904 
00905     x = 0;
00906 
00907     for(;;)
00908     {
00909         if (File->read( Buffer, 2 ).bad())
00910             return FALSE;
00911         cnt = Buffer[0];
00912         b   = Buffer[1];
00913 
00914         if (cnt == RLE_ESCAPE)
00915         {
00916             switch (b)
00917             {
00918                 case RLE_EOF:
00919                     return TRUE;
00920 
00921                 case RLE_EOL:
00922                     Bits += wWidthBytes - x;
00923                     x = 0;
00924                     break;
00925 
00926                 case RLE_JMP:
00927                     if (File->read( Buffer, 2 ).bad())
00928                         return FALSE;
00929                     dx = (WORD)Buffer[0];
00930                     dy = (WORD)Buffer[1];
00931 
00932                     Bits += wWidthBytes * dy + dx;
00933                     x  += dx;
00934 
00935                     break;
00936 
00937                 default:
00938                     cnt = b;
00939                     x  += cnt;
00940                     if (File->read( Bits, cnt ).bad())
00941                         return FALSE;
00942                     Bits += cnt;
00943 
00944                     if (b & 1)
00945                     {
00946                         if (File->read( Buffer, 1).bad())               // pad read
00947                             return FALSE;
00948                     }
00949 
00950                     break;
00951             }
00952         }
00953         else
00954         {
00955             x += cnt;
00956 
00957             while (cnt-- > 0)
00958                 *Bits++ = b;
00959         }
00960     }
00961     return TRUE;
00962 }


Variable Documentation

BOOL RenderDirection16 = TRUE [static]
 

Definition at line 140 of file dibutil.cpp.

BOOL RenderDirection24 = FALSE [static]
 

Definition at line 141 of file dibutil.cpp.

BOOL RenderDirection4 = FALSE [static]
 

Definition at line 138 of file dibutil.cpp.

BOOL RenderDirection8 = FALSE [static]
 

Definition at line 139 of file dibutil.cpp.

UINT32 SubbandConversionSize = 0x80000 [static]
 

Definition at line 150 of file dibutil.cpp.


Generated on Sat Nov 10 03:49:30 2007 for Camelot by  doxygen 1.4.4