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