[NTOS:IO]
[reactos.git] / base / applications / mspaint / dib.c
1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL
4 * FILE: base/applications/paint/dib.c
5 * PURPOSE: Some DIB related functions
6 * PROGRAMMERS: Benedikt Freisen
7 */
8
9 /* INCLUDES *********************************************************/
10
11 #include "precomp.h"
12
13 /* FUNCTIONS ********************************************************/
14
15 HBITMAP
16 CreateDIBWithProperties(int width, int height)
17 {
18 BITMAPINFO bmi;
19 ZeroMemory(&bmi, sizeof(BITMAPINFO));
20 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
21 bmi.bmiHeader.biWidth = width;
22 bmi.bmiHeader.biHeight = height;
23 bmi.bmiHeader.biPlanes = 1;
24 bmi.bmiHeader.biBitCount = 24;
25 bmi.bmiHeader.biCompression = BI_RGB;
26 return CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, NULL, NULL, 0);
27 }
28
29 int
30 GetDIBWidth(HBITMAP hBitmap)
31 {
32 BITMAP bm;
33 GetObject(hBitmap, sizeof(BITMAP), &bm);
34 return bm.bmWidth;
35 }
36
37 int
38 GetDIBHeight(HBITMAP hBitmap)
39 {
40 BITMAP bm;
41 GetObject(hBitmap, sizeof(BITMAP), &bm);
42 return bm.bmHeight;
43 }
44
45 void
46 SaveDIBToFile(HBITMAP hBitmap, LPTSTR FileName, HDC hDC, LPSYSTEMTIME time, int *size, int hRes, int vRes)
47 {
48 BITMAP bm;
49 HANDLE hFile;
50 BITMAPFILEHEADER bf;
51 BITMAPINFOHEADER bi;
52 int imgDataSize;
53 DWORD dwBytesWritten;
54 char *buffer;
55
56 GetObject(hBitmap, sizeof(BITMAP), &bm);
57
58 ZeroMemory(&bf, sizeof(BITMAPFILEHEADER));
59 ZeroMemory(&bi, sizeof(BITMAPINFOHEADER));
60
61 imgDataSize = bm.bmWidthBytes * bm.bmHeight;
62 bf.bfType = 0x4d42; /* BM */
63 bf.bfSize = imgDataSize + 52;
64 bf.bfOffBits = 54;
65 bi.biSize = sizeof(BITMAPINFOHEADER);
66 bi.biWidth = bm.bmWidth;
67 bi.biHeight = bm.bmHeight;
68 bi.biPlanes = bm.bmPlanes;
69 bi.biBitCount = bm.bmBitsPixel;
70 bi.biCompression = BI_RGB;
71 bi.biXPelsPerMeter = hRes;
72 bi.biYPelsPerMeter = vRes;
73
74 buffer = HeapAlloc(GetProcessHeap(), 0, imgDataSize);
75 GetDIBits(hDC, hBitmap, 0, bm.bmHeight, buffer, (LPBITMAPINFO) & bi, DIB_RGB_COLORS);
76
77 hFile = CreateFile(FileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
78 if (hFile == INVALID_HANDLE_VALUE)
79 return;
80
81 WriteFile(hFile, &bf, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
82 WriteFile(hFile, &bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
83 WriteFile(hFile, buffer, imgDataSize, &dwBytesWritten, NULL);
84
85 if (time)
86 {
87 FILETIME ft;
88 GetFileTime(hFile, NULL, NULL, &ft);
89 FileTimeToSystemTime(&ft, time);
90 }
91 if (size)
92 *size = GetFileSize(hFile, NULL);
93
94 CloseHandle(hFile);
95 HeapFree(GetProcessHeap(), 0, buffer);
96 }
97
98 void ShowFileLoadError(LPTSTR name)
99 {
100 TCHAR programname[20];
101 TCHAR loaderrortext[100];
102 TCHAR temptext[500];
103 LoadString(hProgInstance, IDS_PROGRAMNAME, programname, SIZEOF(programname));
104 LoadString(hProgInstance, IDS_LOADERRORTEXT, loaderrortext, SIZEOF(loaderrortext));
105 _stprintf(temptext, loaderrortext, name);
106 MessageBox(hMainWnd, temptext, programname, MB_OK | MB_ICONEXCLAMATION);
107 }
108
109 void
110 LoadDIBFromFile(HBITMAP * hBitmap, LPTSTR name, LPSYSTEMTIME time, int *size, int *hRes, int *vRes)
111 {
112 BITMAPFILEHEADER bfh;
113 BITMAPINFO *bi;
114 PVOID pvBits;
115 DWORD dwBytesRead;
116 HANDLE hFile;
117
118 if (!hBitmap)
119 {
120 ShowFileLoadError(name);
121 return;
122 }
123
124 hFile =
125 CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
126 if (hFile == INVALID_HANDLE_VALUE)
127 {
128 ShowFileLoadError(name);
129 return;
130 }
131
132 /* read header and check for 'BM' magic */
133 ReadFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL);
134 if (bfh.bfType != 0x4d42)
135 {
136 CloseHandle(hFile);
137 ShowFileLoadError(name);
138 return;
139 }
140
141 if (time)
142 {
143 FILETIME ft;
144 GetFileTime(hFile, NULL, NULL, &ft);
145 FileTimeToSystemTime(&ft, time);
146 }
147 if (size)
148 *size = GetFileSize(hFile, NULL);
149
150 bi = HeapAlloc(GetProcessHeap(), 0, bfh.bfOffBits - sizeof(BITMAPFILEHEADER));
151 if (!bi)
152 {
153 CloseHandle(hFile);
154 ShowFileLoadError(name);
155 return;
156 }
157
158 ReadFile(hFile, bi, bfh.bfOffBits - sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL);
159 *hBitmap = CreateDIBSection(NULL, bi, DIB_RGB_COLORS, &pvBits, NULL, 0);
160 ReadFile(hFile, pvBits, bfh.bfSize - bfh.bfOffBits, &dwBytesRead, NULL);
161
162 if (hRes)
163 *hRes = (*bi).bmiHeader.biXPelsPerMeter;
164 if (vRes)
165 *vRes = (*bi).bmiHeader.biYPelsPerMeter;
166
167 CloseHandle(hFile);
168 HeapFree(GetProcessHeap(), 0, bi);
169 }