mmdevapi/tests: Fix wrong buffer unit and memory leaks.
[wine] / dlls / gdi32 / tests / dib.c
1 /*
2  * DIB driver tests.
3  *
4  * Copyright 2011 Huw Davies
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <math.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "wincrypt.h"
30
31 #include "wine/test.h"
32
33 static HCRYPTPROV crypt_prov;
34 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
35
36 static const DWORD rop3[256] =
37 {
38     0x000042, 0x010289, 0x020C89, 0x0300AA, 0x040C88, 0x0500A9, 0x060865, 0x0702C5,
39     0x080F08, 0x090245, 0x0A0329, 0x0B0B2A, 0x0C0324, 0x0D0B25, 0x0E08A5, 0x0F0001,
40     0x100C85, 0x1100A6, 0x120868, 0x1302C8, 0x140869, 0x1502C9, 0x165CCA, 0x171D54,
41     0x180D59, 0x191CC8, 0x1A06C5, 0x1B0768, 0x1C06CA, 0x1D0766, 0x1E01A5, 0x1F0385,
42     0x200F09, 0x210248, 0x220326, 0x230B24, 0x240D55, 0x251CC5, 0x2606C8, 0x271868,
43     0x280369, 0x2916CA, 0x2A0CC9, 0x2B1D58, 0x2C0784, 0x2D060A, 0x2E064A, 0x2F0E2A,
44     0x30032A, 0x310B28, 0x320688, 0x330008, 0x3406C4, 0x351864, 0x3601A8, 0x370388,
45     0x38078A, 0x390604, 0x3A0644, 0x3B0E24, 0x3C004A, 0x3D18A4, 0x3E1B24, 0x3F00EA,
46     0x400F0A, 0x410249, 0x420D5D, 0x431CC4, 0x440328, 0x450B29, 0x4606C6, 0x47076A,
47     0x480368, 0x4916C5, 0x4A0789, 0x4B0605, 0x4C0CC8, 0x4D1954, 0x4E0645, 0x4F0E25,
48     0x500325, 0x510B26, 0x5206C9, 0x530764, 0x5408A9, 0x550009, 0x5601A9, 0x570389,
49     0x580785, 0x590609, 0x5A0049, 0x5B18A9, 0x5C0649, 0x5D0E29, 0x5E1B29, 0x5F00E9,
50     0x600365, 0x6116C6, 0x620786, 0x630608, 0x640788, 0x650606, 0x660046, 0x6718A8,
51     0x6858A6, 0x690145, 0x6A01E9, 0x6B178A, 0x6C01E8, 0x6D1785, 0x6E1E28, 0x6F0C65,
52     0x700CC5, 0x711D5C, 0x720648, 0x730E28, 0x740646, 0x750E26, 0x761B28, 0x7700E6,
53     0x7801E5, 0x791786, 0x7A1E29, 0x7B0C68, 0x7C1E24, 0x7D0C69, 0x7E0955, 0x7F03C9,
54     0x8003E9, 0x810975, 0x820C49, 0x831E04, 0x840C48, 0x851E05, 0x8617A6, 0x8701C5,
55     0x8800C6, 0x891B08, 0x8A0E06, 0x8B0666, 0x8C0E08, 0x8D0668, 0x8E1D7C, 0x8F0CE5,
56     0x900C45, 0x911E08, 0x9217A9, 0x9301C4, 0x9417AA, 0x9501C9, 0x960169, 0x97588A,
57     0x981888, 0x990066, 0x9A0709, 0x9B07A8, 0x9C0704, 0x9D07A6, 0x9E16E6, 0x9F0345,
58     0xA000C9, 0xA11B05, 0xA20E09, 0xA30669, 0xA41885, 0xA50065, 0xA60706, 0xA707A5,
59     0xA803A9, 0xA90189, 0xAA0029, 0xAB0889, 0xAC0744, 0xAD06E9, 0xAE0B06, 0xAF0229,
60     0xB00E05, 0xB10665, 0xB21974, 0xB30CE8, 0xB4070A, 0xB507A9, 0xB616E9, 0xB70348,
61     0xB8074A, 0xB906E6, 0xBA0B09, 0xBB0226, 0xBC1CE4, 0xBD0D7D, 0xBE0269, 0xBF08C9,
62     0xC000CA, 0xC11B04, 0xC21884, 0xC3006A, 0xC40E04, 0xC50664, 0xC60708, 0xC707AA,
63     0xC803A8, 0xC90184, 0xCA0749, 0xCB06E4, 0xCC0020, 0xCD0888, 0xCE0B08, 0xCF0224,
64     0xD00E0A, 0xD1066A, 0xD20705, 0xD307A4, 0xD41D78, 0xD50CE9, 0xD616EA, 0xD70349,
65     0xD80745, 0xD906E8, 0xDA1CE9, 0xDB0D75, 0xDC0B04, 0xDD0228, 0xDE0268, 0xDF08C8,
66     0xE003A5, 0xE10185, 0xE20746, 0xE306EA, 0xE40748, 0xE506E5, 0xE61CE8, 0xE70D79,
67     0xE81D74, 0xE95CE6, 0xEA02E9, 0xEB0849, 0xEC02E8, 0xED0848, 0xEE0086, 0xEF0A08,
68     0xF00021, 0xF10885, 0xF20B05, 0xF3022A, 0xF40B0A, 0xF50225, 0xF60265, 0xF708C5,
69     0xF802E5, 0xF90845, 0xFA0089, 0xFB0A09, 0xFC008A, 0xFD0A0A, 0xFE02A9, 0xFF0062
70 };
71
72 static inline BOOL rop_uses_src(DWORD rop)
73 {
74     return (((rop & 0xcc0000) >> 2) != (rop & 0x330000));
75 }
76
77 static const char *sha1_graphics_a8r8g8b8[] =
78 {
79     "a3cadd34d95d3d5cc23344f69aab1c2e55935fcf",
80     "2426172d9e8fec27d9228088f382ef3c93717da9",
81     "9e8f27ca952cdba01dbf25d07c34e86a7820c012",
82     "664fac17803859a4015c6ae29e5538e314d5c827",
83     "17b2c177bdce5e94433574a928bda5c94a8cdfa5",
84     "fe6cc678fb13a3ead67839481bf22348adc69f52",
85     "d51bd330cec510cdccf5394328bd8e5411901e9e",
86     "df4aebf98d91f11be560dd232123b3ae327303d7",
87     "f2af53dd073a09b1031d0032d28da35c82adc566",
88     "eb5a963a6f7b25533ddfb8915e70865d037bd156",
89     "c387917268455017aa0b28bed73aa6554044bbb3",
90     "dcae44fee010dbf7a107797a503923fd8b1abe2e",
91     "6c530622a025d872a642e8f950867884d7b136cb",
92     "7c07d91b8f68fb31821701b3dcb96de018bf0c66",
93     "b2261353decda2712b83538ab434a49ce21f3172",
94     "35f731c0f6356b8f30651bb3cbe0d922c49deba5",
95     "9b9874c1c1d92afa554137e191d34ea33acc322f",
96     "c311dd74325e8cebfc8529a6d24a6fa4ecb7137e",
97     "d7398de15b2837a58a62a701ca1b3384625afec4",
98     "a78b28472bb7ff480ddedd06b9cf2daa775fa7ae",
99     "5246ef357e7317b9d141a3294d300c195da76cb7",
100     "e2a8eef4aeda3a0f6c950075acba38f1f9e0814d",
101     "8b66f14d51ecdeea12bc993302bb9b7d3ec085a1",
102     "7da9dd3d40d44d92deb9883fb7110443c2d5769a",
103     NULL
104 };
105
106 static const char *sha1_graphics_a8b8g8r8[] =
107 {
108     "a3cadd34d95d3d5cc23344f69aab1c2e55935fcf",
109     "e0bc877697093ed440e125154e247ca9d65e933c",
110     "c6d7faf5a502299f99d59eef3f7650bd63dbe108",
111     "9d8c05c3ebd786e7d052418e905a80a64bf7853d",
112     "3da12af0a810fd993fa3dbe23328a4fcd2b6c92a",
113     "b91c8f21cc4d7994abc551feff5b6927d267a9db",
114     "d49dd2c6a37e975b6dc3d201ccc217a788b30284",
115     "ca6753f9eb44529cf8c67cd6abcd4ed1ef758904",
116     "18c3ae944e0afb6c43c21cde093ddb22a27611e4",
117     "b753ebb39d90210cc717f57b53dd439f7de6b077",
118     "38c017dd1fff26b492a57e09f3ce2c4370faf225",
119     "94368cea5033b435454daa56d55546310675131e",
120     "bf57a6a37fb107d29ed3d45695919887abcb7902",
121     "3db0f8bcca3d94920aa57be6321202b8c3c08822",
122     "1f1fc165a4dae7ba118ddccb58a279bfe3876b0a",
123     "8e09abb108e137c99527ab4c9bd07d95b9254bbb",
124     "b0178632775d29bec2b16de7b9b8287115c40d0f",
125     "ca7e859647b9498b53fdd92543ad8aea98ff46f3",
126     "3369889a67d6c79a24ee15f7d14374f9995215e4",
127     "473a1fd07df800c87a5d3286b642ace10c61c6af",
128     "10cd25a0ed5cd8f978d7d68236f81d949b938e84",
129     "4851c5b7d5bc18590e787c0c218a592ef504e738",
130     "9aa506e3df33e0d5298755aa4144e10eb4b5adcf",
131     "abdf003699364fe45fab7dc61e67c606d0063b40",
132     NULL
133 };
134
135 static const char *sha1_graphics_24[] =
136 {
137     "e993b15c9bd14fb45a15310450b7083c44e42665",
138     "edbd7bab3d957fbc85e89612197cf918f5f5af20",
139     "6a7efb3b6e0b49336df1bd2937ca09a11d976531",
140     "236eb5ca9da70ec7cc719cd2fd291bab14000257",
141     "f98023c7cd8c068f2d7a77ce3600004b90ea12d6",
142     "5c4cb9cea2226fc671bb4a11f8253343ee94bb4b",
143     "fd4be592483623dbc800fe28210a1f0daa71999b",
144     "788b8de98c47974fa9f232a6042ae4ca546ddb7d",
145     "a8772e6c44ba633fb384a7c4b50b435f1406107e",
146     "883bc8f305c602edca785e21cd00f488583fb13f",
147     "3bac4e80993f49dc3926e30524115fca9d7a8026",
148     "91369e35be29059a0665782541db4c8b324c6bb2",
149     "0fa8cf332a56bb6d7e14e85861fdd60f51d70501",
150     "593d694cdcc8349b3bfc8257041dbcb27e61da45",
151     "1036b91d93e31cd1d4740d0c8642e115e5a38188",
152     "1898073cdb35ca4d2b21bba933ac16a0b4297317",
153     "5068bff794553cf5a3145ae407c9a2984357844c",
154     "413a7989969c229dee4ab1798362f32f96cf0a10",
155     "0bb222e540b82720d4971e4a2fc626899af03e03",
156     "adc20832d8c43f1cf372d8392535492013cd2306",
157     "45649794dcbcabda487f66f7a80fc1bec79047a1",
158     "b4df692ac70a5f9f303270df4641ab014c6cbf46",
159     "8bc3128ba47891366fd7b02fde7ca19100e64b9f",
160     "e649e00efe7fea1eb8b17f7867fe089e5270c44b",
161     NULL
162 };
163
164 static const char *sha1_graphics_r5g5b5[] =
165 {
166     "2a2ab8b3c019e70b788ade028b0e9e53ffc529ae",
167     "847005cf7371f511bcc837251cde07b1796f6113",
168     "a8f75743a930843ec14d516cd048b6e0468e5d89",
169     "d094f51ce9b9daa9c1d9594ea88be2a2db651459",
170     "cf3928e240c9149788e1635b115a4e5baea0dd8f",
171     "a9034a905daa91757b4f63345c0e40638cd53ca8",
172     "15ee915d989e49bb9bab5b834d8f355bd067cd8f",
173     "99474fecf11df7b7035c35be6b8b697be9889418",
174     "cbc2898717f97ebb07c0c7cc04abde936dc5b584",
175     "29c896b591fdf4ddd23e5c0da1818c37e4686d94",
176     "4b5b275d33c1ebfe5bdc61df2ad125e865b800fa",
177     "92df731fa1f89550d9d4f7ea36c13f2e57c4b02a",
178     "420e39ff3bdd04c4b6cc2c98e99cb7993c7a0de5",
179     "1fabf0fdd046857b1974e31c1c1764fa9d1a762f",
180     "449092689226a1172b6086ba1181d6b6d6499f26",
181     "1a92a60f190d33ef06d9decb56fd3fdd33f3af03",
182     "e61f5978c2e28c0c6d8f5eefe0f840c975586efc",
183     "897d16f4d6a6ddad685d23ed7828d4f676539b75",
184     "9d21bcfdeaf1ca5d47eb823bdefc24d7a95f4f56",
185     "6daaf945a955928c5c124c880522ca4634fb2343",
186     "12a288390d16e1efa99d4185301de48a4d433b14",
187     "3a50ce21b3563a604b4fc9f247a30f5a981f1ba6",
188     "d7d97e28ed316f6596c737eb83baa5948d86b673",
189     "ecc2991277d7314f55b00e0f284ae3703aeef81e",
190     NULL
191 };
192
193 static const char *sha1_graphics_r4g4b4[] =
194 {
195     "2a2ab8b3c019e70b788ade028b0e9e53ffc529ae",
196     "cfa0ab83ee93283ad914c3748f0532da1697af1d",
197     "8bd18697d1ef27492805667a0bc956343ac08667",
198     "e8501c830321584474654f90e40eaf27dc21e6a8",
199     "d95ab10fcfb8447b41742e89f1ae8cd297a32fc4",
200     "821177710961d2cb5f7e7dfc0e06e767b6042753",
201     "667124365ffadeea1d8791bedda77a0c7b898de8",
202     "c9f23e684b600dea17575b4b17175fbd9106c3a9",
203     "7678876e50eae35d1eaa096aae25afaa0b864bf3",
204     "fb52b0c373a5f2a60b981604b120962942d2447a",
205     "5ab8dd07436681d762fa04ad7c6d71291c488924",
206     "0167981d9e1490a2ebd396ff7582f0943aa8e1b8",
207     "115a6bd382410a4a1d3c1fa71d8bf02536863e38",
208     "65c6d1228e3b6d63d42647f14217bc1658b70d9a",
209     "25fcb75aa687aac35b8f72640889fe92413e00c5",
210     "3bddf9d53e89560b083302b146cd33791b13d941",
211     "a81504498c7a7bb46340ce74476a42f70f2730b1",
212     "e61a4f2657a444d8c49f84fb944f9f847667bf2b",
213     "32b6e0aa79b7e96cd0ab2da167f6463c011023a8",
214     "1d283aa4d2b2114f7809fe59357d590c7c779aa7",
215     "29640e2ddd2d3016da14507c3ce9b2ce32f39bb4",
216     "d591232bbc2592462c819a9486750f64180518fd",
217     "0e183a4c30b3da345129cffe33fe0fc593d8666b",
218     "f14d9a4bd8a365b7c8f068a0dad481b6eb2b178b",
219     NULL
220 };
221
222 static const char *sha1_graphics_8[] =
223 {
224     "41728d7ff2bb425b5fc06521adeabf6cc73136f3",
225     "512246d4886ab889a090b167ba194577cb95272e",
226     "921e852d4564cb9e5ac15ff68b5207bebea871d1",
227     "9636b0ebefc443ea11949ccd28f6ca454277dd41",
228     "aa9050da55e6b6957c60b7d603fce539cb5c0048",
229     "e2b93aca15fb1233ac09a713dced1f4cd950b1e4",
230     "3e3a603fc26cc305aa27f88da7d2a3b0073877d8",
231     "390b2bf70daba36310683f46af9cd50b9a061396",
232     "82d21737e9a7247397a6c983a9b6d9a0452dd74d",
233     "2a8460af91675e01cbe9384eb6cd3eb2cb420960",
234     "1af53b1218ee9844fcda891b836d42f6b2f66bd5",
235     "da1cc34a9d9b779fc7849e03e214096026506464",
236     "5ba8f99ca034666effa556748c49a0f5a015125f",
237     "b67ba2f55659c75ac72c1112494461bb3086e1a4",
238     "73e2859ce849f756f954718ce3c90f02e31712b6",
239     "b1dff0f5dd233b44ee568878c5d3f8ae1d80c6d9",
240     "1f27dc1a1316fb7a4a78fe40fcd4bdae3aaad218",
241     "6e375e1485a1e45ac6ab10af49645d5fb2e76dff",
242     "cfc67c325c7cdf96d90af9b3cceb8d0504cbb3b0",
243     "7262364067e03c7fa498af1d59d228d6c63b460e",
244     "5241241a355a667ef0834049adf4218e8b3f16b8",
245     "1f13ea0034db4b0ffa4ddcff9664fd892058f9cd",
246     "3caf512cfddfd463d0750cfe3cadb58548eb2ae8",
247     "4e5e7d5fd64818b2b3d3e793c88f603b699d2f0f",
248     NULL
249 };
250
251 static const char *sha1_graphics_4[] =
252 {
253     "fa867e2976a549ecd3b1fa67df54963232fcef8c",
254     "256d742b4da96b373b4fa5663d0ad3b5faab5c8e",
255     "d96d8f4232b930bccd53b903b5efaf8c0bdb16f4",
256     "9401799e6116c35e5f0e5bdca07ea25316757a72",
257     "482ae2b0ef1d64752b5ef11cc7f35a33eb55d07c",
258     "dcfb3e01100b41c0f75a1c5f84b6de6b90138281",
259     "2505598845fa026ea7187582461efbf06cb6904f",
260     "3981a19363beca8f28d32a5928ac296fd22a5296",
261     "01404024ebb2c266d17d734059524d874491650f",
262     "c87bbff3f83b8ec11bb03cfa9bc9ee5166c4c7ef",
263     "f35c5d62853be78c5d39fb2f45200dc262aa8e18",
264     "46e94a55f5f58a6b915078d8ffdc725f53aab516",
265     "665bbbc749a5ffeedc0d62aef0661a5ce845b017",
266     "1f26a01730f67d40ea711a50d9d801bac15a642e",
267     "3b53d24178cfacba53103a44dfd5d072b15a6781",
268     "c52cfd57f26037723d37192722fc3a217f280c9e",
269     "e34da6500cf2e424d980714d92737cf6c31a7bda",
270     "d17f4358ae529f920960ed89e535902ee13b0033",
271     "0f44e12ecd1ea7e39433890443626d4fc35204a4",
272     "eb38683e812fd13dca971ba8f4cfd2b6820d3524",
273     "73bbc83f88f1aaa6df0158b63e70bb3165163163",
274     "39c16648cf6c261be71a33cec41867f28e119b94",
275     "26ad5116562e7b58c76a26eaf521e2e40899e944",
276     "1bcc54eaf8e3c2b7c59ecccb23c240181d7ba8b8",
277     NULL
278 };
279
280 static inline DWORD get_stride(BITMAPINFO *bmi)
281 {
282     return ((bmi->bmiHeader.biBitCount * bmi->bmiHeader.biWidth + 31) >> 3) & ~3;
283 }
284
285 static inline DWORD get_dib_size(BITMAPINFO *bmi)
286 {
287     return get_stride(bmi) * abs(bmi->bmiHeader.biHeight);
288 }
289
290 static char *hash_dib(BITMAPINFO *bmi, void *bits)
291 {
292     DWORD dib_size = get_dib_size(bmi);
293     HCRYPTHASH hash;
294     char *buf;
295     BYTE hash_buf[20];
296     DWORD hash_size = sizeof(hash_buf);
297     int i;
298     static const char *hex = "0123456789abcdef";
299
300     if(!crypt_prov) return NULL;
301
302     if(!CryptCreateHash(crypt_prov, CALG_SHA1, 0, 0, &hash)) return NULL;
303
304     CryptHashData(hash, bits, dib_size, 0);
305
306     CryptGetHashParam(hash, HP_HASHVAL, NULL, &hash_size, 0);
307     if(hash_size != sizeof(hash_buf)) return NULL;
308
309     CryptGetHashParam(hash, HP_HASHVAL, hash_buf, &hash_size, 0);
310     CryptDestroyHash(hash);
311
312     buf = HeapAlloc(GetProcessHeap(), 0, hash_size * 2 + 1);
313
314     for(i = 0; i < hash_size; i++)
315     {
316         buf[i * 2] = hex[hash_buf[i] >> 4];
317         buf[i * 2 + 1] = hex[hash_buf[i] & 0xf];
318     }
319     buf[i * 2] = '\0';
320
321     return buf;
322 }
323
324 static void compare_hash(BITMAPINFO *bmi, BYTE *bits, const char ***sha1, const char *info)
325 {
326     char *hash = hash_dib(bmi, bits);
327
328     if(!hash)
329     {
330         skip("SHA1 hashing unavailable on this platform\n");
331         return;
332     }
333
334     if(**sha1)
335     {
336         ok(!strcmp(hash, **sha1), "%d: %s: expected hash %s got %s\n",
337            bmi->bmiHeader.biBitCount, info, **sha1, hash);
338         (*sha1)++;
339     }
340     else ok(**sha1 != NULL, "missing hash, got \"%s\",\n", hash);
341
342     HeapFree(GetProcessHeap(), 0, hash);
343 }
344
345 static const RECT bias_check[] =
346 {
347     {100, 100, 200, 150},
348     {100, 100, 150, 200},
349     {100, 100,  50, 200},
350     {100, 100,   0, 150},
351     {100, 100,   0,  50},
352     {100, 100,  50,   0},
353     {100, 100, 150,   0},
354     {100, 100, 200,  50}
355 };
356
357 static const RECT hline_clips[] =
358 {
359     {120, 120, 140, 120}, /* unclipped */
360     {100, 122, 140, 122}, /* l edgecase */
361     { 99, 124, 140, 124}, /* l edgecase clipped */
362     {120, 126, 200, 126}, /* r edgecase */
363     {120, 128, 201, 128}, /* r edgecase clipped */
364     { 99, 130, 201, 130}, /* l and r clipped */
365     {120, 100, 140, 100}, /* t edgecase */
366     {120,  99, 140,  99}, /* t edgecase clipped */
367     {120, 199, 140, 199}, /* b edgecase */
368     {120, 200, 140, 200}, /* b edgecase clipped */
369     {120, 132, 310, 132}, /* inside two clip rects */
370     { 10, 134, 101, 134}, /* r end on l edgecase */
371     { 10, 136, 100, 136}, /* r end on l edgecase clipped */
372     {199, 138, 220, 138}, /* l end on r edgecase */
373     {200, 140, 220, 140}  /* l end on r edgecase clipped */
374 };
375
376 static const RECT vline_clips[] =
377 {
378     {120, 120, 120, 140}, /* unclipped */
379     {100, 120, 100, 140}, /* l edgecase */
380     { 99, 120,  99, 140}, /* l edgecase clipped */
381     {199, 120, 199, 140}, /* r edgecase */
382     {200, 120, 200, 140}, /* r edgecase clipped */
383     {122,  99, 122, 201}, /* t and b clipped */
384     {124, 100, 124, 140}, /* t edgecase */
385     {126,  99, 126, 140}, /* t edgecase clipped */
386     {128, 120, 128, 200}, /* b edgecase */
387     {130, 120, 130, 201}, /* b edgecase clipped */
388     {132,  12, 132, 140}, /* inside two clip rects */
389     {134,  90, 134, 101}, /* b end on t edgecase */
390     {136,  90, 136, 100}, /* b end on t edgecase clipped */
391     {138, 199, 138, 220}, /* t end on b edgecase */
392     {140, 200, 140, 220}  /* t end on b edgecase clipped */
393 };
394
395 static const RECT line_clips[] =
396 {
397     { 90, 110, 310, 120},
398     { 90, 120, 295, 130},
399     { 90, 190, 110, 240}, /* totally clipped, moving outcodes */
400     { 90, 130, 100, 135}, /* totally clipped, end pt on l edge */
401     { 90, 132, 101, 137}, /* end pt just inside l edge */
402     {200, 140, 210, 141}, /* totally clipped, start pt on r edge */
403     {199, 142, 210, 143}  /* start pt just inside r edge */
404 };
405
406 static const RECT patblt_clips[] =
407 {
408     {120, 120, 140, 126}, /* unclipped */
409     {100, 130, 140, 136}, /* l edgecase */
410     { 99, 140, 140, 146}, /* l edgecase clipped */
411     {180, 130, 200, 136}, /* r edgecase */
412     {180, 140, 201, 146}, /* r edgecase clipped */
413     {120, 100, 130, 110}, /* t edgecase */
414     {140,  99, 150, 110}, /* t edgecase clipped */
415     {120, 180, 130, 200}, /* b edgecase */
416     {140, 180, 150, 201}, /* b edgecase */
417     {199, 150, 210, 156}, /* l edge on r edgecase */
418     {200, 160, 210, 166}, /* l edge on r edgecase clipped */
419     { 90, 150, 101, 156}, /* r edge on l edgecase */
420     { 90, 160, 100, 166}, /* r edge on l edgecase clipped */
421     {160,  90, 166, 101}, /* b edge on t edgecase */
422     {170,  90, 176, 101}, /* b edge on t edgecase clipped */
423     {160, 199, 166, 210}, /* t edge on b edgecase */
424     {170, 200, 176, 210}, /* t edge on b edgecase clipped */
425 };
426
427 static const RECT rectangles[] =
428 {
429     {10,   11, 100, 101},
430     {250, 100, 350,  10},
431     {120,  10, 120,  20}, /* zero width */
432     {120,  10, 130,  10}, /* zero height */
433     {120,  40, 121,  41}, /* 1 x 1 */
434     {130,  50, 132,  52}, /* 2 x 2 */
435     {140,  60, 143,  63}, /* 3 x 3 */
436     {150,  70, 154,  74}, /* 4 x 4 */
437     {120,  20, 121,  30}, /* width == 1 */
438     {130,  20, 132,  30}, /* width == 2 */
439     {140,  20, 143,  30}, /* width == 3 */
440     {200,  20, 210,  21}, /* height == 1 */
441     {200,  30, 210,  32}, /* height == 2 */
442     {200,  40, 210,  43}  /* height == 3 */
443 };
444
445 static const BITMAPINFOHEADER dib_brush_header_8888 = {sizeof(BITMAPINFOHEADER), 16, -16, 1, 32, BI_RGB, 0, 0, 0, 0, 0};
446 static const BITMAPINFOHEADER dib_brush_header_24   = {sizeof(BITMAPINFOHEADER), 16, -16, 1, 24, BI_RGB, 0, 0, 0, 0, 0};
447 static const BITMAPINFOHEADER dib_brush_header_555  = {sizeof(BITMAPINFOHEADER), 16, -16, 1, 16, BI_RGB, 0, 0, 0, 0, 0};
448 static const BITMAPINFOHEADER dib_brush_header_8    = {sizeof(BITMAPINFOHEADER), 16, -16, 1,  8, BI_RGB, 0, 0, 0, 0, 0};
449 static const BITMAPINFOHEADER dib_brush_header_4    = {sizeof(BITMAPINFOHEADER), 16, -16, 1,  4, BI_RGB, 0, 0, 0, 0, 0};
450
451 static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits, const char ***sha1)
452 {
453     DWORD dib_size = get_dib_size(bmi);
454     HPEN solid_pen, dashed_pen, orig_pen;
455     HBRUSH solid_brush, dib_brush, orig_brush;
456     INT i, y;
457     HRGN hrgn, hrgn2;
458     BYTE dib_brush_buf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD) + 16 * 16 * sizeof(DWORD)]; /* Enough for 16 x 16 at 32 bpp */
459     BITMAPINFO *brush_bi = (BITMAPINFO*)dib_brush_buf;
460     BYTE *brush_bits;
461
462     memset(bits, 0xcc, dib_size);
463     compare_hash(bmi, bits, sha1, "empty");
464
465     solid_pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0xff));
466     orig_pen = SelectObject(hdc, solid_pen);
467     SetBrushOrgEx(hdc, 0, 0, NULL);
468
469     /* horizontal and vertical lines */
470     for(i = 1; i <= 16; i++)
471     {
472         SetROP2(hdc, i);
473         MoveToEx(hdc, 10, i * 3, NULL);
474         LineTo(hdc, 100, i * 3); /* l -> r */
475         MoveToEx(hdc, 100, 50 + i * 3, NULL);
476         LineTo(hdc, 10, 50 + i * 3); /* r -> l */
477         MoveToEx(hdc, 120 + i * 3, 10, NULL);
478         LineTo(hdc, 120 + i * 3, 100); /* t -> b */
479         MoveToEx(hdc, 170 + i * 3, 100, NULL);
480         LineTo(hdc, 170 + i * 3, 10); /* b -> t */
481     }
482     compare_hash(bmi, bits, sha1, "h and v solid lines");
483     memset(bits, 0xcc, dib_size);
484
485     /* diagonal lines */
486     SetROP2(hdc, R2_COPYPEN);
487     for(i = 0; i < 16; i++)
488     {
489         double s = sin(M_PI * i / 8.0);
490         double c = cos(M_PI * i / 8.0);
491
492         MoveToEx(hdc, 200.5 + 10 * c, 200.5 + 10 * s, NULL);
493         LineTo(hdc, 200.5 + 100 * c, 200.5 + 100 * s);
494     }
495     compare_hash(bmi, bits, sha1, "diagonal solid lines");
496     memset(bits, 0xcc, dib_size);
497
498     for(i = 0; i < sizeof(bias_check) / sizeof(bias_check[0]); i++)
499     {
500         MoveToEx(hdc, bias_check[i].left, bias_check[i].top, NULL);
501         LineTo(hdc, bias_check[i].right, bias_check[i].bottom);
502     }
503     compare_hash(bmi, bits, sha1, "more diagonal solid lines");
504     memset(bits, 0xcc, dib_size);
505
506     /* solid brush PatBlt */
507     solid_brush = CreateSolidBrush(RGB(0x33, 0xaa, 0xff));
508     orig_brush = SelectObject(hdc, solid_brush);
509
510     for(i = 0, y = 10; i < 256; i++)
511     {
512         BOOL ret;
513
514         ret = PatBlt(hdc, 10, y, 100, 10, rop3[i]);
515
516         if(rop_uses_src(rop3[i]))
517             ok(ret == FALSE, "got TRUE for %x\n", rop3[i]);
518         else
519         {
520             ok(ret, "got FALSE for %x\n", rop3[i]);
521             y += 20;
522         }
523
524     }
525     compare_hash(bmi, bits, sha1, "solid patblt");
526     memset(bits, 0xcc, dib_size);
527
528     /* clipped lines */
529     hrgn = CreateRectRgn(10, 10, 200, 20);
530     hrgn2 = CreateRectRgn(100, 100, 200, 200);
531     CombineRgn(hrgn, hrgn, hrgn2, RGN_OR);
532     SetRectRgn(hrgn2, 290, 100, 300, 200);
533     CombineRgn(hrgn, hrgn, hrgn2, RGN_OR);
534     ExtSelectClipRgn(hdc, hrgn, RGN_COPY);
535     DeleteObject(hrgn2);
536
537     for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
538     {
539         MoveToEx(hdc, hline_clips[i].left, hline_clips[i].top, NULL);
540         LineTo(hdc, hline_clips[i].right, hline_clips[i].bottom);
541     }
542     compare_hash(bmi, bits, sha1, "clipped solid hlines");
543     memset(bits, 0xcc, dib_size);
544
545     for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
546     {
547         MoveToEx(hdc, vline_clips[i].left, vline_clips[i].top, NULL);
548         LineTo(hdc, vline_clips[i].right, vline_clips[i].bottom);
549     }
550     compare_hash(bmi, bits, sha1, "clipped solid vlines");
551     memset(bits, 0xcc, dib_size);
552
553     for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
554     {
555         MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
556         LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
557     }
558     compare_hash(bmi, bits, sha1, "clipped solid diagonal lines");
559     memset(bits, 0xcc, dib_size);
560
561     /* clipped PatBlt */
562     for(i = 0; i < sizeof(patblt_clips) / sizeof(patblt_clips[0]); i++)
563     {
564         PatBlt(hdc, patblt_clips[i].left, patblt_clips[i].top,
565                patblt_clips[i].right - patblt_clips[i].left,
566                patblt_clips[i].bottom - patblt_clips[i].top, PATCOPY);
567     }
568     compare_hash(bmi, bits, sha1, "clipped patblt");
569     memset(bits, 0xcc, dib_size);
570
571     /* clipped dashed lines */
572     dashed_pen = CreatePen(PS_DASH, 1, RGB(0xff, 0, 0));
573     SelectObject(hdc, dashed_pen);
574     SetBkMode(hdc, TRANSPARENT);
575     SetBkColor(hdc, RGB(0, 0xff, 0));
576
577     for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
578     {
579         MoveToEx(hdc, hline_clips[i].left, hline_clips[i].top, NULL);
580         LineTo(hdc, hline_clips[i].right, hline_clips[i].bottom);
581     }
582     compare_hash(bmi, bits, sha1, "clipped dashed hlines");
583     memset(bits, 0xcc, dib_size);
584
585     for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
586     {
587         MoveToEx(hdc, hline_clips[i].right - 1, hline_clips[i].bottom, NULL);
588         LineTo(hdc, hline_clips[i].left - 1, hline_clips[i].top);
589     }
590     compare_hash(bmi, bits, sha1, "clipped dashed hlines r -> l");
591     memset(bits, 0xcc, dib_size);
592
593     for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
594     {
595         MoveToEx(hdc, vline_clips[i].left, vline_clips[i].top, NULL);
596         LineTo(hdc, vline_clips[i].right, vline_clips[i].bottom);
597     }
598     compare_hash(bmi, bits, sha1, "clipped dashed vlines");
599     memset(bits, 0xcc, dib_size);
600
601     for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
602     {
603         MoveToEx(hdc, vline_clips[i].right, vline_clips[i].bottom - 1, NULL);
604         LineTo(hdc, vline_clips[i].left, vline_clips[i].top - 1);
605     }
606     compare_hash(bmi, bits, sha1, "clipped dashed vlines b -> t");
607     memset(bits, 0xcc, dib_size);
608
609     for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
610     {
611         MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
612         LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
613     }
614     compare_hash(bmi, bits, sha1, "clipped dashed diagonal lines");
615     memset(bits, 0xcc, dib_size);
616
617     SetBkMode(hdc, OPAQUE);
618
619     for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
620     {
621         MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
622         LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
623     }
624     compare_hash(bmi, bits, sha1, "clipped opaque dashed diagonal lines");
625     memset(bits, 0xcc, dib_size);
626
627     ExtSelectClipRgn(hdc, NULL, RGN_COPY);
628
629     /* 8888 DIB pattern brush */
630
631     brush_bi->bmiHeader = dib_brush_header_8888;
632     brush_bits = (BYTE*)brush_bi + sizeof(BITMAPINFOHEADER);
633     memset(brush_bits, 0, 16 * 16 * sizeof(DWORD));
634     brush_bits[2] = 0xff;
635     brush_bits[6] = 0xff;
636     brush_bits[14] = 0xff;
637     brush_bits[65] = 0xff;
638     brush_bits[69] = 0xff;
639     brush_bits[72] = 0xff;
640
641     dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
642
643     SelectObject(hdc, dib_brush);
644     SetBrushOrgEx(hdc, 1, 1, NULL);
645
646     for(i = 0, y = 10; i < 256; i++)
647     {
648         BOOL ret;
649
650         if(!rop_uses_src(rop3[i]))
651         {
652             ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
653             ok(ret, "got FALSE for %x\n", rop3[i]);
654             y += 25;
655         }
656     }
657     compare_hash(bmi, bits, sha1, "top-down 8888 dib brush patblt");
658     memset(bits, 0xcc, dib_size);
659
660     SelectObject(hdc, orig_brush);
661     DeleteObject(dib_brush);
662
663     /* 8888 bottom-up DIB pattern brush */
664
665     brush_bi->bmiHeader.biHeight = -brush_bi->bmiHeader.biHeight;
666
667     dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
668
669     SelectObject(hdc, dib_brush);
670
671     /* This used to set the x origin to 100 as well, but
672        there's a Windows bug for 24 bpp where the brush's x offset
673        is incorrectly calculated for rops that involve both D and P */
674     SetBrushOrgEx(hdc, 4, 100, NULL);
675
676     for(i = 0, y = 10; i < 256; i++)
677     {
678         BOOL ret;
679
680         if(!rop_uses_src(rop3[i]))
681         {
682             ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
683             ok(ret, "got FALSE for %x\n", rop3[i]);
684             y += 25;
685         }
686     }
687     compare_hash(bmi, bits, sha1, "bottom-up 8888 dib brush patblt");
688     memset(bits, 0xcc, dib_size);
689
690     /* 24 bpp dib pattern brush */
691
692     brush_bi->bmiHeader = dib_brush_header_24;
693     brush_bits = (BYTE*)brush_bi + sizeof(BITMAPINFOHEADER);
694     memset(brush_bits, 0, 16 * 16 * 3);
695     brush_bits[0] = brush_bits[3] = brush_bits[6] = brush_bits[8] = 0xff;
696     brush_bits[49] = brush_bits[52] = 0xff;
697
698     dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
699
700     SelectObject(hdc, dib_brush);
701     SetBrushOrgEx(hdc, 1, 1, NULL);
702
703     for(i = 0, y = 10; i < 256; i++)
704     {
705         BOOL ret;
706
707         if(!rop_uses_src(rop3[i]))
708         {
709             ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
710             ok(ret, "got FALSE for %x\n", rop3[i]);
711             y += 25;
712         }
713     }
714     compare_hash(bmi, bits, sha1, "top-down 24 bpp brush patblt");
715     memset(bits, 0xcc, dib_size);
716
717     SelectObject(hdc, orig_brush);
718     DeleteObject(dib_brush);
719
720     /* 555 dib pattern brush */
721
722     brush_bi->bmiHeader = dib_brush_header_555;
723     brush_bits = (BYTE*)brush_bi + sizeof(BITMAPINFOHEADER);
724     memset(brush_bits, 0, 16 * 16 * sizeof(WORD));
725     brush_bits[0] = brush_bits[1] = 0xff;
726     brush_bits[32] = brush_bits[34] = 0x7c;
727
728     dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
729
730     SelectObject(hdc, dib_brush);
731     SetBrushOrgEx(hdc, 1, 1, NULL);
732
733     for(i = 0, y = 10; i < 256; i++)
734     {
735         BOOL ret;
736
737         if(!rop_uses_src(rop3[i]))
738         {
739             ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
740             ok(ret, "got FALSE for %x\n", rop3[i]);
741             y += 25;
742         }
743     }
744     compare_hash(bmi, bits, sha1, "top-down 555 dib brush patblt");
745     memset(bits, 0xcc, dib_size);
746
747     SelectObject(hdc, orig_brush);
748     DeleteObject(dib_brush);
749
750     SetBrushOrgEx(hdc, 0, 0, NULL);
751
752     /* 8 bpp dib pattern brush */
753
754     brush_bi->bmiHeader = dib_brush_header_8;
755     brush_bi->bmiHeader.biClrUsed = 3;
756     memset(brush_bi->bmiColors, 0, brush_bi->bmiHeader.biClrUsed * sizeof(RGBQUAD));
757     brush_bi->bmiColors[0].rgbRed = 0xff;
758     brush_bi->bmiColors[1].rgbRed = 0xff;
759     brush_bi->bmiColors[1].rgbGreen = 0xff;
760     brush_bi->bmiColors[1].rgbBlue = 0xff;
761
762     brush_bits = (BYTE*)brush_bi + sizeof(BITMAPINFOHEADER) + brush_bi->bmiHeader.biClrUsed * sizeof(RGBQUAD);
763     memset(brush_bits, 0, 16 * 16 * sizeof(BYTE));
764     brush_bits[0] = brush_bits[1] = 1;
765     brush_bits[16] = brush_bits[17] = 2;
766     brush_bits[32] = brush_bits[33] = 6;
767
768     dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
769
770     SelectObject(hdc, dib_brush);
771     SetBrushOrgEx(hdc, 1, 1, NULL);
772
773     for(i = 0, y = 10; i < 256; i++)
774     {
775         BOOL ret;
776
777         if(!rop_uses_src(rop3[i]))
778         {
779             ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
780             ok(ret, "got FALSE for %x\n", rop3[i]);
781             y += 25;
782         }
783     }
784     compare_hash(bmi, bits, sha1, "top-down 8 bpp dib brush patblt");
785     memset(bits, 0xcc, dib_size);
786
787     SelectObject(hdc, orig_brush);
788     DeleteObject(dib_brush);
789
790     /* 4 bpp dib pattern brush */
791
792     brush_bi->bmiHeader = dib_brush_header_4;
793     dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
794
795     SelectObject(hdc, dib_brush);
796     SetBrushOrgEx(hdc, 1, 1, NULL);
797
798     for(i = 0, y = 10; i < 256; i++)
799     {
800         BOOL ret;
801
802         if(!rop_uses_src(rop3[i]))
803         {
804             ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
805             ok(ret, "got FALSE for %x\n", rop3[i]);
806             y += 25;
807         }
808     }
809     compare_hash(bmi, bits, sha1, "top-down 4 bpp dib brush patblt");
810     memset(bits, 0xcc, dib_size);
811
812     SelectObject(hdc, orig_brush);
813     SetBrushOrgEx(hdc, 0, 0, NULL);
814
815     /* Rectangle */
816
817     SelectObject(hdc, solid_pen);
818     SelectObject(hdc, solid_brush);
819
820     for(i = 0; i < sizeof(rectangles)/sizeof(rectangles[0]); i++)
821     {
822         Rectangle(hdc, rectangles[i].left, rectangles[i].top, rectangles[i].right, rectangles[i].bottom);
823     }
824
825     SelectObject(hdc, dashed_pen);
826     for(i = 0; i < sizeof(rectangles)/sizeof(rectangles[0]); i++)
827     {
828         Rectangle(hdc, rectangles[i].left, rectangles[i].top + 150, rectangles[i].right, rectangles[i].bottom + 150);
829     }
830
831     compare_hash(bmi, bits, sha1, "rectangles");
832     memset(bits, 0xcc, dib_size);
833     SelectObject(hdc, solid_pen);
834
835     /* PaintRgn */
836
837     PaintRgn(hdc, hrgn);
838     compare_hash(bmi, bits, sha1, "PaintRgn");
839     memset(bits, 0xcc, dib_size);
840
841     /* RTL rectangles */
842
843     if( !pSetLayout )
844     {
845         win_skip("Don't have SetLayout\n");
846         (*sha1)++;
847     }
848     else
849     {
850         pSetLayout(hdc, LAYOUT_RTL);
851         PaintRgn(hdc, hrgn);
852         PatBlt(hdc, 10, 250, 10, 10, PATCOPY);
853         Rectangle(hdc, 100, 250, 110, 260);
854         compare_hash(bmi, bits, sha1, "rtl");
855         memset(bits, 0xcc, dib_size);
856
857         pSetLayout(hdc, LAYOUT_LTR);
858     }
859
860     SelectObject(hdc, orig_brush);
861     SelectObject(hdc, orig_pen);
862     DeleteObject(hrgn);
863     DeleteObject(dib_brush);
864     DeleteObject(dashed_pen);
865     DeleteObject(solid_brush);
866     DeleteObject(solid_pen);
867 }
868
869 static void test_simple_graphics(void)
870 {
871     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
872     BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
873     DWORD *bit_fields = (DWORD*)(bmibuf + sizeof(BITMAPINFOHEADER));
874     HDC mem_dc;
875     BYTE *bits;
876     HBITMAP dib, orig_bm;
877     const char **sha1;
878     DIBSECTION ds;
879
880     mem_dc = CreateCompatibleDC(NULL);
881
882     /* a8r8g8b8 */
883     trace("8888\n");
884     memset(bmi, 0, sizeof(bmibuf));
885     bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
886     bmi->bmiHeader.biHeight = 512;
887     bmi->bmiHeader.biWidth = 512;
888     bmi->bmiHeader.biBitCount = 32;
889     bmi->bmiHeader.biPlanes = 1;
890     bmi->bmiHeader.biCompression = BI_RGB;
891
892     dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
893     ok(dib != NULL, "ret NULL\n");
894     ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
895     ok(ds.dsBitfields[0] == 0, "got %08x\n", ds.dsBitfields[0]);
896     ok(ds.dsBitfields[1] == 0, "got %08x\n", ds.dsBitfields[1]);
897     ok(ds.dsBitfields[2] == 0, "got %08x\n", ds.dsBitfields[2]);
898     ok(ds.dsBmih.biCompression == BI_RGB ||
899        broken(ds.dsBmih.biCompression == BI_BITFIELDS), /* nt4 sp1 and 2 */
900        "got %x\n", ds.dsBmih.biCompression);
901
902     orig_bm = SelectObject(mem_dc, dib);
903
904     sha1 = sha1_graphics_a8r8g8b8;
905     draw_graphics(mem_dc, bmi, bits, &sha1);
906
907     SelectObject(mem_dc, orig_bm);
908     DeleteObject(dib);
909
910     /* a8r8g8b8 - bitfields.  Should be the same as the regular 32 bit case.*/
911     trace("8888 - bitfields\n");
912     bmi->bmiHeader.biBitCount = 32;
913     bmi->bmiHeader.biCompression = BI_BITFIELDS;
914     bit_fields[0] = 0xff0000;
915     bit_fields[1] = 0x00ff00;
916     bit_fields[2] = 0x0000ff;
917
918     dib = CreateDIBSection(mem_dc, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
919     ok(dib != NULL, "ret NULL\n");
920     ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
921     ok(ds.dsBitfields[0] == 0xff0000, "got %08x\n", ds.dsBitfields[0]);
922     ok(ds.dsBitfields[1] == 0x00ff00, "got %08x\n", ds.dsBitfields[1]);
923     ok(ds.dsBitfields[2] == 0x0000ff, "got %08x\n", ds.dsBitfields[2]);
924     ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
925
926     orig_bm = SelectObject(mem_dc, dib);
927
928     sha1 = sha1_graphics_a8r8g8b8;
929     draw_graphics(mem_dc, bmi, bits, &sha1);
930
931     SelectObject(mem_dc, orig_bm);
932     DeleteObject(dib);
933
934     /* a8b8g8r8 - bitfields. */
935     trace("a8b8g8r8 - bitfields\n");
936     bmi->bmiHeader.biBitCount = 32;
937     bmi->bmiHeader.biCompression = BI_BITFIELDS;
938     bit_fields[0] = 0x0000ff;
939     bit_fields[1] = 0x00ff00;
940     bit_fields[2] = 0xff0000;
941
942     dib = CreateDIBSection(mem_dc, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
943     ok(dib != NULL, "ret NULL\n");
944     ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
945     ok(ds.dsBitfields[0] == 0x0000ff, "got %08x\n", ds.dsBitfields[0]);
946     ok(ds.dsBitfields[1] == 0x00ff00, "got %08x\n", ds.dsBitfields[1]);
947     ok(ds.dsBitfields[2] == 0xff0000, "got %08x\n", ds.dsBitfields[2]);
948     ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
949
950     orig_bm = SelectObject(mem_dc, dib);
951
952     sha1 = sha1_graphics_a8b8g8r8;
953     draw_graphics(mem_dc, bmi, bits, &sha1);
954
955     SelectObject(mem_dc, orig_bm);
956     DeleteObject(dib);
957
958     /* 24 */
959     trace("24\n");
960     bmi->bmiHeader.biBitCount = 24;
961     bmi->bmiHeader.biCompression = BI_RGB;
962
963     dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
964     ok(dib != NULL, "ret NULL\n");
965     orig_bm = SelectObject(mem_dc, dib);
966
967     sha1 = sha1_graphics_24;
968     draw_graphics(mem_dc, bmi, bits, &sha1);
969
970     SelectObject(mem_dc, orig_bm);
971     DeleteObject(dib);
972
973     /* r5g5b5 */
974     trace("555\n");
975     bmi->bmiHeader.biBitCount = 16;
976     bmi->bmiHeader.biCompression = BI_RGB;
977
978     dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
979     ok(dib != NULL, "ret NULL\n");
980     ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
981     ok(ds.dsBitfields[0] == 0x7c00, "got %08x\n", ds.dsBitfields[0]);
982     ok(ds.dsBitfields[1] == 0x03e0, "got %08x\n", ds.dsBitfields[1]);
983     ok(ds.dsBitfields[2] == 0x001f, "got %08x\n", ds.dsBitfields[2]);
984 todo_wine
985     ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
986
987     orig_bm = SelectObject(mem_dc, dib);
988
989     sha1 = sha1_graphics_r5g5b5;
990     draw_graphics(mem_dc, bmi, bits, &sha1);
991
992     SelectObject(mem_dc, orig_bm);
993     DeleteObject(dib);
994
995     /* r4g4b4 */
996     trace("444\n");
997     bmi->bmiHeader.biBitCount = 16;
998     bmi->bmiHeader.biCompression = BI_BITFIELDS;
999     bit_fields[0] = 0x0f00;
1000     bit_fields[1] = 0x00f0;
1001     bit_fields[2] = 0x000f;
1002     dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1003     ok(dib != NULL, "ret NULL\n");
1004     ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
1005     ok(ds.dsBitfields[0] == 0x0f00, "got %08x\n", ds.dsBitfields[0]);
1006     ok(ds.dsBitfields[1] == 0x00f0, "got %08x\n", ds.dsBitfields[1]);
1007     ok(ds.dsBitfields[2] == 0x000f, "got %08x\n", ds.dsBitfields[2]);
1008     ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
1009
1010     orig_bm = SelectObject(mem_dc, dib);
1011
1012     sha1 = sha1_graphics_r4g4b4;
1013     draw_graphics(mem_dc, bmi, bits, &sha1);
1014
1015     SelectObject(mem_dc, orig_bm);
1016     DeleteObject(dib);
1017
1018     /* 8 */
1019     trace("8\n");
1020     bmi->bmiHeader.biBitCount = 8;
1021     bmi->bmiHeader.biCompression = BI_RGB;
1022     bmi->bmiHeader.biClrUsed = 5;
1023     bmi->bmiColors[0].rgbRed = 0xff;
1024     bmi->bmiColors[0].rgbGreen = 0xff;
1025     bmi->bmiColors[0].rgbBlue = 0xff;
1026     bmi->bmiColors[1].rgbRed = 0;
1027     bmi->bmiColors[1].rgbGreen = 0;
1028     bmi->bmiColors[1].rgbBlue = 0;
1029     bmi->bmiColors[2].rgbRed = 0xff;
1030     bmi->bmiColors[2].rgbGreen = 0;
1031     bmi->bmiColors[2].rgbBlue = 0;
1032     bmi->bmiColors[3].rgbRed = 0;
1033     bmi->bmiColors[3].rgbGreen = 0xff;
1034     bmi->bmiColors[3].rgbBlue = 0;
1035     bmi->bmiColors[4].rgbRed = 0;
1036     bmi->bmiColors[4].rgbGreen = 0;
1037     bmi->bmiColors[4].rgbBlue = 0xff;
1038
1039     dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1040     ok(dib != NULL, "ret NULL\n");
1041
1042     orig_bm = SelectObject(mem_dc, dib);
1043
1044     sha1 = sha1_graphics_8;
1045     draw_graphics(mem_dc, bmi, bits, &sha1);
1046
1047     SelectObject(mem_dc, orig_bm);
1048     DeleteObject(dib);
1049
1050     /* 4 */
1051     trace("4\n");
1052     bmi->bmiHeader.biBitCount = 4;
1053
1054     dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1055     ok(dib != NULL, "ret NULL\n");
1056
1057     orig_bm = SelectObject(mem_dc, dib);
1058
1059     sha1 = sha1_graphics_4;
1060     draw_graphics(mem_dc, bmi, bits, &sha1);
1061
1062     SelectObject(mem_dc, orig_bm);
1063     DeleteObject(dib);
1064
1065     DeleteDC(mem_dc);
1066 }
1067
1068 START_TEST(dib)
1069 {
1070     HMODULE mod = GetModuleHandleA("gdi32.dll");
1071     pSetLayout = (void *)GetProcAddress( mod, "SetLayout" );
1072
1073     CryptAcquireContextW(&crypt_prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
1074
1075     test_simple_graphics();
1076
1077     CryptReleaseContext(crypt_prov, 0);
1078 }