В свое время в msdn был такой пример для работы с dib
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. 269. 270. 271. 272. 273. 274. 275. 276. 277. 278. 279. 280. 281. 282. 283. 284. 285. 286. 287. 288. 289. 290. 291. 292. 293. 294. 295. 296. 297. 298. 299. 300. 301. 302. 303. 304. 305. 306. 307. 308. 309. 310. 311. 312. 313. 314. 315. 316. 317. 318. 319. 320. 321. 322. 323. 324. 325. 326. 327. 328. 329. 330. 331. 332. 333. 334. 335. 336. 337. 338. 339. 340. 341. 342. 343. 344. 345. 346. 347. 348. 349. 350. 351. 352. 353. 354. 355. 356. 357. 358. 359. 360. 361. 362. 363. 364. 365. 366. 367. 368. 369. 370. 371. 372. 373. 374. 375. 376. 377. 378. 379. 380. 381. 382. 383. 384. 385. 386. 387. 388. 389. 390. 391. 392. 393. 394. 395. 396. 397. 398. 399. 400. 401. 402. 403. 404. 405. 406. 407. 408. 409. 410. 411. 412. 413. 414. 415. 416. 417. 418. 419. 420. 421. 422. 423. 424. 425. 426. 427. 428. 429. 430. 431. 432. 433. 434. 435. 436. 437. 438. 439. 440. 441. 442. 443. 444. 445. 446. 447. 448. 449. 450. 451. 452. 453. 454. 455. 456. 457. 458. 459. 460. 461. 462. 463. 464. 465. 466. 467. 468. 469. 470. 471. 472. 473. 474. 475. 476. 477. 478. 479. 480. 481. 482. 483. 484. 485. 486. 487. 488. 489. 490. 491. 492. 493. 494. 495. 496. 497. 498. 499. 500. 501. 502. 503. 504. 505. 506. 507. 508. 509. 510. 511. 512. 513. 514. 515. 516. 517. 518. 519. 520. 521. 522. 523. 524. 525. 526. 527. 528. 529. 530. 531. 532. 533. 534. 535. 536. 537. 538. 539. 540. 541. 542. 543. 544. 545. 546. 547. 548. 549. 550. 551. 552. 553. 554. 555. 556. 557. 558. 559. 560. 561. 562. 563. 564. 565. 566. 567. 568. 569. 570. 571. 572. 573. 574. 575. 576. 577. 578. 579. 580. 581. 582. 583. 584. 585. 586. 587. 588. 589. 590. 591. 592. 593. 594. 595. 596. 597. 598. 599. 600. 601. 602. 603. 604. 605. 606. 607. 608. 609. 610. 611. 612. 613. 614. 615. 616. 617. 618. 619. 620. 621. 622. 623. 624. 625. 626. 627. 628. 629. 630. 631. 632. 633. 634. 635. 636. 637. 638. 639. 640. 641. 642. 643. 644. 645. 646. 647. 648. 649. 650. 651. 652. 653. 654. 655. 656. 657. 658. 659. 660. 661. 662. 663. 664. 665. 666. 667. 668. 669. 670. 671. 672. 673. 674. 675. 676. 677. 678. 679. 680. 681. 682. 683. 684. 685. 686. 687. 688. 689. 690. 691. 692. 693. 694. 695. 696. 697. 698. 699. 700. 701. 702. 703. 704. 705. 706. 707. 708. 709. 710. 711. 712. 713. 714. 715. 716. 717. 718. 719. 720. 721. 722. 723. 724. 725. 726. 727. 728. 729. 730. 731. 732. 733. 734. 735. 736. 737. 738. 739. 740. 741. 742. 743. 744. 745. 746. 747. 748. 749. 750. 751. 752. 753. 754. 755. 756. 757. 758. 759. 760. 761. 762. 763. 764. 765. 766. 767. 768. 769. 770. 771. 772. 773. 774. 775. 776. 777. 778. 779. 780. 781. 782. 783. 784. 785. 786. 787. 788. 789. 790. 791. 792. 793. 794. 795. 796. 797. 798. 799. 800. 801. 802. 803. 804. 805. 806. 807. 808. 809. 810. 811. 812. 813. 814. 815. 816. 817. 818. 819. 820. 821. 822. 823. 824. 825. 826. 827. 828. 829. 830. 831. 832. 833. 834. 835. 836. 837. 838. 839. 840. 841. 842. 843. 844. 845. 846. 847. 848. 849. 850. 851. 852. 853. 854. 855. 856. 857. 858. 859. 860. 861. 862. 863. 864. 865. 866. 867. 868. 869. 870. 871. 872. 873. 874. 875. 876. 877. 878. 879. 880. 881. 882. 883. 884. 885. 886. 887.
/******************************************************************************\
* This is a part of the Microsoft Source Code Samples.
* Copyright (C) 1993-1995 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/
/*******************************************************************************
* *
* MODULE : DIB.C *
* *
* DESCRIPTION : Routines for dealing with Device Independent Bitmaps. *
* *
* FUNCTIONS : OpenDIB() - Opens DIB file and creates a memory DIB*
* *
* WriteDIB() - Writes a global handle in CF_DIB format*
* to a file. *
* *
* DibInfo() - Retrieves the info. block associated *
* with a CF_DIB format memory block. *
* *
* CreateBIPalette() - Creates a GDI palette given a pointer *
* to a BITMAPINFO structure. *
* *
* CreateDibPalette() - Creates a GDI palette given a HANDLE *
* to a BITMAPINFO structure. *
* *
* ReadDibBitmapInfo() - Reads a file in DIB format and returns *
* a global handle to it's BITMAPINFO *
* *
* PaletteSize() - Calculates the palette size in bytes *
* of given DIB *
* *
* DibNumColors() - Determines the number of colors in DIB *
* *
* BitmapFromDib() - Creates a DDB given a global handle to *
* a block in CF_DIB format. *
* *
* DibFromBitmap() - Creates a DIB repr. the DDB passed in. *
* *
* DrawBitmap() - Draws a bitmap at specified position *
* in the DC. *
* *
* DibBlt() - Draws a bitmap in CIF_DIB format using *
* SetDIBitsToDevice() *
* *
* StretchDibBlt() - Draws a bitmap in CIF_DIB format using *
* StretchDIBits() *
* *
* *
*******************************************************************************/
#include "dib.h"
/****************************************************************************
* *
* FUNCTION :OpenDIB(LPSTR szFile) *
* *
* PURPOSE :Open a DIB file and create a MEMORY DIB, a memory handle *
* containing BITMAPINFO, palette data and the bits. *
* *
* RETURNS :A handle to the DIB. *
* *
****************************************************************************/
HANDLE OpenDIB (LPSTR szFile)
{
HFILE fh;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen = 0 ;
DWORD dwBits;
HANDLE hdib;
HANDLE h;
OFSTRUCT of;
/* Open the file and read the DIB information */
fh = OpenFile(szFile, &of, (UINT)OF_READ);
if (fh == - 1 )
return NULL;
hdib = ReadDibBitmapInfo(fh);
if (!hdib)
return NULL;
DibInfo(hdib,&bi);
/* Calculate the memory needed to hold the DIB */
dwBits = bi.biSizeImage;
dwLen = bi.biSize + (DWORD)PaletteSize (&bi) + dwBits;
/* Try to increase the size of the bitmap info. buffer to hold the DIB */
h = GlobalReAlloc(hdib, dwLen, GHND);
if (!h){
GlobalFree(hdib);
hdib = NULL;
}
else
hdib = h;
/* Read in the bits */
if (hdib){
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
_lread(fh, (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi), dwBits);
GlobalUnlock(hdib);
}
_lclose(fh);
return hdib;
}
/****************************************************************************
* *
* FUNCTION : WriteDIB(LPSTR szFile,HANDLE hdib) *
* *
* PURPOSE : Write a global handle in CF_DIB format to a file. *
* *
* RETURNS : TRUE - if successful. *
* FALSE - otherwise *
* *
****************************************************************************/
BOOL WriteDIB (
LPSTR szFile,
HANDLE hdib)
{
BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER lpbi;
HFILE fh;
OFSTRUCT of;
if (!hdib)
return FALSE;
fh = OpenFile(szFile, &of, (UINT)OF_CREATE|OF_READWRITE);
if (fh == - 1 )
return FALSE;
lpbi = (LPBITMAPINFOHEADER)GlobalLock (hdib);
/* Fill in the fields of the file header */
hdr.bfType = BFT_BITMAP;
hdr.bfSize = GlobalSize (hdib) + SIZEOF_BITMAPFILEHEADER_PACKED;
hdr.bfReserved1 = 0 ;
hdr.bfReserved2 = 0 ;
hdr.bfOffBits = (DWORD) (SIZEOF_BITMAPFILEHEADER_PACKED + lpbi->biSize +
PaletteSize(lpbi));
#if defined(_MAC)
// swap the struct members around so they're the right order
// when on disk.
//
hdr.bfType = SWAPWORD(hdr.bfType);
hdr.bfSize = SWAPLONG(hdr.bfSize);
hdr.bfReserved1 = SWAPWORD(hdr.bfReserved1);
hdr.bfReserved2 = SWAPWORD(hdr.bfReserved2);
hdr.bfOffBits = SWAPLONG(hdr.bfOffBits);
lpbi->biSize = SWAPLONG(lpbi->biSize);
lpbi->biWidth = SWAPLONG(lpbi->biWidth);
lpbi->biHeight = SWAPLONG(lpbi->biHeight);
lpbi->biPlanes = SWAPWORD(lpbi->biPlanes);
lpbi->biBitCount = SWAPWORD(lpbi->biBitCount);
lpbi->biCompression = SWAPLONG(lpbi->biCompression);
lpbi->biSizeImage = SWAPLONG(lpbi->biSizeImage);
lpbi->biXPelsPerMeter = SWAPLONG(lpbi->biXPelsPerMeter);
lpbi->biYPelsPerMeter = SWAPLONG(lpbi->biYPelsPerMeter);
lpbi->biClrUsed = SWAPLONG(lpbi->biClrUsed);
lpbi->biClrImportant = SWAPLONG(lpbi->biClrImportant);
#endif
%af_src_comm_9
#ifdef FIXDWORDALIGNMENT
_lwrite(fh, (LPSTR)&hdr, (UINT)(SIZEOF_BITMAPFILEHEADER_PACKED));
#else
WriteMapFileHeaderandConvertFromDwordAlignToPacked(fh, &hdr);
#endif
%af_src_comm_10
%af_src_comm_11
_lwrite (fh, (LPSTR)lpbi, GlobalSize (hdib));
GlobalUnlock (hdib);
_lclose(fh);
return TRUE;
}
%af_src_comm_12
BOOL DibInfo (
HANDLE hbi,
LPBITMAPINFOHEADER lpbi)
{
if (hbi){
*lpbi = *(LPBITMAPINFOHEADER)GlobalLock (hbi);
%af_src_comm_13
if (lpbi->biSize != sizeof (BITMAPCOREHEADER)){
if (lpbi->biSizeImage == 0L)
lpbi->biSizeImage = WIDTHBYTES(lpbi->biWidth*lpbi->biBitCount) * lpbi->biHeight;
if (lpbi->biClrUsed == 0L)
lpbi->biClrUsed = DibNumColors (lpbi);
}
GlobalUnlock (hbi);
return TRUE;
}
return FALSE;
}
%af_src_comm_14
HPALETTE CreateBIPalette (LPBITMAPINFOHEADER lpbi)
{
LOGPALETTE *pPal;
HPALETTE hpal = NULL;
WORD nNumColors;
BYTE red;
BYTE green;
BYTE blue;
WORD i;
RGBQUAD *pRgb;
if (!lpbi)
return NULL;
if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
return NULL;
%af_src_comm_15
pRgb = (RGBQUAD *)((LPSTR)lpbi + (WORD)lpbi->biSize);
nNumColors = DibNumColors(lpbi);
if (nNumColors){
%af_src_comm_16
pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
if (!pPal)
return NULL;
pPal->palNumEntries = nNumColors;
pPal->palVersion = PALVERSION;
%af_src_comm_17
for (i = 0; i < nNumColors; i++){
pPal->palPalEntry[i].peRed = pRgb[i].rgbRed;
pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen;
pPal->palPalEntry[i].peBlue = pRgb[i].rgbBlue;
pPal->palPalEntry[i].peFlags = (BYTE)0;
}
hpal = CreatePalette(pPal);
LocalFree((HANDLE)pPal);
}
else if (lpbi->biBitCount == 24){
%af_src_comm_18
nNumColors = MAXPALETTE;
pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
if (!pPal)
return NULL;
pPal->palNumEntries = nNumColors;
pPal->palVersion = PALVERSION;
red = green = blue = 0;
%af_src_comm_19
for (i = 0; i < pPal->palNumEntries; i++){
pPal->palPalEntry[i].peRed = red;
pPal->palPalEntry[i].peGreen = green;
pPal->palPalEntry[i].peBlue = blue;
pPal->palPalEntry[i].peFlags = (BYTE)0;
if (!(red += 32))
if (!(green += 32))
blue += 64;
}
hpal = CreatePalette(pPal);
LocalFree((HANDLE)pPal);
}
return hpal;
}
%af_src_comm_20
HPALETTE CreateDibPalette (HANDLE hbi)
{
HPALETTE hpal;
if (!hbi)
return NULL;
hpal = CreateBIPalette((LPBITMAPINFOHEADER)GlobalLock(hbi));
GlobalUnlock(hbi);
return hpal;
}
%af_src_comm_21
HANDLE ReadDibBitmapInfo (HFILE fh)
{
DWORD off;
HANDLE hbi = NULL;
int size;
int i;
WORD nNumColors;
RGBQUAD *pRgb;
BITMAPINFOHEADER bi;
BITMAPCOREHEADER bc;
BITMAPINFOHEADER *lpbi;
BITMAPFILEHEADER bf;
DWORD dwWidth = 0;
DWORD dwHeight = 0;
WORD wPlanes, wBitCount;
// Reset file pointer and read file header
off = _llseek(fh, 0L, SEEK_CUR);
if (sizeof(bf) != _lread(fh, (LPSTR)&bf, sizeof(bf)))
{
return NULL;
}
// Do we have a RC HEADER?
if (!ISDIB (bf.bfType))
{
bf.bfOffBits = 0L;
_llseek(fh, off, SEEK_SET);
}
if (sizeof(bi) != _lread(fh, (LPSTR)&bi, sizeof(bi)))
{
return NULL;
}
nNumColors = DibNumColors((void *)&bi);
// Check the nature (BITMAPINFO or BITMAPCORE) of the info. block
// and extract the field information accordingly. If a BITMAPCOREHEADER,
// transfer it's field information to a BITMAPINFOHEADER-style block
switch (size = (int)bi.biSize)
{
case sizeof(BITMAPINFOHEADER):
break;
case sizeof(BITMAPCOREHEADER):
bc = *(BITMAPCOREHEADER *)&bi;
dwWidth = (DWORD)bc.bcWidth; // width in pixels
dwHeight = (DWORD)bc.bcHeight; // height in pixels
wPlanes = bc.bcPlanes; // # of planes. Always 1 for DIB
wBitCount = bc.bcBitCount; // color bits per pixel.
bi.biSize = sizeof(BITMAPINFOHEADER); // size of this structure
bi.biWidth = dwWidth;
bi.biHeight = dwHeight;
bi.biPlanes = wPlanes;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB; // no compression
bi.biSizeImage = 0 ; // 0 == default size
bi.biXPelsPerMeter = 0 ; // not used for this app
bi.biYPelsPerMeter = 0 ; // not used for this app
bi.biClrUsed = nNumColors; // # of colors used.
bi.biClrImportant = nNumColors; // # of important colors
_llseek(fh, (LONG)sizeof(BITMAPCOREHEADER) - sizeof(BITMAPINFOHEADER), SEEK_CUR);
break;
default:
{
return NULL;
}
}
// Fill in some default values if they are zero
if (bi.biSizeImage == 0 ) // compute size of the image
bi.biSizeImage = WIDTHBYTES ((DWORD)bi.biWidth * bi.biBitCount) * bi.biHeight;
if (bi.biClrUsed == 0 ) // compute the # of colors used
bi.biClrUsed = DibNumColors((LPSTR)&bi);
// Allocate for the BITMAPINFO structure and the color table.
hbi = GlobalAlloc(GHND, (LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
if (hbi == NULL)
{
return NULL;
}
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hbi);
*lpbi = bi;
// Get a pointer to the color table
pRgb = (RGBQUAD *)((LPSTR)lpbi + bi.biSize);
if (nNumColors)
{
if (size == sizeof(BITMAPCOREHEADER))
{
// Convert a old color table (3 byte RGBTRIPLEs) to a new
// color table (4 byte RGBQUADs)
_lread(fh, (LPSTR)pRgb, nNumColors * sizeof(RGBTRIPLE));
for (i = nNumColors - 1 ; i >= 0 ; i--)
{
RGBQUAD rgb;
rgb.rgbRed = ((RGBTRIPLE *)pRgb)[i].rgbtRed;
rgb.rgbBlue = ((RGBTRIPLE *)pRgb)[i].rgbtBlue;
rgb.rgbGreen = ((RGBTRIPLE *)pRgb)[i].rgbtGreen;
rgb.rgbReserved = (BYTE) 0 ;
pRgb[i] = rgb;
}
}
else
_lread(fh, (LPSTR)pRgb, nNumColors * sizeof(RGBQUAD));
}
if (bf.bfOffBits != 0L)
_llseek(fh, off + bf.bfOffBits, SEEK_SET);
GlobalUnlock(hbi);
return hbi;
}
/****************************************************************************
* *
* FUNCTION : PaletteSize(VOID * pv) *
* *
* PURPOSE : Calculates the palette size in bytes. If the info. block *
* is of the BITMAPCOREHEADER type, the number of colors is *
* multiplied by 3 to give the palette size, otherwise the *
* number of colors is multiplied by 4. *
* *
* RETURNS : Palette size in number of bytes. *
* *
****************************************************************************/
WORD PaletteSize (VOID * pv)
{
LPBITMAPINFOHEADER lpbi;
WORD NumColors;
lpbi = (LPBITMAPINFOHEADER)pv;
NumColors = DibNumColors(lpbi);
if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
return (WORD)(NumColors * sizeof(RGBTRIPLE));
else
return (WORD)(NumColors * sizeof(RGBQUAD));
}
/****************************************************************************
* *
* FUNCTION : DibNumColors(VOID * pv) *
* *
* PURPOSE : Determines the number of colors in the DIB by looking at *
* the BitCount filed in the info block. *
* *
* RETURNS : The number of colors in the DIB. *
* *
****************************************************************************/
WORD DibNumColors (void *pv)
{
INT bits;
LPBITMAPINFOHEADER lpbi;
LPBITMAPCOREHEADER lpbc;
lpbi = ((LPBITMAPINFOHEADER)pv);
lpbc = ((LPBITMAPCOREHEADER)pv);
/* With the BITMAPINFO format headers, the size of the palette
* is in biClrUsed, whereas in the BITMAPCORE - style headers, it
* is dependent on the bits per pixel ( = 2 raised to the power of
* bits/pixel).
*/
if (lpbi->biSize != sizeof(BITMAPCOREHEADER)){
if (lpbi->biClrUsed != 0 )
return (WORD)lpbi->biClrUsed;
bits = lpbi->biBitCount;
}
else
bits = lpbc->bcBitCount;
switch (bits){
case 1 :
return 2 ;
case 4 :
return 16 ;
case 8 :
return 256 ;
default:
/* A 24 bitcount DIB has no color table */
return 0 ;
}
}
/****************************************************************************
* *
* FUNCTION : DibFromBitmap() *
* *
* PURPOSE : Will create a global memory block in DIB format that *
* represents the Device-dependent bitmap (DDB) passed in. *
* *
* RETURNS : A handle to the DIB *
* *
****************************************************************************/
HANDLE DibFromBitmap (
HBITMAP hbm,
DWORD biStyle,
WORD biBits,
HPALETTE hpal)
{
BITMAP bm;
BITMAPINFOHEADER bi;
BITMAPINFOHEADER *lpbi;
DWORD dwLen;
HANDLE hdib;
HANDLE h;
HDC hdc;
if (!hbm)
return NULL;
if (hpal == NULL)
hpal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
GetObject(hbm,sizeof(bm),(LPSTR)&bm);
if (biBits == 0 )
biBits = bm.bmPlanes * bm.bmBitsPixel;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1 ;
bi.biBitCount = biBits;
bi.biCompression = biStyle;
bi.biSizeImage = 0 ;
bi.biXPelsPerMeter = 0 ;
bi.biYPelsPerMeter = 0 ;
bi.biClrUsed = 0 ;
bi.biClrImportant = 0 ;
dwLen = bi.biSize + PaletteSize(&bi);
hdc = GetDC(NULL);
hpal = SelectPalette(hdc,hpal,FALSE);
RealizePalette(hdc);
hdib = GlobalAlloc(GHND,dwLen);
if (!hdib){
SelectPalette(hdc,hpal,FALSE);
ReleaseDC(NULL,hdc);
return NULL;
}
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
*lpbi = bi;
/* call GetDIBits with a NULL lpBits param, so it will calculate the
* biSizeImage field for us
*/
GetDIBits(hdc, hbm, 0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
bi = *lpbi;
GlobalUnlock(hdib);
/* If the driver did not fill in the biSizeImage field, make one up */
if (bi.biSizeImage == 0 ){
bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
if (biStyle != BI_RGB)
bi.biSizeImage = (bi.biSizeImage * 3 ) / 2 ;
}
/* realloc the buffer big enough to hold all the bits */
dwLen = bi.biSize + PaletteSize(&bi) + bi.biSizeImage;
if (h = GlobalReAlloc(hdib,dwLen, 0 ))
hdib = h;
else{
GlobalFree(hdib);
hdib = NULL;
SelectPalette(hdc,hpal,FALSE);
ReleaseDC(NULL,hdc);
return hdib;
}
/* call GetDIBits with a NON-NULL lpBits param, and actualy get the
* bits this time
*/
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
if (GetDIBits( hdc,
hbm,
0L,
(DWORD)bi.biHeight,
(LPBYTE)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi),
(LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS) == 0 ){
GlobalUnlock(hdib);
hdib = NULL;
SelectPalette(hdc,hpal,FALSE);
ReleaseDC(NULL,hdc);
return NULL;
}
bi = *lpbi;
GlobalUnlock(hdib);
SelectPalette(hdc,hpal,FALSE);
ReleaseDC(NULL,hdc);
return hdib;
}
/****************************************************************************
* *
* FUNCTION : BitmapFromDib(HANDLE hdib, HPALETTE hpal) *
* *
* PURPOSE : Will create a DDB (Device Dependent Bitmap) given a global *
* handle to a memory block in CF_DIB format *
* *
* RETURNS : A handle to the DDB. *
* *
****************************************************************************/
HBITMAP BitmapFromDib (
HANDLE hdib,
HPALETTE hpal)
{
LPBITMAPINFOHEADER lpbi;
HPALETTE hpalT;
HDC hdc;
HBITMAP hbm;
if (!hdib)
return NULL;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
if (!lpbi)
return NULL;
hdc = GetDC(NULL);
if (hpal){
hpalT = SelectPalette(hdc,hpal,FALSE);
RealizePalette(hdc); // GDI Bug...????
}
hbm = CreateDIBitmap(hdc,
(LPBITMAPINFOHEADER)lpbi,
(LONG)CBM_INIT,
(LPSTR)lpbi + lpbi->biSize + PaletteSize(lpbi),
(LPBITMAPINFO)lpbi,
DIB_RGB_COLORS );
if (hpal)
SelectPalette(hdc,hpalT,FALSE);
ReleaseDC(NULL,hdc);
GlobalUnlock(hdib);
return hbm;
}
/****************************************************************************
* *
* FUNCTION : DrawBitmap(HDC hdc, int x, int y, HBITMAP hbm, DWORD rop) *
* *
* PURPOSE : Draws bitmap <hbm> at the specifed position in DC <hdc> *
* *
* RETURNS : Return value of BitBlt() *
* *
****************************************************************************/
BOOL DrawBitmap (
HDC hdc,
INT x,
INT y,
HBITMAP hbm,
DWORD rop)
{
HDC hdcBits;
BITMAP bm;
// HPALETTE hpalT;
BOOL f;
if (!hdc || !hbm)
return FALSE;
// Made this code a little more robust
// by checking the results of a few calls.
// memory, esp on the mac, can get sucked
// up really fast and make these fail
// 2-9-94 Garth Brown
//
if(hdcBits = CreateCompatibleDC(hdc))
{
if(GetObject(hbm,sizeof(BITMAP),(LPSTR)&bm) != 0 )
{
HGDIOBJ hObj;
hObj = SelectObject(hdcBits,hbm);
if ((hObj != NULL) && (hObj != (HGDIOBJ)GDI_ERROR))
{
f = BitBlt(hdc, 0 , 0 ,bm.bmWidth,bm.bmHeight,hdcBits, 0 , 0 ,rop);
}
else
{
// most likely to fail, so we'll put a message box here
//
MessageBox(NULL, "Select Object failed: out of memory?",
"Error Selecting Bitmap!", MB_OK);
return(FALSE);
}
}
DeleteDC(hdcBits);
}
return f;
UNREFERENCED_PARAMETER(y);
UNREFERENCED_PARAMETER(x);
}
/****************************************************************************
* *
* FUNCTION : DibBlt( HDC hdc, *
* int x0, int y0, *
* int dx, int dy, *
* HANDLE hdib, *
* int x1, int y1, *
* LONG rop) *
* *
* PURPOSE : Draws a bitmap in CF_DIB format, using SetDIBits to device.*
* taking the same parameters as BitBlt(). *
* *
* RETURNS : TRUE - if function succeeds. *
* FALSE - otherwise. *
* *
****************************************************************************/
BOOL DibBlt (
HDC hdc,
INT x0,
INT y0,
INT dx,
INT dy,
HANDLE hdib,
INT x1,
INT y1,
LONG rop)
{
LPBITMAPINFOHEADER lpbi;
// HPALETTE hpal,hpalT;
LPSTR pBuf;
// HDC hdcMem;
// HBITMAP hbm,hbmT;
if (!hdib)
return PatBlt(hdc,x0,y0,dx,dy,rop);
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
if (!lpbi)
return FALSE;
pBuf = (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi);
SetDIBitsToDevice (hdc, x0, y0, dx, dy,
x1,y1,
x1,
dy,
pBuf, (LPBITMAPINFO)lpbi,
DIB_RGB_COLORS );
GlobalUnlock(hdib);
return TRUE;
}
/****************************************************************************
* *
* FUNCTION : StretchDibBlt( HDC hdc, *
* int x, int y, *
* int dx, int dy, *
* HANDLE hdib, *
* int x0, int y0, *
* int dx0, int dy0, *
* LONG rop) *
* *
* PURPOSE : Draws a bitmap in CF_DIB format, using StretchDIBits() *
* taking the same parameters as StretchBlt(). *
* *
* RETURNS : TRUE - if function succeeds. *
* FALSE - otherwise. *
* *
****************************************************************************/
BOOL StretchDibBlt (
HDC hdc,
INT x,
INT y,
INT dx,
INT dy,
HANDLE hdib,
INT x0,
INT y0,
INT dx0,
INT dy0,
LONG rop)
{
LPBITMAPINFOHEADER lpbi;
LPSTR pBuf;
BOOL f;
if (!hdib)
return PatBlt(hdc,x,y,dx,dy,rop);
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
if (!lpbi)
return FALSE;
pBuf = (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi);
SetStretchBltMode(hdc,COLORONCOLOR);
f = StretchDIBits ( hdc,
x, y,
dx, dy,
x0, y0,
dx0, dy0,
pBuf, (LPBITMAPINFO)lpbi,
DIB_RGB_COLORS,
rop);
GlobalUnlock(hdib);
return f;
}
/****************************************************************************
* *
* FUNCTION : ReadBitMapFileHeaderandConvertToDwordAlign(HFILE fh, LPBITMAPFILEHEADER pbf)
* *
* PURPOSE : read file header (which is packed) and convert into unpacked BITMAPFILEHEADER strucutre
* *
* RETURNS : VOID
* *
****************************************************************************/
VOID ReadBitMapFileHeaderandConvertToDwordAlign(HFILE fh, LPBITMAPFILEHEADER pbf, LPDWORD lpdwoff)
{
DWORD off;
off = _llseek(fh, 0L, (UINT) SEEK_CUR);
*lpdwoff = off;
/* BITMAPFILEHEADER STRUCUTURE is as follows
* BITMAPFILEHEADER
* WORD bfType
> .... < add WORD if packed here!
* DWORD bfSize
* WORD bfReserved1
* WORD bfReserved2
* DWORD bfOffBits
* This is the packed format, unpacked adds a WORD after bfType
*/
/* read in bfType*/
_lread(fh, (LPSTR) &pbf->bfType, sizeof(WORD));
/* read in last 3 dwords*/
_lread(fh, (LPSTR) &pbf->bfSize, sizeof(DWORD) * 3 );
}
/****************************************************************************
* *
* FUNCTION : WriteMapFileHeaderandConvertFromDwordAlignToPacked(HFILE fh, LPBITMAPFILEHEADER pbf)
* *
* PURPOSE : write header structure (which NOT packed) and write it PACKED
* *
* RETURNS : VOID
* *
****************************************************************************/
VOID WriteMapFileHeaderandConvertFromDwordAlignToPacked(HFILE fh, LPBITMAPFILEHEADER pbf)
{
/* write bfType*/
_lwrite(fh, (LPSTR)&pbf->bfType, (UINT)sizeof (WORD));
/* now pass over extra word, and only write next 3 DWORDS!*/
_lwrite(fh, (LPSTR)&pbf->bfSize, sizeof(DWORD) * 3 );
}
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35.
HANDLE OpenDIB (LPSTR szFile);
BOOL WriteDIB (LPSTR szFile,HANDLE hdib);
WORD PaletteSize (VOID * pv);
WORD DibNumColors (void *pv);
HPALETTE CreateDibPalette (HANDLE hdib);
HPALETTE CreateBIPalette (LPBITMAPINFOHEADER lpbi);
HANDLE DibFromBitmap (HBITMAP hbm, DWORD biStyle, WORD biBits, HPALETTE hpal);
HBITMAP BitmapFromDib (HANDLE hdib, HPALETTE hpal);
BOOL DibBlt (HDC hdc, INT x0, INT y0, INT dx, INT dy, HANDLE hdib, INT x1, INT y1, LONG rop);
BOOL StretchDibBlt (HDC hdc, INT x0, INT y0, INT dx, INT dy, HANDLE hdib, INT x1, INT y1, INT dx1, INT dy1, LONG rop);
BOOL DibInfo (HANDLE hdib,LPBITMAPINFOHEADER lpbi);
HANDLE ReadDibBitmapInfo (INT fh);
BOOL DrawBitmap (HDC hdc, INT x, INT y, HBITMAP hbm, DWORD rop);
VOID ReadBitMapFileHeaderandConvertToDwordAlign(HFILE fh, LPBITMAPFILEHEADER pbf, LPDWORD lpdwoff);
VOID WriteMapFileHeaderandConvertFromDwordAlignToPacked(HFILE fh, LPBITMAPFILEHEADER pbf);
#define SIZEOF_BITMAPFILEHEADER_PACKED ( \
sizeof(WORD) + /* bfType */ \
sizeof(DWORD) + /* bfSize */ \
sizeof(WORD) + /* bfReserved1 */ \
sizeof(WORD) + /* bfReserved2 */ \
sizeof(DWORD)) /* bfOffBits */
#define BFT_ICON 0x4349 /* 'IC' */
#define BFT_BITMAP 0x4d42 /* 'BM' */
#define BFT_CURSOR 0x5450 /* 'PT' */
#define WIDTHBYTES(i) ((i+ 31 )/ 32 * 4 )
#define PALVERSION 0x300
#define MAXPALETTE 256 /* max. # supported palette entries */
#define ISDIB(bft) ((bft) == BFT_BITMAP)
|