Rework WriteIniValues to use MSI_IterateRecords.
[wine] / dlls / oleaut32 / tests / olepicture.c
1 /*
2  * OLEPICTURE test program
3  *
4  * Copyright 2005 Marcus Meissner
5  *
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #include <stdarg.h>
23 #include <stdio.h>
24 #include <math.h>
25 #include <float.h>
26 #include <time.h>
27
28 #define COBJMACROS
29
30 #include <wine/test.h>
31 #include <windef.h>
32 #include <winbase.h>
33 #include <winuser.h>
34 #include <wingdi.h>
35 #include <winnls.h>
36 #include <winerror.h>
37 #include <winnt.h>
38
39 #include <wtypes.h>
40 #include <olectl.h>
41 #include <objidl.h>
42
43 static HMODULE hOleaut32;
44
45 static HRESULT (WINAPI *pOleLoadPicture)(LPSTREAM,LONG,BOOL,REFIID,LPVOID*);
46
47 /* 1x1 pixel gif */
48 static const unsigned char gifimage[35] = {
49 0x47,0x49,0x46,0x38,0x37,0x61,0x01,0x00,0x01,0x00,0x80,0x00,0x00,0xff,0xff,0xff,
50 0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x02,0x02,0x44,
51 0x01,0x00,0x3b
52 };
53
54 /* 1x1 pixel jpg */
55 static const unsigned char jpgimage[285] = {
56 0xff,0xd8,0xff,0xe0,0x00,0x10,0x4a,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2c,
57 0x01,0x2c,0x00,0x00,0xff,0xdb,0x00,0x43,0x00,0x05,0x03,0x04,0x04,0x04,0x03,0x05,
58 0x04,0x04,0x04,0x05,0x05,0x05,0x06,0x07,0x0c,0x08,0x07,0x07,0x07,0x07,0x0f,0x0b,
59 0x0b,0x09,0x0c,0x11,0x0f,0x12,0x12,0x11,0x0f,0x11,0x11,0x13,0x16,0x1c,0x17,0x13,
60 0x14,0x1a,0x15,0x11,0x11,0x18,0x21,0x18,0x1a,0x1d,0x1d,0x1f,0x1f,0x1f,0x13,0x17,
61 0x22,0x24,0x22,0x1e,0x24,0x1c,0x1e,0x1f,0x1e,0xff,0xdb,0x00,0x43,0x01,0x05,0x05,
62 0x05,0x07,0x06,0x07,0x0e,0x08,0x08,0x0e,0x1e,0x14,0x11,0x14,0x1e,0x1e,0x1e,0x1e,
63 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
64 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,
65 0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0x1e,0xff,0xc0,
66 0x00,0x11,0x08,0x00,0x01,0x00,0x01,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,
67 0x01,0xff,0xc4,0x00,0x15,0x00,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
68 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0xff,0xc4,0x00,0x14,0x10,0x01,0x00,0x00,
69 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc4,
70 0x00,0x14,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
71 0x00,0x00,0x00,0x00,0xff,0xc4,0x00,0x14,0x11,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
72 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xda,0x00,0x0c,0x03,0x01,
73 0x00,0x02,0x11,0x03,0x11,0x00,0x3f,0x00,0xb2,0xc0,0x07,0xff,0xd9
74 };
75
76 #if 0 /* no png support yet */
77 /* 1x1 pixel png */
78 static const unsigned char pngimage[285] = {
79 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
80 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x02,0x00,0x00,0x00,0x90,0x77,0x53,
81 0xde,0x00,0x00,0x00,0x09,0x70,0x48,0x59,0x73,0x00,0x00,0x0b,0x13,0x00,0x00,0x0b,
82 0x13,0x01,0x00,0x9a,0x9c,0x18,0x00,0x00,0x00,0x07,0x74,0x49,0x4d,0x45,0x07,0xd5,
83 0x06,0x03,0x0f,0x07,0x2d,0x12,0x10,0xf0,0xfd,0x00,0x00,0x00,0x0c,0x49,0x44,0x41,
84 0x54,0x08,0xd7,0x63,0xf8,0xff,0xff,0x3f,0x00,0x05,0xfe,0x02,0xfe,0xdc,0xcc,0x59,
85 0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
86 };
87 #endif
88
89 /* 1x1 pixel bmp */
90 static const unsigned char bmpimage[66] = {
91 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
92 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
93 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
94 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00,
95 0x00,0x00
96 };
97
98 /* 2x2 pixel gif */
99 static const unsigned char gif4pixel[42] = {
100 0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
101 0x39,0x62,0xfc,0xff,0x1a,0xe5,0xff,0xff,0xff,0x2c,0x00,0x00,0x00,0x00,0x02,0x00,
102 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b
103 };
104
105 static void
106 test_pic(const unsigned char *imgdata, unsigned int imgsize)
107 {
108         LPBYTE          data;
109         LPSTREAM        stream;
110         IPicture*       pic = NULL;
111         HRESULT         hres;
112         LPVOID          pvObj = NULL;
113         HGLOBAL         hglob;
114         ULARGE_INTEGER  newpos1;
115         LARGE_INTEGER   seekto;
116         OLE_HANDLE      handle, hPal;
117         OLE_XSIZE_HIMETRIC      width;
118         OLE_YSIZE_HIMETRIC      height;
119         short           type;
120         DWORD           attr;
121         ULONG           res;
122
123         /* let the fun begin */
124         hglob = GlobalAlloc (0, imgsize);
125         data = GlobalLock (hglob);
126         memcpy(data, imgdata, imgsize);
127
128         hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
129         ok (hres == S_OK, "createstreamonhglobal failed? doubt it... hres 0x%08lx\n", hres);
130
131         memset(&seekto,0,sizeof(seekto));
132         hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
133         ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08lx\n", hres);
134
135         pvObj = NULL;
136         hres = pOleLoadPicture(stream, imgsize, TRUE, &IID_IPicture, &pvObj);
137         pic = pvObj;
138
139         ok(hres == S_OK,"OLP (NULL,..) does not return 0, but 0x%08lx\n",hres);
140         ok(pic != NULL,"OLP (NULL,..) returns NULL, instead of !NULL\n");
141         if (pic == NULL)
142                 return;
143
144 #if 0
145         hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos2);
146         ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08lx\n", hres);
147
148         /* The stream position here is some bytes after the image, in both wine and
149          * native. But not at the correct end. -Marcus
150          */
151         fprintf(stderr,"newpos1 %ld, newpos2 %ld\n", newpos1.LowPart, newpos2.LowPart);
152         ok (    newpos2.LowPart == imgsize,
153                 "seeked after end of gifimage (offset %d instead of expected %d)\n",
154                 newpos2.LowPart, imgsize
155         );
156 #endif
157
158         pvObj = NULL;
159         hres = IPicture_QueryInterface (pic, &IID_IPicture, &pvObj);
160
161         ok(hres == S_OK,"IPicture_QI does not return S_OK, but 0x%08lx\n", hres);
162         ok(pvObj != NULL,"IPicture_QI does return NULL, instead of a ptr\n");
163
164         IPicture_Release ((IPicture*)pvObj);
165
166         handle = 0;
167         hres = IPicture_get_Handle (pic, &handle);
168         ok(hres == S_OK,"IPicture_get_Handle does not return S_OK, but 0x%08lx\n", hres);
169         ok(handle != 0, "IPicture_get_Handle returns a NULL handle, but it should be non NULL\n");
170
171         width = 0;
172         hres = IPicture_get_Width (pic, &width);
173         ok(hres == S_OK,"IPicture_get_Width does not return S_OK, but 0x%08lx\n", hres);
174         ok(width != 0, "IPicture_get_Width returns 0, but it should not be 0.\n");
175
176         height = 0;
177         hres = IPicture_get_Height (pic, &height);
178         ok(hres == S_OK,"IPicture_get_Height does not return S_OK, but 0x%08lx\n", hres);
179         ok(height != 0, "IPicture_get_Height returns 0, but it should not be 0.\n");
180
181         type = 0;
182         hres = IPicture_get_Type (pic, &type);
183         ok(hres == S_OK,"IPicture_get_Type does not return S_OK, but 0x%08lx\n", hres);
184         ok(type == PICTYPE_BITMAP, "IPicture_get_Type returns %d, but it should be PICTYPE_BITMAP(%d).\n", type, PICTYPE_BITMAP);
185
186         attr = 0;
187         hres = IPicture_get_Attributes (pic, &attr);
188         ok(hres == S_OK,"IPicture_get_Attributes does not return S_OK, but 0x%08lx\n", hres);
189         ok(attr == 0, "IPicture_get_Attributes returns %ld, but it should be 0.\n", attr);
190
191         hPal = 0;
192         hres = IPicture_get_hPal (pic, &hPal);
193         ok(hres == S_OK,"IPicture_get_hPal does not return S_OK, but 0x%08lx\n", hres);
194         /* a single pixel b/w image has no palette */
195         ok(hPal == 0, "IPicture_get_hPal returns %ld, but it should be 0.\n", (long)hPal);
196
197         res = IPicture_Release (pic);
198         ok (res == 0, "refcount after release is %ld, but should be 1?\n", res);
199 }
200
201 static void test_empty_image() {
202         LPBYTE          data;
203         LPSTREAM        stream;
204         IPicture*       pic = NULL;
205         HRESULT         hres;
206         LPVOID          pvObj = NULL;
207         HGLOBAL         hglob;
208         OLE_HANDLE      handle;
209         ULARGE_INTEGER  newpos1;
210         LARGE_INTEGER   seekto;
211         short           type;
212
213         /* Empty image. Happens occasionally in VB programs. */
214         hglob = GlobalAlloc (0, 8);
215         data = GlobalLock (hglob);
216         memcpy(data,"lt\0\0",4);
217         ((DWORD*)data)[1] = 0;
218         hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
219         ok (hres == S_OK, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08lx\n", hres);
220
221         memset(&seekto,0,sizeof(seekto));
222         hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
223         ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08lx\n", hres);
224
225         pvObj = NULL;
226         hres = pOleLoadPicture(stream, 8, TRUE, &IID_IPicture, &pvObj);
227         pic = pvObj;
228         ok(hres == S_OK,"empty picture not loaded, hres 0x%08lx\n", hres);
229         ok(pic != NULL,"empty picture not loaded, pic is NULL\n");
230
231         hres = IPicture_get_Type (pic, &type);
232         ok (hres == S_OK,"empty picture get type failed with hres 0x%08lx\n", hres);
233         ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
234
235         hres = IPicture_get_Handle (pic, &handle);
236         ok (hres == S_OK,"empty picture get handle failed with hres 0x%08lx\n", hres);
237         ok (handle == 0, "empty picture get handle did not return 0, but 0x%08x\n", handle);
238         IPicture_Release (pic);
239 }
240
241 static void test_empty_image_2() {
242         LPBYTE          data;
243         LPSTREAM        stream;
244         IPicture*       pic = NULL;
245         HRESULT         hres;
246         LPVOID          pvObj = NULL;
247         HGLOBAL         hglob;
248         ULARGE_INTEGER  newpos1;
249         LARGE_INTEGER   seekto;
250         short           type;
251
252         /* Empty image at random stream position. */
253         hglob = GlobalAlloc (0, 200);
254         data = GlobalLock (hglob);
255         data += 42;
256         memcpy(data,"lt\0\0",4);
257         ((DWORD*)data)[1] = 0;
258         hres = CreateStreamOnHGlobal (hglob, TRUE, &stream);
259         ok (hres == S_OK, "CreatestreamOnHGlobal failed? doubt it... hres 0x%08lx\n", hres);
260
261         memset(&seekto,0,sizeof(seekto));
262         seekto.u.LowPart = 42;
263         hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
264         ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08lx\n", hres);
265
266         pvObj = NULL;
267         hres = pOleLoadPicture(stream, 8, TRUE, &IID_IPicture, &pvObj);
268         pic = pvObj;
269         ok(hres == S_OK,"empty picture not loaded, hres 0x%08lx\n", hres);
270         ok(pic != NULL,"empty picture not loaded, pic is NULL\n");
271
272         hres = IPicture_get_Type (pic, &type);
273         ok (hres == S_OK,"empty picture get type failed with hres 0x%08lx\n", hres);
274         ok (type == PICTYPE_NONE,"type is %d, but should be PICTYPE_NONE(0)\n", type);
275
276         IPicture_Release (pic);
277 }
278
279 START_TEST(olepicture)
280 {
281         hOleaut32 = LoadLibraryA("oleaut32.dll");
282         pOleLoadPicture = (void*)GetProcAddress(hOleaut32, "OleLoadPicture");
283         if (!pOleLoadPicture)
284             return;
285
286         /* Test regular 1x1 pixel images of gif, jpg, bmp type */
287         test_pic(gifimage, sizeof(gifimage));
288         test_pic(jpgimage, sizeof(jpgimage));
289         test_pic(bmpimage, sizeof(bmpimage));
290         test_pic(gif4pixel, sizeof(gif4pixel));
291         /* no PNG support yet here or in older Windows...
292         test_pic(pngimage, sizeof(pngimage));
293          */
294         test_empty_image();
295         test_empty_image_2();
296 }