ole32/tests: Relax the reference counting tests a bit. We only care whether reference...
[wine/hramrach.git] / dlls / avifil32 / tmpfile.c
blob49b5a0a91bbac8830a0903a225e81f07cb6b7fb9
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <stdarg.h>
21 #include "windef.h"
22 #include "winbase.h"
23 #include "wingdi.h"
24 #include "winuser.h"
25 #include "winerror.h"
26 #include "vfw.h"
28 #include "avifile_private.h"
29 #include "extrachunk.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(avifile);
35 /***********************************************************************/
37 static HRESULT WINAPI ITmpFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj);
38 static ULONG WINAPI ITmpFile_fnAddRef(IAVIFile* iface);
39 static ULONG WINAPI ITmpFile_fnRelease(IAVIFile* iface);
40 static HRESULT WINAPI ITmpFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size);
41 static HRESULT WINAPI ITmpFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam);
42 static HRESULT WINAPI ITmpFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi);
43 static HRESULT WINAPI ITmpFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size);
44 static HRESULT WINAPI ITmpFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size);
45 static HRESULT WINAPI ITmpFile_fnEndRecord(IAVIFile*iface);
46 static HRESULT WINAPI ITmpFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam);
48 static const struct IAVIFileVtbl itmpft = {
49 ITmpFile_fnQueryInterface,
50 ITmpFile_fnAddRef,
51 ITmpFile_fnRelease,
52 ITmpFile_fnInfo,
53 ITmpFile_fnGetStream,
54 ITmpFile_fnCreateStream,
55 ITmpFile_fnWriteData,
56 ITmpFile_fnReadData,
57 ITmpFile_fnEndRecord,
58 ITmpFile_fnDeleteStream
61 typedef struct _ITmpFileImpl {
62 /* IUnknown stuff */
63 const IAVIFileVtbl *lpVtbl;
64 LONG ref;
66 /* IAVIFile stuff */
67 AVIFILEINFOW fInfo;
68 PAVISTREAM *ppStreams;
69 } ITmpFileImpl;
71 PAVIFILE AVIFILE_CreateAVITempFile(int nStreams, const PAVISTREAM *ppStreams) {
72 ITmpFileImpl *tmpFile;
73 int i;
75 tmpFile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ITmpFileImpl));
76 if (tmpFile == NULL)
77 return NULL;
79 tmpFile->lpVtbl = &itmpft;
80 tmpFile->ref = 1;
81 memset(&tmpFile->fInfo, 0, sizeof(tmpFile->fInfo));
83 tmpFile->fInfo.dwStreams = nStreams;
84 tmpFile->ppStreams = HeapAlloc(GetProcessHeap(), 0, nStreams * sizeof(PAVISTREAM));
85 if (tmpFile->ppStreams == NULL) {
86 HeapFree(GetProcessHeap(), 0, tmpFile);
87 return NULL;
90 for (i = 0; i < nStreams; i++) {
91 AVISTREAMINFOW sInfo;
93 tmpFile->ppStreams[i] = ppStreams[i];
95 AVIStreamAddRef(ppStreams[i]);
96 AVIStreamInfoW(ppStreams[i], &sInfo, sizeof(sInfo));
97 if (i == 0) {
98 tmpFile->fInfo.dwScale = sInfo.dwScale;
99 tmpFile->fInfo.dwRate = sInfo.dwRate;
100 if (!sInfo.dwScale || !sInfo.dwRate) {
101 tmpFile->fInfo.dwScale = 1;
102 tmpFile->fInfo.dwRate = 100;
106 if (tmpFile->fInfo.dwSuggestedBufferSize < sInfo.dwSuggestedBufferSize)
107 tmpFile->fInfo.dwSuggestedBufferSize = sInfo.dwSuggestedBufferSize;
110 register DWORD tmp;
112 tmp = MulDiv(AVIStreamSampleToTime(ppStreams[i], sInfo.dwLength),
113 tmpFile->fInfo.dwScale, tmpFile->fInfo.dwRate * 1000);
114 if (tmpFile->fInfo.dwLength < tmp)
115 tmpFile->fInfo.dwLength = tmp;
117 tmp = sInfo.rcFrame.right - sInfo.rcFrame.left;
118 if (tmpFile->fInfo.dwWidth < tmp)
119 tmpFile->fInfo.dwWidth = tmp;
120 tmp = sInfo.rcFrame.bottom - sInfo.rcFrame.top;
121 if (tmpFile->fInfo.dwHeight < tmp)
122 tmpFile->fInfo.dwHeight = tmp;
126 return (PAVIFILE)tmpFile;
129 static HRESULT WINAPI ITmpFile_fnQueryInterface(IAVIFile *iface, REFIID refiid,
130 LPVOID *obj)
132 ITmpFileImpl *This = (ITmpFileImpl *)iface;
134 TRACE("(%p,%s,%p)\n", This, debugstr_guid(refiid), obj);
136 if (IsEqualGUID(&IID_IUnknown, refiid) ||
137 IsEqualGUID(&IID_IAVIFile, refiid)) {
138 *obj = iface;
139 IAVIFile_AddRef(iface);
141 return S_OK;
144 return OLE_E_ENUM_NOMORE;
147 static ULONG WINAPI ITmpFile_fnAddRef(IAVIFile *iface)
149 ITmpFileImpl *This = (ITmpFileImpl *)iface;
150 ULONG ref = InterlockedIncrement(&This->ref);
152 TRACE("(%p) -> %d\n", iface, ref);
154 return ref;
157 static ULONG WINAPI ITmpFile_fnRelease(IAVIFile *iface)
159 ITmpFileImpl *This = (ITmpFileImpl *)iface;
160 ULONG ref = InterlockedDecrement(&This->ref);
162 TRACE("(%p) -> %d\n", iface, ref);
164 if (!ref) {
165 unsigned int i;
167 for (i = 0; i < This->fInfo.dwStreams; i++) {
168 if (This->ppStreams[i] != NULL) {
169 AVIStreamRelease(This->ppStreams[i]);
171 This->ppStreams[i] = NULL;
175 HeapFree(GetProcessHeap(), 0, This);
176 return 0;
179 return ref;
182 static HRESULT WINAPI ITmpFile_fnInfo(IAVIFile *iface,
183 AVIFILEINFOW *afi, LONG size)
185 ITmpFileImpl *This = (ITmpFileImpl *)iface;
187 TRACE("(%p,%p,%d)\n",iface,afi,size);
189 if (afi == NULL)
190 return AVIERR_BADPARAM;
191 if (size < 0)
192 return AVIERR_BADSIZE;
194 memcpy(afi, &This->fInfo, min((DWORD)size, sizeof(This->fInfo)));
196 if ((DWORD)size < sizeof(This->fInfo))
197 return AVIERR_BUFFERTOOSMALL;
198 return AVIERR_OK;
201 static HRESULT WINAPI ITmpFile_fnGetStream(IAVIFile *iface, PAVISTREAM *avis,
202 DWORD fccType, LONG lParam)
204 ITmpFileImpl *This = (ITmpFileImpl *)iface;
206 ULONG nStream = (ULONG)-1;
208 TRACE("(%p,%p,0x%08X,%d)\n", iface, avis, fccType, lParam);
210 if (avis == NULL || lParam < 0)
211 return AVIERR_BADPARAM;
213 if (fccType != streamtypeANY) {
214 /* search the number of the specified stream */
215 ULONG i;
217 for (i = 0; i < This->fInfo.dwStreams; i++) {
218 AVISTREAMINFOW sInfo;
219 HRESULT hr;
221 hr = AVIStreamInfoW(This->ppStreams[i], &sInfo, sizeof(sInfo));
222 if (FAILED(hr))
223 return hr;
225 if (sInfo.fccType == fccType) {
226 if (lParam == 0) {
227 nStream = i;
228 break;
229 } else
230 lParam--;
233 } else
234 nStream = lParam;
236 /* Does the requested stream exist ? */
237 if (nStream < This->fInfo.dwStreams && This->ppStreams[nStream] != NULL) {
238 *avis = This->ppStreams[nStream];
239 AVIStreamAddRef(*avis);
241 return AVIERR_OK;
244 /* Sorry, but the specified stream doesn't exist */
245 return AVIERR_NODATA;
248 static HRESULT WINAPI ITmpFile_fnCreateStream(IAVIFile *iface,PAVISTREAM *avis,
249 AVISTREAMINFOW *asi)
251 TRACE("(%p,%p,%p)\n",iface,avis,asi);
253 return AVIERR_UNSUPPORTED;
256 static HRESULT WINAPI ITmpFile_fnWriteData(IAVIFile *iface, DWORD ckid,
257 LPVOID lpData, LONG size)
259 TRACE("(%p,0x%08X,%p,%d)\n", iface, ckid, lpData, size);
261 return AVIERR_UNSUPPORTED;
264 static HRESULT WINAPI ITmpFile_fnReadData(IAVIFile *iface, DWORD ckid,
265 LPVOID lpData, LONG *size)
267 TRACE("(%p,0x%08X,%p,%p)\n", iface, ckid, lpData, size);
269 return AVIERR_UNSUPPORTED;
272 static HRESULT WINAPI ITmpFile_fnEndRecord(IAVIFile *iface)
274 TRACE("(%p)\n",iface);
276 return AVIERR_OK;
279 static HRESULT WINAPI ITmpFile_fnDeleteStream(IAVIFile *iface, DWORD fccType,
280 LONG lParam)
282 TRACE("(%p,0x%08X,%d)\n", iface, fccType, lParam);
284 return AVIERR_UNSUPPORTED;