ff506e8d760124169f02327d74c479f12e270d1e
[reactos.git] / reactos / base / applications / mspaint / dib.cpp
1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL
4 * FILE: base/applications/mspaint_new/dib.cpp
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 = (char*) HeapAlloc(GetProcessHeap(), 0, imgDataSize);
75 if (!buffer)
76 return;
77
78 GetDIBits(hDC, hBitmap, 0, bm.bmHeight, buffer, (LPBITMAPINFO) & bi, DIB_RGB_COLORS);
79
80 hFile = CreateFile(FileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
81 if (hFile == INVALID_HANDLE_VALUE)
82 {
83 HeapFree(GetProcessHeap(), 0, buffer);
84 return;
85 }
86
87 WriteFile(hFile, &bf, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
88 WriteFile(hFile, &bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
89 WriteFile(hFile, buffer, imgDataSize, &dwBytesWritten, NULL);
90
91 if (time)
92 {
93 FILETIME ft;
94 GetFileTime(hFile, NULL, NULL, &ft);
95 FileTimeToSystemTime(&ft, time);
96 }
97 if (size)
98 *size = GetFileSize(hFile, NULL);
99
100 CloseHandle(hFile);
101 HeapFree(GetProcessHeap(), 0, buffer);
102 }
103
104 void ShowFileLoadError(LPTSTR name)
105 {
106 TCHAR programname[20];
107 TCHAR loaderrortext[100];
108 TCHAR temptext[500];
109 LoadString(hProgInstance, IDS_PROGRAMNAME, programname, SIZEOF(programname));
110 LoadString(hProgInstance, IDS_LOADERRORTEXT, loaderrortext, SIZEOF(loaderrortext));
111 _stprintf(temptext, loaderrortext, name);
112 mainWindow.MessageBox(temptext, programname, MB_OK | MB_ICONEXCLAMATION);
113 }
114
115 void
116 LoadDIBFromFile(HBITMAP * hBitmap, LPTSTR name, LPSYSTEMTIME time, int *size, int *hRes, int *vRes)
117 {
118 BITMAPFILEHEADER bfh;
119 BITMAPINFO *bi;
120 PVOID pvBits;
121 DWORD dwBytesRead;
122 HANDLE hFile;
123
124 if (!hBitmap)
125 {
126 ShowFileLoadError(name);
127 return;
128 }
129
130 hFile =
131 CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
132 if (hFile == INVALID_HANDLE_VALUE)
133 {
134 ShowFileLoadError(name);
135 return;
136 }
137
138 /* read header and check for 'BM' magic */
139 ReadFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL);
140 if (bfh.bfType != 0x4d42)
141 {
142 CloseHandle(hFile);
143 ShowFileLoadError(name);
144 return;
145 }
146
147 if (time)
148 {
149 FILETIME ft;
150 GetFileTime(hFile, NULL, NULL, &ft);
151 FileTimeToSystemTime(&ft, time);
152 }
153 if (size)
154 *size = GetFileSize(hFile, NULL);
155
156 bi = (BITMAPINFO*) HeapAlloc(GetProcessHeap(), 0, bfh.bfOffBits - sizeof(BITMAPFILEHEADER));
157 if (!bi)
158 {
159 CloseHandle(hFile);
160 ShowFileLoadError(name);
161 return;
162 }
163
164 ReadFile(hFile, bi, bfh.bfOffBits - sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL);
165 *hBitmap = CreateDIBSection(NULL, bi, DIB_RGB_COLORS, &pvBits, NULL, 0);
166 ReadFile(hFile, pvBits, bfh.bfSize - bfh.bfOffBits, &dwBytesRead, NULL);
167
168 if (hRes)
169 *hRes = (*bi).bmiHeader.biXPelsPerMeter;
170 if (vRes)
171 *vRes = (*bi).bmiHeader.biYPelsPerMeter;
172
173 CloseHandle(hFile);
174 HeapFree(GetProcessHeap(), 0, bi);
175 }