]>
git.saurik.com Git - wxWidgets.git/blob - src/msw/dibutils.cpp
10a61b9249bf8b2e89688567c38447fcbca6bdae
   1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Utilities for DIBs 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Microsoft, Julian Smart and Markus Holzem 
   9 // Licence:     wxWindows license 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "dibutils.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  33 #include "wx/msw/dibutils.h" 
  35 #if defined(__WIN32__) 
  36 #if !defined(__MWERKS__) && !defined(__SALFORDC__) 
  37     #include <memory.h>             // for _fmemcpy() 
  41     #define hmemcpy memcpy 
  45 #define BFT_ICON   0x4349   /* 'IC' */ 
  46 #define BFT_BITMAP 0x4d42   /* 'BM' */ 
  47 #define BFT_CURSOR 0x5450   /* 'PT' */ 
  49 /* flags for _lseek */ 
  56  *  Clear the System Palette so that we can ensure an identity palette  
  57  *  mapping for fast performance. 
  60 void ClearSystemPalette(void) 
  62   //*** A dummy palette setup 
  67     PALETTEENTRY aEntries
[256]; 
  74   HPALETTE ScreenPalette 
= 0; 
  81   //*** Reset everything in the system palette to black 
  82   for(Counter 
= 0; Counter 
< 256; Counter
++) 
  84     Palette
.aEntries
[Counter
].peRed 
= 0; 
  85    Palette
.aEntries
[Counter
].peGreen 
= 0; 
  86     Palette
.aEntries
[Counter
].peBlue 
= 0; 
  87     Palette
.aEntries
[Counter
].peFlags 
= PC_NOCOLLAPSE
; 
  90   //*** Create, select, realize, deselect, and delete the palette 
  91   ScreenDC 
= GetDC(NULL
); 
  92   ScreenPalette 
= CreatePalette((LOGPALETTE 
*)&Palette
); 
  96    ScreenPalette 
= SelectPalette(ScreenDC
,ScreenPalette
,FALSE
); 
  97    nMapped 
= RealizePalette(ScreenDC
); 
  98     ScreenPalette 
= SelectPalette(ScreenDC
,ScreenPalette
,FALSE
); 
  99     bOK 
= DeleteObject(ScreenPalette
); 
 102   nOK 
= ReleaseDC(NULL
, ScreenDC
); 
 109  *   Open a DIB file and return a MEMORY DIB, a memory handle containing.. 
 116 int DibWriteFile(LPSTR szFile
, LPBITMAPINFOHEADER lpbi
) 
 121    fh 
= OpenFile(szFile
, &of
, OF_WRITE 
| OF_CREATE
); 
 124 //   printf("la regamos0"); 
 128   long size 
= DibSize(lpbi
); 
 131   BITMAPFILEHEADER bmf
; 
 133   bmf
.bfSize 
= sizeof(bmf
) + size
; 
 136   bmf
