2 * Copyright 2001 Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "wine/debug.h"
29 #include "avifile_private.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(avifile);
33 static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj);
34 static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface);
35 static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface);
36 static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2);
37 static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size);
38 static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags);
39 static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize);
40 static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize);
41 static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread);
42 static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten);
43 static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples);
44 static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread);
45 static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size);
46 static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen);
49 struct ICOM_VTABLE(IAVIStream) iavist = {
50 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
51 IAVIStream_fnQueryInterface,
56 IAVIStream_fnFindSample,
57 IAVIStream_fnReadFormat,
58 IAVIStream_fnSetFormat,
62 IAVIStream_fnReadData,
63 IAVIStream_fnWriteData,
69 typedef struct IAVIStreamImpl
71 ICOM_VFIELD(IAVIStream);
74 /* IAVIStream stuff */
76 WINE_AVISTREAM_DATA* pData;
79 static HRESULT IAVIStream_Construct( IAVIStreamImpl* This );
80 static void IAVIStream_Destruct( IAVIStreamImpl* This );
82 HRESULT AVIFILE_CreateIAVIStream(void** ppobj)
88 This = (IAVIStreamImpl*)HeapAlloc(AVIFILE_data.hHeap,HEAP_ZERO_MEMORY,
89 sizeof(IAVIStreamImpl));
91 ICOM_VTBL(This) = &iavist;
92 hr = IAVIStream_Construct( This );
95 IAVIStream_Destruct( This );
99 *ppobj = (LPVOID)This;
105 /****************************************************************************
109 static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj) {
110 ICOM_THIS(IAVIStreamImpl,iface);
112 TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
113 if ( IsEqualGUID(&IID_IUnknown,refiid) ||
114 IsEqualGUID(&IID_IAVIStream,refiid) )
116 IAVIStream_AddRef(iface);
120 /* can return IGetFrame interface too */
122 return OLE_E_ENUM_NOMORE;
125 static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface) {
126 ICOM_THIS(IAVIStreamImpl,iface);
128 TRACE("(%p)->AddRef()\n",iface);
129 return ++(This->ref);
132 static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface) {
133 ICOM_THIS(IAVIStreamImpl,iface);
135 TRACE("(%p)->Release()\n",iface);
136 if ((--(This->ref)) > 0 )
138 IAVIStream_Destruct(This);
140 HeapFree(AVIFILE_data.hHeap,0,iface);
144 /****************************************************************************
145 * IAVIStream interface
148 static HRESULT IAVIStream_Construct( IAVIStreamImpl* This )
153 AVIFILE_data.dwClassObjRef ++;
158 static void IAVIStream_Destruct( IAVIStreamImpl* This )
160 AVIFILE_data.dwClassObjRef --;
163 static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2)
165 ICOM_THIS(IAVIStreamImpl,iface);
167 FIXME("(%p)->Create(%ld,%ld)\n",iface,lParam1,lParam2);
169 This->paf = (IAVIFile*)lParam1;
170 This->pData = (WINE_AVISTREAM_DATA*)lParam2;
175 static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size)
177 ICOM_THIS(IAVIStreamImpl,iface);
180 FIXME("(%p)->Info(%p,%ld)\n",iface,psi,size);
181 if ( This->pData == NULL )
184 memset( &siw, 0, sizeof(AVISTREAMINFOW) );
185 siw.fccType = This->pData->pstrhdr->fccType;
186 siw.fccHandler = This->pData->pstrhdr->fccHandler;
187 siw.dwFlags = This->pData->pstrhdr->dwFlags;
188 siw.dwCaps = 0; /* FIXME */
189 siw.wPriority = This->pData->pstrhdr->wPriority;
190 siw.wLanguage = This->pData->pstrhdr->wLanguage;
191 siw.dwScale = This->pData->pstrhdr->dwScale;
192 siw.dwRate = This->pData->pstrhdr->dwRate;
193 siw.dwStart = This->pData->pstrhdr->dwStart;
194 siw.dwLength = This->pData->pstrhdr->dwLength;
195 siw.dwInitialFrames = This->pData->pstrhdr->dwInitialFrames;
196 siw.dwSuggestedBufferSize = This->pData->pstrhdr->dwSuggestedBufferSize;
197 siw.dwQuality = This->pData->pstrhdr->dwQuality;
198 siw.dwSampleSize = This->pData->pstrhdr->dwSampleSize;
199 siw.rcFrame.left = This->pData->pstrhdr->rcFrame.left;
200 siw.rcFrame.top = This->pData->pstrhdr->rcFrame.top;
201 siw.rcFrame.right = This->pData->pstrhdr->rcFrame.right;
202 siw.rcFrame.bottom = This->pData->pstrhdr->rcFrame.bottom;
203 siw.dwEditCount = 0; /* FIXME */
204 siw.dwFormatChangeCount = 0; /* FIXME */
207 if ( size > sizeof(AVISTREAMINFOW) )
208 size = sizeof(AVISTREAMINFOW);
209 memcpy( psi, &siw, size );
214 static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags)
216 ICOM_THIS(IAVIStreamImpl,iface);
218 AVIINDEXENTRY* pIndexEntry;
219 DWORD dwCountOfIndexEntry;
220 LONG lCur, lAdd, lEnd;
222 FIXME("(%p)->FindSample(%ld,0x%08lx)\n",This,pos,flags);
224 hr = AVIFILE_IAVIFile_GetIndexTable(
225 This->paf, This->pData->dwStreamIndex,
226 &pIndexEntry, &dwCountOfIndexEntry );
230 if ( flags & (~(FIND_DIR|FIND_TYPE|FIND_RET)) )
232 FIXME( "unknown flag %08lx\n", flags );
236 switch ( flags & FIND_DIR )
241 lEnd = dwCountOfIndexEntry;
242 if ( lCur > dwCountOfIndexEntry )
247 if ( lCur > dwCountOfIndexEntry )
248 lCur = dwCountOfIndexEntry;
252 case FIND_FROM_START:
255 lEnd = dwCountOfIndexEntry;
258 FIXME( "unknown direction flag %08lx\n", (flags & FIND_DIR) );
262 switch ( flags & FIND_TYPE )
267 if ( pIndexEntry[lCur].dwFlags & AVIIF_KEYFRAME )
277 if ( !(pIndexEntry[lCur].dwFlags & AVIIF_NOTIME) )
285 FIXME( "FIND_FORMAT is not implemented.\n" );
288 FIXME( "unknown type flag %08lx\n", (flags & FIND_TYPE) );
292 switch ( flags & FIND_RET )
297 FIXME( "FIND_LENGTH is not implemented.\n" );
300 return pIndexEntry[lCur].dwChunkOffset;
302 return pIndexEntry[lCur].dwChunkLength;
304 FIXME( "FIND_INDEX is not implemented.\n" );
307 FIXME( "unknown return type flag %08lx\n", (flags & FIND_RET) );
314 static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize) {
315 ICOM_THIS(IAVIStreamImpl,iface);
317 TRACE("(%p)->ReadFormat(%ld,%p,%p)\n",This,pos,format,formatsize);
318 if ( This->pData == NULL )
321 /* FIXME - check pos. */
322 if ( format == NULL )
324 *formatsize = This->pData->dwFmtLen;
327 if ( (*formatsize) < This->pData->dwFmtLen )
328 return AVIERR_BUFFERTOOSMALL;
330 memcpy( format, This->pData->pbFmt, This->pData->dwFmtLen );
331 *formatsize = This->pData->dwFmtLen;
336 static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize) {
337 ICOM_THIS(IAVIStreamImpl,iface);
339 FIXME("(%p)->SetFormat(%ld,%p,%ld)\n",This,pos,format,formatsize);
343 static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) {
344 ICOM_THIS(IAVIStreamImpl,iface);
346 AVIINDEXENTRY* pIndexEntry;
347 DWORD dwCountOfIndexEntry;
350 FIXME("(%p)->Read(%ld,%ld,%p,%ld,%p,%p)\n",This,start,samples,buffer,buffersize,bytesread,samplesread);
355 hr = AVIFILE_IAVIFile_GetIndexTable(
356 This->paf, This->pData->dwStreamIndex,
357 &pIndexEntry, &dwCountOfIndexEntry );
362 if ( start >= dwCountOfIndexEntry || samples <= 0 )
364 FIXME("start %ld,samples %ld,total %ld\n",start,samples,dwCountOfIndexEntry);
368 /* FIXME - no audio support. */
369 dwFrameLength = pIndexEntry[start].dwChunkLength;
371 if ( buffer == NULL )
373 *bytesread = dwFrameLength;
377 if ( buffersize < dwFrameLength )
379 FIXME( "buffer is too small!\n" );
380 return AVIERR_BUFFERTOOSMALL;
383 hr = AVIFILE_IAVIFile_ReadMovieData(
385 pIndexEntry[start].dwChunkOffset + sizeof(DWORD)*2,
386 dwFrameLength, buffer );
389 FIXME( "ReadMovieData failed!\n");
392 *bytesread = dwFrameLength;
398 static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) {
399 ICOM_THIS(IAVIStreamImpl,iface);
402 FIXME("(%p)->Write(%ld,%ld,%p,%ld,0x%08lx,%p,%p)\n",This,start,samples,buffer,buffersize,flags,sampwritten,byteswritten);
406 static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples) {
407 ICOM_THIS(IAVIStreamImpl,iface);
409 FIXME("(%p)->Delete(%ld,%ld)\n",This,start,samples);
412 static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread) {
413 ICOM_THIS(IAVIStreamImpl,iface);
415 FIXME("(%p)->ReadData(0x%08lx,%p,%p)\n",This,fcc,lp,lpread);
419 static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size) {
420 ICOM_THIS(IAVIStreamImpl,iface);
422 FIXME("(%p)->WriteData(0x%08lx,%p,%ld)\n",This,fcc,lp,size);
426 static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen) {
427 ICOM_THIS(IAVIStreamImpl,iface);
429 FIXME("(%p)->SetInfo(%p,%ld)\n",This,info,infolen);