mshtml: Added hack to allow pass post data to IPersistMoniker::Load.
[wine] / dlls / avifil32 / tmpfile.c
1 /*
2  * Copyright 2003 Michael Günnewig
3  *
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.
8  *
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.
13  *
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
17  */
18
19 #define COM_NO_WINDOWS_H
20 #include <assert.h>
21 #include <stdarg.h>
22
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"
32
33 #include "avifile_private.h"
34 #include "extrachunk.h"
35
36 #include "wine/debug.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(avifile);
39
40 /***********************************************************************/
41
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);
52
53 static const 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
64 };
65
66 typedef struct _ITmpFileImpl {
67   /* IUnknown stuff */
68   const IAVIFileVtbl *lpVtbl;
69   LONG         ref;
70
71   /* IAVIFile stuff */
72   AVIFILEINFOW  fInfo;
73   PAVISTREAM   *ppStreams;
74 } ITmpFileImpl;
75
76 PAVIFILE AVIFILE_CreateAVITempFile(int nStreams, PAVISTREAM *ppStreams) {
77   ITmpFileImpl *tmpFile;
78   int           i;
79
80   tmpFile = LocalAlloc(LPTR, sizeof(ITmpFileImpl));
81   if (tmpFile == NULL)
82     return NULL;
83
84   tmpFile->lpVtbl = &itmpft;
85   tmpFile->ref    = 1;
86   memset(&tmpFile->fInfo, 0, sizeof(tmpFile->fInfo));
87
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;
93   }
94
95   for (i = 0; i < nStreams; i++) {
96     AVISTREAMINFOW sInfo;
97
98     tmpFile->ppStreams[i] = ppStreams[i];
99
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;
108       }
109     }
110
111     if (tmpFile->fInfo.dwSuggestedBufferSize < sInfo.dwSuggestedBufferSize)
112       tmpFile->fInfo.dwSuggestedBufferSize = sInfo.dwSuggestedBufferSize;
113
114     {
115       register DWORD tmp;
116
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;
121
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;
128     }
129   }
130
131   return (PAVIFILE)tmpFile;
132 }
133
134 static HRESULT WINAPI ITmpFile_fnQueryInterface(IAVIFile *iface, REFIID refiid,
135                                                 LPVOID *obj)
136 {
137   ITmpFileImpl *This = (ITmpFileImpl *)iface;
138
139   TRACE("(%p,%s,%p)\n", This, debugstr_guid(refiid), obj);
140
141   if (IsEqualGUID(&IID_IUnknown, refiid) ||
142       IsEqualGUID(&IID_IAVIFile, refiid)) {
143     *obj = iface;
144     IAVIFile_AddRef(iface);
145
146     return S_OK;
147   }
148
149   return OLE_E_ENUM_NOMORE;
150 }
151
152 static ULONG   WINAPI ITmpFile_fnAddRef(IAVIFile *iface)
153 {
154   ITmpFileImpl *This = (ITmpFileImpl *)iface;
155   ULONG ref = InterlockedIncrement(&This->ref);
156
157   TRACE("(%p) -> %ld\n", iface, ref);
158
159   return ref;
160 }
161
162 static ULONG   WINAPI ITmpFile_fnRelease(IAVIFile *iface)
163 {
164   ITmpFileImpl *This = (ITmpFileImpl *)iface;
165   ULONG ref = InterlockedDecrement(&This->ref);
166
167   TRACE("(%p) -> %ld\n", iface, ref);
168
169   if (!ref) {
170     unsigned int i;
171
172     for (i = 0; i < This->fInfo.dwStreams; i++) {
173       if (This->ppStreams[i] != NULL) {
174         AVIStreamRelease(This->ppStreams[i]);
175
176         This->ppStreams[i] = NULL;
177       }
178     }
179
180     LocalFree((HLOCAL)This);
181     return 0;
182   }
183
184   return ref;
185 }
186
187 static HRESULT WINAPI ITmpFile_fnInfo(IAVIFile *iface,
188                                       AVIFILEINFOW *afi, LONG size)
189 {
190   ITmpFileImpl *This = (ITmpFileImpl *)iface;
191
192   TRACE("(%p,%p,%ld)\n",iface,afi,size);
193
194   if (afi == NULL)
195     return AVIERR_BADPARAM;
196   if (size < 0)
197     return AVIERR_BADSIZE;
198
199   memcpy(afi, &This->fInfo, min((DWORD)size, sizeof(This->fInfo)));
200
201   if ((DWORD)size < sizeof(This->fInfo))
202     return AVIERR_BUFFERTOOSMALL;
203   return AVIERR_OK;
204 }
205
206 static HRESULT WINAPI ITmpFile_fnGetStream(IAVIFile *iface, PAVISTREAM *avis,
207                                            DWORD fccType, LONG lParam)
208 {
209   ITmpFileImpl *This = (ITmpFileImpl *)iface;
210
211   ULONG nStream = (ULONG)-1;
212
213   TRACE("(%p,%p,0x%08lX,%ld)\n", iface, avis, fccType, lParam);
214
215   if (avis == NULL || lParam < 0)
216     return AVIERR_BADPARAM;
217
218   if (fccType != streamtypeANY) {
219     /* search the number of the specified stream */
220     ULONG i;
221
222     for (i = 0; i < This->fInfo.dwStreams; i++) {
223       AVISTREAMINFOW sInfo;
224       HRESULT        hr;
225
226       hr = AVIStreamInfoW(This->ppStreams[i], &sInfo, sizeof(sInfo));
227       if (FAILED(hr))
228         return hr;
229
230       if (sInfo.fccType == fccType) {
231         if (lParam == 0) {
232           nStream = i;
233           break;
234         } else
235           lParam--;
236       }
237     }
238   } else
239     nStream = lParam;
240
241   /* Does the requested stream exist ? */
242   if (nStream < This->fInfo.dwStreams && This->ppStreams[nStream] != NULL) {
243     *avis = This->ppStreams[nStream];
244     AVIStreamAddRef(*avis);
245
246     return AVIERR_OK;
247   }
248
249   /* Sorry, but the specified stream doesn't exist */
250   return AVIERR_NODATA;
251 }
252
253 static HRESULT WINAPI ITmpFile_fnCreateStream(IAVIFile *iface,PAVISTREAM *avis,
254                                               AVISTREAMINFOW *asi)
255 {
256   TRACE("(%p,%p,%p)\n",iface,avis,asi);
257
258   return AVIERR_UNSUPPORTED;
259 }
260
261 static HRESULT WINAPI ITmpFile_fnWriteData(IAVIFile *iface, DWORD ckid,
262                                            LPVOID lpData, LONG size)
263 {
264   TRACE("(%p,0x%08lX,%p,%ld)\n", iface, ckid, lpData, size);
265
266   return AVIERR_UNSUPPORTED;
267 }
268
269 static HRESULT WINAPI ITmpFile_fnReadData(IAVIFile *iface, DWORD ckid,
270                                           LPVOID lpData, LONG *size)
271 {
272   TRACE("(%p,0x%08lX,%p,%p)\n", iface, ckid, lpData, size);
273
274   return AVIERR_UNSUPPORTED;
275 }
276
277 static HRESULT WINAPI ITmpFile_fnEndRecord(IAVIFile *iface)
278 {
279   TRACE("(%p)\n",iface);
280
281   return AVIERR_OK;
282 }
283
284 static HRESULT WINAPI ITmpFile_fnDeleteStream(IAVIFile *iface, DWORD fccType,
285                                               LONG lParam)
286 {
287   TRACE("(%p,0x%08lX,%ld)\n", iface, fccType, lParam);
288
289   return AVIERR_UNSUPPORTED;
290 }