- Add wavefile handler.

- Add implementation for IGetFrame.
- Implemented loading and writing of AVIs.
- Add some more stubs for some API functions.
- Add resources to avifil32.dll.
- Implemented AVISaveOptionsFree.
- Declared IID_* as extern in avifil32.spec (avoids linker problem).
This commit is contained in:
Michael Günnewig 2002-10-18 00:24:41 +00:00 committed by Alexandre Julliard
parent 9af06a4424
commit 4c04e1fd87
16 changed files with 4083 additions and 67 deletions

View File

@ -763,8 +763,8 @@ x11drv/__install__: x11drv.dll$(DLLEXT)
advapi32: kernel32.dll$(DLLEXT) ntdll.dll$(DLLEXT)
avicap32: ntdll.dll$(DLLEXT)
avifil32: msvfw32.dll$(DLLEXT) shell32.dll$(DLLEXT) user32.dll$(DLLEXT) advapi32.dll$(DLLEXT) \
kernel32.dll$(DLLEXT)
avifil32: msvfw32.dll$(DLLEXT) shell32.dll$(DLLEXT) winmm.dll$(DLLEXT) user32.dll$(DLLEXT) \
advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT)
comcat: ole32.dll$(DLLEXT) user32.dll$(DLLEXT) advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT)
comctl32: user32.dll$(DLLEXT) gdi32.dll$(DLLEXT) advapi32.dll$(DLLEXT) kernel32.dll$(DLLEXT) \
winmm.dll$(DLLEXT)

View File

@ -2,3 +2,4 @@ Makefile
avifil32.dll.dbg.c
avifil32.spec.c
avifile.spec.c
rsrc.res

View File

@ -3,7 +3,7 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = avifil32.dll
IMPORTS = msvfw32 shell32 user32 advapi32 kernel32
IMPORTS = msvfw32 shell32 winmm user32 advapi32 kernel32
ALTNAMES = avifile.dll
EXTRALIBS = $(LIBUUID)
@ -13,7 +13,13 @@ SYMBOLFILE = $(MODULE).tmp.o
C_SRCS = \
api.c \
avifile.c \
factory.c
extrachunk.c \
factory.c \
getframe.c \
wavfile.c
RC_SRCS = \
rsrc.rc
@MAKE_DLL_RULES@

View File

