gdi32/tests: Remove win9x hacks.
[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     "87f6b6a19f021ca5912d285e14ce2ff9474d79f3",
101     "e2a8eef4aeda3a0f6c950075acba38f1f9e0814d",
102     "8b66f14d51ecdeea12bc993302bb9b7d3ec085a1",
103     "7da9dd3d40d44d92deb9883fb7110443c2d5769a",
104     "e358efb1c11172e40855de620bdb8a8e545cd790",
105     "9e0c2596c6ecb4f1bc97b18ec3ca493d37626608",
106     NULL
107 };
108
109 static const char *sha1_graphics_a8b8g8r8[] =
110 {
111     "a3cadd34d95d3d5cc23344f69aab1c2e55935fcf",
112     "e0bc877697093ed440e125154e247ca9d65e933c",
113     "c6d7faf5a502299f99d59eef3f7650bd63dbe108",
114     "9d8c05c3ebd786e7d052418e905a80a64bf7853d",
115     "3da12af0a810fd993fa3dbe23328a4fcd2b6c92a",
116     "b91c8f21cc4d7994abc551feff5b6927d267a9db",
117     "d49dd2c6a37e975b6dc3d201ccc217a788b30284",
118     "ca6753f9eb44529cf8c67cd6abcd4ed1ef758904",
119     "18c3ae944e0afb6c43c21cde093ddb22a27611e4",
120     "b753ebb39d90210cc717f57b53dd439f7de6b077",
121     "38c017dd1fff26b492a57e09f3ce2c4370faf225",
122     "94368cea5033b435454daa56d55546310675131e",
123     "bf57a6a37fb107d29ed3d45695919887abcb7902",
124     "3db0f8bcca3d94920aa57be6321202b8c3c08822",
125     "1f1fc165a4dae7ba118ddccb58a279bfe3876b0a",
126     "8e09abb108e137c99527ab4c9bd07d95b9254bbb",
127     "b0178632775d29bec2b16de7b9b8287115c40d0f",
128     "ca7e859647b9498b53fdd92543ad8aea98ff46f3",
129     "3369889a67d6c79a24ee15f7d14374f9995215e4",
130     "473a1fd07df800c87a5d3286b642ace10c61c6af",
131     "10cd25a0ed5cd8f978d7d68236f81d949b938e84",
132     "b8951d2b20518fd129e5113a5f429626893913bf",
133     "4851c5b7d5bc18590e787c0c218a592ef504e738",
134     "9aa506e3df33e0d5298755aa4144e10eb4b5adcf",
135     "abdf003699364fe45fab7dc61e67c606d0063b40",
136     "89abaadff4e68c738cf9251c51e3609564843381",
137     "f6aa3f907f620b9f3493f03cb3b4b292df3a9545",
138     NULL
139 };
140
141 static const char *sha1_graphics_24[] =
142 {
143     "e993b15c9bd14fb45a15310450b7083c44e42665",
144     "edbd7bab3d957fbc85e89612197cf918f5f5af20",
145     "6a7efb3b6e0b49336df1bd2937ca09a11d976531",
146     "236eb5ca9da70ec7cc719cd2fd291bab14000257",
147     "f98023c7cd8c068f2d7a77ce3600004b90ea12d6",
148     "5c4cb9cea2226fc671bb4a11f8253343ee94bb4b",
149     "fd4be592483623dbc800fe28210a1f0daa71999b",
150     "788b8de98c47974fa9f232a6042ae4ca546ddb7d",
151     "a8772e6c44ba633fb384a7c4b50b435f1406107e",
152     "883bc8f305c602edca785e21cd00f488583fb13f",
153     "3bac4e80993f49dc3926e30524115fca9d7a8026",
154     "91369e35be29059a0665782541db4c8b324c6bb2",
155     "0fa8cf332a56bb6d7e14e85861fdd60f51d70501",
156     "593d694cdcc8349b3bfc8257041dbcb27e61da45",
157     "1036b91d93e31cd1d4740d0c8642e115e5a38188",
158     "1898073cdb35ca4d2b21bba933ac16a0b4297317",
159     "5068bff794553cf5a3145ae407c9a2984357844c",
160     "413a7989969c229dee4ab1798362f32f96cf0a10",
161     "0bb222e540b82720d4971e4a2fc626899af03e03",
162     "adc20832d8c43f1cf372d8392535492013cd2306",
163     "45649794dcbcabda487f66f7a80fc1bec79047a1",
164     "367c2dc1e91ff9ea0e984d6fb3000cfb4e0ae7e9",
165     "b4df692ac70a5f9f303270df4641ab014c6cbf46",
166     "8bc3128ba47891366fd7b02fde7ca19100e64b9f",
167     "e649e00efe7fea1eb8b17f7867fe089e5270c44b",
168     "a0bffbbfb0adf6f188479c88da04e25d76ab4822",
169     "92a1ab214dd8027c407814420449119466c92840",
170     NULL
171 };
172
173 static const char *sha1_graphics_r5g5b5[] =
174 {
175     "2a2ab8b3c019e70b788ade028b0e9e53ffc529ae",
176     "847005cf7371f511bcc837251cde07b1796f6113",
177     "a8f75743a930843ec14d516cd048b6e0468e5d89",
178     "d094f51ce9b9daa9c1d9594ea88be2a2db651459",
179     "cf3928e240c9149788e1635b115a4e5baea0dd8f",
180     "a9034a905daa91757b4f63345c0e40638cd53ca8",
181     "15ee915d989e49bb9bab5b834d8f355bd067cd8f",
182     "99474fecf11df7b7035c35be6b8b697be9889418",
183     "cbc2898717f97ebb07c0c7cc04abde936dc5b584",
184     "29c896b591fdf4ddd23e5c0da1818c37e4686d94",
185     "4b5b275d33c1ebfe5bdc61df2ad125e865b800fa",
186     "92df731fa1f89550d9d4f7ea36c13f2e57c4b02a",
187     "420e39ff3bdd04c4b6cc2c98e99cb7993c7a0de5",
188     "1fabf0fdd046857b1974e31c1c1764fa9d1a762f",
189     "449092689226a1172b6086ba1181d6b6d6499f26",
190     "1a92a60f190d33ef06d9decb56fd3fdd33f3af03",
191     "e61f5978c2e28c0c6d8f5eefe0f840c975586efc",
192     "897d16f4d6a6ddad685d23ed7828d4f676539b75",
193     "9d21bcfdeaf1ca5d47eb823bdefc24d7a95f4f56",
194     "6daaf945a955928c5c124c880522ca4634fb2343",
195     "12a288390d16e1efa99d4185301de48a4d433b14",
196     "ea92af2538b76f41a3a03eaa11ac395c9b6197c4",
197     "3a50ce21b3563a604b4fc9f247a30f5a981f1ba6",
198     "d7d97e28ed316f6596c737eb83baa5948d86b673",
199     "ecc2991277d7314f55b00e0f284ae3703aeef81e",
200     "656bf3b7121bcd620a0a3ad488f0d66604824577",
201     "d7d8493b5fa7a3a8323d6ac84245093a79f052c1",
202     NULL
203 };
204
205 static const char *sha1_graphics_r4g4b4[] =
206 {
207     "2a2ab8b3c019e70b788ade028b0e9e53ffc529ae",
208     "cfa0ab83ee93283ad914c3748f0532da1697af1d",
209     "8bd18697d1ef27492805667a0bc956343ac08667",
210     "e8501c830321584474654f90e40eaf27dc21e6a8",
211     "d95ab10fcfb8447b41742e89f1ae8cd297a32fc4",
212     "821177710961d2cb5f7e7dfc0e06e767b6042753",
213     "667124365ffadeea1d8791bedda77a0c7b898de8",
214     "c9f23e684b600dea17575b4b17175fbd9106c3a9",
215     "7678876e50eae35d1eaa096aae25afaa0b864bf3",
216     "fb52b0c373a5f2a60b981604b120962942d2447a",
217     "5ab8dd07436681d762fa04ad7c6d71291c488924",
218     "0167981d9e1490a2ebd396ff7582f0943aa8e1b8",
219     "115a6bd382410a4a1d3c1fa71d8bf02536863e38",
220     "65c6d1228e3b6d63d42647f14217bc1658b70d9a",
221     "25fcb75aa687aac35b8f72640889fe92413e00c5",
222     "3bddf9d53e89560b083302b146cd33791b13d941",
223     "a81504498c7a7bb46340ce74476a42f70f2730b1",
224     "e61a4f2657a444d8c49f84fb944f9f847667bf2b",
225     "32b6e0aa79b7e96cd0ab2da167f6463c011023a8",
226     "1d283aa4d2b2114f7809fe59357d590c7c779aa7",
227     "29640e2ddd2d3016da14507c3ce9b2ce32f39bb4",
228     "57ebf8becac1524543da120e88e9cc57ecfdec49",
229     "d591232bbc2592462c819a9486750f64180518fd",
230     "0e183a4c30b3da345129cffe33fe0fc593d8666b",
231     "f14d9a4bd8a365b7c8f068a0dad481b6eb2b178b",
232     "8933450132bf949ba4bc28626968425b5ed2867d",
233     "9928a8f28a66c00069a124f7171b248817005763",
234     NULL
235 };
236
237 static const char *sha1_graphics_8[] =
238 {
239     "41728d7ff2bb425b5fc06521adeabf6cc73136f3",
240     "512246d4886ab889a090b167ba194577cb95272e",
241     "921e852d4564cb9e5ac15ff68b5207bebea871d1",
242     "9636b0ebefc443ea11949ccd28f6ca454277dd41",
243     "aa9050da55e6b6957c60b7d603fce539cb5c0048",
244     "e2b93aca15fb1233ac09a713dced1f4cd950b1e4",
245     "3e3a603fc26cc305aa27f88da7d2a3b0073877d8",
246     "390b2bf70daba36310683f46af9cd50b9a061396",
247     "82d21737e9a7247397a6c983a9b6d9a0452dd74d",
248     "2a8460af91675e01cbe9384eb6cd3eb2cb420960",
249     "1af53b1218ee9844fcda891b836d42f6b2f66bd5",
250     "da1cc34a9d9b779fc7849e03e214096026506464",
251     "5ba8f99ca034666effa556748c49a0f5a015125f",
252     "b67ba2f55659c75ac72c1112494461bb3086e1a4",
253     "73e2859ce849f756f954718ce3c90f02e31712b6",
254     "b1dff0f5dd233b44ee568878c5d3f8ae1d80c6d9",
255     "1f27dc1a1316fb7a4a78fe40fcd4bdae3aaad218",
256     "6e375e1485a1e45ac6ab10af49645d5fb2e76dff",
257     "cfc67c325c7cdf96d90af9b3cceb8d0504cbb3b0",
258     "7262364067e03c7fa498af1d59d228d6c63b460e",
259     "5241241a355a667ef0834049adf4218e8b3f16b8",
260     "db22d666690948eb966f75b796c72c7150a5c4b9",
261     "1f13ea0034db4b0ffa4ddcff9664fd892058f9cd",
262     "3caf512cfddfd463d0750cfe3cadb58548eb2ae8",
263     "4e5e7d5fd64818b2b3d3e793c88f603b699d2f0f",
264     "c4efce8f7ed2d380ea5dc6fe1ef8448a27827532",
265     "bdc0a354635b879871077c5b712570e469863c99",
266     NULL
267 };
268
269 static const char *sha1_graphics_4[] =
270 {
271     "fa867e2976a549ecd3b1fa67df54963232fcef8c",
272     "256d742b4da96b373b4fa5663d0ad3b5faab5c8e",
273     "d96d8f4232b930bccd53b903b5efaf8c0bdb16f4",
274     "9401799e6116c35e5f0e5bdca07ea25316757a72",
275     "482ae2b0ef1d64752b5ef11cc7f35a33eb55d07c",
276     "dcfb3e01100b41c0f75a1c5f84b6de6b90138281",
277     "2505598845fa026ea7187582461efbf06cb6904f",
278     "3981a19363beca8f28d32a5928ac296fd22a5296",
279     "01404024ebb2c266d17d734059524d874491650f",
280     "c87bbff3f83b8ec11bb03cfa9bc9ee5166c4c7ef",
281     "f35c5d62853be78c5d39fb2f45200dc262aa8e18",
282     "46e94a55f5f58a6b915078d8ffdc725f53aab516",
283     "665bbbc749a5ffeedc0d62aef0661a5ce845b017",
284     "1f26a01730f67d40ea711a50d9d801bac15a642e",
285     "3b53d24178cfacba53103a44dfd5d072b15a6781",
286     "c52cfd57f26037723d37192722fc3a217f280c9e",
287     "e34da6500cf2e424d980714d92737cf6c31a7bda",
288     "d17f4358ae529f920960ed89e535902ee13b0033",
289     "0f44e12ecd1ea7e39433890443626d4fc35204a4",
290     "eb38683e812fd13dca971ba8f4cfd2b6820d3524",
291     "73bbc83f88f1aaa6df0158b63e70bb3165163163",
292     "0dc2690a5c58a2907a8ab06693ebfab6698172eb",
293     "39c16648cf6c261be71a33cec41867f28e119b94",
294     "26ad5116562e7b58c76a26eaf521e2e40899e944",
295     "1bcc54eaf8e3c2b7c59ecccb23c240181d7ba8b8",
296     "4f827ca6927f15191588456f985bf29d2a3b3c24",
297     "e7de769c3d12ea9dd223bef4881c578823bec67e",
298     NULL
299 };
300
301 static const char *sha1_graphics_1[] =
302 {
303     "23366004515f3bc46796ea505d748f8d0f97fbe1",
304     "ad674a4104c6a1eacaee8f20effdfe31775b4409",
305     "a7cc69f957d7b533a0a330859a143d701daac73c",
306     "a955bf088c5edb129289ce65caace48ec95632e4",
307     "5316d3c558c254479883133cf58cd07ab521d3f0",
308     "fcbfdb5d60716ea05f2d1896fae7a6e7a8249d35",
309     "2c140b39cc8d21358fded8959cd655f03d7f0f89",
310     "121423a38b4ac4743bd516e0a7e88a3863796313",
311     "7c17635c6c7f62dbf8fd4773d0c503358553d2c7",
312     "21d5d9e47bb07de2cf7bc99b7725390d03a6cde6",
313     "f69ee65ea25676429a28eea79b5b9cb9206b8d01",
314     "39ff81f77ef4ee772367ed1a63785987c060126e",
315     "4c686508a994ca4c7a0a73b8c0fe52423c180d9c",
316     "b0cc1f5e244ae0c0835a9866a46abdfcd56d1cb1",
317     "7ddf19df5bbdf4475b6ec1bc042425e382502864",
318     "144c9a846e5e37ac6efd5ed3a97ec231479e8fca",
319     "c5ffc59048bf786b5646ad6226cd8633965de9ef",
320     "40fadc2d24c713b04ff96f7dc26e70e85f26c55e",
321     "400a21caa01e015096ee1afcf1b54e7f8ec515bd",
322     "0ff4b49797e30e3555aab45219adf449a9a560ff",
323     "280327328ca940c212ce24fe72e0b00014072767",
324     "144c9a846e5e37ac6efd5ed3a97ec231479e8fca",
325     "b85463875f755b85f1464b1b6275912bcbad6c9f",
326     "816f200969feecc788b61dfeecf05b1790984401",
327     "a4964d8bbf80fe785f906bc0f7c5b113242a58fc",
328     "a5d204cc7342d40b765ca042f8668e22601c4ff9",
329     "adb2818f6d3845dd140bc0f9abdbaa89d2a8c3de",
330     "0a76e0121facb103857130bc6e12185ad77fc3fa",
331     "02aede714773d654d0fc2f640afaa133ec718ad5",
332     "13cc63972aee4f6ae27091a8af18de01f1d3a5da",
333     "3bb745ccb08402ce6fac6ee26fb8d7aad2dba27e",
334     "b26699f62661e16a1dc452d24c88ce363a1f2998",
335     "4d95c3d1e170f004c80aa8c52feafb8e0e90760e",
336     "c14832e69ec3585c15987b3d69d5007236fa9814",
337     "e44ea620b0c47125a34193537ab9d219a52ad028",
338     "d1e6091caa4482d3142df3b958606c41ebf4698e",
339     "07c1116d8286fb665a1005de220eadc3d5999aaf",
340     "4afb0649488f6e6f7d3a2b8bf438d82f2c88f4d1",
341     "f2fe295317e795a88edd0b2c52618b8cb0e7f2ce",
342     "ffc78c075d4be66806f6c59180772d5eed963dc0",
343     NULL
344 };
345
346 static inline DWORD get_stride(BITMAPINFO *bmi)
347 {
348     return ((bmi->bmiHeader.biBitCount * bmi->bmiHeader.biWidth + 31) >> 3) & ~3;
349 }
350
351 static inline DWORD get_dib_size(BITMAPINFO *bmi)
352 {
353     return get_stride(bmi) * abs(bmi->bmiHeader.biHeight);
354 }
355
356 static char *hash_dib(BITMAPINFO *bmi, void *bits)
357 {
358     DWORD dib_size = get_dib_size(bmi);
359     HCRYPTHASH hash;
360     char *buf;
361     BYTE hash_buf[20];
362     DWORD hash_size = sizeof(hash_buf);
363     int i;
364     static const char *hex = "0123456789abcdef";
365
366     if(!crypt_prov) return NULL;
367
368     if(!CryptCreateHash(crypt_prov, CALG_SHA1, 0, 0, &hash)) return NULL;
369
370     CryptHashData(hash, bits, dib_size, 0);
371
372     CryptGetHashParam(hash, HP_HASHVAL, NULL, &hash_size, 0);
373     if(hash_size != sizeof(hash_buf)) return NULL;
374
375     CryptGetHashParam(hash, HP_HASHVAL, hash_buf, &hash_size, 0);
376     CryptDestroyHash(hash);
377
378     buf = HeapAlloc(GetProcessHeap(), 0, hash_size * 2 + 1);
379
380     for(i = 0; i < hash_size; i++)
381     {
382         buf[i * 2] = hex[hash_buf[i] >> 4];
383         buf[i * 2 + 1] = hex[hash_buf[i] & 0xf];
384     }
385     buf[i * 2] = '\0';
386
387     return buf;
388 }
389
390 static void compare_hash_broken_todo(BITMAPINFO *bmi, BYTE *bits, const char ***sha1, const char *info, int num_broken, BOOL todo)
391 {
392     char *hash = hash_dib(bmi, bits);
393     BOOL ok_cond;
394     int i;
395
396     if(!hash)
397     {
398         skip("SHA1 hashing unavailable on this platform\n");
399         return;
400     }
401
402     for(i = 0; i <= num_broken; i++)
403     {
404         if((*sha1)[i] == NULL)
405         {
406             ok((*sha1)[i] != NULL, "missing hash, got \"%s\",\n", hash);
407             return;
408         }
409     }
410
411     ok_cond = !strcmp(hash, **sha1);
412
413     for(i = 1; i <= num_broken; i++)
414         ok_cond = ok_cond || broken( !strcmp(hash, (*sha1)[i]) );
415
416     if(todo)
417         todo_wine ok( ok_cond, "%d: %s: expected hash %s got %s\n",
418                       bmi->bmiHeader.biBitCount, info, **sha1, hash );
419     else
420         ok( ok_cond, "%d: %s: expected hash %s got %s\n",
421             bmi->bmiHeader.biBitCount, info, **sha1, hash );
422
423     *sha1 += num_broken + 1;
424
425     HeapFree(GetProcessHeap(), 0, hash);
426 }
427
428 static void compare_hash(BITMAPINFO *bmi, BYTE *bits, const char ***sha1, const char *info)
429 {
430     compare_hash_broken_todo(bmi, bits, sha1, info, 0, FALSE);
431 }
432
433 static const RECT bias_check[] =
434 {
435     {100, 100, 200, 150},
436     {100, 100, 150, 200},
437     {100, 100,  50, 200},
438     {100, 100,   0, 150},
439     {100, 100,   0,  50},
440     {100, 100,  50,   0},
441     {100, 100, 150,   0},
442     {100, 100, 200,  50}
443 };
444
445 static const RECT hline_clips[] =
446 {
447     {120, 120, 140, 120}, /* unclipped */
448     {100, 122, 140, 122}, /* l edgecase */
449     { 99, 124, 140, 124}, /* l edgecase clipped */
450     {120, 126, 200, 126}, /* r edgecase */
451     {120, 128, 201, 128}, /* r edgecase clipped */
452     { 99, 130, 201, 130}, /* l and r clipped */
453     {120, 100, 140, 100}, /* t edgecase */
454     {120,  99, 140,  99}, /* t edgecase clipped */
455     {120, 199, 140, 199}, /* b edgecase */
456     {120, 200, 140, 200}, /* b edgecase clipped */
457     {120, 132, 310, 132}, /* inside two clip rects */
458     { 10, 134, 101, 134}, /* r end on l edgecase */
459     { 10, 136, 100, 136}, /* r end on l edgecase clipped */
460     {199, 138, 220, 138}, /* l end on r edgecase */
461     {200, 140, 220, 140}  /* l end on r edgecase clipped */
462 };
463
464 static const RECT vline_clips[] =
465 {
466     {120, 120, 120, 140}, /* unclipped */
467     {100, 120, 100, 140}, /* l edgecase */
468     { 99, 120,  99, 140}, /* l edgecase clipped */
469     {199, 120, 199, 140}, /* r edgecase */
470     {200, 120, 200, 140}, /* r edgecase clipped */
471     {122,  99, 122, 201}, /* t and b clipped */
472     {124, 100, 124, 140}, /* t edgecase */
473     {126,  99, 126, 140}, /* t edgecase clipped */
474     {128, 120, 128, 200}, /* b edgecase */
475     {130, 120, 130, 201}, /* b edgecase clipped */
476     {132,  12, 132, 140}, /* inside two clip rects */
477     {134,  90, 134, 101}, /* b end on t edgecase */
478     {136,  90, 136, 100}, /* b end on t edgecase clipped */
479     {138, 199, 138, 220}, /* t end on b edgecase */
480     {140, 200, 140, 220}  /* t end on b edgecase clipped */
481 };
482
483 static const RECT line_clips[] =
484 {
485     { 90, 110, 310, 120},
486     { 90, 120, 295, 130},
487     { 90, 190, 110, 240}, /* totally clipped, moving outcodes */
488     { 90, 130, 100, 135}, /* totally clipped, end pt on l edge */
489     { 90, 132, 101, 137}, /* end pt just inside l edge */
490     {200, 140, 210, 141}, /* totally clipped, start pt on r edge */
491     {199, 142, 210, 143}  /* start pt just inside r edge */
492 };
493
494 static const RECT patblt_clips[] =
495 {
496     {120, 120, 140, 126}, /* unclipped */
497     {100, 130, 140, 136}, /* l edgecase */
498     { 99, 140, 140, 146}, /* l edgecase clipped */
499     {180, 130, 200, 136}, /* r edgecase */
500     {180, 140, 201, 146}, /* r edgecase clipped */
501     {120, 100, 130, 110}, /* t edgecase */
502     {140,  99, 150, 110}, /* t edgecase clipped */
503     {120, 180, 130, 200}, /* b edgecase */
504     {140, 180, 150, 201}, /* b edgecase */
505     {199, 150, 210, 156}, /* l edge on r edgecase */
506     {200, 160, 210, 166}, /* l edge on r edgecase clipped */
507     { 90, 150, 101, 156}, /* r edge on l edgecase */
508     { 90, 160, 100, 166}, /* r edge on l edgecase clipped */
509     {160,  90, 166, 101}, /* b edge on t edgecase */
510     {170,  90, 176, 101}, /* b edge on t edgecase clipped */
511     {160, 199, 166, 210}, /* t edge on b edgecase */
512     {170, 200, 176, 210}, /* t edge on b edgecase clipped */
513 };
514
515 static const RECT rectangles[] =
516 {
517     {10,   11, 100, 101},
518     {250, 100, 350,  10},
519     {120,  10, 120,  20}, /* zero width */
520     {120,  10, 130,  10}, /* zero height */
521     {120,  40, 121,  41}, /* 1 x 1 */
522     {130,  50, 132,  52}, /* 2 x 2 */
523     {140,  60, 143,  63}, /* 3 x 3 */
524     {150,  70, 154,  74}, /* 4 x 4 */
525     {120,  20, 121,  30}, /* width == 1 */
526     {130,  20, 132,  30}, /* width == 2 */
527     {140,  20, 143,  30}, /* width == 3 */
528     {200,  20, 210,  21}, /* height == 1 */
529     {200,  30, 210,  32}, /* height == 2 */
530     {200,  40, 210,  43}  /* height == 3 */
531 };
532
533 static const BITMAPINFOHEADER dib_brush_header_8888 = {sizeof(BITMAPINFOHEADER), 16, -16, 1, 32, BI_RGB, 0, 0, 0, 0, 0};
534 static const BITMAPINFOHEADER dib_brush_header_24   = {sizeof(BITMAPINFOHEADER), 16, -16, 1, 24, BI_RGB, 0, 0, 0, 0, 0};
535 static const BITMAPINFOHEADER dib_brush_header_555  = {sizeof(BITMAPINFOHEADER), 16, -16, 1, 16, BI_RGB, 0, 0, 0, 0, 0};
536 static const BITMAPINFOHEADER dib_brush_header_8    = {sizeof(BITMAPINFOHEADER), 16, -16, 1,  8, BI_RGB, 0, 0, 0, 0, 0};
537 static const BITMAPINFOHEADER dib_brush_header_4    = {sizeof(BITMAPINFOHEADER), 16, -16, 1,  4, BI_RGB, 0, 0, 0, 0, 0};
538 static const BITMAPINFOHEADER dib_brush_header_1    = {sizeof(BITMAPINFOHEADER), 16, -16, 1,  1, BI_RGB, 0, 0, 0, 0, 0};
539
540 static void draw_graphics(HDC hdc, BITMAPINFO *bmi, BYTE *bits, const char ***sha1)
541 {
542     DWORD dib_size = get_dib_size(bmi);
543     HPEN solid_pen, dashed_pen, orig_pen;
544     HBRUSH solid_brush, dib_brush, hatch_brush, orig_brush;
545     INT i, y, hatch_style;
546     HRGN hrgn, hrgn2;
547     BYTE dib_brush_buf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD) + 16 * 16 * sizeof(DWORD)]; /* Enough for 16 x 16 at 32 bpp */
548     BITMAPINFO *brush_bi = (BITMAPINFO*)dib_brush_buf;
549     BYTE *brush_bits;
550     BOOL dib_is_1bpp = (bmi->bmiHeader.biBitCount == 1);
551
552     memset(bits, 0xcc, dib_size);
553     compare_hash(bmi, bits, sha1, "empty");
554
555     solid_pen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0xff));
556     orig_pen = SelectObject(hdc, solid_pen);
557     SetBrushOrgEx(hdc, 0, 0, NULL);
558
559     /* horizontal and vertical lines */
560     for(i = 1; i <= 16; i++)
561     {
562         SetROP2(hdc, i);
563         MoveToEx(hdc, 10, i * 3, NULL);
564         LineTo(hdc, 100, i * 3); /* l -> r */
565         MoveToEx(hdc, 100, 50 + i * 3, NULL);
566         LineTo(hdc, 10, 50 + i * 3); /* r -> l */
567         MoveToEx(hdc, 120 + i * 3, 10, NULL);
568         LineTo(hdc, 120 + i * 3, 100); /* t -> b */
569         MoveToEx(hdc, 170 + i * 3, 100, NULL);
570         LineTo(hdc, 170 + i * 3, 10); /* b -> t */
571     }
572     compare_hash(bmi, bits, sha1, "h and v solid lines");
573     memset(bits, 0xcc, dib_size);
574
575     /* diagonal lines */
576     SetROP2(hdc, R2_COPYPEN);
577     for(i = 0; i < 16; i++)
578     {
579         double s = sin(M_PI * i / 8.0);
580         double c = cos(M_PI * i / 8.0);
581
582         MoveToEx(hdc, 200.5 + 10 * c, 200.5 + 10 * s, NULL);
583         LineTo(hdc, 200.5 + 100 * c, 200.5 + 100 * s);
584     }
585     compare_hash(bmi, bits, sha1, "diagonal solid lines");
586     memset(bits, 0xcc, dib_size);
587
588     for(i = 0; i < sizeof(bias_check) / sizeof(bias_check[0]); i++)
589     {
590         MoveToEx(hdc, bias_check[i].left, bias_check[i].top, NULL);
591         LineTo(hdc, bias_check[i].right, bias_check[i].bottom);
592     }
593     compare_hash(bmi, bits, sha1, "more diagonal solid lines");
594     memset(bits, 0xcc, dib_size);
595
596     /* solid brush PatBlt */
597     solid_brush = CreateSolidBrush(RGB(0x33, 0xaa, 0xff));
598     orig_brush = SelectObject(hdc, solid_brush);
599
600     for(i = 0, y = 10; i < 256; i++)
601     {
602         BOOL ret;
603
604         ret = PatBlt(hdc, 10, y, 100, 10, rop3[i]);
605
606         if(rop_uses_src(rop3[i]))
607             ok(ret == FALSE, "got TRUE for %x\n", rop3[i]);
608         else
609         {
610             ok(ret, "got FALSE for %x\n", rop3[i]);
611             y += 20;
612         }
613
614     }
615     compare_hash(bmi, bits, sha1, "solid patblt");
616     memset(bits, 0xcc, dib_size);
617
618     /* clipped lines */
619     hrgn = CreateRectRgn(10, 10, 200, 20);
620     hrgn2 = CreateRectRgn(100, 100, 200, 200);
621     CombineRgn(hrgn, hrgn, hrgn2, RGN_OR);
622     SetRectRgn(hrgn2, 290, 100, 300, 200);
623     CombineRgn(hrgn, hrgn, hrgn2, RGN_OR);
624     ExtSelectClipRgn(hdc, hrgn, RGN_COPY);
625     DeleteObject(hrgn2);
626
627     for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
628     {
629         MoveToEx(hdc, hline_clips[i].left, hline_clips[i].top, NULL);
630         LineTo(hdc, hline_clips[i].right, hline_clips[i].bottom);
631     }
632     compare_hash(bmi, bits, sha1, "clipped solid hlines");
633     memset(bits, 0xcc, dib_size);
634
635     for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
636     {
637         MoveToEx(hdc, vline_clips[i].left, vline_clips[i].top, NULL);
638         LineTo(hdc, vline_clips[i].right, vline_clips[i].bottom);
639     }
640     compare_hash(bmi, bits, sha1, "clipped solid vlines");
641     memset(bits, 0xcc, dib_size);
642
643     for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
644     {
645         MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
646         LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
647     }
648     compare_hash(bmi, bits, sha1, "clipped solid diagonal lines");
649     memset(bits, 0xcc, dib_size);
650
651     /* clipped PatBlt */
652     for(i = 0; i < sizeof(patblt_clips) / sizeof(patblt_clips[0]); i++)
653     {
654         PatBlt(hdc, patblt_clips[i].left, patblt_clips[i].top,
655                patblt_clips[i].right - patblt_clips[i].left,
656                patblt_clips[i].bottom - patblt_clips[i].top, PATCOPY);
657     }
658     compare_hash(bmi, bits, sha1, "clipped patblt");
659     memset(bits, 0xcc, dib_size);
660
661     /* clipped dashed lines */
662     dashed_pen = CreatePen(PS_DASH, 1, RGB(0xff, 0, 0));
663     SelectObject(hdc, dashed_pen);
664     SetBkMode(hdc, TRANSPARENT);
665     SetBkColor(hdc, RGB(0, 0xff, 0));
666
667     for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
668     {
669         MoveToEx(hdc, hline_clips[i].left, hline_clips[i].top, NULL);
670         LineTo(hdc, hline_clips[i].right, hline_clips[i].bottom);
671     }
672     compare_hash(bmi, bits, sha1, "clipped dashed hlines");
673     memset(bits, 0xcc, dib_size);
674
675     for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
676     {
677         MoveToEx(hdc, hline_clips[i].right - 1, hline_clips[i].bottom, NULL);
678         LineTo(hdc, hline_clips[i].left - 1, hline_clips[i].top);
679     }
680     compare_hash(bmi, bits, sha1, "clipped dashed hlines r -> l");
681     memset(bits, 0xcc, dib_size);
682
683     for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
684     {
685         MoveToEx(hdc, vline_clips[i].left, vline_clips[i].top, NULL);
686         LineTo(hdc, vline_clips[i].right, vline_clips[i].bottom);
687     }
688     compare_hash(bmi, bits, sha1, "clipped dashed vlines");
689     memset(bits, 0xcc, dib_size);
690
691     for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
692     {
693         MoveToEx(hdc, vline_clips[i].right, vline_clips[i].bottom - 1, NULL);
694         LineTo(hdc, vline_clips[i].left, vline_clips[i].top - 1);
695     }
696     compare_hash(bmi, bits, sha1, "clipped dashed vlines b -> t");
697     memset(bits, 0xcc, dib_size);
698
699     for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
700     {
701         MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
702         LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
703     }
704     compare_hash(bmi, bits, sha1, "clipped dashed diagonal lines");
705     memset(bits, 0xcc, dib_size);
706
707     SetBkMode(hdc, OPAQUE);
708
709     for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
710     {
711         MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
712         LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
713     }
714     compare_hash(bmi, bits, sha1, "clipped opaque dashed diagonal lines");
715     memset(bits, 0xcc, dib_size);
716
717     ExtSelectClipRgn(hdc, NULL, RGN_COPY);
718
719     /* 8888 DIB pattern brush */
720
721     brush_bi->bmiHeader = dib_brush_header_8888;
722     brush_bits = (BYTE*)brush_bi + sizeof(BITMAPINFOHEADER);
723     memset(brush_bits, 0, 16 * 16 * sizeof(DWORD));
724     brush_bits[2] = 0xff;
725     brush_bits[6] = 0xff;
726     brush_bits[14] = 0xff;
727     brush_bits[65] = 0xff;
728     brush_bits[69] = 0xff;
729     brush_bits[72] = 0xff;
730
731     dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
732
733     SelectObject(hdc, dib_brush);
734     SetBrushOrgEx(hdc, 1, 1, NULL);
735
736     for(i = 0, y = 10; i < 256; i++)
737     {
738         BOOL ret;
739
740         if(!rop_uses_src(rop3[i]))
741         {
742             ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
743             ok(ret, "got FALSE for %x\n", rop3[i]);
744             y += 25;
745         }
746     }
747     compare_hash_broken_todo(bmi, bits, sha1, "top-down 8888 dib brush patblt", dib_is_1bpp ? 2 : 0, dib_is_1bpp);
748     memset(bits, 0xcc, dib_size);
749
750     SelectObject(hdc, orig_brush);
751     DeleteObject(dib_brush);
752
753     /* 8888 bottom-up DIB pattern brush */
754
755     brush_bi->bmiHeader.biHeight = -brush_bi->bmiHeader.biHeight;
756
757     dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
758
759     SelectObject(hdc, dib_brush);
760
761     /* This used to set the x origin to 100 as well, but
762        there's a Windows bug for 24 bpp where the brush's x offset
763        is incorrectly calculated for rops that involve both D and P */
764     SetBrushOrgEx(hdc, 4, 100, NULL);
765
766     for(i = 0, y = 10; i < 256; i++)
767     {
768         BOOL ret;
769
770         if(!rop_uses_src(rop3[i]))
771         {
772             ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
773             ok(ret, "got FALSE for %x\n", rop3[i]);
774             y += 25;
775         }
776     }
777     compare_hash_broken_todo(bmi, bits, sha1, "bottom-up 8888 dib brush patblt", dib_is_1bpp ? 2 : 0, dib_is_1bpp);
778     memset(bits, 0xcc, dib_size);
779
780     SelectObject(hdc, orig_brush);
781     DeleteObject(dib_brush);
782
783     /* 24 bpp dib pattern brush */
784
785     brush_bi->bmiHeader = dib_brush_header_24;
786     brush_bits = (BYTE*)brush_bi + sizeof(BITMAPINFOHEADER);
787     memset(brush_bits, 0, 16 * 16 * 3);
788     brush_bits[0] = brush_bits[3] = brush_bits[6] = brush_bits[8] = 0xff;
789     brush_bits[49] = brush_bits[52] = 0xff;
790
791     dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
792
793     SelectObject(hdc, dib_brush);
794     SetBrushOrgEx(hdc, 1, 1, NULL);
795
796     for(i = 0, y = 10; i < 256; i++)
797     {
798         BOOL ret;
799
800         if(!rop_uses_src(rop3[i]))
801         {
802             ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
803             ok(ret, "got FALSE for %x\n", rop3[i]);
804             y += 25;
805         }
806     }
807     compare_hash_broken_todo(bmi, bits, sha1, "top-down 24 bpp brush patblt", dib_is_1bpp ? 2 : 0, dib_is_1bpp);
808     memset(bits, 0xcc, dib_size);
809
810     SelectObject(hdc, orig_brush);
811     DeleteObject(dib_brush);
812
813     /* 555 dib pattern brush */
814
815     brush_bi->bmiHeader = dib_brush_header_555;
816     brush_bits = (BYTE*)brush_bi + sizeof(BITMAPINFOHEADER);
817     memset(brush_bits, 0, 16 * 16 * sizeof(WORD));
818     brush_bits[0] = brush_bits[1] = 0xff;
819     brush_bits[32] = brush_bits[34] = 0x7c;
820
821     dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
822
823     SelectObject(hdc, dib_brush);
824     SetBrushOrgEx(hdc, 1, 1, NULL);
825
826     for(i = 0, y = 10; i < 256; i++)
827     {
828         BOOL ret;
829
830         if(!rop_uses_src(rop3[i]))
831         {
832             ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
833             ok(ret, "got FALSE for %x\n", rop3[i]);
834             y += 25;
835         }
836     }
837     compare_hash_broken_todo(bmi, bits, sha1, "top-down 555 dib brush patblt", dib_is_1bpp ? 1 : 0, dib_is_1bpp);
838     memset(bits, 0xcc, dib_size);
839
840     SelectObject(hdc, orig_brush);
841     DeleteObject(dib_brush);
842
843     SetBrushOrgEx(hdc, 0, 0, NULL);
844
845     /* 8 bpp dib pattern brush */
846
847     brush_bi->bmiHeader = dib_brush_header_8;
848     brush_bi->bmiHeader.biClrUsed = 3;
849     memset(brush_bi->bmiColors, 0, brush_bi->bmiHeader.biClrUsed * sizeof(RGBQUAD));
850     brush_bi->bmiColors[0].rgbRed = 0xff;
851     brush_bi->bmiColors[1].rgbRed = 0xff;
852     brush_bi->bmiColors[1].rgbGreen = 0xff;
853     brush_bi->bmiColors[1].rgbBlue = 0xff;
854
855     brush_bits = (BYTE*)brush_bi + sizeof(BITMAPINFOHEADER) + brush_bi->bmiHeader.biClrUsed * sizeof(RGBQUAD);
856     memset(brush_bits, 0, 16 * 16 * sizeof(BYTE));
857     brush_bits[0] = brush_bits[1] = 1;
858     brush_bits[16] = brush_bits[17] = 2;
859     brush_bits[32] = brush_bits[33] = 6;
860
861     dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
862
863     SelectObject(hdc, dib_brush);
864     SetBrushOrgEx(hdc, 1, 1, NULL);
865
866     for(i = 0, y = 10; i < 256; i++)
867     {
868         BOOL ret;
869
870         if(!rop_uses_src(rop3[i]))
871         {
872             ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
873             ok(ret, "got FALSE for %x\n", rop3[i]);
874             y += 25;
875         }
876     }
877     compare_hash_broken_todo(bmi, bits, sha1, "top-down 8 bpp dib brush patblt", dib_is_1bpp ? 2 : 0, dib_is_1bpp);
878     memset(bits, 0xcc, dib_size);
879
880     SelectObject(hdc, orig_brush);
881     DeleteObject(dib_brush);
882
883     /* 4 bpp dib pattern brush */
884
885     brush_bi->bmiHeader = dib_brush_header_4;
886     dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
887
888     SelectObject(hdc, dib_brush);
889     SetBrushOrgEx(hdc, 1, 1, NULL);
890
891     for(i = 0, y = 10; i < 256; i++)
892     {
893         BOOL ret;
894
895         if(!rop_uses_src(rop3[i]))
896         {
897             ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
898             ok(ret, "got FALSE for %x\n", rop3[i]);
899             y += 25;
900         }
901     }
902     compare_hash_broken_todo(bmi, bits, sha1, "top-down 4 bpp dib brush patblt", dib_is_1bpp ? 2 : 0, dib_is_1bpp);
903     memset(bits, 0xcc, dib_size);
904
905     SelectObject(hdc, orig_brush);
906     DeleteObject(dib_brush);
907
908     /* 1 bpp dib pattern brush */
909
910     brush_bi->bmiHeader = dib_brush_header_1;
911     brush_bi->bmiHeader.biClrUsed = 2;
912     memset(brush_bits, 0, 16 * 4);
913     brush_bits[0] = 0xf0;
914     brush_bits[4] = 0xf0;
915     brush_bits[8] = 0xf0;
916
917     dib_brush = CreateDIBPatternBrushPt(brush_bi, DIB_RGB_COLORS);
918     SelectObject(hdc, dib_brush);
919     for(i = 0, y = 10; i < 256; i++)
920     {
921         BOOL ret;
922
923         if(!rop_uses_src(rop3[i]))
924         {
925             ret = PatBlt(hdc, 10 + i, y, 100, 20, rop3[i]);
926             ok(ret, "got FALSE for %x\n", rop3[i]);
927             y += 25;
928         }
929     }
930
931     compare_hash_broken_todo(bmi, bits, sha1, "top-down 1 bpp dib brush patblt", dib_is_1bpp ? 2 : 0, dib_is_1bpp);
932     memset(bits, 0xcc, dib_size);
933
934     SelectObject(hdc, orig_brush);
935     SetBrushOrgEx(hdc, 0, 0, NULL);
936
937     /* Rectangle */
938
939     SelectObject(hdc, solid_pen);
940     SelectObject(hdc, solid_brush);
941
942     for(i = 0; i < sizeof(rectangles)/sizeof(rectangles[0]); i++)
943     {
944         Rectangle(hdc, rectangles[i].left, rectangles[i].top, rectangles[i].right, rectangles[i].bottom);
945     }
946
947     SelectObject(hdc, dashed_pen);
948     for(i = 0; i < sizeof(rectangles)/sizeof(rectangles[0]); i++)
949     {
950         Rectangle(hdc, rectangles[i].left, rectangles[i].top + 150, rectangles[i].right, rectangles[i].bottom + 150);
951     }
952
953     compare_hash(bmi, bits, sha1, "rectangles");
954     memset(bits, 0xcc, dib_size);
955     SelectObject(hdc, solid_pen);
956
957     /* PaintRgn */
958
959     PaintRgn(hdc, hrgn);
960     compare_hash(bmi, bits, sha1, "PaintRgn");
961     memset(bits, 0xcc, dib_size);
962
963     /* RTL rectangles */
964
965     if( !pSetLayout )
966     {
967         win_skip("Don't have SetLayout\n");
968         (*sha1)++;
969     }
970     else
971     {
972         pSetLayout(hdc, LAYOUT_RTL);
973         PaintRgn(hdc, hrgn);
974         PatBlt(hdc, 10, 250, 10, 10, PATCOPY);
975         Rectangle(hdc, 100, 250, 110, 260);
976         compare_hash(bmi, bits, sha1, "rtl");
977         memset(bits, 0xcc, dib_size);
978
979         pSetLayout(hdc, LAYOUT_LTR);
980     }
981
982     for(i = 0, y = 10; i < 256; i++)
983     {
984         BOOL ret;
985
986         if(!rop_uses_src(rop3[i]))
987         {
988             for(hatch_style = HS_HORIZONTAL; hatch_style <= HS_DIAGCROSS; hatch_style++)
989             {
990                 hatch_brush = CreateHatchBrush(hatch_style, RGB(0xff, 0, 0));
991                 SelectObject(hdc, hatch_brush);
992                 ret = PatBlt(hdc, 10 + i + 30 * hatch_style, y, 20, 20, rop3[i]);
993                 ok(ret, "got FALSE for %x\n", rop3[i]);
994                 SelectObject(hdc, orig_brush);
995                 DeleteObject(hatch_brush);
996             }
997             y += 25;
998         }
999     }
1000
1001     compare_hash_broken_todo(bmi, bits, sha1, "hatch brushes", 1, FALSE); /* nt4 is different */
1002     memset(bits, 0xcc, dib_size);
1003
1004     SelectObject(hdc, orig_brush);
1005     SelectObject(hdc, orig_pen);
1006     DeleteObject(hrgn);
1007     DeleteObject(dib_brush);
1008     DeleteObject(dashed_pen);
1009     DeleteObject(solid_brush);
1010     DeleteObject(solid_pen);
1011 }
1012
1013 static void test_simple_graphics(void)
1014 {
1015     char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
1016     BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
1017     DWORD *bit_fields = (DWORD*)(bmibuf + sizeof(BITMAPINFOHEADER));
1018     HDC mem_dc;
1019     BYTE *bits;
1020     HBITMAP dib, orig_bm;
1021     const char **sha1;
1022     DIBSECTION ds;
1023
1024     mem_dc = CreateCompatibleDC(NULL);
1025
1026     /* a8r8g8b8 */
1027     trace("8888\n");
1028     memset(bmi, 0, sizeof(bmibuf));
1029     bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
1030     bmi->bmiHeader.biHeight = 512;
1031     bmi->bmiHeader.biWidth = 512;
1032     bmi->bmiHeader.biBitCount = 32;
1033     bmi->bmiHeader.biPlanes = 1;
1034     bmi->bmiHeader.biCompression = BI_RGB;
1035
1036     dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1037     ok(dib != NULL, "ret NULL\n");
1038     ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
1039     ok(ds.dsBitfields[0] == 0, "got %08x\n", ds.dsBitfields[0]);
1040     ok(ds.dsBitfields[1] == 0, "got %08x\n", ds.dsBitfields[1]);
1041     ok(ds.dsBitfields[2] == 0, "got %08x\n", ds.dsBitfields[2]);
1042     ok(ds.dsBmih.biCompression == BI_RGB ||
1043        broken(ds.dsBmih.biCompression == BI_BITFIELDS), /* nt4 sp1 and 2 */
1044        "got %x\n", ds.dsBmih.biCompression);
1045
1046     orig_bm = SelectObject(mem_dc, dib);
1047
1048     sha1 = sha1_graphics_a8r8g8b8;
1049     draw_graphics(mem_dc, bmi, bits, &sha1);
1050
1051     SelectObject(mem_dc, orig_bm);
1052     DeleteObject(dib);
1053
1054     /* a8r8g8b8 - bitfields.  Should be the same as the regular 32 bit case.*/
1055     trace("8888 - bitfields\n");
1056     bmi->bmiHeader.biBitCount = 32;
1057     bmi->bmiHeader.biCompression = BI_BITFIELDS;
1058     bit_fields[0] = 0xff0000;
1059     bit_fields[1] = 0x00ff00;
1060     bit_fields[2] = 0x0000ff;
1061
1062     dib = CreateDIBSection(mem_dc, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1063     ok(dib != NULL, "ret NULL\n");
1064     ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
1065     ok(ds.dsBitfields[0] == 0xff0000, "got %08x\n", ds.dsBitfields[0]);
1066     ok(ds.dsBitfields[1] == 0x00ff00, "got %08x\n", ds.dsBitfields[1]);
1067     ok(ds.dsBitfields[2] == 0x0000ff, "got %08x\n", ds.dsBitfields[2]);
1068     ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
1069
1070     orig_bm = SelectObject(mem_dc, dib);
1071
1072     sha1 = sha1_graphics_a8r8g8b8;
1073     draw_graphics(mem_dc, bmi, bits, &sha1);
1074
1075     SelectObject(mem_dc, orig_bm);
1076     DeleteObject(dib);
1077
1078     /* a8b8g8r8 - bitfields. */
1079     trace("a8b8g8r8 - bitfields\n");
1080     bmi->bmiHeader.biBitCount = 32;
1081     bmi->bmiHeader.biCompression = BI_BITFIELDS;
1082     bit_fields[0] = 0x0000ff;
1083     bit_fields[1] = 0x00ff00;
1084     bit_fields[2] = 0xff0000;
1085
1086     dib = CreateDIBSection(mem_dc, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1087     ok(dib != NULL, "ret NULL\n");
1088     ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
1089     ok(ds.dsBitfields[0] == 0x0000ff, "got %08x\n", ds.dsBitfields[0]);
1090     ok(ds.dsBitfields[1] == 0x00ff00, "got %08x\n", ds.dsBitfields[1]);
1091     ok(ds.dsBitfields[2] == 0xff0000, "got %08x\n", ds.dsBitfields[2]);
1092     ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
1093
1094     orig_bm = SelectObject(mem_dc, dib);
1095
1096     sha1 = sha1_graphics_a8b8g8r8;
1097     draw_graphics(mem_dc, bmi, bits, &sha1);
1098
1099     SelectObject(mem_dc, orig_bm);
1100     DeleteObject(dib);
1101
1102     /* 24 */
1103     trace("24\n");
1104     bmi->bmiHeader.biBitCount = 24;
1105     bmi->bmiHeader.biCompression = BI_RGB;
1106
1107     dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1108     ok(dib != NULL, "ret NULL\n");
1109     orig_bm = SelectObject(mem_dc, dib);
1110
1111     sha1 = sha1_graphics_24;
1112     draw_graphics(mem_dc, bmi, bits, &sha1);
1113
1114     SelectObject(mem_dc, orig_bm);
1115     DeleteObject(dib);
1116
1117     /* r5g5b5 */
1118     trace("555\n");
1119     bmi->bmiHeader.biBitCount = 16;
1120     bmi->bmiHeader.biCompression = BI_RGB;
1121
1122     dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1123     ok(dib != NULL, "ret NULL\n");
1124     ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
1125     ok(ds.dsBitfields[0] == 0x7c00, "got %08x\n", ds.dsBitfields[0]);
1126     ok(ds.dsBitfields[1] == 0x03e0, "got %08x\n", ds.dsBitfields[1]);
1127     ok(ds.dsBitfields[2] == 0x001f, "got %08x\n", ds.dsBitfields[2]);
1128 todo_wine
1129     ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
1130
1131     orig_bm = SelectObject(mem_dc, dib);
1132
1133     sha1 = sha1_graphics_r5g5b5;
1134     draw_graphics(mem_dc, bmi, bits, &sha1);
1135
1136     SelectObject(mem_dc, orig_bm);
1137     DeleteObject(dib);
1138
1139     /* r4g4b4 */
1140     trace("444\n");
1141     bmi->bmiHeader.biBitCount = 16;
1142     bmi->bmiHeader.biCompression = BI_BITFIELDS;
1143     bit_fields[0] = 0x0f00;
1144     bit_fields[1] = 0x00f0;
1145     bit_fields[2] = 0x000f;
1146     dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1147     ok(dib != NULL, "ret NULL\n");
1148     ok(GetObjectW( dib, sizeof(ds), &ds ), "GetObject failed\n");
1149     ok(ds.dsBitfields[0] == 0x0f00, "got %08x\n", ds.dsBitfields[0]);
1150     ok(ds.dsBitfields[1] == 0x00f0, "got %08x\n", ds.dsBitfields[1]);
1151     ok(ds.dsBitfields[2] == 0x000f, "got %08x\n", ds.dsBitfields[2]);
1152     ok(ds.dsBmih.biCompression == BI_BITFIELDS, "got %x\n", ds.dsBmih.biCompression);
1153
1154     orig_bm = SelectObject(mem_dc, dib);
1155
1156     sha1 = sha1_graphics_r4g4b4;
1157     draw_graphics(mem_dc, bmi, bits, &sha1);
1158
1159     SelectObject(mem_dc, orig_bm);
1160     DeleteObject(dib);
1161
1162     /* 8 */
1163     trace("8\n");
1164     bmi->bmiHeader.biBitCount = 8;
1165     bmi->bmiHeader.biCompression = BI_RGB;
1166     bmi->bmiHeader.biClrUsed = 5;
1167     bmi->bmiColors[0].rgbRed = 0xff;
1168     bmi->bmiColors[0].rgbGreen = 0xff;
1169     bmi->bmiColors[0].rgbBlue = 0xff;
1170     bmi->bmiColors[1].rgbRed = 0;
1171     bmi->bmiColors[1].rgbGreen = 0;
1172     bmi->bmiColors[1].rgbBlue = 0;
1173     bmi->bmiColors[2].rgbRed = 0xff;
1174     bmi->bmiColors[2].rgbGreen = 0;
1175     bmi->bmiColors[2].rgbBlue = 0;
1176     bmi->bmiColors[3].rgbRed = 0;
1177     bmi->bmiColors[3].rgbGreen = 0xff;
1178     bmi->bmiColors[3].rgbBlue = 0;
1179     bmi->bmiColors[4].rgbRed = 0;
1180     bmi->bmiColors[4].rgbGreen = 0;
1181     bmi->bmiColors[4].rgbBlue = 0xff;
1182
1183     dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1184     ok(dib != NULL, "ret NULL\n");
1185
1186     orig_bm = SelectObject(mem_dc, dib);
1187
1188     sha1 = sha1_graphics_8;
1189     draw_graphics(mem_dc, bmi, bits, &sha1);
1190
1191     SelectObject(mem_dc, orig_bm);
1192     DeleteObject(dib);
1193
1194     /* 4 */
1195     trace("4\n");
1196     bmi->bmiHeader.biBitCount = 4;
1197
1198     dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1199     ok(dib != NULL, "ret NULL\n");
1200
1201     orig_bm = SelectObject(mem_dc, dib);
1202
1203     sha1 = sha1_graphics_4;
1204     draw_graphics(mem_dc, bmi, bits, &sha1);
1205
1206     SelectObject(mem_dc, orig_bm);
1207     DeleteObject(dib);
1208
1209     /* 1 */
1210     trace("1\n");
1211     bmi->bmiHeader.biBitCount = 1;
1212     bmi->bmiHeader.biClrUsed = 2;
1213
1214     bmi->bmiColors[0].rgbRed = 0x00;
1215     bmi->bmiColors[0].rgbGreen = 0x01;
1216     bmi->bmiColors[0].rgbBlue = 0xff;
1217     bmi->bmiColors[1].rgbRed = 0xff;
1218     bmi->bmiColors[1].rgbGreen = 0x00;
1219     bmi->bmiColors[1].rgbBlue = 0x00;
1220
1221     dib = CreateDIBSection(0, bmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
1222     ok(dib != NULL, "ret NULL\n");
1223
1224     orig_bm = SelectObject(mem_dc, dib);
1225
1226     sha1 = sha1_graphics_1;
1227     draw_graphics(mem_dc, bmi, bits, &sha1);
1228
1229     SelectObject(mem_dc, orig_bm);
1230     DeleteObject(dib);
1231
1232     DeleteDC(mem_dc);
1233 }
1234
1235 START_TEST(dib)
1236 {
1237     HMODULE mod = GetModuleHandleA("gdi32.dll");
1238     pSetLayout = (void *)GetProcAddress( mod, "SetLayout" );
1239
1240     CryptAcquireContextW(&crypt_prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
1241
1242     test_simple_graphics();
1243
1244     CryptReleaseContext(crypt_prov, 0);
1245 }