|
|
1.1 root 1: /******************************Module*Header*******************************\
2: * Module Name: savebmp.c
3: *
4: *
5: * Created: 06-Jan-1992 10:59:36
6: * Author: Petrus Wong
7: *
8: * Copyright (c) 1990 Microsoft Corporation
9: *
10: * Contains the main routine, SaveBitmapFile, for saving a DDB into file
11: * in DIB format.
12: *
13: * Dependencies:
14: *
15: * (#defines)
16: * (#includes)
17: * #include <windows.h>
18: * #include "jtypes.h"
19: *
20: \**************************************************************************/
21: #include <windows.h>
22: #include "jtypes.h"
23:
1.1.1.3 ! root 24: extern HPALETTE ghPal;
1.1 root 25: extern HWND ghwndMain;
26: extern char gtext[256];
27: BOOL SaveBitmapFile(HDC, HBITMAP, PSTR);
28: void ErrorOut(char errstring[30]);
29:
30: /******************************Public*Routine******************************\
31: * SaveBitmapFile
32: *
33: *
34: * Effects: Save pInfo->hBmpSaved into disk specified by pszFileName
35: *
36: * Warnings: assumes hBmpSaved is not selected into window's DC other than
37: * pInfo->hwnd's DC
38: *
39: * History:
40: * 14-Jan-1992 -by- Petrus Wong
41: * Wrote it.
42: \**************************************************************************/
43:
44: BOOL SaveBitmapFile(HDC hDC, HBITMAP hBmp, PSTR pszFileName)
45: {
46: int hFile;
47: OFSTRUCT ofReOpenBuff;
48: HBITMAP hTmpBmp, hBmpOld;
49: BOOL bSuccess;
50: BITMAPFILEHEADER bfh;
51: PBITMAPINFO pbmi;
52: PBYTE pBits;
53: BITMAPINFO bmi;
54: PBYTE pjTmp, pjTmpBmi;
55: ULONG sizBMI;
56:
57:
58: bSuccess = TRUE;
1.1.1.3 ! root 59: #if 0
! 60: if (ghPal) {
! 61: SelectPalette(hDC, ghPal, FALSE);
! 62: RealizePalette(hDC);
! 63: }
! 64: #endif
1.1 root 65: if (!hBmp) {
66: MessageBox(ghwndMain, "There's no Bitmap to save!", "Error", MB_OK);
67: return FALSE;
68: }
69:
70: //
71: // Let the graphics engine to retrieve the dimension of the bitmap for us
72: // GetDIBits uses the size to determine if it's BITMAPCOREINFO or BITMAPINFO
73: // if BitCount != 0, color table will be retrieved
74: //
75: bmi.bmiHeader.biSize = 0x28; // GDI need this to work
76: bmi.bmiHeader.biBitCount = 0; // don't get the color table
77: if ((GetDIBits(hDC, hBmp, 0, 0, (LPSTR)NULL, &bmi, DIB_RGB_COLORS)) == 0) {
78: MessageBox(ghwndMain, "GetDIBits failed!", "Error", MB_OK);
79: return FALSE;
80: }
81:
82: //
83: // Now that we know the size of the image, alloc enough memory to retrieve
84: // the actual bits
85: //
86: if ((pBits = (PBYTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
1.1.1.2 root 87: bmi.bmiHeader.biSizeImage)) == NULL) {
1.1 root 88: MessageBox(ghwndMain, "Failed in Memory Allocation for pBits!", "Error", MB_OK);
89: return FALSE;
90: }
91:
92: //
93: // Note: 24 bits per pixel has no color table. So, we don't have to
94: // allocate memory for retrieving that. Otherwise, we do.
95: //
96: pbmi = &bmi; // assume no color table
1.1.1.3 ! root 97:
! 98: switch (bmi.bmiHeader.biBitCount) {
! 99: case 24: // has color table
! 100: sizBMI = sizeof(BITMAPINFOHEADER);
! 101: break;
! 102: case 16:
! 103: case 32:
! 104: sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*3;
! 105: break;
! 106: default:
! 107: sizBMI = sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*(1<<bmi.bmiHeader.biBitCount);
! 108: break;
! 109:
! 110: }
! 111:
! 112: //
! 113: // Allocate memory for color table if it is not 24bpp...
! 114: //
! 115: if (sizBMI != sizeof(BITMAPINFOHEADER)) {
! 116: ULONG sizTmp;
1.1 root 117: //
118: // I need more memory for the color table
119: //
120: if ((pbmi = (PBITMAPINFO)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizBMI )) == NULL) {
121: MessageBox(ghwndMain, "Failed in Memory Allocation for pbmi!", "Error", MB_OK);
122: bSuccess = FALSE;
123: goto ErrExit1;
124: }
125: //
126: // Now that we've a bigger chunk of memory, let's copy the Bitmap
127: // info header data over
128: //
129: pjTmp = (PBYTE)pbmi;
130: pjTmpBmi = (PBYTE)&bmi;
1.1.1.3 ! root 131: sizTmp = sizeof(BITMAPINFOHEADER);
1.1 root 132:
1.1.1.3 ! root 133: while(sizTmp--)
1.1 root 134: {
135: *(((PBYTE)pjTmp)++) = *((pjTmpBmi)++);
136: }
137: }
138:
139: //
140: // Let's open the file and get ready for writing
141: //
142: if ((hFile = OpenFile(pszFileName, (LPOFSTRUCT)&ofReOpenBuff,
143: OF_CREATE | OF_WRITE)) == -1) {
144: MessageBox(ghwndMain, "Failed in OpenFile!", "Error", MB_OK);
145: ErrorOut("OpenFile");
146: goto ErrExit2;
147: }
148:
149: //
150: // But first, fill in the info for the BitmapFileHeader
151: //
152: bfh.bfType = 0x4D42; // 'BM'
1.1.1.3 ! root 153: bfh.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizBMI+
1.1 root 154: pbmi->bmiHeader.biSizeImage;
155: bfh.bfReserved1 =
156: bfh.bfReserved2 = 0;
1.1.1.3 ! root 157: bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizBMI;
1.1 root 158:
159: //
160: // Write out the file header now
161: //
162: if (_lwrite(hFile, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER)) == -1) {
163: MessageBox(ghwndMain, "Failed in WriteFile!", "Error", MB_OK);
164: bSuccess = FALSE;
165: goto ErrExit3;
166: }
167:
168: //
169: // Bitmap can't be selected into a DC when calling GetDIBits
170: // Assume that the hDC is the DC where the bitmap would have been selected
171: // if indeed it has been selected
172: //
173: if (hTmpBmp = CreateCompatibleBitmap(hDC, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight)) {
174: hBmpOld = SelectObject(hDC, hTmpBmp);
175: if ((GetDIBits(hDC, hBmp, 0, pbmi->bmiHeader.biHeight, (LPSTR)pBits, pbmi, DIB_RGB_COLORS))==0){
176: MessageBox(ghwndMain, "Failed in GetDIBits!", "Error", MB_OK);
177: bSuccess = FALSE;
178: goto ErrExit4;
179: }
180: } else {
181: MessageBox(ghwndMain, "Failed in creating bitmap!", "Error", MB_OK);
182: bSuccess = FALSE;
183: goto ErrExit3;
184: }
185:
186: //
187: // Now write out the BitmapInfoHeader and color table, if any
188: //
1.1.1.3 ! root 189: if (_lwrite(hFile, (LPSTR)pbmi, sizBMI) == -1) {
1.1 root 190: MessageBox(ghwndMain, "Failed in WriteFile!", "Error", MB_OK);
191: bSuccess = FALSE;
192: goto ErrExit4;
193: }
194:
195: //
196: // write the bits also
197: //
198: if (_lwrite(hFile, (LPSTR)pBits, pbmi->bmiHeader.biSizeImage) == -1) {
199: MessageBox(ghwndMain, "Failed in WriteFile!", "Error", MB_OK);
200: bSuccess = FALSE;
201: goto ErrExit4;
202: }
203:
1.1.1.3 ! root 204:
1.1 root 205: ErrExit4:
206: SelectObject(hDC, hBmpOld);
207: DeleteObject(hTmpBmp);
208: ErrExit3:
209: _lclose(hFile);
210: ErrExit2:
211: GlobalFree(pbmi);
212: ErrExit1:
213: GlobalFree(pBits);
214: return bSuccess;
215: }
216:
217: /************************************************************************
218: * void ErrorOut(char errstring[30])
219: *
220: * Purpose: Print out an meainful error code by means of
221: * GetLastError and printf
222: *
223: * Inputs: errstring - the action that failed, passed by the
224: * calling proc.
225: *
226: * Returns: none
227: *
228: * Calls: GetLastError
229: *
230: * History:
231: * 09-13-91 Pete Grey Created.
232: *
233: \************************************************************************/
234:
235:
236: void ErrorOut(char errstring[30])
237: {
238: DWORD Error;
239: CHAR str[80];
240:
241: Error= GetLastError();
242: wsprintf((LPSTR) str, "Error on %s = %d\n", errstring, Error);
243: MessageBox(ghwndMain, (LPSTR)str, "Error", MB_OK);
244: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.