|
|
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:
24:
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;
59: if (!hBmp) {
60: MessageBox(ghwndMain, "There's no Bitmap to save!", "Error", MB_OK);
61: return FALSE;
62: }
63:
64: //
65: // Let the graphics engine to retrieve the dimension of the bitmap for us
66: // GetDIBits uses the size to determine if it's BITMAPCOREINFO or BITMAPINFO
67: // if BitCount != 0, color table will be retrieved
68: //
69: bmi.bmiHeader.biSize = 0x28; // GDI need this to work
70: bmi.bmiHeader.biBitCount = 0; // don't get the color table
71: if ((GetDIBits(hDC, hBmp, 0, 0, (LPSTR)NULL, &bmi, DIB_RGB_COLORS)) == 0) {
72: MessageBox(ghwndMain, "GetDIBits failed!", "Error", MB_OK);
73: return FALSE;
74: }
75:
76: //
77: // Now that we know the size of the image, alloc enough memory to retrieve
78: // the actual bits
79: //
80: if ((pBits = (PBYTE)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,
81: bmi.bmiHeader.biWidth * bmi.bmiHeader.biHeight)) == NULL) {
82: MessageBox(ghwndMain, "Failed in Memory Allocation for pBits!", "Error", MB_OK);
83: return FALSE;
84: }
85:
86: //
87: // Note: 24 bits per pixel has no color table. So, we don't have to
88: // allocate memory for retrieving that. Otherwise, we do.
89: //
90: pbmi = &bmi; // assume no color table
91: if (bmi.bmiHeader.biBitCount != 24) { // has color table
92: sizBMI = sizeof(BITMAPINFO)+sizeof(RGBQUAD)*(1<<bmi.bmiHeader.biBitCount);
93: //
94: // I need more memory for the color table
95: //
96: if ((pbmi = (PBITMAPINFO)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizBMI )) == NULL) {
97: MessageBox(ghwndMain, "Failed in Memory Allocation for pbmi!", "Error", MB_OK);
98: bSuccess = FALSE;
99: goto ErrExit1;
100: }
101: #if 0
102: pbmi->bmiHeader.biSize = bmi.bmiHeader.biSize;
103: pbmi->bmiHeader.biWidth = bmi.bmiHeader.biWidth;
104: pbmi->bmiHeader.biHeight = bmi.bmiHeader.biHeight;
105: pbmi->bmiHeader.biPlanes = bmi.bmiHeader.biPlanes;
106: pbmi->bmiHeader.biBitCount = bmi.bmiHeader.biBitCount;
107: pbmi->bmiHeader.biCompression = bmi.bmiHeader.biCompression;
108: pbmi->bmiHeader.biSizeImage = bmi.bmiHeader.biSizeImage;
109: pbmi->bmiHeader.biXPelsPerMeter = bmi.bmiHeader.biXPelsPerMeter;
110: pbmi->bmiHeader.biYPelsPerMeter = bmi.bmiHeader.biYPelsPerMeter;
111: pbmi->bmiHeader.biClrUsed = bmi.bmiHeader.biClrUsed;
112: pbmi->bmiHeader.biClrImportant = bmi.bmiHeader.biClrImportant;
113: #endif
114: //
115: // Now that we've a bigger chunk of memory, let's copy the Bitmap
116: // info header data over
117: //
118: pjTmp = (PBYTE)pbmi;
119: pjTmpBmi = (PBYTE)&bmi;
120: sizBMI = sizeof(BITMAPINFOHEADER);
121:
122: while(sizBMI--)
123: {
124: *(((PBYTE)pjTmp)++) = *((pjTmpBmi)++);
125: }
126:
127: }
128:
129: //
130: // Let's open the file and get ready for writing
131: //
132: if ((hFile = OpenFile(pszFileName, (LPOFSTRUCT)&ofReOpenBuff,
133: OF_CREATE | OF_WRITE)) == -1) {
134: MessageBox(ghwndMain, "Failed in OpenFile!", "Error", MB_OK);
135: ErrorOut("OpenFile");
136: goto ErrExit2;
137: }
138:
139: //
140: // But first, fill in the info for the BitmapFileHeader
141: //
142: bfh.bfType = 0x4D42; // 'BM'
143: bfh.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*
144: ((pbmi->bmiHeader.biBitCount == 24) ? 0 : (1<<pbmi->bmiHeader.biBitCount))+
145: pbmi->bmiHeader.biSizeImage;
146: bfh.bfReserved1 =
147: bfh.bfReserved2 = 0;
148: bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
149: sizeof(RGBQUAD)*((pbmi->bmiHeader.biBitCount == 24) ? 0 : (1<<pbmi->bmiHeader.biBitCount));
150:
151: //
152: // Write out the file header now
153: //
154: if (_lwrite(hFile, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER)) == -1) {
155: MessageBox(ghwndMain, "Failed in WriteFile!", "Error", MB_OK);
156: bSuccess = FALSE;
157: goto ErrExit3;
158: }
159:
160: //
161: // Bitmap can't be selected into a DC when calling GetDIBits
162: // Assume that the hDC is the DC where the bitmap would have been selected
163: // if indeed it has been selected
164: //
165: if (hTmpBmp = CreateCompatibleBitmap(hDC, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight)) {
166: hBmpOld = SelectObject(hDC, hTmpBmp);
167: if ((GetDIBits(hDC, hBmp, 0, pbmi->bmiHeader.biHeight, (LPSTR)pBits, pbmi, DIB_RGB_COLORS))==0){
168: MessageBox(ghwndMain, "Failed in GetDIBits!", "Error", MB_OK);
169: bSuccess = FALSE;
170: goto ErrExit4;
171: }
172: } else {
173: MessageBox(ghwndMain, "Failed in creating bitmap!", "Error", MB_OK);
174: bSuccess = FALSE;
175: goto ErrExit3;
176: }
177:
178: //
179: // Now write out the BitmapInfoHeader and color table, if any
180: //
181: if (_lwrite(hFile, (LPSTR)pbmi, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) *
182: ((pbmi->bmiHeader.biBitCount == 24) ? 0 : (1 << pbmi->bmiHeader.biBitCount))) == -1) {
183: MessageBox(ghwndMain, "Failed in WriteFile!", "Error", MB_OK);
184: bSuccess = FALSE;
185: goto ErrExit4;
186: }
187:
188: //
189: // write the bits also
190: //
191: if (_lwrite(hFile, (LPSTR)pBits, pbmi->bmiHeader.biSizeImage) == -1) {
192: MessageBox(ghwndMain, "Failed in WriteFile!", "Error", MB_OK);
193: bSuccess = FALSE;
194: goto ErrExit4;
195: }
196:
197: ErrExit4:
198: SelectObject(hDC, hBmpOld);
199: DeleteObject(hTmpBmp);
200: ErrExit3:
201: _lclose(hFile);
202: ErrExit2:
203: GlobalFree(pbmi);
204: ErrExit1:
205: GlobalFree(pBits);
206: return bSuccess;
207: }
208:
209: /************************************************************************
210: * void ErrorOut(char errstring[30])
211: *
212: * Purpose: Print out an meainful error code by means of
213: * GetLastError and printf
214: *
215: * Inputs: errstring - the action that failed, passed by the
216: * calling proc.
217: *
218: * Returns: none
219: *
220: * Calls: GetLastError
221: *
222: * History:
223: * 09-13-91 Pete Grey Created.
224: *
225: \************************************************************************/
226:
227:
228: void ErrorOut(char errstring[30])
229: {
230: DWORD Error;
231: CHAR str[80];
232:
233: Error= GetLastError();
234: wsprintf((LPSTR) str, "Error on %s = %d\n", errstring, Error);
235: MessageBox(ghwndMain, (LPSTR)str, "Error", MB_OK);
236: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.