source: trunk/src/avifil32/iafile.c@ 8045

Last change on this file since 8045 was 6712, checked in by sandervl, 24 years ago

restored old version

File size: 18.4 KB
Line 
1/*
2 * Copyright 1999 Marcus Meissner
3 * Copyright 2001 Hidenori TAKESHIMA <hidenori@a2.ctktv.ne.jp>
4 *
5 * FIXME - implements editing/writing.
6 */
7
8#include <string.h>
9#include <stdio.h>
10#include <assert.h>
11
12#include "winbase.h"
13#include "winnls.h"
14#include "mmsystem.h"
15#include "winerror.h"
16#include "vfw.h"
17#include "debugtools.h"
18#include "avifile_private.h"
19
20DEFAULT_DEBUG_CHANNEL(avifile);
21
22#define AVIFILE_STREAMS_MAX 4
23
24
25static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj);
26static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface);
27static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface);
28static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size);
29static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam);
30static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi);
31static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size);
32static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size);
33static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface);
34static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam);
35
36struct ICOM_VTABLE(IAVIFile) iavift = {
37 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
38 IAVIFile_fnQueryInterface,
39 IAVIFile_fnAddRef,
40 IAVIFile_fnRelease,
41 IAVIFile_fnInfo,
42 IAVIFile_fnGetStream,
43 IAVIFile_fnCreateStream,
44 IAVIFile_fnWriteData,
45 IAVIFile_fnReadData,
46 IAVIFile_fnEndRecord,
47 IAVIFile_fnDeleteStream,
48 /* IAVIFILE_fnOpen */ /* FIXME? */
49};
50
51
52typedef struct IAVIFileImpl
53{
54 ICOM_VFIELD(IAVIFile);
55 /* IUnknown stuff */
56 DWORD ref;
57 /* IAVIFile stuff */
58 HANDLE hf;
59 DWORD dwAVIFileCaps;
60 DWORD dwAVIFileScale;
61 DWORD dwAVIFileRate;
62 DWORD dwAVIFileLength;
63 DWORD dwAVIFileEditCount;
64 MainAVIHeader hdr;
65 IAVIStream* pStreams[AVIFILE_STREAMS_MAX];
66 AVIStreamHeader strhdrs[AVIFILE_STREAMS_MAX];
67 DWORD dwMoviTop;
68 DWORD dwCountOfIndexEntry;
69 AVIINDEXENTRY* pIndexEntry;
70 AVIINDEXENTRY* pStreamIndexEntry[AVIFILE_STREAMS_MAX+1];
71} IAVIFileImpl;
72
73
74/****************************************************************************
75 * AVI file parser.
76 */
77
78static HRESULT AVIFILE_IAVIFile_ReadNextChunkHeader(
79 IAVIFileImpl* This, FOURCC* pfcc, DWORD* pdwSize )
80{
81 BYTE buf[8];
82 DWORD dwRead;
83
84 if ( ( !ReadFile( This->hf, buf, 8, &dwRead, NULL ) ) ||
85 ( 8 != dwRead ) )
86 return AVIERR_FILEREAD;
87 *pfcc = mmioFOURCC(buf[0],buf[1],buf[2],buf[3]);
88 *pdwSize = ( ((DWORD)buf[4]) ) |
89 ( ((DWORD)buf[5]) << 8 ) |
90 ( ((DWORD)buf[6]) << 16 ) |
91 ( ((DWORD)buf[7]) << 24 );
92
93 return S_OK;
94}
95
96static HRESULT AVIFILE_IAVIFile_SkipChunkData(
97 IAVIFileImpl* This, DWORD dwChunkSize )
98{
99 LONG lHigh = 0;
100 DWORD dwRes;
101
102 if ( dwChunkSize == 0 )
103 return S_OK;
104
105 SetLastError(NO_ERROR);
106 dwRes = SetFilePointer( This->hf, (LONG)dwChunkSize,
107 &lHigh, FILE_CURRENT );
108 if ( dwRes == (DWORD)0xffffffff && GetLastError() != NO_ERROR )
109 return AVIERR_FILEREAD;
110
111 return S_OK;
112}
113
114static HRESULT AVIFILE_IAVIFile_ReadChunkData(
115 IAVIFileImpl* This, DWORD dwChunkSize,
116 LPVOID lpvBuf, DWORD dwBufSize, LPDWORD lpdwRead )
117{
118 if ( dwBufSize > dwChunkSize )
119 dwBufSize = dwChunkSize;
120 if ( ( !ReadFile( This->hf, lpvBuf, dwBufSize, lpdwRead, NULL ) ) ||
121 ( dwBufSize != *lpdwRead ) )
122 return AVIERR_FILEREAD;
123
124 return AVIFILE_IAVIFile_SkipChunkData( This, dwChunkSize - dwBufSize );
125}
126
127static HRESULT AVIFILE_IAVIFile_SeekToSpecifiedChunk(
128 IAVIFileImpl* This, FOURCC fccType, DWORD* pdwLen )
129{
130 HRESULT hr;
131 FOURCC fcc;
132 BYTE buf[4];
133 DWORD dwRead;
134
135 while ( 1 )
136 {
137 hr = AVIFILE_IAVIFile_ReadNextChunkHeader(
138 This, &fcc, pdwLen );
139 if ( hr != S_OK )
140 return hr;
141 if ( fcc == fccType )
142 return S_OK;
143
144 if ( fcc == FOURCC_LIST )
145 {
146 if ( ( !ReadFile( This->hf, buf, 4, &dwRead, NULL ) ) ||
147 ( 4 != dwRead ) )
148 return AVIERR_FILEREAD;
149 }
150 else
151 {
152 hr = AVIFILE_IAVIFile_SkipChunkData(
153 This, *pdwLen );
154 if ( hr != S_OK )
155 return hr;
156 }
157 }
158}
159
160
161WINE_AVISTREAM_DATA* AVIFILE_Alloc_IAVIStreamData( DWORD dwFmtLen )
162{
163 WINE_AVISTREAM_DATA* pData;
164
165 pData = (WINE_AVISTREAM_DATA*)
166 HeapAlloc( AVIFILE_data.hHeap,HEAP_ZERO_MEMORY,
167 sizeof(WINE_AVISTREAM_DATA) );
168 if ( pData == NULL )
169 return NULL;
170 if ( dwFmtLen > 0 )
171 {
172 pData->pbFmt = (BYTE*)
173 HeapAlloc( AVIFILE_data.hHeap,HEAP_ZERO_MEMORY,
174 sizeof(BYTE)*dwFmtLen );
175 if ( pData->pbFmt == NULL )
176 {
177 AVIFILE_Free_IAVIStreamData( pData );
178 return NULL;
179 }
180 }
181 pData->dwFmtLen = dwFmtLen;
182
183 return pData;
184}
185
186void AVIFILE_Free_IAVIStreamData( WINE_AVISTREAM_DATA* pData )
187{
188 if ( pData != NULL )
189 {
190 if ( pData->pbFmt != NULL )
191 HeapFree( AVIFILE_data.hHeap,0,pData->pbFmt );
192 HeapFree( AVIFILE_data.hHeap,0,pData );
193 }
194}
195
196static void AVIFILE_IAVIFile_InitIndexTable(
197 IAVIFileImpl* This,
198 AVIINDEXENTRY* pIndexBuf,
199 AVIINDEXENTRY* pIndexData,
200 DWORD dwCountOfIndexEntry )
201{
202 DWORD dwStreamIndex;
203 DWORD dwIndex;
204 FOURCC ckid;
205
206 dwStreamIndex = 0;
207 for ( ; dwStreamIndex < (AVIFILE_STREAMS_MAX+1); dwStreamIndex ++ )
208 This->pStreamIndexEntry[dwStreamIndex] = NULL;
209
210 dwStreamIndex = 0;
211 for ( ; dwStreamIndex < This->hdr.dwStreams; dwStreamIndex ++ )
212 {
213 ckid = mmioFOURCC('0','0'+dwStreamIndex,0,0);
214 TRACE( "testing ckid %c%c%c%c\n",
215 (int)(ckid>> 0)&0xff,
216 (int)(ckid>> 8)&0xff,
217 (int)(ckid>>16)&0xff,
218 (int)(ckid>>24)&0xff );
219 This->pStreamIndexEntry[dwStreamIndex] = pIndexBuf;
220 FIXME( "pIndexBuf = %p\n", pIndexBuf );
221 for ( dwIndex = 0; dwIndex < dwCountOfIndexEntry; dwIndex++ )
222 {
223 TRACE( "ckid %c%c%c%c\n",
224 (int)(pIndexData[dwIndex].ckid>> 0)&0xff,
225 (int)(pIndexData[dwIndex].ckid>> 8)&0xff,
226 (int)(pIndexData[dwIndex].ckid>>16)&0xff,
227 (int)(pIndexData[dwIndex].ckid>>24)&0xff );
228
229 if ( (pIndexData[dwIndex].ckid & mmioFOURCC(0xff,0xff,0,0))
230 == ckid )
231 {
232 memcpy( pIndexBuf, &pIndexData[dwIndex],
233 sizeof(AVIINDEXENTRY) );
234 pIndexBuf ++;
235 }
236 }
237 FIXME( "pIndexBuf = %p\n", pIndexBuf );
238 }
239 This->pStreamIndexEntry[This->hdr.dwStreams] = pIndexBuf;
240}
241
242
243/****************************************************************************
244 * Create an IAVIFile object.
245 */
246
247static HRESULT AVIFILE_IAVIFile_Construct( IAVIFileImpl* This );
248static void AVIFILE_IAVIFile_Destruct( IAVIFileImpl* This );
249
250HRESULT AVIFILE_CreateIAVIFile(void** ppobj)
251{
252 IAVIFileImpl *This;
253 HRESULT hr;
254
255 TRACE("(%p)\n",ppobj);
256 *ppobj = NULL;
257 This = (IAVIFileImpl*)HeapAlloc(AVIFILE_data.hHeap,HEAP_ZERO_MEMORY,
258 sizeof(IAVIFileImpl));
259 if ( This == NULL )
260 return AVIERR_MEMORY;
261 This->ref = 1;
262 ICOM_VTBL(This) = &iavift;
263 hr = AVIFILE_IAVIFile_Construct( This );
264 if ( hr != S_OK )
265 {
266 AVIFILE_IAVIFile_Destruct( This );
267 return hr;
268 }
269
270 TRACE("new -> %p\n",This);
271 *ppobj = (LPVOID)This;
272
273 return S_OK;
274}
275
276/****************************************************************************
277 * IUnknown interface
278 */
279
280static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj) {
281 ICOM_THIS(IAVIFileImpl,iface);
282
283 TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj);
284 if ( IsEqualGUID(&IID_IUnknown,refiid) ||
285 IsEqualGUID(&IID_IAVIFile,refiid) )
286 {
287 *obj = iface;
288 IAVIFile_AddRef(iface);
289 return S_OK;
290 }
291 return OLE_E_ENUM_NOMORE;
292}
293
294static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface) {
295 ICOM_THIS(IAVIFileImpl,iface);
296
297 TRACE("(%p)->AddRef()\n",iface);
298 return ++(This->ref);
299}
300
301static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface) {
302 ICOM_THIS(IAVIFileImpl,iface);
303
304 TRACE("(%p)->Release()\n",iface);
305 if ( (--(This->ref)) > 0 )
306 return This->ref;
307
308 AVIFILE_IAVIFile_Destruct(This);
309 HeapFree(AVIFILE_data.hHeap,0,iface);
310 return 0;
311}
312
313/****************************************************************************
314 * IAVIFile interface
315 */
316
317static HRESULT AVIFILE_IAVIFile_Construct( IAVIFileImpl* This )
318{
319 DWORD dwIndex;
320
321 This->hf = INVALID_HANDLE_VALUE;
322 This->dwAVIFileCaps = 0;
323 This->dwAVIFileScale = 0;
324 This->dwAVIFileRate = 0;
325 This->dwAVIFileLength = 0;
326 This->dwAVIFileEditCount = 0;
327 for ( dwIndex = 0; dwIndex < AVIFILE_STREAMS_MAX; dwIndex++ )
328 This->pStreams[dwIndex] = NULL;
329 This->dwCountOfIndexEntry = 0;
330 This->pIndexEntry = NULL;
331
332 AVIFILE_data.dwClassObjRef ++;
333
334 return S_OK;
335}
336
337static void AVIFILE_IAVIFile_Destruct( IAVIFileImpl* This )
338{
339 DWORD dwIndex;
340
341 if ( This->pIndexEntry != NULL )
342 {
343 HeapFree(AVIFILE_data.hHeap,0,This->pIndexEntry);
344 This->pIndexEntry = NULL;
345 }
346
347 for ( dwIndex = 0; dwIndex < AVIFILE_STREAMS_MAX; dwIndex++ )
348 {
349 if ( This->pStreams[dwIndex] != NULL )
350 {
351 IAVIStream_Release( This->pStreams[dwIndex] );
352 This->pStreams[dwIndex] = NULL;
353 }
354 }
355
356 if ( This->hf != INVALID_HANDLE_VALUE )
357 CloseHandle( This->hf );
358
359 AVIFILE_data.dwClassObjRef --;
360}
361
362static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size)
363{
364 ICOM_THIS(IAVIFileImpl,iface);
365 AVIFILEINFOW fiw;
366
367 FIXME("(%p)->Info(%p,%ld)\n",iface,afi,size);
368
369 memset( &fiw, 0, sizeof(fiw) );
370 fiw.dwMaxBytesPerSec = This->hdr.dwMaxBytesPerSec;
371 fiw.dwFlags = This->hdr.dwFlags;
372 fiw.dwCaps = This->dwAVIFileCaps;
373 fiw.dwStreams = This->hdr.dwStreams;
374 fiw.dwSuggestedBufferSize = This->hdr.dwSuggestedBufferSize;
375 fiw.dwWidth = This->hdr.dwWidth;
376 fiw.dwHeight = This->hdr.dwHeight;
377 fiw.dwScale = This->dwAVIFileScale; /* FIXME */
378 fiw.dwRate = This->dwAVIFileRate; /* FIXME */
379 fiw.dwLength = This->dwAVIFileLength; /* FIXME */
380 fiw.dwEditCount = This->dwAVIFileEditCount; /* FIXME */
381 /* fiw.szFileType[64]; */
382
383 if ( size > sizeof(AVIFILEINFOW) )
384 size = sizeof(AVIFILEINFOW);
385 memcpy( afi, &fiw, size );
386
387 return S_OK;
388}
389
390static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam)
391{
392 ICOM_THIS(IAVIFileImpl,iface);
393
394 FIXME("(%p)->GetStream(%p,0x%08lx,%ld)\n",iface,avis,fccType,lParam);
395 if ( fccType != 0 )
396 return E_FAIL;
397 if ( lParam < 0 || lParam >= This->hdr.dwStreams )
398 return E_FAIL;
399 *avis = This->pStreams[lParam];
400 IAVIStream_AddRef( *avis );
401
402 return S_OK;
403}
404
405static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi)
406{
407 ICOM_THIS(IAVIFileImpl,iface);
408
409 FIXME("(%p,%p,%p)\n",This,avis,asi);
410 return E_FAIL;
411}
412
413static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size)
414{
415 ICOM_THIS(IAVIFileImpl,iface);
416
417 FIXME("(%p)->WriteData(0x%08lx,%p,%ld)\n",This,ckid,lpData,size);
418 /* FIXME: write data to file */
419 return E_FAIL;
420}
421
422static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size)
423{
424 ICOM_THIS(IAVIFileImpl,iface);
425
426 FIXME("(%p)->ReadData(0x%08lx,%p,%p)\n",This,ckid,lpData,size);
427 /* FIXME: read at most size bytes from file */
428
429 return E_FAIL;
430}
431
432static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface)
433{
434 ICOM_THIS(IAVIFileImpl,iface);
435
436 FIXME("(%p)->EndRecord()\n",This);
437 /* FIXME: end record? */
438 return E_FAIL;
439}
440
441static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam)
442{
443 ICOM_THIS(IAVIFileImpl,iface);
444
445 FIXME("(%p)->DeleteStream(0x%08lx,%ld)\n",This,fccType,lParam);
446 /* FIXME: delete stream? */
447 return E_FAIL;
448}
449
450/*****************************************************************************
451 * AVIFILE_IAVIFile_Open (internal)
452 */
453HRESULT AVIFILE_IAVIFile_Open( PAVIFILE paf, LPCWSTR szFile, UINT uMode )
454{
455 ICOM_THIS(IAVIFileImpl,paf);
456 HRESULT hr;
457 DWORD dwAcc;
458 DWORD dwShared;
459 DWORD dwCreate;
460 BYTE buf[12];
461 DWORD dwRead;
462 FOURCC fccFileType;
463 DWORD dwLen;
464 DWORD dwIndex;
465
466 FIXME("(%p)->Open(%p,%u)\n",This,szFile,uMode);
467
468 if ( This->hf != INVALID_HANDLE_VALUE )
469 {
470 CloseHandle( This->hf );
471 This->hf = INVALID_HANDLE_VALUE;
472 }
473
474 switch ( uMode & 0x3 )
475 {
476 case OF_READ: /* 0x0 */
477 dwAcc = GENERIC_READ;
478 dwCreate = OPEN_EXISTING;
479 This->dwAVIFileCaps = AVIFILECAPS_CANREAD;
480 break;
481 case OF_WRITE: /* 0x1 */
482 dwAcc = GENERIC_WRITE;
483 dwCreate = OPEN_ALWAYS;
484 This->dwAVIFileCaps = AVIFILECAPS_CANWRITE;
485 break;
486 case OF_READWRITE: /* 0x2 */
487 dwAcc = GENERIC_READ|GENERIC_WRITE;
488 dwCreate = OPEN_ALWAYS;
489 This->dwAVIFileCaps = AVIFILECAPS_CANREAD|AVIFILECAPS_CANWRITE;
490 break;
491 default:
492 return E_FAIL;
493 }
494
495 if ( This->dwAVIFileCaps & AVIFILECAPS_CANWRITE )
496 {
497 FIXME( "editing AVI is currently not supported!\n" );
498 return E_FAIL;
499 }
500
501 switch ( uMode & 0x70 )
502 {
503 case OF_SHARE_COMPAT: /* 0x00 */
504 dwShared = FILE_SHARE_READ|FILE_SHARE_WRITE;
505 break;
506 case OF_SHARE_EXCLUSIVE: /* 0x10 */
507 dwShared = 0;
508 break;
509 case OF_SHARE_DENY_WRITE: /* 0x20 */
510 dwShared = FILE_SHARE_READ;
511 break;
512 case OF_SHARE_DENY_READ: /* 0x30 */
513 dwShared = FILE_SHARE_WRITE;
514 break;
515 case OF_SHARE_DENY_NONE: /* 0x40 */
516 dwShared = FILE_SHARE_READ|FILE_SHARE_WRITE;
517 break;
518 default:
519 return E_FAIL;
520 }
521 if ( uMode & OF_CREATE )
522 dwCreate = CREATE_ALWAYS;
523
524 This->hf = CreateFileW( szFile, dwAcc, dwShared, NULL,
525 dwCreate, FILE_ATTRIBUTE_NORMAL,
526 (HANDLE)NULL );
527 if ( This->hf == INVALID_HANDLE_VALUE )
528 return AVIERR_FILEOPEN;
529
530 if ( dwAcc & GENERIC_READ )
531 {
532 if ( !ReadFile( This->hf, buf, 12, &dwRead, NULL ) )
533 return AVIERR_FILEREAD;
534 if ( dwRead == 12 )
535 {
536 if ( mmioFOURCC(buf[0],buf[1],buf[2],buf[3]) != FOURCC_RIFF )
537 return AVIERR_BADFORMAT;
538
539 fccFileType = mmioFOURCC(buf[8],buf[9],buf[10],buf[11]);
540 if ( fccFileType != formtypeAVI )
541 return AVIERR_BADFORMAT;
542
543 /* get AVI main header. */
544 hr = AVIFILE_IAVIFile_SeekToSpecifiedChunk(
545 This, ckidAVIMAINHDR, &dwLen );
546 if ( hr != S_OK )
547 return hr;
548 if ( dwLen < (sizeof(DWORD)*10) )
549 return AVIERR_BADFORMAT;
550 hr = AVIFILE_IAVIFile_ReadChunkData(
551 This, dwLen,
552 &(This->hdr), sizeof(MainAVIHeader), &dwLen );
553 if ( This->hdr.dwStreams == 0 ||
554 This->hdr.dwStreams > AVIFILE_STREAMS_MAX )
555 return AVIERR_BADFORMAT;
556
557 /* get stream headers. */
558 dwIndex = 0;
559 while ( dwIndex < This->hdr.dwStreams )
560 {
561 WINE_AVISTREAM_DATA* pData;
562
563 hr = AVIFILE_IAVIFile_SeekToSpecifiedChunk(
564 This, ckidSTREAMHEADER, &dwLen );
565 if ( hr != S_OK )
566 return hr;
567 if ( dwLen < (sizeof(DWORD)*12) )
568 return AVIERR_BADFORMAT;
569 hr = AVIFILE_IAVIFile_ReadChunkData(
570 This, dwLen,
571 &This->strhdrs[dwIndex],
572 sizeof(AVIStreamHeader), &dwLen );
573
574 hr = AVIFILE_IAVIFile_SeekToSpecifiedChunk(
575 This, ckidSTREAMFORMAT, &dwLen );
576 if ( hr != S_OK )
577 return hr;
578 pData = AVIFILE_Alloc_IAVIStreamData( dwLen );
579 if ( pData == NULL )
580 return AVIERR_MEMORY;
581 hr = AVIFILE_IAVIFile_ReadChunkData(
582 This, dwLen,
583 pData->pbFmt, dwLen, &dwLen );
584 if ( hr != S_OK )
585 {
586 AVIFILE_Free_IAVIStreamData( pData );
587 return hr;
588 }
589 pData->dwStreamIndex = dwIndex;
590 pData->pstrhdr = &This->strhdrs[dwIndex];
591
592 hr = AVIStreamCreate(&This->pStreams[dwIndex],
593 (LONG)paf, (LONG)(pData), NULL );
594 if ( hr != S_OK )
595 {
596 AVIFILE_Free_IAVIStreamData( pData );
597 return hr;
598 }
599
600 if ( (This->strhdrs[dwIndex].fccType
601 == mmioFOURCC('v','i','d','s')) ||
602 (This->strhdrs[dwIndex].fccType
603 == mmioFOURCC('V','I','D','S')) )
604 {
605 This->dwAVIFileScale =
606 This->strhdrs[dwIndex].dwScale;
607 This->dwAVIFileRate =
608 This->strhdrs[dwIndex].dwRate;
609 This->dwAVIFileLength =
610 This->strhdrs[dwIndex].dwLength;
611 }
612 else
613 if ( This->dwAVIFileScale == 0 )
614 {
615 This->dwAVIFileScale =
616 This->strhdrs[dwIndex].dwScale;
617 This->dwAVIFileRate =
618 This->strhdrs[dwIndex].dwRate;
619 This->dwAVIFileLength =
620 This->strhdrs[dwIndex].dwLength;
621 }
622
623 dwIndex ++;
624 }
625
626 /* skip movi. */
627 while ( 1 )
628 {
629 hr = AVIFILE_IAVIFile_SeekToSpecifiedChunk(
630 This, FOURCC_LIST, &dwLen );
631 if ( hr != S_OK )
632 return hr;
633 if ( dwLen < 4 )
634 return AVIERR_BADFORMAT;
635
636 This->dwMoviTop = SetFilePointer( This->hf,0,NULL,FILE_CURRENT );
637 if ( This->dwMoviTop == 0xffffffff )
638 return AVIERR_BADFORMAT;
639
640 if ( ( !ReadFile(This->hf, buf, 4, &dwRead, NULL) ) ||
641 ( dwRead != 4 ) )
642 return AVIERR_FILEREAD;
643
644 hr = AVIFILE_IAVIFile_SkipChunkData(
645 This, dwLen - 4 );
646 if ( hr != S_OK )
647 return hr;
648 if ( mmioFOURCC(buf[0],buf[1],buf[2],buf[3])
649 == mmioFOURCC('m', 'o', 'v', 'i') )
650 break;
651 }
652
653 /* get idx1. */
654 hr = AVIFILE_IAVIFile_SeekToSpecifiedChunk(
655 This, ckidAVINEWINDEX, &dwLen );
656 if ( hr != S_OK )
657 return hr;
658
659 This->dwCountOfIndexEntry = dwLen / sizeof(AVIINDEXENTRY);
660 This->pIndexEntry = (AVIINDEXENTRY*)
661 HeapAlloc(AVIFILE_data.hHeap,HEAP_ZERO_MEMORY,
662 sizeof(AVIINDEXENTRY) *
663 This->dwCountOfIndexEntry * 2 );
664 if ( This->pIndexEntry == NULL )
665 return AVIERR_MEMORY;
666 hr = AVIFILE_IAVIFile_ReadChunkData(
667 This, dwLen,
668 This->pIndexEntry + This->dwCountOfIndexEntry,
669 sizeof(AVIINDEXENTRY) *
670 This->dwCountOfIndexEntry, &dwLen );
671 if ( hr != S_OK )
672 return hr;
673 AVIFILE_IAVIFile_InitIndexTable(
674 This, This->pIndexEntry,
675 This->pIndexEntry + This->dwCountOfIndexEntry,
676 This->dwCountOfIndexEntry );
677 }
678 else
679 {
680 /* FIXME - create the handle has GENERIC_WRITE access. */
681 return AVIERR_FILEREAD;
682 }
683 }
684 else
685 {
686 return AVIERR_FILEOPEN; /* FIXME */
687 }
688
689 return S_OK;
690}
691
692/*****************************************************************************
693 * AVIFILE_IAVIFile_GetIndexTable (internal)
694 */
695HRESULT AVIFILE_IAVIFile_GetIndexTable( PAVIFILE paf, DWORD dwStreamIndex,
696 AVIINDEXENTRY** ppIndexEntry,
697 DWORD* pdwCountOfIndexEntry )
698{
699 ICOM_THIS(IAVIFileImpl,paf);
700
701 if ( dwStreamIndex < 0 || dwStreamIndex >= This->hdr.dwStreams )
702 {
703 FIXME( "invalid stream index %lu\n", dwStreamIndex );
704 return E_FAIL;
705 }
706 FIXME( "cur %p, next %p\n",
707 This->pStreamIndexEntry[dwStreamIndex],
708 This->pStreamIndexEntry[dwStreamIndex+1] );
709 *ppIndexEntry = This->pStreamIndexEntry[dwStreamIndex];
710 *pdwCountOfIndexEntry =
711 This->pStreamIndexEntry[dwStreamIndex+1] -
712 This->pStreamIndexEntry[dwStreamIndex];
713
714 return S_OK;
715}
716
717/*****************************************************************************
718 * AVIFILE_IAVIFile_ReadMovieData (internal)
719 */
720HRESULT AVIFILE_IAVIFile_ReadMovieData( PAVIFILE paf, DWORD dwOffset,
721 DWORD dwLength, LPVOID lpvBuf )
722{
723 ICOM_THIS(IAVIFileImpl,paf);
724 LONG lHigh = 0;
725 DWORD dwRes;
726
727 if ( dwLength == 0 )
728 return S_OK;
729 SetLastError(NO_ERROR);
730 dwRes = SetFilePointer( This->hf, (LONG)(dwOffset+This->dwMoviTop),
731 &lHigh, FILE_BEGIN );
732 if ( dwRes == (DWORD)0xffffffff && GetLastError() != NO_ERROR )
733 return AVIERR_FILEREAD;
734
735 if ( ( !ReadFile(This->hf, lpvBuf, dwLength, &dwRes, NULL) ) ||
736 ( dwLength != dwRes ) )
737 {
738 FIXME( "error in ReadFile()\n" );
739 return AVIERR_FILEREAD;
740 }
741
742 return S_OK;
743}
744
Note: See TracBrowser for help on using the repository browser.