Added mappings for a few messages.
[wine] / dlls / avifil32 / iastream.c
1 /*
2  * Copyright 2001 Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
3  */
4
5 #include <string.h>
6 #include <stdio.h>
7 #include <assert.h>
8
9 #include "winbase.h"
10 #include "winnls.h"
11 #include "mmsystem.h"
12 #include "winerror.h"
13 #include "vfw.h"
14 #include "debugtools.h"
15 #include "avifile_private.h"
16
17 DEFAULT_DEBUG_CHANNEL(avifile);
18
19 static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj);
20 static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface);
21 static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface);
22 static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2);
23 static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size);
24 static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags);
25 static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize);
26 static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize);
27 static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread);
28 static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten);
29 static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples);
30 static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread);
31 static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size);
32 static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen);
33
34
35 struct ICOM_VTABLE(IAVIStream) iavist = {
36     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
37     IAVIStream_fnQueryInterface,
38     IAVIStream_fnAddRef,
39     IAVIStream_fnRelease,
40     IAVIStream_fnCreate,
41     IAVIStream_fnInfo,
42     IAVIStream_fnFindSample,
43     IAVIStream_fnReadFormat,
44     IAVIStream_fnSetFormat,
45     IAVIStream_fnRead,
46     IAVIStream_fnWrite,
47     IAVIStream_fnDelete,
48     IAVIStream_fnReadData,
49     IAVIStream_fnWriteData,
50     IAVIStream_fnSetInfo
51 };
52
53
54
55 typedef struct IAVIStreamImpl
56 {
57         ICOM_VFIELD(IAVIStream);
58         /* IUnknown stuff */
59         DWORD           ref;
60         /* IAVIStream stuff */
61         IAVIFile*               paf;
62         WINE_AVISTREAM_DATA*    pData;
63 } IAVIStreamImpl;
64
65 static HRESULT IAVIStream_Construct( IAVIStreamImpl* This );
66 static void IAVIStream_Destruct( IAVIStreamImpl* This );
67
68 HRESULT AVIFILE_CreateIAVIStream(void** ppobj)
69 {
70         IAVIStreamImpl  *This;
71         HRESULT         hr;
72
73         *ppobj = NULL;
74         This = (IAVIStreamImpl*)HeapAlloc(AVIFILE_data.hHeap,HEAP_ZERO_MEMORY,
75                                           sizeof(IAVIStreamImpl));
76         This->ref = 1;
77         ICOM_VTBL(This) = &iavist;
78         hr = IAVIStream_Construct( This );
79         if ( hr != S_OK )
80         {
81                 IAVIStream_Destruct( This );
82                 return hr;
83         }
84
85         *ppobj = (LPVOID)This;
86
87         return S_OK;
88 }
89
90
91 /****************************************************************************
92  * IUnknown interface
93  */
94
95 static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj) {
96         ICOM_THIS(IAVIStreamImpl,iface);
97
98         TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
99         if ( IsEqualGUID(&IID_IUnknown,refiid) ||
100              IsEqualGUID(&IID_IAVIStream,refiid) )
101         {
102                 IAVIStream_AddRef(iface);
103                 *obj = iface;
104                 return S_OK;
105         }
106         /* can return IGetFrame interface too */
107
108         return OLE_E_ENUM_NOMORE;
109 }
110
111 static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface) {
112         ICOM_THIS(IAVIStreamImpl,iface);
113
114         TRACE("(%p)->AddRef()\n",iface);
115         return ++(This->ref);
116 }
117
118 static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface) {
119         ICOM_THIS(IAVIStreamImpl,iface);
120
121         TRACE("(%p)->Release()\n",iface);
122         if ((--(This->ref)) > 0 )
123                 return This->ref;
124         IAVIStream_Destruct(This);
125
126         HeapFree(AVIFILE_data.hHeap,0,iface);
127         return 0;
128 }
129
130 /****************************************************************************
131  * IAVIStream interface
132  */
133
134 static HRESULT IAVIStream_Construct( IAVIStreamImpl* This )
135 {
136         This->paf = NULL;
137         This->pData = NULL;
138
139         AVIFILE_data.dwClassObjRef ++;
140
141         return S_OK;
142 }
143
144 static void IAVIStream_Destruct( IAVIStreamImpl* This )
145 {
146         AVIFILE_data.dwClassObjRef --;
147 }
148
149 static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2)
150 {
151         ICOM_THIS(IAVIStreamImpl,iface);
152
153         FIXME("(%p)->Create(%ld,%ld)\n",iface,lParam1,lParam2);
154
155         This->paf = (IAVIFile*)lParam1;
156         This->pData = (WINE_AVISTREAM_DATA*)lParam2;
157
158         return S_OK;
159 }
160
161 static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size)
162 {
163         ICOM_THIS(IAVIStreamImpl,iface);
164         AVISTREAMINFOW  siw;
165
166         FIXME("(%p)->Info(%p,%ld)\n",iface,psi,size);
167         if ( This->pData == NULL )
168                 return E_UNEXPECTED;
169
170         memset( &siw, 0, sizeof(AVISTREAMINFOW) );
171         siw.fccType = This->pData->pstrhdr->fccType;
172         siw.fccHandler = This->pData->pstrhdr->fccHandler;
173         siw.dwFlags = This->pData->pstrhdr->dwFlags;
174         siw.dwCaps = 0; /* FIXME */
175         siw.wPriority = This->pData->pstrhdr->wPriority;
176         siw.wLanguage = This->pData->pstrhdr->wLanguage;
177         siw.dwScale = This->pData->pstrhdr->dwScale;
178         siw.dwRate = This->pData->pstrhdr->dwRate;
179         siw.dwStart = This->pData->pstrhdr->dwStart;
180         siw.dwLength = This->pData->pstrhdr->dwLength;
181         siw.dwInitialFrames = This->pData->pstrhdr->dwInitialFrames;
182         siw.dwSuggestedBufferSize = This->pData->pstrhdr->dwSuggestedBufferSize;
183         siw.dwQuality = This->pData->pstrhdr->dwQuality;
184         siw.dwSampleSize = This->pData->pstrhdr->dwSampleSize;
185         siw.rcFrame.left = This->pData->pstrhdr->rcFrame.left;
186         siw.rcFrame.top = This->pData->pstrhdr->rcFrame.top;
187         siw.rcFrame.right = This->pData->pstrhdr->rcFrame.right;
188         siw.rcFrame.bottom = This->pData->pstrhdr->rcFrame.bottom;
189         siw.dwEditCount = 0; /* FIXME */
190         siw.dwFormatChangeCount = 0; /* FIXME */
191         /* siw.szName[64] */
192
193         if ( size > sizeof(AVISTREAMINFOW) )
194                 size = sizeof(AVISTREAMINFOW);
195         memcpy( psi, &siw, size );
196
197         return S_OK;
198 }
199
200 static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags)
201 {
202         ICOM_THIS(IAVIStreamImpl,iface);
203         HRESULT hr;
204         AVIINDEXENTRY*  pIndexEntry;
205         DWORD           dwCountOfIndexEntry;
206         LONG            lCur, lAdd, lEnd;
207
208         FIXME("(%p)->FindSample(%ld,0x%08lx)\n",This,pos,flags);
209
210         hr = AVIFILE_IAVIFile_GetIndexTable(
211                 This->paf, This->pData->dwStreamIndex,
212                 &pIndexEntry, &dwCountOfIndexEntry );
213         if ( hr != S_OK )
214                 return -1L;
215
216         if ( flags & (~(FIND_DIR|FIND_TYPE|FIND_RET)) )
217         {
218                 FIXME( "unknown flag %08lx\n", flags );
219                 return -1L;
220         }
221
222         switch ( flags & FIND_DIR )
223         {
224         case FIND_NEXT:
225                 lCur = pos;
226                 lAdd = 1;
227                 lEnd = dwCountOfIndexEntry;
228                 if ( lCur > dwCountOfIndexEntry )
229                         return -1L;
230                 break;
231         case FIND_PREV:
232                 lCur = pos;
233                 if ( lCur > dwCountOfIndexEntry )
234                         lCur = dwCountOfIndexEntry;
235                 lAdd = -1;
236                 lEnd = 0;
237                 break;
238         case FIND_FROM_START:
239                 lCur = 0;
240                 lAdd = 1;
241                 lEnd = dwCountOfIndexEntry;
242                 break;
243         default:
244                 FIXME( "unknown direction flag %08lx\n", (flags & FIND_DIR) );
245                 return -1L;
246         }
247
248         switch ( flags & FIND_TYPE )
249         {
250         case FIND_KEY:
251                 while ( 1 )
252                 {
253                         if ( pIndexEntry[lCur].dwFlags & AVIIF_KEYFRAME )
254                                 break;
255                         if ( lCur == lEnd )
256                                 return -1L;
257                         lCur += lAdd;
258                 }
259                 break;
260         case FIND_ANY:
261                 while ( 1 )
262                 {
263                         if ( !(pIndexEntry[lCur].dwFlags & AVIIF_NOTIME) )
264                                 break;
265                         if ( lCur == lEnd )
266                                 return -1L;
267                         lCur += lAdd;
268                 }
269                 break;
270         case FIND_FORMAT:
271                 FIXME( "FIND_FORMAT is not implemented.\n" );
272                 return -1L;
273         default:
274                 FIXME( "unknown type flag %08lx\n", (flags & FIND_TYPE) );
275                 return -1L;
276         }
277
278         switch ( flags & FIND_RET )
279         {
280         case FIND_POS:
281                 return lCur;
282         case FIND_LENGTH:
283                 FIXME( "FIND_LENGTH is not implemented.\n" );
284                 return -1L;
285         case FIND_OFFSET:
286                 return pIndexEntry[lCur].dwChunkOffset;
287         case FIND_SIZE:
288                 return pIndexEntry[lCur].dwChunkLength;
289         case FIND_INDEX:
290                 FIXME( "FIND_INDEX is not implemented.\n" );
291                 return -1L;
292         default:
293                 FIXME( "unknown return type flag %08lx\n", (flags & FIND_RET) );
294                 break;
295         }
296
297         return -1L;
298 }
299
300 static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize) {
301         ICOM_THIS(IAVIStreamImpl,iface);
302
303         TRACE("(%p)->ReadFormat(%ld,%p,%p)\n",This,pos,format,formatsize);
304         if ( This->pData == NULL )
305                 return E_UNEXPECTED;
306
307         /* FIXME - check pos. */
308         if ( format == NULL )
309         {
310                 *formatsize = This->pData->dwFmtLen;
311                 return S_OK;
312         }
313         if ( (*formatsize) < This->pData->dwFmtLen )
314                 return AVIERR_BUFFERTOOSMALL;
315
316         memcpy( format, This->pData->pbFmt, This->pData->dwFmtLen );
317         *formatsize = This->pData->dwFmtLen;
318
319         return S_OK;
320 }
321
322 static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize) {
323         ICOM_THIS(IAVIStreamImpl,iface);
324
325         FIXME("(%p)->SetFormat(%ld,%p,%ld)\n",This,pos,format,formatsize);
326         return E_FAIL;
327 }
328
329 static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) {
330         ICOM_THIS(IAVIStreamImpl,iface);
331         HRESULT hr;
332         AVIINDEXENTRY*  pIndexEntry;
333         DWORD           dwCountOfIndexEntry;
334         DWORD           dwFrameLength;
335
336         FIXME("(%p)->Read(%ld,%ld,%p,%ld,%p,%p)\n",This,start,samples,buffer,buffersize,bytesread,samplesread);
337
338         *bytesread = 0;
339         *samplesread = 0;
340
341         hr = AVIFILE_IAVIFile_GetIndexTable(
342                 This->paf, This->pData->dwStreamIndex,
343                 &pIndexEntry, &dwCountOfIndexEntry );
344         if ( hr != S_OK )
345                 return hr;
346         if ( start < 0 )
347                 return E_FAIL;
348         if ( start >= dwCountOfIndexEntry || samples <= 0 )
349         {
350                 FIXME("start %ld,samples %ld,total %ld\n",start,samples,dwCountOfIndexEntry);
351                 return S_OK;
352         }
353
354         /* FIXME - is this data valid??? */
355         dwFrameLength = pIndexEntry[start].dwChunkLength + sizeof(DWORD)*2;
356
357         if ( buffer == NULL )
358         {
359                 *bytesread = dwFrameLength;
360                 *samplesread = 1;
361                 return S_OK;
362         }
363         if ( buffersize < dwFrameLength )
364         {
365                 FIXME( "buffer is too small!\n" );
366                 return AVIERR_BUFFERTOOSMALL;
367         }
368
369         hr = AVIFILE_IAVIFile_ReadMovieData(
370                         This->paf,
371                         pIndexEntry[start].dwChunkOffset,
372                         dwFrameLength, buffer );
373         if ( hr != S_OK )
374         {
375                 FIXME( "ReadMovieData failed!\n");
376                 return hr;
377         }
378         *bytesread = dwFrameLength;
379         *samplesread = 1;
380
381         return S_OK;
382 }
383
384 static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) {
385         ICOM_THIS(IAVIStreamImpl,iface);
386
387
388         FIXME("(%p)->Write(%ld,%ld,%p,%ld,0x%08lx,%p,%p)\n",This,start,samples,buffer,buffersize,flags,sampwritten,byteswritten);
389         return E_FAIL;
390 }
391
392 static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples) {
393         ICOM_THIS(IAVIStreamImpl,iface);
394
395         FIXME("(%p)->Delete(%ld,%ld)\n",This,start,samples);
396         return E_FAIL;
397 }
398 static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread) {
399         ICOM_THIS(IAVIStreamImpl,iface);
400
401         FIXME("(%p)->ReadData(0x%08lx,%p,%p)\n",This,fcc,lp,lpread);
402         return E_FAIL;
403 }
404
405 static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size) {
406         ICOM_THIS(IAVIStreamImpl,iface);
407
408         FIXME("(%p)->WriteData(0x%08lx,%p,%ld)\n",This,fcc,lp,size);
409         return E_FAIL;
410 }
411
412 static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen) {
413         ICOM_THIS(IAVIStreamImpl,iface);
414
415         FIXME("(%p)->SetInfo(%p,%ld)\n",This,info,infolen);
416
417         return E_FAIL;
418 }
419