Updated (prepare|unprepare)header functions to allow correct callback
[wine/testsucceed.git] / dlls / avifil32 / avifile.c
blob7b2e9cce332fe195cd26e965701e8222797e0b41
1 /*
2 * Copyright 1999 Marcus Meissner
3 */
4 #include <string.h>
5 #include <stdio.h>
6 #include <assert.h>
8 #include "vfw.h"
9 #include "winbase.h"
10 #include "wine/winestring.h"
11 #include "driver.h"
12 #include "mmsystem.h"
13 #include "winerror.h"
14 #include "debugstr.h"
15 #include "debug.h"
17 typedef struct IAVIStreamImpl {
18 /* IUnknown stuff */
19 ICOM_VTABLE(IAVIStream)* lpvtbl;
20 DWORD ref;
21 /* IAVIStream stuff */
22 LPVOID lpInputFormat;
23 DWORD inputformatsize;
24 BOOL iscompressing;
25 DWORD curframe;
27 /* Compressor stuff */
28 HIC hic;
29 LPVOID lpCompressFormat;
30 ICINFO icinfo;
31 DWORD compbufsize;
32 LPVOID compbuffer;
34 DWORD decompbufsize;
35 LPVOID decompbuffer;
36 LPVOID decompformat;
37 AVICOMPRESSOPTIONS aco;
39 LPVOID lpPrev; /* pointer to decompressed frame later */
40 LPVOID lpPrevFormat; /* pointer to decompressed info later */
41 } IAVIStreamImpl;
43 void WINAPI
44 AVIFileInit(void) {
45 FIXME(avifile,"(),stub!\n");
48 typedef struct IAVIFileImpl {
49 /* IUnknown stuff */
50 ICOM_VTABLE(IAVIFile)* lpvtbl;
51 DWORD ref;
52 /* IAVIFile stuff... */
53 } IAVIFileImpl;
55 struct ICOM_VTABLE(IAVIStream) iavist;
57 static HRESULT WINAPI IAVIFile_fnQueryInterface(IAVIFile* iface,REFIID refiid,LPVOID *obj) {
58 ICOM_THIS(IAVIFileImpl,iface);
59 char xrefiid[50];
61 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
62 TRACE(relay,"(%p)->QueryInterface(%s,%p)\n",This,xrefiid,obj);
63 if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
64 !memcmp(&IID_IAVIFile,refiid,sizeof(IID_IAVIFile))
65 ) {
66 *obj = iface;
67 return S_OK;
69 return OLE_E_ENUM_NOMORE;
72 static ULONG WINAPI IAVIFile_fnAddRef(IAVIFile* iface) {
73 ICOM_THIS(IAVIFileImpl,iface);
75 FIXME(relay,"(%p)->AddRef()\n",iface);
76 return ++(This->ref);
79 static ULONG WINAPI IAVIFile_fnRelease(IAVIFile* iface) {
80 ICOM_THIS(IAVIFileImpl,iface);
82 FIXME(relay,"(%p)->Release()\n",iface);
83 if (!--(This->ref)) {
84 HeapFree(GetProcessHeap(),0,iface);
85 return 0;
87 return This->ref;
90 static HRESULT WINAPI IAVIFile_fnInfo(IAVIFile*iface,AVIFILEINFOW*afi,LONG size) {
91 FIXME(avifile,"(%p)->Info(%p,%ld)\n",iface,afi,size);
93 /* FIXME: fill out struct? */
94 return E_FAIL;
97 static HRESULT WINAPI IAVIFile_fnGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam) {
98 FIXME(avifile,"(%p)->GetStream(%p,0x%08lx,%ld)\n",iface,avis,fccType,lParam);
99 /* FIXME: create interface etc. */
100 return E_FAIL;
103 static HRESULT WINAPI IAVIFile_fnCreateStream(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi) {
104 ICOM_THIS(IAVIStreamImpl,iface);
105 char fcc[5];
106 IAVIStreamImpl *istream;
108 FIXME(avifile,"(%p,%p,%p)\n",This,avis,asi);
109 istream = (IAVIStreamImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IAVIStreamImpl));
110 istream->ref = 1;
111 istream->lpvtbl = &iavist;
112 fcc[4]='\0';
113 memcpy(fcc,(char*)&(asi->fccType),4);
114 FIXME(avifile,"\tfccType '%s'\n",fcc);
115 memcpy(fcc,(char*)&(asi->fccHandler),4);
116 FIXME(avifile,"\tfccHandler '%s'\n",fcc);
117 FIXME(avifile,"\tdwFlags 0x%08lx\n",asi->dwFlags);
118 FIXME(avifile,"\tdwCaps 0x%08lx\n",asi->dwCaps);
119 FIXME(avifile,"\tname '%s'\n",debugstr_w(asi->szName));
121 istream->curframe = 0;
122 *avis = (PAVISTREAM)istream;
123 return S_OK;
126 static HRESULT WINAPI IAVIFile_fnWriteData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG size) {
127 FIXME(avifile,"(%p)->WriteData(0x%08lx,%p,%ld)\n",iface,ckid,lpData,size);
128 /* FIXME: write data to file */
129 return E_FAIL;
132 static HRESULT WINAPI IAVIFile_fnReadData(IAVIFile*iface,DWORD ckid,LPVOID lpData,LONG *size) {
133 FIXME(avifile,"(%p)->ReadData(0x%08lx,%p,%p)\n",iface,ckid,lpData,size);
134 /* FIXME: read at most size bytes from file */
135 return E_FAIL;
138 static HRESULT WINAPI IAVIFile_fnEndRecord(IAVIFile*iface) {
139 FIXME(avifile,"(%p)->EndRecord()\n",iface);
140 /* FIXME: end record? */
141 return E_FAIL;
144 static HRESULT WINAPI IAVIFile_fnDeleteStream(IAVIFile*iface,DWORD fccType,LONG lParam) {
145 FIXME(avifile,"(%p)->DeleteStream(0x%08lx,%ld)\n",iface,fccType,lParam);
146 /* FIXME: delete stream? */
147 return E_FAIL;
150 struct ICOM_VTABLE(IAVIFile) iavift = {
151 IAVIFile_fnQueryInterface,
152 IAVIFile_fnAddRef,
153 IAVIFile_fnRelease,
154 IAVIFile_fnInfo,
155 IAVIFile_fnGetStream,
156 IAVIFile_fnCreateStream,
157 IAVIFile_fnWriteData,
158 IAVIFile_fnReadData,
159 IAVIFile_fnEndRecord,
160 IAVIFile_fnDeleteStream
163 HRESULT WINAPI AVIFileOpenA(
164 PAVIFILE * ppfile,LPCSTR szFile,UINT uMode,LPCLSID lpHandler
166 char buf[80];
167 IAVIFileImpl *iavi;
170 if (HIWORD(lpHandler))
171 WINE_StringFromCLSID(lpHandler,buf);
172 else
173 sprintf(buf,"<clsid-0x%04lx>",(DWORD)lpHandler);
175 FIXME(avifile,"(%p,%s,0x%08lx,%s),stub!\n",ppfile,szFile,(DWORD)uMode,buf);
176 iavi = (IAVIFileImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IAVIFileImpl));
177 iavi->ref = 1;
178 iavi->lpvtbl = &iavift;
179 *ppfile = (LPVOID)iavi;
180 return S_OK;
183 static HRESULT WINAPI IAVIStream_fnQueryInterface(IAVIStream*iface,REFIID refiid,LPVOID *obj) {
184 ICOM_THIS(IAVIStreamImpl,iface);
185 char xrefiid[50];
187 WINE_StringFromCLSID((LPCLSID)refiid,xrefiid);
188 TRACE(relay,"(%p)->QueryInterface(%s,%p)\n",This,xrefiid,obj);
189 if ( !memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown)) ||
190 !memcmp(&IID_IAVIStream,refiid,sizeof(IID_IAVIStream))
192 *obj = This;
193 return S_OK;
195 /* can return IGetFrame interface too */
196 return OLE_E_ENUM_NOMORE;
199 static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream*iface) {
200 ICOM_THIS(IAVIStreamImpl,iface);
202 FIXME(relay,"(%p)->AddRef()\n",iface);
203 return ++(This->ref);
206 static ULONG WINAPI IAVIStream_fnRelease(IAVIStream* iface) {
207 ICOM_THIS(IAVIStreamImpl,iface);
209 FIXME(relay,"(%p)->Release()\n",iface);
210 if (!--(This->ref)) {
211 HeapFree(GetProcessHeap(),0,This);
212 return 0;
214 return This->ref;
217 HRESULT WINAPI IAVIStream_fnCreate(IAVIStream*iface,LPARAM lParam1,LPARAM lParam2) {
218 FIXME(avifile,"(%p)->Create(0x%08lx,0x%08lx)\n",iface,lParam1,lParam2);
219 return E_FAIL;
222 HRESULT WINAPI IAVIStream_fnInfo(IAVIStream*iface,AVISTREAMINFOW *psi,LONG size) {
223 FIXME(avifile,"(%p)->Info(%p,%ld)\n",iface,psi,size);
224 return E_FAIL;
227 LONG WINAPI IAVIStream_fnFindSample(IAVIStream*iface,LONG pos,LONG flags) {
228 FIXME(avifile,"(%p)->FindSample(%ld,0x%08lx)\n",iface,pos,flags);
229 return E_FAIL;
232 HRESULT WINAPI IAVIStream_fnReadFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG *formatsize) {
233 FIXME(avifile,"(%p)->ReadFormat(%ld,%p,%p)\n",iface,pos,format,formatsize);
234 return E_FAIL;
237 /*****************************************************************************
238 * [IAVIStream::SetFormat]
240 HRESULT WINAPI IAVIStream_fnSetFormat(IAVIStream*iface,LONG pos,LPVOID format,LONG formatsize) {
241 IAVIStreamImpl *as = (IAVIStreamImpl*)iface;
243 FIXME(avifile,"(%p)->SetFormat(%ld,%p,%ld)\n",iface,pos,format,formatsize);
244 if (as->lpInputFormat) HeapFree(GetProcessHeap(),0,as->lpInputFormat);
245 as->inputformatsize = formatsize;
246 as->lpInputFormat = HeapAlloc(GetProcessHeap(),0,formatsize);
247 memcpy(as->lpInputFormat,format,formatsize);
248 if (as->iscompressing) {
249 int xsize;
250 /* Set up the Compressor part */
251 xsize = ICCompressGetFormatSize(as->hic,as->lpInputFormat);
252 as->lpCompressFormat = HeapAlloc(GetProcessHeap(),0,xsize);
253 ICCompressGetFormat(as->hic,as->lpInputFormat,as->lpCompressFormat);
254 ICCompressBegin(as->hic,as->lpInputFormat,as->lpCompressFormat);
255 as->compbufsize = ICCompressGetSize(as->hic,as->lpInputFormat,as->lpCompressFormat);
256 as->compbuffer = HeapAlloc(GetProcessHeap(),0,as->compbufsize);
258 /* Set up the Decompressor part (for prev frames?) */
259 xsize=ICDecompressGetFormatSize(as->hic,as->lpCompressFormat);
260 as->decompformat = HeapAlloc(GetProcessHeap(),0,xsize);
261 ICDecompressGetFormat(as->hic,as->lpCompressFormat,as->decompformat);
262 as->decompbufsize=((LPBITMAPINFOHEADER)as->decompbuffer)->biSizeImage;
263 as->decompbuffer = HeapReAlloc(GetProcessHeap(),0,as->decompbuffer,as->decompbufsize);
264 memset(as->decompbuffer,0xff,as->decompbufsize);
265 assert(HeapValidate(GetProcessHeap(),0,NULL));
267 ICDecompressGetFormat(as->hic,as->lpCompressFormat,as->decompformat);
268 ICDecompressBegin(as->hic,as->lpCompressFormat,as->decompformat);
269 as->lpPrev = as->lpPrevFormat = NULL;
271 return S_OK;
274 HRESULT WINAPI IAVIStream_fnRead(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) {
275 FIXME(avifile,"(%p)->Read(%ld,%ld,%p,%ld,%p,%p)\n",iface,start,samples,buffer,buffersize,bytesread,samplesread);
276 return E_FAIL;
279 HRESULT WINAPI IAVIStream_fnWrite(IAVIStream*iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) {
280 IAVIStreamImpl *as = (IAVIStreamImpl*)iface;
281 DWORD ckid,xflags;
283 FIXME(avifile,"(%p)->Write(%ld,%ld,%p,%ld,0x%08lx,%p,%p)\n",iface,start,samples,buffer,buffersize,flags,sampwritten,byteswritten);
285 ICCompress(
286 as->hic,flags,
287 as->lpCompressFormat,
288 as->compbuffer,
289 as->lpInputFormat,buffer,
290 &ckid,&xflags,
291 as->curframe,0xffffff/*framesize*/,as->aco.dwQuality,
292 as->lpPrevFormat,as->lpPrev
294 ICDecompress(
295 as->hic,
296 flags, /* FIXME: check */
297 as->lpCompressFormat,
298 as->compbuffer,
299 as->decompformat,
300 as->decompbuffer
302 /* We now have a prev format for the next compress ... */
303 as->lpPrevFormat = as->decompformat;
304 as->lpPrev = as->decompbuffer;
305 return S_OK;
308 HRESULT WINAPI IAVIStream_fnDelete(IAVIStream*iface,LONG start,LONG samples) {
309 FIXME(avifile,"(%p)->Delete(%ld,%ld)\n",iface,start,samples);
310 return E_FAIL;
313 HRESULT WINAPI IAVIStream_fnReadData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG *lpread) {
314 FIXME(avifile,"(%p)->ReadData(0x%08lx,%p,%p)\n",iface,fcc,lp,lpread);
315 return E_FAIL;
318 HRESULT WINAPI IAVIStream_fnWriteData(IAVIStream*iface,DWORD fcc,LPVOID lp,LONG size) {
319 FIXME(avifile,"(%p)->WriteData(0x%08lx,%p,%ld)\n",iface,fcc,lp,size);
320 return E_FAIL;
323 HRESULT WINAPI IAVIStream_fnSetInfo(IAVIStream*iface,AVISTREAMINFOW*info,LONG infolen) {
324 FIXME(avifile,"(%p)->SetInfo(%p,%ld)\n",iface,info,infolen);
325 return E_FAIL;
328 struct ICOM_VTABLE(IAVIStream) iavist = {
329 IAVIStream_fnQueryInterface,
330 IAVIStream_fnAddRef,
331 IAVIStream_fnRelease,
332 IAVIStream_fnCreate,
333 IAVIStream_fnInfo,
334 IAVIStream_fnFindSample,
335 IAVIStream_fnReadFormat,
336 IAVIStream_fnSetFormat,
337 IAVIStream_fnRead,
338 IAVIStream_fnWrite,
339 IAVIStream_fnDelete,
340 IAVIStream_fnReadData,
341 IAVIStream_fnWriteData,
342 IAVIStream_fnSetInfo
345 HRESULT WINAPI AVIFileCreateStreamA(PAVIFILE iface,PAVISTREAM *ppavi,AVISTREAMINFOA * psi) {
346 AVISTREAMINFOW psiw;
348 /* Only the szName at the end is different */
349 memcpy(&psiw,psi,sizeof(*psi)-sizeof(psi->szName));
350 lstrcpynAtoW(psiw.szName,psi->szName,sizeof(psi->szName));
351 return iface->lpvtbl->fnCreateStream(iface,ppavi,&psiw);
354 HRESULT WINAPI AVIFileCreateStreamW(IAVIFile*iface,PAVISTREAM*avis,AVISTREAMINFOW*asi) {
355 return iface->lpvtbl->fnCreateStream(iface,avis,asi);
359 HRESULT WINAPI AVIFileGetStream(IAVIFile*iface,PAVISTREAM*avis,DWORD fccType,LONG lParam) {
360 return iface->lpvtbl->fnGetStream(iface,avis,fccType,lParam);
363 HRESULT WINAPI AVIFileInfoA(PAVIFILE iface,LPAVIFILEINFOA afi,LONG size) {
364 AVIFILEINFOW afiw;
365 HRESULT hres;
367 if (size < sizeof(AVIFILEINFOA))
368 return AVIERR_BADSIZE;
369 hres = iface->lpvtbl->fnInfo(iface,&afiw,sizeof(afiw));
370 memcpy(afi,&afiw,sizeof(*afi)-sizeof(afi->szFileType));
371 lstrcpynWtoA(afi->szFileType,afiw.szFileType,sizeof(afi->szFileType));
372 return hres;
375 HRESULT WINAPI AVIStreamInfoW(PAVISTREAM iface,AVISTREAMINFOW *asi,LONG
376 size) {
377 return iface->lpvtbl->fnInfo(iface,asi,size);
380 HRESULT WINAPI AVIStreamInfoA(PAVISTREAM iface,AVISTREAMINFOA *asi,LONG
381 size) {
382 AVISTREAMINFOW asiw;
383 HRESULT hres;
385 if (size<sizeof(AVISTREAMINFOA))
386 return AVIERR_BADSIZE;
387 hres = iface->lpvtbl->fnInfo(iface,&asiw,sizeof(asiw));
388 memcpy(asi,&asiw,sizeof(asiw)-sizeof(asiw.szName));
389 lstrcpynWtoA(asi->szName,asiw.szName,sizeof(asi->szName));
390 return hres;
393 HRESULT WINAPI AVIFileInfoW(PAVIFILE iface,LPAVIFILEINFOW afi,LONG size) {
394 return iface->lpvtbl->fnInfo(iface,afi,size);
397 HRESULT WINAPI AVIMakeCompressedStream(PAVISTREAM *ppsCompressed,PAVISTREAM ppsSource,AVICOMPRESSOPTIONS *aco,CLSID *pclsidHandler) {
398 char fcc[5];
399 IAVIStreamImpl *as;
400 FIXME(avifile,"(%p,%p,%p,%p)\n",ppsCompressed,ppsSource,aco,pclsidHandler);
401 fcc[4]='\0';
402 memcpy(fcc,&(aco->fccType),4);
403 FIXME(avifile,"\tfccType: '%s'\n",fcc);
404 memcpy(fcc,&(aco->fccHandler),4);
405 FIXME(avifile,"\tfccHandler: '%s'\n",fcc);
406 FIXME(avifile,"\tdwFlags: 0x%08lx\n",aco->dwFlags);
408 /* we just create a duplicate for now */
409 ((IUnknown*)ppsSource)->lpvtbl->fnAddRef((IUnknown*)ppsSource);
410 *ppsCompressed = ppsSource;
411 as = (IAVIStreamImpl*)ppsSource;
413 /* this is where the fun begins. Open a compressor and prepare it. */
414 as->hic = ICOpen(aco->fccType,aco->fccHandler,ICMODE_COMPRESS);
416 /* May happen. for instance if the codec is not able to compress */
417 if (!as->hic)
418 return AVIERR_UNSUPPORTED;
420 ICGetInfo(as->hic,&(as->icinfo),sizeof(ICINFO));
421 FIXME(avifile,"Opened compressor: '%s' '%s'\n",debugstr_w(as->icinfo.szName),debugstr_w(as->icinfo.szDescription));
422 as->iscompressing = TRUE;
423 memcpy(&(as->aco),aco,sizeof(*aco));
424 if (as->icinfo.dwFlags & VIDCF_COMPRESSFRAMES) {
425 ICCOMPRESSFRAMES icf;
427 /* now what to fill in there ... Hmm */
428 memset(&icf,0,sizeof(icf));
429 icf.lDataRate = aco->dwBytesPerSecond;
430 icf.lQuality = aco->dwQuality;
431 icf.lKeyRate = aco->dwKeyFrameEvery;
433 icf.GetData = (void*)0xdead4242;
434 icf.PutData = (void*)0xdead4243;
435 ICSendMessage(as->hic,ICM_COMPRESS_FRAMES_INFO,(LPARAM)&icf,sizeof(icf));
437 return S_OK;
440 HRESULT WINAPI AVIStreamSetFormat(PAVISTREAM iface,LONG pos,LPVOID format,LONG formatsize) {
441 return iface->lpvtbl->fnSetFormat(iface,pos,format,formatsize);
444 HRESULT WINAPI AVIStreamReadFormat(PAVISTREAM iface,LONG pos,LPVOID format,LONG *formatsize) {
445 return iface->lpvtbl->fnReadFormat(iface,pos,format,formatsize);
448 HRESULT WINAPI AVIStreamWrite(PAVISTREAM iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,DWORD flags,LONG *sampwritten,LONG *byteswritten) {
449 return iface->lpvtbl->fnWrite(iface,start,samples,buffer,buffersize,flags,sampwritten,byteswritten);
452 HRESULT WINAPI AVIStreamRead(PAVISTREAM iface,LONG start,LONG samples,LPVOID buffer,LONG buffersize,LONG *bytesread,LONG *samplesread) {
453 return iface->lpvtbl->fnRead(iface,start,samples,buffer,buffersize,bytesread,samplesread);
456 HRESULT WINAPI AVIStreamWriteData(PAVISTREAM iface,DWORD fcc,LPVOID lp,LONG size) {
457 return iface->lpvtbl->fnWriteData(iface,fcc,lp,size);
460 HRESULT WINAPI AVIStreamReadData(PAVISTREAM iface,DWORD fcc,LPVOID lp,LONG *lpread) {
461 return iface->lpvtbl->fnReadData(iface,fcc,lp,lpread);
464 LONG WINAPI AVIStreamStart(PAVISTREAM iface) {
465 AVISTREAMINFOW si;
467 iface->lpvtbl->fnInfo(iface,&si,sizeof(si));
468 return si.dwStart;
471 LONG WINAPI AVIStreamLength(PAVISTREAM iface) {
472 AVISTREAMINFOW si;
473 HRESULT ret;
475 ret = iface->lpvtbl->fnInfo(iface,&si,sizeof(si));
476 if (ret) /* error */
477 return 1;
478 return si.dwLength;
481 ULONG WINAPI AVIStreamRelease(PAVISTREAM iface) {
482 return ((LPUNKNOWN)iface)->lpvtbl->fnRelease((LPUNKNOWN)iface);
485 PGETFRAME WINAPI AVIStreamGetFrameOpen(PAVISTREAM iface,LPBITMAPINFOHEADER bmi) {
486 FIXME(msvideo,"(%p)->(%p),stub!\n",iface,bmi);
487 return NULL;
490 LPVOID WINAPI AVIStreamGetFrame(PGETFRAME pg,LONG pos) {
491 return pg->lpvtbl->fnGetFrame(pg,pos);
494 HRESULT WINAPI AVIStreamGetFrameClose(PGETFRAME pg) {
495 if (pg) ((LPUNKNOWN)pg)->lpvtbl->fnRelease((LPUNKNOWN)pg);
496 return 0;
499 ULONG WINAPI AVIFileRelease(PAVIFILE iface) {
500 return ((LPUNKNOWN)iface)->lpvtbl->fnRelease((LPUNKNOWN)iface);
503 void WINAPI AVIFileExit(void) {
504 FIXME(avifile,"(), stub.\n");