Get rid of the no longer used ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
[wine/multimedia.git] / dlls / avifil32 / tmpfile.c
blob6978456d804c9dcc02fbccd09a83dbe1159dade5
1 /*
2 * Copyright 2003 Michael Günnewig
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #define COM_NO_WINDOWS_H
20 #include <assert.h>
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "winnls.h"
28 #include "winerror.h"
29 #include "windowsx.h"
30 #include "mmsystem.h"
31 #include "vfw.h"
33 #include "avifile_private.h"
34 #include "extrachunk.h"
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(avifile);
40 /***********************************************************************/
42 static HRESULT WINAPI ITmpFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj);
43 static ULONG WINAPI ITmpFile_fnAddRef(IAVIFile* iface);
44 static ULONG WINAPI ITmpFile_fnRelease(IAVIFile* iface);
45 static HRESULT WINAPI ITmpFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size);
46 static HRESULT WINAPI ITmpFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam);
47 static HRESULT WINAPI ITmpFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi);
48 static HRESULT WINAPI ITmpFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size);
49 static HRESULT WINAPI ITmpFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size);
50 static HRESULT WINAPI ITmpFile_fnEndRecord(IAVIFile*iface);
51 static HRESULT WINAPI ITmpFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam);
53 struct IAVIFileVtbl itmpft = {
54 ITmpFile_fnQueryInterface,
55 ITmpFile_fnAddRef,
56 ITmpFile_fnRelease,
57 ITmpFile_fnInfo,
58 ITmpFile_fnGetStream,
59 ITmpFile_fnCreateStream,
60 ITmpFile_fnWriteData,
61 ITmpFile_fnReadData,
62 ITmpFile_fnEndRecord,
63 ITmpFile_fnDeleteStream
66 typedef struct _ITmpFileImpl {
67 /* IUnknown stuff */
68 IAVIFileVtbl *lpVtbl;
69 DWORD ref;
71 /* IAVIFile stuff */
72 AVIFILEINFOW fInfo;
73 PAVISTREAM *ppStreams;
74 } ITmpFileImpl;
76 PAVIFILE AVIFILE_CreateAVITempFile(int nStreams, PAVISTREAM *ppStreams) {
77 ITmpFileImpl *tmpFile;
78 int i;
80 tmpFile = LocalAlloc(LPTR, sizeof(ITmpFileImpl));
81 if (tmpFile == NULL)
82 return NULL;
84 tmpFile->lpVtbl = &itmpft;
85 tmpFile->ref = 1;
86 memset(&tmpFile->fInfo, 0, sizeof(tmpFile->fInfo));
88 tmpFile->fInfo.dwStreams = nStreams;
89 tmpFile->ppStreams = LocalAlloc(LPTR, nStreams * sizeof(PAVISTREAM));
90 if (tmpFile->ppStreams == NULL) {
91 LocalFree((HLOCAL)tmpFile);
92 return NULL;
95 for (i = 0; i < nStreams; i++) {
96 AVISTREAMINFOW sInfo;
98 tmpFile->ppStreams[i] = ppStreams[i];
100 AVIStreamAddRef(ppStreams[i]);
101 AVIStreamInfoW(ppStreams[i], &sInfo, sizeof(sInfo));
102 if (i == 0) {
103 tmpFile->fInfo.dwScale = sInfo.dwScale;
104 tmpFile->fInfo.dwRate = sInfo.dwRate;
105 if (!sInfo.dwScale || !sInfo.dwRate) {
106 tmpFile->fInfo.dwScale = 1;
107 tmpFile->fInfo.dwRate = 100;
111 if (tmpFile->fInfo.dwSuggestedBufferSize < sInfo.dwSuggestedBufferSize)
112 tmpFile->fInfo.dwSuggestedBufferSize = sInfo.dwSuggestedBufferSize;
115 register DWORD tmp;
117 tmp = MulDiv(AVIStreamSampleToTime(ppStreams[i], sInfo.dwLength), \
118 tmpFile->fInfo.dwScale, tmpFile->fInfo.dwRate * 1000);
119 if (tmpFile->fInfo.dwLength < tmp)
120 tmpFile->fInfo.dwLength = tmp;
122 tmp = sInfo.rcFrame.right - sInfo.rcFrame.left;
123 if (tmpFile->fInfo.dwWidth < tmp)
124 tmpFile->fInfo.dwWidth = tmp;
125 tmp = sInfo.rcFrame.bottom - sInfo.rcFrame.top;
126 if (tmpFile->fInfo.dwHeight < tmp)
127 tmpFile->fInfo.dwHeight = tmp;
131 return (PAVIFILE)tmpFile;
134 static HRESULT WINAPI ITmpFile_fnQueryInterface(IAVIFile *iface, REFIID refiid,
135 LPVOID *obj)
137 ICOM_THIS(ITmpFileImpl,iface);
139 TRACE("(%p,%s,%p)\n", This, debugstr_guid(refiid), obj);
141 if (IsEqualGUID(&IID_IUnknown, refiid) ||
142 IsEqualGUID(&IID_IAVIFile, refiid)) {
143 *obj = iface;
144 IAVIFile_AddRef(iface);
146 return S_OK;
149 return OLE_E_ENUM_NOMORE;
152 static ULONG WINAPI ITmpFile_fnAddRef(IAVIFile *iface)
154 ICOM_THIS(ITmpFileImpl,iface);
156 TRACE("(%p) -> %ld\n", iface, This->ref + 1);
157 return ++(This->ref);
160 static ULONG WINAPI ITmpFile_fnRelease(IAVIFile *iface)
162 ICOM_THIS(ITmpFileImpl,iface);
164 TRACE("(%p) -> %ld\n", iface, This->ref - 1);
166 if (!--(This->ref)) {
167 int i;
169 for (i = 0; i < This->fInfo.dwStreams; i++) {
170 if (This->ppStreams[i] != NULL) {
171 AVIStreamRelease(This->ppStreams[i]);
173 This->ppStreams[i] = NULL;
177 LocalFree((HLOCAL)This);
178 return 0;
181 return This->ref;
184 static HRESULT WINAPI ITmpFile_fnInfo(IAVIFile *iface,
185 AVIFILEINFOW *afi, LONG size)
187 ICOM_THIS(ITmpFileImpl,iface);
189 TRACE("(%p,%p,%ld)\n",iface,afi,size);
191 if (afi == NULL)
192 return AVIERR_BADPARAM;
193 if (size < 0)
194 return AVIERR_BADSIZE;
196 memcpy(afi, &This->fInfo, min((DWORD)size, sizeof(This->fInfo)));
198 if ((DWORD)size < sizeof(This->fInfo))
199 return AVIERR_BUFFERTOOSMALL;
200 return AVIERR_OK;
203 static HRESULT WINAPI ITmpFile_fnGetStream(IAVIFile *iface, PAVISTREAM *avis,
204 DWORD fccType, LONG lParam)
206 ICOM_THIS(ITmpFileImpl,iface);
208 ULONG nStream = (ULONG)-1;
210 TRACE("(%p,%p,0x%08lX,%ld)\n", iface, avis, fccType, lParam);
212 if (avis == NULL || lParam < 0)
213 return AVIERR_BADPARAM;
215 if (fccType != streamtypeANY) {
216 /* search the number of the specified stream */
217 ULONG i;
219 for (i = 0; i < This->fInfo.dwStreams; i++) {
220 AVISTREAMINFOW sInfo;
221 HRESULT hr;
223 hr = AVIStreamInfoW(This->ppStreams[i], &sInfo, sizeof(sInfo));
224 if (FAILED(hr))
225 return hr;
227 if (sInfo.fccType == fccType) {
228 if (lParam == 0) {
229 nStream = i;
230 break;
231 } else
232 lParam--;
235 } else
236 nStream = lParam;
238 /* Does the requested stream exist ? */
239 if (nStream < This->fInfo.dwStreams && This->ppStreams[nStream] != NULL) {
240 *avis = This->ppStreams[nStream];
241 AVIStreamAddRef(*avis);
243 return AVIERR_OK;
246 /* Sorry, but the specified stream doesn't exist */
247 return AVIERR_NODATA;
250 static HRESULT WINAPI ITmpFile_fnCreateStream(IAVIFile *iface,PAVISTREAM *avis,
251 AVISTREAMINFOW *asi)
253 TRACE("(%p,%p,%p)\n",iface,avis,asi);
255 return AVIERR_UNSUPPORTED;
258 static HRESULT WINAPI ITmpFile_fnWriteData(IAVIFile *iface, DWORD ckid,
259 LPVOID lpData, LONG size)
261 TRACE("(%p,0x%08lX,%p,%ld)\n", iface, ckid, lpData, size);
263 return AVIERR_UNSUPPORTED;
266 static HRESULT WINAPI ITmpFile_fnReadData(IAVIFile *iface, DWORD ckid,
267 LPVOID lpData, LONG *size)
269 TRACE("(%p,0x%08lX,%p,%p)\n", iface, ckid, lpData, size);
271 return AVIERR_UNSUPPORTED;
274 static HRESULT WINAPI ITmpFile_fnEndRecord(IAVIFile *iface)
276 TRACE("(%p)\n",iface);
278 return AVIERR_OK;
281 static HRESULT WINAPI ITmpFile_fnDeleteStream(IAVIFile *iface, DWORD fccType,
282 LONG lParam)
284 TRACE("(%p,0x%08lX,%ld)\n", iface, fccType, lParam);
286 return AVIERR_UNSUPPORTED;