diff --git a/dlls/avifil32/Makefile.in b/dlls/avifil32/Makefile.in index e303b87ba3b..c8738dea1cc 100644 --- a/dlls/avifil32/Makefile.in +++ b/dlls/avifil32/Makefile.in @@ -10,7 +10,13 @@ LDDLLFLAGS = @LDDLLFLAGS@ SYMBOLFILE = $(MODULE).tmp.o C_SRCS = \ - avifile.c + api.c \ + comentry.c \ + iafile.c \ + iastream.c \ + igframe.c \ + main.c \ + string.c @MAKE_DLL_RULES@ diff --git a/dlls/avifil32/api.c b/dlls/avifil32/api.c new file mode 100644 index 00000000000..f9ba622d45e --- /dev/null +++ b/dlls/avifil32/api.c @@ -0,0 +1,545 @@ +/* + * Copyright 1999 Marcus Meissner + * Copyright 2001 Hidenori TAKESHIMA + */ + +#include +#include +#include + +#include "winbase.h" +#include "winnls.h" +#include "mmsystem.h" +#include "winerror.h" +#include "ole2.h" +#include "vfw.h" +#include "debugtools.h" + +DEFAULT_DEBUG_CHANNEL(avifile); + +#include "avifile_private.h" + + +/*********************************************************************** + * AVIFileInit (AVIFIL32.@) + */ +void WINAPI AVIFileInit(void) +{ + TRACE("()\n"); + if ( AVIFILE_data.dwAVIFileRef == 0 ) + { + if ( FAILED(CoInitialize(NULL)) ) + AVIFILE_data.fInitCOM = FALSE; + else + AVIFILE_data.fInitCOM = TRUE; + } + AVIFILE_data.dwAVIFileRef ++; +} + +/*********************************************************************** + * AVIFileExit (AVIFIL32.@) + */ +void WINAPI AVIFileExit(void) +{ + TRACE("()\n"); + if ( AVIFILE_data.dwAVIFileRef == 0 ) + { + ERR( "unexpected AVIFileExit()\n" ); + return; + } + + AVIFILE_data.dwAVIFileRef --; + if ( AVIFILE_data.dwAVIFileRef == 0 ) + { + if ( AVIFILE_data.fInitCOM ) + { + CoUninitialize(); + AVIFILE_data.fInitCOM = FALSE; + } + } +} + +/*********************************************************************** + * AVIFileAddRef (AVIFIL32.@) + */ +ULONG WINAPI AVIFileAddRef(PAVIFILE pfile) +{ + return IAVIFile_AddRef( pfile ); +} + +/*********************************************************************** + * AVIFileRelease (AVIFIL32.@) + */ +ULONG WINAPI AVIFileRelease(PAVIFILE pfile) +{ + return IAVIFile_Release( pfile ); +} + +/*********************************************************************** + * AVIFileOpenA (AVIFIL32.@) + */ +HRESULT WINAPI AVIFileOpenA( + PAVIFILE* ppfile,LPCSTR szFile,UINT uMode,LPCLSID lpHandler ) +{ + WCHAR* pwsz; + HRESULT hr; + + TRACE("(%p,%p,%u,%p)\n",ppfile,szFile,uMode,lpHandler); + pwsz = AVIFILE_strdupAtoW( szFile ); + if ( pwsz == NULL ) + return AVIERR_MEMORY; + hr = AVIFileOpenW(ppfile,pwsz,uMode,lpHandler); + HeapFree( AVIFILE_data.hHeap, 0, pwsz ); + return hr; +} + +/*********************************************************************** + * AVIFileOpenW (AVIFIL32.@) + */ +HRESULT WINAPI AVIFileOpenW( + PAVIFILE* ppfile,LPCWSTR szFile,UINT uMode,LPCLSID lpHandler ) +{ + HRESULT hr; + IClassFactory* pcf; + CLSID clsRIFF; + + TRACE("(%p,%p,%u,%p)\n",ppfile,szFile,uMode,lpHandler); + *ppfile = (PAVIFILE)NULL; + + if ( lpHandler == NULL ) + { + /* FIXME - check RIFF type and get a handler from registry + * if IAVIFile::Open is worked... + */ + memcpy( &clsRIFF, &CLSID_AVIFile, sizeof(CLSID) ); + lpHandler = &clsRIFF; + } + + /* + * FIXME - MS says IAVIFile::Open will be called, + * but no such method in vfw.h... why???? + */ + if ( !IsEqualGUID( lpHandler, &CLSID_AVIFile ) ) + return REGDB_E_CLASSNOTREG; + + hr = AVIFILE_DllGetClassObject(&CLSID_AVIFile, + &IID_IClassFactory,(void**)&pcf); + if ( hr != S_OK ) + return hr; + + hr = IClassFactory_CreateInstance( pcf, NULL, &IID_IAVIFile, + (void**)ppfile ); + IClassFactory_Release( pcf ); + + if ( hr == S_OK ) + { + /* FIXME??? */ + hr = AVIFILE_IAVIFile_Open( *ppfile, szFile, uMode ); + if ( hr != S_OK ) + { + IAVIFile_Release( (*ppfile) ); + *ppfile = NULL; + } + } + + return hr; +} + +/*********************************************************************** + * AVIFileInfoW (AVIFIL32.@) + */ +HRESULT WINAPI AVIFileInfoW(PAVIFILE pfile,AVIFILEINFOW* pfi,LONG lSize) +{ + return IAVIFile_Info( pfile, pfi, lSize ); +} + +/*********************************************************************** + * AVIFileInfoA (AVIFIL32.@) + */ +HRESULT WINAPI AVIFileInfoA(PAVIFILE pfile,AVIFILEINFOA* pfi,LONG lSize) +{ + AVIFILEINFOW fiw; + HRESULT hr; + + if ( lSize < sizeof(AVIFILEINFOA) ) + return AVIERR_BADSIZE; + hr = AVIFileInfoW( pfile, &fiw, sizeof(AVIFILEINFOW) ); + if ( hr != S_OK ) + return hr; + memcpy( pfi,&fiw,sizeof(AVIFILEINFOA) ); + AVIFILE_strncpyWtoA( pfi->szFileType, fiw.szFileType, + sizeof(pfi->szFileType) ); + pfi->szFileType[sizeof(pfi->szFileType)-1] = 0; + + return S_OK; +} + +/*********************************************************************** + * AVIFileGetStream (AVIFIL32.@) + */ +HRESULT WINAPI AVIFileGetStream(PAVIFILE pfile,PAVISTREAM* pas,DWORD fccType,LONG lParam) +{ + return IAVIFile_GetStream(pfile,pas,fccType,lParam); +} + +/*********************************************************************** + * AVIFileCreateStreamW (AVIFIL32.@) + */ +HRESULT WINAPI AVIFileCreateStreamW(PAVIFILE pfile,PAVISTREAM* ppas,AVISTREAMINFOW* pasi) +{ + return IAVIFile_CreateStream(pfile,ppas,pasi); +} + +/*********************************************************************** + * AVIFileCreateStreamA (AVIFIL32.@) + */ +HRESULT WINAPI AVIFileCreateStreamA(PAVIFILE pfile,PAVISTREAM* ppas,AVISTREAMINFOA* pasi) +{ + AVISTREAMINFOW siw; + HRESULT hr; + + memcpy( &siw,pasi,sizeof(AVISTREAMINFOA) ); + AVIFILE_strncpyAtoW( siw.szName, pasi->szName, + sizeof(siw.szName)/sizeof(siw.szName[0]) ); + siw.szName[sizeof(siw.szName)/sizeof(siw.szName[0])-1] = 0; + + hr = AVIFileCreateStreamW(pfile,ppas,&siw); + + return hr; +} + +/*********************************************************************** + * AVIFileWriteData (AVIFIL32.@) + */ +HRESULT WINAPI AVIFileWriteData( + PAVIFILE pfile,DWORD dwChunkId,LPVOID lpvData,LONG cbData ) +{ + return IAVIFile_WriteData( pfile,dwChunkId,lpvData,cbData ); +} + +/*********************************************************************** + * AVIFileReadData (AVIFIL32.@) + */ +HRESULT WINAPI AVIFileReadData( + PAVIFILE pfile,DWORD dwChunkId,LPVOID lpvData,LPLONG pcbData ) +{ + return IAVIFile_ReadData( pfile,dwChunkId,lpvData,pcbData ); +} + +/*********************************************************************** + * AVIFileEndRecord (AVIFIL32.@) + */ +HRESULT WINAPI AVIFileEndRecord( PAVIFILE pfile ) +{ + return IAVIFile_EndRecord( pfile ); +} + +/*********************************************************************** + * AVIStreamAddRef (AVIFIL32.@) + */ +ULONG WINAPI AVIStreamAddRef(PAVISTREAM pas) +{ + return IAVIStream_Release(pas); +} + +/*********************************************************************** + * AVIStreamRelease (AVIFIL32.@) + */ +ULONG WINAPI AVIStreamRelease(PAVISTREAM pas) +{ + return IAVIStream_Release(pas); +} + +/*********************************************************************** + * AVIStreamInfoW (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamInfoW(PAVISTREAM pas,AVISTREAMINFOW* psi,LONG lSize) +{ + return IAVIStream_Info(pas,psi,lSize); +} + +/*********************************************************************** + * AVIStreamInfoA (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamInfoA(PAVISTREAM pas,AVISTREAMINFOA* psi,LONG lSize) +{ + AVISTREAMINFOW siw; + HRESULT hr; + + if (lSize < sizeof(AVISTREAMINFOA)) + return AVIERR_BADSIZE; + hr = AVIStreamInfoW(pas,&siw,sizeof(AVISTREAMINFOW)); + if ( hr != S_OK ) + return hr; + memcpy( psi,&siw,sizeof(AVIFILEINFOA) ); + AVIFILE_strncpyWtoA( psi->szName, siw.szName, sizeof(psi->szName) ); + psi->szName[sizeof(psi->szName)-1] = 0; + + return hr; +} + +/*********************************************************************** + * AVIStreamFindSample (AVIFIL32.@) + */ +LONG WINAPI AVIStreamFindSample(PAVISTREAM pas,LONG lPos,LONG lFlags) +{ + return IAVIStream_FindSample(pas,lPos,lFlags); +} + +/*********************************************************************** + * AVIStreamReadFormat (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamReadFormat(PAVISTREAM pas,LONG pos,LPVOID format,LONG *formatsize) { + return IAVIStream_ReadFormat(pas,pos,format,formatsize); +} + +/*********************************************************************** + * AVIStreamSetFormat (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamSetFormat(PAVISTREAM pas,LONG pos,LPVOID format,LONG formatsize) { + return IAVIStream_SetFormat(pas,pos,format,formatsize); +} + +/*********************************************************************** + * AVIStreamReadData (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamReadData(PAVISTREAM pas,DWORD fcc,LPVOID lp,LONG *lpread) { + return IAVIStream_ReadData(pas,fcc,lp,lpread); +} + +/*********************************************************************** + * AVIStreamWriteData (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamWriteData(PAVISTREAM pas,DWORD fcc,LPVOID lp,LONG size) { + return IAVIStream_WriteData(pas,fcc,lp,size); +} + +/*********************************************************************** + * AVIStreamRead (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamRead(PAVISTREAM pas,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) +{ + return IAVIStream_Read(pas,start,samples,buffer,buffersize,bytesread,samplesread); +} + +/*********************************************************************** + * AVIStreamWrite (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamWrite(PAVISTREAM pas,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) { + return IAVIStream_Write(pas,start,samples,buffer,buffersize,flags,sampwritten,byteswritten); +} + + +/*********************************************************************** + * AVIStreamStart (AVIFIL32.@) + */ +LONG WINAPI AVIStreamStart(PAVISTREAM pas) +{ + AVISTREAMINFOW si; + HRESULT hr; + + hr = IAVIStream_Info(pas,&si,sizeof(si)); + if (hr != S_OK) + return -1; + return (LONG)si.dwStart; +} + +/*********************************************************************** + * AVIStreamLength (AVIFIL32.@) + */ +LONG WINAPI AVIStreamLength(PAVISTREAM pas) +{ + AVISTREAMINFOW si; + HRESULT hr; + + hr = IAVIStream_Info(pas,&si,sizeof(si)); + if (hr != S_OK) + return -1; + return (LONG)si.dwLength; +} + +/*********************************************************************** + * AVIStreamTimeToSample (AVIFIL32.@) + */ +LONG WINAPI AVIStreamTimeToSample(PAVISTREAM pas,LONG lTime) +{ + AVISTREAMINFOW si; + HRESULT hr; + + hr = IAVIStream_Info(pas,&si,sizeof(si)); + if (hr != S_OK) + return -1; + + /* I am too lazy... */ + FIXME("(%p,%ld)",pas,lTime); + return (LONG)-1L; +} + +/*********************************************************************** + * AVIStreamSampleToTime (AVIFIL32.@) + */ +LONG WINAPI AVIStreamSampleToTime(PAVISTREAM pas,LONG lSample) +{ + AVISTREAMINFOW si; + HRESULT hr; + + hr = IAVIStream_Info(pas,&si,sizeof(si)); + if (hr != S_OK) + return -1; + + /* I am too lazy... */ + FIXME("(%p,%ld)",pas,lSample); + return (LONG)-1L; +} + +/*********************************************************************** + * AVIStreamBeginStreaming (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamBeginStreaming(PAVISTREAM pas,LONG lStart,LONG lEnd,LONG lRate) +{ + FIXME("(%p)->(%ld,%ld,%ld),stub!\n",pas,lStart,lEnd,lRate); + return E_FAIL; +} + +/*********************************************************************** + * AVIStreamEndStreaming (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamEndStreaming(PAVISTREAM pas) +{ + FIXME("(%p)->(),stub!\n",pas); + return E_FAIL; +} + +/*********************************************************************** + * AVIStreamGetFrameOpen (AVIFIL32.@) + */ +PGETFRAME WINAPI AVIStreamGetFrameOpen(PAVISTREAM pas,LPBITMAPINFOHEADER pbi) +{ + IGetFrame* pgf; + HRESULT hr; + AVISTREAMINFOW si; + + FIXME("(%p,%p)\n",pas,pbi); + + hr = IAVIStream_Info(pas,&si,sizeof(si)); + if (hr != S_OK) + return NULL; + + hr = AVIFILE_CreateIGetFrame((void**)&pgf,pas,pbi); + if ( hr != S_OK ) + return NULL; + hr = IGetFrame_Begin( pgf, si.dwStart, si.dwLength, 1000 ); + if ( hr != S_OK ) + { + IGetFrame_Release( pgf ); + return NULL; + } + + return pgf; +} + +/*********************************************************************** + * AVIStreamGetFrame (AVIFIL32.@) + */ +LPVOID WINAPI AVIStreamGetFrame(PGETFRAME pgf, LONG lPos) +{ + return IGetFrame_GetFrame(pgf,lPos); +} + +/*********************************************************************** + * AVIStreamGetFrameClose (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamGetFrameClose(PGETFRAME pgf) +{ + return IGetFrame_End(pgf); +} + +/*********************************************************************** + * AVIStreamOpenFromFileA (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamOpenFromFileA(PAVISTREAM* ppas, LPCSTR szFile, DWORD fccType, LONG lParam, UINT uMode, CLSID* lpHandler) +{ + WCHAR* pwsz; + HRESULT hr; + + pwsz = AVIFILE_strdupAtoW( szFile ); + if ( pwsz == NULL ) + return AVIERR_MEMORY; + hr = AVIStreamOpenFromFileW(ppas,pwsz,fccType,lParam,uMode,lpHandler); + HeapFree( AVIFILE_data.hHeap, 0, pwsz ); + return hr; +} + +/*********************************************************************** + * AVIStreamOpenFromFileW (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamOpenFromFileW(PAVISTREAM* ppas, LPCWSTR szFile, DWORD fccType, LONG lParam, UINT uMode, CLSID* lpHandler) +{ + HRESULT hr; + PAVIFILE paf; + AVIFILEINFOW fi; + + *ppas = NULL; + hr = AVIFileOpenW(&paf,szFile,uMode,lpHandler); + if ( hr != S_OK ) + return hr; + hr = AVIFileInfoW(paf,&fi,sizeof(AVIFILEINFOW)); + if ( hr == S_OK ) + hr = AVIFileGetStream(paf,ppas,fccType,lParam); + + IAVIFile_Release(paf); + + return hr; +} + +/*********************************************************************** + * AVIStreamCreate (AVIFIL32.@) + */ +HRESULT WINAPI AVIStreamCreate(PAVISTREAM* ppas, LONG lParam1, LONG lParam2, CLSID* lpHandler) +{ + HRESULT hr; + IClassFactory* pcf; + + *ppas = NULL; + + if ( lpHandler == NULL ) + { + hr = AVIFILE_DllGetClassObject(&CLSID_AVIFile, + &IID_IClassFactory,(void**)&pcf); + } + else + { + if ( !AVIFILE_data.fInitCOM ) + return E_UNEXPECTED; + hr = CoGetClassObject(lpHandler,CLSCTX_INPROC_SERVER, + NULL,&IID_IClassFactory,(void**)&pcf); + } + if ( hr != S_OK ) + return hr; + + hr = IClassFactory_CreateInstance( pcf, NULL, &IID_IAVIStream, + (void**)ppas ); + IClassFactory_Release( pcf ); + + if ( hr == S_OK ) + { + hr = IAVIStream_Create((*ppas),lParam1,lParam2); + if ( hr != S_OK ) + { + IAVIStream_Release((*ppas)); + *ppas = NULL; + } + } + + return hr; +} + +/*********************************************************************** + * AVIMakeCompressedStream (AVIFIL32.@) + */ +HRESULT WINAPI AVIMakeCompressedStream(PAVISTREAM *ppsCompressed,PAVISTREAM ppsSource,AVICOMPRESSOPTIONS *aco,CLSID *pclsidHandler) +{ + FIXME("(%p,%p,%p,%p)\n",ppsCompressed,ppsSource,aco,pclsidHandler); + return E_FAIL; +} + diff --git a/dlls/avifil32/avifil32.spec b/dlls/avifil32/avifil32.spec index d19a3962422..24bca8fc6cd 100644 --- a/dlls/avifil32/avifil32.spec +++ b/dlls/avifil32/avifil32.spec @@ -1,7 +1,9 @@ name avifil32 type win32 +init AVIFILE_DllMain import msvfw32.dll +import ole32.dll import kernel32.dll import ntdll.dll @@ -43,7 +45,7 @@ debug_channels (avifile) @ stub AVISaveW @ stub AVIStreamAddRef @ stub AVIStreamBeginStreaming -@ stub AVIStreamCreate +@ stdcall AVIStreamCreate(ptr long long ptr) AVIStreamCreate @ stub AVIStreamEndStreaming @ stub AVIStreamFindSample @ stdcall AVIStreamGetFrame(ptr long) AVIStreamGetFrame diff --git a/dlls/avifil32/avifile.c b/dlls/avifil32/avifile.c deleted file mode 100644 index 3a7d60a1bd6..00000000000 --- a/dlls/avifil32/avifile.c +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Copyright 1999 Marcus Meissner - */ -#include -#include -#include - -#include "winbase.h" -#include "winnls.h" -#include "mmsystem.h" -#include "winerror.h" -#include "vfw.h" -#include "debugtools.h" - -DEFAULT_DEBUG_CHANNEL(avifile); - -static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj); -static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface); -static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface); -static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size); -static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam); -static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi); -static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size); -static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size); -static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface); -static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam); - -struct ICOM_VTABLE(IAVIFile) iavift = { - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - IAVIFile_fnQueryInterface, - IAVIFile_fnAddRef, - IAVIFile_fnRelease, - IAVIFile_fnInfo, - IAVIFile_fnGetStream, - IAVIFile_fnCreateStream, - IAVIFile_fnWriteData, - IAVIFile_fnReadData, - IAVIFile_fnEndRecord, - IAVIFile_fnDeleteStream -}; - -static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj); -static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface); -static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface); -static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2); -static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size); -static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags); -static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize); -static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize); -static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread); -static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten); -static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples); -static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread); -static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size); -static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen); - -struct ICOM_VTABLE(IAVIStream) iavist = { - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - IAVIStream_fnQueryInterface, - IAVIStream_fnAddRef, - IAVIStream_fnRelease, - IAVIStream_fnCreate, - IAVIStream_fnInfo, - IAVIStream_fnFindSample, - IAVIStream_fnReadFormat, - IAVIStream_fnSetFormat, - IAVIStream_fnRead, - IAVIStream_fnWrite, - IAVIStream_fnDelete, - IAVIStream_fnReadData, - IAVIStream_fnWriteData, - IAVIStream_fnSetInfo -}; - -typedef struct IAVIStreamImpl { - /* IUnknown stuff */ - ICOM_VFIELD(IAVIStream); - DWORD ref; - /* IAVIStream stuff */ - LPVOID lpInputFormat; - DWORD inputformatsize; - BOOL iscompressing; - DWORD curframe; - - /* Compressor stuff */ - HIC hic; - LPVOID lpCompressFormat; - ICINFO icinfo; - DWORD compbufsize; - LPVOID compbuffer; - - DWORD decompbufsize; - LPVOID decompbuffer; - LPVOID decompformat; - AVICOMPRESSOPTIONS aco; - - LPVOID lpPrev; /* pointer to decompressed frame later */ - LPVOID lpPrevFormat; /* pointer to decompressed info later */ -} IAVIStreamImpl; - -/*********************************************************************** - * AVIFileInit (AVIFIL32.@) - * AVIFileInit (AVIFILE.100) - */ -void WINAPI -AVIFileInit(void) { - FIXME("(),stub!\n"); -} - -typedef struct IAVIFileImpl { - /* IUnknown stuff */ - ICOM_VFIELD(IAVIFile); - DWORD ref; - /* IAVIFile stuff... */ -} IAVIFileImpl; - -static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj) { - ICOM_THIS(IAVIFileImpl,iface); - - TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj); - if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) || - !memcmp(&IID_IAVIFile,refiid,sizeof(IID_IAVIFile)) - ) { - *obj = iface; - return S_OK; - } - return OLE_E_ENUM_NOMORE; -} - -static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface) { - ICOM_THIS(IAVIFileImpl,iface); - - FIXME("(%p)->AddRef()\n",iface); - return ++(This->ref); -} - -static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface) { - ICOM_THIS(IAVIFileImpl,iface); - - FIXME("(%p)->Release()\n",iface); - if (!--(This->ref)) { - HeapFree(GetProcessHeap(),0,iface); - return 0; - } - return This->ref; -} - -static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size) { - FIXME("(%p)->Info(%p,%ld)\n",iface,afi,size); - - /* FIXME: fill out struct? */ - return E_FAIL; -} - -static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam) { - FIXME("(%p)->GetStream(%p,0x%08lx,%ld)\n",iface,avis,fccType,lParam); - /* FIXME: create interface etc. */ - return E_FAIL; -} - -static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi) { - ICOM_THIS(IAVIStreamImpl,iface); - char fcc[5]; - IAVIStreamImpl *istream; - - FIXME("(%p,%p,%p)\n",This,avis,asi); - istream = (IAVIStreamImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IAVIStreamImpl)); - istream->ref = 1; - ICOM_VTBL(istream) = &iavist; - fcc[4]='\0'; - memcpy(fcc,(char*)&(asi->fccType),4); - FIXME("\tfccType '%s'\n",fcc); - memcpy(fcc,(char*)&(asi->fccHandler),4); - FIXME("\tfccHandler '%s'\n",fcc); - FIXME("\tdwFlags 0x%08lx\n",asi->dwFlags); - FIXME("\tdwCaps 0x%08lx\n",asi->dwCaps); - FIXME("\tname %s\n",debugstr_w(asi->szName)); - - istream->curframe = 0; - *avis = (PAVISTREAM)istream; - return S_OK; -} - -static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size) { - FIXME("(%p)->WriteData(0x%08lx,%p,%ld)\n",iface,ckid,lpData,size); - /* FIXME: write data to file */ - return E_FAIL; -} - -static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size) { - FIXME("(%p)->ReadData(0x%08lx,%p,%p)\n",iface,ckid,lpData,size); - /* FIXME: read at most size bytes from file */ - return E_FAIL; -} - -static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface) { - FIXME("(%p)->EndRecord()\n",iface); - /* FIXME: end record? */ - return E_FAIL; -} - -static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam) { - FIXME("(%p)->DeleteStream(0x%08lx,%ld)\n",iface,fccType,lParam); - /* FIXME: delete stream? */ - return E_FAIL; -} - -/*********************************************************************** - * AVIFileOpenA (AVIFIL32.@) - * AVIFileOpenA (AVIFILE.102) - */ -HRESULT WINAPI AVIFileOpenA( - PAVIFILE * ppfile,LPCSTR szFile,UINT uMode,LPCLSID lpHandler -) { - IAVIFileImpl *iavi; - - FIXME("(%p,%s,0x%08lx,%s),stub!\n",ppfile,szFile,(DWORD)uMode,debugstr_guid(lpHandler)); - iavi = (IAVIFileImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IAVIFileImpl)); - iavi->ref = 1; - ICOM_VTBL(iavi) = &iavift; - *ppfile = (LPVOID)iavi; - return S_OK; -} - -static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj) { - ICOM_THIS(IAVIStreamImpl,iface); - - TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj); - if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) || - !memcmp(&IID_IAVIStream,refiid,sizeof(IID_IAVIStream)) - ) { - *obj = This; - return S_OK; - } - /* can return IGetFrame interface too */ - return OLE_E_ENUM_NOMORE; -} - -static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface) { - ICOM_THIS(IAVIStreamImpl,iface); - - FIXME("(%p)->AddRef()\n",iface); - return ++(This->ref); -} - -static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface) { - ICOM_THIS(IAVIStreamImpl,iface); - - FIXME("(%p)->Release()\n",iface); - if (!--(This->ref)) { - HeapFree(GetProcessHeap(),0,This); - return 0; - } - return This->ref; -} - -static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2) { - FIXME("(%p)->Create(0x%08lx,0x%08lx)\n",iface,lParam1,lParam2); - return E_FAIL; -} - -static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size) { - FIXME("(%p)->Info(%p,%ld)\n",iface,psi,size); - return E_FAIL; -} - -static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags) { - FIXME("(%p)->FindSample(%ld,0x%08lx)\n",iface,pos,flags); - return E_FAIL; -} - -static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize) { - FIXME("(%p)->ReadFormat(%ld,%p,%p)\n",iface,pos,format,formatsize); - return E_FAIL; -} - -/*********************************************************************** - * IAVIStream::SetFormat - */ -static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize) { - IAVIStreamImpl *as = (IAVIStreamImpl*)iface; - - FIXME("(%p)->SetFormat(%ld,%p,%ld)\n",iface,pos,format,formatsize); - if (as->lpInputFormat) HeapFree(GetProcessHeap(),0,as->lpInputFormat); - as->inputformatsize = formatsize; - as->lpInputFormat = HeapAlloc(GetProcessHeap(),0,formatsize); - memcpy(as->lpInputFormat,format,formatsize); - if (as->iscompressing) { - int xsize; - /* Set up the Compressor part */ - xsize = ICCompressGetFormatSize(as->hic,as->lpInputFormat); - as->lpCompressFormat = HeapAlloc(GetProcessHeap(),0,xsize); - ICCompressGetFormat(as->hic,as->lpInputFormat,as->lpCompressFormat); - ICCompressBegin(as->hic,as->lpInputFormat,as->lpCompressFormat); - as->compbufsize = ICCompressGetSize(as->hic,as->lpInputFormat,as->lpCompressFormat); - as->compbuffer = HeapAlloc(GetProcessHeap(),0,as->compbufsize); - - /* Set up the Decompressor part (for prev frames?) */ - xsize=ICDecompressGetFormatSize(as->hic,as->lpCompressFormat); - as->decompformat = HeapAlloc(GetProcessHeap(),0,xsize); - ICDecompressGetFormat(as->hic,as->lpCompressFormat,as->decompformat); - as->decompbufsize=((LPBITMAPINFOHEADER)as->decompbuffer)->biSizeImage; - as->decompbuffer = HeapReAlloc(GetProcessHeap(),0,as->decompbuffer,as->decompbufsize); - memset(as->decompbuffer,0xff,as->decompbufsize); - assert(HeapValidate(GetProcessHeap(),0,NULL)); - - ICDecompressGetFormat(as->hic,as->lpCompressFormat,as->decompformat); - ICDecompressBegin(as->hic,as->lpCompressFormat,as->decompformat); - as->lpPrev = as->lpPrevFormat = NULL; - } - return S_OK; -} - -static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) { - FIXME("(%p)->Read(%ld,%ld,%p,%ld,%p,%p)\n",iface,start,samples,buffer,buffersize,bytesread,samplesread); - return E_FAIL; -} - -static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) { - IAVIStreamImpl *as = (IAVIStreamImpl*)iface; - DWORD ckid,xflags; - - FIXME("(%p)->Write(%ld,%ld,%p,%ld,0x%08lx,%p,%p)\n",iface,start,samples,buffer,buffersize,flags,sampwritten,byteswritten); - - ICCompress( - as->hic,flags, - as->lpCompressFormat, - as->compbuffer, - as->lpInputFormat,buffer, - &ckid,&xflags, - as->curframe,0xffffff/*framesize*/,as->aco.dwQuality, - as->lpPrevFormat,as->lpPrev - ); - ICDecompress( - as->hic, - flags, /* FIXME: check */ - as->lpCompressFormat, - as->compbuffer, - as->decompformat, - as->decompbuffer - ); - /* We now have a prev format for the next compress ... */ - as->lpPrevFormat = as->decompformat; - as->lpPrev = as->decompbuffer; - return S_OK; -} - -static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples) { - FIXME("(%p)->Delete(%ld,%ld)\n",iface,start,samples); - return E_FAIL; -} -static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread) { - FIXME("(%p)->ReadData(0x%08lx,%p,%p)\n",iface,fcc,lp,lpread); - return E_FAIL; -} - -static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size) { - FIXME("(%p)->WriteData(0x%08lx,%p,%ld)\n",iface,fcc,lp,size); - return E_FAIL; -} - -static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen) { - FIXME("(%p)->SetInfo(%p,%ld)\n",iface,info,infolen); - return E_FAIL; -} - -/*********************************************************************** - * AVIFileCreateStreamA (AVIFIL32.@) - */ -HRESULT WINAPI AVIFileCreateStreamA(PAVIFILE iface,PAVISTREAM *ppavi,AVISTREAMINFOA * psi) { - AVISTREAMINFOW psiw; - - /* Only the szName at the end is different */ - memcpy(&psiw,psi,sizeof(*psi)-sizeof(psi->szName)); - MultiByteToWideChar( CP_ACP, 0, psi->szName, -1, - psiw.szName, sizeof(psiw.szName) / sizeof(WCHAR) ); - return IAVIFile_CreateStream(iface,ppavi,&psiw); -} - -/*********************************************************************** - * AVIFileCreateStreamW (AVIFIL32.@) - */ -HRESULT WINAPI AVIFileCreateStreamW(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi) { - return IAVIFile_CreateStream(iface,avis,asi); -} - - -/*********************************************************************** - * AVIFileGetStream (AVIFIL32.@) - * AVIFileGetStream (AVIFILE.143) - */ -HRESULT WINAPI AVIFileGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam) { - return IAVIFile_GetStream(iface,avis,fccType,lParam); -} - -/*********************************************************************** - * AVIFileInfoA (AVIFIL32.@) - */ -HRESULT WINAPI AVIFileInfoA(PAVIFILE iface,LPAVIFILEINFOA afi,LONG size) { - AVIFILEINFOW afiw; - HRESULT hres; - - if (size < sizeof(AVIFILEINFOA)) - return AVIERR_BADSIZE; - hres = IAVIFile_Info(iface,&afiw,sizeof(afiw)); - memcpy(afi,&afiw,sizeof(*afi)-sizeof(afi->szFileType)); - WideCharToMultiByte( CP_ACP, 0, afiw.szFileType, -1, - afi->szFileType, sizeof(afi->szFileType), NULL, NULL ); - afi->szFileType[sizeof(afi->szFileType)-1] = 0; - return hres; -} - -/*********************************************************************** - * AVIStreamInfoW (AVIFIL32.@) - */ -HRESULT WINAPI AVIStreamInfoW(PAVISTREAM iface,AVISTREAMINFOW *asi,LONG - size) { - return IAVIFile_Info(iface,asi,size); -} - -/*********************************************************************** - * AVIStreamInfoA (AVIFIL32.@) - */ -HRESULT WINAPI AVIStreamInfoA(PAVISTREAM iface,AVISTREAMINFOA *asi,LONG - size) { - AVISTREAMINFOW asiw; - HRESULT hres; - - if (sizeszName, sizeof(asi->szName), NULL, NULL ); - asi->szName[sizeof(asi->szName)-1] = 0; - return hres; -} - -/*********************************************************************** - * AVIFileInfoW (AVIFIL32.@) - */ -HRESULT WINAPI AVIFileInfoW(PAVIFILE iface,LPAVIFILEINFOW afi,LONG size) { - return IAVIFile_Info(iface,afi,size); -} - -/*********************************************************************** - * AVIMakeCompressedStream (AVIFIL32.@) - */ -HRESULT WINAPI AVIMakeCompressedStream(PAVISTREAM *ppsCompressed,PAVISTREAM ppsSource,AVICOMPRESSOPTIONS *aco,CLSID *pclsidHandler) { - char fcc[5]; - IAVIStreamImpl *as; - FIXME("(%p,%p,%p,%p)\n",ppsCompressed,ppsSource,aco,pclsidHandler); - fcc[4]='\0'; - memcpy(fcc,&(aco->fccType),4); - FIXME("\tfccType: '%s'\n",fcc); - memcpy(fcc,&(aco->fccHandler),4); - FIXME("\tfccHandler: '%s'\n",fcc); - FIXME("\tdwFlags: 0x%08lx\n",aco->dwFlags); - - /* we just create a duplicate for now */ - IAVIStream_AddRef(ppsSource); - *ppsCompressed = ppsSource; - as = (IAVIStreamImpl*)ppsSource; - - /* this is where the fun begins. Open a compressor and prepare it. */ - as->hic = ICOpen(aco->fccType,aco->fccHandler,ICMODE_COMPRESS); - - /* May happen. for instance if the codec is not able to compress */ - if (!as->hic) - return AVIERR_UNSUPPORTED; - - ICGetInfo(as->hic,&(as->icinfo),sizeof(ICINFO)); - FIXME("Opened compressor: %s %s\n",debugstr_w(as->icinfo.szName),debugstr_w(as->icinfo.szDescription)); - as->iscompressing = TRUE; - memcpy(&(as->aco),aco,sizeof(*aco)); - if (as->icinfo.dwFlags & VIDCF_COMPRESSFRAMES) { - ICCOMPRESSFRAMES icf; - - /* now what to fill in there ... Hmm */ - memset(&icf,0,sizeof(icf)); - icf.lDataRate = aco->dwBytesPerSecond; - icf.lQuality = aco->dwQuality; - icf.lKeyRate = aco->dwKeyFrameEvery; - - icf.GetData = (void *)0xdead4242; - icf.PutData = (void *)0xdead4243; - ICSendMessage(as->hic,ICM_COMPRESS_FRAMES_INFO,(LPARAM)&icf,sizeof(icf)); - } - return S_OK; -} - -/*********************************************************************** - * AVIStreamSetFormat (AVIFIL32.@) - */ -HRESULT WINAPI AVIStreamSetFormat(PAVISTREAM iface,LONG pos,LPVOID format,LONG formatsize) { - return IAVIStream_SetFormat(iface,pos,format,formatsize); -} - -/*********************************************************************** - * AVIStreamReadFormat (AVIFIL32.@) - */ -HRESULT WINAPI AVIStreamReadFormat(PAVISTREAM iface,LONG pos,LPVOID format,LONG *formatsize) { - return IAVIStream_ReadFormat(iface,pos,format,formatsize); -} - -/*********************************************************************** - * AVIStreamWrite (AVIFIL32.@) - */ -HRESULT WINAPI AVIStreamWrite(PAVISTREAM iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) { - return IAVIStream_Write(iface,start,samples,buffer,buffersize,flags,sampwritten,byteswritten); -} - -/*********************************************************************** - * AVIStreamRead (AVIFIL32.@) - */ -HRESULT WINAPI AVIStreamRead(PAVISTREAM iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) { - return IAVIStream_Read(iface,start,samples,buffer,buffersize,bytesread,samplesread); -} - -/*********************************************************************** - * AVIStreamWriteData (AVIFIL32.@) - */ -HRESULT WINAPI AVIStreamWriteData(PAVISTREAM iface,DWORD fcc,LPVOID lp,LONG size) { - return IAVIStream_WriteData(iface,fcc,lp,size); -} - -/*********************************************************************** - * AVIStreamReadData (AVIFIL32.@) - */ -HRESULT WINAPI AVIStreamReadData(PAVISTREAM iface,DWORD fcc,LPVOID lp,LONG *lpread) { - return IAVIStream_ReadData(iface,fcc,lp,lpread); -} - -/*********************************************************************** - * AVIStreamStart (AVIFIL32.@) - */ -LONG WINAPI AVIStreamStart(PAVISTREAM iface) { - AVISTREAMINFOW si; - - IAVIStream_Info(iface,&si,sizeof(si)); - return si.dwStart; -} - -/*********************************************************************** - * AVIStreamLength (AVIFIL32.@) - */ -LONG WINAPI AVIStreamLength(PAVISTREAM iface) { - AVISTREAMINFOW si; - HRESULT ret; - - ret = IAVIStream_Info(iface,&si,sizeof(si)); - if (ret) /* error */ - return 1; - return si.dwLength; -} - -/*********************************************************************** - * AVIStreamRelease (AVIFIL32.@) - */ -ULONG WINAPI AVIStreamRelease(PAVISTREAM iface) { - return IAVIStream_Release(iface); -} - -/*********************************************************************** - * AVIStreamGetFrameOpen (AVIFIL32.@) - */ -PGETFRAME WINAPI AVIStreamGetFrameOpen(PAVISTREAM iface,LPBITMAPINFOHEADER bmi) { - FIXME("(%p)->(%p),stub!\n",iface,bmi); - return NULL; -} - -/*********************************************************************** - * AVIStreamGetFrame (AVIFIL32.@) - */ -LPVOID WINAPI AVIStreamGetFrame(PGETFRAME pg,LONG pos) { - return IGetFrame_GetFrame(pg,pos); -} - -/*********************************************************************** - * AVIStreamGetFrameClose (AVIFIL32.@) - */ -HRESULT WINAPI AVIStreamGetFrameClose(PGETFRAME pg) { - if (pg) IGetFrame_Release(pg); - return 0; -} - -/*********************************************************************** - * AVIFileRelease (AVIFIL32.@) - * AVIFileRelease (AVIFILE.141) - */ -ULONG WINAPI AVIFileRelease(PAVIFILE iface) { - return IAVIFile_Release(iface); -} - -/*********************************************************************** - * AVIFileExit (AVIFIL32.@) - * AVIFileExit (AVIFILE.101) - */ -void WINAPI AVIFileExit(void) { - FIXME("(), stub.\n"); -} diff --git a/dlls/avifil32/avifile_private.h b/dlls/avifil32/avifile_private.h new file mode 100644 index 00000000000..7aaa60edfc6 --- /dev/null +++ b/dlls/avifil32/avifile_private.h @@ -0,0 +1,68 @@ +#ifndef __WINE_AVIFILE_PRIVATE_H +#define __WINE_AVIFILE_PRIVATE_H + +typedef struct +{ + HANDLE hHeap; + DWORD dwAVIFileRef; + DWORD dwClassObjRef; + BOOL fInitCOM; +} WINE_AVIFILE_DATA; + +extern WINE_AVIFILE_DATA AVIFILE_data; + +INT AVIFILE_strlenAtoW( LPCSTR lpstr ); +INT AVIFILE_strlenWtoA( LPCWSTR lpwstr ); +LPWSTR AVIFILE_strncpyAtoW( LPWSTR lpwstr, LPCSTR lpstr, INT wbuflen ); +LPSTR AVIFILE_strncpyWtoA( LPSTR lpstr, LPCWSTR lpwstr, INT abuflen ); +LPWSTR AVIFILE_strdupAtoW( LPCSTR lpstr ); +LPSTR AVIFILE_strdupWtoA( LPCWSTR lpwstr ); + +HRESULT WINAPI AVIFILE_DllGetClassObject(const CLSID* pclsid,const IID* piid,void** ppv); + +HRESULT AVIFILE_CreateIAVIFile(void** ppobj); +HRESULT AVIFILE_IAVIFile_Open( PAVIFILE paf, LPCWSTR szFile, UINT uMode ); +HRESULT AVIFILE_IAVIFile_GetIndexTable( PAVIFILE paf, DWORD dwStreamIndex, + AVIINDEXENTRY** ppIndexEntry, + DWORD* pdwCountOfIndexEntry ); +HRESULT AVIFILE_IAVIFile_ReadMovieData( PAVIFILE paf, DWORD dwOffset, + DWORD dwLength, LPVOID lpvBuf ); + +HRESULT AVIFILE_CreateIAVIStream(void** ppobj); + +HRESULT AVIFILE_CreateIGetFrame(void** ppobj, + IAVIStream* pstr,LPBITMAPINFOHEADER lpbi); + + +typedef struct +{ + DWORD dwStreamIndex; + AVIStreamHeader* pstrhdr; + BYTE* pbFmt; + DWORD dwFmtLen; +} WINE_AVISTREAM_DATA; + +WINE_AVISTREAM_DATA* AVIFILE_Alloc_IAVIStreamData( DWORD dwFmtLen ); +void AVIFILE_Free_IAVIStreamData( WINE_AVISTREAM_DATA* pData ); + +/* this should be moved to vfw.h */ +#ifndef FIND_DIR +#define FIND_DIR 0x0000000FL +#define FIND_NEXT 0x00000001L +#define FIND_PREV 0x00000004L +#define FIND_FROM_START 0x00000008L + +#define FIND_TYPE 0x000000F0L +#define FIND_KEY 0x00000010L +#define FIND_ANY 0x00000020L +#define FIND_FORMAT 0x00000040L + +#define FIND_RET 0x0000F000L +#define FIND_POS 0x00000000L +#define FIND_LENGTH 0x00001000L +#define FIND_OFFSET 0x00002000L +#define FIND_SIZE 0x00003000L +#define FIND_INDEX 0x00004000L +#endif + +#endif /* __WINE_AVIFILE_PRIVATE_H */ diff --git a/dlls/avifil32/comentry.c b/dlls/avifil32/comentry.c new file mode 100644 index 00000000000..6f92babbecf --- /dev/null +++ b/dlls/avifil32/comentry.c @@ -0,0 +1,142 @@ +/* + * Copyright 2001 Hidenori TAKESHIMA + */ + +#include +#include +#include + +#include "winbase.h" +#include "winnls.h" +#include "mmsystem.h" +#include "winerror.h" +#include "ole2.h" +#include "vfw.h" +#include "debugtools.h" +#include "avifile_private.h" + +DEFAULT_DEBUG_CHANNEL(avifile); + +static HRESULT WINAPI +IClassFactory_fnQueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj); +static ULONG WINAPI IClassFactory_fnAddRef(LPCLASSFACTORY iface); +static ULONG WINAPI IClassFactory_fnRelease(LPCLASSFACTORY iface); +static HRESULT WINAPI IClassFactory_fnCreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj); +static HRESULT WINAPI IClassFactory_fnLockServer(LPCLASSFACTORY iface,BOOL dolock); + +static ICOM_VTABLE(IClassFactory) iclassfact = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + IClassFactory_fnQueryInterface, + IClassFactory_fnAddRef, + IClassFactory_fnRelease, + IClassFactory_fnCreateInstance, + IClassFactory_fnLockServer +}; + +typedef struct +{ + /* IUnknown fields */ + ICOM_VFIELD(IClassFactory); + DWORD ref; +} IClassFactoryImpl; + +static IClassFactoryImpl AVIFILE_GlobalCF = {&iclassfact, 0 }; + + + +static HRESULT WINAPI +IClassFactory_fnQueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) +{ + ICOM_THIS(IClassFactoryImpl,iface); + + TRACE("(%p)->(%p,%p)\n",This,riid,ppobj); + if ( ( IsEqualGUID( &IID_IUnknown, riid ) ) || + ( IsEqualGUID( &IID_IClassFactory, riid ) ) ) + { + *ppobj = iface; + IClassFactory_AddRef(iface); + return S_OK; + } + + return E_NOINTERFACE; +} + +static ULONG WINAPI IClassFactory_fnAddRef(LPCLASSFACTORY iface) +{ + ICOM_THIS(IClassFactoryImpl,iface); + + TRACE("(%p)->()\n",This); + if ( (This->ref) == 0 ) + AVIFILE_data.dwClassObjRef ++; + + return ++(This->ref); +} + +static ULONG WINAPI IClassFactory_fnRelease(LPCLASSFACTORY iface) +{ + ICOM_THIS(IClassFactoryImpl,iface); + + TRACE("(%p)->()\n",This); + if ( (--(This->ref)) > 0 ) + return This->ref; + + AVIFILE_data.dwClassObjRef --; + return 0; +} + +static HRESULT WINAPI IClassFactory_fnCreateInstance(LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj) +{ + /*ICOM_THIS(IClassFactoryImpl,iface);*/ + + *ppobj = NULL; + if ( pOuter != NULL ) + return E_FAIL; + + if ( IsEqualGUID( &IID_IAVIFile, riid ) ) + return AVIFILE_CreateIAVIFile(ppobj); + if ( IsEqualGUID( &IID_IAVIStream, riid ) ) + return AVIFILE_CreateIAVIStream(ppobj); + + return E_NOINTERFACE; +} + +static HRESULT WINAPI IClassFactory_fnLockServer(LPCLASSFACTORY iface,BOOL dolock) +{ + ICOM_THIS(IClassFactoryImpl,iface); + HRESULT hr; + + FIXME("(%p)->(%d),stub!\n",This,dolock); + if (dolock) + hr = IClassFactory_AddRef(iface); + else + hr = IClassFactory_Release(iface); + + return hr; +} + + +/*********************************************************************** + * DllGetClassObject (AVIFIL32.@) + */ +HRESULT WINAPI AVIFILE_DllGetClassObject(const CLSID* pclsid,const IID* piid,void** ppv) +{ + *ppv = NULL; + if ( IsEqualCLSID( &IID_IClassFactory, piid ) ) + { + *ppv = (LPVOID)&AVIFILE_GlobalCF; + IClassFactory_AddRef((IClassFactory*)*ppv); + return S_OK; + } + + return CLASS_E_CLASSNOTAVAILABLE; +} + +/***************************************************************************** + * DllCanUnloadNow (AVIFIL32.@) + */ +DWORD WINAPI AVIFILE_DllCanUnloadNow(void) +{ + return ( AVIFILE_data.dwClassObjRef == 0 ) ? S_OK : S_FALSE; +} + diff --git a/dlls/avifil32/iafile.c b/dlls/avifil32/iafile.c new file mode 100644 index 00000000000..131e89f4dc0 --- /dev/null +++ b/dlls/avifil32/iafile.c @@ -0,0 +1,744 @@ +/* + * Copyright 1999 Marcus Meissner + * Copyright 2001 Hidenori TAKESHIMA + * + * FIXME - implements editing/writing. + */ + +#include +#include +#include + +#include "winbase.h" +#include "winnls.h" +#include "mmsystem.h" +#include "winerror.h" +#include "vfw.h" +#include "debugtools.h" +#include "avifile_private.h" + +DEFAULT_DEBUG_CHANNEL(avifile); + +#define AVIFILE_STREAMS_MAX 4 + + +static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj); +static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface); +static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface); +static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size); +static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam); +static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi); +static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size); +static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size); +static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface); +static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam); + +struct ICOM_VTABLE(IAVIFile) iavift = { + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + IAVIFile_fnQueryInterface, + IAVIFile_fnAddRef, + IAVIFile_fnRelease, + IAVIFile_fnInfo, + IAVIFile_fnGetStream, + IAVIFile_fnCreateStream, + IAVIFile_fnWriteData, + IAVIFile_fnReadData, + IAVIFile_fnEndRecord, + IAVIFile_fnDeleteStream, + /* IAVIFILE_fnOpen */ /* FIXME? */ +}; + + +typedef struct IAVIFileImpl +{ + ICOM_VFIELD(IAVIFile); + /* IUnknown stuff */ + DWORD ref; + /* IAVIFile stuff */ + HANDLE hf; + DWORD dwAVIFileCaps; + DWORD dwAVIFileScale; + DWORD dwAVIFileRate; + DWORD dwAVIFileLength; + DWORD dwAVIFileEditCount; + MainAVIHeader hdr; + IAVIStream* pStreams[AVIFILE_STREAMS_MAX]; + AVIStreamHeader strhdrs[AVIFILE_STREAMS_MAX]; + DWORD dwMoviTop; + DWORD dwCountOfIndexEntry; + AVIINDEXENTRY* pIndexEntry; + AVIINDEXENTRY* pStreamIndexEntry[AVIFILE_STREAMS_MAX+1]; +} IAVIFileImpl; + + +/**************************************************************************** + * AVI file parser. + */ + +static HRESULT AVIFILE_IAVIFile_ReadNextChunkHeader( + IAVIFileImpl* This, FOURCC* pfcc, DWORD* pdwSize ) +{ + BYTE buf[8]; + DWORD dwRead; + + if ( ( !ReadFile( This->hf, buf, 8, &dwRead, NULL ) ) || + ( 8 != dwRead ) ) + return AVIERR_FILEREAD; + *pfcc = mmioFOURCC(buf[0],buf[1],buf[2],buf[3]); + *pdwSize = ( ((DWORD)buf[4]) ) | + ( ((DWORD)buf[5]) << 8 ) | + ( ((DWORD)buf[6]) << 16 ) | + ( ((DWORD)buf[7]) << 24 ); + + return S_OK; +} + +static HRESULT AVIFILE_IAVIFile_SkipChunkData( + IAVIFileImpl* This, DWORD dwChunkSize ) +{ + LONG lHigh = 0; + DWORD dwRes; + + if ( dwChunkSize == 0 ) + return S_OK; + + SetLastError(NO_ERROR); + dwRes = SetFilePointer( This->hf, (LONG)dwChunkSize, + &lHigh, FILE_CURRENT ); + if ( dwRes == (DWORD)0xffffffff && GetLastError() != NO_ERROR ) + return AVIERR_FILEREAD; + + return S_OK; +} + +static HRESULT AVIFILE_IAVIFile_ReadChunkData( + IAVIFileImpl* This, DWORD dwChunkSize, + LPVOID lpvBuf, DWORD dwBufSize, LPDWORD lpdwRead ) +{ + if ( dwBufSize > dwChunkSize ) + dwBufSize = dwChunkSize; + if ( ( !ReadFile( This->hf, lpvBuf, dwBufSize, lpdwRead, NULL ) ) || + ( dwBufSize != *lpdwRead ) ) + return AVIERR_FILEREAD; + + return AVIFILE_IAVIFile_SkipChunkData( This, dwChunkSize - dwBufSize ); +} + +static HRESULT AVIFILE_IAVIFile_SeekToSpecifiedChunk( + IAVIFileImpl* This, FOURCC fccType, DWORD* pdwLen ) +{ + HRESULT hr; + FOURCC fcc; + BYTE buf[4]; + DWORD dwRead; + + while ( 1 ) + { + hr = AVIFILE_IAVIFile_ReadNextChunkHeader( + This, &fcc, pdwLen ); + if ( hr != S_OK ) + return hr; + if ( fcc == fccType ) + return S_OK; + + if ( fcc == FOURCC_LIST ) + { + if ( ( !ReadFile( This->hf, buf, 4, &dwRead, NULL ) ) || + ( 4 != dwRead ) ) + return AVIERR_FILEREAD; + } + else + { + hr = AVIFILE_IAVIFile_SkipChunkData( + This, *pdwLen ); + if ( hr != S_OK ) + return hr; + } + } +} + + +WINE_AVISTREAM_DATA* AVIFILE_Alloc_IAVIStreamData( DWORD dwFmtLen ) +{ + WINE_AVISTREAM_DATA* pData; + + pData = (WINE_AVISTREAM_DATA*) + HeapAlloc( AVIFILE_data.hHeap,HEAP_ZERO_MEMORY, + sizeof(WINE_AVISTREAM_DATA) ); + if ( pData == NULL ) + return NULL; + if ( dwFmtLen > 0 ) + { + pData->pbFmt = (BYTE*) + HeapAlloc( AVIFILE_data.hHeap,HEAP_ZERO_MEMORY, + sizeof(BYTE)*dwFmtLen ); + if ( pData->pbFmt == NULL ) + { + AVIFILE_Free_IAVIStreamData( pData ); + return NULL; + } + } + pData->dwFmtLen = dwFmtLen; + + return pData; +} + +void AVIFILE_Free_IAVIStreamData( WINE_AVISTREAM_DATA* pData ) +{ + if ( pData != NULL ) + { + if ( pData->pbFmt != NULL ) + HeapFree( AVIFILE_data.hHeap,0,pData->pbFmt ); + HeapFree( AVIFILE_data.hHeap,0,pData ); + } +} + +static void AVIFILE_IAVIFile_InitIndexTable( + IAVIFileImpl* This, + AVIINDEXENTRY* pIndexBuf, + AVIINDEXENTRY* pIndexData, + DWORD dwCountOfIndexEntry ) +{ + DWORD dwStreamIndex; + DWORD dwIndex; + FOURCC ckid; + + dwStreamIndex = 0; + for ( ; dwStreamIndex < (AVIFILE_STREAMS_MAX+1); dwStreamIndex ++ ) + This->pStreamIndexEntry[dwStreamIndex] = NULL; + + dwStreamIndex = 0; + for ( ; dwStreamIndex < This->hdr.dwStreams; dwStreamIndex ++ ) + { + ckid = mmioFOURCC('0','0'+dwStreamIndex,0,0); + TRACE( "testing ckid %c%c%c%c\n", + (int)(ckid>> 0)&0xff, + (int)(ckid>> 8)&0xff, + (int)(ckid>>16)&0xff, + (int)(ckid>>24)&0xff ); + This->pStreamIndexEntry[dwStreamIndex] = pIndexBuf; + FIXME( "pIndexBuf = %p\n", pIndexBuf ); + for ( dwIndex = 0; dwIndex < dwCountOfIndexEntry; dwIndex++ ) + { + TRACE( "ckid %c%c%c%c\n", + (int)(pIndexData[dwIndex].ckid>> 0)&0xff, + (int)(pIndexData[dwIndex].ckid>> 8)&0xff, + (int)(pIndexData[dwIndex].ckid>>16)&0xff, + (int)(pIndexData[dwIndex].ckid>>24)&0xff ); + + if ( (pIndexData[dwIndex].ckid & mmioFOURCC(0xff,0xff,0,0)) + == ckid ) + { + memcpy( pIndexBuf, &pIndexData[dwIndex], + sizeof(AVIINDEXENTRY) ); + pIndexBuf ++; + } + } + FIXME( "pIndexBuf = %p\n", pIndexBuf ); + } + This->pStreamIndexEntry[This->hdr.dwStreams] = pIndexBuf; +} + + +/**************************************************************************** + * Create an IAVIFile object. + */ + +static HRESULT AVIFILE_IAVIFile_Construct( IAVIFileImpl* This ); +static void AVIFILE_IAVIFile_Destruct( IAVIFileImpl* This ); + +HRESULT AVIFILE_CreateIAVIFile(void** ppobj) +{ + IAVIFileImpl *This; + HRESULT hr; + + TRACE("(%p)\n",ppobj); + *ppobj = NULL; + This = (IAVIFileImpl*)HeapAlloc(AVIFILE_data.hHeap,HEAP_ZERO_MEMORY, + sizeof(IAVIFileImpl)); + if ( This == NULL ) + return AVIERR_MEMORY; + This->ref = 1; + ICOM_VTBL(This) = &iavift; + hr = AVIFILE_IAVIFile_Construct( This ); + if ( hr != S_OK ) + { + AVIFILE_IAVIFile_Destruct( This ); + return hr; + } + + TRACE("new -> %p\n",This); + *ppobj = (LPVOID)This; + + return S_OK; +} + +/**************************************************************************** + * IUnknown interface + */ + +static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj) { + ICOM_THIS(IAVIFileImpl,iface); + + TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj); + if ( IsEqualGUID(&IID_IUnknown,refiid) || + IsEqualGUID(&IID_IAVIFile,refiid) ) + { + *obj = iface; + IAVIFile_AddRef(iface); + return S_OK; + } + return OLE_E_ENUM_NOMORE; +} + +static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface) { + ICOM_THIS(IAVIFileImpl,iface); + + TRACE("(%p)->AddRef()\n",iface); + return ++(This->ref); +} + +static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface) { + ICOM_THIS(IAVIFileImpl,iface); + + TRACE("(%p)->Release()\n",iface); + if ( (--(This->ref)) > 0 ) + return This->ref; + + AVIFILE_IAVIFile_Destruct(This); + HeapFree(AVIFILE_data.hHeap,0,iface); + return 0; +} + +/**************************************************************************** + * IAVIFile interface + */ + +static HRESULT AVIFILE_IAVIFile_Construct( IAVIFileImpl* This ) +{ + DWORD dwIndex; + + This->hf = INVALID_HANDLE_VALUE; + This->dwAVIFileCaps = 0; + This->dwAVIFileScale = 0; + This->dwAVIFileRate = 0; + This->dwAVIFileLength = 0; + This->dwAVIFileEditCount = 0; + for ( dwIndex = 0; dwIndex < AVIFILE_STREAMS_MAX; dwIndex++ ) + This->pStreams[dwIndex] = NULL; + This->dwCountOfIndexEntry = 0; + This->pIndexEntry = NULL; + + AVIFILE_data.dwClassObjRef ++; + + return S_OK; +} + +static void AVIFILE_IAVIFile_Destruct( IAVIFileImpl* This ) +{ + DWORD dwIndex; + + if ( This->pIndexEntry != NULL ) + { + HeapFree(AVIFILE_data.hHeap,0,This->pIndexEntry); + This->pIndexEntry = NULL; + } + + for ( dwIndex = 0; dwIndex < AVIFILE_STREAMS_MAX; dwIndex++ ) + { + if ( This->pStreams[dwIndex] != NULL ) + { + IAVIStream_Release( This->pStreams[dwIndex] ); + This->pStreams[dwIndex] = NULL; + } + } + + if ( This->hf != INVALID_HANDLE_VALUE ) + CloseHandle( This->hf ); + + AVIFILE_data.dwClassObjRef --; +} + +static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size) +{ + ICOM_THIS(IAVIFileImpl,iface); + AVIFILEINFOW fiw; + + FIXME("(%p)->Info(%p,%ld)\n",iface,afi,size); + + memset( &fiw, 0, sizeof(fiw) ); + fiw.dwMaxBytesPerSec = This->hdr.dwMaxBytesPerSec; + fiw.dwFlags = This->hdr.dwFlags; + fiw.dwCaps = This->dwAVIFileCaps; + fiw.dwStreams = This->hdr.dwStreams; + fiw.dwSuggestedBufferSize = This->hdr.dwSuggestedBufferSize; + fiw.dwWidth = This->hdr.dwWidth; + fiw.dwHeight = This->hdr.dwHeight; + fiw.dwScale = This->dwAVIFileScale; /* FIXME */ + fiw.dwRate = This->dwAVIFileRate; /* FIXME */ + fiw.dwLength = This->dwAVIFileLength; /* FIXME */ + fiw.dwEditCount = This->dwAVIFileEditCount; /* FIXME */ + /* fiw.szFileType[64]; */ + + if ( size > sizeof(AVIFILEINFOW) ) + size = sizeof(AVIFILEINFOW); + memcpy( afi, &fiw, size ); + + return S_OK; +} + +static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam) +{ + ICOM_THIS(IAVIFileImpl,iface); + + FIXME("(%p)->GetStream(%p,0x%08lx,%ld)\n",iface,avis,fccType,lParam); + if ( fccType != 0 ) + return E_FAIL; + if ( lParam < 0 || lParam >= This->hdr.dwStreams ) + return E_FAIL; + *avis = This->pStreams[lParam]; + IAVIStream_AddRef( *avis ); + + return S_OK; +} + +static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi) +{ + ICOM_THIS(IAVIFileImpl,iface); + + FIXME("(%p,%p,%p)\n",This,avis,asi); + return E_FAIL; +} + +static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size) +{ + ICOM_THIS(IAVIFileImpl,iface); + + FIXME("(%p)->WriteData(0x%08lx,%p,%ld)\n",This,ckid,lpData,size); + /* FIXME: write data to file */ + return E_FAIL; +} + +static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size) +{ + ICOM_THIS(IAVIFileImpl,iface); + + FIXME("(%p)->ReadData(0x%08lx,%p,%p)\n",This,ckid,lpData,size); + /* FIXME: read at most size bytes from file */ + + return E_FAIL; +} + +static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface) +{ + ICOM_THIS(IAVIFileImpl,iface); + + FIXME("(%p)->EndRecord()\n",This); + /* FIXME: end record? */ + return E_FAIL; +} + +static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam) +{ + ICOM_THIS(IAVIFileImpl,iface); + + FIXME("(%p)->DeleteStream(0x%08lx,%ld)\n",This,fccType,lParam); + /* FIXME: delete stream? */ + return E_FAIL; +} + +/***************************************************************************** + * AVIFILE_IAVIFile_Open (internal) + */ +HRESULT AVIFILE_IAVIFile_Open( PAVIFILE paf, LPCWSTR szFile, UINT uMode ) +{ + ICOM_THIS(IAVIFileImpl,paf); + HRESULT hr; + DWORD dwAcc; + DWORD dwShared; + DWORD dwCreate; + BYTE buf[12]; + DWORD dwRead; + FOURCC fccFileType; + DWORD dwLen; + DWORD dwIndex; + + FIXME("(%p)->Open(%p,%u)\n",This,szFile,uMode); + + if ( This->hf != INVALID_HANDLE_VALUE ) + { + CloseHandle( This->hf ); + This->hf = INVALID_HANDLE_VALUE; + } + + switch ( uMode & 0x3 ) + { + case OF_READ: /* 0x0 */ + dwAcc = GENERIC_READ; + dwCreate = OPEN_EXISTING; + This->dwAVIFileCaps = AVIFILECAPS_CANREAD; + break; + case OF_WRITE: /* 0x1 */ + dwAcc = GENERIC_WRITE; + dwCreate = OPEN_ALWAYS; + This->dwAVIFileCaps = AVIFILECAPS_CANWRITE; + break; + case OF_READWRITE: /* 0x2 */ + dwAcc = GENERIC_READ|GENERIC_WRITE; + dwCreate = OPEN_ALWAYS; + This->dwAVIFileCaps = AVIFILECAPS_CANREAD|AVIFILECAPS_CANWRITE; + break; + default: + return E_FAIL; + } + + if ( This->dwAVIFileCaps & AVIFILECAPS_CANWRITE ) + { + FIXME( "editing AVI is currently not supported!\n" ); + return E_FAIL; + } + + switch ( uMode & 0x70 ) + { + case OF_SHARE_COMPAT: /* 0x00 */ + dwShared = FILE_SHARE_READ|FILE_SHARE_WRITE; + break; + case OF_SHARE_EXCLUSIVE: /* 0x10 */ + dwShared = 0; + break; + case OF_SHARE_DENY_WRITE: /* 0x20 */ + dwShared = FILE_SHARE_READ; + break; + case OF_SHARE_DENY_READ: /* 0x30 */ + dwShared = FILE_SHARE_WRITE; + break; + case OF_SHARE_DENY_NONE: /* 0x40 */ + dwShared = FILE_SHARE_READ|FILE_SHARE_WRITE; + break; + default: + return E_FAIL; + } + if ( uMode & OF_CREATE ) + dwCreate = CREATE_ALWAYS; + + This->hf = CreateFileW( szFile, dwAcc, dwShared, NULL, + dwCreate, FILE_ATTRIBUTE_NORMAL, + (HANDLE)NULL ); + if ( This->hf == INVALID_HANDLE_VALUE ) + return AVIERR_FILEOPEN; + + if ( dwAcc & GENERIC_READ ) + { + if ( !ReadFile( This->hf, buf, 12, &dwRead, NULL ) ) + return AVIERR_FILEREAD; + if ( dwRead == 12 ) + { + if ( mmioFOURCC(buf[0],buf[1],buf[2],buf[3]) != FOURCC_RIFF ) + return AVIERR_BADFORMAT; + + fccFileType = mmioFOURCC(buf[8],buf[9],buf[10],buf[11]); + if ( fccFileType != formtypeAVI ) + return AVIERR_BADFORMAT; + + /* get AVI main header. */ + hr = AVIFILE_IAVIFile_SeekToSpecifiedChunk( + This, ckidAVIMAINHDR, &dwLen ); + if ( hr != S_OK ) + return hr; + if ( dwLen < (sizeof(DWORD)*10) ) + return AVIERR_BADFORMAT; + hr = AVIFILE_IAVIFile_ReadChunkData( + This, dwLen, + &(This->hdr), sizeof(MainAVIHeader), &dwLen ); + if ( This->hdr.dwStreams == 0 || + This->hdr.dwStreams > AVIFILE_STREAMS_MAX ) + return AVIERR_BADFORMAT; + + /* get stream headers. */ + dwIndex = 0; + while ( dwIndex < This->hdr.dwStreams ) + { + WINE_AVISTREAM_DATA* pData; + + hr = AVIFILE_IAVIFile_SeekToSpecifiedChunk( + This, ckidSTREAMHEADER, &dwLen ); + if ( hr != S_OK ) + return hr; + if ( dwLen < (sizeof(DWORD)*12) ) + return AVIERR_BADFORMAT; + hr = AVIFILE_IAVIFile_ReadChunkData( + This, dwLen, + &This->strhdrs[dwIndex], + sizeof(AVIStreamHeader), &dwLen ); + + hr = AVIFILE_IAVIFile_SeekToSpecifiedChunk( + This, ckidSTREAMFORMAT, &dwLen ); + if ( hr != S_OK ) + return hr; + pData = AVIFILE_Alloc_IAVIStreamData( dwLen ); + if ( pData == NULL ) + return AVIERR_MEMORY; + hr = AVIFILE_IAVIFile_ReadChunkData( + This, dwLen, + pData->pbFmt, dwLen, &dwLen ); + if ( hr != S_OK ) + { + AVIFILE_Free_IAVIStreamData( pData ); + return hr; + } + pData->dwStreamIndex = dwIndex; + pData->pstrhdr = &This->strhdrs[dwIndex]; + + hr = AVIStreamCreate(&This->pStreams[dwIndex], + (LONG)paf, (LONG)(pData), NULL ); + if ( hr != S_OK ) + { + AVIFILE_Free_IAVIStreamData( pData ); + return hr; + } + + if ( (This->strhdrs[dwIndex].fccType + == mmioFOURCC('v','i','d','s')) || + (This->strhdrs[dwIndex].fccType + == mmioFOURCC('V','I','D','S')) ) + { + This->dwAVIFileScale = + This->strhdrs[dwIndex].dwScale; + This->dwAVIFileRate = + This->strhdrs[dwIndex].dwRate; + This->dwAVIFileLength = + This->strhdrs[dwIndex].dwLength; + } + else + if ( This->dwAVIFileScale == 0 ) + { + This->dwAVIFileScale = + This->strhdrs[dwIndex].dwScale; + This->dwAVIFileRate = + This->strhdrs[dwIndex].dwRate; + This->dwAVIFileLength = + This->strhdrs[dwIndex].dwLength; + } + + dwIndex ++; + } + + /* skip movi. */ + while ( 1 ) + { + hr = AVIFILE_IAVIFile_SeekToSpecifiedChunk( + This, FOURCC_LIST, &dwLen ); + if ( hr != S_OK ) + return hr; + if ( dwLen < 4 ) + return AVIERR_BADFORMAT; + + This->dwMoviTop = SetFilePointer( This->hf,0,NULL,FILE_CURRENT ); + if ( This->dwMoviTop == 0xffffffff ) + return AVIERR_BADFORMAT; + + if ( ( !ReadFile(This->hf, buf, 4, &dwRead, NULL) ) || + ( dwRead != 4 ) ) + return AVIERR_FILEREAD; + + hr = AVIFILE_IAVIFile_SkipChunkData( + This, dwLen - 4 ); + if ( hr != S_OK ) + return hr; + if ( mmioFOURCC(buf[0],buf[1],buf[2],buf[3]) + == mmioFOURCC('m', 'o', 'v', 'i') ) + break; + } + + /* get idx1. */ + hr = AVIFILE_IAVIFile_SeekToSpecifiedChunk( + This, ckidAVINEWINDEX, &dwLen ); + if ( hr != S_OK ) + return hr; + + This->dwCountOfIndexEntry = dwLen / sizeof(AVIINDEXENTRY); + This->pIndexEntry = (AVIINDEXENTRY*) + HeapAlloc(AVIFILE_data.hHeap,HEAP_ZERO_MEMORY, + sizeof(AVIINDEXENTRY) * + This->dwCountOfIndexEntry * 2 ); + if ( This->pIndexEntry == NULL ) + return AVIERR_MEMORY; + hr = AVIFILE_IAVIFile_ReadChunkData( + This, dwLen, + This->pIndexEntry + This->dwCountOfIndexEntry, + sizeof(AVIINDEXENTRY) * + This->dwCountOfIndexEntry, &dwLen ); + if ( hr != S_OK ) + return hr; + AVIFILE_IAVIFile_InitIndexTable( + This, This->pIndexEntry, + This->pIndexEntry + This->dwCountOfIndexEntry, + This->dwCountOfIndexEntry ); + } + else + { + /* FIXME - create the handle has GENERIC_WRITE access. */ + return AVIERR_FILEREAD; + } + } + else + { + return AVIERR_FILEOPEN; /* FIXME */ + } + + return S_OK; +} + +/***************************************************************************** + * AVIFILE_IAVIFile_GetIndexTable (internal) + */ +HRESULT AVIFILE_IAVIFile_GetIndexTable( PAVIFILE paf, DWORD dwStreamIndex, + AVIINDEXENTRY** ppIndexEntry, + DWORD* pdwCountOfIndexEntry ) +{ + ICOM_THIS(IAVIFileImpl,paf); + + if ( dwStreamIndex < 0 || dwStreamIndex >= This->hdr.dwStreams ) + { + FIXME( "invalid stream index %lu\n", dwStreamIndex ); + return E_FAIL; + } + FIXME( "cur %p, next %p\n", + This->pStreamIndexEntry[dwStreamIndex], + This->pStreamIndexEntry[dwStreamIndex+1] ); + *ppIndexEntry = This->pStreamIndexEntry[dwStreamIndex]; + *pdwCountOfIndexEntry = + This->pStreamIndexEntry[dwStreamIndex+1] - + This->pStreamIndexEntry[dwStreamIndex]; + + return S_OK; +} + +/***************************************************************************** + * AVIFILE_IAVIFile_ReadMovieData (internal) + */ +HRESULT AVIFILE_IAVIFile_ReadMovieData( PAVIFILE paf, DWORD dwOffset, + DWORD dwLength, LPVOID lpvBuf ) +{ + ICOM_THIS(IAVIFileImpl,paf); + LONG lHigh = 0; + DWORD dwRes; + + if ( dwLength == 0 ) + return S_OK; + SetLastError(NO_ERROR); + dwRes = SetFilePointer( This->hf, (LONG)(dwOffset+This->dwMoviTop), + &lHigh, FILE_BEGIN ); + if ( dwRes == (DWORD)0xffffffff && GetLastError() != NO_ERROR ) + return AVIERR_FILEREAD; + + if ( ( !ReadFile(This->hf, lpvBuf, dwLength, &dwRes, NULL) ) || + ( dwLength != dwRes ) ) + { + FIXME( "error in ReadFile()\n" ); + return AVIERR_FILEREAD; + } + + return S_OK; +} + diff --git a/dlls/avifil32/iastream.c b/dlls/avifil32/iastream.c new file mode 100644 index 00000000000..e96a994f5f7 --- /dev/null +++ b/dlls/avifil32/iastream.c @@ -0,0 +1,419 @@ +/* + * Copyright 2001 Hidenori TAKESHIMA + */ + +#include +#include +#include + +#include "winbase.h" +#include "winnls.h" +#include "mmsystem.h" +#include "winerror.h" +#include "vfw.h" +#include "debugtools.h" +#include "avifile_private.h" + +DEFAULT_DEBUG_CHANNEL(avifile); + +static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj); +static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface); +static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface); +static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2); +static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size); +static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags); +static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize); +static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize); +static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread); +static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten); +static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples); +static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread); +static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size); +static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen); + + +struct ICOM_VTABLE(IAVIStream) iavist = { + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + IAVIStream_fnQueryInterface, + IAVIStream_fnAddRef, + IAVIStream_fnRelease, + IAVIStream_fnCreate, + IAVIStream_fnInfo, + IAVIStream_fnFindSample, + IAVIStream_fnReadFormat, + IAVIStream_fnSetFormat, + IAVIStream_fnRead, + IAVIStream_fnWrite, + IAVIStream_fnDelete, + IAVIStream_fnReadData, + IAVIStream_fnWriteData, + IAVIStream_fnSetInfo +}; + + + +typedef struct IAVIStreamImpl +{ + ICOM_VFIELD(IAVIStream); + /* IUnknown stuff */ + DWORD ref; + /* IAVIStream stuff */ + IAVIFile* paf; + WINE_AVISTREAM_DATA* pData; +} IAVIStreamImpl; + +static HRESULT IAVIStream_Construct( IAVIStreamImpl* This ); +static void IAVIStream_Destruct( IAVIStreamImpl* This ); + +HRESULT AVIFILE_CreateIAVIStream(void** ppobj) +{ + IAVIStreamImpl *This; + HRESULT hr; + + *ppobj = NULL; + This = (IAVIStreamImpl*)HeapAlloc(AVIFILE_data.hHeap,HEAP_ZERO_MEMORY, + sizeof(IAVIStreamImpl)); + This->ref = 1; + ICOM_VTBL(This) = &iavist; + hr = IAVIStream_Construct( This ); + if ( hr != S_OK ) + { + IAVIStream_Destruct( This ); + return hr; + } + + *ppobj = (LPVOID)This; + + return S_OK; +} + + +/**************************************************************************** + * IUnknown interface + */ + +static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj) { + ICOM_THIS(IAVIStreamImpl,iface); + + TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj); + if ( IsEqualGUID(&IID_IUnknown,refiid) || + IsEqualGUID(&IID_IAVIStream,refiid) ) + { + IAVIStream_AddRef(iface); + *obj = iface; + return S_OK; + } + /* can return IGetFrame interface too */ + + return OLE_E_ENUM_NOMORE; +} + +static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface) { + ICOM_THIS(IAVIStreamImpl,iface); + + TRACE("(%p)->AddRef()\n",iface); + return ++(This->ref); +} + +static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface) { + ICOM_THIS(IAVIStreamImpl,iface); + + TRACE("(%p)->Release()\n",iface); + if ((--(This->ref)) > 0 ) + return This->ref; + IAVIStream_Destruct(This); + + HeapFree(AVIFILE_data.hHeap,0,iface); + return 0; +} + +/**************************************************************************** + * IAVIStream interface + */ + +static HRESULT IAVIStream_Construct( IAVIStreamImpl* This ) +{ + This->paf = NULL; + This->pData = NULL; + + AVIFILE_data.dwClassObjRef ++; + + return S_OK; +} + +static void IAVIStream_Destruct( IAVIStreamImpl* This ) +{ + AVIFILE_data.dwClassObjRef --; +} + +static HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2) +{ + ICOM_THIS(IAVIStreamImpl,iface); + + FIXME("(%p)->Create(%ld,%ld)\n",iface,lParam1,lParam2); + + This->paf = (IAVIFile*)lParam1; + This->pData = (WINE_AVISTREAM_DATA*)lParam2; + + return S_OK; +} + +static HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size) +{ + ICOM_THIS(IAVIStreamImpl,iface); + AVISTREAMINFOW siw; + + FIXME("(%p)->Info(%p,%ld)\n",iface,psi,size); + if ( This->pData == NULL ) + return E_UNEXPECTED; + + memset( &siw, 0, sizeof(AVISTREAMINFOW) ); + siw.fccType = This->pData->pstrhdr->fccType; + siw.fccHandler = This->pData->pstrhdr->fccHandler; + siw.dwFlags = This->pData->pstrhdr->dwFlags; + siw.dwCaps = 0; /* FIXME */ + siw.wPriority = This->pData->pstrhdr->wPriority; + siw.wLanguage = This->pData->pstrhdr->wLanguage; + siw.dwScale = This->pData->pstrhdr->dwScale; + siw.dwRate = This->pData->pstrhdr->dwRate; + siw.dwStart = This->pData->pstrhdr->dwStart; + siw.dwLength = This->pData->pstrhdr->dwLength; + siw.dwInitialFrames = This->pData->pstrhdr->dwInitialFrames; + siw.dwSuggestedBufferSize = This->pData->pstrhdr->dwSuggestedBufferSize; + siw.dwQuality = This->pData->pstrhdr->dwQuality; + siw.dwSampleSize = This->pData->pstrhdr->dwSampleSize; + siw.rcFrame.left = This->pData->pstrhdr->rcFrame.left; + siw.rcFrame.top = This->pData->pstrhdr->rcFrame.top; + siw.rcFrame.right = This->pData->pstrhdr->rcFrame.right; + siw.rcFrame.bottom = This->pData->pstrhdr->rcFrame.bottom; + siw.dwEditCount = 0; /* FIXME */ + siw.dwFormatChangeCount = 0; /* FIXME */ + /* siw.szName[64] */ + + if ( size > sizeof(AVISTREAMINFOW) ) + size = sizeof(AVISTREAMINFOW); + memcpy( psi, &siw, size ); + + return S_OK; +} + +static LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags) +{ + ICOM_THIS(IAVIStreamImpl,iface); + HRESULT hr; + AVIINDEXENTRY* pIndexEntry; + DWORD dwCountOfIndexEntry; + LONG lCur, lAdd, lEnd; + + FIXME("(%p)->FindSample(%ld,0x%08lx)\n",This,pos,flags); + + hr = AVIFILE_IAVIFile_GetIndexTable( + This->paf, This->pData->dwStreamIndex, + &pIndexEntry, &dwCountOfIndexEntry ); + if ( hr != S_OK ) + return -1L; + + if ( flags & (~(FIND_DIR|FIND_TYPE|FIND_RET)) ) + { + FIXME( "unknown flag %08lx\n", flags ); + return -1L; + } + + switch ( flags & FIND_DIR ) + { + case FIND_NEXT: + lCur = pos; + lAdd = 1; + lEnd = dwCountOfIndexEntry; + if ( lCur > dwCountOfIndexEntry ) + return -1L; + break; + case FIND_PREV: + lCur = pos; + if ( lCur > dwCountOfIndexEntry ) + lCur = dwCountOfIndexEntry; + lAdd = -1; + lEnd = 0; + break; + case FIND_FROM_START: + lCur = 0; + lAdd = 1; + lEnd = dwCountOfIndexEntry; + break; + default: + FIXME( "unknown direction flag %08lx\n", (flags & FIND_DIR) ); + return -1L; + } + + switch ( flags & FIND_TYPE ) + { + case FIND_KEY: + while ( 1 ) + { + if ( pIndexEntry[lCur].dwFlags & AVIIF_KEYFRAME ) + break; + if ( lCur == lEnd ) + return -1L; + lCur += lAdd; + } + break; + case FIND_ANY: + while ( 1 ) + { + if ( !(pIndexEntry[lCur].dwFlags & AVIIF_NOTIME) ) + break; + if ( lCur == lEnd ) + return -1L; + lCur += lAdd; + } + break; + case FIND_FORMAT: + FIXME( "FIND_FORMAT is not implemented.\n" ); + return -1L; + default: + FIXME( "unknown type flag %08lx\n", (flags & FIND_TYPE) ); + return -1L; + } + + switch ( flags & FIND_RET ) + { + case FIND_POS: + return lCur; + case FIND_LENGTH: + FIXME( "FIND_LENGTH is not implemented.\n" ); + return -1L; + case FIND_OFFSET: + return pIndexEntry[lCur].dwChunkOffset; + case FIND_SIZE: + return pIndexEntry[lCur].dwChunkLength; + case FIND_INDEX: + FIXME( "FIND_INDEX is not implemented.\n" ); + return -1L; + default: + FIXME( "unknown return type flag %08lx\n", (flags & FIND_RET) ); + break; + } + + return -1L; +} + +static HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize) { + ICOM_THIS(IAVIStreamImpl,iface); + + TRACE("(%p)->ReadFormat(%ld,%p,%p)\n",This,pos,format,formatsize); + if ( This->pData == NULL ) + return E_UNEXPECTED; + + /* FIXME - check pos. */ + if ( format == NULL ) + { + *formatsize = This->pData->dwFmtLen; + return S_OK; + } + if ( (*formatsize) < This->pData->dwFmtLen ) + return AVIERR_BUFFERTOOSMALL; + + memcpy( format, This->pData->pbFmt, This->pData->dwFmtLen ); + *formatsize = This->pData->dwFmtLen; + + return S_OK; +} + +static HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize) { + ICOM_THIS(IAVIStreamImpl,iface); + + FIXME("(%p)->SetFormat(%ld,%p,%ld)\n",This,pos,format,formatsize); + return E_FAIL; +} + +static HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) { + ICOM_THIS(IAVIStreamImpl,iface); + HRESULT hr; + AVIINDEXENTRY* pIndexEntry; + DWORD dwCountOfIndexEntry; + DWORD dwFrameLength; + + FIXME("(%p)->Read(%ld,%ld,%p,%ld,%p,%p)\n",This,start,samples,buffer,buffersize,bytesread,samplesread); + + *bytesread = 0; + *samplesread = 0; + + hr = AVIFILE_IAVIFile_GetIndexTable( + This->paf, This->pData->dwStreamIndex, + &pIndexEntry, &dwCountOfIndexEntry ); + if ( hr != S_OK ) + return hr; + if ( start < 0 ) + return E_FAIL; + if ( start >= dwCountOfIndexEntry || samples <= 0 ) + { + FIXME("start %ld,samples %ld,total %ld\n",start,samples,dwCountOfIndexEntry); + return S_OK; + } + + /* FIXME - is this data valid??? */ + dwFrameLength = pIndexEntry[start].dwChunkLength + sizeof(DWORD)*2; + + if ( buffer == NULL ) + { + *bytesread = dwFrameLength; + *samplesread = 1; + return S_OK; + } + if ( buffersize < dwFrameLength ) + { + FIXME( "buffer is too small!\n" ); + return AVIERR_BUFFERTOOSMALL; + } + + hr = AVIFILE_IAVIFile_ReadMovieData( + This->paf, + pIndexEntry[start].dwChunkOffset, + dwFrameLength, buffer ); + if ( hr != S_OK ) + { + FIXME( "ReadMovieData failed!\n"); + return hr; + } + *bytesread = dwFrameLength; + *samplesread = 1; + + return S_OK; +} + +static HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) { + ICOM_THIS(IAVIStreamImpl,iface); + + + FIXME("(%p)->Write(%ld,%ld,%p,%ld,0x%08lx,%p,%p)\n",This,start,samples,buffer,buffersize,flags,sampwritten,byteswritten); + return E_FAIL; +} + +static HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples) { + ICOM_THIS(IAVIStreamImpl,iface); + + FIXME("(%p)->Delete(%ld,%ld)\n",This,start,samples); + return E_FAIL; +} +static HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread) { + ICOM_THIS(IAVIStreamImpl,iface); + + FIXME("(%p)->ReadData(0x%08lx,%p,%p)\n",This,fcc,lp,lpread); + return E_FAIL; +} + +static HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size) { + ICOM_THIS(IAVIStreamImpl,iface); + + FIXME("(%p)->WriteData(0x%08lx,%p,%ld)\n",This,fcc,lp,size); + return E_FAIL; +} + +static HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen) { + ICOM_THIS(IAVIStreamImpl,iface); + + FIXME("(%p)->SetInfo(%p,%ld)\n",This,info,infolen); + + return E_FAIL; +} + diff --git a/dlls/avifil32/igframe.c b/dlls/avifil32/igframe.c new file mode 100644 index 00000000000..8397008598d --- /dev/null +++ b/dlls/avifil32/igframe.c @@ -0,0 +1,413 @@ +/* + * Copyright 2001 Hidenori TAKESHIMA + * + * FIXME - implements color space(depth) converter. + */ + +#include +#include +#include + +#include "winbase.h" +#include "winnls.h" +#include "mmsystem.h" +#include "winerror.h" +#include "vfw.h" +#include "debugtools.h" +#include "avifile_private.h" + +DEFAULT_DEBUG_CHANNEL(avifile); + +static HRESULT WINAPI IGetFrame_fnQueryInterface(IGetFrame* iface,REFIID refiid,LPVOID *obj); +static ULONG WINAPI IGetFrame_fnAddRef(IGetFrame* iface); +static ULONG WINAPI IGetFrame_fnRelease(IGetFrame* iface); +static LPVOID WINAPI IGetFrame_fnGetFrame(IGetFrame* iface,LONG lPos); +static HRESULT WINAPI IGetFrame_fnBegin(IGetFrame* iface,LONG lStart,LONG lEnd,LONG lRate); +static HRESULT WINAPI IGetFrame_fnEnd(IGetFrame* iface); +static HRESULT WINAPI IGetFrame_fnSetFormat(IGetFrame* iface,LPBITMAPINFOHEADER lpbi,LPVOID lpBits,INT x,INT y,INT dx,INT dy); + +struct ICOM_VTABLE(IGetFrame) igetfrm = { + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + IGetFrame_fnQueryInterface, + IGetFrame_fnAddRef, + IGetFrame_fnRelease, + IGetFrame_fnGetFrame, + IGetFrame_fnBegin, + IGetFrame_fnEnd, + IGetFrame_fnSetFormat, +}; + +typedef struct IGetFrameImpl +{ + ICOM_VFIELD(IGetFrame); + /* IUnknown stuff */ + DWORD ref; + /* IGetFrame stuff */ + IAVIStream* pas; + HIC hIC; + LONG lCachedFrame; + BITMAPINFO* pbiICIn; + BITMAPINFO* pbiICOut; + LPVOID pvICOutBits; + LPVOID pvICInFmtBuf; + DWORD dwICInDataBufSize; + LPVOID pvICInDataBuf; + LPVOID pvICOutBuf; +} IGetFrameImpl; + +static HRESULT IGetFrame_Construct( IGetFrameImpl* This, + IAVIStream* pstr, + LPBITMAPINFOHEADER lpbi ); +static void IGetFrame_Destruct( IGetFrameImpl* This ); + + + + +static LPVOID AVIFILE_IGetFrame_DecodeFrame(IGetFrameImpl* This,LONG lPos) +{ + HRESULT hr; + DWORD dwRes; + LONG lFrameLength; + LONG lSampleCount; + ICDECOMPRESS icd; + + if ( This->hIC == (HIC)NULL ) + return NULL; + + hr = IAVIStream_Read(This->pas,lPos,1,NULL,0, + &lFrameLength,&lSampleCount); + if ( hr != S_OK || lSampleCount <= 0 ) + { + FIXME( "IAVIStream_Read failed! res = %08lx\n", hr ); + return NULL; + } + TRACE( "frame length = %ld\n", lFrameLength ); + + if ( This->dwICInDataBufSize < lFrameLength ) + { + LPVOID lpv; + + if ( This->pvICInDataBuf == NULL ) + { + lpv = HeapAlloc( + AVIFILE_data.hHeap,HEAP_ZERO_MEMORY, + lFrameLength ); + } + else + { + lpv = HeapReAlloc( + AVIFILE_data.hHeap,HEAP_ZERO_MEMORY, + This->pvICInDataBuf,lFrameLength ); + } + if ( lpv == NULL ) + { + ERR( "out of memory!\n" ); + return NULL; + } + This->pvICInDataBuf = lpv; + This->dwICInDataBufSize = lFrameLength; + } + + hr = IAVIStream_Read(This->pas,lPos,1, + This->pvICInDataBuf,This->dwICInDataBufSize, + &lFrameLength,&lSampleCount); + if ( hr != S_OK || lSampleCount <= 0 ) + { + FIXME( "IAVIStream_Read to buffer failed! res = %08lx\n", hr ); + return NULL; + } + + This->pbiICIn->bmiHeader.biSizeImage = lFrameLength; + + TRACE( "call ICM_DECOMPRESS\n" ); + icd.dwFlags = (*(BYTE*)This->pvICInDataBuf) == 'c' ? + ICDECOMPRESS_NOTKEYFRAME : 0; + icd.lpbiInput = &This->pbiICIn->bmiHeader; + icd.lpInput = (BYTE*)This->pvICInDataBuf + 8; + icd.lpbiOutput = &This->pbiICOut->bmiHeader; + icd.lpOutput = This->pvICOutBits; + icd.ckid = *((DWORD*)This->pvICInDataBuf); + dwRes = ICSendMessage(This->hIC,ICM_DECOMPRESS, + (DWORD)(&icd),sizeof(ICDECOMPRESS) ); + TRACE( "returned from ICM_DECOMPRESS\n" ); + if ( dwRes != ICERR_OK ) + { + ERR( "ICDecompress failed!\n" ); + return NULL; + } + + This->lCachedFrame = lPos; + + return This->pvICOutBits; +} + +/****************************************************************************/ + +HRESULT AVIFILE_CreateIGetFrame(void** ppobj, + IAVIStream* pstr,LPBITMAPINFOHEADER lpbi) +{ + IGetFrameImpl *This; + HRESULT hr; + + *ppobj = NULL; + This = (IGetFrameImpl*)HeapAlloc(AVIFILE_data.hHeap,HEAP_ZERO_MEMORY, + sizeof(IGetFrameImpl)); + This->ref = 1; + ICOM_VTBL(This) = &igetfrm; + hr = IGetFrame_Construct( This, pstr, lpbi ); + if ( hr != S_OK ) + { + IGetFrame_Destruct( This ); + return hr; + } + + *ppobj = (LPVOID)This; + + return S_OK; +} + +/**************************************************************************** + * IUnknown interface + */ + +static HRESULT WINAPI IGetFrame_fnQueryInterface(IGetFrame* iface,REFIID refiid,LPVOID *obj) +{ + ICOM_THIS(IGetFrameImpl,iface); + + TRACE("(%p)->QueryInterface(%s,%p)\n",This,debugstr_guid(refiid),obj); + if ( IsEqualGUID(&IID_IUnknown,refiid) || + IsEqualGUID(&IID_IGetFrame,refiid) ) + { + IGetFrame_AddRef(iface); + *obj = iface; + return S_OK; + } + + return OLE_E_ENUM_NOMORE; +} + +static ULONG WINAPI IGetFrame_fnAddRef(IGetFrame* iface) +{ + ICOM_THIS(IGetFrameImpl,iface); + + TRACE("(%p)->AddRef()\n",iface); + return ++(This->ref); +} + +static ULONG WINAPI IGetFrame_fnRelease(IGetFrame* iface) +{ + ICOM_THIS(IGetFrameImpl,iface); + + TRACE("(%p)->Release()\n",iface); + if ((--(This->ref)) > 0 ) + return This->ref; + IGetFrame_Destruct(This); + if ( This->pas != NULL ) + IAVIStream_Release( This->pas ); + + HeapFree(AVIFILE_data.hHeap,0,iface); + return 0; +} + +/**************************************************************************** + * IGetFrrame interface + */ + +static LPVOID WINAPI IGetFrame_fnGetFrame(IGetFrame* iface,LONG lPos) +{ + ICOM_THIS(IGetFrameImpl,iface); + LPVOID lpv; + LONG lKeyFrame; + + TRACE( "(%p)->(%ld)\n", This, lPos ); + + if ( lPos < 0 ) + return NULL; + + if ( This->lCachedFrame == lPos ) + return This->pvICOutBits; + if ( (This->lCachedFrame+1) != lPos ) + { + lKeyFrame = IAVIStream_FindSample( This->pas, lPos, + FIND_KEY | FIND_PREV ); + if ( lKeyFrame < 0 || lKeyFrame > lPos ) + return NULL; + while ( ++lKeyFrame < lPos ) + { + lpv = AVIFILE_IGetFrame_DecodeFrame(This, lKeyFrame); + if ( lpv == NULL ) + return NULL; + } + } + + lpv = AVIFILE_IGetFrame_DecodeFrame(This, lPos); + TRACE( "lpv = %p\n",lpv ); + if ( lpv == NULL ) + return NULL; + + return lpv; +} + +static HRESULT WINAPI IGetFrame_fnBegin(IGetFrame* iface,LONG lStart,LONG lEnd,LONG lRate) +{ + ICOM_THIS(IGetFrameImpl,iface); + + TRACE( "(%p)->(%ld,%ld,%ld)\n", This, lStart, lEnd, lRate ); + + if ( This->hIC == (HIC)NULL ) + return E_UNEXPECTED; + + if ( ICDecompressBegin( This->hIC, + This->pbiICIn, + This->pbiICOut ) != ICERR_OK ) + return E_FAIL; + + return S_OK; +} + +static HRESULT WINAPI IGetFrame_fnEnd(IGetFrame* iface) +{ + ICOM_THIS(IGetFrameImpl,iface); + + TRACE( "(%p)->()\n", This ); + + if ( This->hIC == (HIC)NULL ) + return E_UNEXPECTED; + + if ( ICDecompressEnd( This->hIC ) != ICERR_OK ) + return E_FAIL; + + return S_OK; +} + +static HRESULT WINAPI IGetFrame_fnSetFormat(IGetFrame* iface,LPBITMAPINFOHEADER lpbi,LPVOID lpBits,INT x,INT y,INT dx,INT dy) +{ + ICOM_THIS(IGetFrameImpl,iface); + HRESULT hr; + LONG fmtlen; + BITMAPINFOHEADER biTemp; + DWORD dwSizeImage; + + FIXME( "(%p)->(%p,%p,%d,%d,%d,%d)\n",This,lpbi,lpBits,x,y,dx,dy ); + + IGetFrame_Destruct(This); + + hr = IAVIStream_ReadFormat(This->pas,0,NULL,&fmtlen); + if ( hr != S_OK ) + return hr; + This->pvICInFmtBuf = HeapAlloc( + AVIFILE_data.hHeap,HEAP_ZERO_MEMORY,fmtlen); + if ( This->pvICInFmtBuf == NULL ) + return AVIERR_MEMORY; + hr = IAVIStream_ReadFormat(This->pas,0,This->pvICInFmtBuf,&fmtlen); + if ( hr != S_OK ) + return hr; + This->pbiICIn = (LPBITMAPINFO)This->pvICInFmtBuf; + + This->hIC = (HIC)ICOpen( ICTYPE_VIDEO, + This->pbiICIn->bmiHeader.biCompression, + ICMODE_DECOMPRESS ); + if ( This->hIC == (HIC)NULL ) + { + ERR( "no AVI decompressor for %c%c%c%c.\n", + (int)(This->pbiICIn->bmiHeader.biCompression>> 0)&0xff, + (int)(This->pbiICIn->bmiHeader.biCompression>> 8)&0xff, + (int)(This->pbiICIn->bmiHeader.biCompression>>16)&0xff, + (int)(This->pbiICIn->bmiHeader.biCompression>>24)&0xff ); + return E_FAIL; + } + + if ( lpbi == NULL || lpbi == ((LPBITMAPINFOHEADER)1) ) + { + memset( &biTemp, 0, sizeof(biTemp) ); + biTemp.biSize = sizeof(BITMAPINFOHEADER); + biTemp.biWidth = This->pbiICIn->bmiHeader.biWidth; + biTemp.biHeight = This->pbiICIn->bmiHeader.biHeight; + biTemp.biPlanes = 1; + biTemp.biBitCount = 24; + biTemp.biCompression = 0; + lpbi = &biTemp; + } + + if ( lpbi->biPlanes != 1 || lpbi->biCompression != 0 ) + return E_FAIL; + + dwSizeImage = + ((This->pbiICIn->bmiHeader.biWidth*lpbi->biBitCount+7)/8)* + This->pbiICIn->bmiHeader.biHeight; + This->pvICOutBuf = HeapAlloc( + AVIFILE_data.hHeap,HEAP_ZERO_MEMORY, + (sizeof(BITMAPINFO)+sizeof(RGBQUAD)*256)*2+ + dwSizeImage ); + if ( This->pvICOutBuf == NULL ) + return AVIERR_MEMORY; + + This->pbiICOut = (BITMAPINFO*)This->pvICOutBuf; + This->pvICOutBits = (LPVOID)( (BYTE*)This->pvICOutBuf + + sizeof(BITMAPINFO) + sizeof(RGBQUAD)*256 ); + + This->pbiICOut->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + This->pbiICOut->bmiHeader.biWidth = This->pbiICIn->bmiHeader.biWidth; + This->pbiICOut->bmiHeader.biHeight = This->pbiICIn->bmiHeader.biHeight; + This->pbiICOut->bmiHeader.biPlanes = 1; + This->pbiICOut->bmiHeader.biBitCount = lpbi->biBitCount; + This->pbiICOut->bmiHeader.biSizeImage = dwSizeImage; + memcpy( This->pvICOutBits, This->pbiICOut, sizeof(BITMAPINFOHEADER) ); + + return S_OK; +} + +static HRESULT IGetFrame_Construct( IGetFrameImpl* This, + IAVIStream* pstr, + LPBITMAPINFOHEADER lpbi ) +{ + HRESULT hr; + + TRACE( "(%p)->(%p,%p)\n",This,pstr,lpbi ); + + IAVIStream_AddRef( pstr ); + This->pas = pstr; + This->hIC = (HIC)NULL; + This->lCachedFrame = -1L; + This->pbiICIn = NULL; + This->pbiICOut = NULL; + This->pvICInFmtBuf = NULL; + This->pvICInDataBuf = NULL; + This->dwICInDataBufSize = 0; + This->pvICOutBuf = NULL; + + hr = IGetFrame_SetFormat((IGetFrame*)This,lpbi,NULL,0,0,0,0); + if ( hr != S_OK ) + return hr; + + return S_OK; +} + +static void IGetFrame_Destruct( IGetFrameImpl* This ) +{ + if ( This->hIC != (HIC)NULL ) + { + ICClose( This->hIC ); + This->hIC = (HIC)NULL; + } + if ( This->pvICInFmtBuf != NULL ) + { + HeapFree( AVIFILE_data.hHeap, 0, This->pvICInFmtBuf ); + This->pvICInFmtBuf = NULL; + } + if ( This->pvICInDataBuf != NULL ) + { + HeapFree( AVIFILE_data.hHeap, 0, This->pvICInDataBuf ); + This->pvICInDataBuf = NULL; + } + if ( This->pvICOutBuf != NULL ) + { + HeapFree( AVIFILE_data.hHeap, 0, This->pvICOutBuf ); + This->pvICOutBuf = NULL; + } + + This->lCachedFrame = -1L; + This->pbiICIn = NULL; + This->pbiICOut = NULL; + This->dwICInDataBufSize = 0; +} diff --git a/dlls/avifil32/main.c b/dlls/avifil32/main.c new file mode 100644 index 00000000000..71783d1933d --- /dev/null +++ b/dlls/avifil32/main.c @@ -0,0 +1,89 @@ +/* + * Copyright 2001 Hidenori TAKESHIMA + */ + +#include +#include +#include + +#include "winbase.h" +#include "winnls.h" +#include "mmsystem.h" +#include "winerror.h" +#include "vfw.h" +#include "debugtools.h" +#include "avifile_private.h" + +DEFAULT_DEBUG_CHANNEL(avifile); + +WINE_AVIFILE_DATA AVIFILE_data; + + +/*********************************************************************** + * AVIFILE_InitProcess (internal) + */ +static BOOL AVIFILE_InitProcess( void ) +{ + TRACE("()\n"); + + AVIFILE_data.dwAVIFileRef = 0; + AVIFILE_data.dwClassObjRef = 0; + AVIFILE_data.hHeap = (HANDLE)NULL; + + AVIFILE_data.hHeap = HeapCreate( 0, 0x10000, 0 ); + if ( AVIFILE_data.hHeap == (HANDLE)NULL ) + { + ERR( "cannot allocate heap for AVIFILE.\n" ); + return FALSE; + } + + return TRUE; +} + +/*********************************************************************** + * AVIFILE_UninitProcess (internal) + */ +static void AVIFILE_UninitProcess( void ) +{ + TRACE("()\n"); + + if ( AVIFILE_data.dwAVIFileRef != 0 ) + ERR( "you must call AVIFileExit()\n" ); + + if ( AVIFILE_data.dwClassObjRef != 0 ) + ERR( "you must release some objects allocated from AVIFile.\n" ); + + if ( AVIFILE_data.hHeap != (HANDLE)NULL ) + { + HeapDestroy( AVIFILE_data.hHeap ); + AVIFILE_data.hHeap = (HANDLE)NULL; + } +} + +/*********************************************************************** + * AVIFILE_DllMain + */ +BOOL WINAPI AVIFILE_DllMain( + HINSTANCE hInstDLL, + DWORD fdwReason, + LPVOID lpvReserved ) +{ + switch ( fdwReason ) + { + case DLL_PROCESS_ATTACH: + if ( !AVIFILE_InitProcess() ) + return FALSE; + break; + case DLL_PROCESS_DETACH: + AVIFILE_UninitProcess(); + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + } + + return TRUE; +} + + diff --git a/dlls/avifil32/string.c b/dlls/avifil32/string.c new file mode 100644 index 00000000000..562ec177d82 --- /dev/null +++ b/dlls/avifil32/string.c @@ -0,0 +1,95 @@ +/* + * Copyright 2001 Hidenori TAKESHIMA + */ + +#include +#include +#include + +#include "winbase.h" +#include "winnls.h" +#include "mmsystem.h" +#include "winerror.h" +#include "vfw.h" +#include "debugtools.h" +#include "avifile_private.h" + +DEFAULT_DEBUG_CHANNEL(avifile); + + +/**************************************************************************** + * string APIs (internal) - Copied from wine/dlls/imm32/string.c + */ + +INT AVIFILE_strlenAtoW( LPCSTR lpstr ) +{ + INT len; + + len = MultiByteToWideChar( CP_ACP, 0, lpstr, -1, NULL, 0 ); + return ( len > 0 ) ? (len-1) : 0; +} + +INT AVIFILE_strlenWtoA( LPCWSTR lpwstr ) +{ + INT len; + + len = WideCharToMultiByte( CP_ACP, 0, lpwstr, -1, + NULL, 0, NULL, NULL ); + return ( len > 0 ) ? (len-1) : 0; +} + +LPWSTR AVIFILE_strncpyAtoW( LPWSTR lpwstr, LPCSTR lpstr, INT wbuflen ) +{ + INT len; + + len = MultiByteToWideChar( CP_ACP, 0, lpstr, -1, lpwstr, wbuflen ); + if ( len == 0 ) + *lpwstr = 0; + return lpwstr; +} + +LPSTR AVIFILE_strncpyWtoA( LPSTR lpstr, LPCWSTR lpwstr, INT abuflen ) +{ + INT len; + + len = WideCharToMultiByte( CP_ACP, 0, lpwstr, -1, + lpstr, abuflen, NULL, NULL ); + if ( len == 0 ) + *lpstr = 0; + return lpstr; +} + +LPWSTR AVIFILE_strdupAtoW( LPCSTR lpstr ) +{ + INT len; + LPWSTR lpwstr = NULL; + + len = AVIFILE_strlenAtoW( lpstr ); + if ( len > 0 ) + { + lpwstr = (LPWSTR)HeapAlloc( AVIFILE_data.hHeap, 0, sizeof(WCHAR)*(len+1) ); + if ( lpwstr != NULL ) + (void)AVIFILE_strncpyAtoW( lpwstr, lpstr, len+1 ); + } + + return lpwstr; +} + +LPSTR AVIFILE_strdupWtoA( LPCWSTR lpwstr ) +{ + INT len; + LPSTR lpstr = NULL; + + len = AVIFILE_strlenWtoA( lpwstr ); + if ( len > 0 ) + { + lpstr = (LPSTR)HeapAlloc( AVIFILE_data.hHeap, 0, sizeof(CHAR)*(len+1) ); + if ( lpstr != NULL ) + (void)AVIFILE_strncpyWtoA( lpstr, lpwstr, len+1 ); + } + + return lpstr; +} + + + diff --git a/include/vfw.h b/include/vfw.h index e0492f4a96a..ef0fd161651 100644 --- a/include/vfw.h +++ b/include/vfw.h @@ -1004,6 +1004,7 @@ ICOM_DEFINE(IAVIStream, IUnknown) HRESULT WINAPI AVIMakeCompressedStream(PAVISTREAM*ppsCompressed,PAVISTREAM ppsSource,AVICOMPRESSOPTIONS *lpOptions,CLSID*pclsidHandler); +HRESULT WINAPI AVIStreamCreate(PAVISTREAM*,LONG,LONG,CLSID*); HRESULT WINAPI AVIStreamInfoA(PAVISTREAM iface,AVISTREAMINFOA *asi,LONG size); HRESULT WINAPI AVIStreamInfoW(PAVISTREAM iface,AVISTREAMINFOW *asi,LONG size); #define AVIStreamInfo WINELIB_NAME_AW(AVIStreamInfo)