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 int g_tests_executed = 0; 18 int g_tests_failed = 0; 19 void ok_func(const char *file, int line, BOOL value, const char *fmt, ...) 20 { 21 va_list va; 22 va_start(va, fmt); 23 if (!value) 24 { 25 printf("%s (%d): ", file, line); 26 vprintf(fmt, va); 27 g_tests_failed++; 28 } 29 g_tests_executed++; 30 va_end(va); 31 } 32 #undef ok 33 #define ok(value, ...) ok_func(__FILE__, __LINE__, value, __VA_ARGS__) 34 #define START_TEST(x) int main(void) 35 #endif 36 37 const TCHAR* szFiles[] = { 38 TEXT("ant.png"), 39 TEXT("ant.tif"), 40 TEXT("ant.gif"), 41 TEXT("ant.jpg"), 42 TEXT("ant.bmp"), 43 }; 44 45 static TCHAR szTempPath[MAX_PATH]; 46 TCHAR* file_name(const TCHAR* file) 47 { 48 static TCHAR buffer[MAX_PATH]; 49 lstrcpy(buffer, szTempPath); 50 lstrcat(buffer, TEXT("\\")); 51 lstrcat(buffer, file); 52 return buffer; 53 } 54 55 static void write_bitmap(HINSTANCE hInst, int id, TCHAR* file) 56 { 57 HRSRC rsrc; 58 59 rsrc = FindResource(hInst, MAKEINTRESOURCE(id), RT_BITMAP); 60 ok(rsrc != NULL, "Expected to find an image resource\n"); 61 if (rsrc) 62 { 63 void *rsrc_data; 64 HANDLE hfile; 65 BOOL ret; 66 HGLOBAL glob = LoadResource(hInst, rsrc); 67 DWORD rsrc_size = SizeofResource(hInst, rsrc); 68 69 rsrc_data = LockResource(glob); 70 71 hfile = CreateFile(file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); 72 ok(hfile != INVALID_HANDLE_VALUE, "Unable to open temp file: %lu\n", GetLastError()); 73 if (hfile != INVALID_HANDLE_VALUE) 74 { 75 BITMAPFILEHEADER bfh = { 0 }; 76 DWORD dwWritten; 77 78 bfh.bfType = 'MB'; 79 bfh.bfSize = rsrc_size + sizeof(BITMAPFILEHEADER); 80 bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); 81 bfh.bfReserved1 = bfh.bfReserved2 = 0; 82 ret = WriteFile(hfile, &bfh, sizeof(bfh), &dwWritten, NULL); 83 ok(ret, "Unable to write temp file: %lu\n", GetLastError()); 84 ret = WriteFile(hfile, rsrc_data, rsrc_size, &dwWritten, NULL); 85 ok(ret, "Unable to write temp file: %lu\n", GetLastError()); 86 CloseHandle(hfile); 87 } 88 UnlockResource(rsrc_data); 89 } 90 } 91 92 typedef Gdiplus::GpStatus (WINAPI *STARTUP)(ULONG_PTR *, const Gdiplus::GdiplusStartupInput *, Gdiplus::GdiplusStartupOutput *); 93 typedef void (WINAPI *SHUTDOWN)(ULONG_PTR); 94 typedef Gdiplus::GpStatus (WINGDIPAPI *CREATEBITMAPFROMFILE)(GDIPCONST WCHAR*, Gdiplus::GpBitmap **); 95 typedef Gdiplus::GpStatus (WINGDIPAPI *GETPIXELFORMAT)(Gdiplus::GpImage *image, Gdiplus::PixelFormat *format); 96 typedef Gdiplus::GpStatus (WINGDIPAPI *DISPOSEIMAGE)(Gdiplus::GpImage *); 97 98 static HINSTANCE hinstGdiPlus; 99 static ULONG_PTR gdiplusToken; 100 101 static STARTUP Startup; 102 static SHUTDOWN Shutdown; 103 static CREATEBITMAPFROMFILE CreateBitmapFromFile; 104 static GETPIXELFORMAT GetImagePixelFormat; 105 static DISPOSEIMAGE DisposeImage; 106 107 template <typename TYPE> 108 TYPE AddrOf(const char *name) 109 { 110 FARPROC proc = ::GetProcAddress(hinstGdiPlus, name); 111 return reinterpret_cast<TYPE>(proc); 112 } 113 114 static void init_gdip() 115 { 116 hinstGdiPlus = ::LoadLibraryA("gdiplus.dll"); 117 Startup = AddrOf<STARTUP>("GdiplusStartup"); 118 Shutdown = AddrOf<SHUTDOWN>("GdiplusShutdown"); 119 CreateBitmapFromFile = AddrOf<CREATEBITMAPFROMFILE>("GdipCreateBitmapFromFile"); 120 GetImagePixelFormat = AddrOf<GETPIXELFORMAT>("GdipGetImagePixelFormat"); 121 DisposeImage = AddrOf<DISPOSEIMAGE>("GdipDisposeImage"); 122 } 123 124 125 static void determine_file_bpp(TCHAR* tfile, Gdiplus::PixelFormat expect_pf) 126 { 127 using namespace Gdiplus; 128 GpBitmap *pBitmap = NULL; 129 130 #ifdef UNICODE 131 WCHAR* file = tfile; 132 #else 133 WCHAR file[MAX_PATH]; 134 ::MultiByteToWideChar(CP_ACP, 0, tfile, -1, file, MAX_PATH); 135 #endif 136 137 if (Startup == NULL) 138 init_gdip(); 139 140 Gdiplus::GdiplusStartupInput gdiplusStartupInput; 141 Startup(&gdiplusToken, &gdiplusStartupInput, NULL); 142 143 144 Gdiplus::GpStatus status = CreateBitmapFromFile(file, &pBitmap); 145 ok(status == Gdiplus::Ok, "Expected status to be %i, was: %i\n", (int)Gdiplus::Ok, (int)status); 146 ok(pBitmap != NULL, "Expected a valid bitmap\n"); 147 if (pBitmap) 148 { 149 PixelFormat pf; 150 GetImagePixelFormat(pBitmap, &pf); 151 ok(pf == expect_pf, "Expected PixelFormat to be 0x%x, was: 0x%x\n", (int)expect_pf, (int)pf); 152 153 DisposeImage(pBitmap); 154 } 155 Shutdown(gdiplusToken); 156 } 157 158 159 START_TEST(CImage) 160 { 161 HRESULT hr; 162 TCHAR* file; 163 BOOL bOK; 164 int width, height, bpp; 165 size_t n; 166 CImage image1, image2; 167 COLORREF color; 168 HDC hDC; 169 170 #if 0 171 width = image1.GetWidth(); 172 height = image1.GetHeight(); 173 bpp = image1.GetBPP(); 174 #endif 175 176 HINSTANCE hInst = GetModuleHandle(NULL); 177 GetTempPath(MAX_PATH, szTempPath); 178 179 image1.LoadFromResource(hInst, IDB_ANT); 180 ok(!image1.IsNull(), "Expected image1 is not null\n"); 181 182 width = image1.GetWidth(); 183 ok(width == 48, "Expected width to be 48, was: %d\n", width); 184 height = image1.GetHeight(); 185 ok(height == 48, "Expected height to be 48, was: %d\n", height); 186 bpp = image1.GetBPP(); 187 ok(bpp == 8, "Expected bpp to be 8, was: %d\n", bpp); 188 189 190 image2.LoadFromResource(hInst, IDB_CROSS); 191 ok(!image2.IsNull(), "Expected image2 is not null\n"); 192 image2.SetTransparentColor(RGB(255, 255, 255)); 193 194 width = image2.GetWidth(); 195 ok(width == 32, "Expected width to be 32, was: %d\n", width); 196 height = image2.GetHeight(); 197 ok(height == 32, "Expected height to be 32, was: %d\n", height); 198 bpp = image2.GetBPP(); 199 ok(bpp == 8, "Expected bpp to be 8, was: %d\n", bpp); 200 201 color = image1.GetPixel(5, 5); 202 ok(color == RGB(166, 202, 240), "Expected color to be 166, 202, 240; was: %i, %i, %i\n", GetRValue(color), GetGValue(color), GetBValue(color)); 203 204 hDC = image1.GetDC(); 205 bOK = image2.Draw(hDC, 0, 0); 206 image1.ReleaseDC(); 207 ok(bOK != FALSE, "Expected bDraw to be TRUE, was: %d\n", bOK); 208 image2.Destroy(); 209 210 color = image1.GetPixel(5, 5); 211 ok(color == RGB(255, 0,0), "Expected color to be 255, 0, 0; was: %i, %i, %i\n", GetRValue(color), GetGValue(color), GetBValue(color)); 212 213 file = file_name(TEXT("ant.bmp")); 214 write_bitmap(hInst, IDB_ANT, file); 215 216 init_gdip(); 217 218 determine_file_bpp(file, PixelFormat8bppIndexed); 219 220 hr = image2.Load(file); 221 ok(hr == S_OK, "Expected hr to be S_OK, was: %08lx\n", hr); 222 ok(!image2.IsNull(), "Expected image1 is not null\n"); 223 bOK = DeleteFile(file); 224 ok(bOK, "Expected bOK to be TRUE, was: %d\n", bOK); 225 226 width = image2.GetWidth(); 227 ok(width == 48, "Expected width to be 48, was: %d\n", width); 228 height = image2.GetHeight(); 229 ok(height == 48, "Expected height to be 48, was: %d\n", height); 230 bpp = image2.GetBPP(); 231 ok(bpp == 8, "Expected bpp to be 8, was: %d\n", bpp); 232 233 for (n = 0; n < _countof(szFiles); ++n) 234 { 235 file = file_name(szFiles[n]); 236 image2.Destroy(); 237 238 if (n == 0) 239 hr = image1.Save(file, Gdiplus::ImageFormatPNG); 240 else 241 hr = image1.Save(file); 242 ok(hr == S_OK, "Expected hr to be S_OK, was: %08lx (for %i)\n", hr, n); 243 244 bOK = (GetFileAttributes(file) != 0xFFFFFFFF); 245 ok(bOK, "Expected bOK to be TRUE, was: %d (for %i)\n", bOK, n); 246 247 hr = image2.Load(file); 248 ok(hr == S_OK, "Expected hr to be S_OK, was: %08lx (for %i)\n", hr, n); 249 250 width = image2.GetWidth(); 251 ok(width == 48, "Expected width to be 48, was: %d (for %i)\n", width, n); 252 height = image2.GetHeight(); 253 ok(height == 48, "Expected height to be 48, was: %d (for %i)\n", height, n); 254 bpp = image2.GetBPP(); 255 if (n == 3) 256 { 257 ok(bpp == 24, "Expected bpp to be 24, was: %d (for %i)\n", bpp, n); 258 determine_file_bpp(file, PixelFormat24bppRGB); 259 } 260 else 261 { 262 ok(bpp == 8, "Expected bpp to be 8, was: %d (for %i)\n", bpp, n); 263 determine_file_bpp(file, PixelFormat8bppIndexed); 264 } 265 color = image1.GetPixel(5, 5); 266 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); 267 268 bOK = DeleteFile(file); 269 ok(bOK, "Expected bOK to be TRUE, was: %d (for %i)\n", bOK, n); 270 } 271 272 ATL::IAtlStringMgr *mgr = CAtlStringMgr::GetInstance(); 273 CSimpleArray<GUID> aguidFileTypes; 274 #ifdef UNICODE 275 CHAR szBuff[512]; 276 const WCHAR *psz; 277 #else 278 const CHAR *psz; 279 #endif 280 281 CSimpleString strImporters(mgr); 282 aguidFileTypes.RemoveAll(); 283 hr = CImage::GetImporterFilterString(strImporters, 284 aguidFileTypes, 285 TEXT("All Image Files"), 0); 286 ok(hr == S_OK, "Expected hr to be S_OK, was: %ld\n", hr); 287 ok(aguidFileTypes.GetSize() == 9, "Expected aguidFileTypes.GetSize() to be 8, was %d.", aguidFileTypes.GetSize()); 288 ok(IsEqualGUID(aguidFileTypes[0], GUID_NULL), "Expected aguidFileTypes[0] to be GUID_NULL.\n"); 289 ok(IsEqualGUID(aguidFileTypes[1], Gdiplus::ImageFormatBMP), "Expected aguidFileTypes[1] to be Gdiplus::ImageFormatBMP.\n"); 290 ok(IsEqualGUID(aguidFileTypes[2], Gdiplus::ImageFormatJPEG), "Expected aguidFileTypes[2] to be Gdiplus::ImageFormatJPEG.\n"); 291 ok(IsEqualGUID(aguidFileTypes[3], Gdiplus::ImageFormatGIF), "Expected aguidFileTypes[3] to be Gdiplus::ImageFormatGIF.\n"); 292 ok(IsEqualGUID(aguidFileTypes[4], Gdiplus::ImageFormatEMF), "Expected aguidFileTypes[4] to be Gdiplus::ImageFormatEMF.\n"); 293 ok(IsEqualGUID(aguidFileTypes[5], Gdiplus::ImageFormatWMF), "Expected aguidFileTypes[5] to be Gdiplus::ImageFormatWMF.\n"); 294 ok(IsEqualGUID(aguidFileTypes[6], Gdiplus::ImageFormatTIFF), "Expected aguidFileTypes[6] to be Gdiplus::ImageFormatTIFF.\n"); 295 ok(IsEqualGUID(aguidFileTypes[7], Gdiplus::ImageFormatPNG), "Expected aguidFileTypes[7] to be Gdiplus::ImageFormatPNG.\n"); 296 ok(IsEqualGUID(aguidFileTypes[8], Gdiplus::ImageFormatIcon), "Expected aguidFileTypes[8] to be Gdiplus::ImageFormatIcon.\n"); 297 298 psz = strImporters.GetString(); 299 #ifdef UNICODE 300 WideCharToMultiByte(CP_ACP, 0, psz, -1, szBuff, 512, NULL, NULL); 301 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, 302 "The importer filter string is bad, was: %s\n", szBuff); 303 #else 304 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, 305 "The importer filter string is bad, was: %s\n", psz); 306 #endif 307 308 CSimpleString strExporters(mgr); 309 aguidFileTypes.RemoveAll(); 310 hr = CImage::GetExporterFilterString(strExporters, 311 aguidFileTypes, 312 TEXT("All Image Files"), 0); 313 ok(hr == S_OK, "Expected hr to be S_OK, was: %ld\n", hr); 314 ok(aguidFileTypes.GetSize() == 9, "Expected aguidFileTypes.GetSize() to be 8, was %d.", aguidFileTypes.GetSize()); 315 ok(IsEqualGUID(aguidFileTypes[0], GUID_NULL), "Expected aguidFileTypes[0] to be GUID_NULL.\n"); 316 ok(IsEqualGUID(aguidFileTypes[1], Gdiplus::ImageFormatBMP), "Expected aguidFileTypes[1] to be Gdiplus::ImageFormatBMP.\n"); 317 ok(IsEqualGUID(aguidFileTypes[2], Gdiplus::ImageFormatJPEG), "Expected aguidFileTypes[2] to be Gdiplus::ImageFormatJPEG.\n"); 318 ok(IsEqualGUID(aguidFileTypes[3], Gdiplus::ImageFormatGIF), "Expected aguidFileTypes[3] to be Gdiplus::ImageFormatGIF.\n"); 319 ok(IsEqualGUID(aguidFileTypes[4], Gdiplus::ImageFormatEMF), "Expected aguidFileTypes[4] to be Gdiplus::ImageFormatEMF.\n"); 320 ok(IsEqualGUID(aguidFileTypes[5], Gdiplus::ImageFormatWMF), "Expected aguidFileTypes[5] to be Gdiplus::ImageFormatWMF.\n"); 321 ok(IsEqualGUID(aguidFileTypes[6], Gdiplus::ImageFormatTIFF), "Expected aguidFileTypes[6] to be Gdiplus::ImageFormatTIFF.\n"); 322 ok(IsEqualGUID(aguidFileTypes[7], Gdiplus::ImageFormatPNG), "Expected aguidFileTypes[7] to be Gdiplus::ImageFormatPNG.\n"); 323 ok(IsEqualGUID(aguidFileTypes[8], Gdiplus::ImageFormatIcon), "Expected aguidFileTypes[8] to be Gdiplus::ImageFormatIcon.\n"); 324 325 psz = strExporters.GetString(); 326 #ifdef UNICODE 327 WideCharToMultiByte(CP_ACP, 0, psz, -1, szBuff, 512, NULL, NULL); 328 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, 329 "The exporter filter string is bad, was: %s\n", szBuff); 330 #else 331 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, 332 "The exporter filter string is bad, was: %s\n", psz); 333 #endif 334 335 #ifndef __REACTOS__ 336 printf("CImage: %i tests executed (0 marked as todo, %i failures), 0 skipped.\n", g_tests_executed, g_tests_failed); 337 return g_tests_failed; 338 #endif 339 } 340