|
|
1.1 root 1: /****************************************************************************/
2: /* */
3: /* Microsoft Confidential */
4: /* */
5: /* Copyright (c) Microsoft Corp. 1987, 1991 */
6: /* All Rights Reserved */
7: /* */
8: /****************************************************************************/
9: /****************************** Module Header *******************************
10: * Module Name: rwbmp.c
11: *
12: * Routines for reading and writing bitmap files.
13: *
14: * History:
15: *
16: ****************************************************************************/
17:
18: #include "imagedit.h"
19:
20: #include <stdio.h>
21: #include <io.h>
22: #include <fcntl.h> // For NT fstat().
23: #include <sys\types.h> // For fstat() types.
24: #include <sys\stat.h> // For fstat() function.
25:
26:
27:
28: /************************************************************************
29: * LoadBitmapFile
30: *
31: * Loads the specified bitmap file. With ImagEdit, this must be a
32: * Windows 3.0 DIB.
33: *
34: * Arguments:
35: * PSTR pszFullFileName - Name of the bitmap file to load.
36: *
37: * Returns:
38: * TRUE if successful, FALSE otherwise.
39: *
40: * History:
41: *
42: ************************************************************************/
43:
44: BOOL LoadBitmapFile(
45: PSTR pszFullFileName)
46: {
47: HFILE hf;
48: OFSTRUCT OfStruct;
49: struct stat FileStatus;
50: DWORD dwFileSize;
51: DWORD dwDIBSize;
52: BITMAPFILEHEADER bfh;
53: BITMAPINFOHEADER bih;
54: PIMAGEINFO pImage;
55: INT nColors;
56: HANDLE hDIB;
57: PDEVICE pDevice;
58:
59: if ((hf = (HFILE)OpenFile(pszFullFileName, (LPOFSTRUCT)&OfStruct, OF_READ))
60: == (HFILE)-1) {
61: Message(MSG_CANTOPEN, pszFullFileName);
62: return FALSE;
63: }
64:
65: fstat((INT)_open_osfhandle((long)(hf), (int)(O_RDONLY)), &FileStatus);
66: dwFileSize = (DWORD)FileStatus.st_size;
67:
68: ImageLinkFreeList();
69:
70: /*
71: * Read the Bitmap File Header.
72: */
73: if (!MyFileRead(hf, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER),
74: pszFullFileName, FT_BITMAP))
75: goto Error1;
76:
77: /*
78: * Check for the "BM" at the start of the file, and the file size
79: * in the header must match the real file size.
80: */
81: if (bfh.bfType != 0x4D42 || bfh.bfSize != dwFileSize) {
82: Message(MSG_BADBMPFILE, pszFullFileName);
83: goto Error1;
84: }
85:
86: /*
87: * Read the Bitmap Info Header.
88: */
89: if (!MyFileRead(hf, (LPSTR)&bih, sizeof(BITMAPINFOHEADER),
90: pszFullFileName, FT_BITMAP))
91: goto Error1;
92:
93: /*
94: * The DIB size should be the size of the file less the bitmap
95: * file header.
96: */
97: dwDIBSize = dwFileSize - sizeof(BITMAPFILEHEADER);
98:
99: if (!IsValidDIB((LPBITMAPINFO)&bih, dwDIBSize, FALSE)) {
100: Message(MSG_BADBMPFILE, pszFullFileName);
101: goto Error1;
102: }
103:
104: /*
105: * There is a limit to the size of image we will edit. For icons
106: * and cursors, the field that carries the dimensions is a byte,
107: * so the size cannot be greater than 256. This is also what
108: * we limit bitmaps to.
109: */
110: if (bih.biWidth > MAXIMAGEDIM || bih.biHeight > MAXIMAGEDIM) {
111: Message(MSG_BADBMPSIZE, MAXIMAGEDIM, MAXIMAGEDIM);
112: goto Error1;
113: }
114:
115: switch (bih.biBitCount) {
116: case 1:
117: nColors = 2;
118: break;
119:
120: case 4:
121: nColors = 16;
122: break;
123:
124: default:
125: Message(MSG_NOTSUPPORT);
126: goto Error1;
127: }
128:
129: if (!(pDevice = DeviceLinkAlloc(FT_BITMAP, NULL, nColors,
130: (INT)bih.biWidth, (INT)bih.biHeight))) {
131: goto Error1;
132: }
133:
134: if (!(pImage = ImageLinkAlloc(pDevice,
135: (INT)bih.biWidth, (INT)bih.biHeight, 0, 0, nColors)))
136: goto Error1;
137:
138: /*
139: * Allocate space for the DIB for this image.
140: */
141: if (!(hDIB = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwDIBSize))) {
142: Message(MSG_OUTOFMEMORY);
143: goto Error2;
144: }
145:
146: pImage->DIBSize = dwDIBSize;
147: pImage->DIBhandle = hDIB;
148: pImage->DIBPtr = (LPSTR)GlobalLock(hDIB);
149:
150: /*
151: * Jump back to the start of the DIB.
152: */
153: SetFilePointer((HANDLE)hf, sizeof(BITMAPFILEHEADER), NULL, (DWORD)0);
154:
155: /*
156: * Read the entire DIB (including info and color table) into
157: * the allocated memory for it.
158: */
159: if (!MyFileRead(hf, pImage->DIBPtr, (DWORD)pImage->DIBSize,
160: pszFullFileName, FT_BITMAP))
161: goto Error2;
162:
163: _lclose((HFILE)hf);
164:
165: fFileDirty = FALSE;
166: SetFileName(pszFullFileName);
167: giType = FT_BITMAP;
168:
169: /*
170: * Bitmaps only have one "image" in the file.
171: */
172: gnImages = 1;
173:
174: ImageOpen2(pImage);
175:
176: return TRUE;
177:
178: Error2:
179: ImageLinkFreeList();
180:
181: Error1:
182: _lclose((HFILE)hf);
183:
184: return FALSE;
185: }
186:
187:
188:
189: /************************************************************************
190: * SaveBitmapFile
191: *
192: *
193: *
194: * Arguments:
195: *
196: * Returns:
197: * TRUE if successful, FALSE otherwise.
198: *
199: * History:
200: *
201: ************************************************************************/
202:
203: BOOL SaveBitmapFile(
204: PSTR pszFullFileName)
205: {
206: HCURSOR hcurOld;
207: BITMAPFILEHEADER bfh;
208: HFILE hf;
209: OFSTRUCT OfStruct;
210:
211: hcurOld = SetCursor(hcurWait);
212:
213: /*
214: * Save the bits of the current image.
215: */
216: ImageSave();
217:
218: /*
219: * Open the file for writing.
220: */
221: if ((hf = (HFILE)OpenFile(pszFullFileName, &OfStruct, OF_CREATE | OF_READWRITE))
222: == (HFILE)-1) {
223: Message(MSG_CANTCREATE, pszFullFileName);
224: goto Error1;
225: }
226:
227: bfh.bfType = 0x4D42;
228: bfh.bfSize = sizeof(BITMAPFILEHEADER) + gpImageCur->DIBSize;
229: bfh.bfReserved1 = 0;
230: bfh.bfReserved2 = 0;
231: bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
232: (gpImageCur->nColors * sizeof(RGBQUAD));
233:
234: /*
235: * Write the header to disk.
236: */
237: if (!MyFileWrite(hf, (LPSTR)&bfh, sizeof(BITMAPFILEHEADER),
238: pszFullFileName))
239: goto Error2;
240:
241: /*
242: * Now write the DIB (a bitmap file only has one).
243: */
244: if (!MyFileWrite(hf, (LPSTR)gpImageCur->DIBPtr,
245: (DWORD)gpImageCur->DIBSize, pszFullFileName))
246: goto Error2;
247:
248: _lclose((HFILE)hf);
249:
250: fFileDirty = FALSE;
251: SetFileName(pszFullFileName);
252:
253: SetCursor(hcurOld);
254:
255: return TRUE;
256:
257: Error2:
258: _lclose((HFILE)hf);
259:
260: Error1:
261: SetCursor(hcurOld);
262:
263: return FALSE;
264: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.