windowscodecs/tests: Added test for GifFrameDecode_GetResolution.
[wine] / dlls / windowscodecs / tests / stream.c
1 /*
2  * Copyright 2009 Tony Wasserka
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "wine/test.h"
20
21 #define COBJMACROS
22 #include "wincodec.h"
23
24 static void test_StreamOnMemory(void)
25 {
26     IWICImagingFactory *pFactory;
27     IWICStream *pStream, *pBufStream;
28     const BYTE CmpMem[] = {
29         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
30         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
31         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
32         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
33     };
34     BYTE Memory[64], MemBuf[64];
35     LARGE_INTEGER LargeNull, LargeInt;
36     ULARGE_INTEGER uLargeNull, uNewPos;
37     ULONG uBytesRead, uBytesWritten;
38     HRESULT hr;
39     STATSTG Stats;
40
41     LargeNull.QuadPart = 0;
42     uLargeNull.QuadPart = 0;
43
44     memcpy(Memory, CmpMem, sizeof(CmpMem));
45
46     CoInitialize(NULL);
47
48     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&pFactory);
49     if(FAILED(hr)) {
50         skip("CoCreateInstance returned with %#x, expected %#x\n", hr, S_OK);
51         return;
52     }
53
54     hr = IWICImagingFactory_CreateStream(pFactory, &pStream);
55     ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
56     if(FAILED(hr)) {
57         skip("Failed to create stream\n");
58         return;
59     }
60
61     /* InitializeFromMemory */
62     hr = IWICStream_InitializeFromMemory(pStream, NULL, sizeof(Memory));   /* memory = NULL */
63     ok(hr == E_INVALIDARG, "InitializeFromMemory returned with %#x, expected %#x\n", hr, E_INVALIDARG);
64
65     hr = IWICStream_InitializeFromMemory(pStream, Memory, 0);   /* size = 0 */
66     ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
67
68     hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory));   /* stream already initialized */
69     ok(hr == WINCODEC_ERR_WRONGSTATE, "InitializeFromMemory returned with %#x, expected %#x\n", hr, WINCODEC_ERR_WRONGSTATE);
70
71     /* recreate stream */
72     IWICStream_Release(pStream);
73     hr = IWICImagingFactory_CreateStream(pFactory, &pStream);
74     ok(hr == S_OK, "CreateStream failed with %#x\n", hr);
75
76     hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory));
77     ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
78
79
80     /* Seek */
81     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, &uNewPos);
82     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
83     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
84
85     hr = IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
86     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
87
88     LargeInt.u.HighPart = 1;
89     LargeInt.u.LowPart = 0;
90     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
91     ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW), "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
92     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
93
94     LargeInt.QuadPart = sizeof(Memory) + 10;
95     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
96     ok(hr == E_INVALIDARG, "Seek returned with %#x, expected %#x\n", hr, E_INVALIDARG);
97     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
98
99     LargeInt.QuadPart = 1;
100     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos);
101     ok(hr == E_INVALIDARG, "Seek returned with %#x, expected %#x\n", hr, E_INVALIDARG);
102     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
103
104     LargeInt.QuadPart = -1;
105     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos);
106     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
107     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == sizeof(Memory) - 1, "bSeek cursor moved to position (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart);
108
109     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, &uNewPos); /* reset seek pointer */
110     LargeInt.QuadPart = -(LONGLONG)sizeof(Memory) - 5;
111     hr = IWICStream_Seek(pStream, LargeInt, STREAM_SEEK_END, &uNewPos);
112     ok(hr == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW),
113        "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
114     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "bSeek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0); /* remains unchanged */
115     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
116
117
118     /* Read */
119     hr = IWICStream_Read(pStream, MemBuf, 12, &uBytesRead);
120     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
121     if(SUCCEEDED(hr)) {
122         ok(uBytesRead == 12, "Read %u bytes, expected %u\n", uBytesRead, 3);
123         ok(memcmp(MemBuf, CmpMem, 12) == 0, "Read returned invalid data!\n");
124
125         /* check whether the seek pointer has moved correctly */
126         IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
127         ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == uBytesRead, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesRead);
128     }
129
130     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
131
132     hr = IWICStream_Read(pStream, Memory, 10, &uBytesRead);   /* source = dest */
133     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
134     if(SUCCEEDED(hr)) {
135         ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10);
136         ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n");
137     }
138
139     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
140
141     hr = IWICStream_Read(pStream, Memory, sizeof(Memory) + 10, &uBytesRead);   /* request too many bytes */
142     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
143     if(SUCCEEDED(hr)) {
144         ok(uBytesRead == sizeof(Memory), "Read %u bytes\n", uBytesRead);
145         ok(memcmp(Memory, CmpMem, uBytesRead) == 0, "Read returned invalid data!\n");
146     }
147
148     hr = IWICStream_Read(pStream, NULL, 1, &uBytesRead);    /* destination buffer = NULL */
149     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
150
151     hr = IWICStream_Read(pStream, MemBuf, 0, &uBytesRead);    /* read 0 bytes */
152     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
153
154     hr = IWICStream_Read(pStream, NULL, 0, &uBytesRead);
155     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
156
157     hr = IWICStream_Read(pStream, NULL, 0, NULL);
158     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
159
160     hr = IWICStream_Read(pStream, MemBuf, 1, NULL);
161     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
162
163     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
164     ZeroMemory(MemBuf, sizeof(MemBuf));
165     hr = IWICStream_Read(pStream, MemBuf, sizeof(Memory) + 10, &uBytesRead);
166     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
167     if(SUCCEEDED(hr)) {
168         ok(uBytesRead == sizeof(Memory), "Read %u bytes\n", uBytesRead);
169         ok(memcmp(Memory, CmpMem, 64) == 0, "Read returned invalid data!\n");
170     }
171     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
172
173
174     /* Write */
175     MemBuf[0] = CmpMem[0] + 1;
176     MemBuf[1] = CmpMem[1] + 1;
177     MemBuf[2] = CmpMem[2] + 1;
178     hr = IWICStream_Write(pStream, MemBuf, 3, &uBytesWritten);
179     ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK);
180     if(SUCCEEDED(hr)) {
181         ok(uBytesWritten == 3, "Wrote %u bytes, expected %u\n", uBytesWritten, 3);
182         ok(memcmp(MemBuf, Memory, 3) == 0, "Wrote returned invalid data!\n"); /* make sure we're writing directly */
183
184         /* check whether the seek pointer has moved correctly */
185         IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
186         ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == uBytesWritten, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesWritten);
187     }
188     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
189
190     hr = IWICStream_Write(pStream, MemBuf, 0, &uBytesWritten);
191     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
192
193     hr = IWICStream_Write(pStream, NULL, 3, &uBytesWritten);
194     ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
195     ok(uBytesWritten == 0, "Wrote %u bytes, expected %u\n", uBytesWritten, 0);
196     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
197     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
198
199     hr = IWICStream_Write(pStream, NULL, 0, &uBytesWritten);
200     ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
201     ok(uBytesWritten == 0, "Wrote %u bytes, expected %u\n", uBytesWritten, 0);
202     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
203     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
204
205     hr = IWICStream_Write(pStream, CmpMem, sizeof(Memory) + 10, &uBytesWritten);
206     ok(hr == STG_E_MEDIUMFULL, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL);
207     ok(uBytesWritten == 0, "Wrote %u bytes, expected %u\n", uBytesWritten, 0);
208     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
209     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == uBytesWritten, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesWritten);
210     IWICStream_Seek(pStream, LargeNull, STREAM_SEEK_SET, NULL);
211
212
213     /* SetSize */
214     uNewPos.u.HighPart = 0;
215     uNewPos.u.LowPart = sizeof(Memory) + 10;
216     hr = IWICStream_SetSize(pStream, uNewPos);
217     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
218
219     uNewPos.u.HighPart = 0;
220     uNewPos.u.LowPart = sizeof(Memory);
221     hr = IWICStream_SetSize(pStream, uNewPos);
222     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
223
224     uNewPos.u.HighPart = 0;
225     uNewPos.u.LowPart = sizeof(Memory) - 10;
226     hr = IWICStream_SetSize(pStream, uNewPos);
227     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
228
229     uNewPos.u.HighPart = 0;
230     uNewPos.u.LowPart = 0;
231     hr = IWICStream_SetSize(pStream, uNewPos);
232     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
233
234     uNewPos.QuadPart = -10;
235     hr = IWICStream_SetSize(pStream, uNewPos);
236     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
237
238
239     /* CopyTo */
240     uNewPos.u.HighPart = 0;
241     uNewPos.u.LowPart = 5;
242     hr = IWICStream_CopyTo(pStream, NULL, uNewPos, NULL, NULL);
243     ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL);
244
245     hr = IWICImagingFactory_CreateStream(pFactory, &pBufStream);
246     ok(hr == S_OK, "CreateStream failed with %#x\n", hr);
247
248     hr = IWICStream_InitializeFromMemory(pBufStream, Memory, sizeof(Memory));
249     ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
250
251     hr = IWICStream_CopyTo(pStream, (IStream*)pBufStream, uNewPos, NULL, NULL);
252     ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL);
253     IWICStream_Release(pBufStream);
254
255
256     /* Commit */
257     hr = IWICStream_Commit(pStream, STGC_DEFAULT);
258     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
259
260     hr = IWICStream_Commit(pStream, STGC_OVERWRITE);
261     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
262
263     hr = IWICStream_Commit(pStream, STGC_ONLYIFCURRENT);
264     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
265
266     hr = IWICStream_Commit(pStream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
267     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
268
269     hr = IWICStream_Commit(pStream, STGC_CONSOLIDATE);
270     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
271
272
273     /* Revert */
274     IWICStream_Write(pStream, &MemBuf[5], 6, NULL);
275     hr = IWICStream_Revert(pStream);
276     ok(hr == E_NOTIMPL, "Revert returned %#x, expected %#x\n", hr, E_NOTIMPL);
277     memcpy(Memory, CmpMem, sizeof(Memory));
278
279
280     /* LockRegion/UnlockRegion */
281     hr = IWICStream_LockRegion(pStream, uLargeNull, uLargeNull, 0);
282     ok(hr == E_NOTIMPL, "LockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
283
284     hr = IWICStream_UnlockRegion(pStream, uLargeNull, uLargeNull, 0);
285     ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
286
287
288     /* Stat */
289     hr = IWICStream_Stat(pStream, NULL, 0);
290     ok(hr == E_INVALIDARG, "Stat returned %#x, expected %#x\n", hr, E_INVALIDARG);
291
292     hr = IWICStream_Stat(pStream, &Stats, 0);
293     ok(hr == S_OK, "Stat returned %#x, expected %#x\n", hr, S_OK);
294     ok(Stats.pwcsName == NULL, "Stat returned name %p, expected %p\n", Stats.pwcsName, NULL);
295     ok(Stats.type == STGTY_STREAM, "Stat returned type %d, expected %d\n", Stats.type, STGTY_STREAM);
296     ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == sizeof(Memory), "Stat returned size (%u;%u)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart);
297     ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%u;%u), expected (%u;%u)\n", Stats.mtime.dwHighDateTime, Stats.mtime.dwLowDateTime, 0, 0);
298     ok(Stats.ctime.dwHighDateTime == 0 && Stats.ctime.dwLowDateTime == 0, "Stat returned ctime (%u;%u), expected (%u;%u)\n", Stats.ctime.dwHighDateTime, Stats.ctime.dwLowDateTime, 0, 0);
299     ok(Stats.atime.dwHighDateTime == 0 && Stats.atime.dwLowDateTime == 0, "Stat returned atime (%u;%u), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0);
300     ok(Stats.grfMode == 0, "Stat returned access mode %d, expected %d\n", Stats.grfMode, 0);
301     ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#x, expected %#x\n", Stats.grfLocksSupported, 0);
302     ok(Stats.grfStateBits == 0, "Stat returned state bits %#x, expected %#x\n", Stats.grfStateBits, 0);
303
304
305     /* Clone */
306     hr = IWICStream_Clone(pStream, (IStream**)&pBufStream);
307     ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
308
309
310     IWICStream_Release(pStream);
311     IWICStream_Release(pFactory);
312     CoUninitialize();
313 }
314
315 static void test_StreamOnStreamRange(void)
316 {
317     IWICImagingFactory *pFactory;
318     IWICStream *pStream, *pSubStream;
319     IStream *CopyStream;
320     const BYTE CmpMem[] = {
321         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
322         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
323         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
324         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
325     };
326     BYTE Memory[64], MemBuf[64];
327     LARGE_INTEGER LargeNull, LargeInt;
328     ULARGE_INTEGER uLargeNull, uNewPos, uSize;
329     ULONG uBytesRead, uBytesWritten;
330     HRESULT hr;
331     STATSTG Stats;
332
333     LargeNull.QuadPart = 0;
334     uLargeNull.QuadPart = 0;
335
336     memcpy(Memory, CmpMem, sizeof(CmpMem));
337
338     CoInitialize(NULL);
339
340     hr = CoCreateInstance(&CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, &IID_IWICImagingFactory, (void**)&pFactory);
341     if(FAILED(hr)) {
342         skip("CoCreateInstance returned with %#x, expected %#x\n", hr, S_OK);
343         return;
344     }
345
346     hr = IWICImagingFactory_CreateStream(pFactory, &pStream);
347     ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
348     if(FAILED(hr)) {
349         skip("Failed to create stream\n");
350         return;
351     }
352
353     hr = IWICStream_InitializeFromMemory(pStream, Memory, sizeof(Memory));
354     ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
355
356     hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream);
357     ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
358
359     uNewPos.QuadPart = 20;
360     uSize.QuadPart = 20;
361     hr = IWICStream_InitializeFromIStreamRegion(pSubStream, (IStream*)pStream, uNewPos, uSize);
362     ok(hr == S_OK, "InitializeFromIStreamRegion returned with %#x, expected %#x\n", hr, S_OK);
363     if(FAILED(hr)) {
364         skip("InitializeFromIStreamRegion unimplemented\n");
365         IWICStream_Release(pSubStream);
366         IWICStream_Release(pStream);
367         IWICImagingFactory_Release(pFactory);
368         CoUninitialize();
369         return;
370     }
371
372     /* Seek */
373     hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_END, &uNewPos);
374     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 20, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesWritten);
375     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
376
377     hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, &uNewPos);
378     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
379     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
380
381     hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
382     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
383
384     LargeInt.u.HighPart = 1;
385     LargeInt.u.LowPart = 0;
386     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
387     ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
388     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
389
390     LargeInt.QuadPart = 30;
391     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_SET, &uNewPos);
392     ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
393     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
394
395     LargeInt.QuadPart = 1;
396     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos);
397     ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE, "Seek returned with %#x, expected %#x\n", hr, WINCODEC_ERR_VALUEOUTOFRANGE);
398     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
399
400     LargeInt.QuadPart = -1;
401     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos);
402     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
403     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 19, "bSeek cursor moved to position (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart);
404
405     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, &uNewPos); /* reset seek pointer */
406     LargeInt.QuadPart = -25;
407     hr = IWICStream_Seek(pSubStream, LargeInt, STREAM_SEEK_END, &uNewPos);
408     ok(hr == WINCODEC_ERR_VALUEOUTOFRANGE,
409        "Seek returned with %#x, expected %#x\n", hr, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
410     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "bSeek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0); /* remains unchanged */
411     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
412
413
414     /* Read */
415     hr = IWICStream_Read(pSubStream, MemBuf, 12, &uBytesRead);
416     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
417     if(SUCCEEDED(hr)) {
418         ok(uBytesRead == 12, "Read %u bytes, expected %u\n", uBytesRead, 3);
419         ok(memcmp(MemBuf, CmpMem+20, 12) == 0, "Read returned invalid data!\n");
420
421         /* check whether the seek pointer has moved correctly */
422         IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
423         ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == uBytesRead, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesRead);
424     }
425
426     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
427
428     hr = IWICStream_Read(pSubStream, Memory, 10, &uBytesRead);   /* source = dest */
429     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
430     if(SUCCEEDED(hr)) {
431         ok(uBytesRead == 10, "Read %u bytes, expected %u\n", uBytesRead, 10);
432         ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n");
433     }
434
435     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
436
437     hr = IWICStream_Read(pSubStream, Memory, 30, &uBytesRead);   /* request too many bytes */
438     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
439     if(SUCCEEDED(hr)) {
440         ok(uBytesRead == 20, "Read %u bytes\n", uBytesRead);
441         ok(memcmp(Memory, CmpMem+20, uBytesRead) == 0, "Read returned invalid data!\n");
442     }
443
444     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
445     hr = IWICStream_Read(pSubStream, NULL, 1, &uBytesRead);    /* destination buffer = NULL */
446     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
447
448     hr = IWICStream_Read(pSubStream, MemBuf, 0, &uBytesRead);    /* read 0 bytes */
449     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
450
451     hr = IWICStream_Read(pSubStream, NULL, 0, &uBytesRead);
452     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
453
454     hr = IWICStream_Read(pSubStream, NULL, 0, NULL);
455     ok(hr == E_INVALIDARG, "Read returned with %#x, expected %#x\n", hr, E_INVALIDARG);
456
457     hr = IWICStream_Read(pSubStream, MemBuf, 1, NULL);
458     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
459
460     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
461     ZeroMemory(MemBuf, sizeof(MemBuf));
462     hr = IWICStream_Read(pSubStream, MemBuf, 30, &uBytesRead);
463     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
464     if(SUCCEEDED(hr)) {
465         ok(uBytesRead == 20, "Read %u bytes\n", uBytesRead);
466         ok(memcmp(Memory, CmpMem+20, 20) == 0, "Read returned invalid data!\n");
467     }
468     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
469
470
471     /* Write */
472     MemBuf[0] = CmpMem[0] + 1;
473     MemBuf[1] = CmpMem[1] + 1;
474     MemBuf[2] = CmpMem[2] + 1;
475     hr = IWICStream_Write(pSubStream, MemBuf, 3, &uBytesWritten);
476     ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, S_OK);
477     if(SUCCEEDED(hr)) {
478         ok(uBytesWritten == 3, "Wrote %u bytes, expected %u\n", uBytesWritten, 3);
479         ok(memcmp(MemBuf, Memory+20, 3) == 0, "Wrote returned invalid data!\n"); /* make sure we're writing directly */
480
481         /* check whether the seek pointer has moved correctly */
482         IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
483         ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == uBytesWritten, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesWritten);
484     }
485     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
486
487     hr = IWICStream_Write(pSubStream, MemBuf, 0, &uBytesWritten);
488     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
489
490     hr = IWICStream_Write(pSubStream, NULL, 3, &uBytesWritten);
491     ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
492     ok(uBytesWritten == 0, "Wrote %u bytes, expected %u\n", uBytesWritten, 0);
493     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
494     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
495
496     hr = IWICStream_Write(pSubStream, NULL, 0, &uBytesWritten);
497     ok(hr == E_INVALIDARG, "Write returned with %#x, expected %#x\n", hr, E_INVALIDARG);
498     ok(uBytesWritten == 0, "Wrote %u bytes, expected %u\n", uBytesWritten, 0);
499     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
500     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 0, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, 0);
501
502     hr = IWICStream_Write(pSubStream, CmpMem, 30, &uBytesWritten);
503     ok(hr == S_OK, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL);
504     ok(uBytesWritten == 20, "Wrote %u bytes, expected %u\n", uBytesWritten, 0);
505     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
506     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == uBytesWritten, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesWritten);
507     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
508
509
510     /* SetSize */
511     uNewPos.u.HighPart = 0;
512     uNewPos.u.LowPart = sizeof(Memory) + 10;
513     hr = IWICStream_SetSize(pSubStream, uNewPos);
514     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
515
516     uNewPos.u.HighPart = 0;
517     uNewPos.u.LowPart = sizeof(Memory);
518     hr = IWICStream_SetSize(pSubStream, uNewPos);
519     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
520
521     uNewPos.u.HighPart = 0;
522     uNewPos.u.LowPart = sizeof(Memory) - 10;
523     hr = IWICStream_SetSize(pSubStream, uNewPos);
524     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
525
526     uNewPos.u.HighPart = 0;
527     uNewPos.u.LowPart = 0;
528     hr = IWICStream_SetSize(pSubStream, uNewPos);
529     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
530
531     uNewPos.QuadPart = -10;
532     hr = IWICStream_SetSize(pSubStream, uNewPos);
533     ok(hr == E_NOTIMPL, "SetSize returned %#x, expected %#x\n", hr, E_NOTIMPL);
534
535
536     /* CopyTo */
537     uNewPos.u.HighPart = 0;
538     uNewPos.u.LowPart = 30;
539     hr = IWICStream_CopyTo(pSubStream, NULL, uNewPos, NULL, NULL);
540     ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL);
541
542     hr = CreateStreamOnHGlobal(NULL, TRUE, &CopyStream);
543     ok(hr == S_OK, "CreateStream failed with %#x\n", hr);
544
545     hr = IWICStream_CopyTo(pSubStream, CopyStream, uNewPos, NULL, NULL);
546     ok(hr == E_NOTIMPL, "CopyTo returned %#x, expected %#x\n", hr, E_NOTIMPL);
547     IWICStream_Release(CopyStream);
548
549
550     /* Commit */
551     hr = IWICStream_Commit(pSubStream, STGC_DEFAULT);
552     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
553
554     hr = IWICStream_Commit(pSubStream, STGC_OVERWRITE);
555     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
556
557     hr = IWICStream_Commit(pSubStream, STGC_ONLYIFCURRENT);
558     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
559
560     hr = IWICStream_Commit(pSubStream, STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE);
561     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
562
563     hr = IWICStream_Commit(pSubStream, STGC_CONSOLIDATE);
564     ok(hr == E_NOTIMPL, "Commit returned %#x, expected %#x\n", hr, E_NOTIMPL);
565
566
567     /* Revert */
568     IWICStream_Write(pSubStream, &MemBuf[5], 6, NULL);
569     hr = IWICStream_Revert(pSubStream);
570     ok(hr == E_NOTIMPL, "Revert returned %#x, expected %#x\n", hr, E_NOTIMPL);
571     memcpy(Memory, CmpMem, sizeof(Memory));
572
573
574     /* LockRegion/UnlockRegion */
575     hr = IWICStream_LockRegion(pSubStream, uLargeNull, uLargeNull, 0);
576     ok(hr == E_NOTIMPL, "LockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
577
578     hr = IWICStream_UnlockRegion(pSubStream, uLargeNull, uLargeNull, 0);
579     ok(hr == E_NOTIMPL, "UnlockRegion returned %#x, expected %#x\n", hr, E_NOTIMPL);
580
581
582     /* Stat */
583     hr = IWICStream_Stat(pSubStream, NULL, 0);
584     ok(hr == E_INVALIDARG, "Stat returned %#x, expected %#x\n", hr, E_INVALIDARG);
585
586     hr = IWICStream_Stat(pSubStream, &Stats, 0);
587     ok(hr == S_OK, "Stat returned %#x, expected %#x\n", hr, S_OK);
588     ok(Stats.pwcsName == NULL, "Stat returned name %p, expected %p\n", Stats.pwcsName, NULL);
589     ok(Stats.type == STGTY_STREAM, "Stat returned type %d, expected %d\n", Stats.type, STGTY_STREAM);
590     ok(Stats.cbSize.u.HighPart == 0 && Stats.cbSize.u.LowPart == 20, "Stat returned size (%u;%u)\n", Stats.cbSize.u.HighPart, Stats.cbSize.u.LowPart);
591     ok(Stats.mtime.dwHighDateTime == 0 && Stats.mtime.dwLowDateTime == 0, "Stat returned mtime (%u;%u), expected (%u;%u)\n", Stats.mtime.dwHighDateTime, Stats.mtime.dwLowDateTime, 0, 0);
592     ok(Stats.ctime.dwHighDateTime == 0 && Stats.ctime.dwLowDateTime == 0, "Stat returned ctime (%u;%u), expected (%u;%u)\n", Stats.ctime.dwHighDateTime, Stats.ctime.dwLowDateTime, 0, 0);
593     ok(Stats.atime.dwHighDateTime == 0 && Stats.atime.dwLowDateTime == 0, "Stat returned atime (%u;%u), expected (%u;%u)\n", Stats.atime.dwHighDateTime, Stats.atime.dwLowDateTime, 0, 0);
594     ok(Stats.grfMode == 0, "Stat returned access mode %d, expected %d\n", Stats.grfMode, 0);
595     ok(Stats.grfLocksSupported == 0, "Stat returned supported locks %#x, expected %#x\n", Stats.grfLocksSupported, 0);
596     ok(Stats.grfStateBits == 0, "Stat returned state bits %#x, expected %#x\n", Stats.grfStateBits, 0);
597
598
599     /* Clone */
600     hr = IWICStream_Clone(pSubStream, &CopyStream);
601     ok(hr == E_NOTIMPL, "Clone returned %#x, expected %#x\n", hr, E_NOTIMPL);
602
603
604     IWICStream_Release(pSubStream);
605
606
607     /* Recreate, this time larger than the original. */
608     hr = IWICImagingFactory_CreateStream(pFactory, &pSubStream);
609     ok(hr == S_OK, "CreateStream returned with %#x, expected %#x\n", hr, S_OK);
610
611     uNewPos.QuadPart = 48;
612     uSize.QuadPart = 32;
613     hr = IWICStream_InitializeFromIStreamRegion(pSubStream, (IStream*)pStream, uNewPos, uSize);
614     ok(hr == S_OK, "InitializeFromMemory returned with %#x, expected %#x\n", hr, S_OK);
615
616     hr = IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_END, &uNewPos);
617     ok(hr == S_OK, "Seek returned with %#x, expected %#x\n", hr, S_OK);
618     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == 16, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesWritten);
619
620     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
621     hr = IWICStream_Read(pSubStream, Memory, 48, &uBytesRead);
622     ok(hr == S_OK, "Read returned with %#x, expected %#x\n", hr, S_OK);
623     if(SUCCEEDED(hr)) {
624         ok(uBytesRead == 16, "Read %u bytes\n", uBytesRead);
625         ok(memcmp(Memory, CmpMem+48, uBytesRead) == 0, "Read returned invalid data!\n");
626     }
627
628     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_SET, NULL);
629     uBytesWritten = 0;
630     hr = IWICStream_Write(pSubStream, CmpMem, 32, &uBytesWritten);
631     ok(hr == STG_E_MEDIUMFULL, "Write returned with %#x, expected %#x\n", hr, STG_E_MEDIUMFULL);
632     ok(uBytesWritten == 0, "Wrote %u bytes, expected %u\n", uBytesWritten, 0);
633     IWICStream_Seek(pSubStream, LargeNull, STREAM_SEEK_CUR, &uNewPos);
634     ok(uNewPos.u.HighPart == 0 && uNewPos.u.LowPart == uBytesWritten, "Seek cursor moved to position (%u;%u), expected (%u;%u)\n", uNewPos.u.HighPart, uNewPos.u.LowPart, 0, uBytesWritten);
635
636
637     IWICStream_Release(pSubStream);
638     IWICStream_Release(pStream);
639     IWICStream_Release(pFactory);
640     CoUninitialize();
641 }
642
643 START_TEST(stream)
644 {
645     test_StreamOnMemory();
646     test_StreamOnStreamRange();
647 }