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