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