[ATL][ATL_APITEST] Add CImage initial implementation + tests, by Katayama Hirofumi...
[reactos.git] / rostests / apitests / atl / CImage.cpp
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for CImage
5 * PROGRAMMER: Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
6 */
7
8 #include <atlimage.h>
9 #include "resource.h"
10
11 #ifdef __REACTOS__
12 #include <apitest.h>
13 #else
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <stdarg.h>
17 const char *g_file = NULL;
18 int g_line = 0;
19 int g_tests_executed = 0;
20 int g_tests_failed = 0;
21 void ok_func(BOOL value, const char *fmt, ...)
22 {
23 va_list va;
24 va_start(va, fmt);
25 if (!value)
26 {
27 printf("%s (%d): ", g_file, g_line);
28 vprintf(fmt, va);
29 g_tests_failed++;
30 }
31 g_tests_executed++;
32 va_end(va);
33 }
34 #undef ok
35 #define ok g_file = __FILE__; g_line = __LINE__; ok_func
36 #define START_TEST(x) int main(void)
37 #endif
38
39
40 const TCHAR* szFiles[] = {
41 TEXT("ant.png"),
42 TEXT("ant.tif"),
43 TEXT("ant.gif"),
44 TEXT("ant.jpg"),
45 TEXT("ant.bmp"),
46 };
47
48 static TCHAR szTempPath[MAX_PATH];
49 TCHAR* file_name(const TCHAR* file)
50 {
51 static TCHAR buffer[MAX_PATH];
52 lstrcpy(buffer, szTempPath);
53 lstrcat(buffer, TEXT("\\"));
54 lstrcat(buffer, file);
55 return buffer;
56 }
57
58 static void write_bitmap(HINSTANCE hInst, int id, TCHAR* file)
59 {
60 HRSRC rsrc;
61
62 rsrc = FindResource(hInst, MAKEINTRESOURCE(id), MAKEINTRESOURCE(RT_BITMAP));
63 ok(rsrc != NULL, "Expected to find an image resource\n");
64 if (rsrc)
65 {
66 void *rsrc_data;
67 HANDLE hfile;
68 BOOL ret;
69 HGLOBAL glob = LoadResource(hInst, rsrc);
70 DWORD rsrc_size = SizeofResource(hInst, rsrc);
71
72 rsrc_data = LockResource(glob);
73
74 hfile = CreateFile(file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
75 ok(hfile != INVALID_HANDLE_VALUE, "Unable to open temp file: %lu\n", GetLastError());
76 if (hfile != INVALID_HANDLE_VALUE)
77 {
78 BITMAPFILEHEADER bfh = { 0 };
79 DWORD dwWritten;
80
81 bfh.bfType = 'MB';
82 bfh.bfSize = rsrc_size + sizeof(BITMAPFILEHEADER);
83 bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
84 bfh.bfReserved1 = bfh.bfReserved2 = 0;
85 ret = WriteFile(hfile, &bfh, sizeof(bfh), &dwWritten, NULL);
86 ok(ret, "Unable to write temp file: %lu\n", GetLastError());
87 ret = WriteFile(hfile, rsrc_data, rsrc_size, &dwWritten, NULL);
88 ok(ret, "Unable to write temp file: %lu\n", GetLastError());
89 CloseHandle(hfile);
90 }
91 UnlockResource(rsrc_data);
92 }
93 }
94
95 typedef Gdiplus::GpStatus (WINAPI *STARTUP)(ULONG_PTR *, const Gdiplus::GdiplusStartupInput *, Gdiplus::GdiplusStartupOutput *);
96 typedef void (WINAPI *SHUTDOWN)(ULONG_PTR);
97 typedef Gdiplus::GpStatus (WINGDIPAPI *CREATEBITMAPFROMFILE)(GDIPCONST WCHAR*, Gdiplus::GpBitmap **);
98 typedef Gdiplus::GpStatus (WINGDIPAPI *GETPIXELFORMAT)(Gdiplus::GpImage *image, Gdiplus::PixelFormat *format);
99 typedef Gdiplus::GpStatus (WINGDIPAPI *DISPOSEIMAGE)(Gdiplus::GpImage *);
100
101 static HINSTANCE hinstGdiPlus;
102 static ULONG_PTR gdiplusToken;
103
104 static STARTUP Startup;
105 static SHUTDOWN Shutdown;
106 static CREATEBITMAPFROMFILE CreateBitmapFromFile;
107 static GETPIXELFORMAT GetImagePixelFormat;
108 static DISPOSEIMAGE DisposeImage;
109
110 template <typename TYPE>
111 TYPE AddrOf(const char *name)
112 {
113 FARPROC proc = ::GetProcAddress(hinstGdiPlus, name);
114 return reinterpret_cast<TYPE>(proc);
115 }
116
117 static void init_gdip()
118 {
119 hinstGdiPlus = ::LoadLibraryA("gdiplus.dll");
120 Startup = AddrOf<STARTUP>("GdiplusStartup");
121 Shutdown = AddrOf<SHUTDOWN>("GdiplusShutdown");
122 CreateBitmapFromFile = AddrOf<CREATEBITMAPFROMFILE>("GdipCreateBitmapFromFile");
123 GetImagePixelFormat = AddrOf<GETPIXELFORMAT>("GdipGetImagePixelFormat");
124 DisposeImage = AddrOf<DISPOSEIMAGE>("GdipDisposeImage");
125 }
126
127
128 static void determine_file_bpp(TCHAR* tfile, Gdiplus::PixelFormat expect_pf)
129 {
130 using namespace Gdiplus;
131 GpBitmap *pBitmap = NULL;
132
133 #ifdef UNICODE
134 WCHAR* file = tfile;
135 #else
136 WCHAR file[MAX_PATH];
137 ::MultiByteToWideChar(CP_ACP, 0, tfile, -1, file, MAX_PATH);
138 #endif
139
140 if (Startup == NULL)
141 init_gdip();
142
143 Gdiplus::GdiplusStartupInput gdiplusStartupInput;
144 Startup(&gdiplusToken, &gdiplusStartupInput, NULL);
145
146
147 Gdiplus::GpStatus status = CreateBitmapFromFile(file, &pBitmap);
148 ok(status == Gdiplus::Ok, "Expected status to be %i, was: %i\n", (int)Gdiplus::Ok, (int)status);
149 ok(pBitmap != NULL, "Expected a valid bitmap\n");
150 if (pBitmap)
151 {
152 PixelFormat pf;
153 GetImagePixelFormat(pBitmap, &pf);
154 ok(pf == expect_pf, "Expected PixelFormat to be 0x%x, was: 0x%x\n", (int)expect_pf, (int)pf);
155
156 DisposeImage(pBitmap);
157 }
158 Shutdown(gdiplusToken);
159 }
160
161
162 START_TEST(CImage)
163 {
164 HRESULT hr;
165 TCHAR* file;
166 BOOL bOK;
167 int width, height, bpp;
168 size_t n;
169 CImage image1, image2;
170 COLORREF color;
171 HDC hDC;
172
173 #if 0
174 width = image1.GetWidth();
175 height = image1.GetHeight();
176 bpp = image1.GetBPP();
177 #endif
178
179 HINSTANCE hInst = GetModuleHandle(NULL);
180 GetTempPath(MAX_PATH, szTempPath);
181
182 image1.LoadFromResource(hInst, IDB_ANT);
183 ok(!image1.IsNull(), "Expected image1 is not null\n");
184
185 width = image1.GetWidth();
186 ok(width == 48, "Expected width to be 48, was: %d\n", width);
187 height = image1.GetHeight();
188 ok(height == 48, "Expected height to be 48, was: %d\n", height);
189 bpp = image1.GetBPP();
190 ok(bpp == 8, "Expected bpp to be 8, was: %d\n", bpp);
191
192
193 image2.LoadFromResource(hInst, IDB_CROSS);
194 ok(!image2.IsNull(), "Expected image2 is not null\n");
195 image2.SetTransparentColor(RGB(255, 255, 255));
196
197 width = image2.GetWidth();
198 ok(width == 32, "Expected width to be 32, was: %d\n", width);
199 height = image2.GetHeight();
200 ok(height == 32, "Expected height to be 32, was: %d\n", height);
201 bpp = image2.GetBPP();
202 ok(bpp == 8, "Expected bpp to be 8, was: %d\n", bpp);
203
204 color = image1.GetPixel(5, 5);
205 ok(color == RGB(166, 202, 240), "Expected color to be 166, 202, 240; was: %i, %i, %i\n", GetRValue(color), GetGValue(color), GetBValue(color));
206
207 hDC = image1.GetDC();
208 bOK = image2.Draw(hDC, 0, 0);
209 image1.ReleaseDC();
210 ok(bOK != FALSE, "Expected bDraw to be TRUE, was: %d\n", bOK);
211 image2.Destroy();
212
213 color = image1.GetPixel(5, 5);
214 ok(color == RGB(255, 0,0), "Expected color to be 255, 0, 0; was: %i, %i, %i\n", GetRValue(color), GetGValue(color), GetBValue(color));
215
216 file = file_name(TEXT("ant.bmp"));
217 write_bitmap(hInst, IDB_ANT, file);
218
219 init_gdip();
220
221 determine_file_bpp(file, PixelFormat8bppIndexed);
222
223 hr = image2.Load(file);
224 ok(hr == S_OK, "Expected hr to be S_OK, was: %08lx\n", hr);
225 ok(!image2.IsNull(), "Expected image1 is not null\n");
226 bOK = DeleteFile(file);
227 ok(bOK, "Expected bOK to be TRUE, was: %d\n", bOK);
228
229 width = image2.GetWidth();
230 ok(width == 48, "Expected width to be 48, was: %d\n", width);
231 height = image2.GetHeight();
232 ok(height == 48, "Expected height to be 48, was: %d\n", height);
233 bpp = image2.GetBPP();
234 ok(bpp == 8, "Expected bpp to be 8, was: %d\n", bpp);
235
236 for (n = 0; n < _countof(szFiles); ++n)
237 {
238 file = file_name(szFiles[n]);
239 image2.Destroy();
240
241 if (n == 0)
242 hr = image1.Save(file, Gdiplus::ImageFormatPNG);
243 else
244 hr = image1.Save(file);
245 ok(hr == S_OK, "Expected hr to be S_OK, was: %08lx (for %i)\n", hr, n);
246
247 bOK = (GetFileAttributes(file) != 0xFFFFFFFF);
248 ok(bOK, "Expected bOK to be TRUE, was: %d (for %i)\n", bOK, n);
249
250 hr = image2.Load(file);
251 ok(hr == S_OK, "Expected hr to be S_OK, was: %08lx (for %i)\n", hr, n);
252
253 width = image2.GetWidth();
254 ok(width == 48, "Expected width to be 48, was: %d (for %i)\n", width, n);
255 height = image2.GetHeight();
256 ok(height == 48, "Expected height to be 48, was: %d (for %i)\n", height, n);
257 bpp = image2.GetBPP();
258 if (n == 3)
259 {
260 ok(bpp == 24, "Expected bpp to be 24, was: %d (for %i)\n", bpp, n);
261 determine_file_bpp(file, PixelFormat24bppRGB);
262 }
263 else
264 {
265 ok(bpp == 8, "Expected bpp to be 8, was: %d (for %i)\n", bpp, n);
266 determine_file_bpp(file, PixelFormat8bppIndexed);
267 }
268 color = image1.GetPixel(5, 5);
269 ok(color == RGB(255, 0,0), "Expected color to be 255, 0, 0; was: %i, %i, %i (for %i)\n", GetRValue(color), GetGValue(color), GetBValue(color), n);
270
271 bOK = DeleteFile(file);
272 ok(bOK, "Expected bOK to be TRUE, was: %d (for %i)\n", bOK, n);
273 }
274
275 #ifndef __REACTOS__
276 printf("CImage: %i tests executed (0 marked as todo, %i failures), 0 skipped.\n", g_tests_executed, g_tests_failed);
277 #endif
278 }