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