[WINDOWSCODECS_WINETEST] Sync with Wine Staging 4.18. CORE-16441
[reactos.git] / modules / rostests / winetests / windowscodecs / palette.c
1 /*
2 * Copyright 2009 Vincent Povirk for CodeWeavers
3 * Copyright 2012,2016 Dmitry Timoshkov
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20 #include <stdarg.h>
21 #include <assert.h>
22
23 #define COBJMACROS
24
25 #include "windef.h"
26 #include "objbase.h"
27 #include "wincodec.h"
28 #include "wine/test.h"
29
30 static IWICImagingFactory *factory;
31
32 static void test_custom_palette(void)
33 {
34 IWICPalette *palette, *palette2;
35 HRESULT hr;
36 WICBitmapPaletteType type=0xffffffff;
37 UINT count=1;
38 const WICColor initcolors[4]={0xff000000,0xff0000ff,0xffffff00,0xffffffff};
39 WICColor colors[4];
40 BOOL boolresult;
41
42 hr = IWICImagingFactory_CreatePalette(factory, &palette);
43 ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr);
44 if (SUCCEEDED(hr))
45 {
46 hr = IWICPalette_GetType(palette, &type);
47 ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr);
48 ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type);
49
50 hr = IWICPalette_GetColorCount(palette, &count);
51 ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr);
52 ok(count == 0, "expected 0, got %u\n", count);
53
54 hr = IWICPalette_GetColors(palette, 0, colors, &count);
55 ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr);
56 ok(count == 0, "expected 0, got %u\n", count);
57
58 hr = IWICPalette_GetColors(palette, 4, colors, &count);
59 ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr);
60 ok(count == 0, "expected 0, got %u\n", count);
61
62 memcpy(colors, initcolors, sizeof(initcolors));
63 hr = IWICPalette_InitializeCustom(palette, colors, 4);
64 ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%x\n", hr);
65
66 hr = IWICPalette_GetType(palette, &type);
67 ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr);
68 ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type);
69
70 hr = IWICPalette_GetColorCount(palette, &count);
71 ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr);
72 ok(count == 4, "expected 4, got %u\n", count);
73
74 memset(colors, 0, sizeof(colors));
75 count = 0;
76 hr = IWICPalette_GetColors(palette, 4, colors, &count);
77 ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr);
78 ok(count == 4, "expected 4, got %u\n", count);
79 ok(!memcmp(colors, initcolors, sizeof(colors)), "got unexpected palette data\n");
80
81 memset(colors, 0, sizeof(colors));
82 count = 0;
83 hr = IWICPalette_GetColors(palette, 2, colors, &count);
84 ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr);
85 ok(count == 2, "expected 2, got %u\n", count);
86 ok(!memcmp(colors, initcolors, sizeof(WICColor)*2), "got unexpected palette data\n");
87
88 count = 0;
89 hr = IWICPalette_GetColors(palette, 6, colors, &count);
90 ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr);
91 ok(count == 4, "expected 4, got %u\n", count);
92
93 hr = IWICPalette_HasAlpha(palette, &boolresult);
94 ok(SUCCEEDED(hr), "HasAlpha failed, hr=%x\n", hr);
95 ok(!boolresult, "expected FALSE, got TRUE\n");
96
97 hr = IWICPalette_IsBlackWhite(palette, &boolresult);
98 ok(SUCCEEDED(hr), "IsBlackWhite failed, hr=%x\n", hr);
99 ok(!boolresult, "expected FALSE, got TRUE\n");
100
101 hr = IWICPalette_IsGrayscale(palette, &boolresult);
102 ok(SUCCEEDED(hr), "IsGrayscale failed, hr=%x\n", hr);
103 ok(!boolresult, "expected FALSE, got TRUE\n");
104
105 hr = IWICImagingFactory_CreatePalette(factory, &palette2);
106 ok(SUCCEEDED(hr), "CreatePalette failed, hr=%x\n", hr);
107
108 hr = IWICPalette_InitializeFromPalette(palette2, palette);
109 ok(SUCCEEDED(hr), "InitializeFromPalette failed, hr=%x\n", hr);
110
111 type = 0xdeadbeef;
112 hr = IWICPalette_GetType(palette2, &type);
113 ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr);
114 ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type);
115
116 count = 0xdeadbeef;
117 hr = IWICPalette_GetColorCount(palette2, &count);
118 ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr);
119 ok(count == 4, "expected 4, got %u\n", count);
120
121 memset(colors, 0, sizeof(colors));
122 count = 0xdeadbeef;
123 hr = IWICPalette_GetColors(palette2, 4, colors, &count);
124 ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr);
125 ok(count == 4, "expected 4, got %u\n", count);
126 ok(!memcmp(colors, initcolors, sizeof(colors)), "got unexpected palette data\n");
127
128 /* try a palette with some alpha in it */
129 colors[2] = 0x80ffffff;
130 hr = IWICPalette_InitializeCustom(palette, colors, 4);
131 ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%x\n", hr);
132
133 hr = IWICPalette_HasAlpha(palette, &boolresult);
134 ok(SUCCEEDED(hr), "HasAlpha failed, hr=%x\n", hr);
135 ok(boolresult, "expected TRUE, got FALSE\n");
136
137 /* setting to a 0-color palette is acceptable */
138 hr = IWICPalette_InitializeCustom(palette, NULL, 0);
139 ok(SUCCEEDED(hr), "InitializeCustom failed, hr=%x\n", hr);
140
141 type = 0xdeadbeef;
142 hr = IWICPalette_GetType(palette, &type);
143 ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr);
144 ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type);
145
146 count = 0xdeadbeef;
147 hr = IWICPalette_GetColorCount(palette, &count);
148 ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr);
149 ok(count == 0, "expected 0, got %u\n", count);
150
151 count = 0xdeadbeef;
152 hr = IWICPalette_GetColors(palette, 4, colors, &count);
153 ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr);
154 ok(count == 0, "expected 0, got %u\n", count);
155
156 hr = IWICPalette_InitializeFromPalette(palette2, palette);
157 ok(SUCCEEDED(hr), "InitializeFromPalette failed, hr=%x\n", hr);
158
159 type = 0xdeadbeef;
160 hr = IWICPalette_GetType(palette2, &type);
161 ok(SUCCEEDED(hr), "GetType failed, hr=%x\n", hr);
162 ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %x\n", type);
163
164 count = 0xdeadbeef;
165 hr = IWICPalette_GetColorCount(palette2, &count);
166 ok(SUCCEEDED(hr), "GetColorCount failed, hr=%x\n", hr);
167 ok(count == 0, "expected 0, got %u\n", count);
168
169 memset(colors, 0, sizeof(colors));
170 count = 0xdeadbeef;
171 hr = IWICPalette_GetColors(palette2, 4, colors, &count);
172 ok(SUCCEEDED(hr), "GetColors failed, hr=%x\n", hr);
173 ok(count == 0, "expected 0, got %u\n", count);
174
175 /* IWICPalette is paranoid about NULL pointers */
176 hr = IWICPalette_GetType(palette, NULL);
177 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);
178
179 hr = IWICPalette_GetColorCount(palette, NULL);
180 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);
181
182 hr = IWICPalette_InitializeCustom(palette, NULL, 4);
183 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);
184
185 hr = IWICPalette_GetColors(palette, 4, NULL, &count);
186 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);
187
188 hr = IWICPalette_GetColors(palette, 4, colors, NULL);
189 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);
190
191 hr = IWICPalette_HasAlpha(palette, NULL);
192 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);
193
194 hr = IWICPalette_IsBlackWhite(palette, NULL);
195 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);
196
197 hr = IWICPalette_IsGrayscale(palette, NULL);
198 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);
199
200 hr = IWICPalette_InitializeFromPalette(palette, NULL);
201 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %x\n", hr);
202
203 IWICPalette_Release(palette2);
204 IWICPalette_Release(palette);
205 }
206 }
207
208 static void generate_gray16_palette(DWORD *entries, UINT count)
209 {
210 UINT i;
211
212 assert(count == 16);
213
214 for (i = 0; i < 16; i++)
215 {
216 entries[i] = 0xff000000;
217 entries[i] |= (i << 20) | (i << 16) | (i << 12) | (i << 8) | (i << 4) | i;
218 }
219 }
220
221 static void generate_gray256_palette(DWORD *entries, UINT count)
222 {
223 UINT i;
224
225 assert(count == 256);
226
227 for (i = 0; i < 256; i++)
228 {
229 entries[i] = 0xff000000;
230 entries[i] |= (i << 16) | (i << 8) | i;
231 }
232 }
233
234 static void generate_halftone8_palette(DWORD *entries, UINT count, BOOL add_transparent)
235 {
236 UINT i;
237
238 if (add_transparent)
239 ok(count == 17, "expected 17, got %u\n", count);
240 else
241 ok(count == 16, "expected 16, got %u\n", count);
242
243 for (i = 0; i < 8; i++)
244 {
245 entries[i] = 0xff000000;
246 if (i & 1) entries[i] |= 0xff;
247 if (i & 2) entries[i] |= 0xff00;
248 if (i & 4) entries[i] |= 0xff0000;
249 }
250
251 for (i = 8; i < 16; i++)
252 {
253 static const DWORD halftone[8] = { 0xc0c0c0, 0x808080, 0x800000, 0x008000,
254 0x000080, 0x808000, 0x800080, 0x008080 };
255 entries[i] = 0xff000000;
256 entries[i] |= halftone[i-8];
257 }
258
259 if (add_transparent)
260 entries[i] = 0;
261 }
262
263 static void generate_halftone27_palette(DWORD *entries, UINT count, BOOL add_transparent)
264 {
265 static const BYTE halftone_values[4] = { 0x00,0x80,0xff };
266 UINT i;
267
268 if (add_transparent)
269 ok(count == 29, "expected 29, got %u\n", count);
270 else
271 ok(count == 28, "expected 28, got %u\n", count);
272
273 for (i = 0; i < 27; i++)
274 {
275 entries[i] = 0xff000000;
276 entries[i] |= halftone_values[i%3];
277 entries[i] |= halftone_values[(i/3)%3] << 8;
278 entries[i] |= halftone_values[(i/9)%3] << 16;
279 }
280
281 entries[i++] = 0xffc0c0c0;
282 if (add_transparent)
283 entries[i] = 0;
284 }
285
286 static void generate_halftone64_palette(DWORD *entries, UINT count, BOOL add_transparent)
287 {
288 static const BYTE halftone_values[4] = { 0x00,0x55,0xaa,0xff };
289 UINT i;
290
291 if (add_transparent)
292 ok(count == 73, "expected 73, got %u\n", count);
293 else
294 ok(count == 72, "expected 72, got %u\n", count);
295
296 for (i = 0; i < 64; i++)
297 {
298 entries[i] = 0xff000000;
299 entries[i] |= halftone_values[i%4];
300 entries[i] |= halftone_values[(i/4)%4] << 8;
301 entries[i] |= halftone_values[(i/16)%4] << 16;
302 }
303
304 for (i = 64; i < 72; i++)
305 {
306 static const DWORD halftone[8] = { 0xc0c0c0, 0x808080, 0x800000, 0x008000,
307 0x000080, 0x808000, 0x800080, 0x008080 };
308 entries[i] = 0xff000000;
309 entries[i] |= halftone[i-64];
310 }
311
312 if (add_transparent)
313 entries[i] = 0;
314 }
315
316 static void generate_halftone125_palette(DWORD *entries, UINT count, BOOL add_transparent)
317 {
318 static const BYTE halftone_values[5] = { 0x00, 0x40, 0x80, 0xbf, 0xff };
319 UINT i;
320
321 if (add_transparent)
322 ok(count == 127, "expected 127, got %u\n", count);
323 else
324 ok(count == 126, "expected 126, got %u\n", count);
325
326 for (i = 0; i < 125; i++)
327 {
328 entries[i] = 0xff000000;
329 entries[i] |= halftone_values[i%5];
330 entries[i] |= halftone_values[(i/5)%5] << 8;
331 entries[i] |= halftone_values[(i/25)%5] << 16;
332 }
333
334 entries[i++] = 0xffc0c0c0;
335 if (add_transparent)
336 entries[i] = 0;
337 }
338
339 static void generate_halftone216_palette(DWORD *entries, UINT count, BOOL add_transparent)
340 {
341 static const BYTE halftone_values[6] = { 0x00,0x33,0x66,0x99,0xcc,0xff };
342 UINT i;
343
344 if (add_transparent)
345 ok(count == 225, "expected 225, got %u\n", count);
346 else
347 ok(count == 224, "expected 224, got %u\n", count);
348
349 for (i = 0; i < 216; i++)
350 {
351 entries[i] = 0xff000000;
352 entries[i] |= halftone_values[i%6];
353 entries[i] |= halftone_values[(i/6)%6] << 8;
354 entries[i] |= halftone_values[(i/36)%6] << 16;
355 }
356
357 for (i = 216; i < 224; i++)
358 {
359 static const DWORD halftone[8] = { 0xc0c0c0, 0x808080, 0x800000, 0x008000,
360 0x000080, 0x808000, 0x800080, 0x008080 };
361 entries[i] = 0xff000000;
362 entries[i] |= halftone[i-216];
363 }
364
365 if (add_transparent)
366 entries[i] = 0;
367 }
368
369 static void generate_halftone252_palette(DWORD *entries, UINT count, BOOL add_transparent)
370 {
371 static const BYTE halftone_values_rb[6] = { 0x00,0x33,0x66,0x99,0xcc,0xff };
372 static const BYTE halftone_values_g[7] = { 0x00,0x2b,0x55,0x80,0xaa,0xd5,0xff };
373 UINT i;
374
375 if (add_transparent)
376 ok(count == 253, "expected 253, got %u\n", count);
377 else
378 ok(count == 252, "expected 252, got %u\n", count);
379
380 for (i = 0; i < 252; i++)
381 {
382 entries[i] = 0xff000000;
383 entries[i] |= halftone_values_rb[i%6];
384 entries[i] |= halftone_values_g[(i/6)%7] << 8;
385 entries[i] |= halftone_values_rb[(i/42)%6] << 16;
386 }
387
388 if (add_transparent)
389 entries[i] = 0;
390 }
391
392 static void generate_halftone256_palette(DWORD *entries, UINT count, BOOL add_transparent)
393 {
394 static const BYTE halftone_values_b[4] = { 0x00,0x55,0xaa,0xff };
395 static const BYTE halftone_values_gr[8] = { 0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff };
396 UINT i;
397
398 assert(count == 256);
399
400 for (i = 0; i < 256; i++)
401 {
402 entries[i] = 0xff000000;
403 entries[i] |= halftone_values_b[i%4];
404 entries[i] |= halftone_values_gr[(i/4)%8] << 8;
405 entries[i] |= halftone_values_gr[(i/32)%8] << 16;
406 }
407
408 if (add_transparent)
409 entries[255] = 0;
410 }
411
412 static void test_predefined_palette(void)
413 {
414 static struct test_data
415 {
416 WICBitmapPaletteType type;
417 BOOL is_bw, is_gray;
418 UINT count;
419 WICColor color[256];
420 BOOL add_transparent;
421 } td[] =
422 {
423 { WICBitmapPaletteTypeFixedBW, 1, 1, 2, { 0xff000000, 0xffffffff } },
424 { WICBitmapPaletteTypeFixedBW, 1, 1, 2, { 0xff000000, 0xffffffff }, 1 },
425 { WICBitmapPaletteTypeFixedGray4, 0, 1, 4,
426 { 0xff000000, 0xff555555, 0xffaaaaaa, 0xffffffff } },
427 { WICBitmapPaletteTypeFixedGray4, 0, 1, 4,
428 { 0xff000000, 0xff555555, 0xffaaaaaa, 0xffffffff }, 1 },
429 { WICBitmapPaletteTypeFixedGray16, 0, 1, 16, { 0 } },
430 { WICBitmapPaletteTypeFixedGray16, 0, 1, 16, { 0 }, 1 },
431 { WICBitmapPaletteTypeFixedGray256, 0, 1, 256, { 0 } },
432 { WICBitmapPaletteTypeFixedGray256, 0, 1, 256, { 0 }, 1 },
433 { WICBitmapPaletteTypeFixedHalftone8, 0, 0, 16, { 0 } },
434 { WICBitmapPaletteTypeFixedHalftone8, 0, 0, 17, { 0 }, 1 },
435 { WICBitmapPaletteTypeFixedHalftone27, 0, 0, 28, { 0 } },
436 { WICBitmapPaletteTypeFixedHalftone27, 0, 0, 29, { 0 }, 1 },
437 { WICBitmapPaletteTypeFixedHalftone64, 0, 0, 72, { 0 } },
438 { WICBitmapPaletteTypeFixedHalftone64, 0, 0, 73, { 0 }, 1 },
439 { WICBitmapPaletteTypeFixedHalftone125, 0, 0, 126, { 0 } },
440 { WICBitmapPaletteTypeFixedHalftone125, 0, 0, 127, { 0 }, 1 },
441 { WICBitmapPaletteTypeFixedHalftone216, 0, 0, 224, { 0 } },
442 { WICBitmapPaletteTypeFixedHalftone216, 0, 0, 225, { 0 }, 1 },
443 { WICBitmapPaletteTypeFixedHalftone252, 0, 0, 252, { 0 } },
444 { WICBitmapPaletteTypeFixedHalftone252, 0, 0, 253, { 0 }, 1 },
445 { WICBitmapPaletteTypeFixedHalftone256, 0, 0, 256, { 0 } },
446 { WICBitmapPaletteTypeFixedHalftone256, 0, 0, 256, { 0 }, 1 }
447 };
448 IWICPalette *palette;
449 HRESULT hr;
450 WICBitmapPaletteType type;
451 UINT count, i, ret;
452 BOOL bret;
453 WICColor color[256];
454
455 hr = IWICImagingFactory_CreatePalette(factory, &palette);
456 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
457 hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeCustom, FALSE);
458 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
459 hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeMedianCut, FALSE);
460 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
461 hr = IWICPalette_InitializePredefined(palette, 0x0f, FALSE);
462 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
463 IWICPalette_Release(palette);
464
465 for (i = 0; i < ARRAY_SIZE(td); i++)
466 {
467 hr = IWICImagingFactory_CreatePalette(factory, &palette);
468 ok(hr == S_OK, "%u: CreatePalette error %#x\n", i, hr);
469
470 hr = IWICPalette_InitializePredefined(palette, td[i].type, td[i].add_transparent);
471 ok(hr == S_OK, "%u: InitializePredefined error %#x\n", i, hr);
472
473 bret = -1;
474 hr = IWICPalette_IsBlackWhite(palette, &bret);
475 ok(hr == S_OK, "%u: IsBlackWhite error %#x\n", i, hr);
476 ok(bret == td[i].is_bw ||
477 broken(td[i].type == WICBitmapPaletteTypeFixedBW && bret != td[i].is_bw), /* XP */
478 "%u: expected %d, got %d\n",i, td[i].is_bw, bret);
479
480 bret = -1;
481 hr = IWICPalette_IsGrayscale(palette, &bret);
482 ok(hr == S_OK, "%u: IsGrayscale error %#x\n", i, hr);
483 ok(bret == td[i].is_gray, "%u: expected %d, got %d\n", i, td[i].is_gray, bret);
484
485 type = -1;
486 hr = IWICPalette_GetType(palette, &type);
487 ok(hr == S_OK, "%u: GetType error %#x\n", i, hr);
488 ok(type == td[i].type, "%u: expected %#x, got %#x\n", i, td[i].type, type);
489
490 count = 0xdeadbeef;
491 hr = IWICPalette_GetColorCount(palette, &count);
492 ok(hr == S_OK, "%u: GetColorCount error %#x\n", i, hr);
493 ok(count == td[i].count, "%u: expected %u, got %u\n", i, td[i].count, count);
494
495 hr = IWICPalette_GetColors(palette, count, color, &ret);
496 ok(hr == S_OK, "%u: GetColors error %#x\n", i, hr);
497 ok(ret == count, "%u: expected %u, got %u\n", i, count, ret);
498 if (ret == td[i].count)
499 {
500 UINT j;
501
502 if (td[i].type == WICBitmapPaletteTypeFixedGray16)
503 generate_gray16_palette(td[i].color, td[i].count);
504 else if (td[i].type == WICBitmapPaletteTypeFixedGray256)
505 generate_gray256_palette(td[i].color, td[i].count);
506 else if (td[i].type == WICBitmapPaletteTypeFixedHalftone8)
507 generate_halftone8_palette(td[i].color, td[i].count, td[i].add_transparent);
508 else if (td[i].type == WICBitmapPaletteTypeFixedHalftone27)
509 generate_halftone27_palette(td[i].color, td[i].count, td[i].add_transparent);
510 else if (td[i].type == WICBitmapPaletteTypeFixedHalftone64)
511 generate_halftone64_palette(td[i].color, td[i].count, td[i].add_transparent);
512 else if (td[i].type == WICBitmapPaletteTypeFixedHalftone125)
513 generate_halftone125_palette(td[i].color, td[i].count, td[i].add_transparent);
514 else if (td[i].type == WICBitmapPaletteTypeFixedHalftone216)
515 generate_halftone216_palette(td[i].color, td[i].count, td[i].add_transparent);
516 else if (td[i].type == WICBitmapPaletteTypeFixedHalftone252)
517 generate_halftone252_palette(td[i].color, td[i].count, td[i].add_transparent);
518 else if (td[i].type == WICBitmapPaletteTypeFixedHalftone256)
519 generate_halftone256_palette(td[i].color, td[i].count, td[i].add_transparent);
520
521 for (j = 0; j < count; j++)
522 {
523 ok(color[j] == td[i].color[j], "%u:[%u]: expected %#x, got %#x\n",
524 i, j, td[i].color[j], color[j]);
525 }
526 }
527
528 IWICPalette_Release(palette);
529 }
530 }
531
532 static BYTE *init_bitmap(UINT *width, UINT *height, UINT *stride)
533 {
534 BYTE *src;
535 UINT i, j, scale;
536
537 *width = 256;
538 *height = 256;
539 *stride = (*width * 3 + 3) & ~3;
540 trace("width %d, height %d, stride %d\n", *width, *height, *stride);
541
542 src = HeapAlloc(GetProcessHeap(), 0, *stride * *height);
543
544 scale = 256 / *width;
545 if (!scale) scale = 1;
546
547 for (i = 0; i < *height; i++)
548 {
549 for (j = 0; j < *width; j++)
550 {
551 src[i * *stride + j*3 + 0] = scale * i;
552 src[i * *stride + j*3 + 1] = scale * (255 - (i+j)/2);
553 src[i * *stride + j*3 + 2] = scale * j;
554 }
555 }
556
557 return src;
558 }
559
560 static void test_palette_from_bitmap(void)
561 {
562 HRESULT hr;
563 BYTE *data;
564 IWICBitmap *bitmap;
565 IWICPalette *palette;
566 WICBitmapPaletteType type;
567 UINT width, height, stride, count, ret;
568 WICColor color[257];
569
570 data = init_bitmap(&width, &height, &stride);
571
572 hr = IWICImagingFactory_CreateBitmapFromMemory(factory, width, height, &GUID_WICPixelFormat24bppRGB,
573 stride, stride * height, data, &bitmap);
574 ok(hr == S_OK, "CreateBitmapFromMemory error %#x\n", hr);
575
576 hr = IWICImagingFactory_CreatePalette(factory, &palette);
577 ok(hr == S_OK, "CreatePalette error %#x\n", hr);
578
579 hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 0, FALSE);
580 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
581
582 hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 1, FALSE);
583 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
584
585 hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 257, FALSE);
586 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
587
588 hr = IWICPalette_InitializeFromBitmap(palette, NULL, 16, FALSE);
589 ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got %#x\n", hr);
590
591 hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 2, FALSE);
592 ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr);
593 count = 0;
594 hr = IWICPalette_GetColorCount(palette, &count);
595 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
596 ok(count == 2, "expected 2, got %u\n", count);
597
598 hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 2, TRUE);
599 ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr);
600 count = 0;
601 hr = IWICPalette_GetColorCount(palette, &count);
602 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
603 ok(count == 2, "expected 2, got %u\n", count);
604
605 /* without transparent color */
606 hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 16, FALSE);
607 ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr);
608 type = -1;
609 hr = IWICPalette_GetType(palette, &type);
610 ok(hr == S_OK, "GetType error %#x\n", hr);
611 ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type);
612 count = 0;
613 hr = IWICPalette_GetColorCount(palette, &count);
614 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
615 ok(count == 16, "expected 16, got %u\n", count);
616 memset(color, 0, sizeof(color));
617 hr = IWICPalette_GetColors(palette, count, color, &ret);
618 ok(hr == S_OK, "GetColors error %#x\n", hr);
619 ok(ret == count, "expected %u, got %u\n", count, ret);
620 ok(color[count - 1] != 0, "expected !0, got %08x\n", color[count - 1]);
621
622 /* with transparent color */
623 hr = IWICPalette_InitializeFromBitmap(palette, (IWICBitmapSource *)bitmap, 16, TRUE);
624 ok(hr == S_OK, "InitializeFromBitmap error %#x\n", hr);
625 type = -1;
626 hr = IWICPalette_GetType(palette, &type);
627 ok(hr == S_OK, "GetType error %#x\n", hr);
628 ok(type == WICBitmapPaletteTypeCustom, "expected WICBitmapPaletteTypeCustom, got %#x\n", type);
629 count = 0;
630 hr = IWICPalette_GetColorCount(palette, &count);
631 ok(hr == S_OK, "GetColorCount error %#x\n", hr);
632 ok(count == 16, "expected 16, got %u\n", count);
633 memset(color, 0xff, sizeof(color));
634 hr = IWICPalette_GetColors(palette, count, color, &ret);
635 ok(hr == S_OK, "GetColors error %#x\n", hr);
636 ok(ret == count, "expected %u, got %u\n", count, ret);
637 ok(color[count - 1] == 0, "expected 0, got %08x\n", color[count - 1]);
638
639 IWICPalette_Release(palette);
640 IWICBitmap_Release(bitmap);
641
642 HeapFree(GetProcessHeap(), 0, data);
643 }
644
645 START_TEST(palette)
646 {
647 HRESULT hr;
648
649 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
650
651 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
652 &IID_IWICImagingFactory, (void **)&factory);
653 ok(hr == S_OK, "CoCreateInstance error %#x\n", hr);
654
655 test_custom_palette();
656 test_predefined_palette();
657 test_palette_from_bitmap();
658
659 IWICImagingFactory_Release(factory);
660
661 CoUninitialize();
662 }