|
|
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.