wined3d: Recognize Nvidia GT520 cards.
[wine] / dlls / windowscodecs / tests / 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 }