@ -24,11 +24,14 @@
#include "winuser.h"
#include "winreg.h"
#include "winerror.h"
#include "windowsx.h"
#include "ole2.h"
#include "shellapi.h"
#include "vfw.h"
#include "avifile_private.h"
#include "wine/debug.h"
#include "wine/unicode.h"
@ -125,6 +128,25 @@ static HRESULT AVIFILE_CLSIDFromString(LPCSTR idstr, LPCLSID id)
return S_OK;
}
static BOOL AVIFILE_GetFileHandlerByExtension(LPCWSTR szFile, LPCLSID lpclsid)
{
CHAR szRegKey[25];
CHAR szValue[100];
LPWSTR szExt = strrchrW(szFile, '.');
LONG len = sizeof(szValue) / sizeof(szValue[0]);
if (szExt == NULL)
return FALSE;
szExt++;
wsprintfA(szRegKey, "AVIFile\\Extensions\\%.3ls", szExt);
if (RegQueryValueA(HKEY_CLASSES_ROOT, szRegKey, szValue, &len) != ERROR_SUCCESS)
return FALSE;
return (AVIFILE_CLSIDFromString(szValue, lpclsid) == S_OK);
}
/***********************************************************************
* AVIFileInit (AVIFIL32.@)
* AVIFileInit (AVIFILE.100)
@ -190,7 +212,7 @@ HRESULT WINAPI AVIFileOpenW(PAVIFILE *ppfile, LPCWSTR szFile, UINT uMode,
CLSID clsidHandler;
HRESULT hr;
FIXME("(%p,%s,0x%X,%s): stub!\n", ppfile, debugstr_w(szFile), uMode,
TRACE("(%p,%s,0x%X,%s)\n", ppfile, debugstr_w(szFile), uMode,
debugstr_guid(lpHandler));
/* check parameters */
@ -201,7 +223,8 @@ HRESULT WINAPI AVIFileOpenW(PAVIFILE *ppfile, LPCWSTR szFile, UINT uMode,
/* if no handler then try guessing it by extension */
if (lpHandler == NULL) {
FIXME(": must read HKEY_CLASSES_ROOT\\AVIFile\\Extensions\\%s\n", debugstr_w(strrchrW(szFile, L'.')));
if (! AVIFILE_GetFileHandlerByExtension(szFile, &clsidHandler))
return AVIERR_UNSUPPORTED;
} else
memcpy(&clsidHandler, lpHandler, sizeof(clsidHandler));
@ -599,8 +622,9 @@ PGETFRAME WINAPI AVIStreamGetFrameOpen(PAVISTREAM pstream,
if (FAILED(IAVIStream_QueryInterface(pstream, &IID_IGetFrame, (LPVOID*)&pg)) ||
pg == NULL) {
FIXME(": need internal class for IGetFrame!\n");
return NULL;
pg = AVIFILE_CreateGetFrame(pstream);
if (pg == NULL)
return NULL;
}
if (FAILED(IGetFrame_SetFormat(pg, lpbiWanted, NULL, 0, 0, -1, -1))) {
@ -760,7 +784,7 @@ LONG WINAPI AVIStreamStart(PAVISTREAM pstream)
if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
return 0;
return asiw.dwLength;
return asiw.dwStart;
}
/***********************************************************************
@ -820,3 +844,83 @@ LONG WINAPI AVIStreamTimeToSample(PAVISTREAM pstream, LONG lTime)
return (LONG)(((float)lTime * asiw.dwRate) / asiw.dwScale / 1000.0);
}
/***********************************************************************
* AVIBuildFilterA (AVIFIL32.@)
*/
HRESULT WINAPI AVIBuildFilterA(LPSTR szFilter, LONG cbFilter, BOOL fSaving)
{
FIXME("(%p,%ld,%d): stub\n", szFilter, cbFilter, fSaving);
/* check parameters */
if (szFilter == NULL)
return AVIERR_BADPARAM;
if (cbFilter < 2)
return AVIERR_BADSIZE;
szFilter[0] = 0;
szFilter[1] = 0;
return AVIERR_UNSUPPORTED;
}
/***********************************************************************
* AVIBuildFilterW (AVIFIL32.@)
*/
HRESULT WINAPI AVIBuildFilterW(LPWSTR szFilter, LONG cbFilter, BOOL fSaving)
{
FIXME("(%p,%ld,%d): stub\n", szFilter, cbFilter, fSaving);
/* check parameters */
if (szFilter == NULL)
return AVIERR_BADPARAM;
if (cbFilter < 2)
return AVIERR_BADSIZE;
szFilter[0] = 0;
szFilter[1] = 0;
return AVIERR_UNSUPPORTED;
}
/***********************************************************************
* AVISaveOptions (AVIFIL32.@)
*/
BOOL WINAPI AVISaveOptions(HWND hWnd, UINT uFlags, INT nStream,
PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *ppOptions)
{
FIXME("(0x%X,0x%X,%d,%p,%p): stub\n", hWnd, uFlags, nStream,
ppavi, ppOptions);
return FALSE;
}
/***********************************************************************
* AVISaveOptionsFree (AVIFIL32.@)
*/
HRESULT WINAPI AVISaveOptionsFree(INT nStreams,LPAVICOMPRESSOPTIONS*ppOptions)
{
TRACE("(%d,%p)\n", nStreams, ppOptions);
if (nStreams < 0 || ppOptions == NULL)
return AVIERR_BADPARAM;
for (; nStreams > 0; nStreams--) {
if (ppOptions[nStreams] != NULL) {
ppOptions[nStreams]->dwFlags &= ~AVICOMPRESSF_VALID;
if (ppOptions[nStreams]->lpParms != NULL) {
GlobalFreePtr(ppOptions[nStreams]->lpParms);
ppOptions[nStreams]->lpParms = NULL;
ppOptions[nStreams]->cbParms = 0;
}
if (ppOptions[nStreams]->lpFormat != NULL) {
GlobalFreePtr(ppOptions[nStreams]->lpFormat);
ppOptions[nStreams]->lpFormat = NULL;
ppOptions[nStreams]->cbFormat = 0;
}
}
}
return AVIERR_OK;
}

View File

@ -1,6 +1,8 @@
init AVIFILE_DllMain
@ stub AVIBuildFilter
@ stub AVIBuildFilterA
@ stub AVIBuildFilterW
@ stdcall AVIBuildFilterA(str long long) AVIBuildFilterA
@ stdcall AVIBuildFilterW(wstr long long) AVIBuildFilterW
@ stub AVIClearClipboard
@ stdcall AVIFileAddRef(ptr) AVIFileAddRef
@ stub AVIFileCreateStream
@ -26,8 +28,8 @@
@ stub AVIPutFileOnClipboard
@ stub AVISave
@ stub AVISaveA
@ stub AVISaveOptions
@ stub AVISaveOptionsFree
@ stdcall AVISaveOptions(long long long ptr ptr) AVISaveOptions
@ stdcall AVISaveOptionsFree(long ptr) AVISaveOptionsFree
@ stub AVISaveV
@ stub AVISaveVA
@ stub AVISaveVW
@ -59,8 +61,8 @@
@ stdcall AVIStreamWriteData(ptr long ptr long) AVIStreamWriteData
@ stub CLSID_AVISimpleUnMarshal
@ stub CreateEditableStream
@ stub DllCanUnloadNow
@ stub DllGetClassObject
@ stdcall DllCanUnloadNow() AVIFILE_DllCanUnloadNow
@ stdcall DllGetClassObject(ptr ptr ptr) AVIFILE_DllGetClassObject
@ stub EditStreamClone
@ stub EditStreamCopy
@ stub EditStreamCut
@ -71,7 +73,7 @@
@ stub EditStreamSetName
@ stub EditStreamSetNameA
@ stub EditStreamSetNameW
@ stub IID_IAVIEditStream
@ stub IID_IAVIFile
@ stub IID_IAVIStream
@ stub IID_IGetFrame
@ extern IID_IAVIEditStream IID_IAVIEditStream
@ extern IID_IAVIFile IID_IAVIFile
@ extern IID_IAVIStream IID_IAVIStream
@ extern IID_IGetFrame IID_IGetFrame

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
/*
* Copyright 2002 Michael Günnewig
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
LANGUAGE LANG_GERMAN, SUBLANG_GERMAN
STRINGTABLE DISCARDABLE
{
IDS_WAVESTREAMFORMAT "Waveform: %s"
IDS_WAVEFILETYPE "Waveform"
IDS_VIDEO "Video"
IDS_AUDIO "Audio"
IDS_AVISTREAMFORMAT "%s %s #%d"
IDS_AVIFILETYPE "Wine AVI-Standard-Dateibehandlungsroutine"
IDS_UNCOMPRESSED "Unkomprimiert"
}

View File

@ -0,0 +1,30 @@
/*
* Copyright 2002 Michael Günnewig
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
STRINGTABLE DISCARDABLE
{
IDS_WAVESTREAMFORMAT "Waveform: %s"
IDS_WAVEFILETYPE "Waveform"
IDS_VIDEO "video"
IDS_AUDIO "audio"
IDS_AVISTREAMFORMAT "%s %s #%d"
IDS_AVIFILETYPE "Wine AVI-default-filehandler"
IDS_UNCOMPRESSED "uncompressed"
}

View File

@ -23,6 +23,23 @@
#define MAX_AVISTREAMS 4
#endif
#ifndef comptypeDIB
#define comptypeDIB mmioFOURCC('D','I','B',' ')
#endif
#ifndef DIBWIDTHBYTES
#define WIDTHBYTES(i) (((i+31)&(~31))/8)
#define DIBWIDTHBYTES(bi) WIDTHBYTES((bi).biWidth * (bi).biBitCount)
#endif
#define IDS_WAVESTREAMFORMAT 0x0100
#define IDS_WAVEFILETYPE 0x0101
#define IDS_VIDEO 0x0189
#define IDS_AUDIO 0x0190
#define IDS_AVISTREAMFORMAT 0x0191
#define IDS_AVIFILETYPE 0x0192
#define IDS_UNCOMPRESSED 0x0193
DEFINE_AVIGUID(CLSID_ICMStream, 0x00020001, 0, 0);
DEFINE_AVIGUID(CLSID_WAVFile, 0x00020003, 0, 0);
DEFINE_AVIGUID(CLSID_ACMStream, 0x0002000F, 0, 0);
@ -33,5 +50,8 @@ extern HRESULT AVIFILE_CreateAVIFile(REFIID riid, LPVOID *ppobj);
extern HRESULT AVIFILE_CreateWAVFile(REFIID riid, LPVOID *ppobj);
extern HRESULT AVIFILE_CreateACMStream(REFIID riid, LPVOID *ppobj);
extern HRESULT AVIFILE_CreateICMStream(REFIID riid, LPVOID *ppobj);
extern PGETFRAME AVIFILE_CreateGetFrame(PAVISTREAM pstream);
extern LPCWSTR AVIFILE_BasenameW(LPCWSTR szFileName);
#endif

196
dlls/avifil32/extrachunk.c Normal file
View File

@ -0,0 +1,196 @@
/*
* Copyright 2002 Michael Günnewig
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <assert.h>
#include "extrachunk.h"
#include "winbase.h"
#include "windowsx.h"
#include "vfw.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(avifile);
/* reads a chunk outof the extrachunk-structure */
HRESULT ReadExtraChunk(LPEXTRACHUNKS extra,FOURCC ckid,LPVOID lpData,
LPLONG size)
{
LPBYTE lp;
LONG cb;
/* pre-conditions */
assert(extra != NULL);
assert(size != NULL);
lp = extra->lp;
cb = extra->cb;
if (lp != NULL) {
while (cb > 0) {
if (((FOURCC*)lp)[0] == ckid) {
/* found correct chunk */
if (lpData != NULL && *size > 0)
memcpy(lpData, lp + 2 * sizeof(DWORD), min(((LPDWORD)lp)[1],*size));
*size = ((LPDWORD)lp)[1];
return AVIERR_OK;
} else {
/* skip to next chunk */
cb -= ((LPDWORD)lp)[1] + 2 * sizeof(DWORD);
lp += ((LPDWORD)lp)[1] + 2 * sizeof(DWORD);
}
}
}
/* wanted chunk doesn't exist */
*size = 0;
return AVIERR_NODATA;
}
/* writes a chunk into the extrachunk-structure */
HRESULT WriteExtraChunk(LPEXTRACHUNKS extra,FOURCC ckid,LPVOID lpData,
LONG size)
{
LPDWORD lp;
/* pre-conditions */
assert(extra != NULL);
assert(lpData != NULL);
assert(size > 0);
if (extra->lp)
lp = (LPDWORD)GlobalReAllocPtr(extra->lp, extra->cb + size + 2 * sizeof(DWORD), GHND);
else
lp = (LPDWORD)GlobalAllocPtr(GHND, size + 2 * sizeof(DWORD));
if (lp == NULL)
return AVIERR_MEMORY;
extra->lp = lp;
((LPBYTE)lp) += extra->cb;
extra->cb += size + 2 * sizeof(DWORD);
/* insert chunk-header in block */
lp[0] = ckid;
lp[1] = size;
if (lpData != NULL && size > 0)
memcpy(lp + 2, lpData, size);
return AVIERR_OK;
}
/* reads a chunk fomr the HMMIO into the extrachunk-structure */
HRESULT ReadChunkIntoExtra(LPEXTRACHUNKS extra,HMMIO hmmio,MMCKINFO *lpck)
{
LPDWORD lp;
LONG cb;
/* pre-conditions */
assert(extra != NULL);
assert(hmmio != (HMMIO)NULL);
assert(lpck != NULL);
cb = lpck->cksize + 2 * sizeof(DWORD);
cb += (cb & 1);
if (extra->lp != NULL) {
lp = (LPDWORD)GlobalReAllocPtr(extra->lp, extra->cb + cb, GHND);
} else
lp = (LPDWORD)GlobalAllocPtr(GHND, cb);
if (lp == NULL)
return AVIERR_MEMORY;
extra->lp = lp;
((LPBYTE)lp) += extra->cb;
extra->cb += cb;
/* insert chunk-header in block */
lp[0] = lpck->ckid;
lp[1] = lpck->cksize;
if (lpck->cksize > 0) {
if (mmioSeek(hmmio, lpck->dwDataOffset, SEEK_SET) == -1)
return AVIERR_FILEREAD;
if (mmioRead(hmmio, (HPSTR)&lp[2], lpck->cksize) != lpck->cksize)
return AVIERR_FILEREAD;
}
return AVIERR_OK;
}
/* reads all non-junk chunks into the extrachunk-structure until it founds
* the given chunk or the optional parent-chunk is at the end */
HRESULT FindChunkAndKeepExtras(LPEXTRACHUNKS extra,HMMIO hmmio,MMCKINFO *lpck,
MMCKINFO *lpckParent,UINT flags)
{
FOURCC ckid;
FOURCC fccType;
HRESULT hr;
/* pre-conditions */
assert(extra != NULL);
assert(hmmio != (HMMIO)NULL);
assert(lpck != NULL);
TRACE("({%p,%lu},%d,%p,%p,0x%X)\n", extra->lp, extra->cb, hmmio, lpck,
lpckParent, flags);
/* what chunk id and form/list type shoiuld we search? */
if (flags & MMIO_FINDCHUNK) {
ckid = lpck->ckid;
fccType = 0;
} else if (flags & MMIO_FINDLIST) {
ckid = FOURCC_LIST;
fccType = lpck->fccType;
} else if (flags & MMIO_FINDRIFF) {
ckid = FOURCC_RIFF;
fccType = lpck->fccType;
} else
ckid = fccType = (FOURCC)-1; /* collect everything into extra! */
TRACE(": find ckid=0x%08lX fccType=0x%08lX\n", ckid, fccType);
for (;;) {
hr = mmioDescend(hmmio, lpck, lpckParent, 0);
if (hr != S_OK) {
/* No extra chunks infront of desired chunk? */
if (flags == 0 && hr == MMIOERR_CHUNKNOTFOUND)
hr = AVIERR_OK;
return hr;
}
/* Have we found what we search for? */
if ((lpck->ckid == ckid) &&
(fccType == (FOURCC)0 || lpck->fccType == fccType))
return AVIERR_OK;
/* Skip padding chunks, the others put into the extrachunk-structure */
if (lpck->ckid == ckidAVIPADDING ||
lpck->ckid == mmioFOURCC('p','a','d','d'))
hr = mmioAscend(hmmio, lpck, 0);
else
hr = ReadChunkIntoExtra(extra, hmmio, lpck);
if (FAILED(hr))
return hr;
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright 2002 Michael Günnewig
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __WINE_EXTRACHUNK_H
#define __WINE_EXTRACHUNK_H
#include "windef.h"
#include "mmsystem.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _EXTRACHUNKS {
LPVOID lp;
DWORD cb;
} EXTRACHUNKS, *LPEXTRACHUNKS;
/* reads a chunk outof the extrachunk-structure */
HRESULT ReadExtraChunk(LPEXTRACHUNKS extra,FOURCC ckid,LPVOID lp,LPLONG size);
/* writes a chunk into the extrachunk-structure */
HRESULT WriteExtraChunk(LPEXTRACHUNKS extra,FOURCC ckid,LPVOID lp,LONG size);
/* reads a chunk fomr the HMMIO into the extrachunk-structure */
HRESULT ReadChunkIntoExtra(LPEXTRACHUNKS extra,HMMIO hmmio,MMCKINFO *lpck);
/* reads all non-junk chunks into the extrachunk-structure until it founds
* the given chunk or the optional parent-chunk is at the end */
HRESULT FindChunkAndKeepExtras(LPEXTRACHUNKS extra,HMMIO hmmio,
MMCKINFO *lpck,MMCKINFO *lpckParent,UINT flags);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -19,6 +19,7 @@
#include <assert.h>
#include "winbase.h"
#include "winnls.h"
#include "winerror.h"
#include "ole2.h"
@ -126,7 +127,8 @@ static HRESULT WINAPI IClassFactory_fnCreateInstance(LPCLASSFACTORY iface,
{
ICOM_THIS(IClassFactoryImpl,iface);
FIXME("(%p,%p,%s,%p): stub!\n", iface, pOuter, debugstr_guid(riid), ppobj);
FIXME("(%p,%p,%s,%p): partial stub!\n", iface, pOuter, debugstr_guid(riid),
ppobj);
if (ppobj == NULL || pOuter != NULL)
return E_FAIL;
@ -134,11 +136,11 @@ static HRESULT WINAPI IClassFactory_fnCreateInstance(LPCLASSFACTORY iface,
if (IsEqualGUID(&CLSID_AVIFile, &This->clsid))
return AVIFILE_CreateAVIFile(riid,ppobj);
/* if (IsEqualGUID(&CLSID_ICMStream, This->clsid)) */
/* if (IsEqualGUID(&CLSID_ICMStream, &This->clsid)) */
/* return AVIFILE_CreateICMStream(riid,ppobj); */
/* if (IsEqualGUID(&CLSID_WAVFile, This->clsid)) */
/* return AVIFILE_CreateWAVFile(riid,ppobj); */
/* if (IsEqualGUID(&CLSID_ACMStream, This->clsid)) */
if (IsEqualGUID(&CLSID_WAVFile, &This->clsid))
return AVIFILE_CreateWAVFile(riid,ppobj);
/* if (IsEqualGUID(&CLSID_ACMStream, &This->clsid)) */
/* return AVIFILE_CreateACMStream(riid,ppobj); */
return E_NOINTERFACE;
@ -153,6 +155,23 @@ static HRESULT WINAPI IClassFactory_fnLockServer(LPCLASSFACTORY iface,BOOL doloc
return S_OK;
}
LPCWSTR AVIFILE_BasenameW(LPCWSTR szPath)
{
#define SLASH(w) ((w) == '/' || (w) == '\\')
LPCWSTR szCur;
for (szCur = szPath + lstrlenW(szPath);
szCur > szPath && !SLASH(*szCur) && *szCur != ':';)
szCur--;
if (szCur == szPath)
return szCur;
else
return szCur + 1;
#undef SLASH
}
/***********************************************************************
* DllGetClassObject (AVIFIL32.@)
@ -181,7 +200,7 @@ DWORD WINAPI AVIFILE_DllCanUnloadNow(void)
BOOL WINAPI AVIFILE_DllMain(HINSTANCE hInstDll, DWORD fdwReason,
LPVOID lpvReserved)
{
TRACE("(%d,%lu,%p)\n", hInstDll, fdwReason, lpvReserved);
TRACE("(0x%X,%lu,%p)\n", hInstDll, fdwReason, lpvReserved);
switch (fdwReason) {
case DLL_PROCESS_ATTACH:

500
dlls/avifil32/getframe.c Normal file
View File

@ -0,0 +1,500 @@
/*
* Copyright 2002 Michael Günnewig
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <assert.h>
#include "winbase.h"
#include "winnls.h"
#include "windowsx.h"
#include "vfw.h"
#include "avifile_private.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(avifile);
#ifndef DIBPTR
#define DIBPTR(lp) ((LPBYTE)(lp) + (lp)->biSize + \
(lp)->biClrUsed * sizeof(RGBQUAD))
#endif
/***********************************************************************/
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) igetframeVtbl = {
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
IGetFrame_fnQueryInterface,
IGetFrame_fnAddRef,
IGetFrame_fnRelease,
IGetFrame_fnGetFrame,
IGetFrame_fnBegin,
IGetFrame_fnEnd,
IGetFrame_fnSetFormat
};
typedef struct _IGetFrameImpl {
/* IUnknown stuff */
ICOM_VFIELD(IGetFrame);
DWORD ref;
/* IGetFrame stuff */
BOOL bFixedStream;
PAVISTREAM pStream;
LPVOID lpInBuffer;
DWORD cbInBuffer;
LPBITMAPINFOHEADER lpInFormat;
DWORD cbInFormat;
LONG lCurrentFrame;
LPBITMAPINFOHEADER lpOutFormat;
LPVOID lpOutBuffer;
HIC hic;
BOOL bResize;
DWORD x;
DWORD y;
DWORD dx;
DWORD dy;
BOOL bFormatChanges;
DWORD dwFormatChangeCount;
DWORD dwEditCount;
} IGetFrameImpl;
/***********************************************************************/
static void AVIFILE_CloseCompressor(IGetFrameImpl *This)
{
if (This->lpOutFormat != NULL && This->lpInFormat != This->lpOutFormat) {
GlobalFreePtr(This->lpOutFormat);
This->lpOutFormat = NULL;
}
if (This->lpInFormat != NULL) {
GlobalFreePtr(This->lpInFormat);
This->lpInFormat = NULL;
}
if (This->hic != (HIC)NULL) {
if (This->bResize)
ICDecompressExEnd(This->hic);
else
ICDecompressEnd(This->hic);
ICClose(This->hic);
This->hic = (HIC)NULL;
}
}
PGETFRAME AVIFILE_CreateGetFrame(PAVISTREAM pStream)
{
IGetFrameImpl *pg;
/* check parameter */
if (pStream == NULL)
return NULL;
pg = (IGetFrameImpl*)LocalAlloc(LPTR, sizeof(IGetFrameImpl));
if (pg != NULL) {
ICOM_VTBL(pg) = &igetframeVtbl;
pg->ref = 1;
pg->lCurrentFrame = -1;
pg->pStream = pStream;
IAVIStream_AddRef(pStream);
}
return (PGETFRAME)pg;
}
static HRESULT WINAPI IGetFrame_fnQueryInterface(IGetFrame *iface,
REFIID refiid, LPVOID *obj)
{
ICOM_THIS(IGetFrameImpl,iface);
TRACE("(%p,%s,%p)\n", This, debugstr_guid(refiid), obj);
if (IsEqualGUID(&IID_IUnknown, refiid) ||
IsEqualGUID(&IID_IGetFrame, refiid)) {
*obj = iface;
return S_OK;
}
return OLE_E_ENUM_NOMORE;
}
static ULONG WINAPI IGetFrame_fnAddRef(IGetFrame *iface)
{
ICOM_THIS(IGetFrameImpl,iface);
TRACE("(%p)\n", iface);
return ++(This->ref);
}
static ULONG WINAPI IGetFrame_fnRelease(IGetFrame *iface)
{
ICOM_THIS(IGetFrameImpl,iface);
TRACE("(%p)\n", iface);
if (!--(This->ref)) {
AVIFILE_CloseCompressor(This);
if (This->pStream != NULL) {
AVIStreamRelease(This->pStream);
This->pStream = NULL;
}
LocalFree((HLOCAL)iface);
return 0;
}
return This->ref;
}
static LPVOID WINAPI IGetFrame_fnGetFrame(IGetFrame *iface, LONG lPos)
{
ICOM_THIS(IGetFrameImpl,iface);
LONG readBytes;
LONG readSamples;
TRACE("(%p,%ld)\n", iface, lPos);
/* check state */
if (This->pStream == NULL)
return NULL;
if (This->lpInFormat == NULL)
return NULL;
/* Could stream have changed? */
if (! This->bFixedStream) {
AVISTREAMINFOW sInfo;
IAVIStream_Info(This->pStream, &sInfo, sizeof(sInfo));
if (sInfo.dwEditCount != This->dwEditCount) {
This->dwEditCount = sInfo.dwEditCount;
This->lCurrentFrame = -1;
}
if (sInfo.dwFormatChangeCount != This->dwFormatChangeCount) {
/* stream has changed */
if (This->lpOutFormat != NULL) {
BITMAPINFOHEADER bi;
memcpy(&bi, This->lpOutFormat, sizeof(bi));
AVIFILE_CloseCompressor(This);
if (FAILED(IGetFrame_SetFormat(iface, &bi, NULL, 0, 0, -1, -1))) {
if (FAILED(IGetFrame_SetFormat(iface, NULL, NULL, 0, 0, -1, -1)))
return NULL;
}
} else if (FAILED(IGetFrame_SetFormat(iface, NULL, NULL, 0, 0, -1, -1)))
return NULL;
}
}
if (lPos != This->lCurrentFrame) {
LONG lNext = AVIStreamFindSample(This->pStream, lPos, FIND_KEY|FIND_PREV);
if (lNext == -1)
lNext = 0; /* first frame is always a keyframe */
if (lNext <= This->lCurrentFrame && This->lCurrentFrame < lPos)
lNext++;
for (; lNext < lPos; lNext++) {
/* new format for this frame? */
if (This->bFormatChanges) {
AVIStreamReadFormat(This->pStream, lNext, This->lpInFormat, &This->cbInFormat);
if (This->lpOutFormat != NULL) {
if (This->lpOutFormat->biBitCount <= 8)
ICDecompressGetPalette(This->hic, This->lpInFormat,
This->lpOutFormat);
}
}
/* read input frame */
while (FAILED(AVIStreamRead(This->pStream, lNext, 1, This->lpInBuffer,
This->cbInBuffer, &readBytes, &readSamples))) {
/* not enough memory for input buffer? */
readBytes = 0;
if (FAILED(AVIStreamSampleSize(This->pStream, lNext, &readBytes)))
return NULL;
if (This->cbInBuffer >= readBytes)
break;
This->lpInFormat = GlobalReAllocPtr(This->lpInFormat, This->cbInFormat + readBytes, 0);
if (This->lpInFormat == NULL)
return NULL;
This->lpInBuffer = (BYTE*)This->lpInFormat + This->cbInFormat;
}
if (readSamples != 1)
return NULL;
if (readBytes != 0) {
This->lpInFormat->biSizeImage = readBytes;
/* nothing to decompress? */
if (This->hic == (HIC)NULL) {
This->lCurrentFrame = lPos;
return This->lpInFormat;
}
if (This->bResize) {
ICDecompressEx(This->hic,0,This->lpInFormat,This->lpInBuffer,0,0,
This->lpInFormat->biWidth,This->lpInFormat->biHeight,
This->lpOutFormat,This->lpOutBuffer,This->x,This->y,
This->dx,This->dy);
} else {
ICDecompress(This->hic, 0, This->lpInFormat, This->lpInBuffer,
This->lpOutFormat, This->lpOutBuffer);
}
}
} /* for (lNext < lPos) */
} /* if (This->lCurrentFrame != lPos) */
return (This->hic == (HIC)NULL ? This->lpInFormat : This->lpOutFormat);
}
static HRESULT WINAPI IGetFrame_fnBegin(IGetFrame *iface, LONG lStart,
LONG lEnd, LONG lRate)
{
ICOM_THIS(IGetFrameImpl,iface);
TRACE("(%p,%ld,%ld,%ld)\n", iface, lStart, lEnd, lRate);
This->bFixedStream = TRUE;
return (IGetFrame_GetFrame(iface, lStart) ? AVIERR_OK : AVIERR_ERROR);
}
static HRESULT WINAPI IGetFrame_fnEnd(IGetFrame *iface)
{
ICOM_THIS(IGetFrameImpl,iface);
TRACE("(%p)\n", iface);
This->bFixedStream = FALSE;
return AVIERR_OK;
}
static HRESULT WINAPI IGetFrame_fnSetFormat(IGetFrame *iface,
LPBITMAPINFOHEADER lpbiWanted,
LPVOID lpBits, INT x, INT y,
INT dx, INT dy)
{
ICOM_THIS(IGetFrameImpl,iface);
AVISTREAMINFOW sInfo;
LPBITMAPINFOHEADER lpbi = lpbiWanted;
BOOL bBestDisplay = FALSE;
TRACE("(%p,%p,%p,%d,%d,%d,%d)\n", iface, lpbiWanted, lpBits,
x, y, dx, dy);
if (This->pStream == NULL)
return AVIERR_ERROR;
if ((LONG)lpbiWanted == AVIGETFRAMEF_BESTDISPLAYFMT) {
lpbi = NULL;
bBestDisplay = TRUE;
}
IAVIStream_Info(This->pStream, &sInfo, sizeof(sInfo));
if (sInfo.fccType != streamtypeVIDEO)
return AVIERR_UNSUPPORTED;
This->bFormatChanges =
(sInfo.dwFlags & AVISTREAMINFO_FORMATCHANGES ? TRUE : FALSE );
This->dwFormatChangeCount = sInfo.dwFormatChangeCount;
This->dwEditCount = sInfo.dwEditCount;
This->lCurrentFrame = -1;
/* get input format from stream */
if (This->lpInFormat == NULL) {
This->cbInBuffer = sInfo.dwSuggestedBufferSize;
if (This->cbInBuffer == 0)
This->cbInBuffer = 1024;
AVIStreamFormatSize(This->pStream, sInfo.dwStart, &This->cbInFormat);
This->lpInFormat =
(LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, This->cbInFormat + This->cbInBuffer);
if (This->lpInFormat == NULL) {
AVIFILE_CloseCompressor(This);
return AVIERR_MEMORY;
}
AVIStreamReadFormat(This->pStream, sInfo.dwStart, This->lpInFormat, &This->cbInFormat);
This->lpInBuffer = ((LPBYTE)This->lpInFormat) + This->cbInFormat;
}
/* check input format */
if (This->lpInFormat->biClrUsed == 0 && This->lpInFormat->biBitCount <= 8)
This->lpInFormat->biClrUsed = 1u << This->lpInFormat->biBitCount;
if (This->lpInFormat->biSizeImage == 0 &&
This->lpInFormat->biCompression == BI_RGB) {
This->lpInFormat->biSizeImage =
DIBWIDTHBYTES(*This->lpInFormat) * This->lpInFormat->biHeight;
}
/* only to pass through? */
if (This->lpInFormat->biCompression == BI_RGB && lpBits == NULL) {
if (lpbi == NULL ||
(lpbi->biCompression == BI_RGB &&
lpbi->biWidth == This->lpInFormat->biWidth &&
lpbi->biHeight == This->lpInFormat->biHeight &&
lpbi->biBitCount == This->lpInFormat->biBitCount)) {
This->lpOutFormat = This->lpInFormat;
This->lpOutBuffer = DIBPTR(This->lpInFormat);
return AVIERR_OK;
}
}
/* need memory for output format? */
if (This->lpOutFormat == NULL) {
This->lpOutFormat =
(LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, sizeof(BITMAPINFOHEADER)
+ 256 * sizeof(RGBQUAD));
if (This->lpOutFormat == NULL) {
AVIFILE_CloseCompressor(This);
return AVIERR_MEMORY;
}
}
/* need handle to video compressor */
if (This->hic == (HIC)NULL) {
FOURCC fccHandler;
if (This->lpInFormat->biCompression == BI_RGB)
fccHandler = comptypeDIB;
else if (This->lpInFormat->biCompression == BI_RLE8)
fccHandler = mmioFOURCC('R','L','E',' ');
else
fccHandler = sInfo.fccHandler;
if (lpbi != NULL) {
if (lpbi->biWidth == 0)
lpbi->biWidth = This->lpInFormat->biWidth;
if (lpbi->biHeight == 0)
lpbi->biHeight = This->lpInFormat->biHeight;
}
This->hic = ICLocate(ICTYPE_VIDEO, fccHandler, This->lpInFormat, lpbi, ICMODE_DECOMPRESS);
if (This->hic == (HIC)NULL) {
AVIFILE_CloseCompressor(This);
return AVIERR_NOCOMPRESSOR;
}
}
/* output format given? */
if (lpbi != NULL) {
/* check the given output format ... */
if (lpbi->biClrUsed == 0 && lpbi->biBitCount <= 8)
lpbi->biClrUsed = 1u << lpbi->biBitCount;
/* ... and remember it */
memcpy(This->lpOutFormat, lpbi,
lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD));
if (lpbi->biBitCount <= 8)
ICDecompressGetPalette(This->hic, This->lpInFormat, This->lpOutFormat);
return AVIERR_OK;
} else {
if (bBestDisplay) {
ICGetDisplayFormat(This->hic, This->lpInFormat,
This->lpOutFormat, 0, dx, dy);
} else if (ICDecompressGetFormat(This->hic, This->lpInFormat,
This->lpOutFormat) < 0) {
AVIFILE_CloseCompressor(This);
return AVIERR_NOCOMPRESSOR;
}
/* check output format */
if (This->lpOutFormat->biClrUsed == 0 &&
This->lpOutFormat->biBitCount <= 8)
This->lpOutFormat->biClrUsed = 1u << This->lpOutFormat->biBitCount;
if (This->lpOutFormat->biSizeImage == 0 &&
This->lpOutFormat->biCompression == BI_RGB) {
This->lpOutFormat->biSizeImage =
DIBWIDTHBYTES(*This->lpOutFormat) * This->lpOutFormat->biHeight;
}
if (lpBits == NULL) {
register DWORD size = This->lpOutFormat->biClrUsed * sizeof(RGBQUAD);
size += This->lpOutFormat->biSize + This->lpOutFormat->biSizeImage;
This->lpOutFormat =
(LPBITMAPINFOHEADER)GlobalReAllocPtr(This->lpOutFormat, size, GMEM_MOVEABLE);
if (This->lpOutFormat == NULL) {
AVIFILE_CloseCompressor(This);
return AVIERR_MEMORY;
}
This->lpOutBuffer = DIBPTR(This->lpOutFormat);
} else
This->lpOutBuffer = lpBits;
/* for user size was irrelevant */
if (dx == -1)
dx = This->lpOutFormat->biWidth;
if (dy == -1)
dy = This->lpOutFormat->biHeight;
/* need to resize? */
if (x != 0 || y != 0) {
if (dy == This->lpOutFormat->biHeight &&
dx == This->lpOutFormat->biWidth)
This->bResize = FALSE;
else
This->bResize = TRUE;
}
if (This->bResize) {
This->x = x;
This->y = y;
This->dx = dx;
This->dy = dy;
if (ICDecompressExBegin(This->hic,0,This->lpInFormat,This->lpInBuffer,0,
0,This->lpInFormat->biWidth,
This->lpInFormat->biHeight,This->lpOutFormat,
This->lpOutBuffer, x, y, dx, dy) == ICERR_OK)
return AVIERR_OK;
} else if (ICDecompressBegin(This->hic, This->lpInFormat,
This->lpOutFormat) == ICERR_OK)
return AVIERR_OK;
AVIFILE_CloseCompressor(This);
return AVIERR_COMPRESSOR;
}
}
/***********************************************************************/

61
dlls/avifil32/rsrc.rc Normal file
View File

@ -0,0 +1,61 @@
/*
* Top level resource file for avifil32.dll
*
* Copyright 2002 Michael Günnewig
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "windef.h"
#include "winuser.h"
#include "winver.h"
#include "avifile_private.h"
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
1 VERSIONINFO
FILEVERSION 4, 3, 0, 1998
PRODUCTVERSION 4, 3, 0, 1998
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef NDEBUG
FILEFLAGS 0
#else
FILEFLAGS VS_FF_DEBUG
#endif
FILEOS VOS_DOS_WINDOWS32
FILETYPE VFT_DLL
{
BLOCK "StringFileInfo"
{
BLOCK "040604B0" /* Deutschland (Standard) */
{
VALUE "CompanyName", "Wine Developer Team\000"
VALUE "FileDescription", "Wine Bibliothek zur Unterstützung von AVI-Dateien\000"
VALUE "FileVersion", "4.03.1998\000"
VALUE "InternalName", "AVIFIL32\000"
VALUE "LegalCopyright", "Copyright \251 Michael Günnewig 2002\000"
VALUE "OriginalFileName", "AVIFIL32.DLL\000"
VALUE "ProductName", "Wine\000"
VALUE "ProductVersion", "1.00\000"
}
}
}
/*
* Everything specific to any language goes
* in one of the specific files.
*/
#include "avifile_De.rc"
#include "avifile_En.rc"

1075
dlls/avifil32/wavfile.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1057,3 +1057,59 @@
"Times New Roman Greek,161"="Times New Roman,161"
"Times New Roman TUR,162"="Times New Roman,162"
"Tms Rmn"="Times New Roman"
[HKEY_CLASSES_ROOT\AVIFile\Compressors\auds]
@="{0002000F-0000-0000-C000-000000000046}"
[HKEY_CLASSES_ROOT\AVIFile\Compressors\vids]
@="{00020001-0000-0000-C000-000000000046}"
[HKEY_CLASSES_ROOT\AVIFile\Extensions\AU]
@="{00020003-0000-0000-C000-000000000046}"
[HKEY_CLASSES_ROOT\AVIFile\Extensions\AVI]
@="{00020000-0000-0000-C000-000000000046}"
[HKEY_CLASSES_ROOT\AVIFile\Extensions\WAV]
@="{00020003-0000-0000-C000-000000000046}"
[HKEY_CLASSES_ROOT\AVIFile\RIFFHandlers\AVI]
@="{00020000-0000-0000-C000-000000000046}"
[HKEY_CLASSES_ROOT\AVIFile\RIFFHandlers\WAVE]
@="{00020003-0000-0000-C000-000000000046}"
[HKEY_CLASSES_ROOT\CLSID\{00020000-0000-0000-C000-000000000046}\InProcServer]
@="avifile.dll"
[HKEY_CLASSES_ROOT\CLSID\{00020000-0000-0000-C000-000000000046}\InProcServer32]
@="avifil32.dll"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\CLSID\{00020001-0000-0000-C000-000000000046}\InProcServer]
@="avifile.dll"
[HKEY_CLASSES_ROOT\CLSID\{00020001-0000-0000-C000-000000000046}\InProcServer32]
@="avifil32.dll"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\CLSID\{00020003-0000-0000-C000-000000000046}\InProcServer]
@="avifile.dll"
[HKEY_CLASSES_ROOT\CLSID\{00020003-0000-0000-C000-000000000046}\InProcServer32]
@="avifil32.dll"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\CLSID\{0002000D-0000-0000-C000-000000000046}\InProcServer]
@="avifile.dll"
[HKEY_CLASSES_ROOT\CLSID\{0002000D-0000-0000-C000-000000000046}\InProcServer32]
@="avifil32.dll"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\CLSID\{0002000F-0000-0000-C000-000000000046}\InProcServer]
@="avifile.dll"
[HKEY_CLASSES_ROOT\CLSID\{0002000F-0000-0000-C000-000000000046}\InProcServer32]
@="avifil32.dll"
"ThreadingModel"="Apartment"