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