[WINDOWSCODECS_WINETEST]
[reactos.git] / rostests / winetests / windowscodecs / bitmap.c
1 /*
2 * Copyright 2012 Vincent Povirk for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19 #include <stdarg.h>
20 #include <math.h>
21
22 #define COBJMACROS
23
24 #include "windef.h"
25 #include "objbase.h"
26 #include "wincodec.h"
27 #include "wine/test.h"
28
29 static IWICImagingFactory *factory;
30
31 static void test_createbitmap(void)
32 {
33 HRESULT hr;
34 IWICBitmap *bitmap;
35 IWICPalette *palette;
36 IWICBitmapLock *lock, *lock2;
37 WICBitmapPaletteType palettetype;
38 int i;
39 WICRect rc;
40 const BYTE bitmap_data[27] = {
41 128,128,255, 128,128,128, 128,255,128,
42 128,128,128, 128,128,128, 255,255,255,
43 255,128,128, 255,255,255, 255,255,255};
44 BYTE returned_data[27] = {0};
45 BYTE *lock_buffer=NULL, *base_lock_buffer=NULL;
46 UINT lock_buffer_size=0;
47 UINT lock_buffer_stride=0;
48 WICPixelFormatGUID pixelformat = {0};
49 UINT width=0, height=0;
50 double dpix=10.0, dpiy=10.0;
51 int can_lock_null = 1;
52
53 hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
54 WICBitmapCacheOnLoad, &bitmap);
55 ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr);
56
57 if (FAILED(hr))
58 return;
59
60 hr = IWICImagingFactory_CreatePalette(factory, &palette);
61 ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
62
63 /* Palette is unavailable until explicitly set */
64 hr = IWICBitmap_CopyPalette(bitmap, palette);
65 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%x\n", hr);
66
67 hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE);
68 ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr);
69
70 hr = IWICBitmap_SetPalette(bitmap, palette);
71 ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr);
72
73 hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray4, FALSE);
74 ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr);
75
76 hr = IWICBitmap_CopyPalette(bitmap, palette);
77 ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%x\n", hr);
78
79 hr = IWICPalette_GetType(palette, &palettetype);
80 ok(hr == S_OK, "IWICPalette_GetType failed hr=%x\n", hr);
81 ok(palettetype == WICBitmapPaletteTypeFixedGray256,
82 "expected WICBitmapPaletteTypeFixedGray256, got %x\n", palettetype);
83
84 IWICPalette_Release(palette);
85
86 /* pixel data is initially zeroed */
87 hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, 27, returned_data);
88 ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr);
89
90 for (i=0; i<27; i++)
91 ok(returned_data[i] == 0, "returned_data[%i] == %i\n", i, returned_data[i]);
92
93 /* Invalid lock rects */
94 rc.X = rc.Y = 0;
95 rc.Width = 4;
96 rc.Height = 3;
97 hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
98 ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr);
99 if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock);
100
101 rc.Width = 3;
102 rc.Height = 4;
103 hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
104 ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr);
105 if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock);
106
107 rc.Height = 3;
108 rc.X = 4;
109 hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
110 ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr);
111 if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock);
112
113 rc.X = 0;
114 rc.Y = 4;
115 hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
116 ok(hr == E_INVALIDARG, "IWICBitmap_Lock failed hr=%x\n", hr);
117 if (SUCCEEDED(hr)) IWICBitmapLock_Release(lock);
118
119 /* NULL lock rect */
120 hr = IWICBitmap_Lock(bitmap, NULL, WICBitmapLockRead, &lock);
121 ok(hr == S_OK || broken(hr == E_INVALIDARG) /* winxp */, "IWICBitmap_Lock failed hr=%x\n", hr);
122
123 if (SUCCEEDED(hr))
124 {
125 /* entire bitmap is locked */
126 hr = IWICBitmapLock_GetSize(lock, &width, &height);
127 ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr);
128 ok(width == 3, "got %d, expected 3\n", width);
129 ok(height == 3, "got %d, expected 3\n", height);
130
131 IWICBitmapLock_Release(lock);
132 }
133 else
134 can_lock_null = 0;
135
136 /* lock with a valid rect */
137 rc.Y = 0;
138 hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock);
139 ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr);
140 if (SUCCEEDED(hr))
141 {
142 hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride);
143 ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr);
144 /* stride is divisible by 4 */
145 ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride);
146
147 hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer);
148 ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr);
149 /* buffer size does not include padding from the last row */
150 ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size);
151 ok(lock_buffer != NULL, "got NULL data pointer\n");
152 base_lock_buffer = lock_buffer;
153
154 hr = IWICBitmapLock_GetPixelFormat(lock, &pixelformat);
155 ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%x\n", hr);
156 ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
157
158 hr = IWICBitmapLock_GetSize(lock, &width, &height);
159 ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr);
160 ok(width == 3, "got %d, expected 3\n", width);
161 ok(height == 3, "got %d, expected 3\n", height);
162
163 /* We can have multiple simultaneous read locks */
164 hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock2);
165 ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr);
166
167 if (SUCCEEDED(hr))
168 {
169 hr = IWICBitmapLock_GetDataPointer(lock2, &lock_buffer_size, &lock_buffer);
170 ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr);
171 ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size);
172 ok(lock_buffer == base_lock_buffer, "got %p, expected %p\n", lock_buffer, base_lock_buffer);
173
174 IWICBitmapLock_Release(lock2);
175 }
176
177 if (can_lock_null) /* this hangs on xp/vista */
178 {
179 /* But not a read and a write lock */
180 hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock2);
181 ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr);
182 }
183
184 /* But we don't need a write lock to write */
185 if (base_lock_buffer)
186 {
187 for (i=0; i<3; i++)
188 memcpy(base_lock_buffer + lock_buffer_stride*i, bitmap_data + i*9, 9);
189 }
190
191 IWICBitmapLock_Release(lock);
192 }
193
194 /* test that the data we wrote is returned by CopyPixels */
195 hr = IWICBitmap_CopyPixels(bitmap, NULL, 9, 27, returned_data);
196 ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr);
197
198 for (i=0; i<27; i++)
199 ok(returned_data[i] == bitmap_data[i], "returned_data[%i] == %i\n", i, returned_data[i]);
200
201 /* try a valid partial rect, and write mode */
202 rc.X = 2;
203 rc.Y = 0;
204 rc.Width = 1;
205 rc.Height = 2;
206 hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock);
207 ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr);
208
209 if (SUCCEEDED(hr))
210 {
211 if (can_lock_null) /* this hangs on xp/vista */
212 {
213 /* Can't lock again while locked for writing */
214 hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock2);
215 ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr);
216
217 hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockRead, &lock2);
218 ok(hr == WINCODEC_ERR_ALREADYLOCKED, "IWICBitmap_Lock failed hr=%x\n", hr);
219 }
220
221 hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride);
222 ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr);
223 ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride);
224
225 hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer);
226 ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr);
227 ok(lock_buffer_size == 15, "got %i, expected 15\n", lock_buffer_size);
228 ok(lock_buffer == base_lock_buffer+6, "got %p, expected %p+6\n", lock_buffer, base_lock_buffer);
229
230 hr = IWICBitmapLock_GetPixelFormat(lock, &pixelformat);
231 ok(hr == S_OK, "IWICBitmapLock_GetPixelFormat failed hr=%x\n", hr);
232 ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
233
234 hr = IWICBitmapLock_GetSize(lock, &width, &height);
235 ok(hr == S_OK, "IWICBitmapLock_GetSize failed hr=%x\n", hr);
236 ok(width == 1, "got %d, expected 1\n", width);
237 ok(height == 2, "got %d, expected 2\n", height);
238
239 IWICBitmapLock_Release(lock);
240 }
241
242 hr = IWICBitmap_GetPixelFormat(bitmap, &pixelformat);
243 ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr);
244 ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
245
246 hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy);
247 ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr);
248 ok(dpix == 0.0, "got %f, expected 0.0\n", dpix);
249 ok(dpiy == 0.0, "got %f, expected 0.0\n", dpiy);
250
251 hr = IWICBitmap_SetResolution(bitmap, 12.0, 34.0);
252 ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%x\n", hr);
253
254 hr = IWICBitmap_GetResolution(bitmap, &dpix, &dpiy);
255 ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr);
256 ok(dpix == 12.0, "got %f, expected 12.0\n", dpix);
257 ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy);
258
259 hr = IWICBitmap_GetSize(bitmap, &width, &height);
260 ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr);
261 ok(width == 3, "got %d, expected 3\n", width);
262 ok(height == 3, "got %d, expected 3\n", height);
263
264 IWICBitmap_Release(bitmap);
265 }
266
267 static void test_createbitmapfromsource(void)
268 {
269 HRESULT hr;
270 IWICBitmap *bitmap, *bitmap2;
271 IWICPalette *palette;
272 IWICBitmapLock *lock;
273 int i;
274 WICRect rc;
275 const BYTE bitmap_data[27] = {
276 128,128,255, 128,128,128, 128,255,128,
277 128,128,128, 128,128,128, 255,255,255,
278 255,128,128, 255,255,255, 255,255,255};
279 BYTE returned_data[27] = {0};
280 BYTE *lock_buffer=NULL;
281 UINT lock_buffer_stride=0;
282 UINT lock_buffer_size=0;
283 WICPixelFormatGUID pixelformat = {0};
284 UINT width=0, height=0;
285 double dpix=10.0, dpiy=10.0;
286 UINT count;
287 WICBitmapPaletteType palette_type;
288
289 hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat24bppBGR,
290 WICBitmapCacheOnLoad, &bitmap);
291 ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr);
292
293 if (FAILED(hr))
294 return;
295
296 hr = IWICImagingFactory_CreatePalette(factory, &palette);
297 ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
298
299 hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE);
300 ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr);
301
302 hr = IWICBitmap_SetPalette(bitmap, palette);
303 ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr);
304
305 IWICPalette_Release(palette);
306
307 rc.X = rc.Y = 0;
308 rc.Width = 3;
309 rc.Height = 3;
310 hr = IWICBitmap_Lock(bitmap, &rc, WICBitmapLockWrite, &lock);
311 ok(hr == S_OK, "IWICBitmap_Lock failed hr=%x\n", hr);
312 if (SUCCEEDED(hr))
313 {
314 hr = IWICBitmapLock_GetStride(lock, &lock_buffer_stride);
315 ok(hr == S_OK, "IWICBitmapLock_GetStride failed hr=%x\n", hr);
316 ok(lock_buffer_stride == 12, "got %i, expected 12\n", lock_buffer_stride);
317
318 hr = IWICBitmapLock_GetDataPointer(lock, &lock_buffer_size, &lock_buffer);
319 ok(hr == S_OK, "IWICBitmapLock_GetDataPointer failed hr=%x\n", hr);
320 ok(lock_buffer_size == 33, "got %i, expected 33\n", lock_buffer_size);
321 ok(lock_buffer != NULL, "got NULL data pointer\n");
322
323 for (i=0; i<3; i++)
324 memcpy(lock_buffer + lock_buffer_stride*i, bitmap_data + i*9, 9);
325
326 IWICBitmapLock_Release(lock);
327 }
328
329 hr = IWICBitmap_SetResolution(bitmap, 12.0, 34.0);
330 ok(hr == S_OK, "IWICBitmap_SetResolution failed hr=%x\n", hr);
331
332 hr = IWICImagingFactory_CreateBitmapFromSource(factory, (IWICBitmapSource*)bitmap,
333 WICBitmapCacheOnLoad, &bitmap2);
334 ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%x\n", hr);
335
336 IWICBitmap_Release(bitmap);
337
338 if (FAILED(hr)) return;
339
340 hr = IWICImagingFactory_CreatePalette(factory, &palette);
341 ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
342
343 /* palette isn't copied for non-indexed formats? */
344 hr = IWICBitmap_CopyPalette(bitmap2, palette);
345 ok(hr == WINCODEC_ERR_PALETTEUNAVAILABLE, "IWICBitmap_CopyPalette failed hr=%x\n", hr);
346
347 IWICPalette_Release(palette);
348
349 hr = IWICBitmap_CopyPixels(bitmap2, NULL, 9, 27, returned_data);
350 ok(hr == S_OK, "IWICBitmap_CopyPixels failed hr=%x\n", hr);
351
352 for (i=0; i<27; i++)
353 ok(returned_data[i] == bitmap_data[i], "returned_data[%i] == %i\n", i, returned_data[i]);
354
355 hr = IWICBitmap_GetPixelFormat(bitmap2, &pixelformat);
356 ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr);
357 ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat24bppBGR), "unexpected pixel format\n");
358
359 hr = IWICBitmap_GetResolution(bitmap2, &dpix, &dpiy);
360 ok(hr == S_OK, "IWICBitmap_GetResolution failed hr=%x\n", hr);
361 ok(dpix == 12.0, "got %f, expected 12.0\n", dpix);
362 ok(dpiy == 34.0, "got %f, expected 34.0\n", dpiy);
363
364 hr = IWICBitmap_GetSize(bitmap2, &width, &height);
365 ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr);
366 ok(width == 3, "got %d, expected 3\n", width);
367 ok(height == 3, "got %d, expected 3\n", height);
368
369 IWICBitmap_Release(bitmap2);
370
371 /* Ensure palette is copied for indexed formats */
372 hr = IWICImagingFactory_CreateBitmap(factory, 3, 3, &GUID_WICPixelFormat4bppIndexed,
373 WICBitmapCacheOnLoad, &bitmap);
374 ok(hr == S_OK, "IWICImagingFactory_CreateBitmap failed hr=%x\n", hr);
375
376 hr = IWICImagingFactory_CreatePalette(factory, &palette);
377 ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
378
379 hr = IWICPalette_InitializePredefined(palette, WICBitmapPaletteTypeFixedGray256, FALSE);
380 ok(hr == S_OK, "IWICPalette_InitializePredefined failed hr=%x\n", hr);
381
382 hr = IWICBitmap_SetPalette(bitmap, palette);
383 ok(hr == S_OK, "IWICBitmap_SetPalette failed hr=%x\n", hr);
384
385 IWICPalette_Release(palette);
386
387 hr = IWICImagingFactory_CreateBitmapFromSource(factory, (IWICBitmapSource*)bitmap,
388 WICBitmapCacheOnLoad, &bitmap2);
389 ok(hr == S_OK, "IWICImagingFactory_CreateBitmapFromSource failed hr=%x\n", hr);
390
391 IWICBitmap_Release(bitmap);
392
393 hr = IWICImagingFactory_CreatePalette(factory, &palette);
394 ok(hr == S_OK, "IWICImagingFactory_CreatePalette failed hr=%x\n", hr);
395
396 hr = IWICBitmap_CopyPalette(bitmap2, palette);
397 ok(hr == S_OK, "IWICBitmap_CopyPalette failed hr=%x\n", hr);
398
399 hr = IWICPalette_GetColorCount(palette, &count);
400 ok(hr == S_OK, "IWICPalette_GetColorCount failed hr=%x\n", hr);
401 ok(count == 256, "unexpected count %d\n", count);
402
403 hr = IWICPalette_GetType(palette, &palette_type);
404 ok(hr == S_OK, "IWICPalette_GetType failed hr=%x\n", hr);
405 ok(palette_type == WICBitmapPaletteTypeFixedGray256, "unexpected palette type %d\n", palette_type);
406
407 IWICPalette_Release(palette);
408
409 hr = IWICBitmap_GetPixelFormat(bitmap2, &pixelformat);
410 ok(hr == S_OK, "IWICBitmap_GetPixelFormat failed hr=%x\n", hr);
411 ok(IsEqualGUID(&pixelformat, &GUID_WICPixelFormat4bppIndexed), "unexpected pixel format\n");
412
413 hr = IWICBitmap_GetSize(bitmap2, &width, &height);
414 ok(hr == S_OK, "IWICBitmap_GetSize failed hr=%x\n", hr);
415 ok(width == 3, "got %d, expected 3\n", width);
416 ok(height == 3, "got %d, expected 3\n", height);
417
418 IWICBitmap_Release(bitmap2);
419 }
420
421 START_TEST(bitmap)
422 {
423 HRESULT hr;
424
425 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
426
427 hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER,
428 &IID_IWICImagingFactory, (void**)&factory);
429 ok(SUCCEEDED(hr), "CoCreateInstance failed, hr=%x\n", hr);
430
431 test_createbitmap();
432 test_createbitmapfromsource();
433
434 IWICImagingFactory_Release(factory);
435
436 CoUninitialize();
437 }