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)
12 #pragma comment(lib, "rpcrt4.lib")
21 int g_tests_executed
= 0;
22 int g_tests_failed
= 0;
23 void ok_func(const char *file
, int line
, BOOL value
, const char *fmt
, ...)
29 printf("%s (%d): ", file
, line
);
37 #define ok(value, ...) ok_func(__FILE__, __LINE__, value, __VA_ARGS__)
38 #define START_TEST(x) int main(void)
41 bool IsGuidEqual(const GUID
& guid1
, const GUID
& guid2
)
44 if (::UuidEqual(const_cast<GUID
*>(&guid1
),
45 const_cast<GUID
*>(&guid2
), &status
))
47 if (status
== RPC_S_OK
)
53 const TCHAR
* szFiles
[] = {
61 static TCHAR szTempPath
[MAX_PATH
];
62 TCHAR
* file_name(const TCHAR
* file
)
64 static TCHAR buffer
[MAX_PATH
];
65 lstrcpy(buffer
, szTempPath
);
66 lstrcat(buffer
, TEXT("\\"));
67 lstrcat(buffer
, file
);
71 static void write_bitmap(HINSTANCE hInst
, int id
, TCHAR
* file
)
75 rsrc
= FindResource(hInst
, MAKEINTRESOURCE(id
), RT_BITMAP
);
76 ok(rsrc
!= NULL
, "Expected to find an image resource\n");
82 HGLOBAL glob
= LoadResource(hInst
, rsrc
);
83 DWORD rsrc_size
= SizeofResource(hInst
, rsrc
);
85 rsrc_data
= LockResource(glob
);
87 hfile
= CreateFile(file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, 0);
88 ok(hfile
!= INVALID_HANDLE_VALUE
, "Unable to open temp file: %lu\n", GetLastError());
89 if (hfile
!= INVALID_HANDLE_VALUE
)
91 BITMAPFILEHEADER bfh
= { 0 };
95 bfh
.bfSize
= rsrc_size
+ sizeof(BITMAPFILEHEADER
);
96 bfh
.bfOffBits
= sizeof(BITMAPFILEHEADER
) + sizeof(BITMAPINFOHEADER
);
97 bfh
.bfReserved1
= bfh
.bfReserved2
= 0;
98 ret
= WriteFile(hfile
, &bfh
, sizeof(bfh
), &dwWritten
, NULL
);
99 ok(ret
, "Unable to write temp file: %lu\n", GetLastError());
100 ret
= WriteFile(hfile
, rsrc_data
, rsrc_size
, &dwWritten
, NULL
);
101 ok(ret
, "Unable to write temp file: %lu\n", GetLastError());
104 UnlockResource(rsrc_data
);
108 typedef Gdiplus::GpStatus (WINAPI
*STARTUP
)(ULONG_PTR
*, const Gdiplus::GdiplusStartupInput
*, Gdiplus::GdiplusStartupOutput
*);
109 typedef void (WINAPI
*SHUTDOWN
)(ULONG_PTR
);
110 typedef Gdiplus::GpStatus (WINGDIPAPI
*CREATEBITMAPFROMFILE
)(GDIPCONST WCHAR
*, Gdiplus::GpBitmap
**);
111 typedef Gdiplus::GpStatus (WINGDIPAPI
*GETPIXELFORMAT
)(Gdiplus::GpImage
*image
, Gdiplus::PixelFormat
*format
);
112 typedef Gdiplus::GpStatus (WINGDIPAPI
*DISPOSEIMAGE
)(Gdiplus::GpImage
*);
114 static HINSTANCE hinstGdiPlus
;
115 static ULONG_PTR gdiplusToken
;
117 static STARTUP Startup
;
118 static SHUTDOWN Shutdown
;
119 static CREATEBITMAPFROMFILE CreateBitmapFromFile
;
120 static GETPIXELFORMAT GetImagePixelFormat
;
121 static DISPOSEIMAGE DisposeImage
;
123 template <typename TYPE
>
124 TYPE
AddrOf(const char *name
)
126 FARPROC proc
= ::GetProcAddress(hinstGdiPlus
, name
);
127 return reinterpret_cast<TYPE
>(proc
);
130 static void init_gdip()
132 hinstGdiPlus
= ::LoadLibraryA("gdiplus.dll");
133 Startup
= AddrOf
<STARTUP
>("GdiplusStartup");
134 Shutdown
= AddrOf
<SHUTDOWN
>("GdiplusShutdown");
135 CreateBitmapFromFile
= AddrOf
<CREATEBITMAPFROMFILE
>("GdipCreateBitmapFromFile");
136 GetImagePixelFormat
= AddrOf
<GETPIXELFORMAT
>("GdipGetImagePixelFormat");
137 DisposeImage
= AddrOf
<DISPOSEIMAGE
>("GdipDisposeImage");
141 static void determine_file_bpp(TCHAR
* tfile
, Gdiplus::PixelFormat expect_pf
)
143 using namespace Gdiplus
;
144 GpBitmap
*pBitmap
= NULL
;
149 WCHAR file
[MAX_PATH
];
150 ::MultiByteToWideChar(CP_ACP
, 0, tfile
, -1, file
, MAX_PATH
);
156 Gdiplus::GdiplusStartupInput gdiplusStartupInput
;
157 Startup(&gdiplusToken
, &gdiplusStartupInput
, NULL
);
160 Gdiplus::GpStatus status
= CreateBitmapFromFile(file
, &pBitmap
);
161 ok(status
== Gdiplus::Ok
, "Expected status to be %i, was: %i\n", (int)Gdiplus::Ok
, (int)status
);
162 ok(pBitmap
!= NULL
, "Expected a valid bitmap\n");
166 GetImagePixelFormat(pBitmap
, &pf
);
167 ok(pf
== expect_pf
, "Expected PixelFormat to be 0x%x, was: 0x%x\n", (int)expect_pf
, (int)pf
);
169 DisposeImage(pBitmap
);
171 Shutdown(gdiplusToken
);
180 int width
, height
, bpp
;
182 CImage image1
, image2
;
187 width
= image1
.GetWidth();
188 height
= image1
.GetHeight();
189 bpp
= image1
.GetBPP();
192 HINSTANCE hInst
= GetModuleHandle(NULL
);
193 GetTempPath(MAX_PATH
, szTempPath
);
195 image1
.LoadFromResource(hInst
, IDB_ANT
);
196 ok(!image1
.IsNull(), "Expected image1 is not null\n");
198 width
= image1
.GetWidth();
199 ok(width
== 48, "Expected width to be 48, was: %d\n", width
);
200 height
= image1
.GetHeight();
201 ok(height
== 48, "Expected height to be 48, was: %d\n", height
);
202 bpp
= image1
.GetBPP();
203 ok(bpp
== 8, "Expected bpp to be 8, was: %d\n", bpp
);
206 image2
.LoadFromResource(hInst
, IDB_CROSS
);
207 ok(!image2
.IsNull(), "Expected image2 is not null\n");
208 image2
.SetTransparentColor(RGB(255, 255, 255));
210 width
= image2
.GetWidth();
211 ok(width
== 32, "Expected width to be 32, was: %d\n", width
);
212 height
= image2
.GetHeight();
213 ok(height
== 32, "Expected height to be 32, was: %d\n", height
);
214 bpp
= image2
.GetBPP();
215 ok(bpp
== 8, "Expected bpp to be 8, was: %d\n", bpp
);
217 color
= image1
.GetPixel(5, 5);
218 ok(color
== RGB(166, 202, 240), "Expected color to be 166, 202, 240; was: %i, %i, %i\n", GetRValue(color
), GetGValue(color
), GetBValue(color
));
220 hDC
= image1
.GetDC();
221 bOK
= image2
.Draw(hDC
, 0, 0);
223 ok(bOK
!= FALSE
, "Expected bDraw to be TRUE, was: %d\n", bOK
);
226 color
= image1
.GetPixel(5, 5);
227 ok(color
== RGB(255, 0,0), "Expected color to be 255, 0, 0; was: %i, %i, %i\n", GetRValue(color
), GetGValue(color
), GetBValue(color
));
229 file
= file_name(TEXT("ant.bmp"));
230 write_bitmap(hInst
, IDB_ANT
, file
);
234 determine_file_bpp(file
, PixelFormat8bppIndexed
);
236 hr
= image2
.Load(file
);
237 ok(hr
== S_OK
, "Expected hr to be S_OK, was: %08lx\n", hr
);
238 ok(!image2
.IsNull(), "Expected image1 is not null\n");
239 bOK
= DeleteFile(file
);
240 ok(bOK
, "Expected bOK to be TRUE, was: %d\n", bOK
);
242 width
= image2
.GetWidth();
243 ok(width
== 48, "Expected width to be 48, was: %d\n", width
);
244 height
= image2
.GetHeight();
245 ok(height
== 48, "Expected height to be 48, was: %d\n", height
);
246 bpp
= image2
.GetBPP();
247 ok(bpp
== 8, "Expected bpp to be 8, was: %d\n", bpp
);
249 for (n
= 0; n
< _countof(szFiles
); ++n
)
251 file
= file_name(szFiles
[n
]);
255 hr
= image1
.Save(file
, Gdiplus::ImageFormatPNG
);
257 hr
= image1
.Save(file
);
258 ok(hr
== S_OK
, "Expected hr to be S_OK, was: %08lx (for %i)\n", hr
, n
);
260 bOK
= (GetFileAttributes(file
) != 0xFFFFFFFF);
261 ok(bOK
, "Expected bOK to be TRUE, was: %d (for %i)\n", bOK
, n
);
263 hr
= image2
.Load(file
);
264 ok(hr
== S_OK
, "Expected hr to be S_OK, was: %08lx (for %i)\n", hr
, n
);
266 width
= image2
.GetWidth();
267 ok(width
== 48, "Expected width to be 48, was: %d (for %i)\n", width
, n
);
268 height
= image2
.GetHeight();
269 ok(height
== 48, "Expected height to be 48, was: %d (for %i)\n", height
, n
);
270 bpp
= image2
.GetBPP();
273 ok(bpp
== 24, "Expected bpp to be 24, was: %d (for %i)\n", bpp
, n
);
274 determine_file_bpp(file
, PixelFormat24bppRGB
);
278 ok(bpp
== 8, "Expected bpp to be 8, was: %d (for %i)\n", bpp
, n
);
279 determine_file_bpp(file
, PixelFormat8bppIndexed
);
281 color
= image1
.GetPixel(5, 5);
282 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
);
284 bOK
= DeleteFile(file
);
285 ok(bOK
, "Expected bOK to be TRUE, was: %d (for %i)\n", bOK
, n
);
288 ATL::IAtlStringMgr
*mgr
= CAtlStringMgr::GetInstance();
289 CSimpleArray
<GUID
> aguidFileTypes
;
297 CSimpleString
strImporters(mgr
);
298 aguidFileTypes
.RemoveAll();
299 hr
= CImage::GetImporterFilterString(strImporters
,
301 TEXT("All Image Files"), 0);
302 ok(hr
== S_OK
, "Expected hr to be S_OK, was: %ld\n", hr
);
303 ok(aguidFileTypes
.GetSize() == 9, "Expected aguidFileTypes.GetSize() to be 8, was %d.", aguidFileTypes
.GetSize());
304 ok(IsGuidEqual(aguidFileTypes
[0], GUID_NULL
), "Expected aguidFileTypes[0] to be GUID_NULL.\n");
305 ok(IsGuidEqual(aguidFileTypes
[1], Gdiplus::ImageFormatBMP
), "Expected aguidFileTypes[1] to be Gdiplus::ImageFormatBMP.\n");
306 ok(IsGuidEqual(aguidFileTypes
[2], Gdiplus::ImageFormatJPEG
), "Expected aguidFileTypes[2] to be Gdiplus::ImageFormatJPEG.\n");
307 ok(IsGuidEqual(aguidFileTypes
[3], Gdiplus::ImageFormatGIF
), "Expected aguidFileTypes[3] to be Gdiplus::ImageFormatGIF.\n");
308 ok(IsGuidEqual(aguidFileTypes
[4], Gdiplus::ImageFormatEMF
), "Expected aguidFileTypes[4] to be Gdiplus::ImageFormatEMF.\n");
309 ok(IsGuidEqual(aguidFileTypes
[5], Gdiplus::ImageFormatWMF
), "Expected aguidFileTypes[5] to be Gdiplus::ImageFormatWMF.\n");
310 ok(IsGuidEqual(aguidFileTypes
[6], Gdiplus::ImageFormatTIFF
), "Expected aguidFileTypes[6] to be Gdiplus::ImageFormatTIFF.\n");
311 ok(IsGuidEqual(aguidFileTypes
[7], Gdiplus::ImageFormatPNG
), "Expected aguidFileTypes[7] to be Gdiplus::ImageFormatPNG.\n");
312 ok(IsGuidEqual(aguidFileTypes
[8], Gdiplus::ImageFormatIcon
), "Expected aguidFileTypes[8] to be Gdiplus::ImageFormatIcon.\n");
314 psz
= strImporters
.GetString();
316 WideCharToMultiByte(CP_ACP
, 0, psz
, -1, szBuff
, 512, NULL
, NULL
);
317 ok(lstrcmpA(szBuff
, "All Image Files|*.BMP;*.DIB;*.RLE;*.JPG;*.JPEG;*.JPE;*.JFIF;*.GIF;*.EMF;*.WMF;*.TIF;*.TIFF;*.PNG;*.ICO|BMP (*.BMP;*.DIB;*.RLE)|*.BMP;*.DIB;*.RLE|JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)|*.JPG;*.JPEG;*.JPE;*.JFIF|GIF (*.GIF)|*.GIF|EMF (*.EMF)|*.EMF|WMF (*.WMF)|*.WMF|TIFF (*.TIF;*.TIFF)|*.TIF;*.TIFF|PNG (*.PNG)|*.PNG|ICO (*.ICO)|*.ICO||") == 0,
318 "The importer filter string is bad, was: %s\n", szBuff
);
320 ok(lstrcmpA(psz
, "All Image Files|*.BMP;*.DIB;*.RLE;*.JPG;*.JPEG;*.JPE;*.JFIF;*.GIF;*.EMF;*.WMF;*.TIF;*.TIFF;*.PNG;*.ICO|BMP (*.BMP;*.DIB;*.RLE)|*.BMP;*.DIB;*.RLE|JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)|*.JPG;*.JPEG;*.JPE;*.JFIF|GIF (*.GIF)|*.GIF|EMF (*.EMF)|*.EMF|WMF (*.WMF)|*.WMF|TIFF (*.TIF;*.TIFF)|*.TIF;*.TIFF|PNG (*.PNG)|*.PNG|ICO (*.ICO)|*.ICO||") == 0,
321 "The importer filter string is bad, was: %s\n", psz
);
324 CSimpleString
strExporters(mgr
);
325 aguidFileTypes
.RemoveAll();
326 hr
= CImage::GetExporterFilterString(strExporters
,
328 TEXT("All Image Files"), 0);
329 ok(hr
== S_OK
, "Expected hr to be S_OK, was: %ld\n", hr
);
330 ok(aguidFileTypes
.GetSize() == 9, "Expected aguidFileTypes.GetSize() to be 8, was %d.", aguidFileTypes
.GetSize());
331 ok(IsGuidEqual(aguidFileTypes
[0], GUID_NULL
), "Expected aguidFileTypes[0] to be GUID_NULL.\n");
332 ok(IsGuidEqual(aguidFileTypes
[1], Gdiplus::ImageFormatBMP
), "Expected aguidFileTypes[1] to be Gdiplus::ImageFormatBMP.\n");
333 ok(IsGuidEqual(aguidFileTypes
[2], Gdiplus::ImageFormatJPEG
), "Expected aguidFileTypes[2] to be Gdiplus::ImageFormatJPEG.\n");
334 ok(IsGuidEqual(aguidFileTypes
[3], Gdiplus::ImageFormatGIF
), "Expected aguidFileTypes[3] to be Gdiplus::ImageFormatGIF.\n");
335 ok(IsGuidEqual(aguidFileTypes
[4], Gdiplus::ImageFormatEMF
), "Expected aguidFileTypes[4] to be Gdiplus::ImageFormatEMF.\n");
336 ok(IsGuidEqual(aguidFileTypes
[5], Gdiplus::ImageFormatWMF
), "Expected aguidFileTypes[5] to be Gdiplus::ImageFormatWMF.\n");
337 ok(IsGuidEqual(aguidFileTypes
[6], Gdiplus::ImageFormatTIFF
), "Expected aguidFileTypes[6] to be Gdiplus::ImageFormatTIFF.\n");
338 ok(IsGuidEqual(aguidFileTypes
[7], Gdiplus::ImageFormatPNG
), "Expected aguidFileTypes[7] to be Gdiplus::ImageFormatPNG.\n");
339 ok(IsGuidEqual(aguidFileTypes
[8], Gdiplus::ImageFormatIcon
), "Expected aguidFileTypes[8] to be Gdiplus::ImageFormatIcon.\n");
341 psz
= strExporters
.GetString();
343 WideCharToMultiByte(CP_ACP
, 0, psz
, -1, szBuff
, 512, NULL
, NULL
);
344 ok(lstrcmpA(szBuff
, "All Image Files|*.BMP;*.DIB;*.RLE;*.JPG;*.JPEG;*.JPE;*.JFIF;*.GIF;*.EMF;*.WMF;*.TIF;*.TIFF;*.PNG;*.ICO|BMP (*.BMP;*.DIB;*.RLE)|*.BMP;*.DIB;*.RLE|JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)|*.JPG;*.JPEG;*.JPE;*.JFIF|GIF (*.GIF)|*.GIF|EMF (*.EMF)|*.EMF|WMF (*.WMF)|*.WMF|TIFF (*.TIF;*.TIFF)|*.TIF;*.TIFF|PNG (*.PNG)|*.PNG|ICO (*.ICO)|*.ICO||") == 0,
345 "The exporter filter string is bad, was: %s\n", szBuff
);
347 ok(lstrcmpA(psz
, "All Image Files|*.BMP;*.DIB;*.RLE;*.JPG;*.JPEG;*.JPE;*.JFIF;*.GIF;*.EMF;*.WMF;*.TIF;*.TIFF;*.PNG;*.ICO|BMP (*.BMP;*.DIB;*.RLE)|*.BMP;*.DIB;*.RLE|JPEG (*.JPG;*.JPEG;*.JPE;*.JFIF)|*.JPG;*.JPEG;*.JPE;*.JFIF|GIF (*.GIF)|*.GIF|EMF (*.EMF)|*.EMF|WMF (*.WMF)|*.WMF|TIFF (*.TIF;*.TIFF)|*.TIF;*.TIFF|PNG (*.PNG)|*.PNG|ICO (*.ICO)|*.ICO||") == 0,
348 "The exporter filter string is bad, was: %s\n", psz
);
352 printf("CImage: %i tests executed (0 marked as todo, %i failures), 0 skipped.\n", g_tests_executed
, g_tests_failed
);
353 return g_tests_failed
;