[RTL]
[reactos.git] / reactos / 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
99 LoadDIBFromFile(HBITMAP * hBitmap, LPTSTR name, LPSYSTEMTIME time, int *size, int *hRes, int *vRes)
100 {
101 BITMAPFILEHEADER bfh;
102 BITMAPINFO *bi;
103 PVOID pvBits;
104 DWORD dwBytesRead;
105 HANDLE hFile;
106
107 if (!hBitmap)
108 return;
109
110 hFile =
111 CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
112 if (hFile == INVALID_HANDLE_VALUE)
113 return;
114
115 /* read header and check for 'BM' magic */
116 ReadFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL);
117 if (bfh.bfType != 0x4d42)
118 {
119 CloseHandle(hFile);
120 return;
121 }
122
123 if (time)
124 {
125 FILETIME ft;
126 GetFileTime(hFile, NULL, NULL, &ft);
127 FileTimeToSystemTime(&ft, time);
128 }
129 if (size)
130 *size = GetFileSize(hFile, NULL);
131
132 bi = HeapAlloc(GetProcessHeap(), 0, bfh.bfOffBits - sizeof(BITMAPFILEHEADER));
133 if (!bi)
134 return;
135
136 ReadFile(hFile, bi, bfh.bfOffBits - sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL);
137 *hBitmap = CreateDIBSection(NULL, bi, DIB_RGB_COLORS, &pvBits, NULL, 0);
138 ReadFile(hFile, pvBits, bfh.bfSize - bfh.bfOffBits, &dwBytesRead, NULL);
139
140 if (hRes)
141 *hRes = (*bi).bmiHeader.biXPelsPerMeter;
142 if (vRes)
143 *vRes = (*bi).bmiHeader.biYPelsPerMeter;
144
145 CloseHandle(hFile);
146 HeapFree(GetProcessHeap(), 0, bi);
147 }