1 /* 2 * Unit test suite for images 3 * 4 * Copyright (C) 2007 Google (Evan Stade) 5 * Copyright (C) 2012, 2016 Dmitry Timoshkov 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #define COBJMACROS 23 24 #include <math.h> 25 #include <assert.h> 26 #include <stdio.h> 27 28 #include "initguid.h" 29 #include "objbase.h" 30 #include "gdiplus.h" 31 #include "wine/test.h" 32 33 #ifdef __REACTOS__ 34 #include <ole2.h> 35 #endif 36 37 /* FIXME: They belong to gdipluseffects.h */ 38 DEFINE_GUID(BlurEffectGuid, 0x633c80a4, 0x1843, 0x482b, 0x9e, 0xf2, 0xbe, 0x28, 0x34, 0xc5, 0xfd, 0xd4); 39 DEFINE_GUID(SharpenEffectGuid, 0x63cbf3ee, 0xc526, 0x402c, 0x8f, 0x71, 0x62, 0xc5, 0x40, 0xbf, 0x51, 0x42); 40 DEFINE_GUID(ColorMatrixEffectGuid, 0x718f2615, 0x7933, 0x40e3, 0xa5, 0x11, 0x5f, 0x68, 0xfe, 0x14, 0xdd, 0x74); 41 DEFINE_GUID(ColorLUTEffectGuid, 0xa7ce72a9, 0x0f7f, 0x40d7, 0xb3, 0xcc, 0xd0, 0xc0, 0x2d, 0x5c, 0x32, 0x12); 42 DEFINE_GUID(BrightnessContrastEffectGuid, 0xd3a1dbe1, 0x8ec4, 0x4c17, 0x9f, 0x4c, 0xea, 0x97, 0xad, 0x1c, 0x34, 0x3d); 43 DEFINE_GUID(HueSaturationLightnessEffectGuid, 0x8b2dd6c3, 0xeb07, 0x4d87, 0xa5, 0xf0, 0x71, 0x08, 0xe2, 0x6a, 0x9c, 0x5f); 44 DEFINE_GUID(LevelsEffectGuid, 0x99c354ec, 0x2a31, 0x4f3a, 0x8c, 0x34, 0x17, 0xa8, 0x03, 0xb3, 0x3a, 0x25); 45 DEFINE_GUID(TintEffectGuid, 0x1077af00, 0x2848, 0x4441, 0x94, 0x89, 0x44, 0xad, 0x4c, 0x2d, 0x7a, 0x2c); 46 DEFINE_GUID(ColorBalanceEffectGuid, 0x537e597d, 0x251e, 0x48da, 0x96, 0x64, 0x29, 0xca, 0x49, 0x6b, 0x70, 0xf8); 47 DEFINE_GUID(RedEyeCorrectionEffectGuid, 0x74d29d05, 0x69a4, 0x4266, 0x95, 0x49, 0x3c, 0xc5, 0x28, 0x36, 0xb6, 0x32); 48 DEFINE_GUID(ColorCurveEffectGuid, 0xdd6a0022, 0x58e4, 0x4a67, 0x9d, 0x9b, 0xd4, 0x8e, 0xb8, 0x81, 0xa5, 0x3d); 49 50 static GpStatus (WINAPI *pGdipBitmapGetHistogramSize)(HistogramFormat,UINT*); 51 static GpStatus (WINAPI *pGdipBitmapGetHistogram)(GpBitmap*,HistogramFormat,UINT,UINT*,UINT*,UINT*,UINT*); 52 static GpStatus (WINAPI *pGdipImageSetAbort)(GpImage*,GdiplusAbort*); 53 54 static GpStatus (WINGDIPAPI *pGdipInitializePalette)(ColorPalette*,PaletteType,INT,BOOL,GpBitmap*); 55 56 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got)) 57 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got)) 58 59 static BOOL color_match(ARGB c1, ARGB c2, BYTE max_diff) 60 { 61 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE; 62 c1 >>= 8; c2 >>= 8; 63 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE; 64 c1 >>= 8; c2 >>= 8; 65 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE; 66 c1 >>= 8; c2 >>= 8; 67 if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE; 68 return TRUE; 69 } 70 71 static void expect_guid(REFGUID expected, REFGUID got, int line, BOOL todo) 72 { 73 WCHAR bufferW[39]; 74 char buffer[39]; 75 char buffer2[39]; 76 77 StringFromGUID2(got, bufferW, ARRAY_SIZE(bufferW)); 78 WideCharToMultiByte(CP_ACP, 0, bufferW, ARRAY_SIZE(bufferW), buffer, sizeof(buffer), NULL, NULL); 79 StringFromGUID2(expected, bufferW, ARRAY_SIZE(bufferW)); 80 WideCharToMultiByte(CP_ACP, 0, bufferW, ARRAY_SIZE(bufferW), buffer2, sizeof(buffer2), NULL, NULL); 81 todo_wine_if (todo) 82 ok_(__FILE__, line)(IsEqualGUID(expected, got), "Expected %s, got %s\n", buffer2, buffer); 83 } 84 85 static void expect_rawformat(REFGUID expected, GpImage *img, int line, BOOL todo) 86 { 87 GUID raw; 88 GpStatus stat; 89 90 stat = GdipGetImageRawFormat(img, &raw); 91 ok_(__FILE__, line)(stat == Ok, "GdipGetImageRawFormat failed with %d\n", stat); 92 if(stat != Ok) return; 93 expect_guid(expected, &raw, line, todo); 94 } 95 96 static void test_bufferrawformat(void* buff, int size, REFGUID expected, int line, BOOL todo) 97 { 98 LPSTREAM stream; 99 HGLOBAL hglob; 100 LPBYTE data; 101 HRESULT hres; 102 GpStatus stat; 103 GpImage *img; 104 105 hglob = GlobalAlloc (0, size); 106 data = GlobalLock (hglob); 107 memcpy(data, buff, size); 108 GlobalUnlock(hglob); data = NULL; 109 110 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream); 111 ok_(__FILE__, line)(hres == S_OK, "Failed to create a stream\n"); 112 if(hres != S_OK) return; 113 114 stat = GdipLoadImageFromStream(stream, &img); 115 ok_(__FILE__, line)(stat == Ok, "Failed to create a Bitmap\n"); 116 if(stat != Ok){ 117 IStream_Release(stream); 118 return; 119 } 120 121 expect_rawformat(expected, img, line, todo); 122 123 GdipDisposeImage(img); 124 IStream_Release(stream); 125 } 126 127 static void test_Scan0(void) 128 { 129 GpBitmap *bm; 130 GpStatus stat; 131 BYTE buff[360]; 132 133 bm = NULL; 134 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, &bm); 135 expect(Ok, stat); 136 ok(NULL != bm, "Expected bitmap to be initialized\n"); 137 if (stat == Ok) 138 GdipDisposeImage((GpImage*)bm); 139 140 bm = (GpBitmap*)0xdeadbeef; 141 stat = GdipCreateBitmapFromScan0(10, -10, 10, PixelFormat24bppRGB, NULL, &bm); 142 expect(InvalidParameter, stat); 143 ok( !bm, "expected null bitmap\n" ); 144 145 bm = (GpBitmap*)0xdeadbeef; 146 stat = GdipCreateBitmapFromScan0(-10, 10, 10, PixelFormat24bppRGB, NULL, &bm); 147 expect(InvalidParameter, stat); 148 ok( !bm, "expected null bitmap\n" ); 149 150 bm = (GpBitmap*)0xdeadbeef; 151 stat = GdipCreateBitmapFromScan0(10, 0, 10, PixelFormat24bppRGB, NULL, &bm); 152 expect(InvalidParameter, stat); 153 ok( !bm, "expected null bitmap\n" ); 154 155 bm = NULL; 156 stat = GdipCreateBitmapFromScan0(10, 10, 12, PixelFormat24bppRGB, buff, &bm); 157 expect(Ok, stat); 158 ok(NULL != bm, "Expected bitmap to be initialized\n"); 159 if (stat == Ok) 160 GdipDisposeImage((GpImage*)bm); 161 162 bm = (GpBitmap*) 0xdeadbeef; 163 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, buff, &bm); 164 expect(InvalidParameter, stat); 165 ok( !bm, "expected null bitmap\n" ); 166 167 bm = (GpBitmap*)0xdeadbeef; 168 stat = GdipCreateBitmapFromScan0(10, 10, 0, PixelFormat24bppRGB, buff, &bm); 169 expect(InvalidParameter, stat); 170 ok( bm == (GpBitmap*)0xdeadbeef, "expected deadbeef bitmap\n" ); 171 172 bm = NULL; 173 stat = GdipCreateBitmapFromScan0(10, 10, -8, PixelFormat24bppRGB, buff, &bm); 174 expect(Ok, stat); 175 ok(NULL != bm, "Expected bitmap to be initialized\n"); 176 if (stat == Ok) 177 GdipDisposeImage((GpImage*)bm); 178 179 bm = (GpBitmap*)0xdeadbeef; 180 stat = GdipCreateBitmapFromScan0(10, 10, -10, PixelFormat24bppRGB, buff, &bm); 181 expect(InvalidParameter, stat); 182 ok( !bm, "expected null bitmap\n" ); 183 } 184 185 static void test_FromGdiDib(void) 186 { 187 GpBitmap *bm; 188 GpStatus stat; 189 BYTE buff[400]; 190 BYTE rbmi[sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)]; 191 BITMAPINFO *bmi = (BITMAPINFO*)rbmi; 192 PixelFormat format; 193 194 bm = NULL; 195 196 memset(rbmi, 0, sizeof(rbmi)); 197 198 bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 199 bmi->bmiHeader.biWidth = 10; 200 bmi->bmiHeader.biHeight = 10; 201 bmi->bmiHeader.biPlanes = 1; 202 bmi->bmiHeader.biBitCount = 32; 203 bmi->bmiHeader.biCompression = BI_RGB; 204 205 stat = GdipCreateBitmapFromGdiDib(NULL, buff, &bm); 206 expect(InvalidParameter, stat); 207 208 stat = GdipCreateBitmapFromGdiDib(bmi, NULL, &bm); 209 expect(InvalidParameter, stat); 210 211 stat = GdipCreateBitmapFromGdiDib(bmi, buff, NULL); 212 expect(InvalidParameter, stat); 213 214 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm); 215 expect(Ok, stat); 216 ok(NULL != bm, "Expected bitmap to be initialized\n"); 217 if (stat == Ok) 218 { 219 stat = GdipGetImagePixelFormat((GpImage*)bm, &format); 220 expect(Ok, stat); 221 expect(PixelFormat32bppRGB, format); 222 223 GdipDisposeImage((GpImage*)bm); 224 } 225 226 bmi->bmiHeader.biBitCount = 24; 227 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm); 228 expect(Ok, stat); 229 ok(NULL != bm, "Expected bitmap to be initialized\n"); 230 if (stat == Ok) 231 { 232 stat = GdipGetImagePixelFormat((GpImage*)bm, &format); 233 expect(Ok, stat); 234 expect(PixelFormat24bppRGB, format); 235 236 GdipDisposeImage((GpImage*)bm); 237 } 238 239 bmi->bmiHeader.biBitCount = 16; 240 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm); 241 expect(Ok, stat); 242 ok(NULL != bm, "Expected bitmap to be initialized\n"); 243 if (stat == Ok) 244 { 245 stat = GdipGetImagePixelFormat((GpImage*)bm, &format); 246 expect(Ok, stat); 247 expect(PixelFormat16bppRGB555, format); 248 249 GdipDisposeImage((GpImage*)bm); 250 } 251 252 bmi->bmiHeader.biBitCount = 8; 253 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm); 254 expect(Ok, stat); 255 ok(NULL != bm, "Expected bitmap to be initialized\n"); 256 if (stat == Ok) 257 { 258 stat = GdipGetImagePixelFormat((GpImage*)bm, &format); 259 expect(Ok, stat); 260 expect(PixelFormat8bppIndexed, format); 261 262 GdipDisposeImage((GpImage*)bm); 263 } 264 265 bmi->bmiHeader.biBitCount = 4; 266 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm); 267 expect(Ok, stat); 268 ok(NULL != bm, "Expected bitmap to be initialized\n"); 269 if (stat == Ok) 270 { 271 stat = GdipGetImagePixelFormat((GpImage*)bm, &format); 272 expect(Ok, stat); 273 expect(PixelFormat4bppIndexed, format); 274 275 GdipDisposeImage((GpImage*)bm); 276 } 277 278 bmi->bmiHeader.biBitCount = 1; 279 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm); 280 expect(Ok, stat); 281 ok(NULL != bm, "Expected bitmap to be initialized\n"); 282 if (stat == Ok) 283 { 284 stat = GdipGetImagePixelFormat((GpImage*)bm, &format); 285 expect(Ok, stat); 286 expect(PixelFormat1bppIndexed, format); 287 288 GdipDisposeImage((GpImage*)bm); 289 } 290 291 bmi->bmiHeader.biBitCount = 0; 292 stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm); 293 expect(InvalidParameter, stat); 294 } 295 296 static void test_GetImageDimension(void) 297 { 298 GpBitmap *bm; 299 GpStatus stat; 300 const REAL WIDTH = 10.0, HEIGHT = 20.0; 301 REAL w,h; 302 303 bm = (GpBitmap*)0xdeadbeef; 304 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm); 305 expect(Ok,stat); 306 ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n"); 307 ok(NULL != bm, "Expected bitmap to not be NULL\n"); 308 309 stat = GdipGetImageDimension(NULL,&w,&h); 310 expect(InvalidParameter, stat); 311 312 stat = GdipGetImageDimension((GpImage*)bm,NULL,&h); 313 expect(InvalidParameter, stat); 314 315 stat = GdipGetImageDimension((GpImage*)bm,&w,NULL); 316 expect(InvalidParameter, stat); 317 318 w = -1; 319 h = -1; 320 stat = GdipGetImageDimension((GpImage*)bm,&w,&h); 321 expect(Ok, stat); 322 expectf(WIDTH, w); 323 expectf(HEIGHT, h); 324 GdipDisposeImage((GpImage*)bm); 325 } 326 327 static void test_GdipImageGetFrameDimensionsCount(void) 328 { 329 GpBitmap *bm; 330 GpStatus stat; 331 const REAL WIDTH = 10.0, HEIGHT = 20.0; 332 UINT w; 333 GUID dimension = {0}; 334 UINT count; 335 ARGB color; 336 337 bm = (GpBitmap*)0xdeadbeef; 338 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB,NULL, &bm); 339 expect(Ok,stat); 340 ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n"); 341 ok(NULL != bm, "Expected bitmap to not be NULL\n"); 342 343 stat = GdipImageGetFrameDimensionsCount(NULL,&w); 344 expect(InvalidParameter, stat); 345 346 stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,NULL); 347 expect(InvalidParameter, stat); 348 349 w = -1; 350 stat = GdipImageGetFrameDimensionsCount((GpImage*)bm,&w); 351 expect(Ok, stat); 352 expect(1, w); 353 354 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 1); 355 expect(Ok, stat); 356 expect_guid(&FrameDimensionPage, &dimension, __LINE__, FALSE); 357 358 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 2); 359 expect(InvalidParameter, stat); 360 361 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 0); 362 expect(InvalidParameter, stat); 363 364 stat = GdipImageGetFrameCount(NULL, &dimension, &count); 365 expect(InvalidParameter, stat); 366 367 /* WinXP crashes on this test */ 368 if(0) 369 { 370 stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, NULL); 371 expect(InvalidParameter, stat); 372 } 373 374 stat = GdipImageGetFrameCount((GpImage*)bm, NULL, &count); 375 expect(Ok, stat); 376 377 count = 12345; 378 stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, &count); 379 expect(Ok, stat); 380 expect(1, count); 381 382 GdipBitmapSetPixel(bm, 0, 0, 0xffffffff); 383 384 stat = GdipImageSelectActiveFrame((GpImage*)bm, &dimension, 0); 385 expect(Ok, stat); 386 387 /* SelectActiveFrame has no effect on image data of memory bitmaps */ 388 color = 0xdeadbeef; 389 stat = GdipBitmapGetPixel(bm, 0, 0, &color); 390 expect(Ok, stat); 391 expect(0xffffffff, color); 392 393 GdipDisposeImage((GpImage*)bm); 394 } 395 396 static void test_LoadingImages(void) 397 { 398 GpStatus stat; 399 GpBitmap *bm; 400 GpImage *img; 401 static const WCHAR nonexistentW[] = {'n','o','n','e','x','i','s','t','e','n','t',0}; 402 403 stat = GdipCreateBitmapFromFile(0, 0); 404 expect(InvalidParameter, stat); 405 406 bm = (GpBitmap *)0xdeadbeef; 407 stat = GdipCreateBitmapFromFile(0, &bm); 408 expect(InvalidParameter, stat); 409 ok(bm == (GpBitmap *)0xdeadbeef, "returned %p\n", bm); 410 411 bm = (GpBitmap *)0xdeadbeef; 412 stat = GdipCreateBitmapFromFile(nonexistentW, &bm); 413 todo_wine expect(InvalidParameter, stat); 414 ok(!bm, "returned %p\n", bm); 415 416 stat = GdipLoadImageFromFile(0, 0); 417 expect(InvalidParameter, stat); 418 419 img = (GpImage *)0xdeadbeef; 420 stat = GdipLoadImageFromFile(0, &img); 421 expect(InvalidParameter, stat); 422 ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img); 423 424 img = (GpImage *)0xdeadbeef; 425 stat = GdipLoadImageFromFile(nonexistentW, &img); 426 todo_wine expect(OutOfMemory, stat); 427 ok(!img, "returned %p\n", img); 428 429 stat = GdipLoadImageFromFileICM(0, 0); 430 expect(InvalidParameter, stat); 431 432 img = (GpImage *)0xdeadbeef; 433 stat = GdipLoadImageFromFileICM(0, &img); 434 expect(InvalidParameter, stat); 435 ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img); 436 437 img = (GpImage *)0xdeadbeef; 438 stat = GdipLoadImageFromFileICM(nonexistentW, &img); 439 todo_wine expect(OutOfMemory, stat); 440 ok(!img, "returned %p\n", img); 441 } 442 443 static void test_SavingImages(void) 444 { 445 GpStatus stat; 446 GpBitmap *bm; 447 UINT n; 448 UINT s; 449 const REAL WIDTH = 10.0, HEIGHT = 20.0; 450 REAL w, h; 451 ImageCodecInfo *codecs; 452 static const CHAR filenameA[] = "a.bmp"; 453 static const WCHAR filename[] = { 'a','.','b','m','p',0 }; 454 455 codecs = NULL; 456 457 stat = GdipSaveImageToFile(0, 0, 0, 0); 458 expect(InvalidParameter, stat); 459 460 bm = NULL; 461 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm); 462 expect(Ok, stat); 463 if (!bm) 464 return; 465 466 /* invalid params */ 467 stat = GdipSaveImageToFile((GpImage*)bm, 0, 0, 0); 468 expect(InvalidParameter, stat); 469 470 stat = GdipSaveImageToFile((GpImage*)bm, filename, 0, 0); 471 expect(InvalidParameter, stat); 472 473 /* encoder tests should succeed -- already tested */ 474 stat = GdipGetImageEncodersSize(&n, &s); 475 if (stat != Ok || n == 0) goto cleanup; 476 477 codecs = GdipAlloc(s); 478 if (!codecs) goto cleanup; 479 480 stat = GdipGetImageEncoders(n, s, codecs); 481 if (stat != Ok) goto cleanup; 482 483 stat = GdipSaveImageToFile((GpImage*)bm, filename, &codecs[0].Clsid, 0); 484 expect(Ok, stat); 485 486 GdipDisposeImage((GpImage*)bm); 487 bm = 0; 488 489 /* re-load and check image stats */ 490 stat = GdipLoadImageFromFile(filename, (GpImage**)&bm); 491 expect(Ok, stat); 492 if (stat != Ok) goto cleanup; 493 494 stat = GdipGetImageDimension((GpImage*)bm, &w, &h); 495 if (stat != Ok) goto cleanup; 496 497 expectf(WIDTH, w); 498 expectf(HEIGHT, h); 499 500 cleanup: 501 GdipFree(codecs); 502 if (bm) 503 GdipDisposeImage((GpImage*)bm); 504 ok(DeleteFileA(filenameA), "Delete failed.\n"); 505 } 506 507 static void test_encoders(void) 508 { 509 GpStatus stat; 510 UINT n; 511 UINT s; 512 ImageCodecInfo *codecs; 513 int i; 514 int bmp_found; 515 516 static const CHAR bmp_format[] = "BMP"; 517 518 stat = GdipGetImageEncodersSize(&n, &s); 519 expect(stat, Ok); 520 521 codecs = GdipAlloc(s); 522 if (!codecs) 523 return; 524 525 stat = GdipGetImageEncoders(n, s, NULL); 526 expect(GenericError, stat); 527 528 stat = GdipGetImageEncoders(0, s, codecs); 529 expect(GenericError, stat); 530 531 stat = GdipGetImageEncoders(n, s-1, codecs); 532 expect(GenericError, stat); 533 534 stat = GdipGetImageEncoders(n, s+1, codecs); 535 expect(GenericError, stat); 536 537 stat = GdipGetImageEncoders(n, s, codecs); 538 expect(stat, Ok); 539 540 bmp_found = FALSE; 541 for (i = 0; i < n; i++) 542 { 543 CHAR desc[32]; 544 545 WideCharToMultiByte(CP_ACP, 0, codecs[i].FormatDescription, -1, 546 desc, 32, 0, 0); 547 548 if (CompareStringA(LOCALE_SYSTEM_DEFAULT, 0, 549 desc, -1, 550 bmp_format, -1) == CSTR_EQUAL) { 551 bmp_found = TRUE; 552 break; 553 } 554 } 555 if (!bmp_found) 556 ok(FALSE, "No BMP codec found.\n"); 557 558 GdipFree(codecs); 559 } 560 561 static void test_LockBits(void) 562 { 563 GpStatus stat; 564 GpBitmap *bm; 565 GpRect rect; 566 BitmapData bd; 567 const INT WIDTH = 10, HEIGHT = 20; 568 ARGB color; 569 int y; 570 571 bm = NULL; 572 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm); 573 expect(Ok, stat); 574 575 rect.X = 2; 576 rect.Y = 3; 577 rect.Width = 4; 578 rect.Height = 5; 579 580 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000); 581 expect(Ok, stat); 582 583 stat = GdipBitmapSetPixel(bm, 2, 8, 0xff480000); 584 expect(Ok, stat); 585 586 /* read-only */ 587 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd); 588 expect(Ok, stat); 589 590 if (stat == Ok) { 591 expect(0xc3, ((BYTE*)bd.Scan0)[2]); 592 expect(0x48, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]); 593 594 ((char*)bd.Scan0)[2] = 0xff; 595 596 stat = GdipBitmapUnlockBits(bm, &bd); 597 expect(Ok, stat); 598 } 599 600 stat = GdipBitmapGetPixel(bm, 2, 3, &color); 601 expect(Ok, stat); 602 expect(0xffff0000, color); 603 604 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000); 605 expect(Ok, stat); 606 607 /* read-only, with NULL rect -> whole bitmap lock */ 608 stat = GdipBitmapLockBits(bm, NULL, ImageLockModeRead, PixelFormat24bppRGB, &bd); 609 expect(Ok, stat); 610 expect(bd.Width, WIDTH); 611 expect(bd.Height, HEIGHT); 612 613 if (stat == Ok) { 614 ((char*)bd.Scan0)[2 + 2*3 + 3*bd.Stride] = 0xff; 615 616 stat = GdipBitmapUnlockBits(bm, &bd); 617 expect(Ok, stat); 618 } 619 620 stat = GdipBitmapGetPixel(bm, 2, 3, &color); 621 expect(Ok, stat); 622 expect(0xffff0000, color); 623 624 /* read-only, consecutive */ 625 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd); 626 expect(Ok, stat); 627 628 if (stat == Ok) { 629 stat = GdipBitmapUnlockBits(bm, &bd); 630 expect(Ok, stat); 631 } 632 633 stat = GdipDisposeImage((GpImage*)bm); 634 expect(Ok, stat); 635 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm); 636 expect(Ok, stat); 637 638 /* read x2 */ 639 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd); 640 expect(Ok, stat); 641 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd); 642 expect(WrongState, stat); 643 644 stat = GdipBitmapUnlockBits(bm, &bd); 645 expect(Ok, stat); 646 647 stat = GdipDisposeImage((GpImage*)bm); 648 expect(Ok, stat); 649 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm); 650 expect(Ok, stat); 651 652 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffff0000); 653 expect(Ok, stat); 654 655 stat = GdipBitmapSetPixel(bm, 2, 8, 0xffc30000); 656 expect(Ok, stat); 657 658 /* write, no conversion */ 659 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd); 660 expect(Ok, stat); 661 662 if (stat == Ok) { 663 /* all bits are readable, inside the rect or not */ 664 expect(0xff, ((BYTE*)bd.Scan0)[2]); 665 expect(0xc3, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]); 666 667 stat = GdipBitmapUnlockBits(bm, &bd); 668 expect(Ok, stat); 669 } 670 671 /* read, conversion */ 672 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat32bppARGB, &bd); 673 expect(Ok, stat); 674 675 if (stat == Ok) { 676 expect(0xff, ((BYTE*)bd.Scan0)[2]); 677 if (0) 678 /* Areas outside the rectangle appear to be uninitialized */ 679 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n"); 680 681 ((BYTE*)bd.Scan0)[2] = 0xc3; 682 683 stat = GdipBitmapUnlockBits(bm, &bd); 684 expect(Ok, stat); 685 } 686 687 /* writes do not work in read mode if there was a conversion */ 688 stat = GdipBitmapGetPixel(bm, 2, 3, &color); 689 expect(Ok, stat); 690 expect(0xffff0000, color); 691 692 /* read/write, conversion */ 693 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeWrite, PixelFormat32bppARGB, &bd); 694 expect(Ok, stat); 695 696 if (stat == Ok) { 697 expect(0xff, ((BYTE*)bd.Scan0)[2]); 698 ((BYTE*)bd.Scan0)[1] = 0x88; 699 if (0) 700 /* Areas outside the rectangle appear to be uninitialized */ 701 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n"); 702 703 stat = GdipBitmapUnlockBits(bm, &bd); 704 expect(Ok, stat); 705 } 706 707 stat = GdipBitmapGetPixel(bm, 2, 3, &color); 708 expect(Ok, stat); 709 expect(0xffff8800, color); 710 711 /* write, conversion */ 712 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat32bppARGB, &bd); 713 expect(Ok, stat); 714 715 if (stat == Ok) { 716 if (0) 717 { 718 /* This is completely uninitialized. */ 719 ok(0xff != ((BYTE*)bd.Scan0)[2], "original image bits are readable\n"); 720 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n"); 721 } 722 723 /* Initialize the buffer so the unlock doesn't access undefined memory */ 724 for (y=0; y<5; y++) 725 memset(((BYTE*)bd.Scan0) + bd.Stride * y, 0, 12); 726 727 ((BYTE*)bd.Scan0)[0] = 0x12; 728 ((BYTE*)bd.Scan0)[1] = 0x34; 729 ((BYTE*)bd.Scan0)[2] = 0x56; 730 731 stat = GdipBitmapUnlockBits(bm, &bd); 732 expect(Ok, stat); 733 } 734 735 stat = GdipBitmapGetPixel(bm, 2, 3, &color); 736 expect(Ok, stat); 737 expect(0xff563412, color); 738 739 stat = GdipBitmapGetPixel(bm, 2, 8, &color); 740 expect(Ok, stat); 741 expect(0xffc30000, color); 742 743 stat = GdipDisposeImage((GpImage*)bm); 744 expect(Ok, stat); 745 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm); 746 expect(Ok, stat); 747 748 /* write, no modification */ 749 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd); 750 expect(Ok, stat); 751 752 if (stat == Ok) { 753 stat = GdipBitmapUnlockBits(bm, &bd); 754 expect(Ok, stat); 755 } 756 757 /* write, consecutive */ 758 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd); 759 expect(Ok, stat); 760 761 if (stat == Ok) { 762 stat = GdipBitmapUnlockBits(bm, &bd); 763 expect(Ok, stat); 764 } 765 766 stat = GdipDisposeImage((GpImage*)bm); 767 expect(Ok, stat); 768 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm); 769 expect(Ok, stat); 770 771 /* write, modify */ 772 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite, PixelFormat24bppRGB, &bd); 773 expect(Ok, stat); 774 775 if (stat == Ok) { 776 if (bd.Scan0) 777 ((char*)bd.Scan0)[2] = 0xff; 778 779 stat = GdipBitmapUnlockBits(bm, &bd); 780 expect(Ok, stat); 781 } 782 783 stat = GdipBitmapGetPixel(bm, 2, 3, &color); 784 expect(Ok, stat); 785 expect(0xffff0000, color); 786 787 stat = GdipDisposeImage((GpImage*)bm); 788 expect(Ok, stat); 789 790 /* dispose locked */ 791 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm); 792 expect(Ok, stat); 793 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead, PixelFormat24bppRGB, &bd); 794 expect(Ok, stat); 795 stat = GdipDisposeImage((GpImage*)bm); 796 expect(Ok, stat); 797 } 798 799 static void test_LockBits_UserBuf(void) 800 { 801 GpStatus stat; 802 GpBitmap *bm; 803 GpRect rect; 804 BitmapData bd; 805 const INT WIDTH = 10, HEIGHT = 20; 806 DWORD bits[200]; 807 ARGB color; 808 809 bm = NULL; 810 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat32bppARGB, NULL, &bm); 811 expect(Ok, stat); 812 813 memset(bits, 0xaa, sizeof(bits)); 814 815 rect.X = 2; 816 rect.Y = 3; 817 rect.Width = 4; 818 rect.Height = 5; 819 820 bd.Width = 4; 821 bd.Height = 6; 822 bd.Stride = WIDTH * 4; 823 bd.PixelFormat = PixelFormat32bppARGB; 824 bd.Scan0 = &bits[2+3*WIDTH]; 825 bd.Reserved = 0xaaaaaaaa; 826 827 /* read-only */ 828 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd); 829 expect(Ok, stat); 830 831 expect(0xaaaaaaaa, bits[0]); 832 expect(0, bits[2+3*WIDTH]); 833 834 bits[2+3*WIDTH] = 0xdeadbeef; 835 836 if (stat == Ok) { 837 stat = GdipBitmapUnlockBits(bm, &bd); 838 expect(Ok, stat); 839 } 840 841 stat = GdipBitmapGetPixel(bm, 2, 3, &color); 842 expect(Ok, stat); 843 expect(0, color); 844 845 /* write-only */ 846 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeWrite|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd); 847 expect(Ok, stat); 848 849 expect(0xdeadbeef, bits[2+3*WIDTH]); 850 bits[2+3*WIDTH] = 0x12345678; 851 852 if (stat == Ok) { 853 stat = GdipBitmapUnlockBits(bm, &bd); 854 expect(Ok, stat); 855 } 856 857 stat = GdipBitmapGetPixel(bm, 2, 3, &color); 858 expect(Ok, stat); 859 expect(0x12345678, color); 860 861 bits[2+3*WIDTH] = 0; 862 863 /* read/write */ 864 stat = GdipBitmapLockBits(bm, &rect, ImageLockModeRead|ImageLockModeWrite|ImageLockModeUserInputBuf, PixelFormat32bppARGB, &bd); 865 expect(Ok, stat); 866 867 expect(0x12345678, bits[2+3*WIDTH]); 868 bits[2+3*WIDTH] = 0xdeadbeef; 869 870 if (stat == Ok) { 871 stat = GdipBitmapUnlockBits(bm, &bd); 872 expect(Ok, stat); 873 } 874 875 stat = GdipBitmapGetPixel(bm, 2, 3, &color); 876 expect(Ok, stat); 877 expect(0xdeadbeef, color); 878 879 stat = GdipDisposeImage((GpImage*)bm); 880 expect(Ok, stat); 881 } 882 883 struct BITMAPINFOWITHBITFIELDS 884 { 885 BITMAPINFOHEADER bmiHeader; 886 DWORD masks[3]; 887 }; 888 889 union BITMAPINFOUNION 890 { 891 BITMAPINFO bi; 892 struct BITMAPINFOWITHBITFIELDS bf; 893 }; 894 895 static void test_GdipCreateBitmapFromHBITMAP(void) 896 { 897 GpBitmap* gpbm = NULL; 898 HBITMAP hbm = NULL; 899 HPALETTE hpal = NULL; 900 GpStatus stat; 901 BYTE buff[1000]; 902 LOGPALETTE* LogPal = NULL; 903 REAL width, height; 904 const REAL WIDTH1 = 5; 905 const REAL HEIGHT1 = 15; 906 const REAL WIDTH2 = 10; 907 const REAL HEIGHT2 = 20; 908 HDC hdc; 909 union BITMAPINFOUNION bmi; 910 BYTE *bits; 911 PixelFormat format; 912 913 stat = GdipCreateBitmapFromHBITMAP(NULL, NULL, NULL); 914 expect(InvalidParameter, stat); 915 916 hbm = CreateBitmap(WIDTH1, HEIGHT1, 1, 1, NULL); 917 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, NULL); 918 expect(InvalidParameter, stat); 919 920 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm); 921 expect(Ok, stat); 922 expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height)); 923 expectf(WIDTH1, width); 924 expectf(HEIGHT1, height); 925 if (stat == Ok) 926 GdipDisposeImage((GpImage*)gpbm); 927 DeleteObject(hbm); 928 929 memset(buff, 0, sizeof(buff)); 930 hbm = CreateBitmap(WIDTH2, HEIGHT2, 1, 1, &buff); 931 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm); 932 expect(Ok, stat); 933 /* raw format */ 934 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)gpbm, __LINE__, FALSE); 935 936 expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height)); 937 expectf(WIDTH2, width); 938 expectf(HEIGHT2, height); 939 if (stat == Ok) 940 GdipDisposeImage((GpImage*)gpbm); 941 DeleteObject(hbm); 942 943 hdc = CreateCompatibleDC(0); 944 ok(hdc != NULL, "CreateCompatibleDC failed\n"); 945 bmi.bi.bmiHeader.biSize = sizeof(bmi.bi.bmiHeader); 946 bmi.bi.bmiHeader.biHeight = HEIGHT1; 947 bmi.bi.bmiHeader.biWidth = WIDTH1; 948 bmi.bi.bmiHeader.biBitCount = 24; 949 bmi.bi.bmiHeader.biPlanes = 1; 950 bmi.bi.bmiHeader.biCompression = BI_RGB; 951 bmi.bi.bmiHeader.biClrUsed = 0; 952 953 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 954 ok(hbm != NULL, "CreateDIBSection failed\n"); 955 956 bits[0] = 0; 957 958 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm); 959 expect(Ok, stat); 960 expect(Ok, GdipGetImageDimension((GpImage*) gpbm, &width, &height)); 961 expectf(WIDTH1, width); 962 expectf(HEIGHT1, height); 963 if (stat == Ok) 964 { 965 /* test whether writing to the bitmap affects the original */ 966 stat = GdipBitmapSetPixel(gpbm, 0, 0, 0xffffffff); 967 expect(Ok, stat); 968 969 expect(0, bits[0]); 970 971 GdipDisposeImage((GpImage*)gpbm); 972 } 973 974 LogPal = GdipAlloc(sizeof(LOGPALETTE)); 975 ok(LogPal != NULL, "unable to allocate LOGPALETTE\n"); 976 LogPal->palVersion = 0x300; 977 LogPal->palNumEntries = 1; 978 hpal = CreatePalette(LogPal); 979 ok(hpal != NULL, "CreatePalette failed\n"); 980 GdipFree(LogPal); 981 982 stat = GdipCreateBitmapFromHBITMAP(hbm, hpal, &gpbm); 983 expect(Ok, stat); 984 985 if (stat == Ok) 986 GdipDisposeImage((GpImage*)gpbm); 987 988 DeleteObject(hpal); 989 DeleteObject(hbm); 990 991 /* 16-bit 555 dib, rgb */ 992 bmi.bi.bmiHeader.biBitCount = 16; 993 bmi.bi.bmiHeader.biCompression = BI_RGB; 994 995 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 996 ok(hbm != NULL, "CreateDIBSection failed\n"); 997 998 bits[0] = 0; 999 1000 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm); 1001 expect(Ok, stat); 1002 1003 if (stat == Ok) 1004 { 1005 stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height); 1006 expect(Ok, stat); 1007 expectf(WIDTH1, width); 1008 expectf(HEIGHT1, height); 1009 1010 stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format); 1011 expect(Ok, stat); 1012 expect(PixelFormat16bppRGB555, format); 1013 1014 GdipDisposeImage((GpImage*)gpbm); 1015 } 1016 DeleteObject(hbm); 1017 1018 /* 16-bit 555 dib, with bitfields */ 1019 bmi.bi.bmiHeader.biSize = sizeof(bmi); 1020 bmi.bi.bmiHeader.biCompression = BI_BITFIELDS; 1021 bmi.bf.masks[0] = 0x7c00; 1022 bmi.bf.masks[1] = 0x3e0; 1023 bmi.bf.masks[2] = 0x1f; 1024 1025 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 1026 ok(hbm != NULL, "CreateDIBSection failed\n"); 1027 1028 bits[0] = 0; 1029 1030 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm); 1031 expect(Ok, stat); 1032 1033 if (stat == Ok) 1034 { 1035 stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height); 1036 expect(Ok, stat); 1037 expectf(WIDTH1, width); 1038 expectf(HEIGHT1, height); 1039 1040 stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format); 1041 expect(Ok, stat); 1042 expect(PixelFormat16bppRGB555, format); 1043 1044 GdipDisposeImage((GpImage*)gpbm); 1045 } 1046 DeleteObject(hbm); 1047 1048 /* 16-bit 565 dib, with bitfields */ 1049 bmi.bf.masks[0] = 0xf800; 1050 bmi.bf.masks[1] = 0x7e0; 1051 bmi.bf.masks[2] = 0x1f; 1052 1053 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0); 1054 ok(hbm != NULL, "CreateDIBSection failed\n"); 1055 1056 bits[0] = 0; 1057 1058 stat = GdipCreateBitmapFromHBITMAP(hbm, NULL, &gpbm); 1059 expect(Ok, stat); 1060 1061 if (stat == Ok) 1062 { 1063 stat = GdipGetImageDimension((GpImage*) gpbm, &width, &height); 1064 expect(Ok, stat); 1065 expectf(WIDTH1, width); 1066 expectf(HEIGHT1, height); 1067 1068 stat = GdipGetImagePixelFormat((GpImage*) gpbm, &format); 1069 expect(Ok, stat); 1070 expect(PixelFormat16bppRGB565, format); 1071 1072 GdipDisposeImage((GpImage*)gpbm); 1073 } 1074 DeleteObject(hbm); 1075 1076 DeleteDC(hdc); 1077 } 1078 1079 static void test_GdipGetImageFlags(void) 1080 { 1081 GpImage *img; 1082 GpStatus stat; 1083 UINT flags; 1084 1085 img = (GpImage*)0xdeadbeef; 1086 1087 stat = GdipGetImageFlags(NULL, NULL); 1088 expect(InvalidParameter, stat); 1089 1090 stat = GdipGetImageFlags(NULL, &flags); 1091 expect(InvalidParameter, stat); 1092 1093 stat = GdipGetImageFlags(img, NULL); 1094 expect(InvalidParameter, stat); 1095 1096 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat1bppIndexed, NULL, (GpBitmap**)&img); 1097 expect(Ok, stat); 1098 stat = GdipGetImageFlags(img, &flags); 1099 expect(Ok, stat); 1100 expect(ImageFlagsHasAlpha, flags); 1101 GdipDisposeImage(img); 1102 1103 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat4bppIndexed, NULL, (GpBitmap**)&img); 1104 expect(Ok, stat); 1105 stat = GdipGetImageFlags(img, &flags); 1106 expect(Ok, stat); 1107 expect(ImageFlagsHasAlpha, flags); 1108 GdipDisposeImage(img); 1109 1110 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat8bppIndexed, NULL, (GpBitmap**)&img); 1111 expect(Ok, stat); 1112 stat = GdipGetImageFlags(img, &flags); 1113 expect(Ok, stat); 1114 expect(ImageFlagsHasAlpha, flags); 1115 GdipDisposeImage(img); 1116 1117 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppGrayScale, NULL, (GpBitmap**)&img); 1118 expect(Ok, stat); 1119 stat = GdipGetImageFlags(img, &flags); 1120 expect(Ok, stat); 1121 expect(ImageFlagsNone, flags); 1122 GdipDisposeImage(img); 1123 1124 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB555, NULL, (GpBitmap**)&img); 1125 expect(Ok, stat); 1126 stat = GdipGetImageFlags(img, &flags); 1127 expect(Ok, stat); 1128 expect(ImageFlagsNone, flags); 1129 GdipDisposeImage(img); 1130 1131 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppRGB565, NULL, (GpBitmap**)&img); 1132 expect(Ok, stat); 1133 stat = GdipGetImageFlags(img, &flags); 1134 expect(Ok, stat); 1135 expect(ImageFlagsNone, flags); 1136 GdipDisposeImage(img); 1137 1138 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat16bppARGB1555, NULL, (GpBitmap**)&img); 1139 expect(Ok, stat); 1140 stat = GdipGetImageFlags(img, &flags); 1141 expect(Ok, stat); 1142 expect(ImageFlagsHasAlpha, flags); 1143 GdipDisposeImage(img); 1144 1145 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat24bppRGB, NULL, (GpBitmap**)&img); 1146 expect(Ok, stat); 1147 stat = GdipGetImageFlags(img, &flags); 1148 expect(Ok, stat); 1149 expect(ImageFlagsNone, flags); 1150 GdipDisposeImage(img); 1151 1152 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppRGB, NULL, (GpBitmap**)&img); 1153 expect(Ok, stat); 1154 stat = GdipGetImageFlags(img, &flags); 1155 expect(Ok, stat); 1156 expect(ImageFlagsNone, flags); 1157 GdipDisposeImage(img); 1158 1159 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppARGB, NULL, (GpBitmap**)&img); 1160 expect(Ok, stat); 1161 stat = GdipGetImageFlags(img, &flags); 1162 expect(Ok, stat); 1163 expect(ImageFlagsHasAlpha, flags); 1164 GdipDisposeImage(img); 1165 1166 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat32bppPARGB, NULL, (GpBitmap**)&img); 1167 expect(Ok, stat); 1168 stat = GdipGetImageFlags(img, &flags); 1169 expect(Ok, stat); 1170 expect(ImageFlagsHasAlpha, flags); 1171 GdipDisposeImage(img); 1172 1173 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat48bppRGB, NULL, (GpBitmap**)&img); 1174 expect(Ok, stat); 1175 if (stat == Ok) 1176 { 1177 stat = GdipGetImageFlags(img, &flags); 1178 expect(Ok, stat); 1179 expect(ImageFlagsNone, flags); 1180 GdipDisposeImage(img); 1181 } 1182 1183 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppARGB, NULL, (GpBitmap**)&img); 1184 expect(Ok, stat); 1185 if (stat == Ok) 1186 { 1187 expect(Ok, stat); 1188 stat = GdipGetImageFlags(img, &flags); 1189 expect(Ok, stat); 1190 expect(ImageFlagsHasAlpha, flags); 1191 GdipDisposeImage(img); 1192 } 1193 1194 stat = GdipCreateBitmapFromScan0(10, 10, 10, PixelFormat64bppPARGB, NULL, (GpBitmap**)&img); 1195 expect(Ok, stat); 1196 if (stat == Ok) 1197 { 1198 expect(Ok, stat); 1199 stat = GdipGetImageFlags(img, &flags); 1200 expect(Ok, stat); 1201 expect(ImageFlagsHasAlpha, flags); 1202 GdipDisposeImage(img); 1203 } 1204 } 1205 1206 static void test_GdipCloneImage(void) 1207 { 1208 GpStatus stat; 1209 GpRectF rectF; 1210 GpUnit unit; 1211 GpBitmap *bm; 1212 GpImage *image_src, *image_dest = NULL; 1213 const INT WIDTH = 10, HEIGHT = 20; 1214 1215 /* Create an image, clone it, delete the original, make sure the copy works */ 1216 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm); 1217 expect(Ok, stat); 1218 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bm, __LINE__, FALSE); 1219 1220 image_src = ((GpImage*)bm); 1221 stat = GdipCloneImage(image_src, &image_dest); 1222 expect(Ok, stat); 1223 expect_rawformat(&ImageFormatMemoryBMP, image_dest, __LINE__, FALSE); 1224 1225 stat = GdipDisposeImage((GpImage*)bm); 1226 expect(Ok, stat); 1227 stat = GdipGetImageBounds(image_dest, &rectF, &unit); 1228 expect(Ok, stat); 1229 1230 /* Treat FP values carefully */ 1231 expectf((REAL)WIDTH, rectF.Width); 1232 expectf((REAL)HEIGHT, rectF.Height); 1233 1234 stat = GdipDisposeImage(image_dest); 1235 expect(Ok, stat); 1236 } 1237 1238 static void test_testcontrol(void) 1239 { 1240 GpStatus stat; 1241 DWORD param; 1242 1243 param = 0; 1244 stat = GdipTestControl(TestControlGetBuildNumber, ¶m); 1245 expect(Ok, stat); 1246 ok(param != 0, "Build number expected, got %u\n", param); 1247 } 1248 1249 static void test_fromhicon(void) 1250 { 1251 static const BYTE bmp_bits[1024]; 1252 HBITMAP hbmMask, hbmColor; 1253 ICONINFO info; 1254 HICON hIcon; 1255 GpStatus stat; 1256 GpBitmap *bitmap = NULL; 1257 UINT dim; 1258 ImageType type; 1259 PixelFormat format; 1260 1261 /* NULL */ 1262 stat = GdipCreateBitmapFromHICON(NULL, NULL); 1263 expect(InvalidParameter, stat); 1264 stat = GdipCreateBitmapFromHICON(NULL, &bitmap); 1265 expect(InvalidParameter, stat); 1266 1267 /* color icon 1 bit */ 1268 hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits); 1269 ok(hbmMask != 0, "CreateBitmap failed\n"); 1270 hbmColor = CreateBitmap(16, 16, 1, 1, bmp_bits); 1271 ok(hbmColor != 0, "CreateBitmap failed\n"); 1272 info.fIcon = TRUE; 1273 info.xHotspot = 8; 1274 info.yHotspot = 8; 1275 info.hbmMask = hbmMask; 1276 info.hbmColor = hbmColor; 1277 hIcon = CreateIconIndirect(&info); 1278 ok(hIcon != 0, "CreateIconIndirect failed\n"); 1279 DeleteObject(hbmMask); 1280 DeleteObject(hbmColor); 1281 1282 stat = GdipCreateBitmapFromHICON(hIcon, &bitmap); 1283 ok(stat == Ok || 1284 broken(stat == InvalidParameter), /* Win98 */ 1285 "Expected Ok, got %.8x\n", stat); 1286 if(stat == Ok){ 1287 /* check attributes */ 1288 stat = GdipGetImageHeight((GpImage*)bitmap, &dim); 1289 expect(Ok, stat); 1290 expect(16, dim); 1291 stat = GdipGetImageWidth((GpImage*)bitmap, &dim); 1292 expect(Ok, stat); 1293 expect(16, dim); 1294 stat = GdipGetImageType((GpImage*)bitmap, &type); 1295 expect(Ok, stat); 1296 expect(ImageTypeBitmap, type); 1297 stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format); 1298 expect(Ok, stat); 1299 expect(PixelFormat32bppARGB, format); 1300 /* raw format */ 1301 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE); 1302 GdipDisposeImage((GpImage*)bitmap); 1303 } 1304 DestroyIcon(hIcon); 1305 1306 /* color icon 8 bpp */ 1307 hbmMask = CreateBitmap(16, 16, 1, 8, bmp_bits); 1308 ok(hbmMask != 0, "CreateBitmap failed\n"); 1309 hbmColor = CreateBitmap(16, 16, 1, 8, bmp_bits); 1310 ok(hbmColor != 0, "CreateBitmap failed\n"); 1311 info.fIcon = TRUE; 1312 info.xHotspot = 8; 1313 info.yHotspot = 8; 1314 info.hbmMask = hbmMask; 1315 info.hbmColor = hbmColor; 1316 hIcon = CreateIconIndirect(&info); 1317 ok(hIcon != 0, "CreateIconIndirect failed\n"); 1318 DeleteObject(hbmMask); 1319 DeleteObject(hbmColor); 1320 1321 stat = GdipCreateBitmapFromHICON(hIcon, &bitmap); 1322 expect(Ok, stat); 1323 if(stat == Ok){ 1324 /* check attributes */ 1325 stat = GdipGetImageHeight((GpImage*)bitmap, &dim); 1326 expect(Ok, stat); 1327 expect(16, dim); 1328 stat = GdipGetImageWidth((GpImage*)bitmap, &dim); 1329 expect(Ok, stat); 1330 expect(16, dim); 1331 stat = GdipGetImageType((GpImage*)bitmap, &type); 1332 expect(Ok, stat); 1333 expect(ImageTypeBitmap, type); 1334 stat = GdipGetImagePixelFormat((GpImage*)bitmap, &format); 1335 expect(Ok, stat); 1336 expect(PixelFormat32bppARGB, format); 1337 /* raw format */ 1338 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE); 1339 GdipDisposeImage((GpImage*)bitmap); 1340 } 1341 DestroyIcon(hIcon); 1342 } 1343 1344 /* 1x1 pixel png */ 1345 static const unsigned char pngimage[285] = { 1346 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52, 1347 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53, 1348 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b, 1349 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5, 1350 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41, 1351 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59, 1352 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 1353 }; 1354 /* 1x1 pixel gif */ 1355 static const unsigned char gifimage[35] = { 1356 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff, 1357 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44, 1358 0x01,0x00,0x3b 1359 }; 1360 /* 1x1 pixel transparent gif */ 1361 static const unsigned char transparentgif[] = { 1362 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00, 1363 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00, 1364 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b 1365 }; 1366 /* 1x1 pixel bmp */ 1367 static const unsigned char bmpimage[66] = { 1368 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00, 1369 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00, 1370 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00, 1371 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00, 1372 0x00,0x00 1373 }; 1374 /* 1x1 pixel jpg */ 1375 static const unsigned char jpgimage[285] = { 1376 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c, 1377 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05, 1378 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b, 1379 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13, 1380 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17, 1381 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05, 1382 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e, 1383 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e, 1384 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e, 1385 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0, 1386 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11, 1387 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 1388 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00, 1389 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4, 1390 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 1391 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00, 1392 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01, 1393 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9 1394 }; 1395 /* 1x1 pixel tiff */ 1396 static const unsigned char tiffimage[] = { 1397 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00, 1398 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00, 1399 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00, 1400 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01, 1401 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00, 1402 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00, 1403 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01, 1404 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00, 1405 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00, 1406 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01, 1407 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00, 1408 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00, 1409 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00, 1410 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65, 1411 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74, 1412 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48, 1413 0x00,0x00,0x00,0x01 1414 }; 1415 /* 320x320 twip wmf */ 1416 static const unsigned char wmfimage[180] = { 1417 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05, 1418 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00, 1419 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00, 1420 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00, 1421 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00, 1422 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00, 1423 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00, 1424 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02, 1425 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00, 1426 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00, 1427 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00, 1428 0x00,0x00,0x00,0x00 1429 }; 1430 static void test_getrawformat(void) 1431 { 1432 test_bufferrawformat((void*)pngimage, sizeof(pngimage), &ImageFormatPNG, __LINE__, FALSE); 1433 test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF, __LINE__, FALSE); 1434 test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP, __LINE__, FALSE); 1435 test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, FALSE); 1436 test_bufferrawformat((void*)tiffimage, sizeof(tiffimage), &ImageFormatTIFF, __LINE__, FALSE); 1437 test_bufferrawformat((void*)wmfimage, sizeof(wmfimage), &ImageFormatWMF, __LINE__, FALSE); 1438 } 1439 1440 static void test_loadwmf(void) 1441 { 1442 LPSTREAM stream; 1443 HGLOBAL hglob; 1444 LPBYTE data; 1445 HRESULT hres; 1446 GpStatus stat; 1447 GpImage *img; 1448 GpRectF bounds; 1449 GpUnit unit; 1450 REAL res = 12345.0; 1451 MetafileHeader header; 1452 1453 hglob = GlobalAlloc (0, sizeof(wmfimage)); 1454 data = GlobalLock (hglob); 1455 memcpy(data, wmfimage, sizeof(wmfimage)); 1456 GlobalUnlock(hglob); data = NULL; 1457 1458 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream); 1459 ok(hres == S_OK, "Failed to create a stream\n"); 1460 if(hres != S_OK) return; 1461 1462 stat = GdipLoadImageFromStream(stream, &img); 1463 ok(stat == Ok, "Failed to create a Bitmap\n"); 1464 if(stat != Ok){ 1465 IStream_Release(stream); 1466 return; 1467 } 1468 1469 IStream_Release(stream); 1470 1471 stat = GdipGetImageBounds(img, &bounds, &unit); 1472 expect(Ok, stat); 1473 expect(UnitPixel, unit); 1474 expectf(0.0, bounds.X); 1475 expectf(0.0, bounds.Y); 1476 expectf(320.0, bounds.Width); 1477 expectf(320.0, bounds.Height); 1478 1479 stat = GdipGetImageHorizontalResolution(img, &res); 1480 expect(Ok, stat); 1481 expectf(1440.0, res); 1482 1483 stat = GdipGetImageVerticalResolution(img, &res); 1484 expect(Ok, stat); 1485 expectf(1440.0, res); 1486 1487 memset(&header, 0, sizeof(header)); 1488 stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header); 1489 expect(Ok, stat); 1490 if (stat == Ok) 1491 { 1492 expect(MetafileTypeWmfPlaceable, header.Type); 1493 todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size); 1494 todo_wine expect(0x300, header.Version); 1495 expect(0, header.EmfPlusFlags); 1496 expectf(1440.0, header.DpiX); 1497 expectf(1440.0, header.DpiY); 1498 expect(0, header.X); 1499 expect(0, header.Y); 1500 expect(320, header.Width); 1501 expect(320, header.Height); 1502 expect(1, U(header).WmfHeader.mtType); 1503 expect(0, header.EmfPlusHeaderSize); 1504 expect(0, header.LogicalDpiX); 1505 expect(0, header.LogicalDpiY); 1506 } 1507 1508 GdipDisposeImage(img); 1509 } 1510 1511 static void test_createfromwmf(void) 1512 { 1513 HMETAFILE hwmf; 1514 GpImage *img; 1515 GpStatus stat; 1516 GpRectF bounds; 1517 GpUnit unit; 1518 REAL res = 12345.0; 1519 MetafileHeader header; 1520 1521 hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), 1522 wmfimage+sizeof(WmfPlaceableFileHeader)); 1523 ok(hwmf != 0, "SetMetaFileBitsEx failed\n"); 1524 1525 stat = GdipCreateMetafileFromWmf(hwmf, TRUE, 1526 (WmfPlaceableFileHeader*)wmfimage, (GpMetafile**)&img); 1527 expect(Ok, stat); 1528 1529 stat = GdipGetImageBounds(img, &bounds, &unit); 1530 expect(Ok, stat); 1531 expect(UnitPixel, unit); 1532 expectf(0.0, bounds.X); 1533 expectf(0.0, bounds.Y); 1534 expectf(320.0, bounds.Width); 1535 expectf(320.0, bounds.Height); 1536 1537 stat = GdipGetImageHorizontalResolution(img, &res); 1538 expect(Ok, stat); 1539 expectf(1440.0, res); 1540 1541 stat = GdipGetImageVerticalResolution(img, &res); 1542 expect(Ok, stat); 1543 expectf(1440.0, res); 1544 1545 memset(&header, 0, sizeof(header)); 1546 stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header); 1547 expect(Ok, stat); 1548 if (stat == Ok) 1549 { 1550 expect(MetafileTypeWmfPlaceable, header.Type); 1551 todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size); 1552 todo_wine expect(0x300, header.Version); 1553 expect(0, header.EmfPlusFlags); 1554 expectf(1440.0, header.DpiX); 1555 expectf(1440.0, header.DpiY); 1556 expect(0, header.X); 1557 expect(0, header.Y); 1558 expect(320, header.Width); 1559 expect(320, header.Height); 1560 expect(1, U(header).WmfHeader.mtType); 1561 expect(0, header.EmfPlusHeaderSize); 1562 expect(0, header.LogicalDpiX); 1563 expect(0, header.LogicalDpiY); 1564 } 1565 1566 GdipDisposeImage(img); 1567 } 1568 1569 static void test_createfromwmf_noplaceable(void) 1570 { 1571 HMETAFILE hwmf; 1572 GpImage *img; 1573 GpStatus stat; 1574 1575 hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), 1576 wmfimage+sizeof(WmfPlaceableFileHeader)); 1577 ok(hwmf != 0, "SetMetaFileBitsEx failed\n"); 1578 1579 stat = GdipCreateMetafileFromWmf(hwmf, TRUE, NULL, (GpMetafile**)&img); 1580 expect(Ok, stat); 1581 1582 GdipDisposeImage(img); 1583 } 1584 1585 static void test_resolution(void) 1586 { 1587 GpStatus stat; 1588 GpBitmap *bitmap; 1589 GpGraphics *graphics; 1590 REAL res=-1.0; 1591 HDC screendc; 1592 int screenxres, screenyres; 1593 1594 /* create Bitmap */ 1595 stat = GdipCreateBitmapFromScan0(1, 1, 32, PixelFormat24bppRGB, NULL, &bitmap); 1596 expect(Ok, stat); 1597 1598 /* test invalid values */ 1599 stat = GdipGetImageHorizontalResolution(NULL, &res); 1600 expect(InvalidParameter, stat); 1601 1602 stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, NULL); 1603 expect(InvalidParameter, stat); 1604 1605 stat = GdipGetImageVerticalResolution(NULL, &res); 1606 expect(InvalidParameter, stat); 1607 1608 stat = GdipGetImageVerticalResolution((GpImage*)bitmap, NULL); 1609 expect(InvalidParameter, stat); 1610 1611 stat = GdipBitmapSetResolution(NULL, 96.0, 96.0); 1612 expect(InvalidParameter, stat); 1613 1614 stat = GdipBitmapSetResolution(bitmap, 0.0, 0.0); 1615 expect(InvalidParameter, stat); 1616 1617 /* defaults to screen resolution */ 1618 screendc = GetDC(0); 1619 1620 screenxres = GetDeviceCaps(screendc, LOGPIXELSX); 1621 screenyres = GetDeviceCaps(screendc, LOGPIXELSY); 1622 1623 ReleaseDC(0, screendc); 1624 1625 stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res); 1626 expect(Ok, stat); 1627 expectf((REAL)screenxres, res); 1628 1629 stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res); 1630 expect(Ok, stat); 1631 expectf((REAL)screenyres, res); 1632 1633 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics); 1634 expect(Ok, stat); 1635 stat = GdipGetDpiX(graphics, &res); 1636 expect(Ok, stat); 1637 expectf((REAL)screenxres, res); 1638 stat = GdipGetDpiY(graphics, &res); 1639 expect(Ok, stat); 1640 expectf((REAL)screenyres, res); 1641 1642 /* test changing the resolution */ 1643 stat = GdipBitmapSetResolution(bitmap, screenxres*2.0, screenyres*3.0); 1644 expect(Ok, stat); 1645 1646 stat = GdipGetImageHorizontalResolution((GpImage*)bitmap, &res); 1647 expect(Ok, stat); 1648 expectf(screenxres*2.0, res); 1649 1650 stat = GdipGetImageVerticalResolution((GpImage*)bitmap, &res); 1651 expect(Ok, stat); 1652 expectf(screenyres*3.0, res); 1653 1654 stat = GdipGetDpiX(graphics, &res); 1655 expect(Ok, stat); 1656 expectf((REAL)screenxres, res); 1657 stat = GdipGetDpiY(graphics, &res); 1658 expect(Ok, stat); 1659 expectf((REAL)screenyres, res); 1660 1661 stat = GdipDeleteGraphics(graphics); 1662 expect(Ok, stat); 1663 1664 stat = GdipGetImageGraphicsContext((GpImage*)bitmap, &graphics); 1665 expect(Ok, stat); 1666 stat = GdipGetDpiX(graphics, &res); 1667 expect(Ok, stat); 1668 expectf(screenxres*2.0, res); 1669 stat = GdipGetDpiY(graphics, &res); 1670 expect(Ok, stat); 1671 expectf(screenyres*3.0, res); 1672 stat = GdipDeleteGraphics(graphics); 1673 expect(Ok, stat); 1674 1675 stat = GdipDisposeImage((GpImage*)bitmap); 1676 expect(Ok, stat); 1677 } 1678 1679 static void test_createhbitmap(void) 1680 { 1681 GpStatus stat; 1682 GpBitmap *bitmap; 1683 HBITMAP hbitmap, oldhbitmap; 1684 BITMAP bm; 1685 int ret; 1686 HDC hdc; 1687 COLORREF pixel; 1688 BYTE bits[640]; 1689 BitmapData lockeddata; 1690 1691 memset(bits, 0x68, 640); 1692 1693 /* create Bitmap */ 1694 stat = GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB, bits, &bitmap); 1695 expect(Ok, stat); 1696 1697 /* test NULL values */ 1698 stat = GdipCreateHBITMAPFromBitmap(NULL, &hbitmap, 0); 1699 expect(InvalidParameter, stat); 1700 1701 stat = GdipCreateHBITMAPFromBitmap(bitmap, NULL, 0); 1702 expect(InvalidParameter, stat); 1703 1704 /* create HBITMAP */ 1705 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0); 1706 expect(Ok, stat); 1707 1708 if (stat == Ok) 1709 { 1710 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm); 1711 expect(sizeof(BITMAP), ret); 1712 1713 expect(0, bm.bmType); 1714 expect(10, bm.bmWidth); 1715 expect(20, bm.bmHeight); 1716 expect(40, bm.bmWidthBytes); 1717 expect(1, bm.bmPlanes); 1718 expect(32, bm.bmBitsPixel); 1719 ok(bm.bmBits != NULL, "got DDB, expected DIB\n"); 1720 1721 if (bm.bmBits) 1722 { 1723 DWORD val = *(DWORD*)bm.bmBits; 1724 ok(val == 0xff686868, "got %x, expected 0xff686868\n", val); 1725 } 1726 1727 hdc = CreateCompatibleDC(NULL); 1728 1729 oldhbitmap = SelectObject(hdc, hbitmap); 1730 pixel = GetPixel(hdc, 5, 5); 1731 SelectObject(hdc, oldhbitmap); 1732 1733 DeleteDC(hdc); 1734 1735 expect(0x686868, pixel); 1736 1737 DeleteObject(hbitmap); 1738 } 1739 1740 stat = GdipDisposeImage((GpImage*)bitmap); 1741 expect(Ok, stat); 1742 1743 /* make (1,0) have no alpha and (2,0) a different blue value. */ 1744 bits[7] = 0x00; 1745 bits[8] = 0x40; 1746 1747 /* create alpha Bitmap */ 1748 stat = GdipCreateBitmapFromScan0(8, 20, 32, PixelFormat32bppARGB, bits, &bitmap); 1749 expect(Ok, stat); 1750 1751 /* create HBITMAP */ 1752 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0); 1753 expect(Ok, stat); 1754 1755 if (stat == Ok) 1756 { 1757 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm); 1758 expect(sizeof(BITMAP), ret); 1759 1760 expect(0, bm.bmType); 1761 expect(8, bm.bmWidth); 1762 expect(20, bm.bmHeight); 1763 expect(32, bm.bmWidthBytes); 1764 expect(1, bm.bmPlanes); 1765 expect(32, bm.bmBitsPixel); 1766 ok(bm.bmBits != NULL, "got DDB, expected DIB\n"); 1767 1768 if (bm.bmBits) 1769 { 1770 DWORD val = *(DWORD*)bm.bmBits; 1771 ok(val == 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val); 1772 val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1); 1773 ok(val == 0x0, "got %x, expected 0x682a2a2a\n", val); 1774 } 1775 1776 hdc = CreateCompatibleDC(NULL); 1777 1778 oldhbitmap = SelectObject(hdc, hbitmap); 1779 pixel = GetPixel(hdc, 5, 5); 1780 expect(0x2a2a2a, pixel); 1781 pixel = GetPixel(hdc, 1, 0); 1782 expect(0x0, pixel); 1783 1784 SelectObject(hdc, oldhbitmap); 1785 1786 DeleteDC(hdc); 1787 1788 1789 DeleteObject(hbitmap); 1790 } 1791 1792 /* create HBITMAP with bkgnd colour */ 1793 /* gdiplus.dll 5.1 is broken and only applies the blue value */ 1794 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0xff00ff); 1795 expect(Ok, stat); 1796 1797 if (stat == Ok) 1798 { 1799 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm); 1800 expect(sizeof(BITMAP), ret); 1801 1802 expect(0, bm.bmType); 1803 expect(8, bm.bmWidth); 1804 expect(20, bm.bmHeight); 1805 expect(32, bm.bmWidthBytes); 1806 expect(1, bm.bmPlanes); 1807 expect(32, bm.bmBitsPixel); 1808 ok(bm.bmBits != NULL, "got DDB, expected DIB\n"); 1809 1810 if (bm.bmBits) 1811 { 1812 DWORD val = *(DWORD*)bm.bmBits; 1813 ok(val == 0x68c12ac1 || broken(val == 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val); 1814 val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1); 1815 ok(val == 0xff00ff || broken(val == 0xff), "got %x, expected 0xff00ff\n", val); 1816 } 1817 1818 hdc = CreateCompatibleDC(NULL); 1819 1820 oldhbitmap = SelectObject(hdc, hbitmap); 1821 pixel = GetPixel(hdc, 5, 5); 1822 ok(pixel == 0xc12ac1 || broken(pixel == 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel); 1823 pixel = GetPixel(hdc, 1, 0); 1824 ok(pixel == 0xff00ff || broken(pixel == 0xff0000), "got %x, expected 0xff00ff\n", pixel); 1825 pixel = GetPixel(hdc, 2, 0); 1826 ok(pixel == 0xb12ac1 || broken(pixel == 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel); 1827 1828 SelectObject(hdc, oldhbitmap); 1829 DeleteDC(hdc); 1830 DeleteObject(hbitmap); 1831 } 1832 1833 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */ 1834 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0x80ff00ff); 1835 expect(Ok, stat); 1836 1837 if (stat == Ok) 1838 { 1839 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm); 1840 expect(sizeof(BITMAP), ret); 1841 1842 expect(0, bm.bmType); 1843 expect(8, bm.bmWidth); 1844 expect(20, bm.bmHeight); 1845 expect(32, bm.bmWidthBytes); 1846 expect(1, bm.bmPlanes); 1847 expect(32, bm.bmBitsPixel); 1848 ok(bm.bmBits != NULL, "got DDB, expected DIB\n"); 1849 1850 if (bm.bmBits) 1851 { 1852 DWORD val = *(DWORD*)bm.bmBits; 1853 ok(val == 0x68c12ac1 || broken(val == 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val); 1854 val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1); 1855 ok(val == 0xff00ff || broken(val == 0xff), "got %x, expected 0xff00ff\n", val); 1856 } 1857 1858 hdc = CreateCompatibleDC(NULL); 1859 1860 oldhbitmap = SelectObject(hdc, hbitmap); 1861 pixel = GetPixel(hdc, 5, 5); 1862 ok(pixel == 0xc12ac1 || broken(pixel == 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel); 1863 pixel = GetPixel(hdc, 1, 0); 1864 ok(pixel == 0xff00ff || broken(pixel == 0xff0000), "got %x, expected 0xff00ff\n", pixel); 1865 pixel = GetPixel(hdc, 2, 0); 1866 ok(pixel == 0xb12ac1 || broken(pixel == 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel); 1867 1868 SelectObject(hdc, oldhbitmap); 1869 DeleteDC(hdc); 1870 DeleteObject(hbitmap); 1871 } 1872 1873 stat = GdipDisposeImage((GpImage*)bitmap); 1874 expect(Ok, stat); 1875 1876 /* create HBITMAP from locked data */ 1877 memset(bits, 0x68, 640); 1878 stat = GdipCreateBitmapFromScan0(10, 20, 32, PixelFormat24bppRGB, bits, &bitmap); 1879 expect(Ok, stat); 1880 1881 memset(&lockeddata, 0, sizeof(lockeddata)); 1882 stat = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead | ImageLockModeWrite, 1883 PixelFormat32bppRGB, &lockeddata); 1884 expect(Ok, stat); 1885 ((DWORD*)lockeddata.Scan0)[0] = 0xff242424; 1886 stat = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0); 1887 expect(Ok, stat); 1888 stat = GdipBitmapUnlockBits(bitmap, &lockeddata); 1889 expect(Ok, stat); 1890 stat = GdipDisposeImage((GpImage*)bitmap); 1891 expect(Ok, stat); 1892 1893 hdc = CreateCompatibleDC(NULL); 1894 oldhbitmap = SelectObject(hdc, hbitmap); 1895 pixel = GetPixel(hdc, 0, 0); 1896 expect(0x686868, pixel); 1897 SelectObject(hdc, oldhbitmap); 1898 DeleteDC(hdc); 1899 } 1900 1901 static void test_getthumbnail(void) 1902 { 1903 GpStatus stat; 1904 GpImage *bitmap1, *bitmap2; 1905 UINT width, height; 1906 1907 stat = GdipGetImageThumbnail(NULL, 0, 0, &bitmap2, NULL, NULL); 1908 expect(InvalidParameter, stat); 1909 1910 stat = GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1); 1911 expect(Ok, stat); 1912 1913 stat = GdipGetImageThumbnail(bitmap1, 0, 0, NULL, NULL, NULL); 1914 expect(InvalidParameter, stat); 1915 1916 stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL); 1917 expect(Ok, stat); 1918 1919 if (stat == Ok) 1920 { 1921 stat = GdipGetImageWidth(bitmap2, &width); 1922 expect(Ok, stat); 1923 expect(120, width); 1924 1925 stat = GdipGetImageHeight(bitmap2, &height); 1926 expect(Ok, stat); 1927 expect(120, height); 1928 1929 GdipDisposeImage(bitmap2); 1930 } 1931 1932 GdipDisposeImage(bitmap1); 1933 1934 1935 stat = GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1); 1936 expect(Ok, stat); 1937 1938 stat = GdipGetImageThumbnail(bitmap1, 32, 32, &bitmap2, NULL, NULL); 1939 expect(Ok, stat); 1940 1941 if (stat == Ok) 1942 { 1943 stat = GdipGetImageWidth(bitmap2, &width); 1944 expect(Ok, stat); 1945 expect(32, width); 1946 1947 stat = GdipGetImageHeight(bitmap2, &height); 1948 expect(Ok, stat); 1949 expect(32, height); 1950 1951 GdipDisposeImage(bitmap2); 1952 } 1953 1954 stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL); 1955 expect(Ok, stat); 1956 1957 if (stat == Ok) 1958 { 1959 stat = GdipGetImageWidth(bitmap2, &width); 1960 expect(Ok, stat); 1961 expect(120, width); 1962 1963 stat = GdipGetImageHeight(bitmap2, &height); 1964 expect(Ok, stat); 1965 expect(120, height); 1966 1967 GdipDisposeImage(bitmap2); 1968 } 1969 1970 GdipDisposeImage(bitmap1); 1971 } 1972 1973 static void test_getsetpixel(void) 1974 { 1975 GpStatus stat; 1976 GpBitmap *bitmap; 1977 ARGB color; 1978 BYTE bits[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00, 1979 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00}; 1980 1981 stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, bits, &bitmap); 1982 expect(Ok, stat); 1983 1984 /* null parameters */ 1985 stat = GdipBitmapGetPixel(NULL, 1, 1, &color); 1986 expect(InvalidParameter, stat); 1987 1988 stat = GdipBitmapGetPixel(bitmap, 1, 1, NULL); 1989 expect(InvalidParameter, stat); 1990 1991 stat = GdipBitmapSetPixel(NULL, 1, 1, 0); 1992 expect(InvalidParameter, stat); 1993 1994 /* out of bounds */ 1995 stat = GdipBitmapGetPixel(bitmap, -1, 1, &color); 1996 expect(InvalidParameter, stat); 1997 1998 stat = GdipBitmapSetPixel(bitmap, -1, 1, 0); 1999 expect(InvalidParameter, stat); 2000 2001 stat = GdipBitmapGetPixel(bitmap, 1, -1, &color); 2002 ok(stat == InvalidParameter || 2003 broken(stat == Ok), /* Older gdiplus */ 2004 "Expected InvalidParameter, got %.8x\n", stat); 2005 2006 if (0) /* crashes some gdiplus implementations */ 2007 { 2008 stat = GdipBitmapSetPixel(bitmap, 1, -1, 0); 2009 ok(stat == InvalidParameter || 2010 broken(stat == Ok), /* Older gdiplus */ 2011 "Expected InvalidParameter, got %.8x\n", stat); 2012 } 2013 2014 stat = GdipBitmapGetPixel(bitmap, 2, 1, &color); 2015 expect(InvalidParameter, stat); 2016 2017 stat = GdipBitmapSetPixel(bitmap, 2, 1, 0); 2018 expect(InvalidParameter, stat); 2019 2020 stat = GdipBitmapGetPixel(bitmap, 1, 2, &color); 2021 expect(InvalidParameter, stat); 2022 2023 stat = GdipBitmapSetPixel(bitmap, 1, 2, 0); 2024 expect(InvalidParameter, stat); 2025 2026 /* valid use */ 2027 stat = GdipBitmapGetPixel(bitmap, 1, 1, &color); 2028 expect(Ok, stat); 2029 expect(0xffffffff, color); 2030 2031 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color); 2032 expect(Ok, stat); 2033 expect(0xff0000ff, color); 2034 2035 stat = GdipBitmapSetPixel(bitmap, 1, 1, 0xff676869); 2036 expect(Ok, stat); 2037 2038 stat = GdipBitmapSetPixel(bitmap, 0, 0, 0xff474849); 2039 expect(Ok, stat); 2040 2041 stat = GdipBitmapGetPixel(bitmap, 1, 1, &color); 2042 expect(Ok, stat); 2043 expect(0xff676869, color); 2044 2045 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color); 2046 expect(Ok, stat); 2047 expect(0xff474849, color); 2048 2049 stat = GdipDisposeImage((GpImage*)bitmap); 2050 expect(Ok, stat); 2051 } 2052 2053 static void check_halftone_palette(ColorPalette *palette) 2054 { 2055 static const BYTE halftone_values[6]={0x00,0x33,0x66,0x99,0xcc,0xff}; 2056 UINT i; 2057 2058 for (i=0; i<palette->Count; i++) 2059 { 2060 ARGB expected=0xff000000; 2061 if (i<8) 2062 { 2063 if (i&1) expected |= 0x800000; 2064 if (i&2) expected |= 0x8000; 2065 if (i&4) expected |= 0x80; 2066 } 2067 else if (i == 8) 2068 { 2069 expected = 0xffc0c0c0; 2070 } 2071 else if (i < 16) 2072 { 2073 if (i&1) expected |= 0xff0000; 2074 if (i&2) expected |= 0xff00; 2075 if (i&4) expected |= 0xff; 2076 } 2077 else if (i < 40) 2078 { 2079 expected = 0x00000000; 2080 } 2081 else 2082 { 2083 expected |= halftone_values[(i-40)%6]; 2084 expected |= halftone_values[((i-40)/6)%6] << 8; 2085 expected |= halftone_values[((i-40)/36)%6] << 16; 2086 } 2087 ok(expected == palette->Entries[i], "Expected %.8x, got %.8x, i=%u/%u\n", 2088 expected, palette->Entries[i], i, palette->Count); 2089 } 2090 } 2091 2092 static void test_palette(void) 2093 { 2094 GpStatus stat; 2095 GpBitmap *bitmap; 2096 INT size; 2097 BYTE buffer[1040]; 2098 ColorPalette *palette=(ColorPalette*)buffer; 2099 ARGB *entries = palette->Entries; 2100 ARGB color=0; 2101 2102 /* test initial palette from non-indexed bitmap */ 2103 stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppRGB, NULL, &bitmap); 2104 expect(Ok, stat); 2105 2106 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size); 2107 expect(Ok, stat); 2108 expect(sizeof(UINT)*2+sizeof(ARGB), size); 2109 2110 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size); 2111 expect(Ok, stat); 2112 expect(0, palette->Count); 2113 2114 /* test setting palette on not-indexed bitmap */ 2115 palette->Count = 3; 2116 2117 stat = GdipSetImagePalette((GpImage*)bitmap, palette); 2118 expect(Ok, stat); 2119 2120 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size); 2121 expect(Ok, stat); 2122 expect(sizeof(UINT)*2+sizeof(ARGB)*3, size); 2123 2124 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size); 2125 expect(Ok, stat); 2126 expect(3, palette->Count); 2127 2128 GdipDisposeImage((GpImage*)bitmap); 2129 2130 /* test initial palette on 1-bit bitmap */ 2131 stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat1bppIndexed, NULL, &bitmap); 2132 expect(Ok, stat); 2133 2134 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size); 2135 expect(Ok, stat); 2136 expect(sizeof(UINT)*2+sizeof(ARGB)*2, size); 2137 2138 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size); 2139 expect(Ok, stat); 2140 expect(PaletteFlagsGrayScale, palette->Flags); 2141 expect(2, palette->Count); 2142 2143 expect(0xff000000, entries[0]); 2144 expect(0xffffffff, entries[1]); 2145 2146 /* test getting/setting pixels */ 2147 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color); 2148 expect(Ok, stat); 2149 expect(0xff000000, color); 2150 2151 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffffffff); 2152 ok((stat == Ok) || 2153 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat); 2154 2155 if (stat == Ok) 2156 { 2157 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color); 2158 expect(Ok, stat); 2159 expect(0xffffffff, color); 2160 } 2161 2162 GdipDisposeImage((GpImage*)bitmap); 2163 2164 /* test initial palette on 4-bit bitmap */ 2165 stat = GdipCreateBitmapFromScan0(2, 2, 4, PixelFormat4bppIndexed, NULL, &bitmap); 2166 expect(Ok, stat); 2167 2168 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size); 2169 expect(Ok, stat); 2170 expect(sizeof(UINT)*2+sizeof(ARGB)*16, size); 2171 2172 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size); 2173 expect(Ok, stat); 2174 expect(0, palette->Flags); 2175 expect(16, palette->Count); 2176 2177 check_halftone_palette(palette); 2178 2179 /* test getting/setting pixels */ 2180 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color); 2181 expect(Ok, stat); 2182 expect(0xff000000, color); 2183 2184 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffff00ff); 2185 ok((stat == Ok) || 2186 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat); 2187 2188 if (stat == Ok) 2189 { 2190 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color); 2191 expect(Ok, stat); 2192 expect(0xffff00ff, color); 2193 } 2194 2195 GdipDisposeImage((GpImage*)bitmap); 2196 2197 /* test initial palette on 8-bit bitmap */ 2198 stat = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat8bppIndexed, NULL, &bitmap); 2199 expect(Ok, stat); 2200 2201 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size); 2202 expect(Ok, stat); 2203 expect(sizeof(UINT)*2+sizeof(ARGB)*256, size); 2204 2205 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size); 2206 expect(Ok, stat); 2207 expect(PaletteFlagsHalftone, palette->Flags); 2208 expect(256, palette->Count); 2209 2210 check_halftone_palette(palette); 2211 2212 /* test getting/setting pixels */ 2213 stat = GdipBitmapGetPixel(bitmap, 0, 0, &color); 2214 expect(Ok, stat); 2215 expect(0xff000000, color); 2216 2217 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffcccccc); 2218 ok((stat == Ok) || 2219 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat); 2220 2221 if (stat == Ok) 2222 { 2223 stat = GdipBitmapGetPixel(bitmap, 0, 1, &color); 2224 expect(Ok, stat); 2225 expect(0xffcccccc, color); 2226 } 2227 2228 /* test setting/getting a different palette */ 2229 entries[1] = 0xffcccccc; 2230 2231 stat = GdipSetImagePalette((GpImage*)bitmap, palette); 2232 expect(Ok, stat); 2233 2234 entries[1] = 0; 2235 2236 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size); 2237 expect(Ok, stat); 2238 expect(sizeof(UINT)*2+sizeof(ARGB)*256, size); 2239 2240 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size); 2241 expect(Ok, stat); 2242 expect(PaletteFlagsHalftone, palette->Flags); 2243 expect(256, palette->Count); 2244 expect(0xffcccccc, entries[1]); 2245 2246 /* test count < 256 */ 2247 palette->Flags = 12345; 2248 palette->Count = 3; 2249 2250 stat = GdipSetImagePalette((GpImage*)bitmap, palette); 2251 expect(Ok, stat); 2252 2253 entries[1] = 0; 2254 entries[3] = 0xdeadbeef; 2255 2256 stat = GdipGetImagePaletteSize((GpImage*)bitmap, &size); 2257 expect(Ok, stat); 2258 expect(sizeof(UINT)*2+sizeof(ARGB)*3, size); 2259 2260 stat = GdipGetImagePalette((GpImage*)bitmap, palette, size); 2261 expect(Ok, stat); 2262 expect(12345, palette->Flags); 2263 expect(3, palette->Count); 2264 expect(0xffcccccc, entries[1]); 2265 expect(0xdeadbeef, entries[3]); 2266 2267 /* test count > 256 */ 2268 palette->Count = 257; 2269 2270 stat = GdipSetImagePalette((GpImage*)bitmap, palette); 2271 ok(stat == InvalidParameter || 2272 broken(stat == Ok), /* Old gdiplus behavior */ 2273 "Expected %.8x, got %.8x\n", InvalidParameter, stat); 2274 2275 GdipDisposeImage((GpImage*)bitmap); 2276 } 2277 2278 static void test_colormatrix(void) 2279 { 2280 GpStatus stat; 2281 ColorMatrix colormatrix, graymatrix; 2282 GpImageAttributes *imageattr; 2283 const ColorMatrix identity = {{ 2284 {1.0,0.0,0.0,0.0,0.0}, 2285 {0.0,1.0,0.0,0.0,0.0}, 2286 {0.0,0.0,1.0,0.0,0.0}, 2287 {0.0,0.0,0.0,1.0,0.0}, 2288 {0.0,0.0,0.0,0.0,1.0}}}; 2289 const ColorMatrix double_red = {{ 2290 {2.0,0.0,0.0,0.0,0.0}, 2291 {0.0,1.0,0.0,0.0,0.0}, 2292 {0.0,0.0,1.0,0.0,0.0}, 2293 {0.0,0.0,0.0,1.0,0.0}, 2294 {0.0,0.0,0.0,0.0,1.0}}}; 2295 const ColorMatrix asymmetric = {{ 2296 {0.0,1.0,0.0,0.0,0.0}, 2297 {0.0,0.0,1.0,0.0,0.0}, 2298 {0.0,0.0,0.0,1.0,0.0}, 2299 {1.0,0.0,0.0,0.0,0.0}, 2300 {0.0,0.0,0.0,0.0,1.0}}}; 2301 GpBitmap *bitmap1, *bitmap2; 2302 GpGraphics *graphics; 2303 ARGB color; 2304 2305 colormatrix = identity; 2306 graymatrix = identity; 2307 2308 stat = GdipSetImageAttributesColorMatrix(NULL, ColorAdjustTypeDefault, 2309 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault); 2310 expect(InvalidParameter, stat); 2311 2312 stat = GdipCreateImageAttributes(&imageattr); 2313 expect(Ok, stat); 2314 2315 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, 2316 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault); 2317 expect(Ok, stat); 2318 2319 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, 2320 TRUE, NULL, NULL, ColorMatrixFlagsDefault); 2321 expect(InvalidParameter, stat); 2322 2323 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, 2324 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault); 2325 expect(Ok, stat); 2326 2327 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, 2328 TRUE, &colormatrix, NULL, ColorMatrixFlagsSkipGrays); 2329 expect(Ok, stat); 2330 2331 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, 2332 TRUE, &colormatrix, NULL, ColorMatrixFlagsAltGray); 2333 expect(InvalidParameter, stat); 2334 2335 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, 2336 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsAltGray); 2337 expect(Ok, stat); 2338 2339 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, 2340 TRUE, &colormatrix, &graymatrix, 3); 2341 expect(InvalidParameter, stat); 2342 2343 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeCount, 2344 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault); 2345 expect(InvalidParameter, stat); 2346 2347 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeAny, 2348 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault); 2349 expect(InvalidParameter, stat); 2350 2351 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, 2352 FALSE, NULL, NULL, ColorMatrixFlagsDefault); 2353 expect(Ok, stat); 2354 2355 /* Drawing a bitmap transforms the colors */ 2356 colormatrix = double_red; 2357 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, 2358 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault); 2359 expect(Ok, stat); 2360 2361 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap1); 2362 expect(Ok, stat); 2363 2364 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppARGB, NULL, &bitmap2); 2365 expect(Ok, stat); 2366 2367 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff40ccee); 2368 expect(Ok, stat); 2369 2370 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics); 2371 expect(Ok, stat); 2372 2373 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1, 2374 UnitPixel, imageattr, NULL, NULL); 2375 expect(Ok, stat); 2376 2377 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2378 expect(Ok, stat); 2379 expect(0xff80ccee, color); 2380 2381 colormatrix = asymmetric; 2382 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, 2383 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault); 2384 expect(Ok, stat); 2385 2386 stat = GdipBitmapSetPixel(bitmap2, 0, 0, 0); 2387 expect(Ok, stat); 2388 2389 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1, 2390 UnitPixel, imageattr, NULL, NULL); 2391 expect(Ok, stat); 2392 2393 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2394 expect(Ok, stat); 2395 ok(color_match(0xeeff40cc, color, 3), "expected 0xeeff40cc, got 0x%08x\n", color); 2396 2397 /* Toggle NoOp */ 2398 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, FALSE); 2399 expect(Ok, stat); 2400 2401 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, 2402 UnitPixel, imageattr, NULL, NULL); 2403 expect(Ok, stat); 2404 2405 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2406 expect(Ok, stat); 2407 ok(color_match(0xfefe40cc, color, 3), "expected 0xfefe40cc, got 0x%08x\n", color); 2408 2409 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, TRUE); 2410 expect(Ok, stat); 2411 2412 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, 2413 UnitPixel, imageattr, NULL, NULL); 2414 expect(Ok, stat); 2415 2416 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2417 expect(Ok, stat); 2418 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color); 2419 2420 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault); 2421 expect(Ok, stat); 2422 2423 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, FALSE); 2424 expect(Ok, stat); 2425 2426 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, 2427 UnitPixel, imageattr, NULL, NULL); 2428 expect(Ok, stat); 2429 2430 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2431 expect(Ok, stat); 2432 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color); 2433 2434 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, 2435 UnitPixel, imageattr, NULL, NULL); 2436 expect(Ok, stat); 2437 2438 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2439 expect(Ok, stat); 2440 ok(color_match(0xff40ccee, color, 1), "Expected ff40ccee, got %.8x\n", color); 2441 2442 /* Disable adjustment, toggle NoOp */ 2443 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, 2444 FALSE, &colormatrix, NULL, ColorMatrixFlagsDefault); 2445 expect(Ok, stat); 2446 2447 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, FALSE); 2448 expect(Ok, stat); 2449 2450 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, 2451 UnitPixel, imageattr, NULL, NULL); 2452 expect(Ok, stat); 2453 2454 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2455 expect(Ok, stat); 2456 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color); 2457 2458 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, TRUE); 2459 expect(Ok, stat); 2460 2461 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, 2462 UnitPixel, imageattr, NULL, NULL); 2463 expect(Ok, stat); 2464 2465 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2466 expect(Ok, stat); 2467 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color); 2468 2469 /* Reset with NoOp on, enable adjustment. */ 2470 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault); 2471 expect(Ok, stat); 2472 2473 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeDefault, 2474 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault); 2475 expect(Ok, stat); 2476 2477 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, 2478 UnitPixel, imageattr, NULL, NULL); 2479 expect(Ok, stat); 2480 2481 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2482 expect(Ok, stat); 2483 ok(color_match(0xfff24ace, color, 3), "expected 0xfff24ace, got 0x%08x\n", color); 2484 2485 /* Now inhibit specific category. */ 2486 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault); 2487 expect(Ok, stat); 2488 2489 stat = GdipSetImageAttributesColorMatrix(imageattr, ColorAdjustTypeBitmap, 2490 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault); 2491 expect(Ok, stat); 2492 2493 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, 2494 UnitPixel, imageattr, NULL, NULL); 2495 expect(Ok, stat); 2496 2497 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2498 expect(Ok, stat); 2499 ok(color_match(0xfffe41cc, color, 3), "expected 0xfffe41cc, got 0x%08x\n", color); 2500 2501 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeBitmap, TRUE); 2502 expect(Ok, stat); 2503 2504 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, 2505 UnitPixel, imageattr, NULL, NULL); 2506 expect(Ok, stat); 2507 2508 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2509 expect(Ok, stat); 2510 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color); 2511 2512 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeBitmap, FALSE); 2513 expect(Ok, stat); 2514 2515 stat = GdipSetImageAttributesNoOp(imageattr, ColorAdjustTypeDefault, TRUE); 2516 expect(Ok, stat); 2517 2518 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, 2519 UnitPixel, imageattr, NULL, NULL); 2520 expect(Ok, stat); 2521 2522 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2523 expect(Ok, stat); 2524 ok(color_match(0xfff24ace, color, 3), "expected 0xfff24ace, got 0x%08x\n", color); 2525 2526 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeBitmap); 2527 expect(Ok, stat); 2528 2529 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1, 2530 UnitPixel, imageattr, NULL, NULL); 2531 expect(Ok, stat); 2532 2533 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2534 expect(Ok, stat); 2535 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color); 2536 2537 GdipDeleteGraphics(graphics); 2538 GdipDisposeImage((GpImage*)bitmap1); 2539 GdipDisposeImage((GpImage*)bitmap2); 2540 GdipDisposeImageAttributes(imageattr); 2541 } 2542 2543 static void test_gamma(void) 2544 { 2545 GpStatus stat; 2546 GpImageAttributes *imageattr; 2547 GpBitmap *bitmap1, *bitmap2; 2548 GpGraphics *graphics; 2549 ARGB color; 2550 2551 stat = GdipSetImageAttributesGamma(NULL, ColorAdjustTypeDefault, TRUE, 1.0); 2552 expect(InvalidParameter, stat); 2553 2554 stat = GdipCreateImageAttributes(&imageattr); 2555 expect(Ok, stat); 2556 2557 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 1.0); 2558 expect(Ok, stat); 2559 2560 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeAny, TRUE, 1.0); 2561 expect(InvalidParameter, stat); 2562 2563 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, -1.0); 2564 expect(InvalidParameter, stat); 2565 2566 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.0); 2567 expect(InvalidParameter, stat); 2568 2569 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 0.5); 2570 expect(Ok, stat); 2571 2572 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, FALSE, 0.0); 2573 expect(Ok, stat); 2574 2575 /* Drawing a bitmap transforms the colors */ 2576 stat = GdipSetImageAttributesGamma(imageattr, ColorAdjustTypeDefault, TRUE, 3.0); 2577 expect(Ok, stat); 2578 2579 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1); 2580 expect(Ok, stat); 2581 2582 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2); 2583 expect(Ok, stat); 2584 2585 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff80ffff); 2586 expect(Ok, stat); 2587 2588 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics); 2589 expect(Ok, stat); 2590 2591 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1, 2592 UnitPixel, imageattr, NULL, NULL); 2593 expect(Ok, stat); 2594 2595 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2596 expect(Ok, stat); 2597 ok(color_match(0xff20ffff, color, 1), "Expected ff20ffff, got %.8x\n", color); 2598 2599 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault); 2600 expect(Ok, stat); 2601 2602 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1, 2603 UnitPixel, imageattr, NULL, NULL); 2604 expect(Ok, stat); 2605 2606 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 2607 expect(Ok, stat); 2608 ok(color_match(0xff80ffff, color, 1), "Expected ff80ffff, got %.8x\n", color); 2609 2610 GdipDeleteGraphics(graphics); 2611 GdipDisposeImage((GpImage*)bitmap1); 2612 GdipDisposeImage((GpImage*)bitmap2); 2613 GdipDisposeImageAttributes(imageattr); 2614 } 2615 2616 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */ 2617 static const unsigned char gifanimation[72] = { 2618 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00, 2619 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff, 2620 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00, 2621 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01, 2622 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b 2623 }; 2624 2625 /* Generated with ImageMagick: 2626 * convert -transparent black -delay 100 -size 8x2 xc:black \ 2627 * -dispose none -page +0+0 -size 2x2 xc:red \ 2628 * -dispose background -page +2+0 -size 2x2 xc:blue \ 2629 * -dispose previous -page +4+0 -size 2x2 xc:green \ 2630 * -dispose undefined -page +6+0 -size 2x2 xc:gray \ 2631 * test.gif 2632 */ 2633 static const unsigned char gifanimation2[] = { 2634 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00, 2635 0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 2636 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64, 2637 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45, 2638 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e, 2639 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 2640 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 2641 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21, 2642 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c, 2643 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 2644 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 2645 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44, 2646 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64, 2647 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00, 2648 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff, 2649 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 2650 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21, 2651 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c, 2652 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 2653 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 2654 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44, 2655 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64, 2656 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00, 2657 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e, 2658 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00, 2659 0x3b 2660 }; 2661 2662 static ARGB gifanimation2_pixels[5][4] = { 2663 {0, 0, 0, 0}, 2664 {0xffff0000, 0, 0, 0}, 2665 {0xffff0000, 0xff0000ff, 0, 0}, 2666 {0xffff0000, 0, 0xff008000, 0}, 2667 {0xffff0000, 0, 0, 0xff7e7e7e} 2668 }; 2669 2670 static void test_multiframegif(void) 2671 { 2672 LPSTREAM stream; 2673 HGLOBAL hglob; 2674 LPBYTE data; 2675 HRESULT hres; 2676 GpStatus stat; 2677 GpBitmap *bmp; 2678 ARGB color; 2679 UINT count; 2680 GUID dimension; 2681 PixelFormat pixel_format; 2682 INT palette_size, i, j; 2683 char palette_buf[256]; 2684 ColorPalette *palette; 2685 ARGB *palette_entries; 2686 2687 /* Test frame functions with an animated GIF */ 2688 hglob = GlobalAlloc (0, sizeof(gifanimation)); 2689 data = GlobalLock (hglob); 2690 memcpy(data, gifanimation, sizeof(gifanimation)); 2691 GlobalUnlock(hglob); 2692 2693 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream); 2694 ok(hres == S_OK, "Failed to create a stream\n"); 2695 if(hres != S_OK) return; 2696 2697 stat = GdipCreateBitmapFromStream(stream, &bmp); 2698 ok(stat == Ok, "Failed to create a Bitmap\n"); 2699 if(stat != Ok){ 2700 IStream_Release(stream); 2701 return; 2702 } 2703 2704 stat = GdipGetImagePixelFormat((GpImage*)bmp, &pixel_format); 2705 expect(Ok, stat); 2706 expect(PixelFormat32bppARGB, pixel_format); 2707 2708 stat = GdipGetImagePaletteSize((GpImage*)bmp, &palette_size); 2709 expect(Ok, stat); 2710 ok(palette_size == sizeof(ColorPalette) || 2711 broken(palette_size == sizeof(ColorPalette)+sizeof(ARGB[3])), 2712 "palette_size = %d\n", palette_size); 2713 2714 /* Bitmap starts at frame 0 */ 2715 color = 0xdeadbeef; 2716 stat = GdipBitmapGetPixel(bmp, 0, 0, &color); 2717 expect(Ok, stat); 2718 expect(0xffffffff, color); 2719 2720 /* Check that we get correct metadata */ 2721 stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count); 2722 expect(Ok, stat); 2723 expect(1, count); 2724 2725 stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1); 2726 expect(Ok, stat); 2727 expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE); 2728 2729 count = 12345; 2730 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count); 2731 expect(Ok, stat); 2732 expect(2, count); 2733 2734 /* SelectActiveFrame overwrites our current data */ 2735 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1); 2736 expect(Ok, stat); 2737 2738 color = 0xdeadbeef; 2739 GdipBitmapGetPixel(bmp, 0, 0, &color); 2740 expect(Ok, stat); 2741 expect(0xff000000, color); 2742 2743 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0); 2744 expect(Ok, stat); 2745 2746 color = 0xdeadbeef; 2747 stat = GdipBitmapGetPixel(bmp, 0, 0, &color); 2748 expect(Ok, stat); 2749 expect(0xffffffff, color); 2750 2751 /* Write over the image data */ 2752 stat = GdipBitmapSetPixel(bmp, 0, 0, 0xff000000); 2753 expect(Ok, stat); 2754 2755 /* Switching to the same frame does not overwrite our changes */ 2756 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0); 2757 expect(Ok, stat); 2758 2759 stat = GdipBitmapGetPixel(bmp, 0, 0, &color); 2760 expect(Ok, stat); 2761 expect(0xff000000, color); 2762 2763 /* But switching to another frame and back does */ 2764 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1); 2765 expect(Ok, stat); 2766 2767 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0); 2768 expect(Ok, stat); 2769 2770 stat = GdipBitmapGetPixel(bmp, 0, 0, &color); 2771 expect(Ok, stat); 2772 expect(0xffffffff, color); 2773 2774 /* rotate/flip discards the information about other frames */ 2775 stat = GdipImageRotateFlip((GpImage*)bmp, Rotate90FlipNone); 2776 expect(Ok, stat); 2777 2778 count = 12345; 2779 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count); 2780 expect(Ok, stat); 2781 expect(1, count); 2782 2783 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bmp, __LINE__, FALSE); 2784 2785 GdipDisposeImage((GpImage*)bmp); 2786 IStream_Release(stream); 2787 2788 /* Test with a non-animated gif */ 2789 hglob = GlobalAlloc (0, sizeof(gifimage)); 2790 data = GlobalLock (hglob); 2791 memcpy(data, gifimage, sizeof(gifimage)); 2792 GlobalUnlock(hglob); 2793 2794 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream); 2795 ok(hres == S_OK, "Failed to create a stream\n"); 2796 if(hres != S_OK) return; 2797 2798 stat = GdipCreateBitmapFromStream(stream, &bmp); 2799 ok(stat == Ok, "Failed to create a Bitmap\n"); 2800 if(stat != Ok){ 2801 IStream_Release(stream); 2802 return; 2803 } 2804 2805 stat = GdipGetImagePixelFormat((GpImage*)bmp, &pixel_format); 2806 expect(Ok, stat); 2807 expect(PixelFormat8bppIndexed, pixel_format); 2808 2809 /* Check metadata */ 2810 stat = GdipImageGetFrameDimensionsCount((GpImage*)bmp,&count); 2811 expect(Ok, stat); 2812 expect(1, count); 2813 2814 stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1); 2815 expect(Ok, stat); 2816 expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE); 2817 2818 count = 12345; 2819 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count); 2820 expect(Ok, stat); 2821 expect(1, count); 2822 2823 GdipDisposeImage((GpImage*)bmp); 2824 IStream_Release(stream); 2825 2826 /* Test with a non-animated transparent gif */ 2827 hglob = GlobalAlloc (0, sizeof(transparentgif)); 2828 data = GlobalLock (hglob); 2829 memcpy(data, transparentgif, sizeof(transparentgif)); 2830 GlobalUnlock(hglob); 2831 2832 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream); 2833 ok(hres == S_OK, "Failed to create a stream\n"); 2834 2835 stat = GdipCreateBitmapFromStream(stream, &bmp); 2836 IStream_Release(stream); 2837 ok(stat == Ok, "Failed to create a Bitmap\n"); 2838 2839 stat = GdipGetImagePixelFormat((GpImage*)bmp, &pixel_format); 2840 expect(Ok, stat); 2841 expect(PixelFormat8bppIndexed, pixel_format); 2842 2843 stat = GdipBitmapGetPixel(bmp, 0, 0, &color); 2844 expect(Ok, stat); 2845 expect(0, color); 2846 2847 stat = GdipGetImagePaletteSize((GpImage*)bmp, &palette_size); 2848 expect(Ok, stat); 2849 ok(palette_size == sizeof(ColorPalette)+sizeof(ARGB), 2850 "palette_size = %d\n", palette_size); 2851 2852 memset(palette_buf, 0xfe, sizeof(palette_buf)); 2853 palette = (ColorPalette*)palette_buf; 2854 stat = GdipGetImagePalette((GpImage*)bmp, palette, 2855 sizeof(ColorPalette)+sizeof(ARGB)); 2856 palette_entries = palette->Entries; 2857 expect(Ok, stat); 2858 expect(PaletteFlagsHasAlpha, palette->Flags); 2859 expect(2, palette->Count); 2860 expect(0, palette_entries[0]); 2861 expect(0xff000000, palette_entries[1]); 2862 2863 count = 12345; 2864 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count); 2865 expect(Ok, stat); 2866 expect(1, count); 2867 2868 GdipDisposeImage((GpImage*)bmp); 2869 2870 /* Test frame dispose methods */ 2871 hglob = GlobalAlloc (0, sizeof(gifanimation2)); 2872 data = GlobalLock (hglob); 2873 memcpy(data, gifanimation2, sizeof(gifanimation2)); 2874 GlobalUnlock(hglob); 2875 2876 hres = CreateStreamOnHGlobal(hglob, TRUE, &stream); 2877 ok(hres == S_OK, "Failed to create a stream\n"); 2878 2879 stat = GdipCreateBitmapFromStream(stream, &bmp); 2880 ok(stat == Ok, "Failed to create a Bitmap\n"); 2881 IStream_Release(stream); 2882 2883 stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1); 2884 expect(Ok, stat); 2885 expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE); 2886 2887 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count); 2888 expect(Ok, stat); 2889 expect(5, count); 2890 2891 stat = GdipBitmapGetPixel(bmp, 0, 0, &color); 2892 expect(Ok, stat); 2893 expect(0, color); 2894 2895 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 3); 2896 expect(Ok, stat); 2897 stat = GdipBitmapGetPixel(bmp, 2, 0, &color); 2898 expect(Ok, stat); 2899 ok(color==0 || broken(color==0xff0000ff), "color = %x\n", color); 2900 if(color != 0) { 2901 win_skip("broken animated gif support\n"); 2902 GdipDisposeImage((GpImage*)bmp); 2903 return; 2904 } 2905 2906 for(i=0; i<6; i++) { 2907 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, i%5); 2908 expect(Ok, stat); 2909 2910 for(j=0; j<4; j++) { 2911 stat = GdipBitmapGetPixel(bmp, j*2, 0, &color); 2912 expect(Ok, stat); 2913 ok(gifanimation2_pixels[i%5][j] == color, "at %d,%d got %x, expected %x\n", i, j, color, gifanimation2_pixels[i%5][j]); 2914 } 2915 } 2916 2917 GdipDisposeImage((GpImage*)bmp); 2918 } 2919 2920 static void test_rotateflip(void) 2921 { 2922 GpImage *bitmap; 2923 GpStatus stat; 2924 BYTE bits[24]; 2925 static const BYTE orig_bits[24] = { 2926 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23, 2927 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23}; 2928 UINT width, height; 2929 ARGB color; 2930 2931 memcpy(bits, orig_bits, sizeof(bits)); 2932 stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap); 2933 expect(Ok, stat); 2934 2935 stat = GdipImageRotateFlip(bitmap, Rotate90FlipNone); 2936 expect(Ok, stat); 2937 2938 stat = GdipGetImageWidth(bitmap, &width); 2939 expect(Ok, stat); 2940 stat = GdipGetImageHeight(bitmap, &height); 2941 expect(Ok, stat); 2942 expect(2, width); 2943 expect(3, height); 2944 2945 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color); 2946 expect(Ok, stat); 2947 expect(0xff00ffff, color); 2948 2949 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 0, &color); 2950 expect(Ok, stat); 2951 expect(0xffff0000, color); 2952 2953 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 2, &color); 2954 expect(Ok, stat); 2955 expect(0xffffff00, color); 2956 2957 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 1, 2, &color); 2958 expect(Ok, stat); 2959 expect(0xff0000ff, color); 2960 2961 expect(0, bits[0]); 2962 expect(0, bits[1]); 2963 expect(0xff, bits[2]); 2964 2965 GdipDisposeImage(bitmap); 2966 2967 memcpy(bits, orig_bits, sizeof(bits)); 2968 stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap); 2969 expect(Ok, stat); 2970 2971 stat = GdipImageRotateFlip(bitmap, RotateNoneFlipX); 2972 expect(Ok, stat); 2973 2974 stat = GdipGetImageWidth(bitmap, &width); 2975 expect(Ok, stat); 2976 stat = GdipGetImageHeight(bitmap, &height); 2977 expect(Ok, stat); 2978 expect(3, width); 2979 expect(2, height); 2980 2981 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color); 2982 expect(Ok, stat); 2983 expect(0xff0000ff, color); 2984 2985 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color); 2986 expect(Ok, stat); 2987 expect(0xffff0000, color); 2988 2989 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color); 2990 expect(Ok, stat); 2991 expect(0xffffff00, color); 2992 2993 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color); 2994 expect(Ok, stat); 2995 expect(0xff00ffff, color); 2996 2997 expect(0, bits[0]); 2998 expect(0, bits[1]); 2999 expect(0xff, bits[2]); 3000 3001 GdipDisposeImage(bitmap); 3002 3003 memcpy(bits, orig_bits, sizeof(bits)); 3004 stat = GdipCreateBitmapFromScan0(3, 2, 12, PixelFormat24bppRGB, bits, (GpBitmap**)&bitmap); 3005 expect(Ok, stat); 3006 3007 stat = GdipImageRotateFlip(bitmap, RotateNoneFlipY); 3008 expect(Ok, stat); 3009 3010 stat = GdipGetImageWidth(bitmap, &width); 3011 expect(Ok, stat); 3012 stat = GdipGetImageHeight(bitmap, &height); 3013 expect(Ok, stat); 3014 expect(3, width); 3015 expect(2, height); 3016 3017 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 0, &color); 3018 expect(Ok, stat); 3019 expect(0xff00ffff, color); 3020 3021 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 0, &color); 3022 expect(Ok, stat); 3023 expect(0xffffff00, color); 3024 3025 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 0, 1, &color); 3026 expect(Ok, stat); 3027 expect(0xffff0000, color); 3028 3029 stat = GdipBitmapGetPixel((GpBitmap*)bitmap, 2, 1, &color); 3030 expect(Ok, stat); 3031 expect(0xff0000ff, color); 3032 3033 expect(0, bits[0]); 3034 expect(0, bits[1]); 3035 expect(0xff, bits[2]); 3036 3037 GdipDisposeImage(bitmap); 3038 } 3039 3040 static void test_remaptable(void) 3041 { 3042 GpStatus stat; 3043 GpImageAttributes *imageattr; 3044 GpBitmap *bitmap1, *bitmap2; 3045 GpGraphics *graphics; 3046 ARGB color; 3047 ColorMap *map; 3048 3049 map = GdipAlloc(sizeof(ColorMap)); 3050 3051 map->oldColor.Argb = 0xff00ff00; 3052 map->newColor.Argb = 0xffff00ff; 3053 3054 stat = GdipSetImageAttributesRemapTable(NULL, ColorAdjustTypeDefault, TRUE, 1, map); 3055 expect(InvalidParameter, stat); 3056 3057 stat = GdipCreateImageAttributes(&imageattr); 3058 expect(Ok, stat); 3059 3060 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, NULL); 3061 expect(InvalidParameter, stat); 3062 3063 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeCount, TRUE, 1, map); 3064 expect(InvalidParameter, stat); 3065 3066 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeAny, TRUE, 1, map); 3067 expect(InvalidParameter, stat); 3068 3069 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 0, map); 3070 expect(InvalidParameter, stat); 3071 3072 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, FALSE, 0, NULL); 3073 expect(Ok, stat); 3074 3075 stat = GdipSetImageAttributesRemapTable(imageattr, ColorAdjustTypeDefault, TRUE, 1, map); 3076 expect(Ok, stat); 3077 3078 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1); 3079 expect(Ok, stat); 3080 3081 stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap2); 3082 expect(Ok, stat); 3083 3084 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff00ff00); 3085 expect(Ok, stat); 3086 3087 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics); 3088 expect(Ok, stat); 3089 3090 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1, 3091 UnitPixel, imageattr, NULL, NULL); 3092 expect(Ok, stat); 3093 3094 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 3095 expect(Ok, stat); 3096 ok(color_match(0xffff00ff, color, 1), "Expected ffff00ff, got %.8x\n", color); 3097 3098 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault); 3099 expect(Ok, stat); 3100 3101 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1, 3102 UnitPixel, imageattr, NULL, NULL); 3103 expect(Ok, stat); 3104 3105 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 3106 expect(Ok, stat); 3107 ok(color_match(0xff00ff00, color, 1), "Expected ff00ff00, got %.8x\n", color); 3108 3109 GdipDeleteGraphics(graphics); 3110 GdipDisposeImage((GpImage*)bitmap1); 3111 GdipDisposeImage((GpImage*)bitmap2); 3112 GdipDisposeImageAttributes(imageattr); 3113 GdipFree(map); 3114 } 3115 3116 static void test_colorkey(void) 3117 { 3118 GpStatus stat; 3119 GpImageAttributes *imageattr; 3120 GpBitmap *bitmap1, *bitmap2; 3121 GpGraphics *graphics; 3122 ARGB color; 3123 3124 stat = GdipSetImageAttributesColorKeys(NULL, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090); 3125 expect(InvalidParameter, stat); 3126 3127 stat = GdipCreateImageAttributes(&imageattr); 3128 expect(Ok, stat); 3129 3130 stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeCount, TRUE, 0xff405060, 0xff708090); 3131 expect(InvalidParameter, stat); 3132 3133 stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeAny, TRUE, 0xff405060, 0xff708090); 3134 expect(InvalidParameter, stat); 3135 3136 stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090); 3137 expect(Ok, stat); 3138 3139 stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap1); 3140 expect(Ok, stat); 3141 3142 stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, &bitmap2); 3143 expect(Ok, stat); 3144 3145 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0x20405060); 3146 expect(Ok, stat); 3147 3148 stat = GdipBitmapSetPixel(bitmap1, 0, 1, 0x40506070); 3149 expect(Ok, stat); 3150 3151 stat = GdipBitmapSetPixel(bitmap1, 1, 0, 0x60708090); 3152 expect(Ok, stat); 3153 3154 stat = GdipBitmapSetPixel(bitmap1, 1, 1, 0xffffffff); 3155 expect(Ok, stat); 3156 3157 stat = GdipGetImageGraphicsContext((GpImage*)bitmap2, &graphics); 3158 expect(Ok, stat); 3159 3160 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2, 3161 UnitPixel, imageattr, NULL, NULL); 3162 expect(Ok, stat); 3163 3164 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 3165 expect(Ok, stat); 3166 ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8x\n", color); 3167 3168 stat = GdipBitmapGetPixel(bitmap2, 0, 1, &color); 3169 expect(Ok, stat); 3170 ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8x\n", color); 3171 3172 stat = GdipBitmapGetPixel(bitmap2, 1, 0, &color); 3173 expect(Ok, stat); 3174 ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8x\n", color); 3175 3176 stat = GdipBitmapGetPixel(bitmap2, 1, 1, &color); 3177 expect(Ok, stat); 3178 ok(color_match(0xffffffff, color, 1), "Expected ffffffff, got %.8x\n", color); 3179 3180 stat = GdipResetImageAttributes(imageattr, ColorAdjustTypeDefault); 3181 expect(Ok, stat); 3182 3183 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2, 3184 UnitPixel, imageattr, NULL, NULL); 3185 expect(Ok, stat); 3186 3187 stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color); 3188 expect(Ok, stat); 3189 ok(color_match(0x20405060, color, 1), "Expected 20405060, got %.8x\n", color); 3190 3191 stat = GdipBitmapGetPixel(bitmap2, 0, 1, &color); 3192 expect(Ok, stat); 3193 ok(color_match(0x40506070, color, 1), "Expected 40506070, got %.8x\n", color); 3194 3195 stat = GdipBitmapGetPixel(bitmap2, 1, 0, &color); 3196 expect(Ok, stat); 3197 ok(color_match(0x60708090, color, 1), "Expected 60708090, got %.8x\n", color); 3198 3199 stat = GdipBitmapGetPixel(bitmap2, 1, 1, &color); 3200 expect(Ok, stat); 3201 ok(color_match(0xffffffff, color, 1), "Expected ffffffff, got %.8x\n", color); 3202 3203 3204 GdipDeleteGraphics(graphics); 3205 GdipDisposeImage((GpImage*)bitmap1); 3206 GdipDisposeImage((GpImage*)bitmap2); 3207 GdipDisposeImageAttributes(imageattr); 3208 } 3209 3210 static void test_dispose(void) 3211 { 3212 GpStatus stat; 3213 GpImage *image; 3214 char invalid_image[256]; 3215 3216 stat = GdipDisposeImage(NULL); 3217 expect(InvalidParameter, stat); 3218 3219 stat = GdipCreateBitmapFromScan0(2, 2, 0, PixelFormat32bppARGB, NULL, (GpBitmap**)&image); 3220 expect(Ok, stat); 3221 3222 stat = GdipDisposeImage(image); 3223 expect(Ok, stat); 3224 3225 stat = GdipDisposeImage(image); 3226 expect(ObjectBusy, stat); 3227 3228 memset(invalid_image, 0, 256); 3229 stat = GdipDisposeImage((GpImage*)invalid_image); 3230 expect(ObjectBusy, stat); 3231 } 3232 3233 static LONG obj_refcount(void *obj) 3234 { 3235 IUnknown_AddRef((IUnknown *)obj); 3236 return IUnknown_Release((IUnknown *)obj); 3237 } 3238 3239 static GpImage *load_image(const BYTE *image_data, UINT image_size) 3240 { 3241 IStream *stream; 3242 HGLOBAL hmem; 3243 BYTE *data; 3244 HRESULT hr; 3245 GpStatus status; 3246 GpImage *image = NULL, *clone; 3247 ImageType image_type; 3248 LONG refcount, old_refcount; 3249 3250 hmem = GlobalAlloc(0, image_size); 3251 data = GlobalLock(hmem); 3252 memcpy(data, image_data, image_size); 3253 GlobalUnlock(hmem); 3254 3255 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream); 3256 ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); 3257 if (hr != S_OK) return NULL; 3258 3259 refcount = obj_refcount(stream); 3260 ok(refcount == 1, "expected stream refcount 1, got %d\n", refcount); 3261 3262 status = GdipLoadImageFromStream(stream, &image); 3263 if (status != Ok) 3264 { 3265 IStream_Release(stream); 3266 return NULL; 3267 } 3268 3269 status = GdipGetImageType(image, &image_type); 3270 ok(status == Ok, "GdipGetImageType error %d\n", status); 3271 3272 refcount = obj_refcount(stream); 3273 if (image_type == ImageTypeBitmap) 3274 ok(refcount > 1, "expected stream refcount > 1, got %d\n", refcount); 3275 else 3276 ok(refcount == 1, "expected stream refcount 1, got %d\n", refcount); 3277 old_refcount = refcount; 3278 3279 status = GdipCloneImage(image, &clone); 3280 ok(status == Ok, "GdipCloneImage error %d\n", status); 3281 refcount = obj_refcount(stream); 3282 ok(refcount == old_refcount, "expected stream refcount %d, got %d\n", old_refcount, refcount); 3283 status = GdipDisposeImage(clone); 3284 ok(status == Ok, "GdipDisposeImage error %d\n", status); 3285 refcount = obj_refcount(stream); 3286 ok(refcount == old_refcount, "expected stream refcount %d, got %d\n", old_refcount, refcount); 3287 3288 refcount = IStream_Release(stream); 3289 if (image_type == ImageTypeBitmap) 3290 ok(refcount >= 1, "expected stream refcount != 0\n"); 3291 else 3292 ok(refcount == 0, "expected stream refcount 0, got %d\n", refcount); 3293 3294 return image; 3295 } 3296 3297 static void test_image_properties(void) 3298 { 3299 static const struct test_data 3300 { 3301 const BYTE *image_data; 3302 UINT image_size; 3303 ImageType image_type; 3304 UINT prop_count; 3305 UINT prop_count2; /* if win7 behaves differently */ 3306 /* 1st property attributes */ 3307 UINT prop_size; 3308 UINT prop_size2; /* if win7 behaves differently */ 3309 UINT prop_id; 3310 UINT prop_id2; /* if win7 behaves differently */ 3311 } 3312 td[] = 3313 { 3314 { pngimage, sizeof(pngimage), ImageTypeBitmap, 4, ~0, 1, 20, 0x5110, 0x132 }, 3315 { jpgimage, sizeof(jpgimage), ImageTypeBitmap, 2, ~0, 128, 0, 0x5090, 0x5091 }, 3316 { tiffimage, sizeof(tiffimage), ImageTypeBitmap, 16, 0, 4, 0, 0xfe, 0 }, 3317 { bmpimage, sizeof(bmpimage), ImageTypeBitmap, 0, 0, 0, 0, 0, 0 }, 3318 { wmfimage, sizeof(wmfimage), ImageTypeMetafile, 0, 0, 0, 0, 0, 0 } 3319 }; 3320 GpStatus status; 3321 GpImage *image; 3322 UINT prop_count, prop_size, i; 3323 PROPID prop_id[16] = { 0 }; 3324 ImageType image_type; 3325 union 3326 { 3327 PropertyItem data; 3328 char buf[256]; 3329 } item; 3330 3331 for (i = 0; i < ARRAY_SIZE(td); i++) 3332 { 3333 image = load_image(td[i].image_data, td[i].image_size); 3334 if (!image) 3335 { 3336 trace("%u: failed to load image data\n", i); 3337 continue; 3338 } 3339 3340 status = GdipGetImageType(image, &image_type); 3341 ok(status == Ok, "%u: GdipGetImageType error %d\n", i, status); 3342 ok(td[i].image_type == image_type, "%u: expected image_type %d, got %d\n", 3343 i, td[i].image_type, image_type); 3344 3345 status = GdipGetPropertyCount(image, &prop_count); 3346 ok(status == Ok, "%u: GdipGetPropertyCount error %d\n", i, status); 3347 todo_wine_if(td[i].image_data == pngimage || td[i].image_data == jpgimage) 3348 ok(td[i].prop_count == prop_count || td[i].prop_count2 == prop_count, 3349 " %u: expected property count %u or %u, got %u\n", 3350 i, td[i].prop_count, td[i].prop_count2, prop_count); 3351 3352 status = GdipGetPropertyItemSize(NULL, 0, &prop_size); 3353 expect(InvalidParameter, status); 3354 status = GdipGetPropertyItemSize(image, 0, NULL); 3355 expect(InvalidParameter, status); 3356 status = GdipGetPropertyItemSize(image, 0, &prop_size); 3357 if (image_type == ImageTypeMetafile) 3358 expect(NotImplemented, status); 3359 else 3360 expect(PropertyNotFound, status); 3361 3362 status = GdipGetPropertyItem(NULL, 0, 0, &item.data); 3363 expect(InvalidParameter, status); 3364 status = GdipGetPropertyItem(image, 0, 0, NULL); 3365 expect(InvalidParameter, status); 3366 status = GdipGetPropertyItem(image, 0, 0, &item.data); 3367 if (image_type == ImageTypeMetafile) 3368 expect(NotImplemented, status); 3369 else 3370 expect(PropertyNotFound, status); 3371 3372 /* FIXME: remove once Wine is fixed */ 3373 if (td[i].prop_count != prop_count) 3374 { 3375 GdipDisposeImage(image); 3376 continue; 3377 } 3378 3379 status = GdipGetPropertyIdList(NULL, prop_count, prop_id); 3380 expect(InvalidParameter, status); 3381 status = GdipGetPropertyIdList(image, prop_count, NULL); 3382 expect(InvalidParameter, status); 3383 status = GdipGetPropertyIdList(image, 0, prop_id); 3384 if (image_type == ImageTypeMetafile) 3385 expect(NotImplemented, status); 3386 else if (prop_count == 0) 3387 expect(Ok, status); 3388 else 3389 expect(InvalidParameter, status); 3390 status = GdipGetPropertyIdList(image, prop_count - 1, prop_id); 3391 if (image_type == ImageTypeMetafile) 3392 expect(NotImplemented, status); 3393 else 3394 expect(InvalidParameter, status); 3395 status = GdipGetPropertyIdList(image, prop_count + 1, prop_id); 3396 if (image_type == ImageTypeMetafile) 3397 expect(NotImplemented, status); 3398 else 3399 expect(InvalidParameter, status); 3400 status = GdipGetPropertyIdList(image, prop_count, prop_id); 3401 if (image_type == ImageTypeMetafile) 3402 expect(NotImplemented, status); 3403 else 3404 { 3405 expect(Ok, status); 3406 if (prop_count != 0) 3407 ok(td[i].prop_id == prop_id[0] || td[i].prop_id2 == prop_id[0], 3408 " %u: expected property id %#x or %#x, got %#x\n", 3409 i, td[i].prop_id, td[i].prop_id2, prop_id[0]); 3410 } 3411 3412 if (status == Ok) 3413 { 3414 status = GdipGetPropertyItemSize(image, prop_id[0], &prop_size); 3415 if (prop_count == 0) 3416 expect(PropertyNotFound, status); 3417 else 3418 { 3419 expect(Ok, status); 3420 3421 assert(sizeof(item) >= prop_size); 3422 ok(prop_size > sizeof(PropertyItem), "%u: got too small prop_size %u\n", 3423 i, prop_size); 3424 ok(td[i].prop_size + sizeof(PropertyItem) == prop_size || 3425 td[i].prop_size2 + sizeof(PropertyItem) == prop_size, 3426 " %u: expected property size %u or %u, got %u\n", 3427 i, td[i].prop_size, td[i].prop_size2, prop_size); 3428 3429 status = GdipGetPropertyItem(image, prop_id[0], 0, &item.data); 3430 ok(status == InvalidParameter || status == GenericError /* Win7 */, 3431 "%u: expected InvalidParameter, got %d\n", i, status); 3432 status = GdipGetPropertyItem(image, prop_id[0], prop_size - 1, &item.data); 3433 ok(status == InvalidParameter || status == GenericError /* Win7 */, 3434 "%u: expected InvalidParameter, got %d\n", i, status); 3435 status = GdipGetPropertyItem(image, prop_id[0], prop_size + 1, &item.data); 3436 ok(status == InvalidParameter || status == GenericError /* Win7 */, 3437 "%u: expected InvalidParameter, got %d\n", i, status); 3438 status = GdipGetPropertyItem(image, prop_id[0], prop_size, &item.data); 3439 expect(Ok, status); 3440 ok(prop_id[0] == item.data.id, 3441 "%u: expected property id %#x, got %#x\n", i, prop_id[0], item.data.id); 3442 } 3443 } 3444 3445 GdipDisposeImage(image); 3446 } 3447 } 3448 3449 #define IFD_BYTE 1 3450 #define IFD_ASCII 2 3451 #define IFD_SHORT 3 3452 #define IFD_LONG 4 3453 #define IFD_RATIONAL 5 3454 #define IFD_SBYTE 6 3455 #define IFD_UNDEFINED 7 3456 #define IFD_SSHORT 8 3457 #define IFD_SLONG 9 3458 #define IFD_SRATIONAL 10 3459 #define IFD_FLOAT 11 3460 #define IFD_DOUBLE 12 3461 3462 #ifndef PropertyTagTypeSByte 3463 #define PropertyTagTypeSByte 6 3464 #define PropertyTagTypeSShort 8 3465 #define PropertyTagTypeFloat 11 3466 #define PropertyTagTypeDouble 12 3467 #endif 3468 3469 static UINT documented_type(UINT type) 3470 { 3471 switch (type) 3472 { 3473 case PropertyTagTypeSByte: return PropertyTagTypeByte; 3474 case PropertyTagTypeSShort: return PropertyTagTypeShort; 3475 case PropertyTagTypeFloat: return PropertyTagTypeUndefined; 3476 case PropertyTagTypeDouble: return PropertyTagTypeUndefined; 3477 default: return type; 3478 } 3479 } 3480 3481 #include "pshpack2.h" 3482 struct IFD_entry 3483 { 3484 SHORT id; 3485 SHORT type; 3486 ULONG count; 3487 LONG value; 3488 }; 3489 3490 struct IFD_rational 3491 { 3492 LONG numerator; 3493 LONG denominator; 3494 }; 3495 3496 static const struct tiff_data 3497 { 3498 USHORT byte_order; 3499 USHORT version; 3500 ULONG dir_offset; 3501 USHORT number_of_entries; 3502 struct IFD_entry entry[40]; 3503 ULONG next_IFD; 3504 struct IFD_rational xres; 3505 DOUBLE double_val; 3506 struct IFD_rational srational_val; 3507 char string[14]; 3508 SHORT short_val[4]; 3509 LONG long_val[2]; 3510 FLOAT float_val[2]; 3511 struct IFD_rational rational[3]; 3512 BYTE pixel_data[4]; 3513 } TIFF_data = 3514 { 3515 #ifdef WORDS_BIGENDIAN 3516 'M' | 'M' << 8, 3517 #else 3518 'I' | 'I' << 8, 3519 #endif 3520 42, 3521 FIELD_OFFSET(struct tiff_data, number_of_entries), 3522 31, 3523 { 3524 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ 3525 { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */ 3526 { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ 3527 { 0x102, IFD_SHORT, 1, 1 }, /* BITSPERSAMPLE */ 3528 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ 3529 { 0x106, IFD_SHORT, 1, 1 }, /* PHOTOMETRIC */ 3530 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_data, pixel_data) }, /* STRIPOFFSETS */ 3531 { 0x115, IFD_SHORT, 1, 1 }, /* SAMPLESPERPIXEL */ 3532 { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */ 3533 { 0x117, IFD_LONG, 1, 1 }, /* STRIPBYTECOUNT */ 3534 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_data, xres) }, 3535 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_data, xres) }, 3536 { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ 3537 { 0xf001, IFD_BYTE, 1, 0x11223344 }, 3538 { 0xf002, IFD_BYTE, 4, 0x11223344 }, 3539 { 0xf003, IFD_SBYTE, 1, 0x11223344 }, 3540 { 0xf004, IFD_SSHORT, 1, 0x11223344 }, 3541 { 0xf005, IFD_SSHORT, 2, 0x11223344 }, 3542 { 0xf006, IFD_SLONG, 1, 0x11223344 }, 3543 { 0xf007, IFD_FLOAT, 1, 0x11223344 }, 3544 { 0xf008, IFD_DOUBLE, 1, FIELD_OFFSET(struct tiff_data, double_val) }, 3545 { 0xf009, IFD_SRATIONAL, 1, FIELD_OFFSET(struct tiff_data, srational_val) }, 3546 { 0xf00a, IFD_BYTE, 13, FIELD_OFFSET(struct tiff_data, string) }, 3547 { 0xf00b, IFD_SSHORT, 4, FIELD_OFFSET(struct tiff_data, short_val) }, 3548 { 0xf00c, IFD_SLONG, 2, FIELD_OFFSET(struct tiff_data, long_val) }, 3549 { 0xf00e, IFD_ASCII, 13, FIELD_OFFSET(struct tiff_data, string) }, 3550 { 0xf00f, IFD_ASCII, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 }, 3551 { 0xf010, IFD_UNDEFINED, 13, FIELD_OFFSET(struct tiff_data, string) }, 3552 { 0xf011, IFD_UNDEFINED, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 }, 3553 /* Some gdiplus versions ignore these fields. 3554 { 0xf012, IFD_BYTE, 0, 0x11223344 }, 3555 { 0xf013, IFD_SHORT, 0, 0x11223344 }, 3556 { 0xf014, IFD_LONG, 0, 0x11223344 }, 3557 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/ 3558 { 0xf016, IFD_SRATIONAL, 3, FIELD_OFFSET(struct tiff_data, rational) }, 3559 /* Win7 before SP1 doesn't recognize this field, everybody else does. */ 3560 { 0xf017, IFD_FLOAT, 2, FIELD_OFFSET(struct tiff_data, float_val) }, 3561 }, 3562 0, 3563 { 900, 3 }, 3564 1234567890.0987654321, 3565 { 0x1a2b3c4d, 0x5a6b7c8d }, 3566 "Hello World!", 3567 { 0x0101, 0x0202, 0x0303, 0x0404 }, 3568 { 0x11223344, 0x55667788 }, 3569 { (FLOAT)1234.5678, (FLOAT)8765.4321 }, 3570 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } }, 3571 { 0x11, 0x22, 0x33, 0 } 3572 }; 3573 #include "poppack.h" 3574 3575 static void test_tiff_properties(void) 3576 { 3577 static const struct test_data 3578 { 3579 ULONG type, id, length; 3580 const BYTE value[24]; 3581 } td[31] = 3582 { 3583 { PropertyTagTypeShort, 0xff, 2, { 0 } }, 3584 { PropertyTagTypeLong, 0x100, 4, { 1 } }, 3585 { PropertyTagTypeLong, 0x101, 4, { 1 } }, 3586 { PropertyTagTypeShort, 0x102, 2, { 1 } }, 3587 { PropertyTagTypeShort, 0x103, 2, { 1 } }, 3588 { PropertyTagTypeShort, 0x106, 2, { 1 } }, 3589 { PropertyTagTypeLong, 0x111, 4, { 0x44,0x02 } }, 3590 { PropertyTagTypeShort, 0x115, 2, { 1 } }, 3591 { PropertyTagTypeLong, 0x116, 4, { 1 } }, 3592 { PropertyTagTypeLong, 0x117, 4, { 1 } }, 3593 { PropertyTagTypeRational, 0x11a, 8, { 0x84,0x03,0,0,0x03 } }, 3594 { PropertyTagTypeRational, 0x11b, 8, { 0x84,0x03,0,0,0x03 } }, 3595 { PropertyTagTypeShort, 0x128, 2, { 2 } }, 3596 { PropertyTagTypeByte, 0xf001, 1, { 0x44 } }, 3597 { PropertyTagTypeByte, 0xf002, 4, { 0x44,0x33,0x22,0x11 } }, 3598 { PropertyTagTypeSByte, 0xf003, 1, { 0x44 } }, 3599 { PropertyTagTypeSShort, 0xf004, 2, { 0x44,0x33 } }, 3600 { PropertyTagTypeSShort, 0xf005, 4, { 0x44,0x33,0x22,0x11 } }, 3601 { PropertyTagTypeSLONG, 0xf006, 4, { 0x44,0x33,0x22,0x11 } }, 3602 { PropertyTagTypeFloat, 0xf007, 4, { 0x44,0x33,0x22,0x11 } }, 3603 { PropertyTagTypeDouble, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } }, 3604 { PropertyTagTypeSRational, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } }, 3605 { PropertyTagTypeByte, 0xf00a, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } }, 3606 { PropertyTagTypeSShort, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } }, 3607 { PropertyTagTypeSLONG, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } }, 3608 { PropertyTagTypeASCII, 0xf00e, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } }, 3609 { PropertyTagTypeASCII, 0xf00f, 5, { 'a','b','c','d' } }, 3610 { PropertyTagTypeUndefined, 0xf010, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } }, 3611 { PropertyTagTypeUndefined, 0xf011, 4, { 'a','b','c','d' } }, 3612 { PropertyTagTypeSRational, 0xf016, 24, 3613 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05, 3614 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50, 3615 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } }, 3616 /* Win7 before SP1 doesn't recognize this field, everybody else does. */ 3617 { PropertyTagTypeFloat, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } }, 3618 }; 3619 GpStatus status; 3620 GpImage *image; 3621 GUID guid; 3622 UINT dim_count, frame_count, prop_count, prop_size, i; 3623 PROPID *prop_id; 3624 PropertyItem *prop_item; 3625 3626 image = load_image((const BYTE *)&TIFF_data, sizeof(TIFF_data)); 3627 if (!image) 3628 { 3629 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n"); 3630 return; 3631 } 3632 3633 status = GdipImageGetFrameDimensionsCount(image, &dim_count); 3634 expect(Ok, status); 3635 expect(1, dim_count); 3636 3637 status = GdipImageGetFrameDimensionsList(image, &guid, 1); 3638 expect(Ok, status); 3639 expect_guid(&FrameDimensionPage, &guid, __LINE__, FALSE); 3640 3641 frame_count = 0xdeadbeef; 3642 status = GdipImageGetFrameCount(image, &guid, &frame_count); 3643 expect(Ok, status); 3644 expect(1, frame_count); 3645 3646 prop_count = 0xdeadbeef; 3647 status = GdipGetPropertyCount(image, &prop_count); 3648 expect(Ok, status); 3649 ok(prop_count == ARRAY_SIZE(td) || 3650 broken(prop_count == ARRAY_SIZE(td) - 1) /* Win7 SP0 */, 3651 "expected property count %u, got %u\n", (UINT) ARRAY_SIZE(td), prop_count); 3652 3653 prop_id = HeapAlloc(GetProcessHeap(), 0, prop_count * sizeof(*prop_id)); 3654 3655 status = GdipGetPropertyIdList(image, prop_count, prop_id); 3656 expect(Ok, status); 3657 3658 for (i = 0; i < prop_count; i++) 3659 { 3660 status = GdipGetPropertyItemSize(image, prop_id[i], &prop_size); 3661 expect(Ok, status); 3662 if (status != Ok) break; 3663 ok(prop_size > sizeof(*prop_item), "%u: too small item length %u\n", i, prop_size); 3664 3665 prop_item = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, prop_size); 3666 status = GdipGetPropertyItem(image, prop_id[i], prop_size, prop_item); 3667 expect(Ok, status); 3668 ok(prop_item->value == prop_item + 1, "expected item->value %p, got %p\n", prop_item + 1, prop_item->value); 3669 ok(td[i].type == prop_item->type || 3670 /* Win7 stopped using proper but not documented types, and it 3671 looks broken since TypeFloat and TypeDouble now reported as 3672 TypeUndefined, and signed types reported as unsigned. */ 3673 broken(prop_item->type == documented_type(td[i].type)), 3674 "%u: expected type %u, got %u\n", i, td[i].type, prop_item->type); 3675 ok(td[i].id == prop_item->id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item->id); 3676 prop_size -= sizeof(*prop_item); 3677 ok(prop_item->length == prop_size, "%u: expected length %u, got %u\n", i, prop_size, prop_item->length); 3678 ok(td[i].length == prop_item->length || broken(td[i].id == 0xf00f && td[i].length == prop_item->length+1) /* XP */, 3679 "%u: expected length %u, got %u\n", i, td[i].length, prop_item->length); 3680 ok(td[i].length == prop_size || broken(td[i].id == 0xf00f && td[i].length == prop_size+1) /* XP */, 3681 "%u: expected length %u, got %u\n", i, td[i].length, prop_size); 3682 if (td[i].length == prop_item->length) 3683 { 3684 int match = memcmp(td[i].value, prop_item->value, td[i].length) == 0; 3685 ok(match || broken(td[i].length <= 4 && !match), "%u: data mismatch\n", i); 3686 if (!match) 3687 { 3688 UINT j; 3689 BYTE *data = prop_item->value; 3690 trace("id %#x:", prop_item->id); 3691 for (j = 0; j < prop_item->length; j++) 3692 trace(" %02x", data[j]); 3693 trace("\n"); 3694 } 3695 } 3696 HeapFree(GetProcessHeap(), 0, prop_item); 3697 } 3698 3699 HeapFree(GetProcessHeap(), 0, prop_id); 3700 3701 GdipDisposeImage(image); 3702 } 3703 3704 static void test_GdipGetAllPropertyItems(void) 3705 { 3706 static const struct test_data 3707 { 3708 ULONG type, id, length; 3709 BYTE value[32]; 3710 } td[16] = 3711 { 3712 { PropertyTagTypeLong, 0xfe, 4, { 0 } }, 3713 { PropertyTagTypeShort, 0x100, 2, { 1 } }, 3714 { PropertyTagTypeShort, 0x101, 2, { 1 } }, 3715 { PropertyTagTypeShort, 0x102, 6, { 8,0,8,0,8,0 } }, 3716 { PropertyTagTypeShort, 0x103, 2, { 1 } }, 3717 { PropertyTagTypeShort, 0x106, 2, { 2,0 } }, 3718 { PropertyTagTypeASCII, 0x10d, 27, "/home/meh/Desktop/test.tif" }, 3719 { PropertyTagTypeLong, 0x111, 4, { 8,0,0,0 } }, 3720 { PropertyTagTypeShort, 0x112, 2, { 1 } }, 3721 { PropertyTagTypeShort, 0x115, 2, { 3,0 } }, 3722 { PropertyTagTypeShort, 0x116, 2, { 0x40,0 } }, 3723 { PropertyTagTypeLong, 0x117, 4, { 3,0,0,0 } }, 3724 { PropertyTagTypeRational, 0x11a, 8, { 0,0,0,72,0,0,0,1 } }, 3725 { PropertyTagTypeRational, 0x11b, 8, { 0,0,0,72,0,0,0,1 } }, 3726 { PropertyTagTypeShort, 0x11c, 2, { 1 } }, 3727 { PropertyTagTypeShort, 0x128, 2, { 2 } } 3728 }; 3729 GpStatus status; 3730 GpImage *image; 3731 GUID guid; 3732 UINT dim_count, frame_count, prop_count, prop_size, i; 3733 UINT total_size, total_count; 3734 PROPID *prop_id; 3735 PropertyItem *prop_item; 3736 const char *item_data; 3737 3738 image = load_image(tiffimage, sizeof(tiffimage)); 3739 ok(image != 0, "Failed to load TIFF image data\n"); 3740 if (!image) return; 3741 3742 dim_count = 0xdeadbeef; 3743 status = GdipImageGetFrameDimensionsCount(image, &dim_count); 3744 expect(Ok, status); 3745 expect(1, dim_count); 3746 3747 status = GdipImageGetFrameDimensionsList(image, &guid, 1); 3748 expect(Ok, status); 3749 expect_guid(&FrameDimensionPage, &guid, __LINE__, FALSE); 3750 3751 frame_count = 0xdeadbeef; 3752 status = GdipImageGetFrameCount(image, &guid, &frame_count); 3753 expect(Ok, status); 3754 expect(1, frame_count); 3755 3756 prop_count = 0xdeadbeef; 3757 status = GdipGetPropertyCount(image, &prop_count); 3758 expect(Ok, status); 3759 ok(prop_count == ARRAY_SIZE(td), 3760 "expected property count %u, got %u\n", (UINT) ARRAY_SIZE(td), prop_count); 3761 3762 prop_id = HeapAlloc(GetProcessHeap(), 0, prop_count * sizeof(*prop_id)); 3763 3764 status = GdipGetPropertyIdList(image, prop_count, prop_id); 3765 expect(Ok, status); 3766 3767 prop_size = 0; 3768 for (i = 0; i < prop_count; i++) 3769 { 3770 UINT size; 3771 status = GdipGetPropertyItemSize(image, prop_id[i], &size); 3772 expect(Ok, status); 3773 if (status != Ok) break; 3774 ok(size > sizeof(*prop_item), "%u: too small item length %u\n", i, size); 3775 3776 prop_size += size; 3777 3778 prop_item = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 3779 status = GdipGetPropertyItem(image, prop_id[i], size, prop_item); 3780 expect(Ok, status); 3781 ok(prop_item->value == prop_item + 1, "expected item->value %p, got %p\n", prop_item + 1, prop_item->value); 3782 ok(td[i].type == prop_item->type, 3783 "%u: expected type %u, got %u\n", i, td[i].type, prop_item->type); 3784 ok(td[i].id == prop_item->id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item->id); 3785 size -= sizeof(*prop_item); 3786 ok(prop_item->length == size, "%u: expected length %u, got %u\n", i, size, prop_item->length); 3787 ok(td[i].length == prop_item->length, "%u: expected length %u, got %u\n", i, td[i].length, prop_item->length); 3788 if (td[i].length == prop_item->length) 3789 { 3790 int match = memcmp(td[i].value, prop_item->value, td[i].length) == 0; 3791 ok(match, "%u: data mismatch\n", i); 3792 if (!match) 3793 { 3794 UINT j; 3795 BYTE *data = prop_item->value; 3796 trace("id %#x:", prop_item->id); 3797 for (j = 0; j < prop_item->length; j++) 3798 trace(" %02x", data[j]); 3799 trace("\n"); 3800 } 3801 } 3802 HeapFree(GetProcessHeap(), 0, prop_item); 3803 } 3804 3805 HeapFree(GetProcessHeap(), 0, prop_id); 3806 3807 status = GdipGetPropertySize(NULL, &total_size, &total_count); 3808 expect(InvalidParameter, status); 3809 status = GdipGetPropertySize(image, &total_size, NULL); 3810 expect(InvalidParameter, status); 3811 status = GdipGetPropertySize(image, NULL, &total_count); 3812 expect(InvalidParameter, status); 3813 status = GdipGetPropertySize(image, NULL, NULL); 3814 expect(InvalidParameter, status); 3815 total_size = 0xdeadbeef; 3816 total_count = 0xdeadbeef; 3817 status = GdipGetPropertySize(image, &total_size, &total_count); 3818 expect(Ok, status); 3819 ok(prop_count == total_count, 3820 "expected total property count %u, got %u\n", prop_count, total_count); 3821 ok(prop_size == total_size, 3822 "expected total property size %u, got %u\n", prop_size, total_size); 3823 3824 prop_item = HeapAlloc(GetProcessHeap(), 0, prop_size); 3825 3826 status = GdipGetAllPropertyItems(image, 0, prop_count, prop_item); 3827 expect(InvalidParameter, status); 3828 status = GdipGetAllPropertyItems(image, prop_size, 1, prop_item); 3829 expect(InvalidParameter, status); 3830 status = GdipGetAllPropertyItems(image, prop_size, prop_count, NULL); 3831 expect(InvalidParameter, status); 3832 status = GdipGetAllPropertyItems(image, prop_size, prop_count, NULL); 3833 expect(InvalidParameter, status); 3834 status = GdipGetAllPropertyItems(image, 0, 0, NULL); 3835 expect(InvalidParameter, status); 3836 status = GdipGetAllPropertyItems(image, prop_size + 1, prop_count, prop_item); 3837 expect(InvalidParameter, status); 3838 status = GdipGetAllPropertyItems(image, prop_size, prop_count, prop_item); 3839 expect(Ok, status); 3840 3841 item_data = (const char *)(prop_item + prop_count); 3842 for (i = 0; i < prop_count; i++) 3843 { 3844 ok(prop_item[i].value == item_data, "%u: expected value %p, got %p\n", 3845 i, item_data, prop_item[i].value); 3846 ok(td[i].type == prop_item[i].type, 3847 "%u: expected type %u, got %u\n", i, td[i].type, prop_item[i].type); 3848 ok(td[i].id == prop_item[i].id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item[i].id); 3849 ok(td[i].length == prop_item[i].length, "%u: expected length %u, got %u\n", i, td[i].length, prop_item[i].length); 3850 if (td[i].length == prop_item[i].length) 3851 { 3852 int match = memcmp(td[i].value, prop_item[i].value, td[i].length) == 0; 3853 ok(match, "%u: data mismatch\n", i); 3854 if (!match) 3855 { 3856 UINT j; 3857 BYTE *data = prop_item[i].value; 3858 trace("id %#x:", prop_item[i].id); 3859 for (j = 0; j < prop_item[i].length; j++) 3860 trace(" %02x", data[j]); 3861 trace("\n"); 3862 } 3863 } 3864 item_data += prop_item[i].length; 3865 } 3866 3867 HeapFree(GetProcessHeap(), 0, prop_item); 3868 3869 GdipDisposeImage(image); 3870 } 3871 3872 static void test_tiff_palette(void) 3873 { 3874 GpStatus status; 3875 GpImage *image; 3876 PixelFormat format; 3877 INT size; 3878 struct 3879 { 3880 ColorPalette pal; 3881 ARGB entry[256]; 3882 } palette; 3883 ARGB *entries = palette.pal.Entries; 3884 3885 /* 1bpp TIFF without palette */ 3886 image = load_image((const BYTE *)&TIFF_data, sizeof(TIFF_data)); 3887 if (!image) 3888 { 3889 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n"); 3890 return; 3891 } 3892 3893 status = GdipGetImagePixelFormat(image, &format); 3894 expect(Ok, status); 3895 ok(format == PixelFormat1bppIndexed, "expected PixelFormat1bppIndexed, got %#x\n", format); 3896 3897 status = GdipGetImagePaletteSize(image, &size); 3898 ok(status == Ok || broken(status == GenericError), /* XP */ 3899 "GdipGetImagePaletteSize error %d\n", status); 3900 if (status == GenericError) 3901 { 3902 GdipDisposeImage(image); 3903 return; 3904 } 3905 expect(sizeof(ColorPalette) + sizeof(ARGB), size); 3906 3907 status = GdipGetImagePalette(image, &palette.pal, size); 3908 expect(Ok, status); 3909 expect(0, palette.pal.Flags); 3910 expect(2, palette.pal.Count); 3911 if (palette.pal.Count == 2) 3912 { 3913 ok(entries[0] == 0xff000000, "expected 0xff000000, got %#x\n", entries[0]); 3914 ok(entries[1] == 0xffffffff, "expected 0xffffffff, got %#x\n", entries[1]); 3915 } 3916 3917 GdipDisposeImage(image); 3918 } 3919 3920 static void test_bitmapbits(void) 3921 { 3922 /* 8 x 2 bitmap */ 3923 static const BYTE pixels_24[48] = 3924 { 3925 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0, 3926 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0, 3927 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0, 3928 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0 3929 }; 3930 static const BYTE pixels_00[48] = 3931 { 3932 0,0,0, 0,0,0, 0,0,0, 0,0,0, 3933 0,0,0, 0,0,0, 0,0,0, 0,0,0, 3934 0,0,0, 0,0,0, 0,0,0, 0,0,0, 3935 0,0,0, 0,0,0, 0,0,0, 0,0,0 3936 }; 3937 static const BYTE pixels_24_77[64] = 3938 { 3939 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0, 3940 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0, 3941 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3942 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0, 3943 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0, 3944 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77 3945 }; 3946 static const BYTE pixels_77[64] = 3947 { 3948 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3949 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3950 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3951 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3952 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3953 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3954 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3955 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77 3956 }; 3957 static const BYTE pixels_8[16] = 3958 { 3959 0x01,0,0x01,0,0x01,0,0x01,0, 3960 0x01,0,0x01,0,0x01,0,0x01,0 3961 }; 3962 static const BYTE pixels_8_77[64] = 3963 { 3964 0x01,0,0x01,0,0x01,0,0x01,0, 3965 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3966 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3967 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3968 0x01,0,0x01,0,0x01,0,0x01,0, 3969 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3970 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3971 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77 3972 }; 3973 static const BYTE pixels_1_77[64] = 3974 { 3975 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3976 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3977 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3978 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3979 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3980 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3981 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77, 3982 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77 3983 }; 3984 static const BYTE pixels_1[8] = {0xaa,0,0,0,0xaa,0,0,0}; 3985 static const struct test_data 3986 { 3987 PixelFormat format; 3988 UINT bpp; 3989 ImageLockMode mode; 3990 UINT stride, size; 3991 const BYTE *pixels; 3992 const BYTE *pixels_unlocked; 3993 } td[] = 3994 { 3995 /* 0 */ 3996 { PixelFormat24bppRGB, 24, 0xfff0, 24, 48, pixels_24, pixels_00 }, 3997 3998 { PixelFormat24bppRGB, 24, 0, 24, 48, pixels_24, pixels_00 }, 3999 { PixelFormat24bppRGB, 24, ImageLockModeRead, 24, 48, pixels_24, pixels_00 }, 4000 { PixelFormat24bppRGB, 24, ImageLockModeWrite, 24, 48, pixels_24, pixels_00 }, 4001 { PixelFormat24bppRGB, 24, ImageLockModeRead|ImageLockModeWrite, 24, 48, pixels_24, pixels_00 }, 4002 { PixelFormat24bppRGB, 24, ImageLockModeRead|ImageLockModeUserInputBuf, 32, 64, pixels_24_77, pixels_24 }, 4003 { PixelFormat24bppRGB, 24, ImageLockModeWrite|ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_00 }, 4004 { PixelFormat24bppRGB, 24, ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_24 }, 4005 /* 8 */ 4006 { PixelFormat8bppIndexed, 8, 0, 8, 16, pixels_8, pixels_24 }, 4007 { PixelFormat8bppIndexed, 8, ImageLockModeRead, 8, 16, pixels_8, pixels_24 }, 4008 { PixelFormat8bppIndexed, 8, ImageLockModeWrite, 8, 16, pixels_8, pixels_00 }, 4009 { PixelFormat8bppIndexed, 8, ImageLockModeRead|ImageLockModeWrite, 8, 16, pixels_8, pixels_00 }, 4010 { PixelFormat8bppIndexed, 8, ImageLockModeRead|ImageLockModeUserInputBuf, 32, 64, pixels_8_77, pixels_24 }, 4011 { PixelFormat8bppIndexed, 8, ImageLockModeWrite|ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_00 }, 4012 { PixelFormat8bppIndexed, 8, ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_24 }, 4013 /* 15 */ 4014 { PixelFormat1bppIndexed, 1, 0, 4, 8, pixels_1, pixels_24 }, 4015 { PixelFormat1bppIndexed, 1, ImageLockModeRead, 4, 8, pixels_1, pixels_24 }, 4016 { PixelFormat1bppIndexed, 1, ImageLockModeWrite, 4, 8, pixels_1, pixels_00 }, 4017 { PixelFormat1bppIndexed, 1, ImageLockModeRead|ImageLockModeWrite, 4, 8, pixels_1, pixels_00 }, 4018 { PixelFormat1bppIndexed, 1, ImageLockModeRead|ImageLockModeUserInputBuf, 32, 64, pixels_1_77, pixels_24 }, 4019 { PixelFormat1bppIndexed, 1, ImageLockModeWrite|ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_00 }, 4020 { PixelFormat1bppIndexed, 1, ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_24 }, 4021 }; 4022 BYTE buf[64]; 4023 GpStatus status; 4024 GpBitmap *bitmap; 4025 UINT i; 4026 BitmapData data; 4027 struct 4028 { 4029 ColorPalette pal; 4030 ARGB entries[1]; 4031 } palette; 4032 ARGB *entries = palette.pal.Entries; 4033 4034 for (i = 0; i < ARRAY_SIZE(td); i++) 4035 { 4036 BYTE pixels[sizeof(pixels_24)]; 4037 memcpy(pixels, pixels_24, sizeof(pixels_24)); 4038 status = GdipCreateBitmapFromScan0(8, 2, 24, PixelFormat24bppRGB, pixels, &bitmap); 4039 expect(Ok, status); 4040 4041 /* associate known palette with pixel data */ 4042 palette.pal.Flags = PaletteFlagsGrayScale; 4043 palette.pal.Count = 2; 4044 entries[0] = 0xff000000; 4045 entries[1] = 0xffffffff; 4046 status = GdipSetImagePalette((GpImage *)bitmap, &palette.pal); 4047 expect(Ok, status); 4048 4049 memset(&data, 0xfe, sizeof(data)); 4050 if (td[i].mode & ImageLockModeUserInputBuf) 4051 { 4052 memset(buf, 0x77, sizeof(buf)); 4053 data.Scan0 = buf; 4054 data.Stride = 32; 4055 } 4056 status = GdipBitmapLockBits(bitmap, NULL, td[i].mode, td[i].format, &data); 4057 ok(status == Ok || broken(status == InvalidParameter) /* XP */, "%u: GdipBitmapLockBits error %d\n", i, status); 4058 if (status != Ok) 4059 { 4060 GdipDisposeImage((GpImage *)bitmap); 4061 continue; 4062 } 4063 ok(data.Width == 8, "%u: expected 8, got %d\n", i, data.Width); 4064 ok(data.Height == 2, "%u: expected 2, got %d\n", i, data.Height); 4065 ok(td[i].stride == data.Stride, "%u: expected %d, got %d\n", i, td[i].stride, data.Stride); 4066 ok(td[i].format == data.PixelFormat, "%u: expected %d, got %d\n", i, td[i].format, data.PixelFormat); 4067 ok(td[i].size == data.Height * data.Stride, "%u: expected %d, got %d\n", i, td[i].size, data.Height * data.Stride); 4068 if (td[i].mode & ImageLockModeUserInputBuf) 4069 ok(data.Scan0 == buf, "%u: got wrong buffer\n", i); 4070 if (td[i].size == data.Height * data.Stride) 4071 { 4072 UINT j, match, width_bytes = (data.Width * td[i].bpp) / 8; 4073 4074 match = 1; 4075 for (j = 0; j < data.Height; j++) 4076 { 4077 if (memcmp((const BYTE *)data.Scan0 + j * data.Stride, td[i].pixels + j * data.Stride, width_bytes) != 0) 4078 { 4079 match = 0; 4080 break; 4081 } 4082 } 4083 if ((td[i].mode & (ImageLockModeRead|ImageLockModeUserInputBuf)) || td[i].format == PixelFormat24bppRGB) 4084 { 4085 ok(match, 4086 "%u: data should match\n", i); 4087 if (!match) 4088 { 4089 BYTE *bits = data.Scan0; 4090 trace("%u: data mismatch for format %#x:", i, td[i].format); 4091 for (j = 0; j < td[i].size; j++) 4092 trace(" %02x", bits[j]); 4093 trace("\n"); 4094 } 4095 } 4096 else 4097 ok(!match, "%u: data shouldn't match\n", i); 4098 4099 memset(data.Scan0, 0, td[i].size); 4100 } 4101 4102 status = GdipBitmapUnlockBits(bitmap, &data); 4103 ok(status == Ok, "%u: GdipBitmapUnlockBits error %d\n", i, status); 4104 4105 memset(&data, 0xfe, sizeof(data)); 4106 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat24bppRGB, &data); 4107 ok(status == Ok, "%u: GdipBitmapLockBits error %d\n", i, status); 4108 ok(data.Width == 8, "%u: expected 8, got %d\n", i, data.Width); 4109 ok(data.Height == 2, "%u: expected 2, got %d\n", i, data.Height); 4110 ok(data.Stride == 24, "%u: expected 24, got %d\n", i, data.Stride); 4111 ok(data.PixelFormat == PixelFormat24bppRGB, "%u: got wrong pixel format %d\n", i, data.PixelFormat); 4112 ok(data.Height * data.Stride == 48, "%u: expected 48, got %d\n", i, data.Height * data.Stride); 4113 if (data.Height * data.Stride == 48) 4114 { 4115 int match = memcmp(data.Scan0, td[i].pixels_unlocked, 48) == 0; 4116 ok(match, "%u: data should match\n", i); 4117 if (!match) 4118 { 4119 UINT j; 4120 BYTE *bits = data.Scan0; 4121 trace("%u: data mismatch for format %#x:", i, td[i].format); 4122 for (j = 0; j < 48; j++) 4123 trace(" %02x", bits[j]); 4124 trace("\n"); 4125 } 4126 } 4127 4128 status = GdipBitmapUnlockBits(bitmap, &data); 4129 ok(status == Ok, "%u: GdipBitmapUnlockBits error %d\n", i, status); 4130 4131 status = GdipDisposeImage((GpImage *)bitmap); 4132 expect(Ok, status); 4133 } 4134 } 4135 4136 static void test_DrawImage(void) 4137 { 4138 BYTE black_1x1[4] = { 0,0,0,0 }; 4139 BYTE white_2x2[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 4140 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; 4141 BYTE black_2x2[16] = { 0,0,0,0,0,0,0xff,0xff, 4142 0,0,0,0,0,0,0xff,0xff }; 4143 GpStatus status; 4144 union 4145 { 4146 GpBitmap *bitmap; 4147 GpImage *image; 4148 } u1, u2; 4149 GpGraphics *graphics; 4150 int match; 4151 4152 status = GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB, black_1x1, &u1.bitmap); 4153 expect(Ok, status); 4154 status = GdipBitmapSetResolution(u1.bitmap, 100.0, 100.0); 4155 expect(Ok, status); 4156 4157 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB, white_2x2, &u2.bitmap); 4158 expect(Ok, status); 4159 status = GdipBitmapSetResolution(u2.bitmap, 300.0, 300.0); 4160 expect(Ok, status); 4161 status = GdipGetImageGraphicsContext(u2.image, &graphics); 4162 expect(Ok, status); 4163 status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor); 4164 expect(Ok, status); 4165 4166 status = GdipDrawImageI(graphics, u1.image, 0, 0); 4167 expect(Ok, status); 4168 4169 match = memcmp(white_2x2, black_2x2, sizeof(black_2x2)) == 0; 4170 ok(match, "data should match\n"); 4171 if (!match) 4172 { 4173 UINT i, size = sizeof(white_2x2); 4174 BYTE *bits = white_2x2; 4175 for (i = 0; i < size; i++) 4176 trace(" %02x", bits[i]); 4177 trace("\n"); 4178 } 4179 4180 status = GdipDeleteGraphics(graphics); 4181 expect(Ok, status); 4182 status = GdipDisposeImage(u1.image); 4183 expect(Ok, status); 4184 status = GdipDisposeImage(u2.image); 4185 expect(Ok, status); 4186 } 4187 4188 static void test_DrawImage_SourceCopy(void) 4189 { 4190 DWORD dst_pixels[4] = { 0xffffffff, 0xffffffff, 4191 0xffffffff, 0xffffffff }; 4192 DWORD src_pixels[4] = { 0, 0xffff0000, 4193 0, 0xff00ff }; 4194 4195 GpStatus status; 4196 union 4197 { 4198 GpBitmap *bitmap; 4199 GpImage *image; 4200 } u1, u2; 4201 GpGraphics *graphics; 4202 4203 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB, (BYTE*)dst_pixels, &u1.bitmap); 4204 expect(Ok, status); 4205 4206 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB, (BYTE*)src_pixels, &u2.bitmap); 4207 expect(Ok, status); 4208 status = GdipGetImageGraphicsContext(u1.image, &graphics); 4209 expect(Ok, status); 4210 status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor); 4211 expect(Ok, status); 4212 4213 status = GdipSetCompositingMode(graphics, CompositingModeSourceCopy); 4214 expect(Ok, status); 4215 4216 status = GdipDrawImageI(graphics, u2.image, 0, 0); 4217 expect(Ok, status); 4218 4219 todo_wine expect(0, dst_pixels[0]); 4220 expect(0xffff0000, dst_pixels[1]); 4221 todo_wine expect(0, dst_pixels[2]); 4222 todo_wine expect(0, dst_pixels[3]); 4223 4224 status = GdipDeleteGraphics(graphics); 4225 expect(Ok, status); 4226 status = GdipDisposeImage(u1.image); 4227 expect(Ok, status); 4228 status = GdipDisposeImage(u2.image); 4229 expect(Ok, status); 4230 } 4231 4232 static void test_GdipDrawImagePointRect(void) 4233 { 4234 BYTE black_1x1[4] = { 0,0,0,0 }; 4235 BYTE white_2x2[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 4236 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; 4237 BYTE black_2x2[16] = { 0,0,0,0,0,0,0xff,0xff, 4238 0,0,0,0,0,0,0xff,0xff }; 4239 GpStatus status; 4240 union 4241 { 4242 GpBitmap *bitmap; 4243 GpImage *image; 4244 } u1, u2; 4245 GpGraphics *graphics; 4246 int match; 4247 4248 status = GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB, black_1x1, &u1.bitmap); 4249 expect(Ok, status); 4250 status = GdipBitmapSetResolution(u1.bitmap, 100.0, 100.0); 4251 expect(Ok, status); 4252 4253 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB, white_2x2, &u2.bitmap); 4254 expect(Ok, status); 4255 status = GdipBitmapSetResolution(u2.bitmap, 300.0, 300.0); 4256 expect(Ok, status); 4257 status = GdipGetImageGraphicsContext(u2.image, &graphics); 4258 expect(Ok, status); 4259 status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor); 4260 expect(Ok, status); 4261 4262 status = GdipDrawImagePointRectI(graphics, u1.image, 0, 0, 0, 0, 1, 1, UnitPixel); 4263 expect(Ok, status); 4264 4265 match = memcmp(white_2x2, black_2x2, sizeof(black_2x2)) == 0; 4266 ok(match, "data should match\n"); 4267 if (!match) 4268 { 4269 UINT i, size = sizeof(white_2x2); 4270 BYTE *bits = white_2x2; 4271 for (i = 0; i < size; i++) 4272 trace(" %02x", bits[i]); 4273 trace("\n"); 4274 } 4275 4276 status = GdipDeleteGraphics(graphics); 4277 expect(Ok, status); 4278 status = GdipDisposeImage(u1.image); 4279 expect(Ok, status); 4280 status = GdipDisposeImage(u2.image); 4281 expect(Ok, status); 4282 } 4283 4284 static void test_image_format(void) 4285 { 4286 static const PixelFormat fmt[] = 4287 { 4288 PixelFormat1bppIndexed, PixelFormat4bppIndexed, PixelFormat8bppIndexed, 4289 PixelFormat16bppGrayScale, PixelFormat16bppRGB555, PixelFormat16bppRGB565, 4290 PixelFormat16bppARGB1555, PixelFormat24bppRGB, PixelFormat32bppRGB, 4291 PixelFormat32bppARGB, PixelFormat32bppPARGB, PixelFormat48bppRGB, 4292 PixelFormat64bppARGB, PixelFormat64bppPARGB, PixelFormat32bppCMYK 4293 }; 4294 GpStatus status; 4295 GpBitmap *bitmap; 4296 GpImage *thumb; 4297 HBITMAP hbitmap; 4298 BITMAP bm; 4299 PixelFormat format; 4300 BitmapData data; 4301 UINT i, ret; 4302 4303 for (i = 0; i < ARRAY_SIZE(fmt); i++) 4304 { 4305 status = GdipCreateBitmapFromScan0(1, 1, 0, fmt[i], NULL, &bitmap); 4306 ok(status == Ok || broken(status == InvalidParameter) /* before win7 */, 4307 "GdipCreateBitmapFromScan0 error %d\n", status); 4308 if (status != Ok) continue; 4309 4310 status = GdipGetImagePixelFormat((GpImage *)bitmap, &format); 4311 expect(Ok, status); 4312 expect(fmt[i], format); 4313 4314 status = GdipCreateHBITMAPFromBitmap(bitmap, &hbitmap, 0); 4315 if (fmt[i] == PixelFormat16bppGrayScale || fmt[i] == PixelFormat32bppCMYK) 4316 todo_wine expect(InvalidParameter, status); 4317 else 4318 { 4319 expect(Ok, status); 4320 ret = GetObjectW(hbitmap, sizeof(bm), &bm); 4321 expect(sizeof(bm), ret); 4322 expect(0, bm.bmType); 4323 expect(1, bm.bmWidth); 4324 expect(1, bm.bmHeight); 4325 expect(4, bm.bmWidthBytes); 4326 expect(1, bm.bmPlanes); 4327 expect(32, bm.bmBitsPixel); 4328 DeleteObject(hbitmap); 4329 } 4330 4331 status = GdipGetImageThumbnail((GpImage *)bitmap, 0, 0, &thumb, NULL, NULL); 4332 if (fmt[i] == PixelFormat16bppGrayScale || fmt[i] == PixelFormat32bppCMYK) 4333 todo_wine 4334 ok(status == OutOfMemory || broken(status == InvalidParameter) /* before win7 */, 4335 "expected OutOfMemory, got %d\n", status); 4336 else 4337 expect(Ok, status); 4338 if (status == Ok) 4339 { 4340 status = GdipGetImagePixelFormat(thumb, &format); 4341 expect(Ok, status); 4342 ok(format == PixelFormat32bppPARGB || broken(format != PixelFormat32bppPARGB) /* before win7 */, 4343 "expected PixelFormat32bppPARGB, got %#x\n", format); 4344 status = GdipDisposeImage(thumb); 4345 expect(Ok, status); 4346 } 4347 4348 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat32bppPARGB, &data); 4349 if (fmt[i] == PixelFormat16bppGrayScale || fmt[i] == PixelFormat32bppCMYK) 4350 todo_wine expect(InvalidParameter, status); 4351 else 4352 { 4353 expect(Ok, status); 4354 status = GdipBitmapUnlockBits(bitmap, &data); 4355 expect(Ok, status); 4356 } 4357 4358 status = GdipDisposeImage((GpImage *)bitmap); 4359 expect(Ok, status); 4360 } 4361 } 4362 4363 static void test_DrawImage_scale(void) 4364 { 4365 static const BYTE back_8x1[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40, 4366 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }; 4367 static const BYTE image_080[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40, 4368 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }; 4369 static const BYTE image_100[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40, 4370 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }; 4371 static const BYTE image_120[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x40, 4372 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }; 4373 static const BYTE image_150[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80, 4374 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }; 4375 static const BYTE image_180[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80, 4376 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }; 4377 static const BYTE image_200[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80, 4378 0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }; 4379 static const BYTE image_250[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80, 4380 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 }; 4381 static const BYTE image_120_half[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 4382 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }; 4383 static const BYTE image_150_half[24] = { 0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, 4384 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 }; 4385 static const BYTE image_200_half[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80, 4386 0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x40,0x40,0x40 }; 4387 static const BYTE image_250_half[24] = { 0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80, 4388 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x40 }; 4389 static const struct test_data 4390 { 4391 REAL scale_x; 4392 PixelOffsetMode pixel_offset_mode; 4393 const BYTE *image; 4394 BOOL todo; 4395 } td[] = 4396 { 4397 { 0.8, PixelOffsetModeNone, image_080 }, /* 0 */ 4398 { 1.0, PixelOffsetModeNone, image_100 }, 4399 { 1.2, PixelOffsetModeNone, image_120 }, 4400 { 1.5, PixelOffsetModeNone, image_150 }, 4401 { 1.8, PixelOffsetModeNone, image_180 }, 4402 { 2.0, PixelOffsetModeNone, image_200 }, 4403 { 2.5, PixelOffsetModeNone, image_250 }, 4404 4405 { 0.8, PixelOffsetModeHighSpeed, image_080 }, /* 7 */ 4406 { 1.0, PixelOffsetModeHighSpeed, image_100 }, 4407 { 1.2, PixelOffsetModeHighSpeed, image_120 }, 4408 { 1.5, PixelOffsetModeHighSpeed, image_150 }, 4409 { 1.8, PixelOffsetModeHighSpeed, image_180 }, 4410 { 2.0, PixelOffsetModeHighSpeed, image_200 }, 4411 { 2.5, PixelOffsetModeHighSpeed, image_250 }, 4412 4413 { 0.8, PixelOffsetModeHalf, image_080 }, /* 14 */ 4414 { 1.0, PixelOffsetModeHalf, image_100 }, 4415 { 1.2, PixelOffsetModeHalf, image_120_half, TRUE }, 4416 { 1.5, PixelOffsetModeHalf, image_150_half, TRUE }, 4417 { 1.8, PixelOffsetModeHalf, image_180 }, 4418 { 2.0, PixelOffsetModeHalf, image_200_half, TRUE }, 4419 { 2.5, PixelOffsetModeHalf, image_250_half, TRUE }, 4420 4421 { 0.8, PixelOffsetModeHighQuality, image_080 }, /* 21 */ 4422 { 1.0, PixelOffsetModeHighQuality, image_100 }, 4423 { 1.2, PixelOffsetModeHighQuality, image_120_half, TRUE }, 4424 { 1.5, PixelOffsetModeHighQuality, image_150_half, TRUE }, 4425 { 1.8, PixelOffsetModeHighQuality, image_180 }, 4426 { 2.0, PixelOffsetModeHighQuality, image_200_half, TRUE }, 4427 { 2.5, PixelOffsetModeHighQuality, image_250_half, TRUE }, 4428 }; 4429 BYTE src_2x1[6] = { 0x80,0x80,0x80,0x80,0x80,0x80 }; 4430 BYTE dst_8x1[24]; 4431 GpStatus status; 4432 union 4433 { 4434 GpBitmap *bitmap; 4435 GpImage *image; 4436 } u1, u2; 4437 GpGraphics *graphics; 4438 GpMatrix *matrix; 4439 int i, match; 4440 4441 status = GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB, src_2x1, &u1.bitmap); 4442 expect(Ok, status); 4443 status = GdipBitmapSetResolution(u1.bitmap, 100.0, 100.0); 4444 expect(Ok, status); 4445 4446 status = GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB, dst_8x1, &u2.bitmap); 4447 expect(Ok, status); 4448 status = GdipBitmapSetResolution(u2.bitmap, 100.0, 100.0); 4449 expect(Ok, status); 4450 status = GdipGetImageGraphicsContext(u2.image, &graphics); 4451 expect(Ok, status); 4452 status = GdipSetInterpolationMode(graphics, InterpolationModeNearestNeighbor); 4453 expect(Ok, status); 4454 4455 for (i = 0; i < ARRAY_SIZE(td); i++) 4456 { 4457 status = GdipSetPixelOffsetMode(graphics, td[i].pixel_offset_mode); 4458 expect(Ok, status); 4459 4460 status = GdipCreateMatrix2(td[i].scale_x, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix); 4461 expect(Ok, status); 4462 status = GdipSetWorldTransform(graphics, matrix); 4463 expect(Ok, status); 4464 GdipDeleteMatrix(matrix); 4465 4466 memcpy(dst_8x1, back_8x1, sizeof(dst_8x1)); 4467 status = GdipDrawImageI(graphics, u1.image, 1, 0); 4468 expect(Ok, status); 4469 4470 match = memcmp(dst_8x1, td[i].image, sizeof(dst_8x1)) == 0; 4471 todo_wine_if (!match && td[i].todo) 4472 ok(match, "%d: data should match\n", i); 4473 if (!match) 4474 { 4475 UINT i, size = sizeof(dst_8x1); 4476 const BYTE *bits = dst_8x1; 4477 for (i = 0; i < size; i++) 4478 trace(" %02x", bits[i]); 4479 trace("\n"); 4480 } 4481 } 4482 4483 status = GdipDeleteGraphics(graphics); 4484 expect(Ok, status); 4485 status = GdipDisposeImage(u1.image); 4486 expect(Ok, status); 4487 status = GdipDisposeImage(u2.image); 4488 expect(Ok, status); 4489 } 4490 4491 static const BYTE animatedgif[] = { 4492 'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00, 4493 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c, 4494 /*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/ 4495 0x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0', 4496 0x03,0x01,0x05,0x00,0x00, 4497 0x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00, 4498 0x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00, 4499 0x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00, 4500 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81, 4501 0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac, 4502 0x02,0x02,0x4C,0x01,0x00, 4503 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00, 4504 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00, 4505 0x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00, 4506 0x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81, 4507 0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc, 4508 0x02,0x02,0x44,0x01,0x00, 4509 0x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00, 4510 0x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B 4511 }; 4512 4513 static void test_gif_properties(void) 4514 { 4515 static const struct test_data 4516 { 4517 ULONG type, id, length; 4518 const BYTE value[13]; 4519 } td[] = 4520 { 4521 { PropertyTagTypeLong, PropertyTagFrameDelay, 8, { 10,0,0,0,20,0,0,0 } }, 4522 { PropertyTagTypeASCII, PropertyTagExifUserComment, 13, { 'H','e','l','l','o',' ','W','o','r','l','d','!',0 } }, 4523 { PropertyTagTypeShort, PropertyTagLoopCount, 2, { 5,0 } }, 4524 { PropertyTagTypeByte, PropertyTagGlobalPalette, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } }, 4525 { PropertyTagTypeByte, PropertyTagIndexBackground, 1, { 2 } }, 4526 { PropertyTagTypeByte, PropertyTagIndexTransparent, 1, { 8 } } 4527 }; 4528 GpStatus status; 4529 GpImage *image; 4530 GUID guid; 4531 UINT dim_count, frame_count, prop_count, prop_size, i; 4532 UINT total_size, total_count; 4533 PROPID *prop_id; 4534 PropertyItem *prop_item; 4535 const char *item_data; 4536 4537 image = load_image(animatedgif, sizeof(animatedgif)); 4538 if (!image) /* XP fails to load this GIF image */ 4539 { 4540 trace("Failed to load GIF image data\n"); 4541 return; 4542 } 4543 4544 status = GdipImageGetFrameDimensionsCount(image, &dim_count); 4545 expect(Ok, status); 4546 expect(1, dim_count); 4547 4548 status = GdipImageGetFrameDimensionsList(image, &guid, 1); 4549 expect(Ok, status); 4550 expect_guid(&FrameDimensionTime, &guid, __LINE__, FALSE); 4551 4552 status = GdipImageGetFrameCount(image, &guid, &frame_count); 4553 expect(Ok, status); 4554 expect(2, frame_count); 4555 4556 status = GdipImageSelectActiveFrame(image, &guid, 1); 4557 expect(Ok, status); 4558 4559 status = GdipGetPropertyCount(image, &prop_count); 4560 expect(Ok, status); 4561 ok(prop_count == ARRAY_SIZE(td) || broken(prop_count == 1) /* before win7 */, 4562 "expected property count %u, got %u\n", (UINT) ARRAY_SIZE(td), prop_count); 4563 4564 if (prop_count != ARRAY_SIZE(td)) 4565 { 4566 GdipDisposeImage(image); 4567 return; 4568 } 4569 4570 prop_id = HeapAlloc(GetProcessHeap(), 0, prop_count * sizeof(*prop_id)); 4571 4572 status = GdipGetPropertyIdList(image, prop_count, prop_id); 4573 expect(Ok, status); 4574 4575 prop_size = 0; 4576 for (i = 0; i < prop_count; i++) 4577 { 4578 UINT size; 4579 status = GdipGetPropertyItemSize(image, prop_id[i], &size); 4580 expect(Ok, status); 4581 if (status != Ok) break; 4582 ok(size > sizeof(*prop_item), "%u: too small item length %u\n", i, size); 4583 4584 prop_size += size; 4585 4586 prop_item = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); 4587 status = GdipGetPropertyItem(image, prop_id[i], size, prop_item); 4588 expect(Ok, status); 4589 ok(prop_item->value == prop_item + 1, "expected item->value %p, got %p\n", prop_item + 1, prop_item->value); 4590 ok(td[i].type == prop_item->type, 4591 "%u: expected type %u, got %u\n", i, td[i].type, prop_item->type); 4592 ok(td[i].id == prop_item->id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item->id); 4593 size -= sizeof(*prop_item); 4594 ok(prop_item->length == size, "%u: expected length %u, got %u\n", i, size, prop_item->length); 4595 ok(td[i].length == prop_item->length, "%u: expected length %u, got %u\n", i, td[i].length, prop_item->length); 4596 if (td[i].length == prop_item->length) 4597 { 4598 int match = memcmp(td[i].value, prop_item->value, td[i].length) == 0; 4599 ok(match, "%u: data mismatch\n", i); 4600 if (!match) 4601 { 4602 UINT j; 4603 BYTE *data = prop_item->value; 4604 trace("id %#x:", prop_item->id); 4605 for (j = 0; j < prop_item->length; j++) 4606 trace(" %02x", data[j]); 4607 trace("\n"); 4608 } 4609 } 4610 HeapFree(GetProcessHeap(), 0, prop_item); 4611 } 4612 4613 HeapFree(GetProcessHeap(), 0, prop_id); 4614 4615 status = GdipGetPropertySize(NULL, &total_size, &total_count); 4616 expect(InvalidParameter, status); 4617 status = GdipGetPropertySize(image, &total_size, NULL); 4618 expect(InvalidParameter, status); 4619 status = GdipGetPropertySize(image, NULL, &total_count); 4620 expect(InvalidParameter, status); 4621 status = GdipGetPropertySize(image, NULL, NULL); 4622 expect(InvalidParameter, status); 4623 total_size = 0xdeadbeef; 4624 total_count = 0xdeadbeef; 4625 status = GdipGetPropertySize(image, &total_size, &total_count); 4626 expect(Ok, status); 4627 ok(prop_count == total_count, 4628 "expected total property count %u, got %u\n", prop_count, total_count); 4629 ok(prop_size == total_size, 4630 "expected total property size %u, got %u\n", prop_size, total_size); 4631 4632 prop_item = HeapAlloc(GetProcessHeap(), 0, prop_size); 4633 4634 status = GdipGetAllPropertyItems(image, 0, prop_count, prop_item); 4635 expect(InvalidParameter, status); 4636 status = GdipGetAllPropertyItems(image, prop_size, 1, prop_item); 4637 expect(InvalidParameter, status); 4638 status = GdipGetAllPropertyItems(image, prop_size, prop_count, NULL); 4639 expect(InvalidParameter, status); 4640 status = GdipGetAllPropertyItems(image, prop_size, prop_count, NULL); 4641 expect(InvalidParameter, status); 4642 status = GdipGetAllPropertyItems(image, 0, 0, NULL); 4643 expect(InvalidParameter, status); 4644 status = GdipGetAllPropertyItems(image, prop_size + 1, prop_count, prop_item); 4645 expect(InvalidParameter, status); 4646 status = GdipGetAllPropertyItems(image, prop_size, prop_count, prop_item); 4647 expect(Ok, status); 4648 4649 item_data = (const char *)(prop_item + prop_count); 4650 for (i = 0; i < prop_count; i++) 4651 { 4652 ok(prop_item[i].value == item_data, "%u: expected value %p, got %p\n", 4653 i, item_data, prop_item[i].value); 4654 ok(td[i].type == prop_item[i].type, 4655 "%u: expected type %u, got %u\n", i, td[i].type, prop_item[i].type); 4656 ok(td[i].id == prop_item[i].id, "%u: expected id %#x, got %#x\n", i, td[i].id, prop_item[i].id); 4657 ok(td[i].length == prop_item[i].length, "%u: expected length %u, got %u\n", i, td[i].length, prop_item[i].length); 4658 if (td[i].length == prop_item[i].length) 4659 { 4660 int match = memcmp(td[i].value, prop_item[i].value, td[i].length) == 0; 4661 ok(match, "%u: data mismatch\n", i); 4662 if (!match) 4663 { 4664 UINT j; 4665 BYTE *data = prop_item[i].value; 4666 trace("id %#x:", prop_item[i].id); 4667 for (j = 0; j < prop_item[i].length; j++) 4668 trace(" %02x", data[j]); 4669 trace("\n"); 4670 } 4671 } 4672 item_data += prop_item[i].length; 4673 } 4674 4675 HeapFree(GetProcessHeap(), 0, prop_item); 4676 4677 GdipDisposeImage(image); 4678 } 4679 4680 static void test_ARGB_conversion(void) 4681 { 4682 BYTE argb[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 }; 4683 BYTE pargb[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 }; 4684 BYTE rgb32_xp[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff }; 4685 BYTE rgb24[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff }; 4686 BYTE *bits; 4687 GpBitmap *bitmap; 4688 BitmapData data; 4689 GpStatus status; 4690 int match; 4691 4692 status = GdipCreateBitmapFromScan0(2, 1, 8, PixelFormat32bppARGB, argb, &bitmap); 4693 expect(Ok, status); 4694 4695 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat32bppPARGB, &data); 4696 expect(Ok, status); 4697 ok(data.Width == 2, "expected 2, got %d\n", data.Width); 4698 ok(data.Height == 1, "expected 1, got %d\n", data.Height); 4699 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride); 4700 ok(data.PixelFormat == PixelFormat32bppPARGB, "expected PixelFormat32bppPARGB, got %d\n", data.PixelFormat); 4701 match = !memcmp(data.Scan0, pargb, sizeof(pargb)); 4702 ok(match, "bits don't match\n"); 4703 if (!match) 4704 { 4705 bits = data.Scan0; 4706 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB, 4707 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]); 4708 } 4709 status = GdipBitmapUnlockBits(bitmap, &data); 4710 expect(Ok, status); 4711 4712 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat32bppRGB, &data); 4713 expect(Ok, status); 4714 ok(data.Width == 2, "expected 2, got %d\n", data.Width); 4715 ok(data.Height == 1, "expected 1, got %d\n", data.Height); 4716 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride); 4717 ok(data.PixelFormat == PixelFormat32bppRGB, "expected PixelFormat32bppRGB, got %d\n", data.PixelFormat); 4718 match = !memcmp(data.Scan0, argb, sizeof(argb)) || 4719 !memcmp(data.Scan0, rgb32_xp, sizeof(rgb32_xp)); 4720 ok(match, "bits don't match\n"); 4721 if (!match) 4722 { 4723 bits = data.Scan0; 4724 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB, 4725 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]); 4726 } 4727 status = GdipBitmapUnlockBits(bitmap, &data); 4728 expect(Ok, status); 4729 4730 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat24bppRGB, &data); 4731 expect(Ok, status); 4732 ok(data.Width == 2, "expected 2, got %d\n", data.Width); 4733 ok(data.Height == 1, "expected 1, got %d\n", data.Height); 4734 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride); 4735 ok(data.PixelFormat == PixelFormat24bppRGB, "expected PixelFormat24bppRGB, got %d\n", data.PixelFormat); 4736 match = !memcmp(data.Scan0, rgb24, sizeof(rgb24)); 4737 ok(match, "bits don't match\n"); 4738 if (!match) 4739 { 4740 bits = data.Scan0; 4741 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB, 4742 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]); 4743 } 4744 status = GdipBitmapUnlockBits(bitmap, &data); 4745 expect(Ok, status); 4746 4747 GdipDisposeImage((GpImage *)bitmap); 4748 } 4749 4750 4751 static void test_CloneBitmapArea(void) 4752 { 4753 GpStatus status; 4754 GpBitmap *bitmap, *copy; 4755 BitmapData data, data2; 4756 4757 status = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB, NULL, &bitmap); 4758 expect(Ok, status); 4759 4760 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead | ImageLockModeWrite, PixelFormat24bppRGB, &data); 4761 expect(Ok, status); 4762 4763 status = GdipBitmapLockBits(bitmap, NULL, ImageLockModeRead, PixelFormat24bppRGB, &data2); 4764 expect(WrongState, status); 4765 4766 status = GdipCloneBitmapAreaI(0, 0, 1, 1, PixelFormat24bppRGB, bitmap, ©); 4767 expect(Ok, status); 4768 4769 status = GdipBitmapUnlockBits(bitmap, &data); 4770 expect(Ok, status); 4771 4772 GdipDisposeImage((GpImage *)copy); 4773 GdipDisposeImage((GpImage *)bitmap); 4774 } 4775 4776 static BOOL get_encoder_clsid(LPCWSTR mime, GUID *format, CLSID *clsid) 4777 { 4778 GpStatus status; 4779 UINT n_codecs, info_size, i; 4780 ImageCodecInfo *info; 4781 BOOL ret = FALSE; 4782 4783 status = GdipGetImageEncodersSize(&n_codecs, &info_size); 4784 expect(Ok, status); 4785 4786 info = GdipAlloc(info_size); 4787 4788 status = GdipGetImageEncoders(n_codecs, info_size, info); 4789 expect(Ok, status); 4790 4791 for (i = 0; i < n_codecs; i++) 4792 { 4793 if (!lstrcmpW(info[i].MimeType, mime)) 4794 { 4795 *format = info[i].FormatID; 4796 *clsid = info[i].Clsid; 4797 ret = TRUE; 4798 break; 4799 } 4800 } 4801 4802 GdipFree(info); 4803 return ret; 4804 } 4805 4806 static void test_supported_encoders(void) 4807 { 4808 static const WCHAR bmp_mimetype[] = { 'i', 'm', 'a','g', 'e', '/', 'b', 'm', 'p',0 }; 4809 static const WCHAR jpeg_mimetype[] = { 'i','m','a','g','e','/','j','p','e','g',0 }; 4810 static const WCHAR gif_mimetype[] = { 'i','m','a','g','e','/','g','i','f',0 }; 4811 static const WCHAR tiff_mimetype[] = { 'i','m','a','g','e','/','t','i','f','f',0 }; 4812 static const WCHAR png_mimetype[] = { 'i','m','a','g','e','/','p','n','g',0 }; 4813 static const struct test_data 4814 { 4815 LPCWSTR mime; 4816 const GUID *format; 4817 } td[] = 4818 { 4819 { bmp_mimetype, &ImageFormatBMP }, 4820 { jpeg_mimetype, &ImageFormatJPEG }, 4821 { gif_mimetype, &ImageFormatGIF }, 4822 { tiff_mimetype, &ImageFormatTIFF }, 4823 { png_mimetype, &ImageFormatPNG } 4824 }; 4825 GUID format, clsid; 4826 BOOL ret; 4827 HRESULT hr; 4828 GpStatus status; 4829 GpBitmap *bm; 4830 IStream *stream; 4831 HGLOBAL hmem; 4832 int i; 4833 4834 status = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat24bppRGB, NULL, &bm); 4835 ok(status == Ok, "GdipCreateBitmapFromScan0 error %d\n", status); 4836 4837 for (i = 0; i < ARRAY_SIZE(td); i++) 4838 { 4839 ret = get_encoder_clsid(td[i].mime, &format, &clsid); 4840 ok(ret, "%s encoder is not in the list\n", wine_dbgstr_w(td[i].mime)); 4841 expect_guid(td[i].format, &format, __LINE__, FALSE); 4842 4843 hmem = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, 16); 4844 4845 hr = CreateStreamOnHGlobal(hmem, TRUE, &stream); 4846 ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr); 4847 4848 status = GdipSaveImageToStream((GpImage *)bm, stream, &clsid, NULL); 4849 ok(status == Ok, "GdipSaveImageToStream error %d\n", status); 4850 4851 IStream_Release(stream); 4852 } 4853 4854 GdipDisposeImage((GpImage *)bm); 4855 } 4856 4857 static void test_createeffect(void) 4858 { 4859 static const GUID noneffect = { 0xcd0c3d4b, 0xe15e, 0x4cf2, { 0x9e, 0xa8, 0x6e, 0x1d, 0x65, 0x48, 0xc5, 0xa5 } }; 4860 GpStatus (WINAPI *pGdipCreateEffect)( const GUID guid, CGpEffect **effect); 4861 GpStatus (WINAPI *pGdipDeleteEffect)( CGpEffect *effect); 4862 GpStatus stat; 4863 CGpEffect *effect; 4864 HMODULE mod = GetModuleHandleA("gdiplus.dll"); 4865 int i; 4866 const GUID * const effectlist[] = 4867 {&BlurEffectGuid, &SharpenEffectGuid, &ColorMatrixEffectGuid, &ColorLUTEffectGuid, 4868 &BrightnessContrastEffectGuid, &HueSaturationLightnessEffectGuid, &LevelsEffectGuid, 4869 &TintEffectGuid, &ColorBalanceEffectGuid, &RedEyeCorrectionEffectGuid, &ColorCurveEffectGuid}; 4870 4871 pGdipCreateEffect = (void*)GetProcAddress( mod, "GdipCreateEffect"); 4872 pGdipDeleteEffect = (void*)GetProcAddress( mod, "GdipDeleteEffect"); 4873 if(!pGdipCreateEffect || !pGdipDeleteEffect) 4874 { 4875 /* GdipCreateEffect/GdipDeleteEffect was introduced in Windows Vista. */ 4876 win_skip("GDIPlus version 1.1 not available\n"); 4877 return; 4878 } 4879 4880 stat = pGdipCreateEffect(BlurEffectGuid, NULL); 4881 expect(InvalidParameter, stat); 4882 4883 stat = pGdipCreateEffect(noneffect, &effect); 4884 todo_wine expect(Win32Error, stat); 4885 4886 for(i=0; i < ARRAY_SIZE(effectlist); i++) 4887 { 4888 stat = pGdipCreateEffect(*effectlist[i], &effect); 4889 todo_wine expect(Ok, stat); 4890 if(stat == Ok) 4891 { 4892 stat = pGdipDeleteEffect(effect); 4893 expect(Ok, stat); 4894 } 4895 } 4896 } 4897 4898 static void test_getadjustedpalette(void) 4899 { 4900 ColorMap colormap; 4901 GpImageAttributes *imageattributes; 4902 ColorPalette *palette; 4903 GpStatus stat; 4904 4905 stat = GdipCreateImageAttributes(&imageattributes); 4906 expect(Ok, stat); 4907 4908 colormap.oldColor.Argb = 0xffffff00; 4909 colormap.newColor.Argb = 0xffff00ff; 4910 stat = GdipSetImageAttributesRemapTable(imageattributes, ColorAdjustTypeBitmap, 4911 TRUE, 1, &colormap); 4912 expect(Ok, stat); 4913 4914 colormap.oldColor.Argb = 0xffffff80; 4915 colormap.newColor.Argb = 0xffff80ff; 4916 stat = GdipSetImageAttributesRemapTable(imageattributes, ColorAdjustTypeDefault, 4917 TRUE, 1, &colormap); 4918 expect(Ok, stat); 4919 4920 palette = GdipAlloc(sizeof(*palette) + sizeof(ARGB) * 2); 4921 palette->Count = 0; 4922 4923 stat = GdipGetImageAttributesAdjustedPalette(imageattributes, palette, ColorAdjustTypeBitmap); 4924 expect(InvalidParameter, stat); 4925 4926 palette->Count = 3; 4927 palette->Entries[0] = 0xffffff00; 4928 palette->Entries[1] = 0xffffff80; 4929 palette->Entries[2] = 0xffffffff; 4930 4931 stat = GdipGetImageAttributesAdjustedPalette(imageattributes, palette, ColorAdjustTypeBitmap); 4932 expect(Ok, stat); 4933 expect(0xffff00ff, palette->Entries[0]); 4934 expect(0xffffff80, palette->Entries[1]); 4935 expect(0xffffffff, palette->Entries[2]); 4936 4937 palette->Entries[0] = 0xffffff00; 4938 palette->Entries[1] = 0xffffff80; 4939 palette->Entries[2] = 0xffffffff; 4940 4941 stat = GdipGetImageAttributesAdjustedPalette(imageattributes, palette, ColorAdjustTypeBrush); 4942 expect(Ok, stat); 4943 expect(0xffffff00, palette->Entries[0]); 4944 expect(0xffff80ff, palette->Entries[1]); 4945 expect(0xffffffff, palette->Entries[2]); 4946 4947 stat = GdipGetImageAttributesAdjustedPalette(NULL, palette, ColorAdjustTypeBitmap); 4948 expect(InvalidParameter, stat); 4949 4950 stat = GdipGetImageAttributesAdjustedPalette(imageattributes, NULL, ColorAdjustTypeBitmap); 4951 expect(InvalidParameter, stat); 4952 4953 stat = GdipGetImageAttributesAdjustedPalette(imageattributes, palette, -1); 4954 expect(InvalidParameter, stat); 4955 4956 stat = GdipGetImageAttributesAdjustedPalette(imageattributes, palette, ColorAdjustTypeDefault); 4957 expect(InvalidParameter, stat); 4958 4959 GdipFree(palette); 4960 GdipDisposeImageAttributes(imageattributes); 4961 } 4962 4963 static void test_histogram(void) 4964 { 4965 UINT ch0[256], ch1[256], ch2[256], ch3[256]; 4966 HistogramFormat test_formats[] = 4967 { 4968 HistogramFormatARGB, 4969 HistogramFormatPARGB, 4970 HistogramFormatRGB, 4971 HistogramFormatGray, 4972 HistogramFormatB, 4973 HistogramFormatG, 4974 HistogramFormatR, 4975 HistogramFormatA, 4976 }; 4977 const UINT WIDTH = 8, HEIGHT = 16; 4978 UINT num, i, x; 4979 GpStatus stat; 4980 GpBitmap *bm; 4981 4982 if (!pGdipBitmapGetHistogramSize) 4983 { 4984 win_skip("GdipBitmapGetHistogramSize is not supported\n"); 4985 return; 4986 } 4987 4988 stat = pGdipBitmapGetHistogramSize(HistogramFormatARGB, NULL); 4989 expect(InvalidParameter, stat); 4990 4991 stat = pGdipBitmapGetHistogramSize(0xff, NULL); 4992 expect(InvalidParameter, stat); 4993 4994 num = 123; 4995 stat = pGdipBitmapGetHistogramSize(10, &num); 4996 expect(Ok, stat); 4997 expect(256, num); 4998 4999 for (i = 0; i < ARRAY_SIZE(test_formats); i++) 5000 { 5001 num = 0; 5002 stat = pGdipBitmapGetHistogramSize(test_formats[i], &num); 5003 expect(Ok, stat); 5004 expect(256, num); 5005 } 5006 5007 bm = NULL; 5008 stat = GdipCreateBitmapFromScan0(WIDTH, HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm); 5009 expect(Ok, stat); 5010 5011 /* Three solid rgb rows, next three rows are rgb shades. */ 5012 for (x = 0; x < WIDTH; x++) 5013 { 5014 GdipBitmapSetPixel(bm, x, 0, 0xffff0000); 5015 GdipBitmapSetPixel(bm, x, 1, 0xff00ff00); 5016 GdipBitmapSetPixel(bm, x, 2, 0xff0000ff); 5017 5018 GdipBitmapSetPixel(bm, x, 3, 0xff010000); 5019 GdipBitmapSetPixel(bm, x, 4, 0xff003f00); 5020 GdipBitmapSetPixel(bm, x, 5, 0xff000020); 5021 } 5022 5023 stat = pGdipBitmapGetHistogram(NULL, HistogramFormatRGB, 256, ch0, ch1, ch2, ch3); 5024 expect(InvalidParameter, stat); 5025 5026 stat = pGdipBitmapGetHistogram(bm, 123, 256, ch0, ch1, ch2, ch3); 5027 expect(InvalidParameter, stat); 5028 5029 stat = pGdipBitmapGetHistogram(bm, 123, 256, ch0, ch1, ch2, NULL); 5030 expect(InvalidParameter, stat); 5031 5032 stat = pGdipBitmapGetHistogram(bm, 123, 256, ch0, ch1, NULL, NULL); 5033 expect(InvalidParameter, stat); 5034 5035 stat = pGdipBitmapGetHistogram(bm, 123, 256, ch0, NULL, NULL, NULL); 5036 expect(InvalidParameter, stat); 5037 5038 /* Requested format matches bitmap format */ 5039 stat = pGdipBitmapGetHistogram(bm, HistogramFormatRGB, 256, ch0, ch1, ch2, ch3); 5040 expect(InvalidParameter, stat); 5041 5042 stat = pGdipBitmapGetHistogram(bm, HistogramFormatRGB, 100, ch0, ch1, ch2, NULL); 5043 expect(InvalidParameter, stat); 5044 5045 stat = pGdipBitmapGetHistogram(bm, HistogramFormatRGB, 257, ch0, ch1, ch2, NULL); 5046 expect(InvalidParameter, stat); 5047 5048 /* Channel 3 is not used, must be NULL */ 5049 stat = pGdipBitmapGetHistogram(bm, HistogramFormatRGB, 256, ch0, ch1, ch2, NULL); 5050 expect(Ok, stat); 5051 5052 ok(ch0[0xff] == WIDTH, "Got red (0xff) %u\n", ch0[0xff]); 5053 ok(ch1[0xff] == WIDTH, "Got green (0xff) %u\n", ch1[0xff]); 5054 ok(ch2[0xff] == WIDTH, "Got blue (0xff) %u\n", ch1[0xff]); 5055 ok(ch0[0x01] == WIDTH, "Got red (0x01) %u\n", ch0[0x01]); 5056 ok(ch1[0x3f] == WIDTH, "Got green (0x3f) %u\n", ch1[0x3f]); 5057 ok(ch2[0x20] == WIDTH, "Got blue (0x20) %u\n", ch1[0x20]); 5058 5059 /* ARGB histogram from RGB data. */ 5060 stat = pGdipBitmapGetHistogram(bm, HistogramFormatARGB, 256, ch0, ch1, ch2, NULL); 5061 expect(InvalidParameter, stat); 5062 5063 stat = pGdipBitmapGetHistogram(bm, HistogramFormatARGB, 256, ch0, ch1, ch2, ch3); 5064 expect(Ok, stat); 5065 5066 ok(ch1[0xff] == WIDTH, "Got red (0xff) %u\n", ch1[0xff]); 5067 ok(ch2[0xff] == WIDTH, "Got green (0xff) %u\n", ch2[0xff]); 5068 ok(ch3[0xff] == WIDTH, "Got blue (0xff) %u\n", ch3[0xff]); 5069 ok(ch1[0x01] == WIDTH, "Got red (0x01) %u\n", ch1[0x01]); 5070 ok(ch2[0x3f] == WIDTH, "Got green (0x3f) %u\n", ch2[0x3f]); 5071 ok(ch3[0x20] == WIDTH, "Got blue (0x20) %u\n", ch3[0x20]); 5072 5073 ok(ch0[0xff] == WIDTH * HEIGHT, "Got alpha (0xff) %u\n", ch0[0xff]); 5074 5075 /* Request grayscale histogram from RGB bitmap. */ 5076 stat = pGdipBitmapGetHistogram(bm, HistogramFormatGray, 256, ch0, ch1, ch2, ch3); 5077 expect(InvalidParameter, stat); 5078 5079 stat = pGdipBitmapGetHistogram(bm, HistogramFormatGray, 256, ch0, ch1, ch2, NULL); 5080 expect(InvalidParameter, stat); 5081 5082 stat = pGdipBitmapGetHistogram(bm, HistogramFormatGray, 256, ch0, ch1, NULL, NULL); 5083 expect(InvalidParameter, stat); 5084 5085 stat = pGdipBitmapGetHistogram(bm, HistogramFormatGray, 256, ch0, NULL, NULL, NULL); 5086 expect(Ok, stat); 5087 5088 GdipDisposeImage((GpImage*)bm); 5089 } 5090 5091 static void test_imageabort(void) 5092 { 5093 GpStatus stat; 5094 GpBitmap *bm; 5095 5096 if (!pGdipImageSetAbort) 5097 { 5098 win_skip("GdipImageSetAbort() is not supported.\n"); 5099 return; 5100 } 5101 5102 bm = NULL; 5103 stat = GdipCreateBitmapFromScan0(8, 8, 0, PixelFormat24bppRGB, NULL, &bm); 5104 expect(Ok, stat); 5105 5106 stat = pGdipImageSetAbort(NULL, NULL); 5107 expect(InvalidParameter, stat); 5108 5109 stat = pGdipImageSetAbort((GpImage*)bm, NULL); 5110 expect(Ok, stat); 5111 5112 GdipDisposeImage((GpImage*)bm); 5113 } 5114 5115 /* RGB 24 bpp 1x1 pixel PNG image */ 5116 static const char png_1x1_data[] = { 5117 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a, 5118 0x00,0x00,0x00,0x0d,'I','H','D','R',0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,0xde, 5119 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7, 5120 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82 5121 }; 5122 5123 static void test_png_color_formats(void) 5124 { 5125 static const struct 5126 { 5127 char bit_depth, color_type; 5128 PixelFormat format; 5129 UINT flags; 5130 } td[] = 5131 { 5132 /* 2 - PNG_COLOR_TYPE_RGB */ 5133 { 8, 2, PixelFormat24bppRGB, ImageFlagsColorSpaceRGB }, 5134 /* 0 - PNG_COLOR_TYPE_GRAY */ 5135 { 1, 0, PixelFormat1bppIndexed, ImageFlagsColorSpaceRGB }, 5136 { 2, 0, PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY }, 5137 { 4, 0, PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY }, 5138 { 8, 0, PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY }, 5139 { 16, 0, PixelFormat32bppARGB, ImageFlagsColorSpaceGRAY }, 5140 }; 5141 BYTE buf[sizeof(png_1x1_data)]; 5142 GpStatus status; 5143 GpImage *image; 5144 ImageType type; 5145 PixelFormat format; 5146 UINT flags; 5147 int i; 5148 5149 for (i = 0; i < ARRAY_SIZE(td); i++) 5150 { 5151 memcpy(buf, png_1x1_data, sizeof(png_1x1_data)); 5152 buf[24] = td[i].bit_depth; 5153 buf[25] = td[i].color_type; 5154 5155 image = load_image(buf, sizeof(buf)); 5156 ok(image != NULL, "%d: failed to load image data\n", i); 5157 if (!image) continue; 5158 5159 status = GdipGetImageType(image, &type); 5160 ok(status == Ok, "%u: GdipGetImageType error %d\n", i, status); 5161 ok(type == ImageTypeBitmap, "%d: wrong image type %d\n", i, type); 5162 5163 status = GdipGetImagePixelFormat(image, &format); 5164 expect(Ok, status); 5165 ok(format == td[i].format || 5166 broken(td[i].bit_depth == 1 && td[i].color_type == 0 && format == PixelFormat32bppARGB), /* XP */ 5167 "%d: expected %#x, got %#x\n", i, td[i].format, format); 5168 5169 status = GdipGetImageFlags(image, &flags); 5170 expect(Ok, status); 5171 ok((flags & td[i].flags) == td[i].flags || 5172 broken(td[i].bit_depth == 1 && td[i].color_type == 0 && (flags & ImageFlagsColorSpaceGRAY)), /* XP */ 5173 "%d: expected %#x, got %#x\n", i, td[i].flags, flags); 5174 5175 GdipDisposeImage(image); 5176 } 5177 } 5178 5179 static void test_GdipLoadImageFromStream(void) 5180 { 5181 IStream *stream; 5182 GpStatus status; 5183 GpImage *image; 5184 HGLOBAL hglob; 5185 BYTE *data; 5186 HRESULT hr; 5187 5188 status = GdipLoadImageFromStream(NULL, NULL); 5189 ok(status == InvalidParameter, "Unexpected return value %d.\n", status); 5190 5191 image = (void *)0xdeadbeef; 5192 status = GdipLoadImageFromStream(NULL, &image); 5193 ok(status == InvalidParameter, "Unexpected return value %d.\n", status); 5194 ok(image == (void *)0xdeadbeef, "Unexpected image pointer.\n"); 5195 5196 hglob = GlobalAlloc(0, sizeof(pngimage)); 5197 data = GlobalLock (hglob); 5198 memcpy(data, pngimage, sizeof(pngimage)); 5199 GlobalUnlock(hglob); 5200 5201 hr = CreateStreamOnHGlobal(hglob, TRUE, &stream); 5202 ok(hr == S_OK, "Failed to create a stream.\n"); 5203 5204 status = GdipLoadImageFromStream(stream, NULL); 5205 ok(status == InvalidParameter, "Unexpected return value %d.\n", status); 5206 5207 IStream_Release(stream); 5208 } 5209 5210 static BYTE *init_bitmap(UINT *width, UINT *height, UINT *stride) 5211 { 5212 BYTE *src; 5213 UINT i, j, scale; 5214 5215 *width = 256; 5216 *height = 256; 5217 *stride = (*width * 3 + 3) & ~3; 5218 trace("width %d, height %d, stride %d\n", *width, *height, *stride); 5219 5220 src = HeapAlloc(GetProcessHeap(), 0, *stride * *height); 5221 5222 scale = 256 / *width; 5223 if (!scale) scale = 1; 5224 5225 for (i = 0; i < *height; i++) 5226 { 5227 for (j = 0; j < *width; j++) 5228 { 5229 src[i * *stride + j*3 + 0] = scale * i; 5230 src[i * *stride + j*3 + 1] = scale * (255 - (i+j)/2); 5231 src[i * *stride + j*3 + 2] = scale * j; 5232 } 5233 } 5234 5235 return src; 5236 } 5237 5238 static void test_GdipInitializePalette(void) 5239 { 5240 GpStatus status; 5241 BYTE *data; 5242 GpBitmap *bitmap; 5243 ColorPalette *palette; 5244 UINT width, height, stride; 5245 5246 pGdipInitializePalette = (void *)GetProcAddress(GetModuleHandleA("gdiplus.dll"), "GdipInitializePalette"); 5247 if (!pGdipInitializePalette) 5248 { 5249 win_skip("GdipInitializePalette is not supported on this platform\n"); 5250 return; 5251 } 5252 5253 data = init_bitmap(&width, &height, &stride); 5254 5255 status = GdipCreateBitmapFromScan0(width, height, stride, PixelFormat24bppRGB, data, &bitmap); 5256 expect(Ok, status); 5257 5258 palette = GdipAlloc(sizeof(*palette) + sizeof(ARGB) * 255); 5259 5260 palette->Flags = 0; 5261 palette->Count = 15; 5262 status = pGdipInitializePalette(palette, PaletteTypeOptimal, 16, FALSE, bitmap); 5263 expect(GenericError, status); 5264 5265 palette->Flags = 0; 5266 palette->Count = 256; 5267 status = pGdipInitializePalette(palette, PaletteTypeOptimal, 16, FALSE, NULL); 5268 expect(InvalidParameter, status); 5269 5270 memset(palette->Entries, 0x11, sizeof(ARGB) * 256); 5271 palette->Flags = 0; 5272 palette->Count = 256; 5273 status = pGdipInitializePalette(palette, PaletteTypeCustom, 16, FALSE, NULL); 5274 expect(Ok, status); 5275 expect(0, palette->Flags); 5276 expect(256, palette->Count); 5277 expect(0x11111111, palette->Entries[0]); 5278 expect(0x11111111, palette->Entries[128]); 5279 expect(0x11111111, palette->Entries[255]); 5280 5281 memset(palette->Entries, 0x11, sizeof(ARGB) * 256); 5282 palette->Flags = 0; 5283 palette->Count = 256; 5284 status = pGdipInitializePalette(palette, PaletteTypeFixedBW, 0, FALSE, bitmap); 5285 expect(Ok, status); 5286 todo_wine 5287 expect(0x200, palette->Flags); 5288 expect(2, palette->Count); 5289 expect(0xff000000, palette->Entries[0]); 5290 expect(0xffffffff, palette->Entries[1]); 5291 5292 memset(palette->Entries, 0x11, sizeof(ARGB) * 256); 5293 palette->Flags = 0; 5294 palette->Count = 256; 5295 status = pGdipInitializePalette(palette, PaletteTypeFixedHalftone8, 1, FALSE, NULL); 5296 expect(Ok, status); 5297 todo_wine 5298 expect(0x300, palette->Flags); 5299 expect(16, palette->Count); 5300 expect(0xff000000, palette->Entries[0]); 5301 expect(0xffc0c0c0, palette->Entries[8]); 5302 expect(0xff008080, palette->Entries[15]); 5303 5304 memset(palette->Entries, 0x11, sizeof(ARGB) * 256); 5305 palette->Flags = 0; 5306 palette->Count = 256; 5307 status = pGdipInitializePalette(palette, PaletteTypeFixedHalftone8, 1, FALSE, bitmap); 5308 expect(Ok, status); 5309 todo_wine 5310 expect(0x300, palette->Flags); 5311 expect(16, palette->Count); 5312 expect(0xff000000, palette->Entries[0]); 5313 expect(0xffc0c0c0, palette->Entries[8]); 5314 expect(0xff008080, palette->Entries[15]); 5315 5316 memset(palette->Entries, 0x11, sizeof(ARGB) * 256); 5317 palette->Flags = 0; 5318 palette->Count = 256; 5319 status = pGdipInitializePalette(palette, PaletteTypeFixedHalftone252, 1, FALSE, bitmap); 5320 expect(Ok, status); 5321 todo_wine 5322 expect(0x800, palette->Flags); 5323 expect(252, palette->Count); 5324 expect(0xff000000, palette->Entries[0]); 5325 expect(0xff990066, palette->Entries[128]); 5326 expect(0xffffffff, palette->Entries[251]); 5327 5328 palette->Flags = 0; 5329 palette->Count = 256; 5330 status = pGdipInitializePalette(palette, PaletteTypeOptimal, 1, FALSE, bitmap); 5331 expect(InvalidParameter, status); 5332 5333 palette->Flags = 0; 5334 palette->Count = 256; 5335 status = pGdipInitializePalette(palette, PaletteTypeOptimal, 2, FALSE, bitmap); 5336 expect(Ok, status); 5337 expect(0, palette->Flags); 5338 expect(2, palette->Count); 5339 5340 palette->Flags = 0; 5341 palette->Count = 256; 5342 status = pGdipInitializePalette(palette, PaletteTypeOptimal, 16, FALSE, bitmap); 5343 expect(Ok, status); 5344 expect(0, palette->Flags); 5345 expect(16, palette->Count); 5346 5347 /* passing invalid enumeration palette type crashes under most Windows versions */ 5348 5349 GdipFree(palette); 5350 GdipDisposeImage((GpImage *)bitmap); 5351 } 5352 5353 #include "pshpack2.h" 5354 static const struct tiff_1x1_data 5355 { 5356 USHORT byte_order; 5357 USHORT version; 5358 ULONG dir_offset; 5359 USHORT number_of_entries; 5360 struct IFD_entry entry[12]; 5361 ULONG next_IFD; 5362 struct IFD_rational res; 5363 short palette_data[3][256]; 5364 short bps_data[4]; 5365 BYTE pixel_data[32]; 5366 } tiff_1x1_data = 5367 { 5368 #ifdef WORDS_BIGENDIAN 5369 'M' | 'M' << 8, 5370 #else 5371 'I' | 'I' << 8, 5372 #endif 5373 42, 5374 FIELD_OFFSET(struct tiff_1x1_data, number_of_entries), 5375 12, 5376 { 5377 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */ 5378 { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */ 5379 { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */ 5380 { 0x102, IFD_SHORT, 3, FIELD_OFFSET(struct tiff_1x1_data, bps_data) }, /* BITSPERSAMPLE */ 5381 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */ 5382 { 0x106, IFD_SHORT, 1, 2 }, /* PHOTOMETRIC */ 5383 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_1x1_data, pixel_data) }, /* STRIPOFFSETS */ 5384 { 0x115, IFD_SHORT, 1, 3 }, /* SAMPLESPERPIXEL */ 5385 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, 5386 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_1x1_data, res) }, 5387 { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */ 5388 { 0x140, IFD_SHORT, 256*3, FIELD_OFFSET(struct tiff_1x1_data, palette_data) } /* COLORMAP */ 5389 }, 5390 0, 5391 { 96, 1 }, 5392 { { 0 } }, 5393 { 8,8,8,0 }, 5394 { 1,0,2,3,4,5,6,7,8,9,0,1,2,3,4,5 } 5395 }; 5396 #include "poppack.h" 5397 5398 static void test_tiff_color_formats(void) 5399 { 5400 static const struct 5401 { 5402 int photometric; /* PhotometricInterpretation */ 5403 int samples; /* SamplesPerPixel */ 5404 int bps; /* BitsPerSample */ 5405 PixelFormat format; 5406 } td[] = 5407 { 5408 /* 2 - RGB */ 5409 { 2, 3, 1, PixelFormat24bppRGB }, 5410 { 2, 3, 4, PixelFormat24bppRGB }, 5411 { 2, 3, 8, PixelFormat24bppRGB }, 5412 { 2, 3, 16, PixelFormat48bppRGB }, 5413 { 2, 3, 24, 0 }, 5414 #if 0 /* FIXME */ 5415 { 2, 3, 32, 0 }, 5416 #endif 5417 { 2, 4, 1, PixelFormat32bppARGB }, 5418 { 2, 4, 4, PixelFormat32bppARGB }, 5419 { 2, 4, 8, PixelFormat32bppARGB }, 5420 { 2, 4, 16, PixelFormat48bppRGB }, 5421 { 2, 4, 24, 0 }, 5422 { 2, 4, 32, 0 }, 5423 /* 1 - BlackIsZero (Bilevel) */ 5424 { 1, 1, 1, PixelFormat1bppIndexed }, 5425 #if 0 /* FIXME: PNG vs TIFF mismatch */ 5426 { 1, 1, 4, PixelFormat8bppIndexed }, 5427 #endif 5428 { 1, 1, 8, PixelFormat8bppIndexed }, 5429 { 1, 1, 16, PixelFormat32bppARGB }, 5430 { 1, 1, 24, 0 }, 5431 { 1, 1, 32, PixelFormat32bppARGB }, 5432 /* 3 - Palette Color */ 5433 { 3, 1, 1, PixelFormat1bppIndexed }, 5434 { 3, 1, 4, PixelFormat4bppIndexed }, 5435 { 3, 1, 8, PixelFormat8bppIndexed }, 5436 #if 0 /* FIXME: for some reason libtiff replaces photometric 3 by 1 for bps > 8 */ 5437 { 3, 1, 16, 0 }, 5438 { 3, 1, 24, 0 }, 5439 { 3, 1, 32, 0 }, 5440 #endif 5441 /* 5 - Separated */ 5442 { 5, 4, 1, 0 }, 5443 { 5, 4, 4, 0 }, 5444 { 5, 4, 8, PixelFormat32bppCMYK }, 5445 { 5, 4, 16, PixelFormat48bppRGB }, 5446 { 5, 4, 24, 0 }, 5447 { 5, 4, 32, 0 }, 5448 }; 5449 BYTE buf[sizeof(tiff_1x1_data)]; 5450 GpStatus status; 5451 GpImage *image; 5452 UINT count, i; 5453 struct IFD_entry *tag, *tag_photo = NULL, *tag_bps = NULL, *tag_samples = NULL, *tag_colormap = NULL; 5454 short *bps; 5455 ImageType type; 5456 PixelFormat format; 5457 5458 memcpy(buf, &tiff_1x1_data, sizeof(tiff_1x1_data)); 5459 5460 count = *(short *)(buf + tiff_1x1_data.dir_offset); 5461 tag = (struct IFD_entry *)(buf + tiff_1x1_data.dir_offset + sizeof(short)); 5462 5463 /* verify the TIFF structure */ 5464 for (i = 0; i < count; i++) 5465 { 5466 if (tag[i].id == 0x102) /* BitsPerSample */ 5467 tag_bps = &tag[i]; 5468 else if (tag[i].id == 0x106) /* PhotometricInterpretation */ 5469 tag_photo = &tag[i]; 5470 else if (tag[i].id == 0x115) /* SamplesPerPixel */ 5471 tag_samples = &tag[i]; 5472 else if (tag[i].id == 0x140) /* ColorMap */ 5473 tag_colormap = &tag[i]; 5474 } 5475 5476 ok(tag_bps && tag_photo && tag_samples && tag_colormap, "tag 0x102,0x106,0x115 or 0x140 is missing\n"); 5477 if (!tag_bps || !tag_photo || !tag_samples || !tag_colormap) return; 5478 5479 ok(tag_bps->type == IFD_SHORT, "tag 0x102 should have type IFD_SHORT\n"); 5480 bps = (short *)(buf + tag_bps->value); 5481 ok(bps[0] == 8 && bps[1] == 8 && bps[2] == 8 && bps[3] == 0, 5482 "expected bps 8,8,8,0 got %d,%d,%d,%d\n", bps[0], bps[1], bps[2], bps[3]); 5483 5484 for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) 5485 { 5486 tag_colormap->count = (1 << td[i].bps) * 3; 5487 tag_photo->value = td[i].photometric; 5488 tag_bps->count = td[i].samples; 5489 tag_samples->value = td[i].samples; 5490 5491 if (td[i].samples == 1) 5492 tag_bps->value = td[i].bps; 5493 else if (td[i].samples == 2) 5494 tag_bps->value = MAKELONG(td[i].bps, td[i].bps); 5495 else if (td[i].samples == 3) 5496 { 5497 tag_bps->value = (BYTE *)bps - buf; 5498 bps[0] = bps[1] = bps[2] = td[i].bps; 5499 } 5500 else if (td[i].samples == 4) 5501 { 5502 tag_bps->value = (BYTE *)bps - buf; 5503 bps[0] = bps[1] = bps[2] = bps[3] = td[i].bps; 5504 } 5505 else 5506 { 5507 ok(0, "%u: unsupported samples count %d\n", i, td[i].samples); 5508 continue; 5509 } 5510 5511 image = load_image(buf, sizeof(buf)); 5512 if (!td[i].format) 5513 ok(!image, 5514 "%u: (%d,%d,%d) TIFF image loading should have failed\n", i, td[i].photometric, td[i].samples, td[i].bps); 5515 else 5516 ok(image != NULL || broken(!image) /* XP */, "%u: failed to load TIFF image data (%d,%d,%d)\n", 5517 i, td[i].photometric, td[i].samples, td[i].bps); 5518 if (!image) continue; 5519 5520 status = GdipGetImageType(image, &type); 5521 ok(status == Ok, "%u: GdipGetImageType error %d\n", i, status); 5522 ok(type == ImageTypeBitmap, "%u: wrong image type %d\n", i, type); 5523 5524 status = GdipGetImagePixelFormat(image, &format); 5525 expect(Ok, status); 5526 ok(format == td[i].format, 5527 "%u: expected %#x, got %#x\n", i, td[i].format, format); 5528 5529 GdipDisposeImage(image); 5530 } 5531 } 5532 5533 START_TEST(image) 5534 { 5535 HMODULE mod = GetModuleHandleA("gdiplus.dll"); 5536 struct GdiplusStartupInput gdiplusStartupInput; 5537 ULONG_PTR gdiplusToken; 5538 HMODULE hmsvcrt; 5539 int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask); 5540 5541 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */ 5542 hmsvcrt = LoadLibraryA("msvcrt"); 5543 _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s"); 5544 if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e); 5545 5546 gdiplusStartupInput.GdiplusVersion = 1; 5547 gdiplusStartupInput.DebugEventCallback = NULL; 5548 gdiplusStartupInput.SuppressBackgroundThread = 0; 5549 gdiplusStartupInput.SuppressExternalCodecs = 0; 5550 5551 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); 5552 5553 pGdipBitmapGetHistogramSize = (void*)GetProcAddress(mod, "GdipBitmapGetHistogramSize"); 5554 pGdipBitmapGetHistogram = (void*)GetProcAddress(mod, "GdipBitmapGetHistogram"); 5555 pGdipImageSetAbort = (void*)GetProcAddress(mod, "GdipImageSetAbort"); 5556 5557 test_tiff_color_formats(); 5558 test_GdipInitializePalette(); 5559 test_png_color_formats(); 5560 test_supported_encoders(); 5561 test_CloneBitmapArea(); 5562 test_ARGB_conversion(); 5563 test_DrawImage_scale(); 5564 test_image_format(); 5565 test_DrawImage(); 5566 test_DrawImage_SourceCopy(); 5567 test_GdipDrawImagePointRect(); 5568 test_bitmapbits(); 5569 test_tiff_palette(); 5570 test_GdipGetAllPropertyItems(); 5571 test_tiff_properties(); 5572 test_gif_properties(); 5573 test_image_properties(); 5574 test_Scan0(); 5575 test_FromGdiDib(); 5576 test_GetImageDimension(); 5577 test_GdipImageGetFrameDimensionsCount(); 5578 test_LoadingImages(); 5579 test_SavingImages(); 5580 test_encoders(); 5581 test_LockBits(); 5582 test_LockBits_UserBuf(); 5583 test_GdipCreateBitmapFromHBITMAP(); 5584 test_GdipGetImageFlags(); 5585 test_GdipCloneImage(); 5586 test_testcontrol(); 5587 test_fromhicon(); 5588 test_getrawformat(); 5589 test_loadwmf(); 5590 test_createfromwmf(); 5591 test_createfromwmf_noplaceable(); 5592 test_resolution(); 5593 test_createhbitmap(); 5594 test_getthumbnail(); 5595 test_getsetpixel(); 5596 test_palette(); 5597 test_colormatrix(); 5598 test_gamma(); 5599 test_multiframegif(); 5600 test_rotateflip(); 5601 test_remaptable(); 5602 test_colorkey(); 5603 test_dispose(); 5604 test_createeffect(); 5605 test_getadjustedpalette(); 5606 test_histogram(); 5607 test_imageabort(); 5608 test_GdipLoadImageFromStream(); 5609 5610 GdiplusShutdown(gdiplusToken); 5611 } 5612