ReactOS 0.4.17-dev-218-g5635d24
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
33static GpStatus (WINAPI *pGdipBitmapGetHistogramSize)(HistogramFormat,UINT*);
34static GpStatus (WINAPI *pGdipBitmapGetHistogram)(GpBitmap*,HistogramFormat,UINT,UINT*,UINT*,UINT*,UINT*);
35static GpStatus (WINAPI *pGdipImageSetAbort)(GpImage*,GdiplusAbort*);
36
37static GpStatus (WINGDIPAPI *pGdipInitializePalette)(ColorPalette*,PaletteType,INT,BOOL,GpBitmap*);
38
39#define expect(expected, got) ok((got) == (expected), "Expected %d, got %d\n", (UINT)(expected), (UINT)(got))
40#define expectf(expected, got) ok(fabs((expected) - (got)) < 0.0001, "Expected %f, got %f\n", (expected), (got))
41
42static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
43{
44 unsigned int diff = x > y ? x - y : y - x;
45 return diff <= max_diff;
46}
47
48BOOL color_match(ARGB c1, ARGB c2, BYTE max_diff)
49{
50 if (!compare_uint(c1 & 0xff, c2 & 0xff, max_diff)) return FALSE;
51 c1 >>= 8; c2 >>= 8;
52 if (!compare_uint(c1 & 0xff, c2 & 0xff, max_diff)) return FALSE;
53 c1 >>= 8; c2 >>= 8;
54 if (!compare_uint(c1 & 0xff, c2 & 0xff, max_diff)) return FALSE;
55 c1 >>= 8; c2 >>= 8;
56 if (!compare_uint(c1 & 0xff, c2 & 0xff, max_diff)) return FALSE;
57 return TRUE;
58}
59
61{
62 WCHAR bufferW[39];
63 char buffer[39];
64 char buffer2[39];
65
66 StringFromGUID2(got, bufferW, ARRAY_SIZE(bufferW));
67 WideCharToMultiByte(CP_ACP, 0, bufferW, ARRAY_SIZE(bufferW), buffer, sizeof(buffer), NULL, NULL);
68 StringFromGUID2(expected, bufferW, ARRAY_SIZE(bufferW));
69 WideCharToMultiByte(CP_ACP, 0, bufferW, ARRAY_SIZE(bufferW), buffer2, sizeof(buffer2), NULL, NULL);
71 ok_(__FILE__, line)(IsEqualGUID(expected, got), "Expected %s, got %s\n", buffer2, buffer);
72}
73
75{
76 GUID raw;
78
80 ok_(__FILE__, line)(stat == Ok, "GdipGetImageRawFormat failed with %d\n", stat);
81 if(stat != Ok) return;
83}
84
86{
88 UINT dim;
91
93 ok_(__FILE__, line)(stat == Ok, "Expected %d, got %d\n", Ok, stat);
94 ok_(__FILE__, line)(dim == width, "Expected %d, got %d\n", width, dim);
95
97 ok_(__FILE__, line)(stat == Ok, "Expected %d, got %d\n", Ok, stat);
98 ok_(__FILE__, line)(dim == height, "Expected %d, got %d\n", height, dim);
99
101 ok_(__FILE__, line)(stat == Ok, "Expected %d, got %d\n", Ok, stat);
102 ok_(__FILE__, line)(type == ImageTypeBitmap, "Expected %d, got %d\n", ImageTypeBitmap, type);
103
105 ok_(__FILE__, line)(stat == Ok, "Expected %d, got %d\n", Ok, stat);
106 ok_(__FILE__, line)(format == PixelFormat32bppARGB, "Expected %d, got %d\n", PixelFormat32bppARGB, format);
107}
108
109static const char * dbgstr_hexdata(const BYTE *data, UINT len)
110{
111 UINT i, offset = 0;
112 char buffer[770];
113 const UINT max_len = 256;
114 const UINT output_len = (len <= max_len) ? len : max_len - 1;
115
116 if (!len) return "";
117
118 for (i = 0; i < output_len; i++)
119 offset += sprintf(buffer + offset, " %02x", data[i]);
120
121 if (len > output_len)
122 offset += sprintf(buffer + offset, " ...");
123
124 return __wine_dbg_strdup( buffer );
125}
126
127static void expect_bitmap_locked_data(GpBitmap *bitmap, const BYTE *expect_bits,
129{
131 BitmapData lockeddata;
132 int match;
133
134 memset(&lockeddata, 0x55, sizeof(lockeddata));
136 ok_(__FILE__, line)(stat == Ok, "Expected %d, got %d\n", Ok, stat);
137 ok_(__FILE__, line)(lockeddata.Width == width, "Expected %d, got %d\n", width, lockeddata.Width);
138 ok_(__FILE__, line)(lockeddata.Height == height, "Expected %d, got %d\n", height, lockeddata.Height);
139 ok_(__FILE__, line)(lockeddata.Stride == stride, "Expected %d, got %d\n", stride, lockeddata.Stride);
140 ok_(__FILE__, line)(lockeddata.PixelFormat == PixelFormat32bppARGB,
141 "Expected %d, got %d\n", PixelFormat32bppARGB, lockeddata.PixelFormat);
142 match = !memcmp(expect_bits, lockeddata.Scan0, lockeddata.Height * lockeddata.Stride);
143 ok_(__FILE__, line)(match, "data mismatch\n");
144 if (!match)
145 {
146 trace("Expected: %s\n", dbgstr_hexdata(expect_bits, lockeddata.Height * lockeddata.Stride));
147 trace("Got: %s\n", dbgstr_hexdata(lockeddata.Scan0, lockeddata.Height * lockeddata.Stride));
148 }
149 GdipBitmapUnlockBits(bitmap, &lockeddata);
150}
151
153{
155 UINT n_codecs, info_size, i;
157 BOOL ret = FALSE;
158
159 status = GdipGetImageEncodersSize(&n_codecs, &info_size);
160 expect(Ok, status);
161
162 info = GdipAlloc(info_size);
163
164 status = GdipGetImageEncoders(n_codecs, info_size, info);
165 expect(Ok, status);
166
167 for (i = 0; i < n_codecs; i++)
168 {
169 if (!lstrcmpW(info[i].MimeType, mime))
170 {
171 *format = info[i].FormatID;
172 *clsid = info[i].Clsid;
173 ret = TRUE;
174 break;
175 }
176 }
177
178 GdipFree(info);
179 return ret;
180}
181
183{
185 HGLOBAL hglob;
186 LPBYTE data;
189 GpImage *img, *copy;
190
191 hglob = GlobalAlloc (0, size);
192 data = GlobalLock (hglob);
193 memcpy(data, buff, size);
194 GlobalUnlock(hglob); data = NULL;
195
197 ok_(__FILE__, line)(hres == S_OK, "Failed to create a stream\n");
198 if(hres != S_OK) return;
199
201 ok_(__FILE__, line)(stat == Ok, "Failed to create a Bitmap\n");
202 if(stat != Ok){
203 IStream_Release(stream);
204 return;
205 }
206
209 expect(Ok, stat);
211
214 IStream_Release(stream);
215}
216
217static void test_Scan0(void)
218{
219 GpBitmap *bm;
221 BYTE buff[360];
222
223 bm = NULL;
225 expect(Ok, stat);
226 ok(NULL != bm, "Expected bitmap to be initialized\n");
227 if (stat == Ok)
229
230 bm = (GpBitmap*)0xdeadbeef;
233 ok( !bm, "expected null bitmap\n" );
234
235 bm = (GpBitmap*)0xdeadbeef;
238 ok( !bm, "expected null bitmap\n" );
239
240 bm = (GpBitmap*)0xdeadbeef;
243 ok( !bm, "expected null bitmap\n" );
244
245 bm = NULL;
247 expect(Ok, stat);
248 ok(NULL != bm, "Expected bitmap to be initialized\n");
249 if (stat == Ok)
251
252 bm = (GpBitmap*) 0xdeadbeef;
255 ok( !bm, "expected null bitmap\n" );
256
257 bm = (GpBitmap*)0xdeadbeef;
260 ok( bm == (GpBitmap*)0xdeadbeef, "expected deadbeef bitmap\n" );
261
262 bm = NULL;
264 expect(Ok, stat);
265 ok(NULL != bm, "Expected bitmap to be initialized\n");
266 if (stat == Ok)
268
269 bm = (GpBitmap*)0xdeadbeef;
272 ok( !bm, "expected null bitmap\n" );
273}
274
275static void test_FromGdiDib(void)
276{
277 GpBitmap *bm;
279 BYTE buff[400];
280 BYTE rbmi[sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)];
281 BITMAPINFO *bmi = (BITMAPINFO*)rbmi;
283
284 bm = NULL;
285
286 memset(rbmi, 0, sizeof(rbmi));
287
288 bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
289 bmi->bmiHeader.biWidth = 10;
290 bmi->bmiHeader.biHeight = 10;
291 bmi->bmiHeader.biPlanes = 1;
292 bmi->bmiHeader.biBitCount = 32;
294
297
300
303
305 expect(Ok, stat);
306 ok(NULL != bm, "Expected bitmap to be initialized\n");
307 if (stat == Ok)
308 {
310 expect(Ok, stat);
312
314 }
315
316 bmi->bmiHeader.biBitCount = 24;
318 expect(Ok, stat);
319 ok(NULL != bm, "Expected bitmap to be initialized\n");
320 if (stat == Ok)
321 {
323 expect(Ok, stat);
325
327 }
328
329 bmi->bmiHeader.biBitCount = 16;
331 expect(Ok, stat);
332 ok(NULL != bm, "Expected bitmap to be initialized\n");
333 if (stat == Ok)
334 {
336 expect(Ok, stat);
338
340 }
341
342 bmi->bmiHeader.biBitCount = 8;
344 expect(Ok, stat);
345 ok(NULL != bm, "Expected bitmap to be initialized\n");
346 if (stat == Ok)
347 {
349 expect(Ok, stat);
351
353 }
354
355 bmi->bmiHeader.biBitCount = 4;
357 expect(Ok, stat);
358 ok(NULL != bm, "Expected bitmap to be initialized\n");
359 if (stat == Ok)
360 {
362 expect(Ok, stat);
364
366 }
367
368 bmi->bmiHeader.biBitCount = 1;
370 expect(Ok, stat);
371 ok(NULL != bm, "Expected bitmap to be initialized\n");
372 if (stat == Ok)
373 {
375 expect(Ok, stat);
377
379 }
380
381 bmi->bmiHeader.biBitCount = 0;
384}
385
386static void test_GetImageDimension(void)
387{
388 GpBitmap *bm;
390 const REAL WIDTH = 10.0, HEIGHT = 20.0;
391 REAL w,h;
392
393 bm = (GpBitmap*)0xdeadbeef;
395 expect(Ok,stat);
396 ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
397 ok(NULL != bm, "Expected bitmap to not be NULL\n");
398
401
404
407
408 w = -1;
409 h = -1;
411 expect(Ok, stat);
412 expectf(WIDTH, w);
413 expectf(HEIGHT, h);
415}
416
418{
419 GpBitmap *bm;
421 const REAL WIDTH = 10.0, HEIGHT = 20.0;
422 UINT w;
423 GUID dimension = {0};
424 UINT count;
425 ARGB color;
426
427 bm = (GpBitmap*)0xdeadbeef;
429 expect(Ok,stat);
430 ok((GpBitmap*)0xdeadbeef != bm, "Expected bitmap to not be 0xdeadbeef\n");
431 ok(NULL != bm, "Expected bitmap to not be NULL\n");
432
435
438
439 w = -1;
441 expect(Ok, stat);
442 expect(1, w);
443
444 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 1);
445 expect(Ok, stat);
446 expect_guid(&FrameDimensionPage, &dimension, __LINE__, FALSE);
447
448 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 2);
450
451 stat = GdipImageGetFrameDimensionsList((GpImage*)bm, &dimension, 0);
453
454 stat = GdipImageGetFrameCount(NULL, &dimension, &count);
456
457 /* WinXP crashes on this test */
458 if(0)
459 {
460 stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, NULL);
462 }
463
465 expect(Ok, stat);
466
467 count = 12345;
468 stat = GdipImageGetFrameCount((GpImage*)bm, &dimension, &count);
469 expect(Ok, stat);
470 expect(1, count);
471
472 GdipBitmapSetPixel(bm, 0, 0, 0xffffffff);
473
474 stat = GdipImageSelectActiveFrame((GpImage*)bm, &dimension, 0);
475 expect(Ok, stat);
476
477 /* SelectActiveFrame has no effect on image data of memory bitmaps */
478 color = 0xdeadbeef;
479 stat = GdipBitmapGetPixel(bm, 0, 0, &color);
480 expect(Ok, stat);
481 expect(0xffffffff, color);
482
483 stat = GdipImageSelectActiveFrame((GpImage*)bm, &dimension, 1);
484 expect(Ok, stat);
485
487}
488
489static void test_LoadingImages(void)
490{
492 GpBitmap *bm;
493 GpImage *img;
494
497
498 bm = (GpBitmap *)0xdeadbeef;
501 ok(bm == (GpBitmap *)0xdeadbeef, "returned %p\n", bm);
502
503 bm = (GpBitmap *)0xdeadbeef;
504 stat = GdipCreateBitmapFromFile(L"nonexistent", &bm);
506 ok(!bm, "returned %p\n", bm);
507
510
511 img = (GpImage *)0xdeadbeef;
514 ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img);
515
516 img = (GpImage *)0xdeadbeef;
517 stat = GdipLoadImageFromFile(L"nonexistent", &img);
519 ok(!img, "returned %p\n", img);
520
523
524 img = (GpImage *)0xdeadbeef;
527 ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img);
528
529 img = (GpImage *)0xdeadbeef;
530 stat = GdipLoadImageFromFileICM(L"nonexistent", &img);
532 ok(!img, "returned %p\n", img);
533}
534
535static void test_SavingImages(void)
536{
538 GpBitmap *bm;
539 UINT n;
540 UINT s;
541 const REAL WIDTH = 10.0, HEIGHT = 20.0;
542 REAL w, h;
544 static const CHAR filenameA[] = "a.bmp";
545 static const WCHAR filename[] = L"a.bmp";
546
547 codecs = NULL;
548
549 stat = GdipSaveImageToFile(0, 0, 0, 0);
551
552 bm = NULL;
554 expect(Ok, stat);
555 if (!bm)
556 return;
557
558 /* invalid params */
559 stat = GdipSaveImageToFile((GpImage*)bm, 0, 0, 0);
561
564
565 /* encoder tests should succeed -- already tested */
567 if (stat != Ok || n == 0) goto cleanup;
568
569 codecs = GdipAlloc(s);
570 if (!codecs) goto cleanup;
571
573 if (stat != Ok) goto cleanup;
574
575 stat = GdipSaveImageToFile((GpImage*)bm, filename, &codecs[0].Clsid, 0);
576 expect(Ok, stat);
577
579 bm = 0;
580
581 /* re-load and check image stats */
583 expect(Ok, stat);
584 if (stat != Ok) goto cleanup;
585
587 if (stat != Ok) goto cleanup;
588
589 expectf(WIDTH, w);
590 expectf(HEIGHT, h);
591
592 cleanup:
594 if (bm)
596 ok(DeleteFileA(filenameA), "Delete failed.\n");
597}
598
600{
602 BOOL result;
603 GpBitmap *bm1 = NULL, *bm2 = NULL, *check_bm = NULL;
604 const REAL WIDTH = 10.0, HEIGHT = 20.0;
605 REAL w, h;
606 GUID format, tiff_clsid;
609 UINT frame_count;
610 static const CHAR filename1A[] = "1.tif";
611 static const CHAR filename2A[] = "2.tif";
612 static const WCHAR filename1[] = L"1.tif";
613 static const WCHAR filename2[] = L"2.tif";
614
615 params.Count = 1;
616 params.Parameter[0].Guid = EncoderSaveFlag;
617 params.Parameter[0].Type = EncoderParameterValueTypeLong;
618 params.Parameter[0].NumberOfValues = 1;
619 params.Parameter[0].Value = &paramValue;
620
622 expect(Ok, stat);
624 expect(Ok, stat);
625 result = get_encoder_clsid(L"image/tiff", &format, &tiff_clsid);
626 ok(result, "getting TIFF encoding clsid failed");
627
628 if (!bm1 || !bm2 || !result)
629 return;
630
631 /* invalid params: NULL */
632 stat = GdipSaveAdd(0, &params);
634 stat = GdipSaveAdd((GpImage*)bm1, 0);
636
637 stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, 0);
639 stat = GdipSaveAddImage((GpImage*)bm1, 0, &params);
641 stat = GdipSaveAddImage(0, (GpImage*)bm2, &params);
643
644 /* win32 error: SaveAdd() can only be called after Save() with the MultiFrame param */
645 stat = GdipSaveAdd((GpImage*)bm1, &params);
647 stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, &params);
649
650 stat = GdipSaveImageToFile((GpImage*)bm1, filename1, &tiff_clsid, 0); /* param not set! */
651 expect(Ok, stat);
652 if (stat != Ok) goto cleanup;
653
654 stat = GdipSaveAdd((GpImage*)bm1, &params);
656 stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, &params);
658
659 /* win32 error: can't flush before starting the encoding process */
660 paramValue = EncoderValueFlush;
661 stat = GdipSaveAdd((GpImage*)bm1, &params);
663
664 /* win32 error: can't start encoding process through SaveAdd(), only Save() */
665 paramValue = EncoderValueMultiFrame;
666 stat = GdipSaveAdd((GpImage*)bm1, &params);
668
669 /* start encoding process: add first frame (bm1) */
670 paramValue = EncoderValueMultiFrame;
671 stat = GdipSaveImageToFile((GpImage*)bm1, filename1, &tiff_clsid, &params);
672 expect(Ok, stat);
673
674 /* re-start encoding process: add first frame (bm1), should re-create the file */
675 stat = GdipSaveImageToFile((GpImage*)bm1, filename1, &tiff_clsid, &params);
676 expect(Ok, stat);
677
678 /* add second frame (bm2) */
680 stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, &params);
681 expect(Ok, stat);
682 if (stat != Ok) goto cleanup;
683
684 /* finish encoding process */
685 paramValue = EncoderValueFlush;
686 stat = GdipSaveAdd((GpImage*)bm1, &params);
687 expect(Ok, stat);
688
689 /* bm1 should be unchanged, only the saved file on disk has multiple frames */
690 stat = GdipImageGetFrameCount((GpImage*)bm1, &FrameDimensionPage, &frame_count);
691 expect(Ok, stat);
692 expect(1, frame_count);
693
694 /* win32 error: encoding process already finished */
696 stat = GdipSaveAddImage((GpImage*)bm1, (GpImage*)bm2, &params);
698
699 stat = GdipSaveAdd((GpImage*)bm1, &params);
701
703 bm1 = 0;
705 bm2 = 0;
706
707 /* re-load and check image stats */
708 stat = GdipLoadImageFromFile(filename1, (GpImage**)&check_bm);
709 expect(Ok, stat);
710
711 stat = GdipImageGetFrameCount((GpImage*)check_bm, &FrameDimensionPage, &frame_count);
712 expect(Ok, stat);
713 expect(2, frame_count);
714 if (stat != Ok || frame_count != 2) goto cleanup;
715
716 stat = GdipGetImageDimension((GpImage*)check_bm, &w, &h);
717 expect(Ok, stat);
718 expectf(WIDTH, w); /* frame index 0: bm1 stats */
719 expectf(HEIGHT, h);
720
721 stat = GdipImageSelectActiveFrame((GpImage*)check_bm, &FrameDimensionPage, 1);
722 expect(Ok, stat);
723
724 stat = GdipGetImageDimension((GpImage*)check_bm, &w, &h);
725 expectf(2 * WIDTH, w); /* frame index 1: bm2 stats */
726 expectf(2 * HEIGHT, h);
727
728 /* now proper API use for SaveAdd() to swap the frames in check_bm */
729 paramValue = EncoderValueMultiFrame;
730 stat = GdipSaveImageToFile((GpImage*)check_bm, filename2, &tiff_clsid, &params);
731 expect(Ok, stat); /* second frame is active: bm2 */
732
733 stat = GdipImageSelectActiveFrame((GpImage*)check_bm, &FrameDimensionPage, 0);
734 expect(Ok, stat);
735
737 stat = GdipSaveAdd((GpImage*)check_bm, &params);
738 expect(Ok, stat); /* first frame is active: bm1 */
739
740 paramValue = EncoderValueFlush;
741 stat = GdipSaveAdd((GpImage*)check_bm, &params);
742 expect(Ok, stat); /* flushed encoder (finished encoding process) */
743
744 GdipDisposeImage((GpImage*)check_bm);
745 check_bm = 0;
746
747 /* re-load and check image stats */
749 expect(Ok, stat);
750
751 stat = GdipImageGetFrameCount((GpImage*)check_bm, &FrameDimensionPage, &frame_count);
752 expect(Ok, stat);
753 expect(2, frame_count);
754
755 stat = GdipGetImageDimension((GpImage*)check_bm, &w, &h);
756 expect(Ok, stat);
757 expectf(2 * WIDTH, w); /* frame index 0: bm2 stats */
758 expectf(2 * HEIGHT, h);
759
760 stat = GdipImageSelectActiveFrame((GpImage*)check_bm, &FrameDimensionPage, 1);
761 expect(Ok, stat);
762
763 stat = GdipGetImageDimension((GpImage*)check_bm, &w, &h);
764 expectf(WIDTH, w); /* frame index 1: bm1 stats */
765 expectf(HEIGHT, h);
766
767 cleanup:
768 if (bm1)
770 if (bm2)
772 ok(DeleteFileA(filename1A), "Delete 1.tif failed.\n");
773
774 if (check_bm)
775 {
776 GdipDisposeImage((GpImage*)check_bm);
777 ok(DeleteFileA(filename2A), "Delete 2.tif failed.\n");
778 }
779}
780
781static void test_encoders(void)
782{
784 UINT n;
785 UINT s;
787 int i;
788 int bmp_found;
789
790 static const CHAR bmp_format[] = "BMP";
791
793 expect(stat, Ok);
794
795 codecs = GdipAlloc(s);
796 if (!codecs)
797 return;
798
801
804
807
810
812 expect(stat, Ok);
813
814 bmp_found = FALSE;
815 for (i = 0; i < n; i++)
816 {
817 CHAR desc[32];
818
819 WideCharToMultiByte(CP_ACP, 0, codecs[i].FormatDescription, -1,
820 desc, 32, 0, 0);
821
823 desc, -1,
824 bmp_format, -1) == CSTR_EQUAL) {
825 bmp_found = TRUE;
826 break;
827 }
828 }
829 if (!bmp_found)
830 ok(FALSE, "No BMP codec found.\n");
831
833}
834
835static void test_LockBits(void)
836{
838 GpBitmap *bm;
839 GpRect rect;
840 BitmapData bd;
841 const INT WIDTH = 10, HEIGHT = 20;
842 ARGB color;
843 int y;
844
845 bm = NULL;
847 expect(Ok, stat);
848
849 rect.X = 2;
850 rect.Y = 3;
851 rect.Width = 4;
852 rect.Height = 5;
853
854 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000);
855 expect(Ok, stat);
856
857 stat = GdipBitmapSetPixel(bm, 2, 8, 0xff480000);
858 expect(Ok, stat);
859
860 /* read-only */
862 expect(Ok, stat);
863
864 if (stat == Ok) {
865 expect(0xc3, ((BYTE*)bd.Scan0)[2]);
866 expect(0x48, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]);
867
868 ((char*)bd.Scan0)[2] = 0xff;
869
870 stat = GdipBitmapUnlockBits(bm, &bd);
871 expect(Ok, stat);
872 }
873
874 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
875 expect(Ok, stat);
876 expect(0xffff0000, color);
877
878 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffc30000);
879 expect(Ok, stat);
880
881 /* read-only, with NULL rect -> whole bitmap lock */
883 expect(Ok, stat);
884 expect(bd.Width, WIDTH);
885 expect(bd.Height, HEIGHT);
886
887 if (stat == Ok) {
888 ((char*)bd.Scan0)[2 + 2*3 + 3*bd.Stride] = 0xff;
889
890 stat = GdipBitmapUnlockBits(bm, &bd);
891 expect(Ok, stat);
892 }
893
894 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
895 expect(Ok, stat);
896 expect(0xffff0000, color);
897
898 /* read-only, consecutive */
900 expect(Ok, stat);
901
902 if (stat == Ok) {
903 stat = GdipBitmapUnlockBits(bm, &bd);
904 expect(Ok, stat);
905 }
906
908 expect(Ok, stat);
910 expect(Ok, stat);
911
912 /* read x2 */
914 expect(Ok, stat);
917
918 stat = GdipBitmapUnlockBits(bm, &bd);
919 expect(Ok, stat);
920
922 expect(Ok, stat);
924 expect(Ok, stat);
925
926 stat = GdipBitmapSetPixel(bm, 2, 3, 0xffff0000);
927 expect(Ok, stat);
928
929 stat = GdipBitmapSetPixel(bm, 2, 8, 0xffc30000);
930 expect(Ok, stat);
931
932 /* write, no conversion */
934 expect(Ok, stat);
935
936 if (stat == Ok) {
937 /* all bits are readable, inside the rect or not */
938 expect(0xff, ((BYTE*)bd.Scan0)[2]);
939 expect(0xc3, ((BYTE*)bd.Scan0)[2 + bd.Stride * 5]);
940
941 stat = GdipBitmapUnlockBits(bm, &bd);
942 expect(Ok, stat);
943 }
944
945 /* read, conversion */
947 expect(Ok, stat);
948
949 if (stat == Ok) {
950 expect(0xff, ((BYTE*)bd.Scan0)[2]);
951 if (0)
952 /* Areas outside the rectangle appear to be uninitialized */
953 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
954
955 ((BYTE*)bd.Scan0)[2] = 0xc3;
956
957 stat = GdipBitmapUnlockBits(bm, &bd);
958 expect(Ok, stat);
959 }
960
961 /* writes do not work in read mode if there was a conversion */
962 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
963 expect(Ok, stat);
964 expect(0xffff0000, color);
965
966 /* read/write, conversion */
968 expect(Ok, stat);
969
970 if (stat == Ok) {
971 expect(0xff, ((BYTE*)bd.Scan0)[2]);
972 ((BYTE*)bd.Scan0)[1] = 0x88;
973 if (0)
974 /* Areas outside the rectangle appear to be uninitialized */
975 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
976
977 stat = GdipBitmapUnlockBits(bm, &bd);
978 expect(Ok, stat);
979 }
980
981 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
982 expect(Ok, stat);
983 expect(0xffff8800, color);
984
985 /* write, conversion */
987 expect(Ok, stat);
988
989 if (stat == Ok) {
990 if (0)
991 {
992 /* This is completely uninitialized. */
993 ok(0xff != ((BYTE*)bd.Scan0)[2], "original image bits are readable\n");
994 ok(0xc3 != ((BYTE*)bd.Scan0)[2 + bd.Stride * 5], "original image bits are readable\n");
995 }
996
997 /* Initialize the buffer so the unlock doesn't access undefined memory */
998 for (y=0; y<5; y++)
999 memset(((BYTE*)bd.Scan0) + bd.Stride * y, 0, 12);
1000
1001 ((BYTE*)bd.Scan0)[0] = 0x12;
1002 ((BYTE*)bd.Scan0)[1] = 0x34;
1003 ((BYTE*)bd.Scan0)[2] = 0x56;
1004
1005 stat = GdipBitmapUnlockBits(bm, &bd);
1006 expect(Ok, stat);
1007 }
1008
1009 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
1010 expect(Ok, stat);
1011 expect(0xff563412, color);
1012
1013 stat = GdipBitmapGetPixel(bm, 2, 8, &color);
1014 expect(Ok, stat);
1015 expect(0xffc30000, color);
1016
1018 expect(Ok, stat);
1020 expect(Ok, stat);
1021
1022 /* write, no modification */
1024 expect(Ok, stat);
1025
1026 if (stat == Ok) {
1027 stat = GdipBitmapUnlockBits(bm, &bd);
1028 expect(Ok, stat);
1029 }
1030
1031 /* write, consecutive */
1033 expect(Ok, stat);
1034
1035 if (stat == Ok) {
1036 stat = GdipBitmapUnlockBits(bm, &bd);
1037 expect(Ok, stat);
1038 }
1039
1041 expect(Ok, stat);
1043 expect(Ok, stat);
1044
1045 /* write, modify */
1047 expect(Ok, stat);
1048
1049 if (stat == Ok) {
1050 if (bd.Scan0)
1051 ((char*)bd.Scan0)[2] = 0xff;
1052
1053 stat = GdipBitmapUnlockBits(bm, &bd);
1054 expect(Ok, stat);
1055 }
1056
1057 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
1058 expect(Ok, stat);
1059 expect(0xffff0000, color);
1060
1062 expect(Ok, stat);
1063
1064 /* dispose locked */
1066 expect(Ok, stat);
1068 expect(Ok, stat);
1070 expect(Ok, stat);
1071}
1072
1073static void test_LockBits_UserBuf(void)
1074{
1075 GpStatus stat;
1076 GpBitmap *bm;
1077 GpRect rect;
1078 BitmapData bd;
1079 const INT WIDTH = 10, HEIGHT = 20;
1080 DWORD bits[200];
1081 ARGB color;
1082
1083 bm = NULL;
1085 expect(Ok, stat);
1086
1087 memset(bits, 0xaa, sizeof(bits));
1088
1089 rect.X = 2;
1090 rect.Y = 3;
1091 rect.Width = 4;
1092 rect.Height = 5;
1093
1094 bd.Width = 4;
1095 bd.Height = 6;
1096 bd.Stride = WIDTH * 4;
1098 bd.Scan0 = &bits[2+3*WIDTH];
1099 bd.Reserved = 0xaaaaaaaa;
1100
1101 /* read-only */
1103 expect(Ok, stat);
1104
1105 expect(0xaaaaaaaa, bits[0]);
1106 expect(0, bits[2+3*WIDTH]);
1107
1108 bits[2+3*WIDTH] = 0xdeadbeef;
1109
1110 if (stat == Ok) {
1111 stat = GdipBitmapUnlockBits(bm, &bd);
1112 expect(Ok, stat);
1113 }
1114
1115 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
1116 expect(Ok, stat);
1117 expect(0, color);
1118
1119 /* write-only */
1121 expect(Ok, stat);
1122
1123 expect(0xdeadbeef, bits[2+3*WIDTH]);
1124 bits[2+3*WIDTH] = 0x12345678;
1125
1126 if (stat == Ok) {
1127 stat = GdipBitmapUnlockBits(bm, &bd);
1128 expect(Ok, stat);
1129 }
1130
1131 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
1132 expect(Ok, stat);
1133 expect(0x12345678, color);
1134
1135 bits[2+3*WIDTH] = 0;
1136
1137 /* read/write */
1139 expect(Ok, stat);
1140
1141 expect(0x12345678, bits[2+3*WIDTH]);
1142 bits[2+3*WIDTH] = 0xdeadbeef;
1143
1144 if (stat == Ok) {
1145 stat = GdipBitmapUnlockBits(bm, &bd);
1146 expect(Ok, stat);
1147 }
1148
1149 stat = GdipBitmapGetPixel(bm, 2, 3, &color);
1150 expect(Ok, stat);
1151 expect(0xdeadbeef, color);
1152
1154 expect(Ok, stat);
1155}
1156
1158{
1161};
1162
1164{
1167};
1168
1170{
1171 GpBitmap* gpbm = NULL;
1172 HBITMAP hbm = NULL;
1173 HPALETTE hpal = NULL;
1174 GpStatus stat;
1175 BYTE buff[1000];
1176 char logpalette_buf[sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * 255];
1177 LOGPALETTE *LogPal = (LOGPALETTE *)logpalette_buf;
1178 char colorpalette_buf[sizeof(ColorPalette) + sizeof(ARGB) * 255];
1179 ColorPalette *palette = (ColorPalette *)colorpalette_buf;
1180 REAL width, height;
1181 const REAL WIDTH1 = 5;
1182 const REAL HEIGHT1 = 15;
1183 const REAL WIDTH2 = 10;
1184 const REAL HEIGHT2 = 20;
1185 HDC hdc;
1186 union BITMAPINFOUNION bmi;
1187 BYTE *bits;
1189 int i;
1190
1193
1194 hbm = CreateBitmap(WIDTH1, HEIGHT1, 1, 1, NULL);
1197
1199 expect(Ok, stat);
1201 expectf(WIDTH1, width);
1202 expectf(HEIGHT1, height);
1204 expect(Ok, stat);
1206 if (stat == Ok)
1207 GdipDisposeImage((GpImage*)gpbm);
1209
1210 memset(buff, 0, sizeof(buff));
1211 hbm = CreateBitmap(WIDTH2, HEIGHT2, 1, 1, &buff);
1213 expect(Ok, stat);
1214 /* raw format */
1215 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)gpbm, __LINE__, FALSE);
1216
1218 expect(Ok, stat);
1220
1222 expectf(WIDTH2, width);
1223 expectf(HEIGHT2, height);
1224 if (stat == Ok)
1225 GdipDisposeImage((GpImage*)gpbm);
1227
1229 ok(hdc != NULL, "CreateCompatibleDC failed\n");
1230 bmi.bi.bmiHeader.biSize = sizeof(bmi.bi.bmiHeader);
1231 bmi.bi.bmiHeader.biHeight = HEIGHT1;
1232 bmi.bi.bmiHeader.biWidth = WIDTH1;
1233 bmi.bi.bmiHeader.biBitCount = 24;
1234 bmi.bi.bmiHeader.biPlanes = 1;
1236 bmi.bi.bmiHeader.biClrUsed = 0;
1237
1238 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1239 ok(hbm != NULL, "CreateDIBSection failed\n");
1240
1241 bits[0] = 0;
1242
1244 expect(Ok, stat);
1246 expectf(WIDTH1, width);
1247 expectf(HEIGHT1, height);
1249 expect(Ok, stat);
1251 if (stat == Ok)
1252 {
1253 /* test whether writing to the bitmap affects the original */
1254 stat = GdipBitmapSetPixel(gpbm, 0, 0, 0xffffffff);
1255 expect(Ok, stat);
1256
1257 expect(0, bits[0]);
1258
1259 GdipDisposeImage((GpImage*)gpbm);
1260 }
1261
1262 LogPal->palVersion = 0x300;
1263 LogPal->palNumEntries = 8;
1264 for (i = 0; i < 8; i++)
1265 {
1266 LogPal->palPalEntry[i].peRed = i;
1267 LogPal->palPalEntry[i].peGreen = i;
1268 LogPal->palPalEntry[i].peBlue = i;
1269 LogPal->palPalEntry[i].peFlags = 0;
1270 }
1271
1272 hpal = CreatePalette(LogPal);
1273 ok(hpal != NULL, "CreatePalette failed\n");
1274
1275 stat = GdipCreateBitmapFromHBITMAP(hbm, hpal, &gpbm);
1276 expect(Ok, stat);
1277 stat = GdipGetImagePalette((GpImage *)gpbm, palette, sizeof(colorpalette_buf));
1278 expect(Ok, stat);
1279 expect(0, palette->Count);
1280 GdipDisposeImage((GpImage*)gpbm);
1282
1283 for (i = 0; i < 16; i++)
1284 {
1285 RGBQUAD *colors = bmi.bi.bmiColors;
1286 BYTE clr = 255 - i;
1287 colors[i].rgbBlue = clr;
1288 colors[i].rgbGreen = clr;
1289 colors[i].rgbRed = clr;
1290 colors[i].rgbReserved = 0;
1291 }
1292
1293 bmi.bi.bmiHeader.biBitCount = 8;
1294 bmi.bi.bmiHeader.biClrUsed = 16;
1295 bmi.bi.bmiHeader.biClrImportant = 16;
1296 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1297 ok(hbm != NULL, "CreateDIBSection failed\n");
1298
1299 stat = GdipCreateBitmapFromHBITMAP(hbm, hpal, &gpbm);
1300 expect(Ok, stat);
1302 expect(Ok, stat);
1304 stat = GdipGetImagePalette((GpImage *)gpbm, palette, sizeof(colorpalette_buf));
1305 expect(Ok, stat);
1306 expect(256, palette->Count);
1307 for (i = 0; i < 16; i++)
1308 {
1309 BYTE clr = 255 - i;
1310 ARGB argb = 0xff000000 | (clr << 16) | (clr << 8) | clr;
1311 ok(palette->Entries[i] == argb, "got %08lx, expected %08lx\n", palette->Entries[i], argb);
1312 }
1313 GdipDisposeImage((GpImage*)gpbm);
1314
1315 DeleteObject(hpal);
1316
1318 expect(Ok, stat);
1320 expect(Ok, stat);
1322 stat = GdipGetImagePalette((GpImage *)gpbm, palette, sizeof(colorpalette_buf));
1323 expect(Ok, stat);
1324 expect(256, palette->Count);
1325 for (i = 0; i < 16; i++)
1326 {
1327 BYTE clr = 255 - i;
1328 ARGB argb = 0xff000000 | (clr << 16) | (clr << 8) | clr;
1329 ok(palette->Entries[i] == argb, "got %08lx, expected %08lx\n", palette->Entries[i], argb);
1330 }
1331 GdipDisposeImage((GpImage*)gpbm);
1332
1334
1335 /* 16-bit 555 dib, rgb */
1336 bmi.bi.bmiHeader.biBitCount = 16;
1338
1339 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1340 ok(hbm != NULL, "CreateDIBSection failed\n");
1341
1342 bits[0] = 0;
1343
1345 expect(Ok, stat);
1346
1347 if (stat == Ok)
1348 {
1350 expect(Ok, stat);
1351 expectf(WIDTH1, width);
1352 expectf(HEIGHT1, height);
1353
1355 expect(Ok, stat);
1357
1358 GdipDisposeImage((GpImage*)gpbm);
1359 }
1361
1362 /* 16-bit 555 dib, with bitfields */
1363 bmi.bi.bmiHeader.biSize = sizeof(bmi.bi.bmiHeader);
1365 bmi.bf.masks[0] = 0x7c00;
1366 bmi.bf.masks[1] = 0x3e0;
1367 bmi.bf.masks[2] = 0x1f;
1368
1369 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1370 ok(hbm != NULL, "CreateDIBSection failed\n");
1371
1372 bits[0] = 0;
1373
1375 expect(Ok, stat);
1376
1377 if (stat == Ok)
1378 {
1380 expect(Ok, stat);
1381 expectf(WIDTH1, width);
1382 expectf(HEIGHT1, height);
1383
1385 expect(Ok, stat);
1387
1388 GdipDisposeImage((GpImage*)gpbm);
1389 }
1391
1392 /* 16-bit 565 dib, with bitfields */
1393 bmi.bf.masks[0] = 0xf800;
1394 bmi.bf.masks[1] = 0x7e0;
1395 bmi.bf.masks[2] = 0x1f;
1396
1397 hbm = CreateDIBSection(hdc, &bmi.bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1398 ok(hbm != NULL, "CreateDIBSection failed\n");
1399
1400 bits[0] = 0;
1401
1403 expect(Ok, stat);
1404
1405 if (stat == Ok)
1406 {
1408 expect(Ok, stat);
1409 expectf(WIDTH1, width);
1410 expectf(HEIGHT1, height);
1411
1413 expect(Ok, stat);
1415
1416 GdipDisposeImage((GpImage*)gpbm);
1417 }
1419
1420 DeleteDC(hdc);
1421}
1422
1423static void test_GdipGetImageFlags(void)
1424{
1425 GpImage *img;
1426 GpStatus stat;
1427 UINT flags;
1428
1429 img = (GpImage*)0xdeadbeef;
1430
1433
1436
1439
1441 expect(Ok, stat);
1443 expect(Ok, stat);
1446
1448 expect(Ok, stat);
1450 expect(Ok, stat);
1453
1455 expect(Ok, stat);
1457 expect(Ok, stat);
1460
1462 expect(Ok, stat);
1464 expect(Ok, stat);
1467
1469 expect(Ok, stat);
1471 expect(Ok, stat);
1474
1476 expect(Ok, stat);
1478 expect(Ok, stat);
1481
1483 expect(Ok, stat);
1485 expect(Ok, stat);
1488
1490 expect(Ok, stat);
1492 expect(Ok, stat);
1495
1497 expect(Ok, stat);
1499 expect(Ok, stat);
1502
1504 expect(Ok, stat);
1506 expect(Ok, stat);
1509
1511 expect(Ok, stat);
1513 expect(Ok, stat);
1516
1518 expect(Ok, stat);
1519 if (stat == Ok)
1520 {
1522 expect(Ok, stat);
1525 }
1526
1528 expect(Ok, stat);
1529 if (stat == Ok)
1530 {
1531 expect(Ok, stat);
1533 expect(Ok, stat);
1536 }
1537
1539 expect(Ok, stat);
1540 if (stat == Ok)
1541 {
1542 expect(Ok, stat);
1544 expect(Ok, stat);
1547 }
1548}
1549
1550static void test_GdipCloneImage(void)
1551{
1552 GpStatus stat;
1553 GpRectF rectF;
1554 GpUnit unit;
1555 GpBitmap *bm;
1556 GpImage *image_src, *image_dest = NULL;
1557 const INT WIDTH = 10, HEIGHT = 20;
1558
1559 /* Create an image, clone it, delete the original, make sure the copy works */
1561 expect(Ok, stat);
1562 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bm, __LINE__, FALSE);
1563
1564 image_src = ((GpImage*)bm);
1565 stat = GdipCloneImage(image_src, &image_dest);
1566 expect(Ok, stat);
1567 expect_rawformat(&ImageFormatMemoryBMP, image_dest, __LINE__, FALSE);
1568
1570 expect(Ok, stat);
1571 stat = GdipGetImageBounds(image_dest, &rectF, &unit);
1572 expect(Ok, stat);
1573
1574 /* Treat FP values carefully */
1575 expectf((REAL)WIDTH, rectF.Width);
1576 expectf((REAL)HEIGHT, rectF.Height);
1577
1578 stat = GdipDisposeImage(image_dest);
1579 expect(Ok, stat);
1580}
1581
1582static void test_testcontrol(void)
1583{
1584 GpStatus stat;
1585 DWORD param;
1586
1587 param = 0;
1589 expect(Ok, stat);
1590 ok(param != 0, "Build number expected, got %lu\n", param);
1591}
1592
1593static void test_fromhicon(void)
1594{
1595 BYTE bmp_bits[1024], bmp_bits_masked[1024];
1596 HBITMAP hbmMask, hbmColor;
1597 ICONINFO info, iconinfo_base = {TRUE, 0, 0, 0, 0};
1598 HICON hIcon;
1599 GpStatus stat;
1600 GpBitmap *bitmap = NULL;
1601 UINT i;
1602
1603 for (i = 0; i < sizeof(bmp_bits); ++i)
1604 bmp_bits[i] = 111 * i;
1605
1606 /* NULL */
1611
1612 /* monochrome icon */
1613 hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
1614 ok(hbmMask != 0, "CreateBitmap failed\n");
1615 hbmColor = CreateBitmap(16, 16, 1, 1, bmp_bits);
1616 ok(hbmColor != 0, "CreateBitmap failed\n");
1617
1618 info = iconinfo_base;
1619 info.hbmMask = hbmMask;
1620 info.hbmColor = hbmColor;
1622 ok(hIcon != 0, "CreateIconIndirect failed\n");
1623
1625 ok(stat == Ok ||
1626 broken(stat == InvalidParameter), /* Win98 */
1627 "Expected Ok, got %.8x\n", stat);
1628 if(stat == Ok){
1629 expect_image_properties((GpImage*)bitmap, 16, 16, __LINE__);
1630 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1632 }
1634
1635 /* monochrome cursor */
1636 info.fIcon = FALSE;
1637 info.xHotspot = 8;
1638 info.yHotspot = 8;
1639 info.hbmMask = hbmMask;
1640 info.hbmColor = hbmColor;
1642 ok(hIcon != 0, "CreateIconIndirect failed\n");
1643
1646 if (stat == Ok)
1649
1650 /* mask-only icon */
1651 info = iconinfo_base;
1652 info.hbmMask = hbmMask;
1654 ok(hIcon != 0, "CreateIconIndirect failed\n");
1655
1659
1660 DeleteObject(hbmMask);
1661 DeleteObject(hbmColor);
1662
1663 /* 8 bpp icon */
1664 hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
1665 ok(hbmMask != 0, "CreateBitmap failed\n");
1666 hbmColor = CreateBitmap(16, 16, 1, 8, bmp_bits);
1667 ok(hbmColor != 0, "CreateBitmap failed\n");
1668
1669 info = iconinfo_base;
1670 info.hbmMask = hbmMask;
1671 info.hbmColor = hbmColor;
1673 ok(hIcon != 0, "CreateIconIndirect failed\n");
1674 DeleteObject(hbmMask);
1675 DeleteObject(hbmColor);
1676
1678 expect(Ok, stat);
1679 if(stat == Ok){
1680 expect_image_properties((GpImage*)bitmap, 16, 16, __LINE__);
1681 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1683 }
1685
1686 /* 32 bpp icon */
1687 hbmMask = CreateBitmap(16, 16, 1, 1, bmp_bits);
1688 ok(hbmMask != 0, "CreateBitmap failed\n");
1689 hbmColor = CreateBitmap(16, 16, 1, 32, bmp_bits);
1690 ok(hbmColor != 0, "CreateBitmap failed\n");
1691 info = iconinfo_base;
1692 info.hbmMask = hbmMask;
1693 info.hbmColor = hbmColor;
1695 ok(hIcon != 0, "CreateIconIndirect failed\n");
1696 DeleteObject(hbmMask);
1697 DeleteObject(hbmColor);
1698
1699 for (i = 0; i < sizeof(bmp_bits_masked)/sizeof(ARGB); i++)
1700 {
1701 BYTE mask = bmp_bits[i / 8] & (1 << (7 - (i % 8)));
1702 ((ARGB *)bmp_bits_masked)[i] = mask ? 0 : ((ARGB *)bmp_bits)[i] | 0xff000000;
1703 }
1704
1706 expect(Ok, stat);
1707 if(stat == Ok){
1708 expect_image_properties((GpImage*)bitmap, 16, 16, __LINE__);
1709 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1710 expect_bitmap_locked_data(bitmap, bmp_bits_masked, 16, 16, 64, __LINE__);
1712 }
1714
1715 /* non-square 32 bpp icon */
1716 hbmMask = CreateBitmap(16, 8, 1, 1, bmp_bits);
1717 ok(hbmMask != 0, "CreateBitmap failed\n");
1718 hbmColor = CreateBitmap(16, 8, 1, 32, bmp_bits);
1719 ok(hbmColor != 0, "CreateBitmap failed\n");
1720 info = iconinfo_base;
1721 info.hbmMask = hbmMask;
1722 info.hbmColor = hbmColor;
1724 ok(hIcon != 0, "CreateIconIndirect failed\n");
1725 DeleteObject(hbmMask);
1726 DeleteObject(hbmColor);
1727
1729 expect(Ok, stat);
1730 if(stat == Ok){
1731 expect_image_properties((GpImage*)bitmap, 16, 8, __LINE__);
1732 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bitmap, __LINE__, FALSE);
1733 expect_bitmap_locked_data(bitmap, bmp_bits_masked, 16, 8, 64, __LINE__);
1735 }
1737}
1738
1739/* 1x1 pixel png */
1740static const unsigned char pngimage[285] = {
17410x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
17420x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
17430xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
17440x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
17450x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
17460x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
17470xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
1748};
1749/* 1x1 pixel gif */
1750static const unsigned char gifimage[35] = {
17510x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
17520xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
17530x01,0x00,0x3b
1754};
1755/* 1x1 pixel transparent gif */
1756static const unsigned char transparentgif[] = {
17570x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xf0,0x00,0x00,0x00,0x00,0x00,
17580x00,0x00,0x00,0x21,0xf9,0x04,0x01,0x00,0x00,0x00,0x00,0x2c,0x00,0x00,0x00,0x00,
17590x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
1760};
1761/* 1x1 pixel bmp */
1762static const unsigned char bmpimage[66] = {
17630x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
17640x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
17650x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
17660x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
17670x00,0x00
1768};
1769/* 1x1 pixel jpg */
1770static const unsigned char jpgimage[285] = {
17710xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
17720x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
17730x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
17740x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
17750x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
17760x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
17770x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
17780x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
17790x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
17800x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
17810x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
17820x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
17830x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
17840x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
17850x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
17860x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
17870x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
17880x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
1789};
1790/* 1x1 pixel tiff */
1791static const unsigned char tiffimage[] = {
17920x49,0x49,0x2a,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xfe,0x00,
17930x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x01,0x00,
17940x00,0x00,0x01,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
17950x00,0x00,0x02,0x01,0x03,0x00,0x03,0x00,0x00,0x00,0xd2,0x00,0x00,0x00,0x03,0x01,
17960x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,0x01,0x03,0x00,0x01,0x00,
17970x00,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x02,0x00,0x1b,0x00,0x00,0x00,0xd8,0x00,
17980x00,0x00,0x11,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x12,0x01,
17990x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x15,0x01,0x03,0x00,0x01,0x00,
18000x00,0x00,0x03,0x00,0x00,0x00,0x16,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x40,0x00,
18010x00,0x00,0x17,0x01,0x04,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x1a,0x01,
18020x05,0x00,0x01,0x00,0x00,0x00,0xf4,0x00,0x00,0x00,0x1b,0x01,0x05,0x00,0x01,0x00,
18030x00,0x00,0xfc,0x00,0x00,0x00,0x1c,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x01,0x00,
18040x00,0x00,0x28,0x01,0x03,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
18050x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x2f,0x68,0x6f,0x6d,0x65,0x2f,0x6d,0x65,
18060x68,0x2f,0x44,0x65,0x73,0x6b,0x74,0x6f,0x70,0x2f,0x74,0x65,0x73,0x74,0x2e,0x74,
18070x69,0x66,0x00,0x00,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x48,
18080x00,0x00,0x00,0x01
1809};
1810/* 320x320 twip wmf */
1811static const unsigned char wmfimage[180] = {
18120xd7,0xcd,0xc6,0x9a,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x01,0x40,0x01,0xa0,0x05,
18130x00,0x00,0x00,0x00,0xb1,0x52,0x01,0x00,0x09,0x00,0x00,0x03,0x4f,0x00,0x00,0x00,
18140x0f,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0b,0x02,0x00,0x00,
18150x00,0x00,0x05,0x00,0x00,0x00,0x0c,0x02,0x40,0x01,0x40,0x01,0x04,0x00,0x00,0x00,
18160x02,0x01,0x01,0x00,0x04,0x00,0x00,0x00,0x04,0x01,0x0d,0x00,0x08,0x00,0x00,0x00,
18170xfa,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
18180x2d,0x01,0x00,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,0x01,0x00,0x00,0x00,0x00,0x00,
18190x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x01,0x00,0x07,0x00,0x00,0x00,0xfc,0x02,
18200x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x2d,0x01,0x02,0x00,
18210x07,0x00,0x00,0x00,0x1b,0x04,0x40,0x01,0x40,0x01,0x00,0x00,0x00,0x00,0x04,0x00,
18220x00,0x00,0xf0,0x01,0x00,0x00,0x04,0x00,0x00,0x00,0xf0,0x01,0x01,0x00,0x03,0x00,
18230x00,0x00,0x00,0x00
1824};
1825static void test_getrawformat(void)
1826{
1827 test_bufferrawformat((void*)pngimage, sizeof(pngimage), &ImageFormatPNG, __LINE__, FALSE);
1828 test_bufferrawformat((void*)gifimage, sizeof(gifimage), &ImageFormatGIF, __LINE__, FALSE);
1829 test_bufferrawformat((void*)bmpimage, sizeof(bmpimage), &ImageFormatBMP, __LINE__, FALSE);
1830 test_bufferrawformat((void*)jpgimage, sizeof(jpgimage), &ImageFormatJPEG, __LINE__, FALSE);
1831 test_bufferrawformat((void*)tiffimage, sizeof(tiffimage), &ImageFormatTIFF, __LINE__, FALSE);
1832 test_bufferrawformat((void*)wmfimage, sizeof(wmfimage), &ImageFormatWMF, __LINE__, FALSE);
1833}
1834
1835static void test_loadwmf(void)
1836{
1838 HGLOBAL hglob;
1839 LPBYTE data;
1840 HRESULT hres;
1841 GpStatus stat;
1842 GpImage *img;
1843 GpRectF bounds;
1844 GpUnit unit;
1845 REAL res = 12345.0;
1847
1848 hglob = GlobalAlloc (0, sizeof(wmfimage));
1849 data = GlobalLock (hglob);
1850 memcpy(data, wmfimage, sizeof(wmfimage));
1851 GlobalUnlock(hglob); data = NULL;
1852
1854 ok(hres == S_OK, "Failed to create a stream\n");
1855 if(hres != S_OK) return;
1856
1858 ok(stat == Ok, "Failed to create a Bitmap\n");
1859 if(stat != Ok){
1860 IStream_Release(stream);
1861 return;
1862 }
1863
1864 IStream_Release(stream);
1865
1866 stat = GdipGetImageBounds(img, &bounds, &unit);
1867 expect(Ok, stat);
1869 expectf(0.0, bounds.X);
1870 expectf(0.0, bounds.Y);
1871 expectf(320.0, bounds.Width);
1872 expectf(320.0, bounds.Height);
1873
1875 expect(Ok, stat);
1876 expectf(1440.0, res);
1877
1879 expect(Ok, stat);
1880 expectf(1440.0, res);
1881
1882 memset(&header, 0, sizeof(header));
1884 expect(Ok, stat);
1885 if (stat == Ok)
1886 {
1888 todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1889 todo_wine expect(0x300, header.Version);
1890 expect(0, header.EmfPlusFlags);
1891 expectf(1440.0, header.DpiX);
1892 expectf(1440.0, header.DpiY);
1893 expect(0, header.X);
1894 expect(0, header.Y);
1895 expect(320, header.Width);
1896 expect(320, header.Height);
1897 expect(1, header.WmfHeader.mtType);
1898 expect(0, header.EmfPlusHeaderSize);
1899 expect(0, header.LogicalDpiX);
1900 expect(0, header.LogicalDpiY);
1901 }
1902
1904}
1905
1906static void test_createfromwmf(void)
1907{
1908 HMETAFILE hwmf;
1909 GpImage *img;
1910 GpStatus stat;
1911 GpRectF bounds;
1912 GpUnit unit;
1913 REAL res = 12345.0;
1915
1916 hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
1918 ok(hwmf != 0, "SetMetaFileBitsEx failed\n");
1919
1922 expect(Ok, stat);
1923
1924 stat = GdipGetImageBounds(img, &bounds, &unit);
1925 expect(Ok, stat);
1927 expectf(0.0, bounds.X);
1928 expectf(0.0, bounds.Y);
1929 expectf(320.0, bounds.Width);
1930 expectf(320.0, bounds.Height);
1931
1933 expect(Ok, stat);
1934 expectf(1440.0, res);
1935
1937 expect(Ok, stat);
1938 expectf(1440.0, res);
1939
1940 memset(&header, 0, sizeof(header));
1942 expect(Ok, stat);
1943 if (stat == Ok)
1944 {
1946 todo_wine expect(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader), header.Size);
1947 todo_wine expect(0x300, header.Version);
1948 expect(0, header.EmfPlusFlags);
1949 expectf(1440.0, header.DpiX);
1950 expectf(1440.0, header.DpiY);
1951 expect(0, header.X);
1952 expect(0, header.Y);
1953 expect(320, header.Width);
1954 expect(320, header.Height);
1955 expect(1, header.WmfHeader.mtType);
1956 expect(0, header.EmfPlusHeaderSize);
1957 expect(0, header.LogicalDpiX);
1958 expect(0, header.LogicalDpiY);
1959 }
1960
1962}
1963
1965{
1966 HMETAFILE hwmf;
1967 GpImage *img;
1968 GpStatus stat;
1969
1970 hwmf = SetMetaFileBitsEx(sizeof(wmfimage)-sizeof(WmfPlaceableFileHeader),
1972 ok(hwmf != 0, "SetMetaFileBitsEx failed\n");
1973
1975 expect(Ok, stat);
1976
1978}
1979
1980static void test_resolution(void)
1981{
1982 GpStatus stat;
1984 GpGraphics *graphics;
1985 REAL res=-1.0;
1986 HDC screendc;
1987 int screenxres, screenyres;
1988
1989 /* create Bitmap */
1991 expect(Ok, stat);
1992
1993 /* test invalid values */
1996
1999
2002
2005
2006 stat = GdipBitmapSetResolution(NULL, 96.0, 96.0);
2008
2009 stat = GdipBitmapSetResolution(bitmap, 0.0, 0.0);
2011
2012 /* defaults to screen resolution */
2013 screendc = GetDC(0);
2014
2015 screenxres = GetDeviceCaps(screendc, LOGPIXELSX);
2016 screenyres = GetDeviceCaps(screendc, LOGPIXELSY);
2017
2018 ReleaseDC(0, screendc);
2019
2021 expect(Ok, stat);
2022 expectf((REAL)screenxres, res);
2023
2025 expect(Ok, stat);
2026 expectf((REAL)screenyres, res);
2027
2029 expect(Ok, stat);
2030 stat = GdipGetDpiX(graphics, &res);
2031 expect(Ok, stat);
2032 expectf((REAL)screenxres, res);
2033 stat = GdipGetDpiY(graphics, &res);
2034 expect(Ok, stat);
2035 expectf((REAL)screenyres, res);
2036
2037 /* test changing the resolution */
2038 stat = GdipBitmapSetResolution(bitmap, screenxres*2.0, screenyres*3.0);
2039 expect(Ok, stat);
2040
2042 expect(Ok, stat);
2043 expectf(screenxres*2.0, res);
2044
2046 expect(Ok, stat);
2047 expectf(screenyres*3.0, res);
2048
2049 stat = GdipGetDpiX(graphics, &res);
2050 expect(Ok, stat);
2051 expectf((REAL)screenxres, res);
2052 stat = GdipGetDpiY(graphics, &res);
2053 expect(Ok, stat);
2054 expectf((REAL)screenyres, res);
2055
2056 stat = GdipDeleteGraphics(graphics);
2057 expect(Ok, stat);
2058
2060 expect(Ok, stat);
2061 stat = GdipGetDpiX(graphics, &res);
2062 expect(Ok, stat);
2063 expectf(screenxres*2.0, res);
2064 stat = GdipGetDpiY(graphics, &res);
2065 expect(Ok, stat);
2066 expectf(screenyres*3.0, res);
2067 stat = GdipDeleteGraphics(graphics);
2068 expect(Ok, stat);
2069
2071 expect(Ok, stat);
2072}
2073
2074static void test_createhbitmap(void)
2075{
2076 GpStatus stat;
2078 HBITMAP hbitmap, oldhbitmap;
2079 BITMAP bm;
2080 int ret;
2081 HDC hdc;
2082 COLORREF pixel;
2083 BYTE bits[640];
2084 BitmapData lockeddata;
2085
2086 memset(bits, 0x68, 640);
2087
2088 /* create Bitmap */
2090 expect(Ok, stat);
2091
2092 /* test NULL values */
2095
2098
2099 /* create HBITMAP */
2101 expect(Ok, stat);
2102
2103 if (stat == Ok)
2104 {
2105 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
2106 expect(sizeof(BITMAP), ret);
2107
2108 expect(0, bm.bmType);
2109 expect(10, bm.bmWidth);
2110 expect(20, bm.bmHeight);
2111 expect(40, bm.bmWidthBytes);
2112 expect(1, bm.bmPlanes);
2113 expect(32, bm.bmBitsPixel);
2114 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
2115
2116 if (bm.bmBits)
2117 {
2118 DWORD val = *(DWORD*)bm.bmBits;
2119 ok(val == 0xff686868, "got %lx, expected 0xff686868\n", val);
2120 }
2121
2123
2124 oldhbitmap = SelectObject(hdc, hbitmap);
2125 pixel = GetPixel(hdc, 5, 5);
2126 SelectObject(hdc, oldhbitmap);
2127
2128 DeleteDC(hdc);
2129
2130 expect(0x686868, pixel);
2131
2133 }
2134
2136 expect(Ok, stat);
2137
2138 /* make (1,0) have no alpha and (2,0) a different blue value. */
2139 bits[7] = 0x00;
2140 bits[8] = 0x40;
2141
2142 /* create alpha Bitmap */
2144 expect(Ok, stat);
2145
2146 /* create HBITMAP */
2148 expect(Ok, stat);
2149
2150 if (stat == Ok)
2151 {
2152 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
2153 expect(sizeof(BITMAP), ret);
2154
2155 expect(0, bm.bmType);
2156 expect(8, bm.bmWidth);
2157 expect(20, bm.bmHeight);
2158 expect(32, bm.bmWidthBytes);
2159 expect(1, bm.bmPlanes);
2160 expect(32, bm.bmBitsPixel);
2161 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
2162
2163 if (bm.bmBits)
2164 {
2165 DWORD val = *(DWORD*)bm.bmBits;
2166 ok(val == 0x682a2a2a, "got %lx, expected 0x682a2a2a\n", val);
2167 val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
2168 ok(val == 0x0, "got %lx, expected 0x682a2a2a\n", val);
2169 }
2170
2172
2173 oldhbitmap = SelectObject(hdc, hbitmap);
2174 pixel = GetPixel(hdc, 5, 5);
2175 expect(0x2a2a2a, pixel);
2176 pixel = GetPixel(hdc, 1, 0);
2177 expect(0x0, pixel);
2178
2179 SelectObject(hdc, oldhbitmap);
2180
2181 DeleteDC(hdc);
2182
2183
2185 }
2186
2187 /* create HBITMAP with bkgnd colour */
2188 /* gdiplus.dll 5.1 is broken and only applies the blue value */
2190 expect(Ok, stat);
2191
2192 if (stat == Ok)
2193 {
2194 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
2195 expect(sizeof(BITMAP), ret);
2196
2197 expect(0, bm.bmType);
2198 expect(8, bm.bmWidth);
2199 expect(20, bm.bmHeight);
2200 expect(32, bm.bmWidthBytes);
2201 expect(1, bm.bmPlanes);
2202 expect(32, bm.bmBitsPixel);
2203 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
2204
2205 if (bm.bmBits)
2206 {
2207 DWORD val = *(DWORD*)bm.bmBits;
2208 ok(val == 0x68c12ac1 || broken(val == 0x682a2ac1), "got %lx, expected 0x68c12ac1\n", val);
2209 val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
2210 ok(val == 0xff00ff || broken(val == 0xff), "got %lx, expected 0xff00ff\n", val);
2211 }
2212
2214
2215 oldhbitmap = SelectObject(hdc, hbitmap);
2216 pixel = GetPixel(hdc, 5, 5);
2217 ok(pixel == 0xc12ac1 || broken(pixel == 0xc12a2a), "got %lx, expected 0xc12ac1\n", pixel);
2218 pixel = GetPixel(hdc, 1, 0);
2219 ok(pixel == 0xff00ff || broken(pixel == 0xff0000), "got %lx, expected 0xff00ff\n", pixel);
2220 pixel = GetPixel(hdc, 2, 0);
2221 ok(pixel == 0xb12ac1 || broken(pixel == 0xb12a2a), "got %lx, expected 0xb12ac1\n", pixel);
2222
2223 SelectObject(hdc, oldhbitmap);
2224 DeleteDC(hdc);
2226 }
2227
2228 /* create HBITMAP with bkgnd colour with alpha and show it behaves with no alpha. */
2230 expect(Ok, stat);
2231
2232 if (stat == Ok)
2233 {
2234 ret = GetObjectA(hbitmap, sizeof(BITMAP), &bm);
2235 expect(sizeof(BITMAP), ret);
2236
2237 expect(0, bm.bmType);
2238 expect(8, bm.bmWidth);
2239 expect(20, bm.bmHeight);
2240 expect(32, bm.bmWidthBytes);
2241 expect(1, bm.bmPlanes);
2242 expect(32, bm.bmBitsPixel);
2243 ok(bm.bmBits != NULL, "got DDB, expected DIB\n");
2244
2245 if (bm.bmBits)
2246 {
2247 DWORD val = *(DWORD*)bm.bmBits;
2248 ok(val == 0x68c12ac1 || broken(val == 0x682a2ac1), "got %lx, expected 0x68c12ac1\n", val);
2249 val = *((DWORD*)bm.bmBits + (bm.bmHeight-1) * bm.bmWidthBytes/4 + 1);
2250 ok(val == 0xff00ff || broken(val == 0xff), "got %lx, expected 0xff00ff\n", val);
2251 }
2252
2254
2255 oldhbitmap = SelectObject(hdc, hbitmap);
2256 pixel = GetPixel(hdc, 5, 5);
2257 ok(pixel == 0xc12ac1 || broken(pixel == 0xc12a2a), "got %lx, expected 0xc12ac1\n", pixel);
2258 pixel = GetPixel(hdc, 1, 0);
2259 ok(pixel == 0xff00ff || broken(pixel == 0xff0000), "got %lx, expected 0xff00ff\n", pixel);
2260 pixel = GetPixel(hdc, 2, 0);
2261 ok(pixel == 0xb12ac1 || broken(pixel == 0xb12a2a), "got %lx, expected 0xb12ac1\n", pixel);
2262
2263 SelectObject(hdc, oldhbitmap);
2264 DeleteDC(hdc);
2266 }
2267
2269 expect(Ok, stat);
2270
2271 /* create HBITMAP from locked data */
2272 memset(bits, 0x68, 640);
2274 expect(Ok, stat);
2275
2276 memset(&lockeddata, 0, sizeof(lockeddata));
2278 PixelFormat32bppRGB, &lockeddata);
2279 expect(Ok, stat);
2280 ((DWORD*)lockeddata.Scan0)[0] = 0xff242424;
2282 expect(Ok, stat);
2283 stat = GdipBitmapUnlockBits(bitmap, &lockeddata);
2284 expect(Ok, stat);
2286 expect(Ok, stat);
2287
2289 oldhbitmap = SelectObject(hdc, hbitmap);
2290 pixel = GetPixel(hdc, 0, 0);
2291 expect(0x686868, pixel);
2292 SelectObject(hdc, oldhbitmap);
2293 DeleteDC(hdc);
2294}
2295
2296static void test_getthumbnail(void)
2297{
2298 GpStatus stat;
2299 GpImage *bitmap1, *bitmap2;
2300 UINT width, height;
2301
2304
2305 stat = GdipCreateBitmapFromScan0(128, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
2306 expect(Ok, stat);
2307
2308 stat = GdipGetImageThumbnail(bitmap1, 0, 0, NULL, NULL, NULL);
2310
2311 stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
2312 expect(Ok, stat);
2313
2314 if (stat == Ok)
2315 {
2317 expect(Ok, stat);
2318 expect(120, width);
2319
2321 expect(Ok, stat);
2322 expect(120, height);
2323
2325 }
2326
2327 GdipDisposeImage(bitmap1);
2328
2329
2330 stat = GdipCreateBitmapFromScan0(64, 128, 0, PixelFormat32bppRGB, NULL, (GpBitmap**)&bitmap1);
2331 expect(Ok, stat);
2332
2333 stat = GdipGetImageThumbnail(bitmap1, 32, 32, &bitmap2, NULL, NULL);
2334 expect(Ok, stat);
2335
2336 if (stat == Ok)
2337 {
2339 expect(Ok, stat);
2340 expect(32, width);
2341
2343 expect(Ok, stat);
2344 expect(32, height);
2345
2347 }
2348
2349 stat = GdipGetImageThumbnail(bitmap1, 0, 0, &bitmap2, NULL, NULL);
2350 expect(Ok, stat);
2351
2352 if (stat == Ok)
2353 {
2355 expect(Ok, stat);
2356 expect(120, width);
2357
2359 expect(Ok, stat);
2360 expect(120, height);
2361
2363 }
2364
2365 GdipDisposeImage(bitmap1);
2366}
2367
2368static void test_getsetpixel(void)
2369{
2370 GpStatus stat;
2372 ARGB color;
2373 BYTE bits[16] = {0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0x00,
2374 0xff,0x00,0x00,0x00, 0xff,0xff,0xff,0x00};
2375
2377 expect(Ok, stat);
2378
2379 /* null parameters */
2380 stat = GdipBitmapGetPixel(NULL, 1, 1, &color);
2382
2385
2386 stat = GdipBitmapSetPixel(NULL, 1, 1, 0);
2388
2389 /* out of bounds */
2390 stat = GdipBitmapGetPixel(bitmap, -1, 1, &color);
2392
2393 stat = GdipBitmapSetPixel(bitmap, -1, 1, 0);
2395
2396 stat = GdipBitmapGetPixel(bitmap, 1, -1, &color);
2398 broken(stat == Ok), /* Older gdiplus */
2399 "Expected InvalidParameter, got %.8x\n", stat);
2400
2401if (0) /* crashes some gdiplus implementations */
2402{
2403 stat = GdipBitmapSetPixel(bitmap, 1, -1, 0);
2405 broken(stat == Ok), /* Older gdiplus */
2406 "Expected InvalidParameter, got %.8x\n", stat);
2407}
2408
2411
2412 stat = GdipBitmapSetPixel(bitmap, 2, 1, 0);
2414
2417
2418 stat = GdipBitmapSetPixel(bitmap, 1, 2, 0);
2420
2421 /* valid use */
2423 expect(Ok, stat);
2424 expect(0xffffffff, color);
2425
2427 expect(Ok, stat);
2428 expect(0xff0000ff, color);
2429
2430 stat = GdipBitmapSetPixel(bitmap, 1, 1, 0xff676869);
2431 expect(Ok, stat);
2432
2433 stat = GdipBitmapSetPixel(bitmap, 0, 0, 0xff474849);
2434 expect(Ok, stat);
2435
2437 expect(Ok, stat);
2438 expect(0xff676869, color);
2439
2441 expect(Ok, stat);
2442 expect(0xff474849, color);
2443
2445 expect(Ok, stat);
2446}
2447
2449{
2450 static const BYTE halftone_values[6]={0x00,0x33,0x66,0x99,0xcc,0xff};
2451 UINT i;
2452
2453 for (i=0; i<palette->Count; i++)
2454 {
2455 ARGB expected=0xff000000;
2456 if (i<8)
2457 {
2458 if (i&1) expected |= 0x800000;
2459 if (i&2) expected |= 0x8000;
2460 if (i&4) expected |= 0x80;
2461 }
2462 else if (i == 8)
2463 {
2464 expected = 0xffc0c0c0;
2465 }
2466 else if (i < 16)
2467 {
2468 if (i&1) expected |= 0xff0000;
2469 if (i&2) expected |= 0xff00;
2470 if (i&4) expected |= 0xff;
2471 }
2472 else if (i < 40)
2473 {
2474 expected = 0x00000000;
2475 }
2476 else
2477 {
2478 expected |= halftone_values[(i-40)%6];
2479 expected |= halftone_values[((i-40)/6)%6] << 8;
2480 expected |= halftone_values[((i-40)/36)%6] << 16;
2481 }
2482 ok(expected == palette->Entries[i], "Expected %.8lx, got %.8lx, i=%u/%u\n",
2483 expected, palette->Entries[i], i, palette->Count);
2484 }
2485}
2486
2487static void test_palette(void)
2488{
2489 GpStatus stat;
2491 INT size;
2492 BYTE buffer[1040];
2494 ARGB *entries = palette->Entries;
2495 ARGB color=0;
2496
2497 /* test initial palette from non-indexed bitmap */
2499 expect(Ok, stat);
2500
2502 expect(Ok, stat);
2503 expect(sizeof(UINT)*2+sizeof(ARGB), size);
2504
2506 expect(Ok, stat);
2507 expect(0, palette->Count);
2508
2509 /* test setting palette on not-indexed bitmap */
2510 palette->Count = 3;
2511
2513 expect(Ok, stat);
2514
2516 expect(Ok, stat);
2517 expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
2518
2520 expect(Ok, stat);
2521 expect(3, palette->Count);
2522
2524
2525 /* test initial palette on 1-bit bitmap */
2527 expect(Ok, stat);
2528
2530 expect(Ok, stat);
2531 expect(sizeof(UINT)*2+sizeof(ARGB)*2, size);
2532
2534 expect(Ok, stat);
2536 expect(2, palette->Count);
2537
2538 expect(0xff000000, entries[0]);
2539 expect(0xffffffff, entries[1]);
2540
2541 /* test getting/setting pixels */
2543 expect(Ok, stat);
2544 expect(0xff000000, color);
2545
2546 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffffffff);
2547 ok((stat == Ok) ||
2548 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2549
2550 if (stat == Ok)
2551 {
2553 expect(Ok, stat);
2554 expect(0xffffffff, color);
2555 }
2556
2558
2559 /* test initial palette on 4-bit bitmap */
2561 expect(Ok, stat);
2562
2564 expect(Ok, stat);
2565 expect(sizeof(UINT)*2+sizeof(ARGB)*16, size);
2566
2568 expect(Ok, stat);
2569 expect(0, palette->Flags);
2570 expect(16, palette->Count);
2571
2573
2574 /* test getting/setting pixels */
2576 expect(Ok, stat);
2577 expect(0xff000000, color);
2578
2579 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffff00ff);
2580 ok((stat == Ok) ||
2581 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2582
2583 if (stat == Ok)
2584 {
2586 expect(Ok, stat);
2587 expect(0xffff00ff, color);
2588 }
2589
2591
2592 /* test initial palette on 8-bit bitmap */
2594 expect(Ok, stat);
2595
2597 expect(Ok, stat);
2598 expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
2599
2601 expect(Ok, stat);
2603 expect(256, palette->Count);
2604
2606
2607 /* test getting/setting pixels */
2609 expect(Ok, stat);
2610 expect(0xff000000, color);
2611
2612 stat = GdipBitmapSetPixel(bitmap, 0, 1, 0xffcccccc);
2613 ok((stat == Ok) ||
2614 broken(stat == InvalidParameter) /* pre-win7 */, "stat=%.8x\n", stat);
2615
2616 if (stat == Ok)
2617 {
2619 expect(Ok, stat);
2620 expect(0xffcccccc, color);
2621 }
2622
2623 /* test setting/getting a different palette */
2624 entries[1] = 0xffcccccc;
2625
2627 expect(Ok, stat);
2628
2629 entries[1] = 0;
2630
2632 expect(Ok, stat);
2633 expect(sizeof(UINT)*2+sizeof(ARGB)*256, size);
2634
2636 expect(Ok, stat);
2638 expect(256, palette->Count);
2639 expect(0xffcccccc, entries[1]);
2640
2641 /* test count < 256 */
2642 palette->Flags = 12345;
2643 palette->Count = 3;
2644
2646 expect(Ok, stat);
2647
2648 entries[1] = 0;
2649 entries[3] = 0xdeadbeef;
2650
2652 expect(Ok, stat);
2653 expect(sizeof(UINT)*2+sizeof(ARGB)*3, size);
2654
2656 expect(Ok, stat);
2657 expect(12345, palette->Flags);
2658 expect(3, palette->Count);
2659 expect(0xffcccccc, entries[1]);
2660 expect(0xdeadbeef, entries[3]);
2661
2662 /* test count > 256 */
2663 palette->Count = 257;
2664
2667 broken(stat == Ok), /* Old gdiplus behavior */
2668 "Expected %.8x, got %.8x\n", InvalidParameter, stat);
2669
2671}
2672
2673static void test_colormatrix(void)
2674{
2675 GpStatus stat;
2676 ColorMatrix colormatrix, graymatrix;
2677 GpImageAttributes *imageattr;
2678 const ColorMatrix identity = {{
2679 {1.0,0.0,0.0,0.0,0.0},
2680 {0.0,1.0,0.0,0.0,0.0},
2681 {0.0,0.0,1.0,0.0,0.0},
2682 {0.0,0.0,0.0,1.0,0.0},
2683 {0.0,0.0,0.0,0.0,1.0}}};
2684 const ColorMatrix double_red = {{
2685 {2.0,0.0,0.0,0.0,0.0},
2686 {0.0,1.0,0.0,0.0,0.0},
2687 {0.0,0.0,1.0,0.0,0.0},
2688 {0.0,0.0,0.0,1.0,0.0},
2689 {0.0,0.0,0.0,0.0,1.0}}};
2690 const ColorMatrix asymmetric = {{
2691 {0.0,1.0,0.0,0.0,0.0},
2692 {0.0,0.0,1.0,0.0,0.0},
2693 {0.0,0.0,0.0,1.0,0.0},
2694 {1.0,0.0,0.0,0.0,0.0},
2695 {0.0,0.0,0.0,0.0,1.0}}};
2696 GpBitmap *bitmap1, *bitmap2;
2697 GpGraphics *graphics;
2698 ARGB color;
2699
2700 colormatrix = identity;
2701 graymatrix = identity;
2702
2704 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2706
2707 stat = GdipCreateImageAttributes(&imageattr);
2708 expect(Ok, stat);
2709
2711 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2712 expect(Ok, stat);
2713
2717
2719 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2720 expect(Ok, stat);
2721
2723 TRUE, &colormatrix, NULL, ColorMatrixFlagsSkipGrays);
2724 expect(Ok, stat);
2725
2727 TRUE, &colormatrix, NULL, ColorMatrixFlagsAltGray);
2729
2731 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsAltGray);
2732 expect(Ok, stat);
2733
2735 TRUE, &colormatrix, &graymatrix, 3);
2737
2739 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2741
2743 TRUE, &colormatrix, &graymatrix, ColorMatrixFlagsDefault);
2745
2748 expect(Ok, stat);
2749
2750 /* Drawing a bitmap transforms the colors */
2751 colormatrix = double_red;
2753 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2754 expect(Ok, stat);
2755
2757 expect(Ok, stat);
2758
2760 expect(Ok, stat);
2761
2762 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff40ccee);
2763 expect(Ok, stat);
2764
2766 expect(Ok, stat);
2767
2768 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2769 UnitPixel, imageattr, NULL, NULL);
2770 expect(Ok, stat);
2771
2773 expect(Ok, stat);
2774 expect(0xff80ccee, color);
2775
2776 colormatrix = asymmetric;
2778 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2779 expect(Ok, stat);
2780
2781 stat = GdipBitmapSetPixel(bitmap2, 0, 0, 0);
2782 expect(Ok, stat);
2783
2784 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2785 UnitPixel, imageattr, NULL, NULL);
2786 expect(Ok, stat);
2787
2789 expect(Ok, stat);
2790 ok(color_match(0xeeff40cc, color, 3), "expected 0xeeff40cc, got 0x%08lx\n", color);
2791
2792 /* Toggle NoOp */
2794 expect(Ok, stat);
2795
2796 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2797 UnitPixel, imageattr, NULL, NULL);
2798 expect(Ok, stat);
2799
2801 expect(Ok, stat);
2802 ok(color_match(0xfefe40cc, color, 3), "expected 0xfefe40cc, got 0x%08lx\n", color);
2803
2805 expect(Ok, stat);
2806
2807 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2808 UnitPixel, imageattr, NULL, NULL);
2809 expect(Ok, stat);
2810
2812 expect(Ok, stat);
2813 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08lx\n", color);
2814
2816 expect(Ok, stat);
2817
2819 expect(Ok, stat);
2820
2821 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2822 UnitPixel, imageattr, NULL, NULL);
2823 expect(Ok, stat);
2824
2826 expect(Ok, stat);
2827 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08lx\n", color);
2828
2829 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2830 UnitPixel, imageattr, NULL, NULL);
2831 expect(Ok, stat);
2832
2834 expect(Ok, stat);
2835 ok(color_match(0xff40ccee, color, 1), "Expected ff40ccee, got %.8lx\n", color);
2836
2837 /* Disable adjustment, toggle NoOp */
2839 FALSE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2840 expect(Ok, stat);
2841
2843 expect(Ok, stat);
2844
2845 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2846 UnitPixel, imageattr, NULL, NULL);
2847 expect(Ok, stat);
2848
2850 expect(Ok, stat);
2851 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08lx\n", color);
2852
2854 expect(Ok, stat);
2855
2856 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2857 UnitPixel, imageattr, NULL, NULL);
2858 expect(Ok, stat);
2859
2861 expect(Ok, stat);
2862 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08lx\n", color);
2863
2864 /* Reset with NoOp on, enable adjustment. */
2866 expect(Ok, stat);
2867
2869 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2870 expect(Ok, stat);
2871
2872 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2873 UnitPixel, imageattr, NULL, NULL);
2874 expect(Ok, stat);
2875
2877 expect(Ok, stat);
2878 ok(color_match(0xfff24ace, color, 3), "expected 0xfff24ace, got 0x%08lx\n", color);
2879
2880 /* Now inhibit specific category. */
2882 expect(Ok, stat);
2883
2885 TRUE, &colormatrix, NULL, ColorMatrixFlagsDefault);
2886 expect(Ok, stat);
2887
2888 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2889 UnitPixel, imageattr, NULL, NULL);
2890 expect(Ok, stat);
2891
2893 expect(Ok, stat);
2894 ok(color_match(0xfffe41cc, color, 3), "expected 0xfffe41cc, got 0x%08lx\n", color);
2895
2897 expect(Ok, stat);
2898
2899 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2900 UnitPixel, imageattr, NULL, NULL);
2901 expect(Ok, stat);
2902
2904 expect(Ok, stat);
2905 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08lx\n", color);
2906
2908 expect(Ok, stat);
2909
2911 expect(Ok, stat);
2912
2913 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2914 UnitPixel, imageattr, NULL, NULL);
2915 expect(Ok, stat);
2916
2918 expect(Ok, stat);
2919 ok(color_match(0xfff24ace, color, 3), "expected 0xfff24ace, got 0x%08lx\n", color);
2920
2922 expect(Ok, stat);
2923
2924 stat = GdipDrawImageRectRectI(graphics, (GpImage *)bitmap1, 0, 0, 1, 1, 0, 0, 1, 1,
2925 UnitPixel, imageattr, NULL, NULL);
2926 expect(Ok, stat);
2927
2929 expect(Ok, stat);
2930 ok(color_match(0xff40ccee, color, 3), "expected 0xff40ccee, got 0x%08lx\n", color);
2931
2932 GdipDeleteGraphics(graphics);
2933 GdipDisposeImage((GpImage*)bitmap1);
2935 GdipDisposeImageAttributes(imageattr);
2936}
2937
2938static void test_gamma(void)
2939{
2940 GpStatus stat;
2941 GpImageAttributes *imageattr;
2942 GpBitmap *bitmap1, *bitmap2;
2943 GpGraphics *graphics;
2944 ARGB color;
2945
2948
2949 stat = GdipCreateImageAttributes(&imageattr);
2950 expect(Ok, stat);
2951
2953 expect(Ok, stat);
2954
2957
2960
2963
2965 expect(Ok, stat);
2966
2968 expect(Ok, stat);
2969
2970 /* Drawing a bitmap transforms the colors */
2972 expect(Ok, stat);
2973
2975 expect(Ok, stat);
2976
2978 expect(Ok, stat);
2979
2980 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff80ffff);
2981 expect(Ok, stat);
2982
2984 expect(Ok, stat);
2985
2986 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2987 UnitPixel, imageattr, NULL, NULL);
2988 expect(Ok, stat);
2989
2991 expect(Ok, stat);
2992 ok(color_match(0xff20ffff, color, 1), "Expected ff20ffff, got %.8lx\n", color);
2993
2995 expect(Ok, stat);
2996
2997 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
2998 UnitPixel, imageattr, NULL, NULL);
2999 expect(Ok, stat);
3000
3002 expect(Ok, stat);
3003 ok(color_match(0xff80ffff, color, 1), "Expected ff80ffff, got %.8lx\n", color);
3004
3005 GdipDeleteGraphics(graphics);
3006 GdipDisposeImage((GpImage*)bitmap1);
3008 GdipDisposeImageAttributes(imageattr);
3009}
3010
3011/* 1x1 pixel gif, 2 frames; first frame is white, second is black */
3012static const unsigned char gifanimation[72] = {
30130x47,0x49,0x46,0x38,0x39,0x61,0x01,0x00,0x01,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
30140xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0xf9,0x04,0x00,0x0a,0x00,0xff,
30150x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x4c,0x01,0x00,
30160x21,0xf9,0x04,0x01,0x0a,0x00,0x01,0x00,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,
30170x00,0x00,0x02,0x02,0x44,0x01,0x00,0x3b
3018};
3019
3020/* Generated with ImageMagick:
3021 * convert -transparent black -delay 100 -size 8x2 xc:black \
3022 * -dispose none -page +0+0 -size 2x2 xc:red \
3023 * -dispose background -page +2+0 -size 2x2 xc:blue \
3024 * -dispose previous -page +4+0 -size 2x2 xc:green \
3025 * -dispose undefined -page +6+0 -size 2x2 xc:gray \
3026 * test.gif
3027 * Background color index changed to 1.
3028 */
3029static const unsigned char gifanimation2[] = {
3030 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
3031 0x02, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00,
3032 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
3033 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
3034 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
3035 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
3036 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
3037 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
3038 0xf9, 0x04, 0x04, 0x64, 0x00, 0x00, 0x00, 0x2c,
3039 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
3040 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
3041 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
3042 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x08, 0x64,
3043 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
3044 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
3045 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
3046 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
3047 0xf9, 0x04, 0x0c, 0x64, 0x00, 0x00, 0x00, 0x2c,
3048 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
3049 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
3050 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
3051 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
3052 0x00, 0x00, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
3053 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
3054 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
3055 0x3b
3056};
3057
3059 {0, 0, 0, 0},
3060 {0xffff0000, 0, 0, 0},
3061 {0xffff0000, 0xff0000ff, 0, 0},
3062 {0xffff0000, 0, 0xff008000, 0},
3063 {0xffff0000, 0, 0, 0xff7e7e7e}
3064};
3065
3066static const unsigned char gifanimation3[] = {
3067 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x08, 0x00,
3068 0x02, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00,
3069 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x64,
3070 0x00, 0x00, 0x00, 0x21, 0xff, 0x0b, 0x4e, 0x45,
3071 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e,
3072 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00,
3073 0x00, 0x00, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00,
3074 0x02, 0x04, 0x84, 0x8f, 0x09, 0x05, 0x00, 0x21,
3075 0xf9, 0x04, 0x05, 0x64, 0x00, 0x10, 0x00, 0x2c,
3076 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
3077 0x81, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
3078 0x00, 0x00, 0xff, 0x00, 0x00, 0x02, 0x03, 0x44,
3079 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x09, 0x64,
3080 0x00, 0x10, 0x00, 0x2c, 0x02, 0x00, 0x00, 0x00,
3081 0x02, 0x00, 0x02, 0x00, 0x81, 0x00, 0x00, 0xff,
3082 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00,
3083 0xff, 0x02, 0x03, 0x44, 0x34, 0x05, 0x00, 0x21,
3084 0xf9, 0x04, 0x0d, 0x64, 0x00, 0x10, 0x00, 0x2c,
3085 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
3086 0x81, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
3087 0x80, 0x00, 0x00, 0x80, 0x00, 0x02, 0x03, 0x44,
3088 0x34, 0x05, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x64,
3089 0x00, 0x10, 0x00, 0x2c, 0x06, 0x00, 0x00, 0x00,
3090 0x02, 0x00, 0x02, 0x00, 0x80, 0x7e, 0x7e, 0x7e,
3091 0x00, 0x00, 0x00, 0x02, 0x02, 0x84, 0x51, 0x00,
3092 0x3b
3093};
3094
3096 {0xff000000, 0xff000000, 0xff000000, 0xff000000},
3097 {0xffff0000, 0xff000000, 0xff000000, 0xff000000},
3098 {0xffff0000, 0xff0000ff, 0xff000000, 0xff000000},
3099 {0xffff0000, 0xff000000, 0xff008000, 0xff000000},
3100 {0xffff0000, 0xff000000, 0xff000000, 0xff7e7e7e}
3101};
3102
3103static void test_multiframegif(void)
3104{
3106 HGLOBAL hglob;
3107 LPBYTE data;
3108 HRESULT hres;
3109 GpStatus stat;
3110 GpBitmap *bmp;
3111 ARGB color;
3112 UINT count;
3113 GUID dimension;
3115 INT palette_size, i, j;
3116 char palette_buf[256];
3118 ARGB *palette_entries;
3119
3120 /* Test frame functions with an animated GIF */
3121 hglob = GlobalAlloc (0, sizeof(gifanimation));
3122 data = GlobalLock (hglob);
3124 GlobalUnlock(hglob);
3125
3127 ok(hres == S_OK, "Failed to create a stream\n");
3128 if(hres != S_OK) return;
3129
3131 ok(stat == Ok, "Failed to create a Bitmap\n");
3132 if(stat != Ok){
3133 IStream_Release(stream);
3134 return;
3135 }
3136
3138 expect(Ok, stat);
3140
3142 expect(Ok, stat);
3143 ok(palette_size == sizeof(ColorPalette) ||
3144 broken(palette_size == sizeof(ColorPalette)+sizeof(ARGB[3])),
3145 "palette_size = %d\n", palette_size);
3146
3147 /* Bitmap starts at frame 0 */
3148 color = 0xdeadbeef;
3149 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
3150 expect(Ok, stat);
3151 expect(0xffffffff, color);
3152
3153 /* Check that we get correct metadata */
3155 expect(Ok, stat);
3156 expect(1, count);
3157
3158 stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
3159 expect(Ok, stat);
3160 expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
3161
3162 count = 12345;
3163 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
3164 expect(Ok, stat);
3165 expect(2, count);
3166
3167 /* SelectActiveFrame overwrites our current data */
3168 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
3169 expect(Ok, stat);
3170
3171 color = 0xdeadbeef;
3172 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
3173 expect(Ok, stat);
3174 expect(0xff000000, color);
3175
3176 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
3177 expect(Ok, stat);
3178
3179 color = 0xdeadbeef;
3180 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
3181 expect(Ok, stat);
3182 expect(0xffffffff, color);
3183
3184 /* Write over the image data */
3185 stat = GdipBitmapSetPixel(bmp, 0, 0, 0xff000000);
3186 expect(Ok, stat);
3187
3188 /* Switching to the same frame does not overwrite our changes */
3189 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
3190 expect(Ok, stat);
3191
3192 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
3193 expect(Ok, stat);
3194 expect(0xff000000, color);
3195
3196 /* But switching to another frame and back does */
3197 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 1);
3198 expect(Ok, stat);
3199
3200 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
3201 expect(Ok, stat);
3202
3203 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
3204 expect(Ok, stat);
3205 expect(0xffffffff, color);
3206
3207 /* rotate/flip discards the information about other frames */
3209 expect(Ok, stat);
3210
3211 count = 12345;
3212 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
3213 expect(Ok, stat);
3214 expect(1, count);
3215
3216 expect_rawformat(&ImageFormatMemoryBMP, (GpImage*)bmp, __LINE__, FALSE);
3217
3219 IStream_Release(stream);
3220
3221 /* Test with a non-animated gif */
3222 hglob = GlobalAlloc (0, sizeof(gifimage));
3223 data = GlobalLock (hglob);
3224 memcpy(data, gifimage, sizeof(gifimage));
3225 GlobalUnlock(hglob);
3226
3228 ok(hres == S_OK, "Failed to create a stream\n");
3229 if(hres != S_OK) return;
3230
3232 ok(stat == Ok, "Failed to create a Bitmap\n");
3233 if(stat != Ok){
3234 IStream_Release(stream);
3235 return;
3236 }
3237
3239 expect(Ok, stat);
3241
3242 /* Check metadata */
3244 expect(Ok, stat);
3245 expect(1, count);
3246
3247 stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
3248 expect(Ok, stat);
3249 expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
3250
3251 count = 12345;
3252 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
3253 expect(Ok, stat);
3254 expect(1, count);
3255
3257 IStream_Release(stream);
3258
3259 /* Test with a non-animated transparent gif */
3260 hglob = GlobalAlloc (0, sizeof(transparentgif));
3261 data = GlobalLock (hglob);
3263 GlobalUnlock(hglob);
3264
3266 ok(hres == S_OK, "Failed to create a stream\n");
3267
3269 IStream_Release(stream);
3270 ok(stat == Ok, "Failed to create a Bitmap\n");
3271
3273 expect(Ok, stat);
3275
3276 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
3277 expect(Ok, stat);
3278 expect(0, color);
3279
3281 expect(Ok, stat);
3282 ok(palette_size == sizeof(ColorPalette)+sizeof(ARGB),
3283 "palette_size = %d\n", palette_size);
3284
3285 memset(palette_buf, 0xfe, sizeof(palette_buf));
3286 palette = (ColorPalette*)palette_buf;
3288 sizeof(ColorPalette)+sizeof(ARGB));
3289 palette_entries = palette->Entries;
3290 expect(Ok, stat);
3292 expect(2, palette->Count);
3293 expect(0, palette_entries[0]);
3294 expect(0xff000000, palette_entries[1]);
3295
3296 count = 12345;
3297 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
3298 expect(Ok, stat);
3299 expect(1, count);
3300
3302
3303 /* Test frame dispose methods */
3304 hglob = GlobalAlloc (0, sizeof(gifanimation2));
3305 data = GlobalLock (hglob);
3307 GlobalUnlock(hglob);
3308
3310 ok(hres == S_OK, "Failed to create a stream\n");
3311
3313 ok(stat == Ok, "Failed to create a Bitmap\n");
3314 IStream_Release(stream);
3315
3316 stat = GdipImageGetFrameDimensionsList((GpImage*)bmp, &dimension, 1);
3317 expect(Ok, stat);
3318 expect_guid(&FrameDimensionTime, &dimension, __LINE__, FALSE);
3319
3320 stat = GdipImageGetFrameCount((GpImage*)bmp, &dimension, &count);
3321 expect(Ok, stat);
3322 expect(5, count);
3323
3324 stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
3325 expect(Ok, stat);
3326 expect(0, color);
3327
3328 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 3);
3329 expect(Ok, stat);
3330 stat = GdipBitmapGetPixel(bmp, 2, 0, &color);
3331 expect(Ok, stat);
3332 ok(color==0 || broken(color==0xff0000ff), "color = %lx\n", color);
3333 if(color != 0) {
3334 win_skip("broken animated gif support\n");
3336 return;
3337 }
3338
3339 for(i=0; i<6; i++) {
3340 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, i%5);
3341 expect(Ok, stat);
3342
3343 for(j=0; j<4; j++) {
3344 stat = GdipBitmapGetPixel(bmp, j*2, 0, &color);
3345 expect(Ok, stat);
3346 ok(gifanimation2_pixels[i%5][j] == color, "at %d,%d got %lx, expected %lx\n", i, j, color, gifanimation2_pixels[i%5][j]);
3347 }
3348 }
3349
3351
3352 hglob = GlobalAlloc (0, sizeof(gifanimation3));
3353 data = GlobalLock (hglob);
3355 GlobalUnlock(hglob);
3356
3358 ok(hres == S_OK, "Failed to create a stream\n");
3359
3361 ok(stat == Ok, "Failed to create a Bitmap\n");
3362 IStream_Release(stream);
3363
3364 for(i=0; i<6; i++) {
3365 stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, i%5);
3366 expect(Ok, stat);
3367
3368 for(j=0; j<4; j++) {
3369 stat = GdipBitmapGetPixel(bmp, j*2, 0, &color);
3370 expect(Ok, stat);
3371 ok(gifanimation3_pixels[i%5][j] == color, "at %d,%d got %lx, expected %lx\n", i, j, color, gifanimation3_pixels[i%5][j]);
3372 }
3373 }
3374
3376}
3377
3378static void test_rotateflip(void)
3379{
3380 GpImage *bitmap;
3381 GpStatus stat;
3382 BYTE bits[24];
3383 static const BYTE orig_bits[24] = {
3384 0,0,0xff, 0,0xff,0, 0xff,0,0, 23,23,23,
3385 0xff,0xff,0, 0xff,0,0xff, 0,0xff,0xff, 23,23,23};
3386 UINT width, height;
3387 ARGB color;
3388
3389 memcpy(bits, orig_bits, sizeof(bits));
3391 expect(Ok, stat);
3392
3394 expect(Ok, stat);
3395
3397 expect(Ok, stat);
3399 expect(Ok, stat);
3400 expect(2, width);
3401 expect(3, height);
3402
3404 expect(Ok, stat);
3405 expect(0xff00ffff, color);
3406
3408 expect(Ok, stat);
3409 expect(0xffff0000, color);
3410
3412 expect(Ok, stat);
3413 expect(0xffffff00, color);
3414
3416 expect(Ok, stat);
3417 expect(0xff0000ff, color);
3418
3419 expect(0, bits[0]);
3420 expect(0, bits[1]);
3421 expect(0xff, bits[2]);
3422
3424
3425 memcpy(bits, orig_bits, sizeof(bits));
3427 expect(Ok, stat);
3428
3430 expect(Ok, stat);
3431
3433 expect(Ok, stat);
3435 expect(Ok, stat);
3436 expect(3, width);
3437 expect(2, height);
3438
3440 expect(Ok, stat);
3441 expect(0xff0000ff, color);
3442
3444 expect(Ok, stat);
3445 expect(0xffff0000, color);
3446
3448 expect(Ok, stat);
3449 expect(0xffffff00, color);
3450
3452 expect(Ok, stat);
3453 expect(0xff00ffff, color);
3454
3455 expect(0, bits[0]);
3456 expect(0, bits[1]);
3457 expect(0xff, bits[2]);
3458
3460
3461 memcpy(bits, orig_bits, sizeof(bits));
3463 expect(Ok, stat);
3464
3466 expect(Ok, stat);
3467
3469 expect(Ok, stat);
3471 expect(Ok, stat);
3472 expect(3, width);
3473 expect(2, height);
3474
3476 expect(Ok, stat);
3477 expect(0xff00ffff, color);
3478
3480 expect(Ok, stat);
3481 expect(0xffffff00, color);
3482
3484 expect(Ok, stat);
3485 expect(0xffff0000, color);
3486
3488 expect(Ok, stat);
3489 expect(0xff0000ff, color);
3490
3491 expect(0, bits[0]);
3492 expect(0, bits[1]);
3493 expect(0xff, bits[2]);
3494
3496}
3497
3498static void test_remaptable(void)
3499{
3500 GpStatus stat;
3501 GpImageAttributes *imageattr;
3502 GpBitmap *bitmap1, *bitmap2;
3503 GpGraphics *graphics;
3504 ARGB color;
3505 ColorMap *map;
3506
3507 map = GdipAlloc(sizeof(ColorMap));
3508
3509 map->oldColor.Argb = 0xff00ff00;
3510 map->newColor.Argb = 0xffff00ff;
3511
3514
3515 stat = GdipCreateImageAttributes(&imageattr);
3516 expect(Ok, stat);
3517
3520
3523
3526
3529
3531 expect(Ok, stat);
3532
3534 expect(Ok, stat);
3535
3537 expect(Ok, stat);
3538
3540 expect(Ok, stat);
3541
3542 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0xff00ff00);
3543 expect(Ok, stat);
3544
3546 expect(Ok, stat);
3547
3548 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
3549 UnitPixel, imageattr, NULL, NULL);
3550 expect(Ok, stat);
3551
3553 expect(Ok, stat);
3554 ok(color_match(0xffff00ff, color, 1), "Expected ffff00ff, got %.8lx\n", color);
3555
3557 expect(Ok, stat);
3558
3559 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,1,1, 0,0,1,1,
3560 UnitPixel, imageattr, NULL, NULL);
3561 expect(Ok, stat);
3562
3564 expect(Ok, stat);
3565 ok(color_match(0xff00ff00, color, 1), "Expected ff00ff00, got %.8lx\n", color);
3566
3567 GdipDeleteGraphics(graphics);
3568 GdipDisposeImage((GpImage*)bitmap1);
3570 GdipDisposeImageAttributes(imageattr);
3571 GdipFree(map);
3572}
3573
3574static void test_colorkey(void)
3575{
3576 GpStatus stat;
3577 GpImageAttributes *imageattr;
3578 GpBitmap *bitmap1, *bitmap2;
3579 GpGraphics *graphics;
3580 ARGB color;
3581
3584
3585 stat = GdipCreateImageAttributes(&imageattr);
3586 expect(Ok, stat);
3587
3588 stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeCount, TRUE, 0xff405060, 0xff708090);
3590
3591 stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeAny, TRUE, 0xff405060, 0xff708090);
3593
3594 stat = GdipSetImageAttributesColorKeys(imageattr, ColorAdjustTypeDefault, TRUE, 0xff405060, 0xff708090);
3595 expect(Ok, stat);
3596
3598 expect(Ok, stat);
3599
3601 expect(Ok, stat);
3602
3603 stat = GdipBitmapSetPixel(bitmap1, 0, 0, 0x20405060);
3604 expect(Ok, stat);
3605
3606 stat = GdipBitmapSetPixel(bitmap1, 0, 1, 0x40506070);
3607 expect(Ok, stat);
3608
3609 stat = GdipBitmapSetPixel(bitmap1, 1, 0, 0x60708090);
3610 expect(Ok, stat);
3611
3612 stat = GdipBitmapSetPixel(bitmap1, 1, 1, 0xffffffff);
3613 expect(Ok, stat);
3614
3616 expect(Ok, stat);
3617
3618 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2,
3619 UnitPixel, imageattr, NULL, NULL);
3620 expect(Ok, stat);
3621
3623 expect(Ok, stat);
3624 ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8lx\n", color);
3625
3627 expect(Ok, stat);
3628 ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8lx\n", color);
3629
3631 expect(Ok, stat);
3632 ok(color_match(0x00000000, color, 1), "Expected 00000000, got %.8lx\n", color);
3633
3635 expect(Ok, stat);
3636 ok(color_match(0xffffffff, color, 1), "Expected ffffffff, got %.8lx\n", color);
3637
3639 expect(Ok, stat);
3640
3641 stat = GdipDrawImageRectRectI(graphics, (GpImage*)bitmap1, 0,0,2,2, 0,0,2,2,
3642 UnitPixel, imageattr, NULL, NULL);
3643 expect(Ok, stat);
3644
3646 expect(Ok, stat);
3647 ok(color_match(0x20405060, color, 1), "Expected 20405060, got %.8lx\n", color);
3648
3650 expect(Ok, stat);
3651 ok(color_match(0x40506070, color, 1), "Expected 40506070, got %.8lx\n", color);
3652
3654 expect(Ok, stat);
3655 ok(color_match(0x60708090, color, 1), "Expected 60708090, got %.8lx\n", color);
3656
3658 expect(Ok, stat);
3659 ok(color_match(0xffffffff, color, 1), "Expected ffffffff, got %.8lx\n", color);
3660
3661
3662 GdipDeleteGraphics(graphics);
3663 GdipDisposeImage((GpImage*)bitmap1);
3665 GdipDisposeImageAttributes(imageattr);
3666}
3667
3668static void test_dispose(void)
3669{
3670 GpStatus stat;
3671 GpImage *image;
3672 char invalid_image[256];
3673
3676
3678 expect(Ok, stat);
3679
3681 expect(Ok, stat);
3682
3683 if (0) {
3684 /* Can crash with page heap or if the heap region is decommitted. */
3687 }
3688
3689 memset(invalid_image, 0, 256);
3690 stat = GdipDisposeImage((GpImage*)invalid_image);
3692}
3693
3694static LONG obj_refcount(void *obj)
3695{
3696 IUnknown_AddRef((IUnknown *)obj);
3697 return IUnknown_Release((IUnknown *)obj);
3698}
3699
3700static GpImage *load_image(const BYTE *image_data, UINT image_size, BOOL valid_data, BOOL todo_load)
3701{
3702 IStream *stream;
3703 HGLOBAL hmem;
3704 BYTE *data;
3705 HRESULT hr;
3707 GpImage *image = NULL, *clone;
3708 ImageType image_type;
3709 LONG refcount, old_refcount;
3710
3711 hmem = GlobalAlloc(0, image_size);
3712 data = GlobalLock(hmem);
3713 memcpy(data, image_data, image_size);
3714 GlobalUnlock(hmem);
3715
3717 ok(hr == S_OK, "CreateStreamOnHGlobal error %#lx\n", hr);
3718 if (hr != S_OK) return NULL;
3719
3720 refcount = obj_refcount(stream);
3721 ok(refcount == 1, "expected stream refcount 1, got %ld\n", refcount);
3722
3724 todo_wine_if(todo_load)
3725 if (valid_data)
3726 ok(status == Ok || broken(status == InvalidParameter), /* XP */
3727 "GdipLoadImageFromStream error %d\n", status);
3728 else
3729 ok(status != Ok, "GdipLoadImageFromStream should fail\n");
3730 if (status != Ok)
3731 {
3732 IStream_Release(stream);
3733 return NULL;
3734 }
3735
3736 status = GdipGetImageType(image, &image_type);
3737 ok(status == Ok, "GdipGetImageType error %d\n", status);
3738
3739 refcount = obj_refcount(stream);
3740 if (image_type == ImageTypeBitmap)
3741 ok(refcount > 1, "expected stream refcount > 1, got %ld\n", refcount);
3742 else
3743 ok(refcount == 1, "expected stream refcount 1, got %ld\n", refcount);
3744 old_refcount = refcount;
3745
3746 status = GdipCloneImage(image, &clone);
3747 ok(status == Ok, "GdipCloneImage error %d\n", status);
3748 refcount = obj_refcount(stream);
3749 ok(refcount == old_refcount, "expected stream refcount %ld, got %ld\n", old_refcount, refcount);
3750 status = GdipDisposeImage(clone);
3751 ok(status == Ok, "GdipDisposeImage error %d\n", status);
3752 refcount = obj_refcount(stream);
3753 ok(refcount == old_refcount, "expected stream refcount %ld, got %ld\n", old_refcount, refcount);
3754
3755 refcount = IStream_Release(stream);
3756 if (image_type == ImageTypeBitmap)
3757 ok(refcount >= 1, "expected stream refcount != 0\n");
3758 else
3759 ok(refcount == 0, "expected stream refcount 0, got %ld\n", refcount);
3760
3761 return image;
3762}
3763
3765{
3767 const BYTE value[32];
3770};
3771
3772#ifndef PropertyTagTypeSByte
3773#define PropertyTagTypeSByte 6
3774#define PropertyTagTypeSShort 8
3775#define PropertyTagTypeFloat 11
3776#define PropertyTagTypeDouble 12
3777#endif
3778
3780{
3781 /* Win7 stopped using proper but not documented types, and it
3782 looks broken since TypeFloat and TypeDouble now reported as
3783 TypeUndefined, and signed types reported as unsigned. */
3784 switch (type)
3785 {
3790 default: return type;
3791 }
3792}
3793
3795 const struct property_test_data *td_broken, UINT count_broken, UINT *prop_size)
3796{
3798 UINT prop_count, size, i;
3799 PROPID *prop_id;
3800 PropertyItem *prop_item;
3801
3802 prop_count = 0xdeadbeef;
3803 status = GdipGetPropertyCount(image, &prop_count);
3804 expect(Ok, status);
3805 ok(count == prop_count || broken(count_broken != ~0 && count_broken == prop_count),
3806 "expected property count %u, got %u\n", count, prop_count);
3807 if (count_broken != ~0 && count_broken == prop_count)
3808 td = td_broken;
3809
3810 prop_id = malloc(prop_count * sizeof(*prop_id));
3811
3812 status = GdipGetPropertyIdList(image, prop_count, prop_id);
3813 expect(Ok, status);
3814
3815 if (prop_size)
3816 *prop_size = 0;
3817
3818 for (i = 0; i < prop_count; i++)
3819 {
3820 winetest_push_context("prop %u", i);
3821
3822 status = GdipGetPropertyItemSize(image, prop_id[i], &size);
3823 expect(Ok, status);
3824 if (status != Ok)
3825 {
3827 break;
3828 }
3829 ok(size > sizeof(*prop_item), "too small item length %u\n", size);
3830
3831 if (prop_size)
3832 *prop_size += size;
3833
3834 prop_item = calloc(1, size);
3835 status = GdipGetPropertyItem(image, prop_id[i], size, prop_item);
3836 size -= sizeof(*prop_item);
3837 expect(Ok, status);
3838
3839 ok(prop_item->value == prop_item + 1, "expected item->value %p, got %p\n",
3840 prop_item + 1, prop_item->value);
3841 ok(td[i].type == prop_item->type ||
3842 broken(documented_type(td[i].type) == prop_item->type),
3843 "expected type %lu, got %u\n", td[i].type, prop_item->type);
3844 ok(td[i].id == prop_item->id, "expected id %#lx, got %#lx\n", td[i].id, prop_item->id);
3845 ok(prop_item->length == size, "expected length %u, got %lu\n", size, prop_item->length);
3846 ok(td[i].length == prop_item->length || broken(td[i].broken_length),
3847 "expected length %lu, got %lu\n", td[i].length, prop_item->length);
3848 ok(td[i].length == size || broken(td[i].broken_length),
3849 "expected length %lu, got %u\n", td[i].length, size);
3850 if (td[i].length == prop_item->length)
3851 {
3852 int match = !memcmp(td[i].value, prop_item->value, td[i].length);
3853 ok(match || broken(td[i].broken_data), "data mismatch\n");
3854 if (!match)
3855 trace("(id %#lx) %s\n", prop_item->id, dbgstr_hexdata(prop_item->value, prop_item->length));
3856 }
3857
3858 free(prop_item);
3859
3861 }
3862
3863 free(prop_id);
3864}
3865
3867 const struct property_test_data *td_broken, UINT count_broken, UINT prop_size)
3868{
3870 UINT total_count, total_size, i;
3871 PropertyItem *prop_item;
3872 const BYTE *item_data;
3873
3874 total_size = 0xdeadbeef;
3875 total_count = 0xdeadbeef;
3876 status = GdipGetPropertySize(image, &total_size, &total_count);
3877 expect(Ok, status);
3878 ok(prop_size == total_size || prop_size == ~0,
3879 "expected total property size %u, got %u\n", prop_size, total_size);
3880 ok(count == total_count || broken(count_broken != ~0 && count_broken == total_count),
3881 "expected total property count %u, got %u\n", count, total_count);
3882 if (count_broken != ~0 && count_broken == total_count)
3883 td = td_broken;
3884
3885 prop_item = malloc(total_size);
3886 status = GdipGetAllPropertyItems(image, total_size, total_count, prop_item);
3887 expect(Ok, status);
3888
3889 item_data = (const BYTE *)(prop_item + total_count);
3890 for (i = 0; i < total_count && i < count; i++)
3891 {
3892 winetest_push_context("prop %u", i);
3893
3894 ok(prop_item[i].value == item_data,
3895 "expected value %p, got %p\n", item_data, prop_item[i].value);
3896 ok(td[i].type == prop_item[i].type ||
3897 broken(documented_type(td[i].type) == prop_item[i].type),
3898 "expected type %lu, got %u\n", td[i].type, prop_item[i].type);
3899 ok(td[i].id == prop_item[i].id,
3900 "expected id %#lx, got %#lx\n", td[i].id, prop_item[i].id);
3901 ok(td[i].length == prop_item[i].length || broken(td[i].broken_length),
3902 "expected length %lu, got %lu\n", td[i].length, prop_item[i].length);
3903 if (td[i].length == prop_item[i].length)
3904 {
3905 int match = !memcmp(td[i].value, prop_item[i].value, td[i].length);
3906 ok(match || broken(td[i].broken_data), "data mismatch\n");
3907 if (!match)
3908 trace("(id %#lx) %s\n", prop_item[i].id, dbgstr_hexdata(prop_item[i].value, prop_item[i].length));
3909 }
3910 item_data += prop_item[i].length;
3911
3913 }
3914
3915 free(prop_item);
3916}
3917
3918static void test_image_properties(void)
3919{
3920 static const struct test_data
3921 {
3922 const BYTE *image_data;
3924 ImageType image_type;
3925 UINT prop_count;
3926 UINT prop_count2; /* if win7+ behaves differently, else ~0 */
3927 /* 1st property attributes */
3928 UINT prop_size;
3929 UINT prop_size2; /* if win7+ behaves differently, else ~0 */
3930 UINT prop_id;
3931 UINT prop_id2; /* if win7+ behaves differently, else ~0 */
3933 }
3934 td[] =
3935 {
3936 { pngimage, sizeof(pngimage), ImageTypeBitmap, 4, ~0, 1, 20, 0x5110, 0x132, 12 },
3937 { jpgimage, sizeof(jpgimage), ImageTypeBitmap, 2, ~0, 128, ~0, 0x5090, 0x5091, 12 },
3938 { tiffimage, sizeof(tiffimage), ImageTypeBitmap, 16, ~0, 4, ~0, 0xfe, ~0, 12 },
3939 { bmpimage, sizeof(bmpimage), ImageTypeBitmap, 0, ~0, 0, ~0, 0, ~0, 16 },
3940 { gifimage, sizeof(gifimage), ImageTypeBitmap, 1, 4, 4, ~0, 0x5100, ~0, 16 },
3941 { wmfimage, sizeof(wmfimage), ImageTypeMetafile, 0, ~0, 0, ~0, 0, ~0, -GenericError }
3942 };
3944 GpImage *image;
3945 PropertyItem *prop_item;
3946 UINT prop_count, prop_size, i;
3947 PROPID prop_id[16] = { 0 };
3948 ImageType image_type;
3950 union
3951 {
3953 char buf[256];
3954 } item;
3955
3956 for (i = 0; i < ARRAY_SIZE(td); i++)
3957 {
3958 winetest_push_context("%u", i);
3959
3960 image = load_image(td[i].image_data, td[i].image_size, TRUE, FALSE);
3961 if (!image)
3962 {
3963 trace("failed to load image data\n");
3965 continue;
3966 }
3967
3968 status = GdipGetImageType(image, &image_type);
3969 ok(status == Ok, "GdipGetImageType error %d\n", status);
3970 ok(td[i].image_type == image_type, "expected image_type %d, got %d\n",
3971 td[i].image_type, image_type);
3972
3973 palette_size = -1;
3975 if (td[i].palette_size >= 0)
3976 {
3977 ok(status == Ok, "GdipGetImagePaletteSize error %d\n", status);
3978 ok(td[i].palette_size == palette_size, "expected palette_size %d, got %d\n",
3980 }
3981 else
3982 {
3983 ok(status == -td[i].palette_size, "GdipGetImagePaletteSize returned %d\n", status);
3984 ok(palette_size == 0, "expected palette_size 0, got %d\n",
3985 palette_size);
3986 }
3987
3988 status = GdipGetPropertyCount(image, &prop_count);
3989 ok(status == Ok, "GdipGetPropertyCount error %d\n", status);
3990 todo_wine_if(td[i].image_data == jpgimage)
3991 ok(td[i].prop_count == prop_count || (td[i].prop_count2 != ~0 && td[i].prop_count2 == prop_count),
3992 "expected property count %u or %u, got %u\n",
3993 td[i].prop_count, td[i].prop_count2, prop_count);
3994
3995 status = GdipGetPropertyItemSize(NULL, 0, &prop_size);
3999 status = GdipGetPropertyItemSize(image, 0, &prop_size);
4000 if (image_type == ImageTypeMetafile)
4002 else
4004
4005 status = GdipGetPropertyItem(NULL, 0, 0, &item.data);
4009 status = GdipGetPropertyItem(image, 0, 0, &item.data);
4010 if (image_type == ImageTypeMetafile)
4012 else
4014
4015 status = GdipGetPropertyIdList(NULL, prop_count, prop_id);
4017 status = GdipGetPropertyIdList(image, prop_count, NULL);
4020 status = GdipGetPropertyIdList(image, prop_count - 1, prop_id);
4022 status = GdipGetPropertyIdList(image, prop_count + 1, prop_id);
4024 if (image_type != ImageTypeMetafile && prop_count == 0)
4025 expected = Ok;
4026 status = GdipGetPropertyIdList(image, 0, prop_id);
4028 expected = (image_type == ImageTypeMetafile) ? NotImplemented : Ok;
4029 status = GdipGetPropertyIdList(image, prop_count, prop_id);
4031
4032 status = GdipGetPropertyItemSize(image, prop_id[0], &prop_size);
4033 if (image_type == ImageTypeMetafile)
4035 else if (prop_count == 0)
4037 /* FIXME: remove condition once Wine is fixed, i.e. this should just be an else */
4038 else if (td[i].prop_count == prop_count || (td[i].prop_count2 != ~0 && td[i].prop_count2 == prop_count))
4039 {
4040 ok(td[i].prop_id == prop_id[0] || (td[i].prop_id2 != ~0 && td[i].prop_id2 == prop_id[0]),
4041 "expected property id %#x or %#x, got %#lx\n",
4042 td[i].prop_id, td[i].prop_id2, prop_id[0]);
4043
4044 expect(Ok, status);
4045
4046 assert(sizeof(item) >= prop_size);
4047 ok(prop_size > sizeof(PropertyItem), "got too small prop_size %u\n",
4048 prop_size);
4049 ok(td[i].prop_size + sizeof(PropertyItem) == prop_size ||
4050 (td[i].prop_size2 != ~0 && td[i].prop_size2 + sizeof(PropertyItem) == prop_size),
4051 "expected property size (%u or %u)+%u, got %u\n",
4052 td[i].prop_size, td[i].prop_size2, (UINT) sizeof(PropertyItem), prop_size);
4053
4054 status = GdipGetPropertyItem(image, prop_id[0], 0, &item.data);
4055 ok(status == InvalidParameter || status == GenericError /* Win7 */,
4056 "expected InvalidParameter, got %d\n", status);
4057 status = GdipGetPropertyItem(image, prop_id[0], prop_size - 1, &item.data);
4058 ok(status == InvalidParameter || status == GenericError /* Win7 */,
4059 "expected InvalidParameter, got %d\n", status);
4060 status = GdipGetPropertyItem(image, prop_id[0], prop_size + 1, &item.data);
4061 ok(status == InvalidParameter || status == GenericError /* Win7 */,
4062 "expected InvalidParameter, got %d\n", status);
4063 status = GdipGetPropertyItem(image, prop_id[0], prop_size, &item.data);
4064 expect(Ok, status);
4065 ok(prop_id[0] == item.data.id,
4066 "expected property id %#lx, got %#lx\n", prop_id[0], item.data.id);
4067 }
4068
4069 status = GdipGetPropertySize(NULL, &prop_size, &prop_count);
4071 status = GdipGetPropertySize(image, &prop_size, NULL);
4073 status = GdipGetPropertySize(image, NULL, &prop_count);
4077 expected = (image_type == ImageTypeMetafile) ? NotImplemented : Ok;
4078 status = GdipGetPropertySize(image, &prop_size, &prop_count);
4080
4083 status = GdipGetAllPropertyItems(image, prop_size, prop_count, NULL);
4085 prop_item = malloc(prop_size);
4087 if (prop_count != 1)
4088 {
4089 status = GdipGetAllPropertyItems(image, prop_size, 1, prop_item);
4091 }
4092 if (prop_size != 0)
4093 {
4094 status = GdipGetAllPropertyItems(image, 0, prop_count, prop_item);
4096 }
4097 status = GdipGetAllPropertyItems(image, prop_size + 1, prop_count, prop_item);
4099 if (image_type != ImageTypeMetafile)
4100 expected = (prop_count == 0) ? GenericError : Ok;
4101 status = GdipGetAllPropertyItems(image, prop_size, prop_count, prop_item);
4102 ok(status == expected || broken(status == Ok && prop_count == 0), /* XP */
4103 "Expected %d, got %d\n", expected, status);
4104 free(prop_item);
4105
4107
4109 }
4110}
4111
4112#define IFD_BYTE 1
4113#define IFD_ASCII 2
4114#define IFD_SHORT 3
4115#define IFD_LONG 4
4116#define IFD_RATIONAL 5
4117#define IFD_SBYTE 6
4118#define IFD_UNDEFINED 7
4119#define IFD_SSHORT 8
4120#define IFD_SLONG 9
4121#define IFD_SRATIONAL 10
4122#define IFD_FLOAT 11
4123#define IFD_DOUBLE 12
4124
4125#include "pshpack2.h"
4126struct IFD_entry
4127{
4128 SHORT id;
4129 SHORT type;
4130 ULONG count;
4131 LONG value;
4132};
4133
4135{
4138};
4139
4140static const struct tiff_data
4141{
4146 struct IFD_entry entry[40];
4151 char string[14];
4157} TIFF_data =
4158{
4159#ifdef WORDS_BIGENDIAN
4160 'M' | 'M' << 8,
4161#else
4162 'I' | 'I' << 8,
4163#endif
4164 42,
4165 FIELD_OFFSET(struct tiff_data, number_of_entries),
4166 31,
4167 {
4168 { 0xff, IFD_SHORT, 1, 0 }, /* SUBFILETYPE */
4169 { 0x100, IFD_LONG, 1, 1 }, /* IMAGEWIDTH */
4170 { 0x101, IFD_LONG, 1, 1 }, /* IMAGELENGTH */
4171 { 0x102, IFD_SHORT, 1, 1 }, /* BITSPERSAMPLE */
4172 { 0x103, IFD_SHORT, 1, 1 }, /* COMPRESSION: XP doesn't accept IFD_LONG here */
4173 { 0x106, IFD_SHORT, 1, 1 }, /* PHOTOMETRIC */
4174 { 0x111, IFD_LONG, 1, FIELD_OFFSET(struct tiff_data, pixel_data) }, /* STRIPOFFSETS */
4175 { 0x115, IFD_SHORT, 1, 1 }, /* SAMPLESPERPIXEL */
4176 { 0x116, IFD_LONG, 1, 1 }, /* ROWSPERSTRIP */
4177 { 0x117, IFD_LONG, 1, 1 }, /* STRIPBYTECOUNT */
4178 { 0x11a, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_data, xres) },
4179 { 0x11b, IFD_RATIONAL, 1, FIELD_OFFSET(struct tiff_data, xres) },
4180 { 0x128, IFD_SHORT, 1, 2 }, /* RESOLUTIONUNIT */
4181 { 0xf001, IFD_BYTE, 1, 0x11223344 },
4182 { 0xf002, IFD_BYTE, 4, 0x11223344 },
4183 { 0xf003, IFD_SBYTE, 1, 0x11223344 },
4184 { 0xf004, IFD_SSHORT, 1, 0x11223344 },
4185 { 0xf005, IFD_SSHORT, 2, 0x11223344 },
4186 { 0xf006, IFD_SLONG, 1, 0x11223344 },
4187 { 0xf007, IFD_FLOAT, 1, 0x11223344 },
4188 { 0xf008, IFD_DOUBLE, 1, FIELD_OFFSET(struct tiff_data, double_val) },
4189 { 0xf009, IFD_SRATIONAL, 1, FIELD_OFFSET(struct tiff_data, srational_val) },
4190 { 0xf00a, IFD_BYTE, 13, FIELD_OFFSET(struct tiff_data, string) },
4191 { 0xf00b, IFD_SSHORT, 4, FIELD_OFFSET(struct tiff_data, short_val) },
4192 { 0xf00c, IFD_SLONG, 2, FIELD_OFFSET(struct tiff_data, long_val) },
4193 { 0xf00e, IFD_ASCII, 13, FIELD_OFFSET(struct tiff_data, string) },
4194 { 0xf00f, IFD_ASCII, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
4195 { 0xf010, IFD_UNDEFINED, 13, FIELD_OFFSET(struct tiff_data, string) },
4196 { 0xf011, IFD_UNDEFINED, 4, 'a' | 'b' << 8 | 'c' << 16 | 'd' << 24 },
4197 /* Some gdiplus versions ignore these fields.
4198 { 0xf012, IFD_BYTE, 0, 0x11223344 },
4199 { 0xf013, IFD_SHORT, 0, 0x11223344 },
4200 { 0xf014, IFD_LONG, 0, 0x11223344 },
4201 { 0xf015, IFD_FLOAT, 0, 0x11223344 },*/
4202 { 0xf016, IFD_SRATIONAL, 3, FIELD_OFFSET(struct tiff_data, rational) },
4203 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
4204 { 0xf017, IFD_FLOAT, 2, FIELD_OFFSET(struct tiff_data, float_val) },
4205 },
4206 0,
4207 { 900, 3 },
4208 1234567890.0987654321,
4209 { 0x1a2b3c4d, 0x5a6b7c8d },
4210 "Hello World!",
4211 { 0x0101, 0x0202, 0x0303, 0x0404 },
4212 { 0x11223344, 0x55667788 },
4213 { (FLOAT)1234.5678, (FLOAT)8765.4321 },
4214 { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
4215 { 0x11, 0x22, 0x33, 0 }
4217#include "poppack.h"
4218
4219static void test_tiff_properties(void)
4220{
4221 static const struct property_test_data td[31] =
4222 {
4223 { PropertyTagTypeShort, 0xff, 2, { 0 } },
4224 { PropertyTagTypeLong, 0x100, 4, { 1 } },
4225 { PropertyTagTypeLong, 0x101, 4, { 1 } },
4226 { PropertyTagTypeShort, 0x102, 2, { 1 } },
4227 { PropertyTagTypeShort, 0x103, 2, { 1 } },
4228 { PropertyTagTypeShort, 0x106, 2, { 1 } },
4229 { PropertyTagTypeLong, 0x111, 4, { 0x44,0x02 } },
4230 { PropertyTagTypeShort, 0x115, 2, { 1 } },
4231 { PropertyTagTypeLong, 0x116, 4, { 1 } },
4232 { PropertyTagTypeLong, 0x117, 4, { 1 } },
4233 { PropertyTagTypeRational, 0x11a, 8, { 0x84,0x03,0,0,0x03 } },
4234 { PropertyTagTypeRational, 0x11b, 8, { 0x84,0x03,0,0,0x03 } },
4235 { PropertyTagTypeShort, 0x128, 2, { 2 } },
4236 { PropertyTagTypeByte, 0xf001, 1, { 0x44 } },
4237 { PropertyTagTypeByte, 0xf002, 4, { 0x44,0x33,0x22,0x11 } },
4238 { PropertyTagTypeSByte, 0xf003, 1, { 0x44 }, FALSE, TRUE },
4239 { PropertyTagTypeSShort, 0xf004, 2, { 0x44,0x33 }, FALSE, TRUE },
4240 { PropertyTagTypeSShort, 0xf005, 4, { 0x44,0x33,0x22,0x11 }, FALSE, TRUE },
4241 { PropertyTagTypeSLONG, 0xf006, 4, { 0x44,0x33,0x22,0x11 }, FALSE, TRUE },
4242 { PropertyTagTypeFloat, 0xf007, 4, { 0x44,0x33,0x22,0x11 }, FALSE, TRUE },
4243 { PropertyTagTypeDouble, 0xf008, 8, { 0x2c,0x52,0x86,0xb4,0x80,0x65,0xd2,0x41 } },
4244 { PropertyTagTypeSRational, 0xf009, 8, { 0x4d, 0x3c, 0x2b, 0x1a, 0x8d, 0x7c, 0x6b, 0x5a } },
4245 { PropertyTagTypeByte, 0xf00a, 13, "Hello World!" },
4246 { PropertyTagTypeSShort, 0xf00b, 8, { 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04 } },
4247 { PropertyTagTypeSLONG, 0xf00c, 8, { 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
4248 { PropertyTagTypeASCII, 0xf00e, 13, "Hello World!" },
4249 { PropertyTagTypeASCII, 0xf00f, 5, "abcd", TRUE },
4250 { PropertyTagTypeUndefined, 0xf010, 13, "Hello World!" },
4251 { PropertyTagTypeUndefined, 0xf011, 4, { 'a','b','c','d' }, FALSE, TRUE },
4252 { PropertyTagTypeSRational, 0xf016, 24,
4253 { 0x04,0x03,0x02,0x01,0x08,0x07,0x06,0x05,
4254 0x40,0x30,0x20,0x10,0x80,0x70,0x60,0x50,
4255 0x44,0x33,0x22,0x11,0x88,0x77,0x66,0x55 } },
4256 /* Win7 before SP1 doesn't recognize this field, everybody else does. */
4257 { PropertyTagTypeFloat, 0xf017, 8, { 0x2b,0x52,0x9a,0x44,0xba,0xf5,0x08,0x46 } },
4258 };
4260 GpImage *image;
4261 GUID guid;
4262 UINT dim_count, frame_count;
4263
4264 image = load_image((const BYTE *)&TIFF_data, sizeof(TIFF_data), TRUE, FALSE);
4265 if (!image)
4266 {
4267 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
4268 return;
4269 }
4270
4272 expect(Ok, status);
4273 expect(1, dim_count);
4274
4276 expect(Ok, status);
4277 expect_guid(&FrameDimensionPage, &guid, __LINE__, FALSE);
4278
4279 frame_count = 0xdeadbeef;
4280 status = GdipImageGetFrameCount(image, &guid, &frame_count);
4281 expect(Ok, status);
4282 expect(1, frame_count);
4283
4285 check_properties_id_list(image, td, ARRAY_SIZE(td), td, ARRAY_SIZE(td) - 1 /* Win7 SP0 */, NULL);
4287
4289}
4290
4292{
4293 static const struct property_test_data td[16] =
4294 {
4295 { PropertyTagTypeLong, 0xfe, 4, { 0 } },
4296 { PropertyTagTypeShort, 0x100, 2, { 1 } },
4297 { PropertyTagTypeShort, 0x101, 2, { 1 } },
4298 { PropertyTagTypeShort, 0x102, 6, { 8,0,8,0,8,0 } },
4299 { PropertyTagTypeShort, 0x103, 2, { 1 } },
4300 { PropertyTagTypeShort, 0x106, 2, { 2,0 } },
4301 { PropertyTagTypeASCII, 0x10d, 27, "/home/meh/Desktop/test.tif" },
4302 { PropertyTagTypeLong, 0x111, 4, { 8,0,0,0 } },
4303 { PropertyTagTypeShort, 0x112, 2, { 1 } },
4304 { PropertyTagTypeShort, 0x115, 2, { 3,0 } },
4305 { PropertyTagTypeShort, 0x116, 2, { 0x40,0 } },
4306 { PropertyTagTypeLong, 0x117, 4, { 3,0,0,0 } },
4307 { PropertyTagTypeRational, 0x11a, 8, { 0,0,0,72,0,0,0,1 } },
4308 { PropertyTagTypeRational, 0x11b, 8, { 0,0,0,72,0,0,0,1 } },
4309 { PropertyTagTypeShort, 0x11c, 2, { 1 } },
4310 { PropertyTagTypeShort, 0x128, 2, { 2 } }
4311 };
4313 GpImage *image;
4314 GUID guid;
4315 UINT dim_count, frame_count, prop_size;
4316
4318 ok(image != 0, "Failed to load TIFF image data\n");
4319 if (!image) return;
4320
4321 dim_count = 0xdeadbeef;
4323 expect(Ok, status);
4324 expect(1, dim_count);
4325
4327 expect(Ok, status);
4328 expect_guid(&FrameDimensionPage, &guid, __LINE__, FALSE);
4329
4330 frame_count = 0xdeadbeef;
4331 status = GdipImageGetFrameCount(image, &guid, &frame_count);
4332 expect(Ok, status);
4333 expect(1, frame_count);
4334
4336 check_properties_id_list(image, td, ARRAY_SIZE(td), NULL, ~0, &prop_size);
4337 check_properties_get_all(image, td, ARRAY_SIZE(td), NULL, ~0, prop_size);
4339
4341}
4342
4343static void test_tiff_palette(void)
4344{
4346 GpImage *image;
4348 INT size;
4349 struct
4350 {
4351 ColorPalette pal;
4352 ARGB entry[256];
4353 } palette;
4354 ARGB *entries = palette.pal.Entries;
4355
4356 /* 1bpp TIFF without palette */
4357 image = load_image((const BYTE *)&TIFF_data, sizeof(TIFF_data), TRUE, FALSE);
4358 if (!image)
4359 {
4360 win_skip("Failed to load TIFF image data. Might not be supported. Skipping.\n");
4361 return;
4362 }
4363
4365 expect(Ok, status);
4366 ok(format == PixelFormat1bppIndexed, "expected PixelFormat1bppIndexed, got %#x\n", format);
4367
4369 ok(status == Ok || broken(status == GenericError), /* XP */
4370 "GdipGetImagePaletteSize error %d\n", status);
4371 if (status == GenericError)
4372 {
4374 return;
4375 }
4376 expect(sizeof(ColorPalette) + sizeof(ARGB), size);
4377
4379 expect(Ok, status);
4380 expect(0, palette.pal.Flags);
4381 expect(2, palette.pal.Count);
4382 if (palette.pal.Count == 2)
4383 {
4384 ok(entries[0] == 0xff000000, "expected 0xff000000, got %#lx\n", entries[0]);
4385 ok(entries[1] == 0xffffffff, "expected 0xffffffff, got %#lx\n", entries[1]);
4386 }
4387
4389}
4390
4391static void test_bitmapbits(void)
4392{
4393 /* 8 x 2 bitmap */
4394 static const BYTE pixels_24[48] =
4395 {
4396 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
4397 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
4398 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
4399 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0
4400 };
4401 static const BYTE pixels_00[48] =
4402 {
4403 0,0,0, 0,0,0, 0,0,0, 0,0,0,
4404 0,0,0, 0,0,0, 0,0,0, 0,0,0,
4405 0,0,0, 0,0,0, 0,0,0, 0,0,0,
4406 0,0,0, 0,0,0, 0,0,0, 0,0,0
4407 };
4408 static const BYTE pixels_24_77[64] =
4409 {
4410 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
4411 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
4412 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4413 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
4414 0xff,0xff,0xff, 0,0,0, 0xff,0xff,0xff, 0,0,0,
4415 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
4416 };
4417 static const BYTE pixels_77[64] =
4418 {
4419 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4420 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4421 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4422 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4423 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4424 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4425 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4426 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
4427 };
4428 static const BYTE pixels_8[16] =
4429 {
4430 0x01,0,0x01,0,0x01,0,0x01,0,
4431 0x01,0,0x01,0,0x01,0,0x01,0
4432 };
4433 static const BYTE pixels_8_77[64] =
4434 {
4435 0x01,0,0x01,0,0x01,0,0x01,0,
4436 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4437 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4438 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4439 0x01,0,0x01,0,0x01,0,0x01,0,
4440 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4441 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4442 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
4443 };
4444 static const BYTE pixels_1_77[64] =
4445 {
4446 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4447 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4448 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4449 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4450 0xaa,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4451 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4452 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,
4453 0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77
4454 };
4455 static const BYTE pixels_1[8] = {0xaa,0,0,0,0xaa,0,0,0};
4456 static const struct test_data
4457 {
4459 UINT bpp;
4461 UINT stride, size;
4462 const BYTE *pixels;
4463 const BYTE *pixels_unlocked;
4464 } td[] =
4465 {
4466 /* 0 */
4467 { PixelFormat24bppRGB, 24, 0xfff0, 24, 48, pixels_24, pixels_00 },
4468
4469 { PixelFormat24bppRGB, 24, 0, 24, 48, pixels_24, pixels_00 },
4470 { PixelFormat24bppRGB, 24, ImageLockModeRead, 24, 48, pixels_24, pixels_00 },
4471 { PixelFormat24bppRGB, 24, ImageLockModeWrite, 24, 48, pixels_24, pixels_00 },
4472 { PixelFormat24bppRGB, 24, ImageLockModeRead|ImageLockModeWrite, 24, 48, pixels_24, pixels_00 },
4473 { PixelFormat24bppRGB, 24, ImageLockModeRead|ImageLockModeUserInputBuf, 32, 64, pixels_24_77, pixels_24 },
4474 { PixelFormat24bppRGB, 24, ImageLockModeWrite|ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_00 },
4475 { PixelFormat24bppRGB, 24, ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_24 },
4476 /* 8 */
4477 { PixelFormat8bppIndexed, 8, 0, 8, 16, pixels_8, pixels_24 },
4478 { PixelFormat8bppIndexed, 8, ImageLockModeRead, 8, 16, pixels_8, pixels_24 },
4479 { PixelFormat8bppIndexed, 8, ImageLockModeWrite, 8, 16, pixels_8, pixels_00 },
4480 { PixelFormat8bppIndexed, 8, ImageLockModeRead|ImageLockModeWrite, 8, 16, pixels_8, pixels_00 },
4481 { PixelFormat8bppIndexed, 8, ImageLockModeRead|ImageLockModeUserInputBuf, 32, 64, pixels_8_77, pixels_24 },
4482 { PixelFormat8bppIndexed, 8, ImageLockModeWrite|ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_00 },
4483 { PixelFormat8bppIndexed, 8, ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_24 },
4484 /* 15 */
4485 { PixelFormat1bppIndexed, 1, 0, 4, 8, pixels_1, pixels_24 },
4486 { PixelFormat1bppIndexed, 1, ImageLockModeRead, 4, 8, pixels_1, pixels_24 },
4487 { PixelFormat1bppIndexed, 1, ImageLockModeWrite, 4, 8, pixels_1, pixels_00 },
4488 { PixelFormat1bppIndexed, 1, ImageLockModeRead|ImageLockModeWrite, 4, 8, pixels_1, pixels_00 },
4489 { PixelFormat1bppIndexed, 1, ImageLockModeRead|ImageLockModeUserInputBuf, 32, 64, pixels_1_77, pixels_24 },
4490 { PixelFormat1bppIndexed, 1, ImageLockModeWrite|ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_00 },
4491 { PixelFormat1bppIndexed, 1, ImageLockModeUserInputBuf, 32, 64, pixels_77, pixels_24 },
4492 };
4493 BYTE buf[64];
4496 UINT i;
4498 struct
4499 {
4500 ColorPalette pal;
4501 ARGB entries[1];
4502 } palette;
4503 ARGB *entries = palette.pal.Entries;
4504
4505 for (i = 0; i < ARRAY_SIZE(td); i++)
4506 {
4507 BYTE pixels[sizeof(pixels_24)];
4508 memcpy(pixels, pixels_24, sizeof(pixels_24));
4510 expect(Ok, status);
4511
4512 /* associate known palette with pixel data */
4513 palette.pal.Flags = PaletteFlagsGrayScale;
4514 palette.pal.Count = 2;
4515 entries[0] = 0xff000000;
4516 entries[1] = 0xffffffff;
4518 expect(Ok, status);
4519
4520 memset(&data, 0xfe, sizeof(data));
4522 {
4523 memset(buf, 0x77, sizeof(buf));
4524 data.Scan0 = buf;
4525 data.Stride = 32;
4526 }
4528 ok(status == Ok || broken(status == InvalidParameter) /* XP */, "%u: GdipBitmapLockBits error %d\n", i, status);
4529 if (status != Ok)
4530 {
4532 continue;
4533 }
4534 ok(data.Width == 8, "%u: expected 8, got %d\n", i, data.Width);
4535 ok(data.Height == 2, "%u: expected 2, got %d\n", i, data.Height);
4536 ok(td[i].stride == data.Stride, "%u: expected %d, got %d\n", i, td[i].stride, data.Stride);
4537 ok(td[i].format == data.PixelFormat, "%u: expected %d, got %d\n", i, td[i].format, data.PixelFormat);
4538 ok(td[i].size == data.Height * data.Stride, "%u: expected %d, got %d\n", i, td[i].size, data.Height * data.Stride);
4540 ok(data.Scan0 == buf, "%u: got wrong buffer\n", i);
4541 if (td[i].size == data.Height * data.Stride)
4542 {
4543 UINT j, match, width_bytes = (data.Width * td[i].bpp) / 8;
4544
4545 match = 1;
4546 for (j = 0; j < data.Height; j++)
4547 {
4548 if (memcmp((const BYTE *)data.Scan0 + j * data.Stride, td[i].pixels + j * data.Stride, width_bytes) != 0)
4549 {
4550 match = 0;
4551 break;
4552 }
4553 }
4555 {
4556 ok(match,
4557 "%u: data should match\n", i);
4558 if (!match)
4559 trace("%u: data mismatch for format %#x:%s\n", i, td[i].format,
4560 dbgstr_hexdata(data.Scan0, td[i].size));
4561 }
4562 else
4563 ok(!match, "%u: data shouldn't match\n", i);
4564
4565 memset(data.Scan0, 0, td[i].size);
4566 }
4567
4569 ok(status == Ok, "%u: GdipBitmapUnlockBits error %d\n", i, status);
4570
4571 memset(&data, 0xfe, sizeof(data));
4573 ok(status == Ok, "%u: GdipBitmapLockBits error %d\n", i, status);
4574 ok(data.Width == 8, "%u: expected 8, got %d\n", i, data.Width);
4575 ok(data.Height == 2, "%u: expected 2, got %d\n", i, data.Height);
4576 ok(data.Stride == 24, "%u: expected 24, got %d\n", i, data.Stride);
4577 ok(data.PixelFormat == PixelFormat24bppRGB, "%u: got wrong pixel format %d\n", i, data.PixelFormat);
4578 ok(data.Height * data.Stride == 48, "%u: expected 48, got %d\n", i, data.Height * data.Stride);
4579 if (data.Height * data.Stride == 48)
4580 {
4581 int match = memcmp(data.Scan0, td[i].pixels_unlocked, 48) == 0;
4582 ok(match, "%u: data should match\n", i);
4583 if (!match)
4584 trace("%u: data mismatch for format %#x:%s\n", i, td[i].format, dbgstr_hexdata(data.Scan0, 48));
4585 }
4586
4588 ok(status == Ok, "%u: GdipBitmapUnlockBits error %d\n", i, status);
4589
4591 expect(Ok, status);
4592 }
4593}
4594
4595static void test_DrawImage(void)
4596{
4597 BYTE black_1x1[4] = { 0,0,0,0 };
4598 BYTE white_2x2[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4599 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4600 BYTE black_2x2[16] = { 0,0,0,0,0,0,0xff,0xff,
4601 0,0,0,0,0,0,0xff,0xff };
4603 union
4604 {
4606 GpImage *image;
4607 } u1, u2;
4608 GpGraphics *graphics;
4609 int match;
4610
4611 status = GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB, black_1x1, &u1.bitmap);
4612 expect(Ok, status);
4613 status = GdipBitmapSetResolution(u1.bitmap, 100.0, 100.0);
4614 expect(Ok, status);
4615
4616 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB, white_2x2, &u2.bitmap);
4617 expect(Ok, status);
4618 status = GdipBitmapSetResolution(u2.bitmap, 300.0, 300.0);
4619 expect(Ok, status);
4620 status = GdipGetImageGraphicsContext(u2.image, &graphics);
4621 expect(Ok, status);
4623 expect(Ok, status);
4624
4625 status = GdipDrawImageI(graphics, u1.image, 0, 0);
4626 expect(Ok, status);
4627
4628 match = memcmp(white_2x2, black_2x2, sizeof(black_2x2)) == 0;
4629 ok(match, "data should match\n");
4630 if (!match)
4631 trace("%s\n", dbgstr_hexdata(white_2x2, sizeof(white_2x2)));
4632
4633 status = GdipDeleteGraphics(graphics);
4634 expect(Ok, status);
4635 status = GdipDisposeImage(u1.image);
4636 expect(Ok, status);
4637 status = GdipDisposeImage(u2.image);
4638 expect(Ok, status);
4639}
4640
4642{
4643 DWORD dst_pixels[4] = { 0xffffffff, 0xffffffff,
4644 0xffffffff, 0xffffffff };
4645 DWORD src_pixels[4] = { 0, 0xffff0000,
4646 0, 0xff00ff };
4647
4649 union
4650 {
4652 GpImage *image;
4653 } u1, u2;
4654 GpGraphics *graphics;
4655
4656 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB, (BYTE*)dst_pixels, &u1.bitmap);
4657 expect(Ok, status);
4658
4659 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat32bppARGB, (BYTE*)src_pixels, &u2.bitmap);
4660 expect(Ok, status);
4661 status = GdipGetImageGraphicsContext(u1.image, &graphics);
4662 expect(Ok, status);
4664 expect(Ok, status);
4665
4667 expect(Ok, status);
4668
4669 status = GdipDrawImageI(graphics, u2.image, 0, 0);
4670 expect(Ok, status);
4671
4672 expect(0, dst_pixels[0]);
4673 expect(0xffff0000, dst_pixels[1]);
4674 expect(0, dst_pixels[2]);
4675 expect(0, dst_pixels[3]);
4676
4677 status = GdipDeleteGraphics(graphics);
4678 expect(Ok, status);
4679 status = GdipDisposeImage(u1.image);
4680 expect(Ok, status);
4681 status = GdipDisposeImage(u2.image);
4682 expect(Ok, status);
4683}
4684
4686{
4687 BYTE black_1x1[4] = { 0,0,0,0 };
4688 BYTE white_2x2[16] = { 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
4689 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
4690 BYTE black_2x2[16] = { 0,0,0,0,0,0,0xff,0xff,
4691 0,0,0,0,0,0,0xff,0xff };
4693 union
4694 {
4696 GpImage *image;
4697 } u1, u2;
4698 GpGraphics *graphics;
4699 int match;
4700
4701 status = GdipCreateBitmapFromScan0(1, 1, 4, PixelFormat24bppRGB, black_1x1, &u1.bitmap);
4702 expect(Ok, status);
4703 status = GdipBitmapSetResolution(u1.bitmap, 100.0, 100.0);
4704 expect(Ok, status);
4705
4706 status = GdipCreateBitmapFromScan0(2, 2, 8, PixelFormat24bppRGB, white_2x2, &u2.bitmap);
4707 expect(Ok, status);
4708 status = GdipBitmapSetResolution(u2.bitmap, 300.0, 300.0);
4709 expect(Ok, status);
4710 status = GdipGetImageGraphicsContext(u2.image, &graphics);
4711 expect(Ok, status);
4713 expect(Ok, status);
4714
4715 status = GdipDrawImagePointRectI(graphics, u1.image, 0, 0, 0, 0, 1, 1, UnitPixel);
4716 expect(Ok, status);
4717
4718 match = memcmp(white_2x2, black_2x2, sizeof(black_2x2)) == 0;
4719 ok(match, "data should match\n");
4720 if (!match)
4721 trace("%s\n", dbgstr_hexdata(white_2x2, sizeof(white_2x2)));
4722
4723 status = GdipDeleteGraphics(graphics);
4724 expect(Ok, status);
4725 status = GdipDisposeImage(u1.image);
4726 expect(Ok, status);
4727 status = GdipDisposeImage(u2.image);
4728 expect(Ok, status);
4729}
4730
4731static void test_image_format(void)
4732{
4733 static const PixelFormat fmt[] =
4734 {
4740 };
4743 GpImage *thumb;
4745 BITMAP bm;
4748 UINT i, ret;
4749
4750 for (i = 0; i < ARRAY_SIZE(fmt); i++)
4751 {
4753 ok(status == Ok || broken(status == InvalidParameter) /* before win7 */,
4754 "GdipCreateBitmapFromScan0 error %d\n", status);
4755 if (status != Ok) continue;
4756
4758 expect(Ok, status);
4759 expect(fmt[i], format);
4760
4764 else
4765 {
4766 expect(Ok, status);
4767 ret = GetObjectW(hbitmap, sizeof(bm), &bm);
4768 expect(sizeof(bm), ret);
4769 expect(0, bm.bmType);
4770 expect(1, bm.bmWidth);
4771 expect(1, bm.bmHeight);
4772 expect(4, bm.bmWidthBytes);
4773 expect(1, bm.bmPlanes);
4774 expect(32, bm.bmBitsPixel);
4776 }
4777
4778 status = GdipGetImageThumbnail((GpImage *)bitmap, 0, 0, &thumb, NULL, NULL);
4780 todo_wine
4781 ok(status == OutOfMemory || broken(status == InvalidParameter) /* before win7 */,
4782 "expected OutOfMemory, got %d\n", status);
4783 else
4784 expect(Ok, status);
4785 if (status == Ok)
4786 {
4788 expect(Ok, status);
4790 "expected PixelFormat32bppPARGB, got %#x\n", format);
4791 status = GdipDisposeImage(thumb);
4792 expect(Ok, status);
4793 }
4794
4798 else
4799 {
4800 expect(Ok, status);
4802 expect(Ok, status);
4803 }
4804
4806 expect(Ok, status);
4807 }
4808}
4809
4810INT compare_with_precision(const BYTE *ptr1, const BYTE *ptr2, size_t num, INT precision)
4811{
4812 if (ptr1 == NULL || ptr2 == NULL)
4813 return ptr1 < ptr2 ? -1 : 1;
4814
4815 for (size_t i = 0; i < num; i++)
4816 {
4817 INT byte1 = ptr1[i];
4818 INT byte2 = ptr2[i];
4819
4820 if ((byte1 < byte2 - precision) || (byte1 > byte2 + precision))
4821 return byte1 < byte2 ? -1 : 1;
4822 }
4823
4824 return 0;
4825}
4826
4827static void test_DrawImage_scale(void)
4828{
4829 static const BYTE back_8x1[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40,
4830 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4831 static const BYTE image_080[24] = { 0x40,0x40,0x40, 0x80,0x80,0x80, 0x40,0x40,0x40, 0x40,0x40,0x40,
4832 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4833 static const BYTE image_100[24] = { 0x40,0x40,0x40, 0x80,0x80,0x80, 0xcc,0xcc,0xcc, 0x40,0x40,0x40,
4834 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4835 static const BYTE image_120[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0xcc,0xcc,0xcc, 0x40,0x40,0x40,
4836 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4837 static const BYTE image_150[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0x80,0x80,0x80, 0xcc,0xcc,0xcc,
4838 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4839 static const BYTE image_180[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0x80,0x80,0x80, 0xcc,0xcc,0xcc,
4840 0xcc,0xcc,0xcc, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4841 static const BYTE image_200[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0x80,0x80,0x80, 0xcc,0xcc,0xcc,
4842 0xcc,0xcc,0xcc, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4843 static const BYTE image_250[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x80,0x80,0x80,
4844 0xcc,0xcc,0xcc, 0xcc,0xcc,0xcc, 0xcc,0xcc,0xcc, 0x40,0x40,0x40 };
4845 static const BYTE image_120_half[24] = { 0x40,0x40,0x40, 0x80,0x80,0x80, 0xcc,0xcc,0xcc, 0xcc,0xcc,0xcc,
4846 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4847 static const BYTE image_150_half[24] = { 0x40,0x40,0x40, 0x80,0x80,0x80, 0x80,0x80,0x80, 0xcc,0xcc,0xcc,
4848 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4849 static const BYTE image_180_half[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0x80,0x80,0x80, 0x80,0x80,0x80,
4850 0xcc,0xcc,0xcc, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4851 static const BYTE image_200_half[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0x80,0x80,0x80, 0x80,0x80,0x80,
4852 0xcc,0xcc,0xcc, 0xcc,0xcc,0xcc, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4853 static const BYTE image_250_half[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0x80,0x80,0x80, 0x80,0x80,0x80,
4854 0x80,0x80,0x80, 0xcc,0xcc,0xcc, 0xcc,0xcc,0xcc, 0x40,0x40,0x40 };
4855
4856 static const BYTE image_bil_080[24] = { 0x40,0x40,0x40, 0x93,0x93,0x93, 0x86,0x86,0x86, 0x40,0x40,0x40,
4857 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4858 static const BYTE image_bil_120[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0xb2,0xb2,0xb2, 0x87,0x87,0x87,
4859 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4860 static const BYTE image_bil_150[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0x99,0x99,0x99, 0xcc,0xcc,0xcc,
4861 0x6f,0x6f,0x6f, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4862 static const BYTE image_bil_180[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0x88,0x88,0x88, 0xb2,0xb2,0xb2,
4863 0xad,0xad,0xad, 0x5f,0x5f,0x5f, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4864 static const BYTE image_bil_200[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0x80,0x80,0x80, 0xa6,0xa6,0xa6,
4865 0xcc,0xcc,0xcc, 0x86,0x86,0x86, 0x40,0x40,0x40, 0x40,0x40,0x40 };
4866 static const BYTE image_bil_250[24] = { 0x40,0x40,0x40, 0x40,0x40,0x40, 0x40,0x40,0x40, 0x8f,0x8f,0x8f,
4867 0xad,0xad,0xad, 0xcc,0xcc,0xcc, 0x95,0x95,0x95, 0x5c,0x5c,0x5c };
4868 static const struct test_data
4869 {
4870 REAL scale_x;
4871 InterpolationMode interpolation_mode;
4872 PixelOffsetMode pixel_offset_mode;
4873 const BYTE *image;
4874 INT precision;
4875 BOOL todo;
4876 } td[] =
4877 {
4878 { 0.8, InterpolationModeNearestNeighbor, PixelOffsetModeNone, image_080 }, /* 0 */
4885
4893
4894 /* TODO There are missing left pixel column of image*/
4895 { 0.8, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_080 }, /* 14 */
4897 { 1.2, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_120_half, 0, TRUE },
4898 { 1.5, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_150_half, 0, TRUE },
4899 { 1.8, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_180_half, 0, TRUE },
4900 { 2.0, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_200_half, 0, TRUE },
4901 { 2.5, InterpolationModeNearestNeighbor, PixelOffsetModeHalf, image_250_half, 0, TRUE },
4902
4910
4911 /* The bilinear interpolation results are little bit different than on Windows */
4912 /* TODO In two cases, there are missing right pixel column of image */
4913 { 0.8, InterpolationModeBilinear, PixelOffsetModeNone, image_bil_080, 1, TRUE }, /* 28 */
4915 { 1.2, InterpolationModeBilinear, PixelOffsetModeNone, image_bil_120, 2 },
4916 { 1.5, InterpolationModeBilinear, PixelOffsetModeNone, image_bil_150, 1 },
4917 { 1.8, InterpolationModeBilinear, PixelOffsetModeNone, image_bil_180, 1, TRUE },
4918 { 2.0, InterpolationModeBilinear, PixelOffsetModeNone, image_bil_200, 1 },
4919 { 2.5, InterpolationModeBilinear, PixelOffsetModeNone, image_bil_250, 1 },
4920 };
4921 BYTE src_2x1[6] = { 0x80,0x80,0x80, 0xcc,0xcc,0xcc };
4922 BYTE dst_8x1[24];
4924 union
4925 {
4927 GpImage *image;
4928 } u1, u2;
4929 GpGraphics *graphics;
4931 int i, match;
4932
4933 status = GdipCreateBitmapFromScan0(2, 1, 4, PixelFormat24bppRGB, src_2x1, &u1.bitmap);
4934 expect(Ok, status);
4935 status = GdipBitmapSetResolution(u1.bitmap, 100.0, 100.0);
4936 expect(Ok, status);
4937
4938 status = GdipCreateBitmapFromScan0(8, 1, 24, PixelFormat24bppRGB, dst_8x1, &u2.bitmap);
4939 expect(Ok, status);
4940 status = GdipBitmapSetResolution(u2.bitmap, 100.0, 100.0);
4941 expect(Ok, status);
4942 status = GdipGetImageGraphicsContext(u2.image, &graphics);
4943 expect(Ok, status);
4944
4945 for (i = 0; i < ARRAY_SIZE(td); i++)
4946 {
4947 status = GdipSetInterpolationMode(graphics, td[i].interpolation_mode);
4948 expect(Ok, status);
4949
4950 status = GdipSetPixelOffsetMode(graphics, td[i].pixel_offset_mode);
4951 expect(Ok, status);
4952
4953 status = GdipCreateMatrix2(td[i].scale_x, 0.0, 0.0, 1.0, 0.0, 0.0, &matrix);
4954 expect(Ok, status);
4955 status = GdipSetWorldTransform(graphics, matrix);
4956 expect(Ok, status);
4958
4959 memcpy(dst_8x1, back_8x1, sizeof(dst_8x1));
4960 status = GdipDrawImageI(graphics, u1.image, 1, 0);
4961 expect(Ok, status);
4962
4963 match = compare_with_precision(dst_8x1, td[i].image, sizeof(dst_8x1), td[i].precision) == 0;
4964 todo_wine_if (!match && td[i].todo)
4965 ok(match, "%d: data should match\n", i);
4966 if (!match)
4967 {
4968 trace("Expected: %s\n", dbgstr_hexdata(td[i].image, sizeof(dst_8x1)));
4969 trace("Got: %s\n", dbgstr_hexdata(dst_8x1, sizeof(dst_8x1)));
4970 }
4971 }
4972
4973 status = GdipDeleteGraphics(graphics);
4974 expect(Ok, status);
4975 status = GdipDisposeImage(u1.image);
4976 expect(Ok, status);
4977 status = GdipDisposeImage(u2.image);
4978 expect(Ok, status);
4979}
4980
4981static const BYTE animatedgif[] = {
4982'G','I','F','8','9','a',0x01,0x00,0x01,0x00,0xA1,0x02,0x00,
49830x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
4984/*0x21,0xFF,0x0B,'A','N','I','M','E','X','T','S','1','.','0',*/
49850x21,0xFF,0x0B,'N','E','T','S','C','A','P','E','2','.','0',
49860x03,0x01,0x05,0x00,0x00,
49870x21,0xFE,0x0C,'H','e','l','l','o',' ','W','o','r','l','d','!',0x00,
49880x21,0x01,0x0D,'a','n','i','m','a','t','i','o','n','.','g','i','f',0x00,
49890x21,0xF9,0x04,0xff,0x0A,0x00,0x08,0x00,
49900x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
49910xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,
49920x02,0x02,0x4C,0x01,0x00,
49930x21,0xFE,0x08,'i','m','a','g','e',' ','#','1',0x00,
49940x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','1',0x00,
49950x21,0xF9,0x04,0x00,0x14,0x00,0x01,0x00,
49960x2C,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x81,
49970xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,
49980x02,0x02,0x44,0x01,0x00,
49990x21,0xFE,0x08,'i','m','a','g','e',' ','#','2',0x00,
50000x21,0x01,0x0C,'p','l','a','i','n','t','e','x','t',' ','#','2',0x00,0x3B
5001};
5002
5003static const BYTE gif_2frame_global_pal[] = {
5004'G','I','F','8','7','a', 0x01,0x00, 0x01,0x00, 0xa1, 0x02, 0x00,
50050x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,
50060x21,0xF9,0x04, 0x00,0x0A,0x00,0x08, 0x00,
50070x2c, 0x00,0x00, 0x00,0x00, 0x01,0x00, 0x01,0x00, 0x01,
50080x02,0x02,0x44,0x01,0x00,
50090x21,0xF9,0x04, 0x00,0x14,0x00,0x08, 0x00,
50100x2c, 0x00,0x00, 0x00,0x00, 0x01,0x00, 0x01,0x00, 0x01,
50110x02,0x02,0x44,0x01,0x00, 0x3b
5012};
5013
5014static const BYTE gif_2frame_no_pal[] = {
5015'G','I','F','8','7','a', 0x01,0x00, 0x01,0x00, 0x21, 0x02, 0x00,
50160x21,0xF9,0x04, 0x00,0x0A,0x00,0x08, 0x00,
50170x2c, 0x00,0x00, 0x00,0x00, 0x01,0x00, 0x01,0x00, 0x01,
50180x02,0x02,0x44,0x01,0x00,
50190x21,0xF9,0x04, 0x00,0x14,0x00,0x08, 0x00,
50200x2c, 0x00,0x00, 0x00,0x00, 0x01,0x00, 0x01,0x00, 0x01,
50210x02,0x02,0x44,0x01,0x00, 0x3b
5022};
5023
5025'G','I','F','8','7','a', 0x01,0x00, 0x01,0x00, 0x21, 0x02, 0x00,
50260x2c, 0x00,0x00, 0x00,0x00, 0x01,0x00, 0x01,0x00, 0x01,
50270x02,0x02,0x44,0x01,0x00,
50280x21,0xF9,0x04, 0x00,0x14,0x00,0x08, 0x00,
50290x2c, 0x00,0x00, 0x00,0x00, 0x01,0x00, 0x01,0x00, 0x01,
50300x02,0x02,0x44,0x01,0x00, 0x3b
5031};
5032
5034'G','I','F','8','7','a', 0x01,0x00, 0x01,0x00, 0x21, 0x02, 0x00,
50350x21,0xF9,0x04, 0x00,0x0A,0x00,0x08, 0x00,
50360x2c, 0x00,0x00, 0x00,0x00, 0x01,0x00, 0x01,0x00, 0x01,
50370x02,0x02,0x44,0x01,0x00,
50380x2c, 0x00,0x00, 0x00,0x00, 0x01,0x00, 0x01,0x00, 0x01,
50390x02,0x02,0x44,0x01,0x00, 0x3b
5040};
5041
5042static const BYTE gif_no_pal[] = {
5043'G','I','F','8','7','a', 0x01,0x00, 0x01,0x00, 0x27, 0x02, 0x00,
50440x2c, 0x00,0x00, 0x00,0x00, 0x01,0x00, 0x01,0x00, 0x01,
50450x02,0x02,0x44,0x01,0x00, 0x3b
5046};
5047
5048static void test_gif_properties(void)
5049{
5050 static const struct property_test_data animatedgif_props[] =
5051 {
5052 { PropertyTagTypeLong, PropertyTagFrameDelay, 8, { 10,0,0,0,20,0,0,0 } },
5053 { PropertyTagTypeASCII, PropertyTagExifUserComment, 13, "Hello World!" },
5055 { PropertyTagTypeByte, PropertyTagGlobalPalette, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
5058 };
5059 static const struct property_test_data gif_2frame_global_pal_props[] =
5060 {
5061 { PropertyTagTypeLong, PropertyTagFrameDelay, 8, { 10,0,0,0,20,0,0,0 } },
5063 { PropertyTagTypeByte, PropertyTagGlobalPalette, 12, { 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c } },
5065 };
5066 static const struct property_test_data gif_2frame_no_pal_props[] =
5067 {
5068 { PropertyTagTypeLong, PropertyTagFrameDelay, 8, { 10,0,0,0,20,0,0,0 } },
5070 };
5071 static const struct property_test_data gif_2frame_missing_gce1_props[] =
5072 {
5073 { PropertyTagTypeLong, PropertyTagFrameDelay, 8, { 0,0,0,0,20,0,0,0 } },
5075 };
5076 static const struct property_test_data gif_2frame_missing_gce2_props[] =
5077 {
5078 { PropertyTagTypeLong, PropertyTagFrameDelay, 8, { 10,0,0,0,10,0,0,0 } },
5080 };
5081 static const struct property_test_data gif_no_pal_props[] =
5082 {
5083 { PropertyTagTypeLong, PropertyTagFrameDelay, 4, { 0,0,0,0 } },
5085 };
5086
5087 static const struct test_data {
5088 const BYTE *image_data;
5089 size_t image_size;
5090 const struct property_test_data *prop_item;
5091 size_t prop_count;
5092 UINT frame_count;
5093 } td[] =
5094 {
5095#define giftest(img, prop, frames) { img, sizeof(img), prop, ARRAY_SIZE(prop), frames }
5096 giftest(animatedgif, animatedgif_props, 2),
5097 giftest(gif_2frame_global_pal, gif_2frame_global_pal_props, 2),
5098 giftest(gif_2frame_no_pal, gif_2frame_no_pal_props, 2),
5099 giftest(gif_2frame_missing_gce1, gif_2frame_missing_gce1_props, 2),
5100 giftest(gif_2frame_missing_gce2, gif_2frame_missing_gce2_props, 2),
5101 giftest(gif_no_pal, gif_no_pal_props, 1),
5102#undef giftest
5103 };
5104
5106 GpImage *image;
5107 GUID guid;
5108 UINT dim_count, frame_count, prop_size, i;
5109
5110 for (i = 0; i < ARRAY_SIZE(td); i++)
5111 {
5112 winetest_push_context("test %u", i);
5113
5114 image = load_image(td[i].image_data, td[i].image_size, TRUE, FALSE);
5115 if (!image) /* XP fails to load most of these GIF images */
5116 {
5117 trace("Failed to load GIF image data\n");
5119 continue;
5120 }
5121
5123 expect(Ok, status);
5124 expect(1, dim_count);
5125
5127 expect(Ok, status);
5128 expect_guid(&FrameDimensionTime, &guid, __LINE__, FALSE);
5129
5130 status = GdipImageGetFrameCount(image, &guid, &frame_count);
5131 expect(Ok, status);
5132 expect(td[i].frame_count, frame_count);
5133
5134 status = GdipImageSelectActiveFrame(image, &guid, td[i].frame_count - 1);
5135 expect(Ok, status);
5136
5138
5139 winetest_push_context("%s test %u", __FUNCTION__, i);
5140 check_properties_id_list(image, td[i].prop_item, td[i].prop_count, td[i].prop_item, 1, &prop_size);
5141 check_properties_get_all(image, td[i].prop_item, td[i].prop_count, td[i].prop_item, 1, prop_size);
5143
5145 }
5146}
5147
5148static void test_ARGB_conversion(void)
5149{
5150 BYTE argb[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
5151 BYTE pargb[8] = { 0x09,0x11,0x1a,0x80, 0,0,0,0 };
5152 BYTE rgb32_xp[8] = { 0x11,0x22,0x33,0xff, 0xff,0xff,0xff,0xff };
5153 BYTE rgb24[6] = { 0x11,0x22,0x33, 0xff,0xff,0xff };
5154 BYTE *bits;
5158 int match;
5159
5161 expect(Ok, status);
5162
5164 expect(Ok, status);
5165 ok(data.Width == 2, "expected 2, got %d\n", data.Width);
5166 ok(data.Height == 1, "expected 1, got %d\n", data.Height);
5167 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride);
5168 ok(data.PixelFormat == PixelFormat32bppPARGB, "expected PixelFormat32bppPARGB, got %d\n", data.PixelFormat);
5169 match = !memcmp(data.Scan0, pargb, sizeof(pargb));
5170 ok(match, "bits don't match\n");
5171 if (!match)
5172 {
5173 bits = data.Scan0;
5174 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB,
5175 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]);
5176 }
5178 expect(Ok, status);
5179
5181 expect(Ok, status);
5182 ok(data.Width == 2, "expected 2, got %d\n", data.Width);
5183 ok(data.Height == 1, "expected 1, got %d\n", data.Height);
5184 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride);
5185 ok(data.PixelFormat == PixelFormat32bppRGB, "expected PixelFormat32bppRGB, got %d\n", data.PixelFormat);
5186 match = !memcmp(data.Scan0, argb, sizeof(argb)) ||
5187 !memcmp(data.Scan0, rgb32_xp, sizeof(rgb32_xp));
5188 ok(match, "bits don't match\n");
5189 if (!match)
5190 {
5191 bits = data.Scan0;
5192 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppRGB,
5193 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]);
5194 }
5196 expect(Ok, status);
5197
5199 expect(Ok, status);
5200 ok(data.Width == 2, "expected 2, got %d\n", data.Width);
5201 ok(data.Height == 1, "expected 1, got %d\n", data.Height);
5202 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride);
5203 ok(data.PixelFormat == PixelFormat24bppRGB, "expected PixelFormat24bppRGB, got %d\n", data.PixelFormat);
5204 match = !memcmp(data.Scan0, rgb24, sizeof(rgb24));
5205 ok(match, "bits don't match\n");
5206 if (!match)
5207 {
5208 bits = data.Scan0;
5209 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat24bppRGB,
5210 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]);
5211 }
5213 expect(Ok, status);
5214
5216}
5217
5218static void test_PARGB_conversion(void)
5219{
5220 BYTE pargb[8] = { 0x62,0x77,0x99,0x77, 0x62,0x77,0x99,0 };
5221 BYTE argb[8] = { 0xd1,0xfe,0xff,0x77, 0x62,0x77,0x99,0 };
5222 BYTE pargb2[8] = { 0x01,0x01,0x00,0x01, 0xfe,0x7f,0x7f,0xfe };
5223 BYTE *bits;
5227 int match;
5228
5230 expect(Ok, status);
5231
5233 expect(Ok, status);
5234 ok(data.Width == 2, "expected 2, got %d\n", data.Width);
5235 ok(data.Height == 1, "expected 1, got %d\n", data.Height);
5236 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride);
5237 ok(data.PixelFormat == PixelFormat32bppARGB, "expected PixelFormat32bppARGB, got %d\n", data.PixelFormat);
5238 match = !memcmp(data.Scan0, argb, sizeof(argb));
5239 ok(match, "bits don't match\n");
5240 if (!match)
5241 {
5242 bits = data.Scan0;
5243 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppARGB,
5244 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]);
5245 }
5247 expect(Ok, status);
5248
5249 /* Testing SetPixel 32-bit ARGB to PARGB */
5250 status = GdipBitmapSetPixel(bitmap, 0, 0, 0x017f80ff);
5251 expect(Ok, status);
5252 status = GdipBitmapSetPixel(bitmap, 1, 0, 0xfe7f80ff);
5253 expect(Ok, status);
5255 expect(Ok, status);
5256 ok(data.Width == 2, "expected 2, got %d\n", data.Width);
5257 ok(data.Height == 1, "expected 1, got %d\n", data.Height);
5258 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride);
5259 ok(data.PixelFormat == PixelFormat32bppPARGB, "expected PixelFormat32bppPARGB, got %d\n", data.PixelFormat);
5260 match = !memcmp(data.Scan0, pargb2, sizeof(pargb2));
5261 ok(match, "bits don't match\n");
5262 if (!match)
5263 {
5264 bits = data.Scan0;
5265 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppPARGB,
5266 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]);
5267 }
5269 expect(Ok, status);
5270
5272}
5273
5274
5275static void test_CloneBitmapArea(void)
5276{
5277 /* 3x3 pixeldata in various formats: red, green, blue, yellow, turquoise, pink, black, gray, white */
5278 static BYTE bmp_3x3_data_32bpp_argb[] = {
5279 0xff,0x00,0x00,0xff, 0x00,0xff,0x00,0xff, 0x00,0x00,0xff,0xff,
5280 0xff,0xff,0x00,0xff, 0x00,0xff,0xff,0xff, 0xff,0x00,0xff,0xff,
5281 0xff,0xff,0xff,0xff, 0x80,0x80,0x80,0xff, 0x00,0x00,0x00,0xff
5282 };
5283 static BYTE bmp_3x3_data_32bpp_rgb[] = {
5284 0xff,0x00,0x00,0x00, 0x00,0xff,0x00,0x00, 0x00,0x00,0xff,0x00,
5285 0xff,0xff,0x00,0x00, 0x00,0xff,0xff,0x00, 0xff,0x00,0xff,0x00,
5286 0xff,0xff,0xff,0x00, 0x80,0x80,0x80,0x00, 0x00,0x00,0x00,0x00
5287 };
5288 static BYTE bmp_3x3_data_24bpp_rgb[] = {
5289 0xff,0x00,0x00, 0x00,0xff,0x00, 0x00,0x00,0xff,
5290 0xff,0xff,0x00, 0x00,0xff,0xff, 0xff,0x00,0xff,
5291 0xff,0xff,0xff, 0x80,0x80,0x80, 0x00,0x00,0x00
5292 };
5293
5294 static const struct test_data {
5295 BYTE *src_pixeldata;
5296 PixelFormat src_format;
5298 } td[] =
5299 {
5300 { bmp_3x3_data_32bpp_argb, PixelFormat32bppARGB, PixelFormat8bppIndexed },
5301 { bmp_3x3_data_32bpp_argb, PixelFormat32bppARGB, PixelFormat4bppIndexed },
5302 { bmp_3x3_data_32bpp_argb, PixelFormat32bppARGB, PixelFormat1bppIndexed },
5303 { bmp_3x3_data_32bpp_rgb, PixelFormat32bppRGB, PixelFormat8bppIndexed },
5304 { bmp_3x3_data_32bpp_rgb, PixelFormat32bppRGB, PixelFormat4bppIndexed },
5305 { bmp_3x3_data_32bpp_rgb, PixelFormat32bppRGB, PixelFormat1bppIndexed },
5306 { bmp_3x3_data_24bpp_rgb, PixelFormat24bppRGB, PixelFormat8bppIndexed },
5307 { bmp_3x3_data_24bpp_rgb, PixelFormat24bppRGB, PixelFormat4bppIndexed },
5308 { bmp_3x3_data_24bpp_rgb, PixelFormat24bppRGB, PixelFormat1bppIndexed },
5309 };
5310
5312 GpBitmap *bitmap, *copy;
5314 INT x, y, i;
5315
5317 expect(Ok, status);
5318
5320 expect(Ok, status);
5321
5324
5326 expect(Ok, status);
5327
5329 expect(Ok, status);
5330
5333
5334#ifdef __REACTOS__
5335 if (!is_reactos() && (GetNTVersion() < NTDDI_WIN7))
5336 {
5337 trace("Skipping test cases pre Win 7, because they fail.\n");
5338 }
5339 else
5340#endif
5341 for(i=0; i<ARRAY_SIZE(td); i++)
5342 {
5343 status = GdipCreateBitmapFromScan0(3, 3, 4*3, td[i].src_format, td[i].src_pixeldata, &bitmap);
5344 expect(Ok, status);
5345
5346 status = GdipCloneBitmapAreaI(0, 0, 3, 3, td[i].dst_format, bitmap, &copy);
5347 expect(Ok, status);
5348
5349 for (y=0; y<3; y++)
5350 for (x=0; x<3; x++)
5351 {
5352 BOOL match;
5353 ARGB color_orig;
5354 ARGB color_copy;
5355
5356 status = GdipBitmapGetPixel(bitmap, x, y, &color_orig);
5357 expect(Ok, status);
5358
5359 status = GdipBitmapGetPixel(copy, x, y, &color_copy);
5360 expect(Ok, status);
5361
5363 color_orig = (color_orig >> 16 & 0xff) + (color_orig >> 8 & 0xff) + (color_orig & 0xff)
5364 > 0x17d ? 0xffffffff : 0xff000000;
5365
5366 match = color_match(color_orig, color_copy, 0x00);
5367 ok(match == TRUE, "Colors 0x%08lx and 0x%08lx do not match! (Conversion from %x to %x)\n",
5368 color_orig, color_copy, td[i].src_format, td[i].dst_format);
5369 }
5370
5373 }
5374}
5375
5377{
5378 static const struct test_data
5379 {
5380 LPCWSTR mime;
5381 const GUID *format;
5382 } td[] =
5383 {
5384 { L"image/bmp", &ImageFormatBMP },
5385 { L"image/jpeg", &ImageFormatJPEG },
5386 { L"image/gif", &ImageFormatGIF },
5387 { L"image/tiff", &ImageFormatTIFF },
5388 { L"image/png", &ImageFormatPNG }
5389 };
5390 GUID format, clsid;
5391 BOOL ret;
5392 HRESULT hr;
5394 GpBitmap *bm;
5395 IStream *stream;
5396 HGLOBAL hmem;
5397 int i;
5398
5400 ok(status == Ok, "GdipCreateBitmapFromScan0 error %d\n", status);
5401
5402 for (i = 0; i < ARRAY_SIZE(td); i++)
5403 {
5405 ok(ret, "%s encoder is not in the list\n", wine_dbgstr_w(td[i].mime));
5406 expect_guid(td[i].format, &format, __LINE__, FALSE);
5407
5409
5411 ok(hr == S_OK, "CreateStreamOnHGlobal error %#lx\n", hr);
5412
5414 ok(status == Ok, "%s encoder, GdipSaveImageToStream error %d\n", wine_dbgstr_w(td[i].mime), status);
5415
5416 IStream_Release(stream);
5417 }
5418
5420}
5421
5422static void test_createeffect(void)
5423{
5424 static const GUID noneffect = { 0xcd0c3d4b, 0xe15e, 0x4cf2, { 0x9e, 0xa8, 0x6e, 0x1d, 0x65, 0x48, 0xc5, 0xa5 } };
5425 GpStatus (WINAPI *pGdipCreateEffect)( const GUID guid, CGpEffect **effect);
5426 GpStatus (WINAPI *pGdipDeleteEffect)( CGpEffect *effect);
5427 GpStatus (WINAPI *pGdipGetEffectParameterSize)(CGpEffect *effect, UINT *size);
5428 GpStatus (WINAPI *pGdipGetEffectParameters)(CGpEffect *effect, const VOID *params, const UINT size);
5429 GpStatus stat;
5430 CGpEffect *effect = NULL;
5431 HMODULE mod = GetModuleHandleA("gdiplus.dll");
5432 int i;
5433 UINT param_size;
5434
5435 static const struct test_data {
5436 const GUID *effect;
5437 const UINT parameters_number;
5438 } td[] =
5439 {
5440 { &BlurEffectGuid, 8 },
5441 { &BrightnessContrastEffectGuid, 8 },
5442 { &ColorBalanceEffectGuid, 12 },
5443 { &ColorCurveEffectGuid, 12 },
5444 { &ColorLUTEffectGuid, 1024 },
5445 { &ColorMatrixEffectGuid, 100 },
5446 { &HueSaturationLightnessEffectGuid, 12 },
5447 { &LevelsEffectGuid, 12 },
5448 /* Parameter Size for Red Eye Correction effect is different for 64 bits build */
5449#ifdef _WIN64
5450 { &RedEyeCorrectionEffectGuid, 16 },
5451#else
5452 { &RedEyeCorrectionEffectGuid, 8 },
5453#endif
5454 { &SharpenEffectGuid, 8 },
5455 { &TintEffectGuid, 8 },
5456 };
5457
5458 pGdipCreateEffect = (void*)GetProcAddress( mod, "GdipCreateEffect");
5459 pGdipDeleteEffect = (void*)GetProcAddress( mod, "GdipDeleteEffect");
5460 pGdipGetEffectParameterSize = (void*)GetProcAddress( mod, "GdipGetEffectParameterSize");
5461 pGdipGetEffectParameters = (void*)GetProcAddress( mod, "GdipGetEffectParameters");
5462 if (!pGdipCreateEffect || !pGdipDeleteEffect || !pGdipGetEffectParameterSize || !pGdipGetEffectParameters)
5463 {
5464 /* GdipCreateEffect/GdipDeleteEffect/GdipGetEffectParameterSize/GdipGetEffectParameters were introduced in Windows Vista. */
5465 win_skip("GDIPlus version 1.1 not available\n");
5466 return;
5467 }
5468
5469 stat = pGdipCreateEffect(BlurEffectGuid, NULL);
5471
5472 stat = pGdipCreateEffect(noneffect, &effect);
5474 ok( !effect, "expected null effect\n");
5475
5476 param_size = 0;
5477 stat = pGdipGetEffectParameterSize(NULL, &param_size);
5479 expect(0, param_size);
5480
5481 for (i = 0; i < ARRAY_SIZE(td); i++)
5482 {
5483 stat = pGdipCreateEffect(*(td[i].effect), &effect);
5484 expect(Ok, stat);
5485 if (stat == Ok)
5486 {
5487 param_size = 0;
5488 stat = pGdipGetEffectParameterSize(effect, &param_size);
5489 expect(Ok, stat);
5490 expect(td[i].parameters_number, param_size);
5491 stat = pGdipDeleteEffect(effect);
5492 expect(Ok, stat);
5493 }
5494 }
5495
5496 stat = pGdipDeleteEffect(NULL);
5498}
5499
5501{
5502 ColorMap colormap;
5503 GpImageAttributes *imageattributes;
5505 GpStatus stat;
5506
5507 stat = GdipCreateImageAttributes(&imageattributes);
5508 expect(Ok, stat);
5509
5510 colormap.oldColor.Argb = 0xffffff00;
5511 colormap.newColor.Argb = 0xffff00ff;
5513 TRUE, 1, &colormap);
5514 expect(Ok, stat);
5515
5516 colormap.oldColor.Argb = 0xffffff80;
5517 colormap.newColor.Argb = 0xffff80ff;
5519 TRUE, 1, &colormap);
5520 expect(Ok, stat);
5521
5522 palette = GdipAlloc(sizeof(*palette) + sizeof(ARGB) * 2);
5523 palette->Count = 0;
5524
5527
5528 palette->Count = 3;
5529 palette->Entries[0] = 0xffffff00;
5530 palette->Entries[1] = 0xffffff80;
5531 palette->Entries[2] = 0xffffffff;
5532
5534 expect(Ok, stat);
5535 expect(0xffff00ff, palette->Entries[0]);
5536 expect(0xffffff80, palette->Entries[1]);
5537 expect(0xffffffff, palette->Entries[2]);
5538
5539 palette->Entries[0] = 0xffffff00;
5540 palette->Entries[1] = 0xffffff80;
5541 palette->Entries[2] = 0xffffffff;
5542
5544 expect(Ok, stat);
5545 expect(0xffffff00, palette->Entries[0]);
5546 expect(0xffff80ff, palette->Entries[1]);
5547 expect(0xffffffff, palette->Entries[2]);
5548
5551
5554
5555 stat = GdipGetImageAttributesAdjustedPalette(imageattributes, palette, -1);
5557
5560
5562 GdipDisposeImageAttributes(imageattributes);
5563}
5564
5565static void test_histogram(void)
5566{
5567 UINT ch0[256], ch1[256], ch2[256], ch3[256];
5569 {
5578 };
5579 const UINT WIDTH = 8, HEIGHT = 16;
5580 UINT num, i, x;
5581 GpStatus stat;
5582 GpBitmap *bm;
5583
5584 if (!pGdipBitmapGetHistogramSize)
5585 {
5586 win_skip("GdipBitmapGetHistogramSize is not supported\n");
5587 return;
5588 }
5589
5590 stat = pGdipBitmapGetHistogramSize(HistogramFormatARGB, NULL);
5592
5593 stat = pGdipBitmapGetHistogramSize(0xff, NULL);
5595
5596 num = 123;
5597 stat = pGdipBitmapGetHistogramSize(10, &num);
5598 expect(Ok, stat);
5599 expect(256, num);
5600
5601 for (i = 0; i < ARRAY_SIZE(test_formats); i++)
5602 {
5603 num = 0;
5604 stat = pGdipBitmapGetHistogramSize(test_formats[i], &num);
5605 expect(Ok, stat);
5606 expect(256, num);
5607 }
5608
5609 bm = NULL;
5611 expect(Ok, stat);
5612
5613 /* Three solid rgb rows, next three rows are rgb shades. */
5614 for (x = 0; x < WIDTH; x++)
5615 {
5616 GdipBitmapSetPixel(bm, x, 0, 0xffff0000);
5617 GdipBitmapSetPixel(bm, x, 1, 0xff00ff00);
5618 GdipBitmapSetPixel(bm, x, 2, 0xff0000ff);
5619
5620 GdipBitmapSetPixel(bm, x, 3, 0xff010000);
5621 GdipBitmapSetPixel(bm, x, 4, 0xff003f00);
5622 GdipBitmapSetPixel(bm, x, 5, 0xff000020);
5623 }
5624
5625 stat = pGdipBitmapGetHistogram(NULL, HistogramFormatRGB, 256, ch0, ch1, ch2, ch3);
5627
5628 stat = pGdipBitmapGetHistogram(bm, 123, 256, ch0, ch1, ch2, ch3);
5630
5631 stat = pGdipBitmapGetHistogram(bm, 123, 256, ch0, ch1, ch2, NULL);
5633
5634 stat = pGdipBitmapGetHistogram(bm, 123, 256, ch0, ch1, NULL, NULL);
5636
5637 stat = pGdipBitmapGetHistogram(bm, 123, 256, ch0, NULL, NULL, NULL);
5639
5640 /* Requested format matches bitmap format */
5641 stat = pGdipBitmapGetHistogram(bm, HistogramFormatRGB, 256, ch0, ch1, ch2, ch3);
5643
5644 stat = pGdipBitmapGetHistogram(bm, HistogramFormatRGB, 100, ch0, ch1, ch2, NULL);
5646
5647 stat = pGdipBitmapGetHistogram(bm, HistogramFormatRGB, 257, ch0, ch1, ch2, NULL);
5649
5650 /* Channel 3 is not used, must be NULL */
5651 stat = pGdipBitmapGetHistogram(bm, HistogramFormatRGB, 256, ch0, ch1, ch2, NULL);
5652 expect(Ok, stat);
5653
5654 ok(ch0[0xff] == WIDTH, "Got red (0xff) %u\n", ch0[0xff]);
5655 ok(ch1[0xff] == WIDTH, "Got green (0xff) %u\n", ch1[0xff]);
5656 ok(ch2[0xff] == WIDTH, "Got blue (0xff) %u\n", ch1[0xff]);
5657 ok(ch0[0x01] == WIDTH, "Got red (0x01) %u\n", ch0[0x01]);
5658 ok(ch1[0x3f] == WIDTH, "Got green (0x3f) %u\n", ch1[0x3f]);
5659 ok(ch2[0x20] == WIDTH, "Got blue (0x20) %u\n", ch1[0x20]);
5660
5661 /* ARGB histogram from RGB data. */
5662 stat = pGdipBitmapGetHistogram(bm, HistogramFormatARGB, 256, ch0, ch1, ch2, NULL);
5664
5665 stat = pGdipBitmapGetHistogram(bm, HistogramFormatARGB, 256, ch0, ch1, ch2, ch3);
5666 expect(Ok, stat);
5667
5668 ok(ch1[0xff] == WIDTH, "Got red (0xff) %u\n", ch1[0xff]);
5669 ok(ch2[0xff] == WIDTH, "Got green (0xff) %u\n", ch2[0xff]);
5670 ok(ch3[0xff] == WIDTH, "Got blue (0xff) %u\n", ch3[0xff]);
5671 ok(ch1[0x01] == WIDTH, "Got red (0x01) %u\n", ch1[0x01]);
5672 ok(ch2[0x3f] == WIDTH, "Got green (0x3f) %u\n", ch2[0x3f]);
5673 ok(ch3[0x20] == WIDTH, "Got blue (0x20) %u\n", ch3[0x20]);
5674
5675 ok(ch0[0xff] == WIDTH * HEIGHT, "Got alpha (0xff) %u\n", ch0[0xff]);
5676
5677 /* Request grayscale histogram from RGB bitmap. */
5678 stat = pGdipBitmapGetHistogram(bm, HistogramFormatGray, 256, ch0, ch1, ch2, ch3);
5680
5681 stat = pGdipBitmapGetHistogram(bm, HistogramFormatGray, 256, ch0, ch1, ch2, NULL);
5683
5684 stat = pGdipBitmapGetHistogram(bm, HistogramFormatGray, 256, ch0, ch1, NULL, NULL);
5686
5687 stat = pGdipBitmapGetHistogram(bm, HistogramFormatGray, 256, ch0, NULL, NULL, NULL);
5688 expect(Ok, stat);
5689
5691}
5692
5693static void test_imageabort(void)
5694{
5695 GpStatus stat;
5696 GpBitmap *bm;
5697
5698 if (!pGdipImageSetAbort)
5699 {
5700 win_skip("GdipImageSetAbort() is not supported.\n");
5701 return;
5702 }
5703
5704 bm = NULL;
5706 expect(Ok, stat);
5707
5708 stat = pGdipImageSetAbort(NULL, NULL);
5710
5711 stat = pGdipImageSetAbort((GpImage*)bm, NULL);
5712 expect(Ok, stat);
5713
5715}
5716
5717/* RGB 24 bpp 1x1 pixel PNG image */
5718static const char png_1x1_data[] = {
5719 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
5720 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,
5721 0x00,0x00,0x03,0x00,'P','L','T','E',
5722 0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,
5723 0x09,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x0e,0x0e,0x0e,0x0f,0x0f,0x0f,0x10,0x10,0x10,
5724 0x11,0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x13,0x14,0x14,0x14,0x15,0x15,0x15,0x16,0x16,0x16,0x17,0x17,0x17,0x18,0x18,0x18,
5725 0x19,0x19,0x19,0x1a,0x1a,0x1a,0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1f,0x1f,0x1f,0x20,0x20,0x20,
5726 0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25,0x26,0x26,0x26,0x27,0x27,0x27,0x28,0x28,0x28,
5727 0x29,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x30,
5728 0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38,
5729 0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40,
5730 0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43,0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x46,0x47,0x47,0x47,0x48,0x48,0x48,
5731 0x49,0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b,0x4c,0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,0x50,
5732 0x51,0x51,0x51,0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57,0x57,0x58,0x58,0x58,
5733 0x59,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5e,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x60,
5734 0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x63,0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x68,
5735 0x69,0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,0x6b,0x6c,0x6c,0x6c,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x6f,0x70,0x70,0x70,
5736 0x71,0x71,0x71,0x72,0x72,0x72,0x73,0x73,0x73,0x74,0x74,0x74,0x75,0x75,0x75,0x76,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x78,
5737 0x79,0x79,0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,
5738 0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,
5739 0x09,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0b,0x0c,0x0c,0x0c,0x0d,0x0d,0x0d,0x0e,0x0e,0x0e,0x0f,0x0f,0x0f,0x10,0x10,0x10,
5740 0x11,0x11,0x11,0x12,0x12,0x12,0x13,0x13,0x13,0x14,0x14,0x14,0x15,0x15,0x15,0x16,0x16,0x16,0x17,0x17,0x17,0x18,0x18,0x18,
5741 0x19,0x19,0x19,0x1a,0x1a,0x1a,0x1b,0x1b,0x1b,0x1c,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,0x1e,0x1f,0x1f,0x1f,0x20,0x20,0x20,
5742 0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x23,0x24,0x24,0x24,0x25,0x25,0x25,0x26,0x26,0x26,0x27,0x27,0x27,0x28,0x28,0x28,
5743 0x29,0x29,0x29,0x2a,0x2a,0x2a,0x2b,0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2e,0x2f,0x2f,0x2f,0x30,0x30,0x30,
5744 0x31,0x31,0x31,0x32,0x32,0x32,0x33,0x33,0x33,0x34,0x34,0x34,0x35,0x35,0x35,0x36,0x36,0x36,0x37,0x37,0x37,0x38,0x38,0x38,
5745 0x39,0x39,0x39,0x3a,0x3a,0x3a,0x3b,0x3b,0x3b,0x3c,0x3c,0x3c,0x3d,0x3d,0x3d,0x3e,0x3e,0x3e,0x3f,0x3f,0x3f,0x40,0x40,0x40,
5746 0x41,0x41,0x41,0x42,0x42,0x42,0x43,0x43,0x43,0x44,0x44,0x44,0x45,0x45,0x45,0x46,0x46,0x46,0x47,0x47,0x47,0x48,0x48,0x48,
5747 0x49,0x49,0x49,0x4a,0x4a,0x4a,0x4b,0x4b,0x4b,0x4c,0x4c,0x4c,0x4d,0x4d,0x4d,0x4e,0x4e,0x4e,0x4f,0x4f,0x4f,0x50,0x50,0x50,
5748 0x51,0x51,0x51,0x52,0x52,0x52,0x53,0x53,0x53,0x54,0x54,0x54,0x55,0x55,0x55,0x56,0x56,0x56,0x57,0x57,0x57,0x58,0x58,0x58,
5749 0x59,0x59,0x59,0x5a,0x5a,0x5a,0x5b,0x5b,0x5b,0x5c,0x5c,0x5c,0x5d,0x5d,0x5d,0x5e,0x5e,0x5e,0x5f,0x5f,0x5f,0x60,0x60,0x60,
5750 0x61,0x61,0x61,0x62,0x62,0x62,0x63,0x63,0x63,0x64,0x64,0x64,0x65,0x65,0x65,0x66,0x66,0x66,0x67,0x67,0x67,0x68,0x68,0x68,
5751 0x69,0x69,0x69,0x6a,0x6a,0x6a,0x6b,0x6b,0x6b,0x6c,0x6c,0x6c,0x6d,0x6d,0x6d,0x6e,0x6e,0x6e,0x6f,0x6f,0x6f,0x70,0x70,0x70,
5752 0x71,0x71,0x71,0x72,0x72,0x72,0x73,0x73,0x73,0x74,0x74,0x74,0x75,0x75,0x75,0x76,0x76,0x76,0x77,0x77,0x77,0x78,0x78,0x78,
5753 0x79,0x79,0x79,0x7a,0x7a,0x7a,0x7b,0x7b,0x7b,0x7c,0x7c,0x7c,0x7d,0x7d,0x7d,0x7e,0x7e,0x7e,0x7f,0x7f,0x7f,0x80,0x80,0x80,
5754 0x76,0xb6,0x24,0x31,
5755 0x00,0x00,0x00,0x02,'t','R','N','S',0xff,0x00,0xe5,0xb7,0x30,0x4a,
5756 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
5757 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
5758};
5759
5760#define PNG_COLOR_TYPE_GRAY 0
5761#define PNG_COLOR_TYPE_RGB 2
5762#define PNG_COLOR_TYPE_PALETTE 3
5763#define PNG_COLOR_TYPE_GRAY_ALPHA 4
5764#define PNG_COLOR_TYPE_RGB_ALPHA 6
5765
5766static void test_png_color_formats(void)
5767{
5768 static const struct
5769 {
5770 char bit_depth, color_type;
5771 struct {
5774 BOOL todo;
5775 BOOL todo_load;
5776 } t[3];
5777 } td[] =
5778 {
5779 /* 0 */
5780 { 1, PNG_COLOR_TYPE_RGB },
5781 { 2, PNG_COLOR_TYPE_RGB },
5782 { 4, PNG_COLOR_TYPE_RGB },
5783 { 8, PNG_COLOR_TYPE_RGB,
5787 /* libpng refuses to load our test image complaining about extra compressed data,
5788 * but libpng is still able to load the image with other combination of type/depth
5789 * making RGB 16 bpp case special for some reason. Therefore todo = TRUE.
5790 */
5791 { 16, PNG_COLOR_TYPE_RGB,
5795
5796 /* 5 */
5813 { 16, PNG_COLOR_TYPE_GRAY,
5817
5818 /* 10 */
5822 { 0, 0 }}},
5826 { 0, 0 }}},
5830 { 0, 0 }}},
5834 { 0, 0 }}},
5835 { 16, PNG_COLOR_TYPE_PALETTE },
5836 };
5837 BYTE buf[sizeof(png_1x1_data)];
5839 GpImage *image;
5842 UINT flags;
5843 BOOL valid;
5844 int i, j, PLTE_off = 0, tRNS_off = 0;
5846
5848 buf[24] = 2;
5850 image = load_image(buf, sizeof(buf), TRUE, FALSE);
5852 expect(status, Ok);
5853 ok((flags & color_space_mask) == ImageFlagsColorSpaceRGB || broken(flags == 0x12006) /* before win7 */,
5854 "flags = %#x\n", flags);
5855 if ((flags & color_space_mask) != ImageFlagsColorSpaceRGB) {
5857 win_skip("broken PNG color space support\n");
5858 return;
5859 }
5861
5862 for (i = 0; i < sizeof(png_1x1_data) - 4; i++)
5863 {
5864 if (!memcmp(buf + i, "tRNS", 4))
5865 tRNS_off = i;
5866 else if (!memcmp(buf + i, "PLTE", 4))
5867 PLTE_off = i;
5868 }
5869
5870 ok(PLTE_off && tRNS_off, "PLTE offset %d, tRNS offset %d\n", PLTE_off, tRNS_off);
5871 if (!PLTE_off || !tRNS_off) return;
5872
5873 /* In order to test the image data with and without PLTE and tRNS
5874 * chunks, we mask the chunk name with private one (tEST).
5875 */
5876
5877 for (i = 0; i < ARRAY_SIZE(td); i++)
5878 {
5879 for (j = 0; j < 3; j++)
5880 {
5882 buf[24] = td[i].bit_depth;
5883 buf[25] = td[i].color_type;
5884 if (j >=1) memcpy(buf + tRNS_off, "tEST", 4);
5885 if (j >=2) memcpy(buf + PLTE_off, "tEST", 4);
5886
5887 valid = (td[i].t[j].format != 0) || (td[i].t[j].flags != 0);
5888 image = load_image(buf, sizeof(buf), valid, td[i].t[j].todo_load);
5889 todo_wine_if(td[i].t[j].todo_load)
5890 if (valid)
5891 ok(image != NULL, "%d %d: failed to load image data\n", i, j);
5892 else
5893 {
5894 ok(image == NULL, "%d %d: succeed to load image data\n", i, j);
5896 image = NULL;
5897 }
5898 if (!image) continue;
5899
5901 ok(status == Ok, "%d %d: GdipGetImageType error %d\n", i, j, status);
5902 ok(type == ImageTypeBitmap, "%d %d: wrong image type %d\n", i, j, type);
5903
5905 expect(Ok, status);
5906 todo_wine_if(td[i].t[j].todo)
5907 ok(format == td[i].t[j].format,
5908 "%d %d: expected %#x, got %#x\n", i, j, td[i].t[j].format, format);
5909
5911 expect(Ok, status);
5912 ok((flags & color_space_mask) == td[i].t[j].flags,
5913 "%d %d: expected %#x, got %#x\n", i, j, td[i].t[j].flags, flags);
5915 }
5916 }
5917}
5918#undef PNG_COLOR_TYPE_GRAY
5919#undef PNG_COLOR_TYPE_RGB
5920#undef PNG_COLOR_TYPE_PALETTE
5921#undef PNG_COLOR_TYPE_GRAY_ALPHA
5922#undef PNG_COLOR_TYPE_RGB_ALPHA
5923
5924static void test_png_save_palette(void)
5925{
5928 HGLOBAL hglob;
5929 BOOL result;
5930 IStream *stream;
5931 GUID enc_format, clsid;
5934 UINT i, ptr;
5935 BYTE *data;
5936
5937 PixelFormat formats[] = {
5949 };
5950
5951 result = get_encoder_clsid(L"image/png", &enc_format, &clsid);
5952 ok(result, "getting PNG encoding clsid failed");
5953
5955
5956 for (i = 0; i < ARRAY_SIZE(formats); i++)
5957 {
5959 ok(status == Ok, "Unexpected return value %d creating bitmap for PixelFormat %#x\n", status, formats[i]);
5960
5964
5967 (status == GenericError || status == Win32Error) : status == Ok,
5968 "Unexpected return value %d saving image for PixelFormat %#x\n", status, formats[i]);
5969
5970 if (status == Ok)
5971 {
5972 data = GlobalLock(hglob);
5973 seek.QuadPart = 0;
5974 IStream_Seek(stream, seek, STREAM_SEEK_CUR, &pos);
5975 for (ptr = 0; ptr < pos.QuadPart - 4; ptr++)
5976 if (!memcmp(data + ptr, "PLTE", 4))
5977 break;
5978 memset(data, 0, 1024);
5979 GlobalUnlock(hglob);
5980
5982 ok(ptr < pos.QuadPart - 4, "Expected palette not found for PixelFormat %#x\n", formats[i]);
5983 else
5984 ok(ptr >= pos.QuadPart - 4, "Unexpected palette found for PixelFormat %#x\n", formats[i]);
5985 }
5986
5987 IStream_Release(stream);
5988 }
5989
5990 GlobalFree(hglob);
5991}
5992
5993static const BYTE png_minimal[] = {
5994 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
5995 0x00,0x00,0x00,0x0d,'I','H','D','R',0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
5996 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
5997 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
5998};
5999
6000static const BYTE png_phys[] = {
6001 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
6002 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,
6003 0x00,0x00,0x00,0x09,'p','H','Y','s',0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
6004 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
6005 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
6006};
6007
6008static const BYTE png_time[] = {
6009 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
6010 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,
6011 0x00,0x00,0x00,0x07,'t','I','M','E',0x07,0xb2,0x01,0x01,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
6012 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
6013 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
6014};
6015
6016static const BYTE png_hist[] = {
6017 0x89,'P','N','G',0x0d,0x0a,0x1a,0x0a,
6018 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,
6019 0x00,0x00,0x00,0x08,'h','I','S','T',0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0xff,0xff,0xff,0xff,
6020 0x00,0x00,0x00,0x0c,'I','D','A','T',0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,0xe7,
6021 0x00,0x00,0x00,0x00,'I','E','N','D',0xae,0x42,0x60,0x82
6022};
6023
6025{
6026 GpImage *image;
6027 UINT pHYs_off = 0, i;
6028 static const struct {
6029 BYTE unit;
6030 ULONG unitX;
6031 ULONG unitY;
6032 } td[] =
6033 {
6034 {0, 0, 0},
6035 {1, 0, 0},
6036 {0, 1000, 1000},
6037 {1, 1000, 1000},
6038 {1, 3780, 3780},
6039 };
6040 struct property_test_data prop_td[][3] =
6041 {
6043 { PropertyTagTypeLong, PropertyTagPixelPerUnitX, 4, { 0,0,0,0 } },
6044 { PropertyTagTypeLong, PropertyTagPixelPerUnitY, 4, { 0,0,0,0 } }},
6046 { PropertyTagTypeLong, PropertyTagPixelPerUnitX, 4, { 0,0,0,0 } },
6047 { PropertyTagTypeLong, PropertyTagPixelPerUnitY, 4, { 0,0,0,0 } }},
6052 { PropertyTagTypeLong, PropertyTagPixelPerUnitX, 4, { 0xe8,0x03,0,0 } },
6053 { PropertyTagTypeLong, PropertyTagPixelPerUnitY, 4, { 0xe8,0x03,0,0 } }},
6055 { PropertyTagTypeLong, PropertyTagPixelPerUnitX, 4, { 0xc4,0x0e,0,0 } },
6056 { PropertyTagTypeLong, PropertyTagPixelPerUnitY, 4, { 0xc4,0x0e,0,0 } }},
6057 };
6058 BYTE buf[sizeof(png_phys)];
6059
6060
6061 for (i = 0; i < sizeof(png_phys) - 4; i++)
6062 {
6063 if (!memcmp(png_phys + i, "pHYs", 4))
6064 pHYs_off = i;
6065 }
6066
6067 ok(pHYs_off, "pHYs offset %d\n", pHYs_off);
6068 if (!pHYs_off)
6069 return;
6070
6071 for (i = 0; i < ARRAY_SIZE(td); i++)
6072 {
6073 if (i == 0)
6075 else
6076 {
6077 memcpy(buf, png_phys, sizeof(png_phys));
6078 buf[pHYs_off + 4] = (td[i].unitX >> 24) & 0xff;
6079 buf[pHYs_off + 5] = (td[i].unitX >> 16) & 0xff;
6080 buf[pHYs_off + 6] = (td[i].unitX >> 8) & 0xff;
6081 buf[pHYs_off + 7] = td[i].unitX & 0xff;
6082 buf[pHYs_off + 8] = (td[i].unitY >> 24) & 0xff;
6083 buf[pHYs_off + 9] = (td[i].unitY >> 16) & 0xff;
6084 buf[pHYs_off + 10] = (td[i].unitY >> 8) & 0xff;
6085 buf[pHYs_off + 11] = td[i].unitY & 0xff;
6086 buf[pHYs_off + 12] = td[i].unit;
6087 image = load_image(buf, sizeof(buf), TRUE, FALSE);
6088 }
6089
6090 ok(image != NULL, "%u: Failed to load PNG image data\n", i);
6091 if (!image)
6092 continue;
6093
6094 winetest_push_context("%s test %u", __FUNCTION__, i);
6095 check_properties_get_all(image, prop_td[i], 3, NULL, 0, ~0);
6097
6099 }
6100}
6101
6103{
6104 struct property_test_data td[] =
6105 {
6106 { PropertyTagTypeASCII, PropertyTagDateTime, 20, { "1970:01:01 00:00:00" } },
6108 { PropertyTagTypeLong, PropertyTagPixelPerUnitX, 4, { 0,0,0,0 } },
6109 { PropertyTagTypeLong, PropertyTagPixelPerUnitY, 4, { 0,0,0,0 } },
6110 };
6111
6113 ok(image != NULL, "Failed to load PNG image data\n");
6114 if (!image)
6115 return;
6116
6118 check_properties_get_all(image, td, ARRAY_SIZE(td), td, 1, ~0);
6120
6122}
6123
6125{
6126 struct property_test_data td[] =
6127 {
6128 { PropertyTagTypeShort, PropertyTagPaletteHistogram, 8, { 1,0,2,0,3,0,4,0 } },
6130 { PropertyTagTypeLong, PropertyTagPixelPerUnitX, 4, { 0,0,0,0 } },
6131 { PropertyTagTypeLong, PropertyTagPixelPerUnitY, 4, { 0,0,0,0 } },
6132 };
6133
6135 if (!image)
6136 {
6137 win_skip("broken PNG histogram support\n");
6138 return;
6139 }
6140
6144
6146}
6147
6149{
6150 IStream *stream;
6152 GpImage *image;
6153 HGLOBAL hglob;
6154 BYTE *data;
6155 HRESULT hr;
6156
6158 ok(status == InvalidParameter, "Unexpected return value %d.\n", status);
6159
6160 image = (void *)0xdeadbeef;
6162 ok(status == InvalidParameter, "Unexpected return value %d.\n", status);
6163 ok(image == (void *)0xdeadbeef, "Unexpected image pointer.\n");
6164
6165 hglob = GlobalAlloc(0, sizeof(pngimage));
6166 data = GlobalLock (hglob);
6167 memcpy(data, pngimage, sizeof(pngimage));
6168 GlobalUnlock(hglob);
6169
6170 hr = CreateStreamOnHGlobal(hglob, TRUE, &stream);
6171 ok(hr == S_OK, "Failed to create a stream.\n");
6172
6174 ok(status == InvalidParameter, "Unexpected return value %d.\n", status);
6175
6176 IStream_Release(stream);
6177}
6178
6180{
6181 BYTE *src;
6182 UINT i, j, scale;
6183
6184 *width = 256;
6185 *height = 256;
6186 *stride = (*width * 3 + 3) & ~3;
6187 trace("width %d, height %d, stride %d\n", *width, *height, *stride);
6188
6189 src = malloc(*stride * *height);
6190
6191 scale = 256 / *width;
6192 if (!scale) scale = 1;
6193
6194 for (i = 0; i < *height; i++)
6195 {
6196 for (j = 0; j < *width; j++)
6197 {
6198 src[i * *stride + j*3 + 0] = scale * i;
6199 src[i * *stride + j*3 + 1] = scale * (255 - (i+j)/2);
6200 src[i * *stride + j*3 + 2] = scale * j;
6201 }
6202 }
6203
6204 return src;
6205}
6206
6208{
6210 BYTE *data;
6214
6215 pGdipInitializePalette = (void *)GetProcAddress(GetModuleHandleA("gdiplus.dll"), "GdipInitializePalette");
6216 if (!pGdipInitializePalette)
6217 {
6218 win_skip("GdipInitializePalette is not supported on this platform\n");
6219 return;
6220 }
6221
6223
6225 expect(Ok, status);
6226
6227 palette = GdipAlloc(sizeof(*palette) + sizeof(ARGB) * 255);
6228
6229 palette->Flags = 0;
6230 palette->Count = 15;
6231 status = pGdipInitializePalette(palette, PaletteTypeOptimal, 16, FALSE, bitmap);
6233
6234 palette->Flags = 0;
6235 palette->Count = 256;
6236 status = pGdipInitializePalette(palette, PaletteTypeOptimal, 16, FALSE, NULL);
6238
6239 memset(palette->Entries, 0x11, sizeof(ARGB) * 256);
6240 palette->Flags = 0;
6241 palette->Count = 256;
6242 status = pGdipInitializePalette(palette, PaletteTypeCustom, 16, FALSE, NULL);
6243 expect(Ok, status);
6244 expect(0, palette->Flags);
6245 expect(256, palette->Count);
6246 expect(0x11111111, palette->Entries[0]);
6247 expect(0x11111111, palette->Entries[128]);
6248 expect(0x11111111, palette->Entries[255]);
6249
6250 memset(palette->Entries, 0x11, sizeof(ARGB) * 256);
6251 palette->Flags = 0;
6252 palette->Count = 256;
6253 status = pGdipInitializePalette(palette, PaletteTypeFixedBW, 0, FALSE, bitmap);
6254 expect(Ok, status);
6255 todo_wine
6256 expect(0x200, palette->Flags);
6257 expect(2, palette->Count);
6258 expect(0xff000000, palette->Entries[0]);
6259 expect(0xffffffff, palette->Entries[1]);
6260
6261 memset(palette->Entries, 0x11, sizeof(ARGB) * 256);
6262 palette->Flags = 0;
6263 palette->Count = 256;
6264 status = pGdipInitializePalette(palette, PaletteTypeFixedHalftone8, 1, FALSE, NULL);
6265 expect(Ok, status);
6266 todo_wine
6267 expect(0x300, palette->Flags);
6268 expect(16, palette->Count);
6269 expect(0xff000000, palette->Entries[0]);
6270 expect(0xffc0c0c0, palette->Entries[8]);
6271 expect(0xff008080, palette->Entries[15]);
6272
6273 memset(palette->Entries, 0x11, sizeof(ARGB) * 256);
6274 palette->Flags = 0;
6275 palette->Count = 256;
6276 status = pGdipInitializePalette(palette, PaletteTypeFixedHalftone8, 1, FALSE, bitmap);
6277 expect(Ok, status);
6278 todo_wine
6279 expect(0x300, palette->Flags);
6280 expect(16, palette->Count);
6281 expect(0xff000000, palette->Entries[0]);
6282 expect(0xffc0c0c0, palette->Entries[8]);
6283 expect(0xff008080, palette->Entries[15]);
6284
6285 memset(palette->Entries, 0x11, sizeof(ARGB) * 256);
6286 palette->Flags = 0;
6287 palette->Count = 256;
6288 status = pGdipInitializePalette(palette, PaletteTypeFixedHalftone252, 1, FALSE, bitmap);
6289 expect(Ok, status);
6290 todo_wine
6291 expect(0x800, palette->Flags);
6292 expect(252, palette->Count);
6293 expect(0xff000000, palette->Entries[0]);
6294 expect(0xff990066, palette->Entries[128]);
6295 expect(0xffffffff, palette->Entries[251]);
6296
6297 palette->Flags = 0;
6298 palette->Count = 256;
6299 status = pGdipInitializePalette(palette, PaletteTypeOptimal, 1, FALSE, bitmap);
6301
6302 palette->Flags = 0;
6303 palette->Count = 256;
6304 status = pGdipInitializePalette(palette, PaletteTypeOptimal, 2, FALSE, bitmap);
6305 expect(Ok, status);
6306 expect(0, palette->Flags);
6307 expect(2, palette->Count);
6308
6309 palette->Flags = 0;
6310 palette->Count = 256;
6311 status = pGdipInitializePalette(palette, PaletteTypeOptimal, 16, FALSE, bitmap);
6312 expect(Ok, status);
6313 expect(0, palette->Flags);
6314 expect(16, palette->Count);
6315
6316 /* passing invalid enumeration palette type crashes under most Windows versions */
6317
6320 free(data);
6321}
6322
6323static void test_graphics_clear(void)
6324{
6325 BYTE argb[8] = { 0x11,0x22,0x33,0x80, 0xff,0xff,0xff,0 };
6326 BYTE cleared[8] = { 0,0,0,0, 0,0,0,0 };
6327 BYTE *bits;
6329 GpGraphics *graphics;
6332 int match;
6333
6335 expect(Ok, status);
6336
6338 expect(Ok, status);
6339
6340 status = GdipGraphicsClear(graphics, 0x00000000);
6341 expect(Ok, status);
6342
6344 expect(Ok, status);
6345 ok(data.Width == 2, "expected 2, got %d\n", data.Width);
6346 ok(data.Height == 1, "expected 1, got %d\n", data.Height);
6347 ok(data.Stride == 8, "expected 8, got %d\n", data.Stride);
6348 ok(data.PixelFormat == PixelFormat32bppARGB, "expected PixelFormat32bppARGB, got %d\n", data.PixelFormat);
6349 match = !memcmp(data.Scan0, cleared, sizeof(cleared));
6350 ok(match, "bits don't match\n");
6351 if (!match)
6352 {
6353 bits = data.Scan0;
6354 trace("format %#x, bits %02x,%02x,%02x,%02x %02x,%02x,%02x,%02x\n", PixelFormat32bppARGB,
6355 bits[0], bits[1], bits[2], bits[3], bits[4], bits[5], bits[6], bits[7]);
6356 }
6358 expect(Ok, status);
6359
6360 status = GdipDeleteGraphics(graphics);
6361 expect(Ok, status);
6363}
6364
6366{
6367 HMODULE mod = GetModuleHandleA("gdiplus.dll");
6368 struct GdiplusStartupInput gdiplusStartupInput;
6369 ULONG_PTR gdiplusToken;
6370 HMODULE hmsvcrt;
6371 int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask);
6372
6373 /* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
6374 hmsvcrt = LoadLibraryA("msvcrt");
6375 _controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s");
6376 if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e);
6377
6378 gdiplusStartupInput.GdiplusVersion = 1;
6379 gdiplusStartupInput.DebugEventCallback = NULL;
6380 gdiplusStartupInput.SuppressBackgroundThread = 0;
6381 gdiplusStartupInput.SuppressExternalCodecs = 0;
6382
6383 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
6384
6385 pGdipBitmapGetHistogramSize = (void*)GetProcAddress(mod, "GdipBitmapGetHistogramSize");
6386 pGdipBitmapGetHistogram = (void*)GetProcAddress(mod, "GdipBitmapGetHistogram");
6387 pGdipImageSetAbort = (void*)GetProcAddress(mod, "GdipImageSetAbort");
6388
6410 test_Scan0();
6417 test_encoders();
6418 test_LockBits();
6426 test_loadwmf();
6433 test_palette();
6435 test_gamma();
6439 test_colorkey();
6440 test_dispose();
6447
6448 GdiplusShutdown(gdiplusToken);
6449}
std::map< E_MODULE, HMODULE > mod
Definition: LocaleTests.cpp:68
static HBITMAP hbitmap
#define stat
Definition: acwin.h:100
#define GetNTVersion()
Definition: apitest.h:17
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define ARRAY_SIZE(A)
Definition: main.h:20
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
unsigned int ULONG32
Definition: basetsd.h:117
DWORD GetPixel(LPDIRECTDRAWSURFACE7 Surface, UINT x, UINT y)
Definition: blt.cpp:2
Definition: _map.h:48
RECT rect
Definition: combotst.c:67
#define WIDTH
Definition: d3dtest.c:13
#define HEIGHT
Definition: d3dtest.c:14
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
DWORD bpp
Definition: surface.c:185
static const struct pixel_format_desc formats[]
Definition: util.c:59
static unsigned int palette_size(DWORD flags)
Definition: palette.c:241
float REAL
Definition: types.h:41
INT WINAPI StringFromGUID2(REFGUID guid, LPOLESTR str, INT cmax)
Definition: combase.c:1525
HRESULT WINAPI CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL delete_on_release, IStream **stream)
#define CDECL
Definition: compat.h:29
#define CP_ACP
Definition: compat.h:109
#define GetProcAddress(x, y)
Definition: compat.h:753
#define WideCharToMultiByte
Definition: compat.h:111
GpStatus WINGDIPAPI GdipGetDpiX(GpGraphics *graphics, REAL *dpi)
Definition: graphics.c:6988
GpStatus WINGDIPAPI GdipDrawImageI(GpGraphics *graphics, GpImage *image, INT x, INT y)
Definition: graphics.c:3087
GpStatus WINGDIPAPI GdipGetDpiY(GpGraphics *graphics, REAL *dpi)
Definition: graphics.c:7002
GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
Definition: graphics.c:2616
GpStatus WINGDIPAPI GdipSetCompositingMode(GpGraphics *graphics, CompositingMode mode)
Definition: graphics.c:6440
GpStatus WINGDIPAPI GdipGraphicsClear(GpGraphics *graphics, ARGB color)
Definition: graphics.c:5229
GpStatus WINGDIPAPI GdipSetWorldTransform(GpGraphics *graphics, GpMatrix *matrix)
Definition: graphics.c:6724
GpStatus WINGDIPAPI GdipDrawImageRectRectI(GpGraphics *graphics, GpImage *image, INT dstx, INT dsty, INT dstwidth, INT dstheight, INT srcx, INT srcy, INT srcwidth, INT srcheight, GpUnit srcUnit, GDIPCONST GpImageAttributes *imageAttributes, DrawImageAbort callback, VOID *callbackData)
Definition: graphics.c:3574
GpStatus WINGDIPAPI GdipSetInterpolationMode(GpGraphics *graphics, InterpolationMode mode)
Definition: graphics.c:6498
GpStatus WINGDIPAPI GdipDrawImagePointRectI(GpGraphics *graphics, GpImage *image, INT x, INT y, INT srcx, INT srcy, INT srcwidth, INT srcheight, GpUnit srcUnit)
Definition: graphics.c:3122
GpStatus WINGDIPAPI GdipSetPixelOffsetMode(GpGraphics *graphics, PixelOffsetMode mode)
Definition: graphics.c:6587
GpStatus WINGDIPAPI GdipCreateBitmapFromFile(GDIPCONST WCHAR *filename, GpBitmap **bitmap)
Definition: image.c:1437
GpStatus WINGDIPAPI GdipGetPropertySize(GpImage *image, UINT *size, UINT *count)
Definition: image.c:2670
GpStatus WINGDIPAPI GdipSaveAddImage(GpImage *image, GpImage *additional_image, GDIPCONST EncoderParameters *params)
Definition: image.c:4928
GpStatus WINGDIPAPI GdipGetImageVerticalResolution(GpImage *image, REAL *res)
Definition: image.c:2311
GpStatus WINGDIPAPI GdipGetImageRawFormat(GpImage *image, GUID *format)
Definition: image.c:2287
GpStatus WINGDIPAPI GdipGetImagePalette(GpImage *image, ColorPalette *palette, INT size)
Definition: image.c:4950
GpStatus WINGDIPAPI GdipGetImageEncodersSize(UINT *numEncoders, UINT *size)
Definition: image.c:5285
GpStatus WINGDIPAPI GdipGetImageFlags(GpImage *image, UINT *flags)
Definition: image.c:5672
GpStatus WINGDIPAPI GdipSaveImageToStream(GpImage *image, IStream *stream, GDIPCONST CLSID *clsid, GDIPCONST EncoderParameters *params)
Definition: image.c:4880
GpStatus WINGDIPAPI GdipCloneBitmapAreaI(INT x, INT y, INT width, INT height, PixelFormat format, GpBitmap *srcBitmap, GpBitmap **dstBitmap)
Definition: image.c:1377
GpStatus WINGDIPAPI GdipGetAllPropertyItems(GpImage *image, UINT size, UINT count, PropertyItem *buf)
Definition: image.c:2746
GpStatus WINGDIPAPI GdipGetImageWidth(GpImage *image, UINT *width)
Definition: image.c:2323
GpStatus WINGDIPAPI GdipGetImageHeight(GpImage *image, UINT *height)
Definition: image.c:2213
GpStatus WINGDIPAPI GdipGetImageDimension(GpImage *image, REAL *width, REAL *height)
Definition: image.c:2168
GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride, PixelFormat format, BYTE *scan0, GpBitmap **bitmap)
Definition: image.c:1793
#define PropertyTagTypeSShort
Definition: image.c:2520
GpStatus WINGDIPAPI GdipSetImagePalette(GpImage *image, GDIPCONST ColorPalette *palette)
Definition: image.c:4984
GpStatus WINGDIPAPI GdipImageGetFrameCount(GpImage *image, GDIPCONST GUID *dimensionID, UINT *count)
Definition: image.c:2855
static const WCHAR bmp_format[]
Definition: image.c:5015
#define PropertyTagTypeFloat
Definition: image.c:2521
GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage *image, GpGraphics **graphics)
Definition: image.c:2195
#define PropertyTagTypeDouble
Definition: image.c:2522
GpStatus WINGDIPAPI GdipSaveImageToFile(GpImage *image, GDIPCONST WCHAR *filename, GDIPCONST CLSID *clsidEncoder, GDIPCONST EncoderParameters *encoderParams)
Definition: image.c:4596
GpStatus WINGDIPAPI GdipImageGetFrameDimensionsCount(GpImage *image, UINT *count)
Definition: image.c:2875
GpStatus WINGDIPAPI GdipBitmapSetResolution(GpBitmap *bitmap, REAL xdpi, REAL ydpi)
Definition: image.c:1239
GpStatus WINGDIPAPI GdipCreateBitmapFromGdiDib(GDIPCONST BITMAPINFO *info, VOID *bits, GpBitmap **bitmap)
Definition: image.c:1462
GpStatus WINGDIPAPI GdipBitmapLockBits(GpBitmap *bitmap, GDIPCONST GpRect *rect, UINT flags, PixelFormat format, BitmapData *lockeddata)
Definition: image.c:1107
GpStatus WINGDIPAPI GdipGetPropertyCount(GpImage *image, UINT *num)
Definition: image.c:2346
GpStatus WINGDIPAPI GdipDisposeImage(GpImage *image)
Definition: image.c:2099
GpStatus WINGDIPAPI GdipGetImagePixelFormat(GpImage *image, PixelFormat *format)
Definition: image.c:2272
GpStatus WINGDIPAPI GdipLoadImageFromFile(GDIPCONST WCHAR *filename, GpImage **image)
Definition: image.c:2918
GpStatus WINGDIPAPI GdipGetImageThumbnail(GpImage *image, UINT width, UINT height, GpImage **ret_image, GetThumbnailImageAbort cb, VOID *cb_data)
Definition: image.c:5715
GpStatus WINGDIPAPI GdipBitmapGetPixel(GpBitmap *bitmap, INT x, INT y, ARGB *color)
Definition: image.c:310
GpStatus WINGDIPAPI GdipBitmapSetPixel(GpBitmap *bitmap, INT x, INT y, ARGB color)
Definition: image.c:521
#define PropertyTagTypeSByte
Definition: image.c:2519
GpStatus WINGDIPAPI GdipGetImagePaletteSize(GpImage *image, INT *size)
Definition: image.c:2248
GpStatus WINGDIPAPI GdipImageSelectActiveFrame(GpImage *image, GDIPCONST GUID *dimensionID, UINT frame)
Definition: image.c:4474
GpStatus WINGDIPAPI GdipGetPropertyIdList(GpImage *image, UINT num, PROPID *list)
Definition: image.c:2369
GpStatus WINGDIPAPI GdipGetImageType(GpImage *image, ImageType *type)
Definition: image.c:2299
GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream *stream, GpImage **image)
Definition: image.c:4525
GpStatus WINGDIPAPI GdipCreateBitmapFromStream(IStream *stream, GpBitmap **bitmap)
Definition: image.c:1895
GpStatus WINGDIPAPI GdipImageRotateFlip(GpImage *image, RotateFlipType type)
Definition: image.c:5764
GpStatus WINGDIPAPI GdipGetImageEncoders(UINT numEncoders, UINT size, ImageCodecInfo *encoders)
Definition: image.c:5309
GpStatus WINGDIPAPI GdipGetPropertyItem(GpImage *image, PROPID propid, UINT size, PropertyItem *buffer)
Definition: image.c:2617
GpStatus WINGDIPAPI GdipLoadImageFromFileICM(GDIPCONST WCHAR *filename, GpImage **image)
Definition: image.c:2944
GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap *bitmap, HBITMAP *hbmReturn, ARGB background)
Definition: image.c:1535
GpStatus WINGDIPAPI GdipTestControl(GpTestControlEnum control, void *param)
Definition: image.c:5684
GpStatus WINGDIPAPI GdipGetImageBounds(GpImage *image, GpRectF *srcRect, GpUnit *srcUnit)
Definition: image.c:2140
static const struct image_codec codecs[NUM_CODECS]
Definition: image.c:4407
GpStatus WINGDIPAPI GdipCreateBitmapFromHICON(HICON hicon, GpBitmap **bitmap)
Definition: image.c:1619
GpStatus WINGDIPAPI GdipGetImageHorizontalResolution(GpImage *image, REAL *res)
Definition: image.c:2236
GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage)
Definition: image.c:1385
GpStatus WINGDIPAPI GdipGetPropertyItemSize(GpImage *image, PROPID propid, UINT *size)
Definition: image.c:2471
GpStatus WINGDIPAPI GdipImageGetFrameDimensionsList(GpImage *image, GUID *dimensionIDs, UINT count)
Definition: image.c:2890
GpStatus WINGDIPAPI GdipBitmapUnlockBits(GpBitmap *bitmap, BitmapData *lockeddata)
Definition: image.c:1252
GpStatus WINGDIPAPI GdipCreateBitmapFromHBITMAP(HBITMAP hbm, HPALETTE hpal, GpBitmap **bitmap)
Definition: image.c:5392
GpStatus WINGDIPAPI GdipSaveAdd(GpImage *image, GDIPCONST EncoderParameters *params)
Definition: image.c:4913
GpStatus WINGDIPAPI GdipCreateMatrix2(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy, GpMatrix **matrix)
Definition: matrix.c:59
GpStatus WINGDIPAPI GdipDeleteMatrix(GpMatrix *matrix)
Definition: matrix.c:156
GpStatus WINGDIPAPI GdipCreateMetafileFromWmf(HMETAFILE hwmf, BOOL delete, GDIPCONST WmfPlaceableFileHeader *placeable, GpMetafile **metafile)
Definition: metafile.c:4290
GpStatus WINGDIPAPI GdipGetMetafileHeaderFromMetafile(GpMetafile *metafile, MetafileHeader *header)
Definition: metafile.c:4072
static void cleanup(void)
Definition: main.c:1335
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
INT WINAPI CompareStringA(LCID lcid, DWORD flags, LPCSTR str1, INT len1, LPCSTR str2, INT len2)
Definition: locale.c:4015
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4152
GUID guid
Definition: version.c:147
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP errno_t __cdecl _controlfp_s(unsigned int *, unsigned int, unsigned int)
Definition: math.c:1304
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
ULONG RGBQUAD
Definition: precomp.h:47
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
#define __FUNCTION__
Definition: types.h:116
static unsigned char buff[32768]
Definition: fatten.c:17
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOLEAN valid
pKey DeleteObject()
FxCollectionEntry * cur
void WINGDIPAPI GdipFree(void *ptr)
Definition: gdiplus.c:152
Status WINAPI GdiplusStartup(ULONG_PTR *token, const struct GdiplusStartupInput *input, struct GdiplusStartupOutput *output)
Definition: gdiplus.c:83
void *WINGDIPAPI GdipAlloc(SIZE_T size)
Definition: gdiplus.c:144
@ ColorAdjustTypeCount
@ ColorAdjustTypeAny
@ ColorAdjustTypeBrush
@ ColorAdjustTypeBitmap
@ ColorAdjustTypeDefault
@ ColorMatrixFlagsSkipGrays
@ ColorMatrixFlagsAltGray
@ ColorMatrixFlagsDefault
HistogramFormat
@ HistogramFormatRGB
@ HistogramFormatPARGB
@ HistogramFormatB
@ HistogramFormatA
@ HistogramFormatARGB
@ HistogramFormatR
@ HistogramFormatGray
@ HistogramFormatG
@ EncoderValueFlush
Definition: gdiplusenums.h:380
@ EncoderValueMultiFrame
Definition: gdiplusenums.h:378
@ EncoderValueFrameDimensionPage
Definition: gdiplusenums.h:383
@ CompositingModeSourceCopy
Definition: gdiplusenums.h:248
ImageType
Definition: gdiplusenums.h:192
@ ImageTypeBitmap
Definition: gdiplusenums.h:194
@ ImageTypeMetafile
Definition: gdiplusenums.h:195
ImageFlags
Definition: gdiplusenums.h:330
@ ImageFlagsColorSpaceCMYK
Definition: gdiplusenums.h:337
@ ImageFlagsNone
Definition: gdiplusenums.h:331
@ ImageFlagsHasAlpha
Definition: gdiplusenums.h:333
@ ImageFlagsColorSpaceYCBCR
Definition: gdiplusenums.h:339
@ ImageFlagsColorSpaceYCCK
Definition: gdiplusenums.h:340
@ ImageFlagsColorSpaceRGB
Definition: gdiplusenums.h:336
@ ImageFlagsColorSpaceGRAY
Definition: gdiplusenums.h:338
PixelOffsetMode
Definition: gdiplusenums.h:159
@ PixelOffsetModeHighSpeed
Definition: gdiplusenums.h:162
@ PixelOffsetModeHalf
Definition: gdiplusenums.h:165
@ PixelOffsetModeHighQuality
Definition: gdiplusenums.h:163
@ PixelOffsetModeNone
Definition: gdiplusenums.h:164
@ EncoderParameterValueTypeLong
Definition: gdiplusenums.h:351
@ TestControlGetBuildNumber
Definition: gdiplusenums.h:413
Unit
Definition: gdiplusenums.h:26
@ UnitPixel
Definition: gdiplusenums.h:29
@ MetafileTypeWmfPlaceable
Definition: gdiplusenums.h:216
InterpolationMode
Definition: gdiplusenums.h:140
@ InterpolationModeBilinear
Definition: gdiplusenums.h:145
@ InterpolationModeNearestNeighbor
Definition: gdiplusenums.h:147
#define WINGDIPAPI
Definition: gdiplusflat.h:22
Status GpStatus
#define PropertyTagIndexTransparent
#define PropertyTagFrameDelay
#define PropertyTagTypeShort
#define PropertyTagIndexBackground
ImageLockMode
@ ImageLockModeUserInputBuf
@ ImageLockModeRead
@ ImageLockModeWrite
#define PropertyTagTypeLong
#define PropertyTagGlobalPalette
#define PropertyTagTypeUndefined
#define PropertyTagPixelUnit
#define PropertyTagTypeSLONG
#define PropertyTagTypeRational
#define PropertyTagPaletteHistogram
#define PropertyTagTypeByte
#define PropertyTagPixelPerUnitX
#define PropertyTagDateTime
#define PropertyTagPixelPerUnitY
#define PropertyTagTypeSRational
@ RotateNoneFlipY
@ Rotate90FlipNone
@ RotateNoneFlipX
#define PropertyTagLoopCount
#define PropertyTagTypeASCII
#define PropertyTagExifUserComment
void WINAPI GdiplusShutdown(ULONG_PTR)
DWORD ARGB
#define PixelFormat32bppPARGB
#define PixelFormat64bppARGB
#define PixelFormat32bppRGB
static BOOL IsIndexedPixelFormat(PixelFormat format)
#define PixelFormat4bppIndexed
#define PixelFormat64bppPARGB
#define PixelFormat16bppRGB555
@ PaletteFlagsGrayScale
@ PaletteFlagsHalftone
@ PaletteFlagsHasAlpha
#define PixelFormat16bppARGB1555
@ PaletteTypeOptimal
@ PaletteTypeCustom
@ PaletteTypeFixedHalftone8
@ PaletteTypeFixedHalftone252
@ PaletteTypeFixedBW
#define PixelFormat16bppGrayScale
#define PixelFormat8bppIndexed
INT PixelFormat
#define PixelFormat32bppCMYK
#define PixelFormat24bppRGB
#define PixelFormat16bppRGB565
#define PixelFormat1bppIndexed
#define PixelFormat32bppARGB
#define PixelFormat48bppRGB
struct GdiplusAbort GdiplusAbort
Definition: gdiplustypes.h:57
Status
Definition: gdiplustypes.h:24
@ Ok
Definition: gdiplustypes.h:25
@ WrongState
Definition: gdiplustypes.h:33
@ ObjectBusy
Definition: gdiplustypes.h:29
@ InvalidParameter
Definition: gdiplustypes.h:27
@ OutOfMemory
Definition: gdiplustypes.h:28
@ PropertyNotFound
Definition: gdiplustypes.h:44
@ Win32Error
Definition: gdiplustypes.h:32
@ NotImplemented
Definition: gdiplustypes.h:31
@ GenericError
Definition: gdiplustypes.h:26
GLint GLvoid * img
Definition: gl.h:1956
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl.h:1546
GLeglImageOES image
Definition: gl.h:2204
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLdouble GLdouble t
Definition: gl.h:2047
GLint GLint GLsizei width
Definition: gl.h:1546
GLdouble n
Definition: glext.h:7729
GLsizei stride
Definition: glext.h:5848
GLuint res
Definition: glext.h:9613
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
GLenum src
Definition: glext.h:6340
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
GLuint color
Definition: glext.h:6243
GLenum GLint GLuint mask
Definition: glext.h:6028
GLuint GLenum matrix
Definition: glext.h:9407
GLenum mode
Definition: glext.h:6217
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLuint GLfloat * val
Definition: glext.h:7180
GLdouble GLdouble u2
Definition: glext.h:8308
GLuint64EXT * result
Definition: glext.h:11304
GLenum GLint GLint * precision
Definition: glext.h:7539
GLuint GLuint num
Definition: glext.h:9618
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLdouble u1
Definition: glext.h:8308
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
#define FLOAT
Definition: i386-dis.c:525
GpStatus WINGDIPAPI GdipGetImageAttributesAdjustedPalette(GpImageAttributes *imageattr, ColorPalette *palette, ColorAdjustType type)
GpStatus WINGDIPAPI GdipSetImageAttributesColorMatrix(GpImageAttributes *imageattr, ColorAdjustType type, BOOL enableFlag, GDIPCONST ColorMatrix *colorMatrix, GDIPCONST ColorMatrix *grayMatrix, ColorMatrixFlags flags)
GpStatus WINGDIPAPI GdipSetImageAttributesGamma(GpImageAttributes *imageAttr, ColorAdjustType type, BOOL enableFlag, REAL gamma)
GpStatus WINGDIPAPI GdipCreateImageAttributes(GpImageAttributes **imageattr)
GpStatus WINGDIPAPI GdipSetImageAttributesColorKeys(GpImageAttributes *imageattr, ColorAdjustType type, BOOL enableFlag, ARGB colorLow, ARGB colorHigh)
GpStatus WINGDIPAPI GdipDisposeImageAttributes(GpImageAttributes *imageattr)
GpStatus WINGDIPAPI GdipSetImageAttributesRemapTable(GpImageAttributes *imageAttr, ColorAdjustType type, BOOL enableFlag, UINT mapSize, GDIPCONST ColorMap *map)
GpStatus WINGDIPAPI GdipSetImageAttributesNoOp(GpImageAttributes *imageAttr, ColorAdjustType type, BOOL enableFlag)
GpStatus WINGDIPAPI GdipResetImageAttributes(GpImageAttributes *imageAttr, ColorAdjustType type)
#define bits
Definition: infblock.c:15
#define S_OK
Definition: intsafe.h:52
const char * filename
Definition: ioapi.h:137
static ERESOURCE GlobalLock
Definition: sys_arch.c:8
uint32_t entry
Definition: isohybrid.c:63
#define wine_dbgstr_w
Definition: kernel32.h:34
static char filename2[]
Definition: lzexpand_main.c:51
const WCHAR * mime
Definition: mimefilter.c:512
#define win_skip
Definition: minitest.h:67
#define todo_wine_if(is_todo)
Definition: minitest.h:81
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:537
#define todo_wine
Definition: minitest.h:80
static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
Definition: mipmap.c:4858
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define BI_BITFIELDS
Definition: mmreg.h:507
static PVOID ptr
Definition: dispmode.c:27
#define sprintf
Definition: sprintf.c:45
BITMAP bmp
Definition: alphablend.c:62
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
static HICON
Definition: imagelist.c:80
BOOL todo
Definition: filedlg.c:313
BOOL expected
Definition: store.c:2000
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1204
static const char * dst_format
Definition: dib.c:1339
static UINT documented_type(UINT type)
Definition: image.c:3779
static void test_GdipCreateBitmapFromHBITMAP(void)
Definition: image.c:1169
static void test_multiframegif(void)
Definition: image.c:3103
static void test_testcontrol(void)
Definition: image.c:1582
static void test_tiff_palette(void)
Definition: image.c:4343
static UINT *static UINT UINT UINT UINT *static GdiplusAbort *static BOOL
Definition: image.c:37
static UINT *static UINT UINT UINT UINT *static GdiplusAbort *static INT
Definition: image.c:37
static const BYTE gif_2frame_missing_gce1[]
Definition: image.c:5024
#define giftest(img, prop, frames)
static void test_getsetpixel(void)
Definition: image.c:2368
static void test_createhbitmap(void)
Definition: image.c:2074
static void test_PARGB_conversion(void)
Definition: image.c:5218
static void test_GetImageDimension(void)
Definition: image.c:386
static void test_bufferrawformat(void *buff, int size, REFGUID expected, int line, BOOL todo)
Definition: image.c:182
static BYTE * init_bitmap(UINT *width, UINT *height, UINT *stride)
Definition: image.c:6179
static ARGB gifanimation3_pixels[5][4]
Definition: image.c:3095
#define IFD_BYTE
Definition: image.c:4112
static void test_remaptable(void)
Definition: image.c:3498
static void test_GdipLoadImageFromStream(void)
Definition: image.c:6148
#define IFD_SBYTE
Definition: image.c:4117
static void test_createfromwmf_noplaceable(void)
Definition: image.c:1964
static void check_properties_get_all(GpImage *image, const struct property_test_data *td, UINT count, const struct property_test_data *td_broken, UINT count_broken, UINT prop_size)
Definition: image.c:3866
#define PNG_COLOR_TYPE_RGB
Definition: image.c:5761
static void test_encoders(void)
Definition: image.c:781
BOOL color_match(ARGB c1, ARGB c2, BYTE max_diff)
Definition: image.c:48
static void test_DrawImage_SourceCopy(void)
Definition: image.c:4641
static void test_colorkey(void)
Definition: image.c:3574
static const BYTE png_hist[]
Definition: image.c:6016
static void test_graphics_clear(void)
Definition: image.c:6323
static void test_GdipCloneImage(void)
Definition: image.c:1550
static void test_imageabort(void)
Definition: image.c:5693
static void test_png_unit_properties(void)
Definition: image.c:6024
static void test_dispose(void)
Definition: image.c:3668
static const unsigned char transparentgif[]
Definition: image.c:1756
static void test_GdipInitializePalette(void)
Definition: image.c:6207
#define IFD_UNDEFINED
Definition: image.c:4118
static const char png_1x1_data[]
Definition: image.c:5718
static const BYTE gif_2frame_missing_gce2[]
Definition: image.c:5033
static const BYTE png_phys[]
Definition: image.c:6000
static void test_gif_properties(void)
Definition: image.c:5048
static BOOL compare_uint(unsigned int x, unsigned int y, unsigned int max_diff)
Definition: image.c:42
static void test_histogram(void)
Definition: image.c:5565
static void test_getthumbnail(void)
Definition: image.c:2296
static void test_FromGdiDib(void)
Definition: image.c:275
static void test_getrawformat(void)
Definition: image.c:1825
static void test_png_histogram_property(void)
Definition: image.c:6124
static void test_LockBits_UserBuf(void)
Definition: image.c:1073
static BOOL get_encoder_clsid(LPCWSTR mime, GUID *format, CLSID *clsid)
Definition: image.c:152
static void test_colormatrix(void)
Definition: image.c:2673
static const unsigned char gifimage[35]
Definition: image.c:1750
static void test_getadjustedpalette(void)
Definition: image.c:5500
static void test_LockBits(void)
Definition: image.c:835
#define IFD_SRATIONAL
Definition: image.c:4121
static void test_GdipDrawImagePointRect(void)
Definition: image.c:4685
static const BYTE png_minimal[]
Definition: image.c:5993
static const char * dbgstr_hexdata(const BYTE *data, UINT len)
Definition: image.c:109
#define IFD_SLONG
Definition: image.c:4120
static void test_GdipGetImageFlags(void)
Definition: image.c:1423
static void test_SavingImages(void)
Definition: image.c:535
#define IFD_SHORT
Definition: image.c:4114
static UINT *static HistogramFormat
Definition: image.c:34
static void test_DrawImage(void)
Definition: image.c:4595
static const unsigned char bmpimage[66]
Definition: image.c:1762
static void expect_image_properties(GpImage *image, UINT width, UINT height, int line)
Definition: image.c:85
#define IFD_SSHORT
Definition: image.c:4119
static void test_GdipGetAllPropertyItems(void)
Definition: image.c:4291
static void check_halftone_palette(ColorPalette *palette)
Definition: image.c:2448
INT compare_with_precision(const BYTE *ptr1, const BYTE *ptr2, size_t num, INT precision)
Definition: image.c:4810
static void test_rotateflip(void)
Definition: image.c:3378
static void test_LoadingImages(void)
Definition: image.c:489
static GpImage * load_image(const BYTE *image_data, UINT image_size, BOOL valid_data, BOOL todo_load)
Definition: image.c:3700
static const struct tiff_data TIFF_data
static void test_ARGB_conversion(void)
Definition: image.c:5148
#define expect(expected, got)
Definition: image.c:39
static void test_png_save_palette(void)
Definition: image.c:5924
static const BYTE animatedgif[]
Definition: image.c:4981
static void expect_rawformat(REFGUID expected, GpImage *img, int line, BOOL todo)
Definition: image.c:74
static void test_png_datetime_property(void)
Definition: image.c:6102
static void test_createfromwmf(void)
Definition: image.c:1906
static const BYTE gif_no_pal[]
Definition: image.c:5042
static void test_GdipImageGetFrameDimensionsCount(void)
Definition: image.c:417
static UINT *static UINT UINT UINT UINT *static GdiplusAbort *static PaletteType
Definition: image.c:37
static const unsigned char wmfimage[180]
Definition: image.c:1811
static void test_fromhicon(void)
Definition: image.c:1593
static void test_createeffect(void)
Definition: image.c:5422
#define expectf(expected, got)
Definition: image.c:40
#define IFD_DOUBLE
Definition: image.c:4123
static void test_CloneBitmapArea(void)
Definition: image.c:5275
#define PNG_COLOR_TYPE_GRAY
Definition: image.c:5760
static const unsigned char gifanimation[72]
Definition: image.c:3012
static void expect_bitmap_locked_data(GpBitmap *bitmap, const BYTE *expect_bits, UINT width, UINT height, UINT stride, int line)
Definition: image.c:127
static const unsigned char gifanimation2[]
Definition: image.c:3029
static void test_DrawImage_scale(void)
Definition: image.c:4827
static void test_SavingMultiPageTiff(void)
Definition: image.c:599
static void test_png_color_formats(void)
Definition: image.c:5766
static ARGB gifanimation2_pixels[5][4]
Definition: image.c:3058
#define IFD_RATIONAL
Definition: image.c:4116
static const unsigned char tiffimage[]
Definition: image.c:1791
static const unsigned char pngimage[285]
Definition: image.c:1740
#define PNG_COLOR_TYPE_PALETTE
Definition: image.c:5762
static const BYTE gif_2frame_no_pal[]
Definition: image.c:5014
static void test_resolution(void)
Definition: image.c:1980
static void test_image_properties(void)
Definition: image.c:3918
static const unsigned char jpgimage[285]
Definition: image.c:1770
static void test_tiff_properties(void)
Definition: image.c:4219
static void check_properties_id_list(GpImage *image, const struct property_test_data *td, UINT count, const struct property_test_data *td_broken, UINT count_broken, UINT *prop_size)
Definition: image.c:3794
static void test_gamma(void)
Definition: image.c:2938
static void test_Scan0(void)
Definition: image.c:217
static void test_bitmapbits(void)
Definition: image.c:4391
static void test_supported_encoders(void)
Definition: image.c:5376
static void test_loadwmf(void)
Definition: image.c:1835
static void test_palette(void)
Definition: image.c:2487
static const unsigned char gifanimation3[]
Definition: image.c:3066
#define IFD_ASCII
Definition: image.c:4113
static const BYTE gif_2frame_global_pal[]
Definition: image.c:5003
static void test_image_format(void)
Definition: image.c:4731
static LONG obj_refcount(void *obj)
Definition: image.c:3694
#define IFD_LONG
Definition: image.c:4115
#define IFD_FLOAT
Definition: image.c:4122
HRESULT hres
Definition: protocol.c:465
static void test_formats(AUDCLNT_SHAREMODE mode)
Definition: render.c:379
static CHAR filenameA[MAX_PATH]
Definition: storage32.c:35
#define expect_guid(expected, guid)
Definition: typelib.c:49
static const CLSID IPropertyStorage UINT *static const PROPSPEC PROPVARIANT *static UINT const PROPSPEC PROPVARIANT PROPID
Definition: shellole.c:78
static HPALETTE palette
Definition: clipboard.c:1457
static HBITMAP bitmap2
Definition: clipboard.c:1456
HICON hIcon
Definition: msconfig.c:44
const CLSID * clsid
Definition: msctf.cpp:50
unsigned int UINT
Definition: ndis.h:50
#define LOCALE_SYSTEM_DEFAULT
interface IStream * LPSTREAM
Definition: objfwd.h:10
short WCHAR
Definition: pedump.c:58
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
char CHAR
Definition: pedump.c:57
png_const_structrp png_const_inforp int * unit
Definition: png.h:2392
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
#define calloc
Definition: rosglue.h:14
int seek(void *fd, ulong off, int mode)
Definition: pe.c:51
#define memset(x, y, z)
Definition: compat.h:39
#define NTDDI_WIN7
Definition: sdkddkver.h:112
DWORD masks[255]
Definition: image.c:1160
BITMAPINFOHEADER bmiHeader
Definition: image.c:1159
UINT_PTR Reserved
PixelFormat PixelFormat
ARGB Argb
Definition: gdipluscolor.h:302
BOOL SuppressBackgroundThread
Definition: gdiplusinit.h:36
DebugEventProc DebugEventCallback
Definition: gdiplusinit.h:35
GpImage * image
LONG value
SHORT id
SHORT type
ULONG count
LONG denominator
Definition: image.c:4137
LONG numerator
Definition: image.c:4136
REAL Height
Definition: gdiplustypes.h:659
REAL X
Definition: gdiplustypes.h:656
REAL Width
Definition: gdiplustypes.h:658
REAL Y
Definition: gdiplustypes.h:657
Definition: scsiwmi.h:51
Definition: uimain.c:89
Definition: tftpd.h:138
Definition: dsound.c:943
Definition: format.c:58
Definition: parser.c:49
Definition: match.c:28
BOOL broken_length
Definition: image.c:3768
Definition: stat.h:66
Definition: ps.c:97
Definition: parse.h:23
ULONG biClrImportant
Definition: precomp.h:40
USHORT biBitCount
Definition: precomp.h:34
ULONG biCompression
Definition: precomp.h:35
BITMAPINFOHEADER bmiHeader
Definition: wingdi.h:1922
RGBQUAD bmiColors[1]
Definition: wingdi.h:1923
LONG bmHeight
Definition: wingdi.h:1869
LONG bmWidth
Definition: wingdi.h:1868
LONG bmType
Definition: wingdi.h:1867
LONG bmWidthBytes
Definition: wingdi.h:1870
LPVOID bmBits
Definition: wingdi.h:1873
WORD bmPlanes
Definition: wingdi.h:1871
WORD bmBitsPixel
Definition: wingdi.h:1872
WORD palNumEntries
Definition: wingdi.h:2280
WORD palVersion
Definition: wingdi.h:2279
UINT size
Definition: ddsformat.c:389
struct IFD_rational srational_val
Definition: image.c:4150
struct IFD_rational xres
Definition: image.c:4148
DOUBLE double_val
Definition: image.c:4149
struct IFD_rational rational[3]
Definition: image.c:4155
USHORT number_of_entries
Definition: image.c:4145
struct IFD_entry entry[40]
Definition: image.c:4146
SHORT short_val[4]
Definition: image.c:4152
BYTE pixel_data[4]
Definition: image.c:4156
ULONG next_IFD
Definition: image.c:4147
USHORT byte_order
Definition: image.c:4142
FLOAT float_val[2]
Definition: image.c:4154
ULONG dir_offset
Definition: image.c:4144
USHORT version
Definition: image.c:4143
LONG long_val[2]
Definition: image.c:4153
static UINT width_bytes(UINT width, UINT bpp)
Definition: tiffformat.c:859
const uint16_t * LPCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
float FLOAT
Definition: typedefs.h:69
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
double DOUBLE
Definition: typedefs.h:70
#define BI_RGB
Definition: uefivid.c:46
struct BITMAPINFOWITHBITFIELDS bf
Definition: image.c:1166
BITMAPINFO bi
Definition: image.c:1165
Definition: pdh_main.c:96
HBITMAP WINAPI CreateDIBSection(HDC hDC, CONST BITMAPINFO *BitmapInfo, UINT Usage, VOID **Bits, HANDLE hSection, DWORD dwOffset)
Definition: bitmap.c:245
#define GMEM_ZEROINIT
Definition: winbase.h:330
#define GMEM_NODISCARD
Definition: winbase.h:326
#define GMEM_MOVEABLE
Definition: winbase.h:318
DWORD COLORREF
Definition: windef.h:100
#define WINAPI
Definition: msvc.h:6
#define DIB_RGB_COLORS
Definition: wingdi.h:367
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
int WINAPI GetDeviceCaps(_In_opt_ HDC, _In_ int)
int WINAPI GetObjectA(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
#define LOGPIXELSY
Definition: wingdi.h:719
HPALETTE WINAPI CreatePalette(_In_reads_(_Inexpressible_(2 *sizeof(WORD)+plpal->palNumEntries *sizeof(PALETTEENTRY))) const LOGPALETTE *)
struct tagLOGPALETTE LOGPALETTE
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
HMETAFILE WINAPI SetMetaFileBitsEx(_In_ UINT cbBuffer, _In_reads_bytes_(cbBuffer) CONST BYTE *lpData)
#define LOGPIXELSX
Definition: wingdi.h:718
BOOL WINAPI DeleteDC(_In_ HDC)
#define CSTR_EQUAL
Definition: winnls.h:500
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2975
HDC WINAPI GetDC(_In_opt_ HWND)
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2422
unsigned char BYTE
Definition: xxhash.c:193