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