.bfOffBits 
= sizeof(bmf
) + (char far
*)(DibPtr(lpbi
)) - (char far
*)lpbi
; 
 137 #if defined( __WATCOMC__) || defined(__VISUALC__) || defined(__SC__) || defined(__SALFORDC__) || defined(__MWERKS__) 
 138   if (_hwrite(fh
, (LPCSTR
)(&bmf
), sizeof(bmf
))<0 || 
 139   _hwrite(fh
, (LPCSTR
)lpbi
, size
)<0) { 
 141 //   printf("la regamos1"); 
 145   if (_hwrite(fh
, (LPBYTE
)(&bmf
), sizeof(bmf
))<0 || 
 146   _hwrite(fh
, (LPBYTE
)lpbi
, size
)<0) { 
 148 //   printf("la regamos1"); 
 157 PDIB 
DibOpenFile(LPSTR szFile
) 
 166 #if defined(WIN32) || defined(_WIN32) 
 167    #define GetCurrentInstance()    GetModuleHandle(NULL) 
 169    #define GetCurrentInstance()    (HINSTANCE)SELECTOROF((LPVOID)&of) 
 172    fh 
= OpenFile(szFile
, &of
, OF_READ
); 
 178           // TODO: Unicode version 
 180       h 
= FindResource(GetCurrentInstance(), szFile
, RT_BITMAP
); 
 182       h 
= FindResourceA(GetCurrentInstance(), szFile
, RT_BITMAP
); 
 185 #if defined(__WIN32__) 
 186       //!!! can we call GlobalFree() on this? is it the right format. 
 187       //!!! can we write to this resource? 
 189         return (PDIB
)LockResource(LoadResource(GetCurrentInstance(), h
)); 
 192         fh 
= AccessResource(GetCurrentInstance(), h
); 
 199    pdib 
= DibReadBitmapInfo(fh
); 
 204     /* How much memory do we need to hold the DIB */ 
 206     dwBits 
= pdib
->biSizeImage
; 
 207     dwLen  
= pdib
->biSize 
+ DibPaletteSize(pdib
) + dwBits
; 
 209     /* Can we get more memory? */ 
 211    p 
= GlobalReAllocPtr(pdib
,dwLen
,0); 
 225       /* read in the bits */ 
 226       _hread(fh
, (LPBYTE
)pdib 
+ (UINT
)pdib
->biSize 
+ DibPaletteSize(pdib
), dwBits
); 
 236  *  ReadDibBitmapInfo() 
 238  *  Will read a file in DIB format and return a global HANDLE to its 
 239  *  BITMAPINFO.  This function will work with both "old" and "new" 
 240  *  bitmap formats, but will always return a "new" BITMAPINFO. 
 243 PDIB 
DibReadBitmapInfo(HFILE fh
) 
 259     off 
= _llseek(fh
,0L,SEEK_CUR
); 
 261     if (sizeof(bf
) != _lread(fh
,(LPSTR
)&bf
,sizeof(bf
))) 
 265      *  do we have a RC HEADER? 
 267     if (bf
.bfType 
!= BFT_BITMAP
) 
 270         _llseek(fh
,off
,SEEK_SET
); 
 273     if (sizeof(bi
) != _lread(fh
,(LPSTR
)&bi
,sizeof(bi
))) 
 277      *  what type of bitmap info is this? 
 279     switch (size 
= (int)bi
.biSize
) 
 282         case sizeof(BITMAPINFOHEADER
): 
 285         case sizeof(BITMAPCOREHEADER
): 
 286             bc 
= *(BITMAPCOREHEADER
*)&bi
; 
 287             bi
.biSize               
= sizeof(BITMAPINFOHEADER
); 
 288             bi
.biWidth              
= (DWORD
)bc
.bcWidth
; 
 289             bi
.biHeight             
= (DWORD
)bc
.bcHeight
; 
 290             bi
.biPlanes             
=  (UINT
)bc
.bcPlanes
; 
 291             bi
.biBitCount           
=  (UINT
)bc
.bcBitCount
; 
 292             bi
.biCompression        
= BI_RGB
; 
 294             bi
.biXPelsPerMeter      
= 0; 
 295             bi
.biYPelsPerMeter      
= 0; 
 297             bi
.biClrImportant       
= 0; 
 299             _llseek(fh
,(LONG
)sizeof(BITMAPCOREHEADER
)-sizeof(BITMAPINFOHEADER
),SEEK_CUR
); 
 304     nNumColors 
= DibNumColors(&bi
); 
 307     if (bi
.biSizeImage 
== 0) 
 308         bi
.biSizeImage 
= DibSizeImage(&bi
); 
 310     if (bi
.biClrUsed 
== 0) 
 311         bi
.biClrUsed 
= DibNumColors(&bi
); 
 316     pdib 
= (PDIB
)GlobalAllocPtr(GMEM_MOVEABLE
,(LONG
)bi
.biSize 
+ nNumColors 
* sizeof(RGBQUAD
)); 
 323     pRgb 
= DibColors(pdib
); 
 327         if (size 
== sizeof(BITMAPCOREHEADER
)) 
 330              * convert a old color table (3 byte entries) to a new 
 331              * color table (4 byte entries) 
 333             _lread(fh
,(LPVOID
)pRgb
,nNumColors 
* sizeof(RGBTRIPLE
)); 
 335             for (i
=nNumColors
-1; i
>=0; i
--) 
 339                 rgb
.rgbRed      
= ((RGBTRIPLE FAR 
*)pRgb
)[i
].rgbtRed
; 
 340                 rgb
.rgbBlue     
= ((RGBTRIPLE FAR 
*)pRgb
)[i
].rgbtBlue
; 
 341                 rgb
.rgbGreen    
= ((RGBTRIPLE FAR 
*)pRgb
)[i
].rgbtGreen
; 
 342                 rgb
.rgbReserved 
= (BYTE
)0; 
 349             _lread(fh
,(LPVOID
)pRgb
,nNumColors 
* sizeof(RGBQUAD
)); 
 353     if (bf
.bfOffBits 
!= 0L) 
 354         _llseek(fh
,off 
+ bf
.bfOffBits
,SEEK_SET
); 
 360  *  DibSetUsage(hdib,hpal,wUsage) 
 362  *  Modifies the color table of the passed DIB for use with the wUsage 
 363  *  parameter specifed. 
 365  *  if wUsage is DIB_PAL_COLORS the DIB color table is set to 0-256 
 366  *  if wUsage is DIB_RGB_COLORS the DIB color table is set to the RGB values 
 367  *      in the passed palette 
 370 BOOL 
DibSetUsage(PDIB pdib
, HPALETTE hpal
,UINT wUsage
) 
 372     PALETTEENTRY       ape
[256]; 
 379         hpal 
= (HPALETTE
)GetStockObject(DEFAULT_PALETTE
); 
 384     nColors 
= DibNumColors(pdib
); 
 386     if (nColors 
== 3 && DibCompression(pdib
) == BI_BITFIELDS
) 
 391         pRgb 
= DibColors(pdib
); 
 396             // Set the DIB color table to palette indexes 
 399                 for (pw 
= (WORD FAR
*)pRgb
,n
=0; n
<nColors
; n
++,pw
++) 
 404             // Set the DIB color table to RGBQUADS 
 408                 nColors 
=  (nColors 
< 256) ? nColors
: 256; 
 410                 GetPaletteEntries(hpal
,0,nColors
,ape
); 
 412                 for (n
=0; n
<nColors
; n
++) 
 414                     pRgb
[n
].rgbRed      
= ape
[n
].peRed
; 
 415                     pRgb
[n
].rgbGreen    
= ape
[n
].peGreen
; 
 416                     pRgb
[n
].rgbBlue     
= ape
[n
].peBlue
; 
 417                     pRgb
[n
].rgbReserved 
= 0; 
 426  *  DibCreate(bits, dx, dy) 
 428  *  Creates a new packed DIB with the given dimensions and the 
 429  *  given number of bits per pixel 
 432 PDIB 
DibCreate(int bits
, int dx
, int dy
) 
 434     LPBITMAPINFOHEADER lpbi 
; 
 439     dwSizeImage 
= dy
*(DWORD
)((dx
*bits
/8+3)&~3); 
 441     lpbi 
= (PDIB
)GlobalAllocPtr(GHND
,sizeof(BITMAPINFOHEADER
)+dwSizeImage 
+ 1024); 
 446     lpbi
->biSize            
= sizeof(BITMAPINFOHEADER
) ; 
 450     lpbi
->biBitCount        
= bits 
; 
 451     lpbi
->biCompression     
= BI_RGB 
; 
 452     lpbi
->biSizeImage       
= dwSizeImage
; 
 453     lpbi
->biXPelsPerMeter   
= 0 ; 
 454     lpbi
->biYPelsPerMeter   
= 0 ; 
 455     lpbi
->biClrUsed         
= 0 ; 
 456     lpbi
->biClrImportant    
= 0 ; 
 459         lpbi
->biClrUsed 
= 16; 
 462         lpbi
->biClrUsed 
= 256; 
 464     pdw 
= (DWORD FAR 
*)((LPBYTE
)lpbi
+(int)lpbi
->biSize
); 
 466     for (i
=0; i
<(int)lpbi
->biClrUsed
/16; i
++) 
 468         *pdw
++ = 0x00000000;    // 0000  black 
 469         *pdw
++ = 0x00800000;    // 0001  dark red 
 470         *pdw
++ = 0x00008000;    // 0010  dark green 
 471       *pdw
++ = 0x00808000;    // 0011  mustard 
 472         *pdw
++ = 0x00000080;    // 0100  dark blue 
 473         *pdw
++ = 0x00800080;    // 0101  purple 
 474         *pdw
++ = 0x00008080;    // 0110  dark turquoise 
 475         *pdw
++ = 0x00C0C0C0;    // 1000  gray 
 476         *pdw
++ = 0x00808080;    // 0111  dark gray 
 477         *pdw
++ = 0x00FF0000;    // 1001  red 
 478         *pdw
++ = 0x0000FF00;    // 1010  green 
 479       *pdw
++ = 0x00FFFF00;    // 1011  yellow 
 480         *pdw
++ = 0x000000FF;    // 1100  blue 
 481         *pdw
++ = 0x00FF00FF;    // 1101  pink (magenta) 
 482         *pdw
++ = 0x0000FFFF;    // 1110  cyan 
 483         *pdw
++ = 0x00FFFFFF;    // 1111  white 
 489 static void xlatClut8(BYTE FAR 
*pb
, DWORD dwSize
, BYTE FAR 
*xlat
) 
 494     for (dw 
= 0; dw 
< dwSize
; dw
++, ((BYTE _huge 
*&)pb
)++) 
 496     for (dw 
= 0; dw 
< dwSize
; dw
++, ((BYTE _huge 
*)pb
)++) 
 501 static void xlatClut4(BYTE FAR 
*pb
, DWORD dwSize
, BYTE FAR 
*xlat
) 
 506     for (dw 
= 0; dw 
< dwSize
; dw
++, ((BYTE _huge 
*&)pb
)++) 
 508     for (dw 
= 0; dw 
< dwSize
; dw
++, ((BYTE _huge 
*)pb
)++) 
 510         *pb 
= (BYTE
)(xlat
[*pb 
& 0x0F] | (xlat
[(*pb 
>> 4) & 0x0F] << 4)); 
 518 static void xlatRle8(BYTE FAR 
*pb
, DWORD dwSize
, BYTE FAR 
*xlat
) 
 522     BYTE _huge 
*prle 
= pb
; 
 529         if (cnt 
== RLE_ESCAPE
) 
 548                     for (b
=0; b
<cnt
; b
++,prle
++) 
 564 static void xlatRle4(BYTE FAR 
*pb
, DWORD dwSize
, BYTE FAR 
*xlat
) 
 568 static void hmemmove(BYTE _huge 
*d
, BYTE _huge 
*s
, LONG len
) 
 578  *  DibMapToPalette(pdib, hpal) 
 580  *  Map the colors of the DIB, using GetNearestPaletteIndex, to 
 581  *  the colors of the given palette. 
 584 BOOL 
DibMapToPalette(PDIB pdib
, HPALETTE hpal
) 
 586    LPBITMAPINFOHEADER  lpbi
; 
 599    lpbi   
= (LPBITMAPINFOHEADER
)pdib
; 
 600    lpRgb  
= DibColors(pdib
); 
 602    GetObject(hpal
,sizeof(int),(LPSTR
)&nPalColors
); 
 603    nDibColors 
= DibNumColors(pdib
); 
 605    if ((SizeImage 
= lpbi
->biSizeImage
) == 0) 
 606       SizeImage 
= DibSizeImage(lpbi
); 
 609    //  build a xlat table. from the current DIB colors to the given 
 612    for (n
=0; n
<nDibColors
; n
++) 
 613       xlat
[n
] = (BYTE
)GetNearestPaletteIndex(hpal
,RGB(lpRgb
[n
].rgbRed
,lpRgb
[n
].rgbGreen
,lpRgb
[n
].rgbBlue
)); 
 615    lpBits 
= (LPBYTE
)DibPtr(lpbi
); 
 616    lpbi
->biClrUsed 
= nPalColors
; 
 621    if (nPalColors 
> nDibColors
) 
 623       GlobalReAllocPtr(lpbi
, lpbi
->biSize 
+ nPalColors
*sizeof(RGBQUAD
) + SizeImage
, 0); 
 624       hmemmove((BYTE _huge 
*)DibPtr(lpbi
), (BYTE _huge 
*)lpBits
, SizeImage
); 
 625       lpBits 
= (LPBYTE
)DibPtr(lpbi
); 
 627    else if (nPalColors 
< nDibColors
) 
 629       hmemcpy(DibPtr(lpbi
), lpBits
, SizeImage
); 
 630       GlobalReAllocPtr(lpbi
, lpbi
->biSize 
+ nPalColors
*sizeof(RGBQUAD
) + SizeImage
, 0); 
 631       lpBits 
= (LPBYTE
)DibPtr(lpbi
); 
 635    // translate the DIB bits 
 637    switch (lpbi
->biCompression
) 
 640         xlatRle8(lpBits
, SizeImage
, xlat
); 
 644         xlatRle4(lpBits
, SizeImage
, xlat
); 
 648         if (lpbi
->biBitCount 
== 8) 
 649                 xlatClut8(lpBits
, SizeImage
, xlat
); 
 651                 xlatClut4(lpBits
, SizeImage
, xlat
); 
 656     //  Now copy the RGBs in the logical palette to the dib color table 
 658     for (n
=0; n
<nPalColors
; n
++) 
 660         GetPaletteEntries(hpal
,n
,1,&pe
); 
 662         lpRgb
[n
].rgbRed      
= pe
.peRed
; 
 663       lpRgb
[n
].rgbGreen    
= pe
.peGreen
; 
 664       lpRgb
[n
].rgbBlue     
= pe
.peBlue
; 
 665       lpRgb
[n
].rgbReserved 
= (BYTE
)0; 
 672 HPALETTE 
MakePalette(const BITMAPINFO FAR
* Info
, UINT flags
) 
 675   const RGBQUAD far
* rgb 
= Info
->bmiColors
; 
 677   WORD nColors 
= Info
->bmiHeader
.biClrUsed
; 
 679    LOGPALETTE
* logPal 
= (LOGPALETTE
*) 
 680      new BYTE
[sizeof(LOGPALETTE
) + (nColors
-1)*sizeof(PALETTEENTRY
)]; 
 682    logPal
->palVersion  
= 0x300; // Windows 3.0 version 
 683    logPal
->palNumEntries 
= nColors
; 
 684    for (short n 
= 0; n 
< nColors
; n
++) { 
 685     logPal
->palPalEntry
[n
].peRed   
= rgb
[n
].rgbRed
; 
 686     logPal
->palPalEntry
[n
].peGreen 
= rgb
[n
].rgbGreen
; 
 687     logPal
->palPalEntry
[n
].peBlue  
= rgb
[n
].rgbBlue
; 
 688     logPal
->palPalEntry
[n
].peFlags 
= (BYTE
)flags
; 
 690    hPalette 
= ::CreatePalette(logPal
);