ReactOS  0.4.14-dev-114-gc8cbd56
image.c
Go to the documentation of this file.
1 /*
2  * Unit test suite for images
3  *
4  * Copyright (C) 2007 Google (Evan Stade)
5  * Copyright (C) 2012, 2016 Dmitry Timoshkov
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #define COBJMACROS
23 
24 #include <math.h>
25 #include <assert.h>
26 #include <stdio.h>
27 
28 #include "initguid.h"
29 #include "objbase.h"
30 #include "gdiplus.h"
31 #include "wine/test.h"
32 
33 #ifdef __REACTOS__
34 #include <ole2.h>
35 #endif
36 
37 /* FIXME: They belong to gdipluseffects.h */
38 DEFINE_GUID(BlurEffectGuid, 0x633c80a4, 0x1843, 0x482b, 0x9e, 0xf2, 0xbe, 0x28, 0x34, 0xc5, 0xfd, 0xd4);
39 DEFINE_GUID(SharpenEffectGuid, 0x63cbf3ee, 0xc526, 0x402c, 0x8f, 0x71, 0x62, 0xc5, 0x40, 0xbf, 0x51, 0x42);
40 DEFINE_GUID(ColorMatrixEffectGuid, 0x718f2615, 0x7933, 0x40e3, 0xa5, 0x11, 0x5f, 0x68, 0xfe, 0x14, 0xdd, 0x74);
41 DEFINE_GUID(ColorLUTEffectGuid, 0xa7ce72a9, 0x0f7f, 0x40d7, 0xb3, 0xcc, 0xd0, 0xc0, 0x2d, 0x5c, 0x32, 0x12);
42 DEFINE_GUID(BrightnessContrastEffectGuid, 0xd3a1dbe1, 0x8ec4, 0x4c17, 0x9f, 0x4c, 0xea, 0x97, 0xad, 0x1c, 0x34, 0x3d);
43 DEFINE_GUID(HueSaturationLightnessEffectGuid, 0x8b2dd6c3, 0xeb07, 0x4d87, 0xa5, 0xf0, 0x71, 0x08, 0xe2, 0x6a, 0x9c, 0x5f);
44 DEFINE_GUID(LevelsEffectGuid, 0x99c354ec, 0x2a31, 0x4f3a, 0x8c, 0x34, 0x17, 0xa8, 0x03, 0xb3, 0x3a, 0x25);
45 DEFINE_GUID(TintEffectGuid, 0x1077af00, 0x2848, 0x4441, 0x94, 0x89, 0x44, 0xad, 0x4c, 0x2d, 0x7a, 0x2c);
46 DEFINE_GUID(ColorBalanceEffectGuid, 0x537e597d, 0x251e, 0x48da, 0x96, 0x64, 0x29, 0xca, 0x49, 0x6b, 0x70, 0xf8);
47 DEFINE_GUID(RedEyeCorrectionEffectGuid, 0x74d29d05, 0x69a4, 0x4266, 0x95, 0x49, 0x3c, 0xc5, 0x28, 0x36, 0xb6, 0x32);
48 DEFINE_GUID(ColorCurveEffectGuid, 0xdd6a0022, 0x58e4, 0x4a67, 0x9d, 0x9b, 0xd4, 0x8e, 0xb8, 0x81, 0xa5, 0x3d);
49 
50 static GpStatus (WINAPI *pGdipBitmapGetHistogramSize)(HistogramFormat,UINT*);
51 static GpStatus (WINAPI *pGdipBitmapGetHistogram)(GpBitmap*,HistogramFormat,UINT,UINT*,UINT*,UINT*,UINT*);
52 static GpStatus (WINAPI *pGdipImageSetAbort)(GpImage*,GdiplusAbort*);
53 
54 static GpStatus (WINGDIPAPI *pGdipInitializePalette)(ColorPalette*,PaletteType,INT,BOOL,GpBitmap*);
55 
56 #define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got))
57 #define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
58 
59 static BOOL color_match(ARGB c1, ARGB c2, BYTE max_diff)
60 {
61  if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
62  c1 >>= 8; c2 >>= 8;
63  if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
64  c1 >>= 8; c2 >>= 8;
65  if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
66  c1 >>= 8; c2 >>= 8;
67  if (abs((c1 & 0xff) - (c2 & 0xff)) > max_diff) return FALSE;
68  return TRUE;
69 }
70 
71 static void expect_guid(REFGUID expected, REFGUID got, int line, BOOL todo)
72 {
73  WCHAR bufferW[39];
74  char buffer[39];
75  char buffer2[39];
76 
77  StringFromGUID2(got, bufferW, ARRAY_SIZE(bufferW));
78  WideCharToMultiByte(CP_ACP, 0, bufferW, ARRAY_SIZE(bufferW), buffer, sizeof(buffer), NULL, NULL);
79  StringFromGUID2(expected, bufferW, ARRAY_SIZE(bufferW));
80  WideCharToMultiByte(CP_ACP, 0, bufferW, ARRAY_SIZE(bufferW), buffer2, sizeof(buffer2), NULL, NULL);
82  ok_(__FILE__, line)(IsEqualGUID(expected, got), "Expected %s, got %s\n", buffer2, buffer);
83 }
84 
86 {
87  GUID raw;
88  GpStatus stat;
89 
91  ok_(__FILE__, line)(stat == Ok, "GdipGetImageRawFormat failed with %d\n", stat);
92  if(stat != Ok) return;
93  expect_guid(expected, &raw, line, todo);
94 }
95 
96 static void test_bufferrawformat(void* buff, int size, REFGUID expected, int line, BOOL todo)
97 {
99  HGLOBAL hglob;
100  LPBYTE data;
101  HRESULT hres;
102  GpStatus stat;
103  GpImage *img;
104 
105  hglob = GlobalAlloc (0, size);
106  data = GlobalLock (hglob);
107  memcpy(data, buff, size);
108  GlobalUnlock(hglob); data = NULL;
109 
111  ok_(__FILE__, line)(hres == S_OK, "Failed to create a stream\n");
112  if(hres != S_OK) return;
113 
115  ok_(__FILE__, line)(stat == Ok, "Failed to create a Bitmap\n");
116  if(stat != Ok){
117  IStream_Release(stream);
118  return;
119  }
120 
122 
124  IStream_Release(stream);
125 }
126 
127 static void test_Scan0(void)
128 {
129  GpBitmap *bm;
130  GpStatus stat;
131  BYTE buff[360];
132 
133  bm = NULL;
135  expect(Ok, stat);
136  ok(NULL != bm, "Expected bitmap to be initialized\n");
137  if (stat == Ok)
139 
140  bm = (GpBitmap*)0xdeadbeef;
143  ok( !bm, "expected null bitmap\n" );
144 
145  bm = (GpBitmap*)0xdeadbeef;
148  ok( !bm, "expected null bitmap\n" );
149 
150  bm = (GpBitmap*)0xdeadbeef;
153  ok( !bm, "expected null bitmap\n" );
154 
155  bm = NULL;
157  expect(Ok, stat);
158  ok(NULL != bm, "Expected bitmap to be initialized\n");
159  if (stat == Ok)
161 
162  bm = (GpBitmap*) 0xdeadbeef;
165  ok( !bm, "expected null bitmap\n" );
166 
167  bm = (GpBitmap*)0xdeadbeef;
170  ok( bm == (GpBitmap*)0xdeadbeef, "expected deadbeef bitmap\n" );
171 
172  bm = NULL;
174  expect(Ok, stat);
175  ok(NULL != bm, "Expected bitmap to be initialized\n");
176  if (stat == Ok)
178 
179  bm = (GpBitmap*)0xdeadbeef;
182  ok( !bm, "expected null bitmap\n" );
183 }
184 
185 static void test_FromGdiDib(void)
186 {
187  GpBitmap *bm;
188  GpStatus stat;
189  BYTE buff[400];
190  BYTE rbmi[sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)];
191  BITMAPINFO *bmi = (BITMAPINFO*)rbmi;
193 
194  bm = NULL;
195 
196  memset(rbmi, 0, sizeof(rbmi));
197 
198  bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
199  bmi->bmiHeader.biWidth = 10;
200  bmi->bmiHeader.biHeight = 10;
201  bmi->bmiHeader.biPlanes = 1;
202  bmi->bmiHeader.biBitCount = 32;
204 
207 
208  stat = GdipCreateBitmapFromGdiDib(bmi, NULL, &bm);
210 
213 
214  stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
215  expect(Ok, stat);
216  ok(NULL != bm, "Expected bitmap to be initialized\n");
217  if (stat == Ok)
218  {
220  expect(Ok, stat);
222 
224  }
225 
226  bmi->bmiHeader.biBitCount = 24;
227  stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
228  expect(Ok, stat);
229  ok(NULL != bm, "Expected bitmap to be initialized\n");
230  if (stat == Ok)
231  {
233  expect(Ok, stat);
235 
237  }
238 
239  bmi->bmiHeader.biBitCount = 16;
240  stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
241  expect(Ok, stat);
242  ok(NULL != bm, "Expected bitmap to be initialized\n");
243  if (stat == Ok)
244  {
246  expect(Ok, stat);
248 
250  }
251 
252  bmi->bmiHeader.biBitCount = 8;
253  stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
254  expect(Ok, stat);
255  ok(NULL != bm, "Expected bitmap to be initialized\n");
256  if (stat == Ok)
257  {
259  expect(Ok, stat);
261 
263  }
264 
265  bmi->bmiHeader.biBitCount = 4;
266  stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
267  expect(Ok, stat);
268  ok(NULL != bm, "Expected bitmap to be initialized\n");
269  if (stat == Ok)
270  {
272  expect(Ok, stat);
274 
276  }
277 
278  bmi->bmiHeader.biBitCount = 1;
279  stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
280  expect(Ok, stat);
281  ok(NULL != bm, "Expected bitmap to be initialized\n");
282  if (stat == Ok)
283  {
285  expect(Ok, stat);
287 
289  }
290 
291  bmi->bmiHeader.biBitCount = 0;
292  stat = GdipCreateBitmapFromGdiDib(bmi, buff, &bm);
294 }
295 
296 static void test_GetImageDimension(void)
297 {
298  GpBitmap *bm;
299  GpStatus stat;
300  const REAL WIDTH = 10.0, HEIGHT = 20.0;
301  REAL w,h;
302 
303  bm = (GpBitmap*)0xdeadbeef;
305  expect(Ok,stat);
306  ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
307  ok(NULL != bm, "Expected bitmap to not be NULL\n");
308 
311 
314 
317 
318  w = -1;
319  h = -1;
321  expect(Ok, stat);
322  expectf(WIDTH, w);
323  expectf(HEIGHT, h);
325 }
326 
328 {
329  GpBitmap *bm;
330  GpStatus stat;
331  const REAL WIDTH = 10.0, HEIGHT = 20.0;
332  UINT w;
333  GUID dimension = {0};
334  UINT count;
335  ARGB color;
336 
337  bm = (GpBitmap*)0xdeadbeef;
339  expect(Ok,stat);
340  ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
341  ok(NULL != bm, "Expected bitmap to not be NULL\n");
342 
345 
348 
349  w = -1;
351  expect(Ok, stat);
352  expect(1, w);
353 
354  stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 1);
355  expect(Ok, stat);
356  expect_guid(&FrameDimensionPage, &dimension, __LINE__, FALSE);
357 
358  stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 2);
360 
361  stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 0);
363 
364  stat = GdipImageGetFrameCount(NULL, &dimension, &count);
366 
367  /* WinXP crashes on this test */
368  if(0)
369  {
370  stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, NULL);
372  }
373 
375  expect(Ok, stat);
376 
377  count = 12345;
378  stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, &count);
379  expect(Ok, stat);
380  expect(1, count);
381 
382  GdipBitmapSetPixel(bm, 0, 0, 0xffffffff);
383 
384  stat = GdipImageSelectActiveFrame((GpImage*)bm, &dimension, 0);
385  expect(Ok, stat);
386 
387  /* SelectActiveFrame has no effect on image data of memory bitmaps */
388  color = 0xdeadbeef;
389  stat = GdipBitmapGetPixel(bm, 0, 0, &color);
390  expect(Ok, stat);
391  expect(0xffffffff, color);
392 
394 }
395 
396 static void test_LoadingImages(void)
397 {
398  GpStatus stat;
399  GpBitmap *bm;
400  GpImage *img;
401  static const WCHAR nonexistentW[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
402 
405 
406  bm = (GpBitmap *)0xdeadbeef;
407  stat = GdipCreateBitmapFromFile(0, &bm);
409  ok(bm == (GpBitmap *)0xdeadbeef, "returned %p\n", bm);
410 
411  bm = (GpBitmap *)0xdeadbeef;
412  stat = GdipCreateBitmapFromFile(nonexistentW, &bm);
414  ok(!bm, "returned %p\n", bm);
415 
416  stat = GdipLoadImageFromFile(0, 0);
418 
419  img = (GpImage *)0xdeadbeef;
422  ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img);
423 
424  img = (GpImage *)0xdeadbeef;
425  stat = GdipLoadImageFromFile(nonexistentW, &img);
427  ok(!img, "returned %p\n", img);
428 
431 
432  img = (GpImage *)0xdeadbeef;
435  ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img);
436 
437  img = (GpImage *)0xdeadbeef;
438  stat = GdipLoadImageFromFileICM(nonexistentW, &img);
440  ok(!img, "returned %p\n", img);
441 }
442 
443 static void test_SavingImages(void)
444 {
445  GpStatus stat;
446  GpBitmap *bm;
447  UINT n;
448  UINT s;
449  const REAL WIDTH = 10.0, HEIGHT = 20.0;
450  REAL w, h;
452  static const CHAR filenameA[] = "a.bmp";
453  static const WCHAR filename[] = { 'a','.','b','m','p',0 };
454 
455  codecs = NULL;
456 
457  stat = GdipSaveImageToFile(0, 0, 0, 0);
459 
460  bm = NULL;
462  expect(Ok, stat);
463  if (!bm)
464  return;
465 
466  /* invalid params */
467  stat = GdipSaveImageToFile((GpImage*)bm, 0, 0, 0);
469 
470  stat = GdipSaveImageToFile((GpImage*)bm, filename, 0, 0);
472 
473  /* encoder tests should succeed -- already tested */
475  if (stat != Ok || n == 0) goto cleanup;
476 
477  codecs = GdipAlloc(s);
478  if (!codecs) goto cleanup;
479 
481  if (stat != Ok) goto cleanup;
482 
483  stat = GdipSaveImageToFile((GpImage*)bm, filename, &codecs[0].Clsid, 0);
484  expect(Ok, stat);
485 
487  bm = 0;
488 
489  /* re-load and check image stats */
491  expect(Ok, stat);
492  if (stat != Ok) goto cleanup;
493 
494  stat = GdipGetImageDimension((GpImage*)bm, &w, &h);
495  if (stat != Ok) goto cleanup;
496 
497  expectf(WIDTH, w);
498  expectf(HEIGHT, h);
499 
500  cleanup:
501  GdipFree(codecs);
502  if (bm)
504  ok(DeleteFileA(filenameA), "Delete failed.\n");
505 }
506 
507 static void test_encoders(void)
508 {
509  GpStatus stat;
510  UINT n;
511  UINT s;
513  int i;
514  int bmp_found;
515 
516  static const CHAR bmp_format[] = "BMP";
517 
519  expect(stat, Ok);
520 
521  codecs = GdipAlloc(s);
522  if (!codecs)
523  return;
524 
527 
530 
533 
536 
538  expect(stat, Ok);
539 
540  bmp_found = FALSE;
541  for (i = 0; i < n; i++)
542  {
543  CHAR desc[32];
544 
545  WideCharToMultiByte(CP_ACP, 0, codecs[i].FormatDescription, -1,
546  desc, 32, 0, 0);
547 
549  desc, -1,
550  bmp_format, -1) == CSTR_EQUAL) {
551  bmp_found = TRUE;
552  break;
553  }
554  }
555  if (!bmp_found)
556  ok(FALSE, "No BMP codec found.\n");
557 
558  GdipFree(codecs);
559 }
560 
561 static void test_LockBits(void)
562 {
563  GpStatus stat;
564  GpBitmap *bm;
565  GpRect rect;
566  BitmapData bd;
567  const INT WIDTH = 10, HEIGHT = 20;
568  ARGB color;
569  int y;
570 
571  bm = NULL;
573  expect(Ok, stat);
574 
575  rect.X = 2;
576  rect.Y = 3;
577  rect.Width = 4;
578  rect.Height = 5;
579 
580  stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000);
581  expect(Ok, stat);
582 
583  stat = GdipBitmapSetPixel(bm, 2, 8, 0xff480000);
584  expect(Ok, stat);
585 
586  /* read-only */
588  expect(Ok, stat);
589 
590  if (stat == Ok) {
591  expect(0xc3, ((BYTE*)bd.Scan0)[2]);
592  expect(0x48, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]);
593 
594  ((char*)bd.Scan0)[2] = 0xff;
595 
596  stat = GdipBitmapUnlockBits(bm, &bd);
597  expect(Ok, stat);
598  }
599 
600  stat = GdipBitmapGetPixel(bm, 2, 3, &color);
601  expect(Ok, stat);
602  expect(0xffff0000, color);
603 
604  stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000);
605  expect(Ok, stat);
606 
607  /* read-only, with NULL rect -> whole bitmap lock */
609  expect(Ok, stat);
610  expect(bd.Width, WIDTH);
611  expect(bd.Height, HEIGHT);
612 
613  if (stat == Ok) {
614  ((char*)bd.Scan0)[2 + 2*3 + 3*bd.Stride] = 0xff;
615 
616  stat = GdipBitmapUnlockBits(bm, &bd);
617  expect(Ok, stat);
618  }
619 
620  stat = GdipBitmapGetPixel(bm, 2, 3, &color);
621  expect(Ok, stat);
622  expect(0xffff0000, color);
623 
624  /* read-only, consecutive */
626  expect(Ok, stat);
627 
628  if (stat == Ok) {
629  stat = GdipBitmapUnlockBits(bm, &bd);
630  expect(Ok, stat);
631  }
632 
633  stat = GdipDisposeImage((GpImage*)bm);
634  expect(Ok, stat);
636  expect(Ok, stat);
637 
638  /* read x2 */
640  expect(Ok, stat);
643 
644  stat = GdipBitmapUnlockBits(bm, &bd);
645  expect(Ok, stat);
646 
647  stat = GdipDisposeImage((GpImage*)bm);
648  expect(Ok, stat);
650  expect(Ok, stat);
651 
652  stat = GdipBitmapSetPixel(bm, 2, 3, 0xffff0000);
653  expect(Ok, stat);
654 
655  stat = GdipBitmapSetPixel(bm, 2, 8, 0xffc30000);
656  expect(Ok, stat);
657 
658  /* write, no conversion */
660  expect(Ok, stat);
661 
662  if (stat == Ok) {
663  /* all bits are readable, inside the rect or not */
664  expect(0xff, ((BYTE*)bd.Scan0)[2]);
665  expect(0xc3, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]);
666 
667  stat = GdipBitmapUnlockBits(bm, &bd);
668  expect(Ok, stat);
669  }
670 
671  /* read, conversion */
673  expect(Ok, stat);
674 
675  if (stat == Ok) {
676  expect(0xff, ((BYTE*)bd.Scan0)[2]);
677  if (0)
678  /* Areas outside the rectangle appear to be uninitialized */
679  ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
680 
681  ((BYTE*)bd.Scan0)[2] = 0xc3;
682 
683  stat = GdipBitmapUnlockBits(bm, &bd);
684  expect(Ok, stat);
685  }
686 
687  /* writes do not work in read mode if there was a conversion */
688  stat = GdipBitmapGetPixel(bm, 2, 3, &color);
689  expect(Ok, stat);
690  expect(0xffff0000, color);
691 
692  /* read/write, conversion */
694  expect(Ok, stat);
695 
696  if (stat == Ok) {
697  expect(0xff, ((BYTE*)bd.Scan0)[2]);
698  ((BYTE*)bd.Scan0)[1] = 0x88;
699  if (0)
700  /* Areas outside the rectangle appear to be uninitialized */
701  ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
702 
703  stat = GdipBitmapUnlockBits(bm, &bd);
704  expect(Ok, stat);
705  }
706 
707  stat = GdipBitmapGetPixel(bm, 2, 3, &color);
708  expect(Ok, stat);
709  expect(0xffff8800, color);
710 
711  /* write, conversion */
713  expect(Ok, stat);
714 
715  if (stat == Ok) {
716  if (0)
717  {
718  /* This is completely uninitialized. */
719  ok(0xff != ((BYTE*)bd.Scan0)[2], "original image bits are readable\n");
720  ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
721  }
722 
723  /* Initialize the buffer so the unlock doesn't access undefined memory */
724  for (y=0; y<5; y++)
725  memset(((BYTE*)bd.Scan0) + bd.Stride * y, 0, 12);
726 
727  ((BYTE*)bd.Scan0)[0] = 0x12;
728  ((BYTE*)bd.Scan0)[1] = 0x34;
729  ((BYTE*)bd.Scan0)[2] = 0x56;
730 
731  stat = GdipBitmapUnlockBits(bm, &bd);
732  expect(Ok, stat);
733  }
734 
735  stat = GdipBitmapGetPixel(bm, 2, 3, &color);
736  expect(Ok, stat);
737  expect(0xff563412, color);
738 
739  stat = GdipBitmapGetPixel(bm, 2, 8, &color);
740  expect(Ok, stat);
741  expect(0xffc30000, color);
742 
743  stat = GdipDisposeImage((GpImage*)bm);
744  expect(Ok, stat);
746  expect(Ok, stat);
747 
748  /* write, no modification */
750  expect(Ok, stat);
751 
752  if (stat == Ok) {
753  stat = GdipBitmapUnlockBits(bm, &bd);
754  expect(Ok, stat);
755  }
756 
757  /* write, consecutive */
759  expect(Ok, stat);
760 
761  if (stat == Ok) {
762  stat = GdipBitmapUnlockBits(bm, &bd);
763  expect(Ok, stat);
764  }
765 
766  stat = GdipDisposeImage((GpImage*)bm);
767  expect(Ok, stat);
769  expect(Ok, stat);
770 
771  /* write, modify */
773  expect(Ok, stat);
774 
775  if (stat == Ok) {
776  if (bd.Scan0)
777  ((char*)bd.Scan0)[2] = 0xff;
778 
779  stat = GdipBitmapUnlockBits(bm, &bd);
780  expect(Ok, stat);
781  }
782 
783  stat = GdipBitmapGetPixel(bm, 2, 3, &color);
784  expect(Ok, stat);
785  expect(0xffff0000, color);
786 
787  stat = GdipDisposeImage((GpImage*)bm);
788  expect(Ok, stat);
789 
790  /* dispose locked */
792  expect(Ok, stat);
794  expect(Ok, stat);
795  stat = GdipDisposeImage((GpImage*)bm);
796  expect(Ok, stat);
797 }
798 
799 static void test_LockBits_UserBuf(void)
800 {
801  GpStatus stat;
802  GpBitmap *bm;
803  GpRect rect;
804  BitmapData bd;
805  const INT WIDTH = 10, HEIGHT = 20;
806  DWORD bits[200];
807  ARGB color;
808 
809  bm = NULL;
811  expect(Ok, stat);
812 
813  memset(bits, 0xaa, sizeof(bits));
814 
815  rect.X = 2;
816  rect.Y = 3;
817  rect.Width = 4;
818  rect.Height = 5;
819 
820  bd.Width = 4;
821  bd.Height = 6;
822  bd.Stride = WIDTH * 4;
824  bd.Scan0 = &bits[2+3*WIDTH];
825  bd.Reserved = 0xaaaaaaaa;
826 
827  /* read-only */
829  expect(Ok, stat);
830 
831  expect(0xaaaaaaaa, bits[0]);
832  expect(0, bits[2+3*WIDTH]);
833 
834  bits[2+3*WIDTH] = 0xdeadbeef;
835 
836  if (stat == Ok) {
837  stat = GdipBitmapUnlockBits(bm, &bd);
838  expect(Ok, stat);
839  }
840 
841  stat = GdipBitmapGetPixel(bm, 2, 3, &color);
842  expect(Ok, stat);
843  expect(0, color);
844 
845  /* write-only */
847  expect(Ok, stat);
848 
849  expect(0xdeadbeef, bits[2+3*WIDTH]);
850  bits[2+3*WIDTH] = 0x12345678;
851 
852  if (stat == Ok) {
853  stat = GdipBitmapUnlockBits(bm, &bd);
854  expect(Ok, stat);
855  }
856 
857  stat = GdipBitmapGetPixel(bm, 2, 3, &color);
858  expect(Ok, stat);
859  expect(0x12345678, color);
860 
861  bits[2+3*WIDTH] = 0;
862 
863  /* read/write */
865  expect(Ok, stat);
866 
867  expect(0x12345678, bits[2+3*WIDTH]);
868  bits[2+3*WIDTH] = 0xdeadbeef;
869 
870  if (stat == Ok) {
871  stat = GdipBitmapUnlockBits(bm, &bd);
872  expect(Ok, stat);
873  }
874 
875  stat = GdipBitmapGetPixel(bm, 2, 3, &color);
876  expect(Ok, stat);
877  expect(0xdeadbeef, color);
878 
879  stat = GdipDisposeImage((GpImage*)bm);
880  expect(Ok, stat);
881 }
882 
884 {
887 };
888 
890 {
893 };
894 
896 {
897  GpBitmap* gpbm = NULL;
898  HBITMAP hbm = NULL;
899  HPALETTE hpal = NULL;
900  GpStatus stat;
901  BYTE buff[1000];
902  LOGPALETTE* LogPal = NULL;
903  REAL width, height;
904  const REAL WIDTH1 = 5;
905  const REAL HEIGHT1 = 15;
906  const REAL WIDTH2 = 10;
907  const REAL HEIGHT2 = 20;
908  HDC hdc;
909  union BITMAPINFOUNION bmi;
910  BYTE *bits;
912 
915 
916  hbm = CreateBitmap(WIDTH1, HEIGHT1, 1, 1, NULL);
919 
921  expect(Ok, stat);
923  expectf(WIDTH1, width);
924  expectf(HEIGHT1, height);
925  if (stat == Ok)
926  GdipDisposeImage((GpImage*)gpbm);
927  DeleteObject(hbm);
928 
929  memset(buff, 0, sizeof(buff));
930  hbm = CreateBitmap(WIDTH2, HEIGHT2, 1, 1, &buff);
932  expect(Ok, stat);
933  /* raw format */
934  expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)gpbm, __LINE__, FALSE);
935 
937  expectf(WIDTH2, width);
938  expectf(HEIGHT2, height);
939  if (stat == Ok)
940  GdipDisposeImage((GpImage*)gpbm);
941  DeleteObject(hbm);
942 
943  hdc = CreateCompatibleDC(0);
944  ok(hdc != NULL, "CreateCompatibleDC failed\n");
945  bmi.bi.bmiHeader.biSize = sizeof(bmi.bi.bmiHeader);
946  bmi.bi.bmiHeader.biHeight = HEIGHT1;
947  bmi.bi.bmiHeader.biWidth = WIDTH1;
948  bmi.bi.bmiHeader.biBitCount = 24;
949  bmi.bi.bmiHeader.biPlanes = 1;
951  bmi.bi.bmiHeader.biClrUsed = 0;
952 
953  hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
954  ok(hbm != NULL, "CreateDIBSection failed\n");
955 
956  bits[0] = 0;
957 
959  expect(Ok, stat);
961  expectf(WIDTH1, width);
962  expectf(HEIGHT1, height);
963  if (stat == Ok)
964  {
965  /* test whether writing to the bitmap affects the original */
966  stat = GdipBitmapSetPixel(gpbm, 0, 0, 0xffffffff);
967  expect(Ok, stat);
968 
969  expect(0, bits[0]);
970 
971  GdipDisposeImage((GpImage*)gpbm);
972  }
973 
974  LogPal = GdipAlloc(sizeof(LOGPALETTE));
975  ok(LogPal != NULL, "unable to allocate LOGPALETTE\n");
976  LogPal->palVersion = 0x300;
977  LogPal->palNumEntries = 1;
978  hpal = CreatePalette(LogPal);
979  ok(hpal != NULL, "CreatePalette failed\n");
980  GdipFree(LogPal);
981 
982  stat = GdipCreateBitmapFromHBITMAP(hbm, hpal, &gpbm);
983  expect(Ok, stat);
984 
985  if (stat == Ok)
986  GdipDisposeImage((GpImage*)gpbm);
987 
988  DeleteObject(hpal);
989  DeleteObject(hbm);
990 
991  /* 16-bit 555 dib, rgb */
992  bmi.bi.bmiHeader.biBitCount = 16;
994 
995  hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
996  ok(hbm != NULL, "CreateDIBSection failed\n");
997 
998  bits[0] = 0;
999 
1001  expect(Ok, stat);
1002 
1003  if (stat == Ok)
1004  {
1006  expect(Ok, stat);
1007  expectf(WIDTH1, width);
1008  expectf(HEIGHT1, height);
1009 
1011  expect(Ok, stat);
1013 
1014  GdipDisposeImage((GpImage*)gpbm);
1015  }
1016  DeleteObject(hbm);
1017 
1018  /* 16-bit 555 dib, with bitfields */
1019  bmi.bi.bmiHeader.biSize = sizeof(bmi);
1021  bmi.bf.masks[0] = 0x7c00;
1022  bmi.bf.masks[1] = 0x3e0;
1023  bmi.bf.masks[2] = 0x1f;
1024 
1025  hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1026  ok(hbm != NULL, "CreateDIBSection failed\n");
1027 
1028  bits[0] = 0;
1029 
1031  expect(Ok, stat);
1032 
1033  if (stat == Ok)
1034  {
1036  expect(Ok, stat);
1037  expectf(WIDTH1, width);
1038  expectf(HEIGHT1, height);
1039 
1041  expect(Ok, stat);
1043 
1044  GdipDisposeImage((GpImage*)gpbm);
1045  }
1046  DeleteObject(hbm);
1047 
1048  /* 16-bit 565 dib, with bitfields */
1049  bmi.bf.masks[0] = 0xf800;
1050  bmi.bf.masks[1] = 0x7e0;
1051  bmi.bf.masks[2] = 0x1f;
1052 
1053  hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1054  ok(hbm != NULL, "CreateDIBSection failed\n");
1055 
1056  bits[0] = 0;
1057 
1059  expect(Ok, stat);
1060 
1061  if (stat == Ok)
1062  {
1064  expect(Ok, stat);
1065  expectf(WIDTH1, width);
1066  expectf(HEIGHT1, height);
1067 
1069  expect(Ok, stat);
1071 
1072  GdipDisposeImage((GpImage*)gpbm);
1073  }
1074  DeleteObject(hbm);
1075 
1076  DeleteDC(hdc);
1077 }
1078 
1079 static void test_GdipGetImageFlags(void)
1080 {
1081  GpImage *img;
1082  GpStatus stat;
1083  UINT flags;
1084 
1085  img = (GpImage*)0xdeadbeef;
1086 
1089 
1092 
1095 
1097  expect(Ok, stat);
1099  expect(Ok, stat);
1102 
1104  expect(Ok, stat);
1106  expect(Ok, stat);
1109 
1111  expect(Ok, stat);
1113  expect(Ok, stat);
1116 
1118  expect(Ok, stat);
1120  expect(Ok, stat);
1123 
1125  expect(Ok, stat);
1127  expect(Ok, stat);
1130 
1132  expect(Ok, stat);
1134  expect(Ok, stat);
1137 
1139  expect(Ok, stat);
1141  expect(Ok, stat);
1144 
1146  expect(Ok, stat);
1148  expect(Ok, stat);
1151 
1153  expect(Ok, stat);
1155  expect(Ok, stat);
1158 
1160  expect(Ok, stat);
1162  expect(Ok, stat);
1165 
1167  expect(Ok, stat);
1169  expect(Ok, stat);
1172 
1174  expect(Ok, stat);
1175  if (stat == Ok)
1176  {
1178  expect(Ok, stat);
1181  }
1182 
1184  expect(Ok, stat);
1185  if (stat == Ok)
1186  {
1187  expect(Ok, stat);
1189  expect(Ok, stat);
1192  }
1193 
1195  expect(Ok, stat);
1196  if (stat == Ok)
1197  {
1198  expect(Ok, stat);
1200  expect(Ok, stat);
1203  }
1204 }
1205 
1206 static void test_GdipCloneImage(void)
1207 {
1208  GpStatus stat;
1209  GpRectF rectF;
1210  GpUnit unit;
1211  GpBitmap *bm;
1212  GpImage *image_src, *image_dest = NULL;
1213  const INT WIDTH = 10, HEIGHT = 20;
1214 
1215  /* Create an image, clone it, delete the original, make sure the copy works */
1217  expect(Ok, stat);
1218  expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bm, __LINE__, FALSE);
1219 
1220  image_src = ((GpImage*)bm);
1221  stat = GdipCloneImage(image_src, &image_dest);
1222  expect(Ok, stat);
1223  expect_rawformat(&ImageFormatMemoryBMP, image_dest, __LINE__, FALSE);
1224 
1225  stat = GdipDisposeImage((GpImage*)bm);
1226  expect(Ok, stat);
1227  stat = GdipGetImageBounds(image_dest, &rectF, &unit);
1228  expect(Ok, stat);
1229 
1230  /* Treat FP values carefully */
1231  expectf((REAL)WIDTH, rectF.Width);
1232  expectf((REAL)HEIGHT, rectF.Height);
1233 
1234  stat = GdipDisposeImage(image_dest);
1235  expect(Ok, stat);
1236 }
1237 
1238 static void test_testcontrol(void)
1239 {
1240  GpStatus stat;
1241  DWORD param;
1242 
1243  param = 0;
1245  expect(Ok, stat);
1246  ok(param != 0, "Build number expected, got %u\n", param);
1247 }
1248 
1249 static void test_fromhicon(void)
1250 {
1251  static const BYTE bmp_bits[1024];
1252  HBITMAP hbmMask, hbmColor;
1253  ICONINFO info;
1254  HICON hIcon;
1255  GpStatus stat;
1256  GpBitmap *bitmap = NULL;
1257  UINT dim;
1258  ImageType type;
1260 
1261  /* NULL */
1266 
1267  /* color icon 1 bit */
1268  hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
1269  ok(hbmMask != 0, "CreateBitmap failed\n");
1270  hbmColor = CreateBitmap(16, 16, 1, 1, bmp_bits);
1271  ok(hbmColor != 0, "CreateBitmap failed\n");
1272  info.fIcon = TRUE;
1273  info.xHotspot = 8;
1274  info.yHotspot = 8;
1275  info.hbmMask = hbmMask;
1276  info.hbmColor = hbmColor;
1278  ok(hIcon != 0, "CreateIconIndirect failed\n");
1279  DeleteObject(hbmMask);
1280  DeleteObject(hbmColor);
1281 
1283  ok(stat == Ok ||
1284  broken(stat == InvalidParameter), /* Win98 */
1285  "Expected Ok, got %.8x\n", stat);
1286  if(stat == Ok){
1287  /* check attributes */
1289  expect(Ok, stat);
1290  expect(16, dim);
1291  stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1292  expect(Ok, stat);
1293  expect(16, dim);
1295  expect(Ok, stat);
1298  expect(Ok, stat);
1300  /* raw format */
1301  expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1303  }
1304  DestroyIcon(hIcon);
1305 
1306  /* color icon 8 bpp */
1307  hbmMask = CreateBitmap(16, 16, 1, 8, bmp_bits);
1308  ok(hbmMask != 0, "CreateBitmap failed\n");
1309  hbmColor = CreateBitmap(16, 16, 1, 8, bmp_bits);
1310  ok(hbmColor != 0, "CreateBitmap failed\n");
1311  info.fIcon = TRUE;
1312  info.xHotspot = 8;
1313  info.yHotspot = 8;
1314  info.hbmMask = hbmMask;
1315  info.hbmColor = hbmColor;
1317  ok(hIcon != 0, "CreateIconIndirect failed\n");
1318  DeleteObject(hbmMask);
1319  DeleteObject(hbmColor);
1320 
1322  expect(Ok, stat);
1323  if(stat == Ok){
1324  /* check attributes */
1326  expect(Ok, stat);
1327  expect(16, dim);
1328  stat = GdipGetImageWidth((GpImage*)bitmap, &dim);
1329  expect(Ok, stat);
1330  expect(16, dim);
1332  expect(Ok, stat);
1335  expect(Ok, stat);
1337  /* raw format */
1338  expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1340  }
1341  DestroyIcon(hIcon);
1342 }
1343 
1344 /* 1x1 pixel png */
1345 static const unsigned char pngimage[285] = {
1346 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
1347 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
1348 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
1349 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
1350 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
1351 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
1352 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1353 };
1354 /* 1x1 pixel gif */
1355 static const unsigned char gifimage[35] = {
1356 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
1357 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
1358 0x01,0x00,0x3b
1359 };
1360 /* 1x1 pixel transparent gif */
1361 static const unsigned char transparentgif[] = {
1362 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
1363 0x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
1364 0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1365 };
1366 /* 1x1 pixel bmp */
1367 static const unsigned char bmpimage[66] = {
1368 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
1369 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
1370 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
1371 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
1372 0x00,0x00
1373 };
1374 /* 1x1 pixel jpg */
1375 static const unsigned char jpgimage[285] = {
1376 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
1377 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
1378 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
1379 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
1380 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
1381 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
1382 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
1383 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1384 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
1385 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
1386 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
1387 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1388 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
1389 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
1390 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1391 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
1392 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
1393 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1394 };
1395 /* 1x1 pixel tiff */
1396 static const unsigned char tiffimage[] = {
1397 0x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
1398 0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
1399 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1400 0x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
1401 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
1402 0x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
1403 0x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
1404 0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
1405 0x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
1406 0x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
1407 0x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
1408 0x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
1409 0x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
1410 0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
1411 0x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
1412 0x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
1413 0x00,0x00,0x00,0x01
1414 };
1415 /* 320x320 twip wmf */
1416 static const unsigned char wmfimage[180] = {
1417 0xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
1418 0x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
1419 0x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
1420 0x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
1421 0x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
1422 0xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
1423 0x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
1424 0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
1425 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
1426 0x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
1427 0x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
1428 0x00,0x00,0x00,0x00
1429 };
1430 static void test_getrawformat(void)
1431 {
1432  test_bufferrawformat((void*)pngimage, sizeof(pngimage), &ImageFormatPNG, __LINE__, FALSE);
1433  test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF, __LINE__, FALSE);
1434  test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP, __LINE__, FALSE);
1435  test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, FALSE);
1436  test_bufferrawformat((void*)tiffimage, sizeof(tiffimage), &ImageFormatTIFF, __LINE__, FALSE);
1437  test_bufferrawformat((void*)wmfimage, sizeof(wmfimage), &ImageFormatWMF, __LINE__, FALSE);
1438 }
1439 
1440 static void test_loadwmf(void)
1441 {
1442  LPSTREAM stream;
1443  HGLOBAL hglob;
1444  LPBYTE data;
1445  HRESULT hres;
1446  GpStatus stat;
1447  GpImage *img;
1448  GpRectF bounds;
1449  GpUnit unit;
1450  REAL res = 12345.0;
1452 
1453  hglob = GlobalAlloc (0, sizeof(wmfimage));
1454  data = GlobalLock (hglob);
1455  memcpy(data, wmfimage, sizeof(wmfimage));
1456  GlobalUnlock(hglob); data = NULL;
1457 
1458  hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
1459  ok(hres == S_OK, "Failed to create a stream\n");
1460  if(hres != S_OK) return;
1461 
1463  ok(stat == Ok, "Failed to create a Bitmap\n");
1464  if(stat != Ok){
1465  IStream_Release(stream);
1466  return;
1467  }
1468 
1469  IStream_Release(stream);
1470 
1471  stat = GdipGetImageBounds(img, &bounds, &unit);
1472  expect(Ok, stat);
1473  expect(UnitPixel, unit);
1474  expectf(0.0, bounds.X);
1475  expectf(0.0, bounds.Y);
1476  expectf(320.0, bounds.Width);
1477  expectf(320.0, bounds.Height);
1478 
1480  expect(Ok, stat);
1481  expectf(1440.0, res);
1482 
1484  expect(Ok, stat);
1485  expectf(1440.0, res);
1486 
1487  memset(&header, 0, sizeof(header));
1489  expect(Ok, stat);
1490  if (stat == Ok)
1491  {
1493  todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1494  todo_wine expect(0x300, header.Version);
1495  expect(0, header.EmfPlusFlags);
1496  expectf(1440.0, header.DpiX);
1497  expectf(1440.0, header.DpiY);
1498  expect(0, header.X);
1499  expect(0, header.Y);
1500  expect(320, header.Width);
1501  expect(320, header.Height);
1502  expect(1, U(header).WmfHeader.mtType);
1503  expect(0, header.EmfPlusHeaderSize);
1504  expect(0, header.LogicalDpiX);
1505  expect(0, header.LogicalDpiY);
1506  }
1507 
1509 }
1510 
1511 static void test_createfromwmf(void)
1512 {
1513  HMETAFILE hwmf;
1514  GpImage *img;
1515  GpStatus stat;
1516  GpRectF bounds;
1517  GpUnit unit;
1518  REAL res = 12345.0;
1520 
1521  hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
1523  ok(hwmf != 0, "SetMetaFileBitsEx failed\n");
1524 
1527  expect(Ok, stat);
1528 
1529  stat = GdipGetImageBounds(img, &bounds, &unit);
1530  expect(Ok, stat);
1531  expect(UnitPixel, unit);
1532  expectf(0.0, bounds.X);
1533  expectf(0.0, bounds.Y);
1534  expectf(320.0, bounds.Width);
1535  expectf(320.0, bounds.Height);
1536 
1538  expect(Ok, stat);
1539  expectf(1440.0, res);
1540 
1542  expect(Ok, stat);
1543  expectf(1440.0, res);
1544 
1545  memset(&header, 0, sizeof(header));
1547  expect(Ok, stat);
1548  if (stat == Ok)
1549  {
1551  todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1552  todo_wine expect(0x300, header.Version);
1553  expect(0, header.EmfPlusFlags);
1554  expectf(1440.0, header.DpiX);
1555  expectf(1440.0, header.DpiY);
1556  expect(0, header.X);
1557  expect(0, header.Y);
1558  expect(320, header.Width);
1559  expect(320, header.Height);
1560  expect(1, U(header).WmfHeader.mtType);
1561  expect(0, header.EmfPlusHeaderSize);
1562  expect(0, header.LogicalDpiX);
1563  expect(0, header.LogicalDpiY);
1564  }
1565 
1567 }
1568 
1570 {
1571  HMETAFILE hwmf;
1572  GpImage *img;
1573  GpStatus stat;
1574 
1575  hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
1577  ok(hwmf != 0, "SetMetaFileBitsEx failed\n");
1578 
1580  expect(Ok, stat);
1581 
1583 }
1584 
1585 static void test_resolution(void)
1586 {
1587  GpStatus stat;
1588  GpBitmap *bitmap;
1589  GpGraphics *graphics;
1590  REAL res=-1.0;
1591  HDC screendc;
1592  int screenxres, screenyres;
1593 
1594  /* create Bitmap */
1596  expect(Ok, stat);
1597 
1598  /* test invalid values */
1601 
1604 
1607 
1610 
1611  stat = GdipBitmapSetResolution(NULL, 96.0, 96.0);
1613 
1614  stat = GdipBitmapSetResolution(bitmap, 0.0, 0.0);
1616 
1617  /* defaults to screen resolution */
1618  screendc = GetDC(0);
1619 
1620  screenxres = GetDeviceCaps(screendc, LOGPIXELSX);
1621  screenyres = GetDeviceCaps(screendc, LOGPIXELSY);
1622 
1623  ReleaseDC(0, screendc);
1624 
1626  expect(Ok, stat);
1627  expectf((REAL)screenxres, res);
1628 
1630  expect(Ok, stat);
1631  expectf((REAL)screenyres, res);
1632 
1634  expect(Ok, stat);
1635  stat = GdipGetDpiX(graphics, &res);
1636  expect(Ok, stat);
1637  expectf((REAL)screenxres, res);
1638  stat = GdipGetDpiY(graphics, &res);
1639  expect(Ok, stat);
1640  expectf((REAL)screenyres, res);
1641 
1642  /* test changing the resolution */
1643  stat = GdipBitmapSetResolution(bitmap, screenxres*2.0, screenyres*3.0);
1644  expect(Ok, stat);
1645 
1647  expect(Ok, stat);
1648  expectf(screenxres*2.0, res);
1649 
1651  expect(Ok, stat);
1652  expectf(screenyres*3.0, res);
1653 
1654  stat = GdipGetDpiX(graphics, &res);
1655  expect(Ok, stat);
1656  expectf((REAL)screenxres, res);
1657  stat = GdipGetDpiY(graphics, &res);
1658  expect(Ok, stat);
1659  expectf((REAL)screenyres, res);
1660 
1661  stat = GdipDeleteGraphics(graphics);
1662  expect(Ok, stat);
1663 
1665  expect(Ok, stat);
1666  stat = GdipGetDpiX(graphics, &res);
1667  expect(Ok, stat);
1668  expectf(screenxres*2.0, res);
1669  stat = GdipGetDpiY(graphics, &res);
1670  expect(Ok, stat);
1671  expectf(screenyres*3.0, res);
1672  stat = GdipDeleteGraphics(graphics);
1673  expect(Ok, stat);
1674 
1676  expect(Ok, stat);
1677 }
1678 
1679 static void test_createhbitmap(void)
1680 {
1681  GpStatus stat;
1682  GpBitmap *bitmap;
1683  HBITMAP hbitmap, oldhbitmap;
1684  BITMAP bm;
1685  int ret;
1686  HDC hdc;
1687  COLORREF pixel;
1688  BYTE bits[640];
1689  BitmapData lockeddata;
1690 
1691  memset(bits, 0x68, 640);
1692 
1693  /* create Bitmap */
1695  expect(Ok, stat);
1696 
1697  /* test NULL values */
1700 
1703 
1704  /* create HBITMAP */
1706  expect(Ok, stat);
1707 
1708  if (stat == Ok)
1709  {
1710  ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1711  expect(sizeof(BITMAP), ret);
1712 
1713  expect(0, bm.bmType);
1714  expect(10, bm.bmWidth);
1715  expect(20, bm.bmHeight);
1716  expect(40, bm.bmWidthBytes);
1717  expect(1, bm.bmPlanes);
1718  expect(32, bm.bmBitsPixel);
1719  ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1720 
1721  if (bm.bmBits)
1722  {
1723  DWORD val = *(DWORD*)bm.bmBits;
1724  ok(val == 0xff686868, "got %x, expected 0xff686868\n", val);
1725  }
1726 
1728 
1729  oldhbitmap = SelectObject(hdc, hbitmap);
1730  pixel = GetPixel(hdc, 5, 5);
1731  SelectObject(hdc, oldhbitmap);
1732 
1733  DeleteDC(hdc);
1734 
1735  expect(0x686868, pixel);
1736 
1738  }
1739 
1741  expect(Ok, stat);
1742 
1743  /* make (1,0) have no alpha and (2,0) a different blue value. */
1744  bits[7] = 0x00;
1745  bits[8] = 0x40;
1746 
1747  /* create alpha Bitmap */
1749  expect(Ok, stat);
1750 
1751  /* create HBITMAP */
1753  expect(Ok, stat);
1754 
1755  if (stat == Ok)
1756  {
1757  ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1758  expect(sizeof(BITMAP), ret);
1759 
1760  expect(0, bm.bmType);
1761  expect(8, bm.bmWidth);
1762  expect(20, bm.bmHeight);
1763  expect(32, bm.bmWidthBytes);
1764  expect(1, bm.bmPlanes);
1765  expect(32, bm.bmBitsPixel);
1766  ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1767 
1768  if (bm.bmBits)
1769  {
1770  DWORD val = *(DWORD*)bm.bmBits;
1771  ok(val == 0x682a2a2a, "got %x, expected 0x682a2a2a\n", val);
1772  val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
1773  ok(val == 0x0, "got %x, expected 0x682a2a2a\n", val);
1774  }
1775 
1777 
1778  oldhbitmap = SelectObject(hdc, hbitmap);
1779  pixel = GetPixel(hdc, 5, 5);
1780  expect(0x2a2a2a, pixel);
1781  pixel = GetPixel(hdc, 1, 0);
1782  expect(0x0, pixel);
1783 
1784  SelectObject(hdc, oldhbitmap);
1785 
1786  DeleteDC(hdc);
1787 
1788 
1790  }
1791 
1792  /* create HBITMAP with bkgnd colour */
1793  /* gdiplus.dll 5.1 is broken and only applies the blue value */
1795  expect(Ok, stat);
1796 
1797  if (stat == Ok)
1798  {
1799  ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1800  expect(sizeof(BITMAP), ret);
1801 
1802  expect(0, bm.bmType);
1803  expect(8, bm.bmWidth);
1804  expect(20, bm.bmHeight);
1805  expect(32, bm.bmWidthBytes);
1806  expect(1, bm.bmPlanes);
1807  expect(32, bm.bmBitsPixel);
1808  ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1809 
1810  if (bm.bmBits)
1811  {
1812  DWORD val = *(DWORD*)bm.bmBits;
1813  ok(val == 0x68c12ac1 || broken(val == 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val);
1814  val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
1815  ok(val == 0xff00ff || broken(val == 0xff), "got %x, expected 0xff00ff\n", val);
1816  }
1817 
1819 
1820  oldhbitmap = SelectObject(hdc, hbitmap);
1821  pixel = GetPixel(hdc, 5, 5);
1822  ok(pixel == 0xc12ac1 || broken(pixel == 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel);
1823  pixel = GetPixel(hdc, 1, 0);
1824  ok(pixel == 0xff00ff || broken(pixel == 0xff0000), "got %x, expected 0xff00ff\n", pixel);
1825  pixel = GetPixel(hdc, 2, 0);
1826  ok(pixel == 0xb12ac1 || broken(pixel == 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel);
1827 
1828  SelectObject(hdc, oldhbitmap);
1829  DeleteDC(hdc);
1831  }
1832 
1833  /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
1835  expect(Ok, stat);
1836 
1837  if (stat == Ok)
1838  {
1839  ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
1840  expect(sizeof(BITMAP), ret);
1841 
1842  expect(0, bm.bmType);
1843  expect(8, bm.bmWidth);
1844  expect(20, bm.bmHeight);
1845  expect(32, bm.bmWidthBytes);
1846  expect(1, bm.bmPlanes);
1847  expect(32, bm.bmBitsPixel);
1848  ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
1849 
1850  if (bm.bmBits)
1851  {
1852  DWORD val = *(DWORD*)bm.bmBits;
1853  ok(val == 0x68c12ac1 || broken(val == 0x682a2ac1), "got %x, expected 0x68c12ac1\n", val);
1854  val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
1855  ok(val == 0xff00ff || broken(val == 0xff), "got %x, expected 0xff00ff\n", val);
1856  }
1857 
1859 
1860  oldhbitmap = SelectObject(hdc, hbitmap);
1861  pixel = GetPixel(hdc, 5, 5);
1862  ok(pixel == 0xc12ac1 || broken(pixel == 0xc12a2a), "got %x, expected 0xc12ac1\n", pixel);
1863  pixel = GetPixel(hdc, 1, 0);
1864  ok(pixel == 0xff00ff || broken(pixel == 0xff0000), "got %x, expected 0xff00ff\n", pixel);
1865  pixel = GetPixel(hdc, 2, 0);
1866  ok(pixel == 0xb12ac1 || broken(pixel == 0xb12a2a), "got %x, expected 0xb12ac1\n", pixel);
1867 
1868  SelectObject(hdc, oldhbitmap);
1869  DeleteDC(hdc);
1871  }
1872 
1874  expect(Ok, stat);
1875 
1876  /* create HBITMAP from locked data */
1877  memset(bits, 0x68, 640);
1879  expect(Ok, stat);
1880 
1881  memset(&lockeddata, 0, sizeof(lockeddata));
1883  PixelFormat32bppRGB, &lockeddata);
1884  expect(Ok, stat);
1885  ((DWORD*)lockeddata.Scan0)[0] = 0xff242424;
1887  expect(Ok, stat);
1888  stat = GdipBitmapUnlockBits(bitmap, &lockeddata);
1889  expect(Ok, stat);
1891  expect(Ok, stat);
1892 
1894  oldhbitmap = SelectObject(hdc, hbitmap);
1895  pixel = GetPixel(hdc, 0, 0);
1896  expect(0x686868, pixel);
1897  SelectObject(hdc, oldhbitmap);
1898  DeleteDC(hdc);
1899 }
1900 
1901 static void test_getthumbnail(void)
1902 {
1903  GpStatus stat;
1904  GpImage *bitmap1, *bitmap2;
1905  UINT width, height;
1906 
1909 
1910  stat = GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1911  expect(Ok, stat);
1912 
1913  stat = GdipGetImageThumbnail(bitmap1, 0, 0, NULL, NULL, NULL);
1915 
1916  stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1917  expect(Ok, stat);
1918 
1919  if (stat == Ok)
1920  {
1922  expect(Ok, stat);
1923  expect(120, width);
1924 
1926  expect(Ok, stat);
1927  expect(120, height);
1928 
1930  }
1931 
1932  GdipDisposeImage(bitmap1);
1933 
1934 
1935  stat = GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
1936  expect(Ok, stat);
1937 
1938  stat = GdipGetImageThumbnail(bitmap1, 32, 32, &bitmap2, NULL, NULL);
1939  expect(Ok, stat);
1940 
1941  if (stat == Ok)
1942  {
1944  expect(Ok, stat);
1945  expect(32, width);
1946 
1948  expect(Ok, stat);
1949  expect(32, height);
1950 
1952  }
1953 
1954  stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
1955  expect(Ok, stat);
1956 
1957  if (stat == Ok)
1958  {
1960  expect(Ok, stat);
1961  expect(120, width);
1962 
1964  expect(Ok, stat);
1965  expect(120, height);
1966 
1968  }
1969 
1970  GdipDisposeImage(bitmap1);
1971 }
1972 
1973 static void test_getsetpixel(void)
1974 {
1975  GpStatus stat;
1976  GpBitmap *bitmap;
1977  ARGB color;
1978  BYTE bits[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
1979  0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
1980 
1982  expect(Ok, stat);
1983 
1984  /* null parameters */
1985  stat = GdipBitmapGetPixel(NULL, 1, 1, &color);
1987 
1988  stat = GdipBitmapGetPixel(bitmap, 1, 1, NULL);
1990 
1991  stat = GdipBitmapSetPixel(NULL, 1, 1, 0);
1993 
1994  /* out of bounds */
1995  stat = GdipBitmapGetPixel(bitmap, -1, 1, &color);
1997 
1998  stat = GdipBitmapSetPixel(bitmap, -1, 1, 0);
2000 
2001  stat = GdipBitmapGetPixel(bitmap, 1, -1, &color);
2002  ok(stat == InvalidParameter ||
2003  broken(stat == Ok), /* Older gdiplus */
2004  "Expected InvalidParameter, got %.8x\n", stat);
2005 
2006 if (0) /* crashes some gdiplus implementations */
2007 {
2008  stat = GdipBitmapSetPixel(bitmap, 1, -1, 0);
2009  ok(stat == InvalidParameter ||
2010  broken(stat == Ok), /* Older gdiplus */
2011  "Expected InvalidParameter, got %.8x\n", stat);
2012 }
2013 
2014  stat = GdipBitmapGetPixel(bitmap, 2, 1, &color);
2016 
2017  stat = GdipBitmapSetPixel(bitmap, 2, 1, 0);
2019 
2020  stat = GdipBitmapGetPixel(bitmap, 1, 2, &color);
2022 
2023  stat = GdipBitmapSetPixel(bitmap, 1, 2, 0);
2025 
2026  /* valid use */
2027  stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
2028  expect(Ok, stat);
2029  expect(0xffffffff, color);
2030 
2031  stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2032  expect(Ok, stat);
2033  expect(0xff0000ff, color);
2034 
2035  stat = GdipBitmapSetPixel(bitmap, 1, 1, 0xff676869);
2036  expect(Ok, stat);
2037 
2038  stat = GdipBitmapSetPixel(bitmap, 0, 0, 0xff474849);
2039  expect(Ok, stat);
2040 
2041  stat = GdipBitmapGetPixel(bitmap, 1, 1, &color);
2042  expect(Ok, stat);
2043  expect(0xff676869, color);
2044 
2045  stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
2046  expect(Ok, stat);
2047  expect(0xff474849, color);
2048 
2050  expect(Ok, stat);
2051 }
2052 
2054 {
2055  static const BYTE halftone_values[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
2056  UINT i;
2057 
2058  for (i=0; i<palette->Count; i++)
2059  {
2060  ARGB expected=0xff000000;
2061  if (i<8)
2062  {
2063  if (i&1) expected |= 0x800000;
2064  if (i&2) expected |= 0x8000;
2065  if (i&4) expected |= 0x80;
2066  }
2067  else if (i == 8)
2068  {
2069  expected = 0xffc0c0c0;
2070  }
2071  else if (i < 16)
2072  {
2073  if (i&1) expected |= 0xff0000;
2074  if (i&2) expected |= 0xff00;
2075  if (i&4) expected |= 0xff;
2076  }
2077  else if (i < 40)
2078  {
2079  expected = 0x00000000;
2080  }
2081  else
2082  {
2083  expected |= halftone_values[(i-40)%6];
2084  expected |= halftone_values[((i-40)/6)%6] << 8;
2085  expected |= halftone_values[((i-40)/36)%6] << 16;
2086  }
2087  ok(expected == palette->Entries[i], "Expected %.8x, got %.8x, i=%u/%u\n",
2088  expected, palette->Entries[i], i, palette->Count);
2089  }
2090 }
2091 
2092 static void test_palette(void)
2093 {
2094  GpStatus stat;
2095  GpBitmap *bitmap;
2096  INT size;
2097  BYTE buffer[1040];
2099  ARGB *entries = palette->Entries;
2100  ARGB color=0;
2101 
2102  /* test initial palette from non-indexed bitmap */
2104  expect(Ok, stat);
2105 
2107  expect(Ok, stat);
2108  expect(sizeof(UINT)*2+sizeof(ARGB), size);
2109 
2111  expect(Ok, stat);
2112  expect(0, palette->Count);
2113 
2114  /* test setting palette on not-indexed bitmap */
2115  palette->Count = 3;
2116 
2118  expect(Ok, stat);
2119 
2121  expect(Ok, stat);
2122  expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
2123 
2125  expect(Ok, stat);
2126  expect(3, palette->Count);
2127 
2129 
2130  /* test initial palette on 1-bit bitmap */
2132  expect(Ok, stat);
2133 
2135  expect(Ok, stat);
2136  expect(sizeof(UINT)*2+sizeof(ARGB)*2, size);
2137 
2139  expect(Ok, stat);
2141  expect(2, palette->Count);
2142 
2143  expect(0xff000000, entries[0]);
2144  expect(0xffffffff, entries[1]);
2145 
2146  /* test getting/setting pixels */
2147  stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
2148  expect(Ok, stat);
2149  expect(0xff000000, color);
2150 
2151  stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffffffff);
2152  ok((stat == Ok) ||
2153  broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2154 
2155  if (stat == Ok)
2156  {
2157  stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2158  expect(Ok, stat);
2159  expect(0xffffffff, color);
2160  }
2161 
2163 
2164  /* test initial palette on 4-bit bitmap */
2166  expect(Ok, stat);
2167 
2169  expect(Ok, stat);
2170  expect(sizeof(UINT)*2+sizeof(ARGB)*16, size);
2171 
2173  expect(Ok, stat);
2174  expect(0, palette->Flags);
2175  expect(16, palette->Count);
2176 
2178 
2179  /* test getting/setting pixels */
2180  stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
2181  expect(Ok, stat);
2182  expect(0xff000000, color);
2183 
2184  stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffff00ff);
2185  ok((stat == Ok) ||
2186  broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2187 
2188  if (stat == Ok)
2189  {
2190  stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2191  expect(Ok, stat);
2192  expect(0xffff00ff, color);
2193  }
2194 
2196 
2197  /* test initial palette on 8-bit bitmap */
2199  expect(Ok, stat);
2200 
2202  expect(Ok, stat);
2203  expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
2204 
2206  expect(Ok, stat);
2208  expect(256, palette->Count);
2209 
2211 
2212  /* test getting/setting pixels */
2213  stat = GdipBitmapGetPixel(bitmap, 0, 0, &color);
2214  expect(Ok, stat);
2215  expect(0xff000000, color);
2216 
2217  stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffcccccc);
2218  ok((stat == Ok) ||
2219  broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2220 
2221  if (stat == Ok)
2222  {
2223  stat = GdipBitmapGetPixel(bitmap, 0, 1, &color);
2224  expect(Ok, stat);
2225  expect(0xffcccccc, color);
2226  }
2227 
2228  /* test setting/getting a different palette */
2229  entries[1] = 0xffcccccc;
2230 
2232  expect(Ok, stat);
2233 
2234  entries[1] = 0;
2235 
2237  expect(Ok, stat);
2238  expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
2239 
2241  expect(Ok, stat);
2243  expect(256, palette->Count);
2244  expect(0xffcccccc, entries[1]);
2245 
2246  /* test count < 256 */
2247  palette->Flags = 12345;
2248  palette->Count = 3;
2249 
2251  expect(Ok, stat);
2252 
2253  entries[1] = 0;
2254  entries[3] = 0xdeadbeef;
2255 
2257  expect(Ok, stat);
2258  expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
2259 
2261  expect(Ok, stat);
2262  expect(12345, palette->Flags);
2263  expect(3, palette->Count);
2264  expect(0xffcccccc, entries[1]);
2265  expect(0xdeadbeef, entries[3]);
2266 
2267  /* test count > 256 */
2268  palette->Count = 257;
2269 
2271  ok(stat == InvalidParameter ||
2272  broken(stat == Ok), /* Old gdiplus behavior */
2273  "Expected %.8x, got %.8x\n", InvalidParameter, stat);
2274 
2276 }
2277 
2278 static void test_colormatrix(void)
2279 {
2280  GpStatus stat;
2281  ColorMatrix colormatrix, graymatrix;
2282  GpImageAttributes *imageattr;
2283  const ColorMatrix identity = {{
2284  {1.0,0.0,0.0,0.0,0.0},
2285  {0.0,1.0,0.0,0.0,0.0},
2286  {0.0,0.0,1.0,0.0,0.0},
2287  {0.0,0.0,0.0,1.0,0.0},
2288  {0.0,0.0,0.0,0.0,1.0}}};
2289  const ColorMatrix double_red = {{
2290  {2.0,0.0,0.0,0.0,0.0},
2291  {0.0,1.0,0.0,0.0,0.0},
2292  {0.0,0.0,1.0,0.0,0.0},
2293  {0.0,0.0,0.0,1.0,0.0},
2294  {0.0,0.0,0.0,0.0,1.0}}};
2295  const ColorMatrix asymmetric = {{
2296  {0.0,1.0,0.0,0.0,0.0},
2297  {0.0,0.0,1.0,0.0,0.0},
2298  {0.0,0.0,0.0,1.0,0.0},
2299  {1.0,0.0,0.0,0.0,0.0},
2300  {0.0,0.0,0.0,0.0,1.0}}};
2301  GpBitmap *bitmap1, *bitmap2;
2302  GpGraphics *graphics;
2303  ARGB color;
2304 
2305  colormatrix = identity;
2306  graymatrix = identity;
2307 
2309  TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2311 
2312  stat = GdipCreateImageAttributes(&imageattr);
2313  expect(Ok, stat);
2314 
2316  TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2317  expect(Ok, stat);
2318 
2322 
2324  TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2325  expect(Ok, stat);
2326 
2328  TRUE, &colormatrix, NULL, ColorMatrixFlagsSkipGrays);
2329  expect(Ok, stat);
2330 
2332  TRUE, &colormatrix, NULL, ColorMatrixFlagsAltGray);
2334 
2336  TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsAltGray);
2337  expect(Ok, stat);
2338 
2340  TRUE, &colormatrix, &graymatrix, 3);
2342 
2344  TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2346 
2348  TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2350 
2353  expect(Ok, stat);
2354 
2355  /* Drawing a bitmap transforms the colors */
2356  colormatrix = double_red;
2358  TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2359  expect(Ok, stat);
2360 
2362  expect(Ok, stat);
2363 
2365  expect(Ok, stat);
2366 
2367  stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff40ccee);
2368  expect(Ok, stat);
2369 
2371  expect(Ok, stat);
2372 
2373  stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2374  UnitPixel, imageattr, NULL, NULL);
2375  expect(Ok, stat);
2376 
2377  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2378  expect(Ok, stat);
2379  expect(0xff80ccee, color);
2380 
2381  colormatrix = asymmetric;
2383  TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2384  expect(Ok, stat);
2385 
2386  stat = GdipBitmapSetPixel(bitmap2, 0, 0, 0);
2387  expect(Ok, stat);
2388 
2389  stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2390  UnitPixel, imageattr, NULL, NULL);
2391  expect(Ok, stat);
2392 
2393  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2394  expect(Ok, stat);
2395  ok(color_match(0xeeff40cc, color, 3), "expected 0xeeff40cc, got 0x%08x\n", color);
2396 
2397  /* Toggle NoOp */
2399  expect(Ok, stat);
2400 
2401  stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2402  UnitPixel, imageattr, NULL, NULL);
2403  expect(Ok, stat);
2404 
2405  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2406  expect(Ok, stat);
2407  ok(color_match(0xfefe40cc, color, 3), "expected 0xfefe40cc, got 0x%08x\n", color);
2408 
2410  expect(Ok, stat);
2411 
2412  stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2413  UnitPixel, imageattr, NULL, NULL);
2414  expect(Ok, stat);
2415 
2416  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2417  expect(Ok, stat);
2418  ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color);
2419 
2421  expect(Ok, stat);
2422 
2424  expect(Ok, stat);
2425 
2426  stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2427  UnitPixel, imageattr, NULL, NULL);
2428  expect(Ok, stat);
2429 
2430  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2431  expect(Ok, stat);
2432  ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color);
2433 
2434  stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2435  UnitPixel, imageattr, NULL, NULL);
2436  expect(Ok, stat);
2437 
2438  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2439  expect(Ok, stat);
2440  ok(color_match(0xff40ccee, color, 1), "Expected ff40ccee, got %.8x\n", color);
2441 
2442  /* Disable adjustment, toggle NoOp */
2444  FALSE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2445  expect(Ok, stat);
2446 
2448  expect(Ok, stat);
2449 
2450  stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2451  UnitPixel, imageattr, NULL, NULL);
2452  expect(Ok, stat);
2453 
2454  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2455  expect(Ok, stat);
2456  ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color);
2457 
2459  expect(Ok, stat);
2460 
2461  stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2462  UnitPixel, imageattr, NULL, NULL);
2463  expect(Ok, stat);
2464 
2465  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2466  expect(Ok, stat);
2467  ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color);
2468 
2469  /* Reset with NoOp on, enable adjustment. */
2471  expect(Ok, stat);
2472 
2474  TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2475  expect(Ok, stat);
2476 
2477  stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2478  UnitPixel, imageattr, NULL, NULL);
2479  expect(Ok, stat);
2480 
2481  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2482  expect(Ok, stat);
2483  ok(color_match(0xfff24ace, color, 3), "expected 0xfff24ace, got 0x%08x\n", color);
2484 
2485  /* Now inhibit specific category. */
2487  expect(Ok, stat);
2488 
2490  TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2491  expect(Ok, stat);
2492 
2493  stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2494  UnitPixel, imageattr, NULL, NULL);
2495  expect(Ok, stat);
2496 
2497  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2498  expect(Ok, stat);
2499  ok(color_match(0xfffe41cc, color, 3), "expected 0xfffe41cc, got 0x%08x\n", color);
2500 
2502  expect(Ok, stat);
2503 
2504  stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2505  UnitPixel, imageattr, NULL, NULL);
2506  expect(Ok, stat);
2507 
2508  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2509  expect(Ok, stat);
2510  ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color);
2511 
2513  expect(Ok, stat);
2514 
2516  expect(Ok, stat);
2517 
2518  stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2519  UnitPixel, imageattr, NULL, NULL);
2520  expect(Ok, stat);
2521 
2522  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2523  expect(Ok, stat);
2524  ok(color_match(0xfff24ace, color, 3), "expected 0xfff24ace, got 0x%08x\n", color);
2525 
2527  expect(Ok, stat);
2528 
2529  stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2530  UnitPixel, imageattr, NULL, NULL);
2531  expect(Ok, stat);
2532 
2533  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2534  expect(Ok, stat);
2535  ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08x\n", color);
2536 
2537  GdipDeleteGraphics(graphics);
2538  GdipDisposeImage((GpImage*)bitmap1);
2540  GdipDisposeImageAttributes(imageattr);
2541 }
2542 
2543 static void test_gamma(void)
2544 {
2545  GpStatus stat;
2546  GpImageAttributes *imageattr;
2547  GpBitmap *bitmap1, *bitmap2;
2548  GpGraphics *graphics;
2549  ARGB color;
2550 
2553 
2554  stat = GdipCreateImageAttributes(&imageattr);
2555  expect(Ok, stat);
2556 
2558  expect(Ok, stat);
2559 
2562 
2565 
2568 
2570  expect(Ok, stat);
2571 
2573  expect(Ok, stat);
2574 
2575  /* Drawing a bitmap transforms the colors */
2577  expect(Ok, stat);
2578 
2579  stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
2580  expect(Ok, stat);
2581 
2583  expect(Ok, stat);
2584 
2585  stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff80ffff);
2586  expect(Ok, stat);
2587 
2589  expect(Ok, stat);
2590 
2591  stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2592  UnitPixel, imageattr, NULL, NULL);
2593  expect(Ok, stat);
2594 
2595  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2596  expect(Ok, stat);
2597  ok(color_match(0xff20ffff, color, 1), "Expected ff20ffff, got %.8x\n", color);
2598 
2600  expect(Ok, stat);
2601 
2602  stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2603  UnitPixel, imageattr, NULL, NULL);
2604  expect(Ok, stat);
2605 
2606  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
2607  expect(Ok, stat);
2608  ok(color_match(0xff80ffff, color, 1), "Expected ff80ffff, got %.8x\n", color);
2609 
2610  GdipDeleteGraphics(graphics);
2611  GdipDisposeImage((GpImage*)bitmap1);
2613  GdipDisposeImageAttributes(imageattr);
2614 }
2615 
2616 /* 1x1 pixel gif, 2 frames; first frame is white, second is black */
2617 static const unsigned char gifanimation[72] = {
2618 0x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
2619 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
2620 0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
2621 0x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
2622 0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
2623 };
2624 
2625 /* Generated with ImageMagick:
2626  * convert -transparent black -delay 100 -size 8x2 xc:black \
2627  * -dispose none -page +0+0 -size 2x2 xc:red \
2628  * -dispose background -page +2+0 -size 2x2 xc:blue \
2629  * -dispose previous -page +4+0 -size 2x2 xc:green \
2630  * -dispose undefined -page +6+0 -size 2x2 xc:gray \
2631  * test.gif
2632  */
2633 static const unsigned char gifanimation2[] = {
2634  0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
2635  0x02, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
2636  0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
2637  0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
2638  0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
2639  0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
2640  0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
2641  0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
2642  0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
2643  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2644  0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
2645  0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
2646  0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
2647  0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
2648  0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
2649  0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
2650  0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
2651  0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
2652  0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
2653  0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
2654  0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
2655  0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
2656  0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
2657  0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
2658  0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
2659  0x3b
2660 };
2661 
2662 static ARGB gifanimation2_pixels[5][4] = {
2663  {0, 0, 0, 0},
2664  {0xffff0000, 0, 0, 0},
2665  {0xffff0000, 0xff0000ff, 0, 0},
2666  {0xffff0000, 0, 0xff008000, 0},
2667  {0xffff0000, 0, 0, 0xff7e7e7e}
2668 };
2669 
2670 static void test_multiframegif(void)
2671 {
2672  LPSTREAM stream;
2673  HGLOBAL hglob;
2674  LPBYTE data;
2675  HRESULT hres;
2676  GpStatus stat;
2677  GpBitmap *bmp;
2678  ARGB color;
2679  UINT count;
2680  GUID dimension;
2682  INT palette_size, i, j;
2683  char palette_buf[256];
2685  ARGB *palette_entries;
2686 
2687  /* Test frame functions with an animated GIF */
2688  hglob = GlobalAlloc (0, sizeof(gifanimation));
2689  data = GlobalLock (hglob);
2690  memcpy(data, gifanimation, sizeof(gifanimation));
2691  GlobalUnlock(hglob);
2692 
2693  hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2694  ok(hres == S_OK, "Failed to create a stream\n");
2695  if(hres != S_OK) return;
2696 
2698  ok(stat == Ok, "Failed to create a Bitmap\n");
2699  if(stat != Ok){
2700  IStream_Release(stream);
2701  return;
2702  }
2703 
2705  expect(Ok, stat);
2707 
2709  expect(Ok, stat);
2710  ok(palette_size == sizeof(ColorPalette) ||
2711  broken(palette_size == sizeof(ColorPalette)+sizeof(ARGB[3])),
2712  "palette_size = %d\n", palette_size);
2713 
2714  /* Bitmap starts at frame 0 */
2715  color = 0xdeadbeef;
2716  stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2717  expect(Ok, stat);
2718  expect(0xffffffff, color);
2719 
2720  /* Check that we get correct metadata */
2722  expect(Ok, stat);
2723  expect(1, count);
2724 
2725  stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
2726  expect(Ok, stat);
2727  expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2728 
2729  count = 12345;
2730  stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2731  expect(Ok, stat);
2732  expect(2, count);
2733 
2734  /* SelectActiveFrame overwrites our current data */
2735  stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
2736  expect(Ok, stat);
2737 
2738  color = 0xdeadbeef;
2739  stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2740  expect(Ok, stat);
2741  expect(0xff000000, color);
2742 
2743  stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2744  expect(Ok, stat);
2745 
2746  color = 0xdeadbeef;
2747  stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2748  expect(Ok, stat);
2749  expect(0xffffffff, color);
2750 
2751  /* Write over the image data */
2752  stat = GdipBitmapSetPixel(bmp, 0, 0, 0xff000000);
2753  expect(Ok, stat);
2754 
2755  /* Switching to the same frame does not overwrite our changes */
2756  stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2757  expect(Ok, stat);
2758 
2759  stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2760  expect(Ok, stat);
2761  expect(0xff000000, color);
2762 
2763  /* But switching to another frame and back does */
2764  stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
2765  expect(Ok, stat);
2766 
2767  stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
2768  expect(Ok, stat);
2769 
2770  stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2771  expect(Ok, stat);
2772  expect(0xffffffff, color);
2773 
2774  /* rotate/flip discards the information about other frames */
2776  expect(Ok, stat);
2777 
2778  count = 12345;
2779  stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2780  expect(Ok, stat);
2781  expect(1, count);
2782 
2783  expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bmp, __LINE__, FALSE);
2784 
2786  IStream_Release(stream);
2787 
2788  /* Test with a non-animated gif */
2789  hglob = GlobalAlloc (0, sizeof(gifimage));
2790  data = GlobalLock (hglob);
2791  memcpy(data, gifimage, sizeof(gifimage));
2792  GlobalUnlock(hglob);
2793 
2794  hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2795  ok(hres == S_OK, "Failed to create a stream\n");
2796  if(hres != S_OK) return;
2797 
2799  ok(stat == Ok, "Failed to create a Bitmap\n");
2800  if(stat != Ok){
2801  IStream_Release(stream);
2802  return;
2803  }
2804 
2806  expect(Ok, stat);
2808 
2809  /* Check metadata */
2811  expect(Ok, stat);
2812  expect(1, count);
2813 
2814  stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
2815  expect(Ok, stat);
2816  expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2817 
2818  count = 12345;
2819  stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2820  expect(Ok, stat);
2821  expect(1, count);
2822 
2824  IStream_Release(stream);
2825 
2826  /* Test with a non-animated transparent gif */
2827  hglob = GlobalAlloc (0, sizeof(transparentgif));
2828  data = GlobalLock (hglob);
2830  GlobalUnlock(hglob);
2831 
2832  hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2833  ok(hres == S_OK, "Failed to create a stream\n");
2834 
2836  IStream_Release(stream);
2837  ok(stat == Ok, "Failed to create a Bitmap\n");
2838 
2840  expect(Ok, stat);
2842 
2843  stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2844  expect(Ok, stat);
2845  expect(0, color);
2846 
2848  expect(Ok, stat);
2849  ok(palette_size == sizeof(ColorPalette)+sizeof(ARGB),
2850  "palette_size = %d\n", palette_size);
2851 
2852  memset(palette_buf, 0xfe, sizeof(palette_buf));
2853  palette = (ColorPalette*)palette_buf;
2855  sizeof(ColorPalette)+sizeof(ARGB));
2856  palette_entries = palette->Entries;
2857  expect(Ok, stat);
2859  expect(2, palette->Count);
2860  expect(0, palette_entries[0]);
2861  expect(0xff000000, palette_entries[1]);
2862 
2863  count = 12345;
2864  stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2865  expect(Ok, stat);
2866  expect(1, count);
2867 
2869 
2870  /* Test frame dispose methods */
2871  hglob = GlobalAlloc (0, sizeof(gifanimation2));
2872  data = GlobalLock (hglob);
2874  GlobalUnlock(hglob);
2875 
2876  hres = CreateStreamOnHGlobal(hglob, TRUE, &stream);
2877  ok(hres == S_OK, "Failed to create a stream\n");
2878 
2880  ok(stat == Ok, "Failed to create a Bitmap\n");
2881  IStream_Release(stream);
2882 
2883  stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
2884  expect(Ok, stat);
2885  expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
2886 
2887  stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
2888  expect(Ok, stat);
2889  expect(5, count);
2890 
2891  stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
2892  expect(Ok, stat);
2893  expect(0, color);
2894 
2895  stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 3);
2896  expect(Ok, stat);
2897  stat = GdipBitmapGetPixel(bmp, 2, 0, &color);
2898  expect(Ok, stat);
2899  ok(color==0 || broken(color==0xff0000ff), "color = %x\n", color);
2900  if(color != 0) {
2901  win_skip("broken animated gif support\n");
2903  return;
2904  }
2905 
2906  for(i=0; i<6; i++) {
2907  stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, i%5);
2908  expect(Ok, stat);
2909 
2910  for(j=0; j<4; j++) {
2911  stat = GdipBitmapGetPixel(bmp, j*2, 0, &color);
2912  expect(Ok, stat);
2913  ok(gifanimation2_pixels[i%5][j] == color, "at %d,%d got %x, expected %x\n", i, j, color, gifanimation2_pixels[i%5][j]);
2914  }
2915  }
2916 
2918 }
2919 
2920 static void test_rotateflip(void)
2921 {
2922  GpImage *bitmap;
2923  GpStatus stat;
2924  BYTE bits[24];
2925  static const BYTE orig_bits[24] = {
2926  0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
2927  0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
2928  UINT width, height;
2929  ARGB color;
2930 
2931  memcpy(bits, orig_bits, sizeof(bits));
2933  expect(Ok, stat);
2934 
2936  expect(Ok, stat);
2937 
2939  expect(Ok, stat);
2941  expect(Ok, stat);
2942  expect(2, width);
2943  expect(3, height);
2944 
2946  expect(Ok, stat);
2947  expect(0xff00ffff, color);
2948 
2950  expect(Ok, stat);
2951  expect(0xffff0000, color);
2952 
2954  expect(Ok, stat);
2955  expect(0xffffff00, color);
2956 
2958  expect(Ok, stat);
2959  expect(0xff0000ff, color);
2960 
2961  expect(0, bits[0]);
2962  expect(0, bits[1]);
2963  expect(0xff, bits[2]);
2964 
2966 
2967  memcpy(bits, orig_bits, sizeof(bits));
2969  expect(Ok, stat);
2970 
2972  expect(Ok, stat);
2973 
2975  expect(Ok, stat);
2977  expect(Ok, stat);
2978  expect(3, width);
2979  expect(2, height);
2980 
2982  expect(Ok, stat);
2983  expect(0xff0000ff, color);
2984 
2986  expect(Ok, stat);
2987  expect(0xffff0000, color);
2988 
2990  expect(Ok, stat);
2991  expect(0xffffff00, color);
2992 
2994  expect(Ok, stat);
2995  expect(0xff00ffff, color);
2996 
2997  expect(0, bits[0]);
2998  expect(0, bits[1]);
2999  expect(0xff, bits[2]);
3000 
3002 
3003  memcpy(bits, orig_bits, sizeof(bits));
3005  expect(Ok, stat);
3006 
3008  expect(Ok, stat);
3009 
3011  expect(Ok, stat);
3013  expect(Ok, stat);
3014  expect(3, width);
3015  expect(2, height);
3016 
3018  expect(Ok, stat);
3019  expect(0xff00ffff, color);
3020 
3022  expect(Ok, stat);
3023  expect(0xffffff00, color);
3024 
3026  expect(Ok, stat);
3027  expect(0xffff0000, color);
3028 
3030  expect(Ok, stat);
3031  expect(0xff0000ff, color);
3032 
3033  expect(0, bits[0]);
3034  expect(0, bits[1]);
3035  expect(0xff, bits[2]);
3036 
3038 }
3039 
3040 static void test_remaptable(void)
3041 {
3042  GpStatus stat;
3043  GpImageAttributes *imageattr;
3044  GpBitmap *bitmap1, *bitmap2;
3045  GpGraphics *graphics;
3046  ARGB color;
3047  ColorMap *map;
3048 
3049  map = GdipAlloc(sizeof(ColorMap));
3050 
3051  map->oldColor.Argb = 0xff00ff00;
3052  map->newColor.Argb = 0xffff00ff;
3053 
3056 
3057  stat = GdipCreateImageAttributes(&imageattr);
3058  expect(Ok, stat);
3059 
3062 
3065 
3068 
3071 
3073  expect(Ok, stat);
3074 
3076  expect(Ok, stat);
3077 
3078  stat = GdipCreateBitmapFromScan0(1, 1, 0, PixelFormat32bppRGB, NULL, &bitmap1);
3079  expect(Ok, stat);
3080 
3082  expect(Ok, stat);
3083 
3084  stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff00ff00);
3085  expect(Ok, stat);
3086 
3088  expect(Ok, stat);
3089 
3090  stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
3091  UnitPixel, imageattr, NULL, NULL);
3092  expect(Ok, stat);
3093 
3094  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
3095  expect(Ok, stat);
3096  ok(color_match(0xffff00ff, color, 1), "Expected ffff00ff, got %.8x\n", color);
3097 
3099  expect(Ok, stat);
3100 
3101  stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
3102  UnitPixel, imageattr, NULL, NULL);
3103  expect(Ok, stat);
3104 
3105  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
3106  expect(Ok, stat);
3107  ok(color_match(0xff00ff00, color, 1), "Expected ff00ff00, got %.8x\n", color);
3108 
3109  GdipDeleteGraphics(graphics);
3110  GdipDisposeImage((GpImage*)bitmap1);
3112  GdipDisposeImageAttributes(imageattr);
3113  GdipFree(map);
3114 }
3115 
3116 static void test_colorkey(void)
3117 {
3118  GpStatus stat;
3119  GpImageAttributes *imageattr;
3120  GpBitmap *bitmap1, *bitmap2;
3121  GpGraphics *graphics;
3122  ARGB color;
3123 
3126 
3127  stat = GdipCreateImageAttributes(&imageattr);
3128  expect(Ok, stat);
3129 
3130  stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeCount, TRUE, 0xff405060, 0xff708090);
3132 
3133  stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeAny, TRUE, 0xff405060, 0xff708090);
3135 
3136  stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
3137  expect(Ok, stat);
3138 
3140  expect(Ok, stat);
3141 
3143  expect(Ok, stat);
3144 
3145  stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0x20405060);
3146  expect(Ok, stat);
3147 
3148  stat = GdipBitmapSetPixel(bitmap1, 0, 1, 0x40506070);
3149  expect(Ok, stat);
3150 
3151  stat = GdipBitmapSetPixel(bitmap1, 1, 0, 0x60708090);
3152  expect(Ok, stat);
3153 
3154  stat = GdipBitmapSetPixel(bitmap1, 1, 1, 0xffffffff);
3155  expect(Ok, stat);
3156 
3158  expect(Ok, stat);
3159 
3160  stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2,
3161  UnitPixel, imageattr, NULL, NULL);
3162  expect(Ok, stat);
3163 
3164  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
3165  expect(Ok, stat);
3166  ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8x\n", color);
3167 
3168  stat = GdipBitmapGetPixel(bitmap2, 0, 1, &color);
3169  expect(Ok, stat);
3170  ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8x\n", color);
3171 
3172  stat = GdipBitmapGetPixel(bitmap2, 1, 0, &color);
3173  expect(Ok, stat);
3174  ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8x\n", color);
3175 
3176  stat = GdipBitmapGetPixel(bitmap2, 1, 1, &color);
3177  expect(Ok, stat);
3178  ok(color_match(0xffffffff, color, 1), "Expected ffffffff, got %.8x\n", color);
3179 
3181  expect(Ok, stat);
3182 
3183  stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2,
3184  UnitPixel, imageattr, NULL, NULL);
3185  expect(Ok, stat);
3186 
3187  stat = GdipBitmapGetPixel(bitmap2, 0, 0, &color);
3188  expect(Ok, stat);
3189  ok(color_match(0x20405060, color, 1), "Expected 20405060, got %.8x\n", color);
3190 
3191  stat = GdipBitmapGetPixel(bitmap2, 0, 1, &color);
3192  expect(Ok, stat);
3193  ok(color_match(0x40506070, color, 1), "Expected 40506070, got %.8x\n", color);
3194 
3195  stat = GdipBitmapGetPixel(bitmap2, 1, 0, &color);
3196  expect(Ok, stat);
3197  ok(color_match(0x60708090, color, 1), "Expected 60708090, got %.8x\n", color);
3198 
3199  stat = GdipBitmapGetPixel(bitmap2, 1, 1, &color);
3200  expect(Ok, stat);
3201  ok(color_match(0xffffffff, color, 1), "Expected ffffffff, got %.8x\n", color);
3202 
3203 
3204  GdipDeleteGraphics(graphics);
3205  GdipDisposeImage((GpImage*)bitmap1);
3207  GdipDisposeImageAttributes(imageattr);
3208 }
3209 
3210 static void test_dispose(void)
3211 {
3212  GpStatus stat;
3213  GpImage *image;
3214  char invalid_image[256];
3215 
3218 
3220  expect(Ok, stat);
3221 
3223  expect(Ok, stat);
3224 
3227 
3228  memset(invalid_image, 0, 256);
3229  stat = GdipDisposeImage((GpImage*)invalid_image);
3231 }
3232 
3233 static LONG obj_refcount(void *obj)
3234 {
3235  IUnknown_AddRef((IUnknown *)obj);
3236  return IUnknown_Release((IUnknown *)obj);
3237 }
3238 
3239 static GpImage *load_image(const BYTE *image_data, UINT image_size, BOOL valid_data, BOOL todo_load)
3240 {
3241  IStream *stream;
3242  HGLOBAL hmem;
3243  BYTE *data;
3244  HRESULT hr;
3245  GpStatus status;
3246  GpImage *image = NULL, *clone;
3247  ImageType image_type;
3248  LONG refcount, old_refcount;
3249 
3250  hmem = GlobalAlloc(0, image_size);
3251  data = GlobalLock(hmem);
3252  memcpy(data, image_data, image_size);
3253  GlobalUnlock(hmem);
3254 
3255  hr = CreateStreamOnHGlobal(hmem, TRUE, &stream);
3256  ok(hr == S_OK, "CreateStreamOnHGlobal error %#x\n", hr);
3257  if (hr != S_OK) return NULL;
3258 
3259  refcount = obj_refcount(stream);
3260  ok(refcount == 1, "expected stream refcount 1, got %d\n", refcount);
3261 
3263  todo_wine_if(todo_load)
3264  if (valid_data)
3265  ok(status == Ok || broken(status == InvalidParameter), /* XP */
3266  "GdipLoadImageFromStream error %d\n", status);
3267  else
3268  ok(status != Ok, "GdipLoadImageFromStream should fail\n");
3269  if (status != Ok)
3270  {
3271  IStream_Release(stream);
3272  return NULL;
3273  }
3274 
3275  status = GdipGetImageType(image, &image_type);
3276  ok(status == Ok, "GdipGetImageType error %d\n", status);
3277 
3278  refcount = obj_refcount(stream);
3279  if (image_type == ImageTypeBitmap)
3280  ok(refcount > 1, "expected stream refcount > 1, got %d\n", refcount);
3281  else
3282  ok(refcount == 1, "expected stream refcount 1, got %d\n", refcount);
3283  old_refcount = refcount;
3284 
3285  status = GdipCloneImage(image, &clone);
3286  ok(status == Ok, "GdipCloneImage error %d\n", status);
3287  refcount = obj_refcount(stream);
3288  ok(refcount == old_refcount, "expected stream refcount %d, got %d\n", old_refcount, refcount);
3289  status = GdipDisposeImage(clone);
3290  ok(status == Ok, "GdipDisposeImage error %d\n", status);
3291  refcount = obj_refcount(stream);
3292  ok(refcount == old_refcount, "expected stream refcount %d, got %d\n", old_refcount, refcount);
3293 
3294  refcount = IStream_Release(stream);
3295  if (image_type == ImageTypeBitmap)
3296  ok(refcount >= 1, "expected stream refcount != 0\n");
3297  else
3298  ok(refcount == 0, "expected stream refcount 0, got %d\n", refcount);
3299 
3300  return image;
3301 }
3302 
3303 static void test_image_properties(void)
3304 {
3305  static const struct test_data
3306  {
3307  const BYTE *image_data;
3308  UINT image_size;
3309  ImageType image_type;
3310  UINT prop_count;
3311  UINT prop_count2; /* if win7 behaves differently */
3312  /* 1st property attributes */
3313  UINT prop_size;
3314  UINT prop_size2; /* if win7 behaves differently */
3315  UINT prop_id;
3316  UINT prop_id2; /* if win7 behaves differently */
3317  }
3318  td[] =
3319  {
3320  { pngimage, sizeof(pngimage), ImageTypeBitmap, 4, ~0, 1, 20, 0x5110, 0x132 },
3321  { jpgimage, sizeof(jpgimage), ImageTypeBitmap, 2, ~0, 128, 0, 0x5090, 0x5091 },
3322  { tiffimage, sizeof(tiffimage), ImageTypeBitmap, 16, 0, 4, 0, 0xfe, 0 },
3323  { bmpimage, sizeof(bmpimage), ImageTypeBitmap, 0, 0, 0, 0, 0, 0 },
3324  { wmfimage, sizeof(wmfimage), ImageTypeMetafile, 0, 0, 0, 0, 0, 0 }
3325  };
3326  GpStatus status;
3327  GpImage *image;
3328  UINT prop_count, prop_size, i;
3329  PROPID prop_id[16] = { 0 };
3330  ImageType image_type;
3331  union
3332  {
3334  char buf[256];
3335  } item;
3336 
3337  for (i = 0; i < ARRAY_SIZE(td); i++)
3338  {
3339  image = load_image(td[i].image_data, td[i].image_size, TRUE, FALSE);
3340  if (!image)
3341  {
3342  trace("%u: failed to load image data\n", i);
3343  continue;
3344  }
3345 
3346  status = GdipGetImageType(image, &image_type);
3347  ok(status == Ok, "%u: GdipGetImageType error %d\n", i, status);
3348  ok(td[i].image_type == image_type, "%u: expected image_type %d, got %d\n",
3349  i, td[i].image_type, image_type);
3350 
3351  status = GdipGetPropertyCount(image, &prop_count);
3352  ok(status == Ok, "%u: GdipGetPropertyCount error %d\n", i, status);
3353  todo_wine_if(td[i].image_data == pngimage || td[i].image_data == jpgimage)
3354  ok(td[i].prop_count == prop_count || td[i].prop_count2 == prop_count,
3355  " %u: expected property count %u or %u, got %u\n",
3356  i, td[i].prop_count, td[i].prop_count2, prop_count);
3357 
3358  status = GdipGetPropertyItemSize(NULL, 0, &prop_size);
3362  status = GdipGetPropertyItemSize(image, 0, &prop_size);
3363  if (image_type == ImageTypeMetafile)
3365  else
3367 
3368  status = GdipGetPropertyItem(NULL, 0, 0, &item.data);
3372  status = GdipGetPropertyItem(image, 0, 0, &item.data);
3373  if (image_type == ImageTypeMetafile)
3375  else
3377 
3378  /* FIXME: remove once Wine is fixed */
3379  if (td[i].prop_count != prop_count)
3380  {
3382  continue;
3383  }
3384 
3385  status = GdipGetPropertyIdList(NULL, prop_count, prop_id);
3387  status = GdipGetPropertyIdList(image, prop_count, NULL);
3389  status = GdipGetPropertyIdList(image, 0, prop_id);
3390  if (image_type == ImageTypeMetafile)
3392  else if (prop_count == 0)
3393  expect(Ok, status);
3394  else
3396  status = GdipGetPropertyIdList(image, prop_count - 1, prop_id);
3397  if (image_type == ImageTypeMetafile)
3399  else
3401  status = GdipGetPropertyIdList(image, prop_count + 1, prop_id);
3402  if (image_type == ImageTypeMetafile)
3404  else
3406  status = GdipGetPropertyIdList(image, prop_count, prop_id);
3407  if (image_type == ImageTypeMetafile)
3409  else
3410  {
3411  expect(Ok, status);
3412  if (prop_count != 0)
3413  ok(td[i].prop_id == prop_id[0] || td[i].prop_id2 == prop_id[0],
3414  " %u: expected property id %#x or %#x, got %#x\n",
3415  i, td[i].prop_id, td[i].prop_id2, prop_id[0]);
3416  }
3417 
3418  if (status == Ok)
3419  {
3420  status = GdipGetPropertyItemSize(image, prop_id[0], &prop_size);
3421  if (prop_count == 0)
3423  else
3424  {
3425  expect(Ok, status);
3426 
3427  assert(sizeof(item) >= prop_size);
3428  ok(prop_size > sizeof(PropertyItem), "%u: got too small prop_size %u\n",
3429  i, prop_size);
3430  ok(td[i].prop_size + sizeof(PropertyItem) == prop_size ||
3431  td[i].prop_size2 + sizeof(PropertyItem) == prop_size,
3432  " %u: expected property size %u or %u, got %u\n",
3433  i, td[i].prop_size, td[i].prop_size2, prop_size);
3434 
3435  status = GdipGetPropertyItem(image, prop_id[0], 0, &item.data);
3436  ok(status == InvalidParameter || status == GenericError /* Win7 */,
3437  "%u: expected InvalidParameter, got %d\n", i, status);
3438  status = GdipGetPropertyItem(image, prop_id[0], prop_size - 1, &item.data);
3439  ok(status == InvalidParameter || status == GenericError /* Win7 */,
3440  "%u: expected InvalidParameter, got %d\n", i, status);
3441  status = GdipGetPropertyItem(image, prop_id[0], prop_size + 1, &item.data);
3442  ok(status == InvalidParameter || status == GenericError /* Win7 */,
3443  "%u: expected InvalidParameter, got %d\n", i, status);
3444  status = GdipGetPropertyItem(image, prop_id[0], prop_size, &item.data);
3445  expect(Ok, status);
3446  ok(prop_id[0] == item.data.id,
3447  "%u: expected property id %#x, got %#x\n", i, prop_id[0], item.data.id);
3448  }
3449  }
3450 
3452  }
3453 }
3454 
3455 #define IFD_BYTE 1
3456 #define IFD_ASCII 2
3457 #define IFD_SHORT 3
3458 #define IFD_LONG 4
3459 #define IFD_RATIONAL 5
3460 #define IFD_SBYTE 6
3461 #define IFD_UNDEFINED 7
3462 #define IFD_SSHORT 8
3463 #define IFD_SLONG 9
3464 #define IFD_SRATIONAL 10
3465 #define IFD_FLOAT 11
3466 #define IFD_DOUBLE 12
3467 
3468 #ifndef PropertyTagTypeSByte
3469 #define PropertyTagTypeSByte 6
3470 #define PropertyTagTypeSShort 8
3471 #define PropertyTagTypeFloat 11
3472 #define PropertyTagTypeDouble 12
3473 #endif
3474 
3476 {
3477  switch (type)
3478  {
3483  default: return type;
3484  }
3485 }
3486 
3487 #include "pshpack2.h"
3488 struct IFD_entry
3489 {
3490  SHORT id;
3491  SHORT type;
3492  ULONG count;
3493  LONG value;
3494 };
3495 
3497 {