2 * Copyright 1999 Marcus Meissner
3 * Copyright 2002-2003 Michael Günnewig
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #define COM_NO_WINDOWS_H
39 #include "avifile_private.h"
41 #include "wine/debug.h"
42 #include "wine/unicode.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(avifile);
47 /***********************************************************************
48 * for AVIBuildFilterW -- uses fixed size table
50 #define MAX_FILTERS 30 /* 30 => 7kB */
52 typedef struct _AVIFilter {
54 WCHAR szExtensions[MAX_FILTERS * 7];
57 /***********************************************************************
64 LPAVICOMPRESSOPTIONS *ppOptions;
68 /***********************************************************************
69 * copied from dlls/ole32/compobj.c
71 static HRESULT AVIFILE_CLSIDFromString(LPCSTR idstr, LPCLSID id)
73 BYTE const *s = (BYTE const*)idstr;
79 memset(id, 0, sizeof(CLSID));
81 } else { /* validate the CLSID string */
82 if (lstrlenA(s) != 38)
83 return CO_E_CLASSSTRING;
85 if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') ||
86 (s[24]!='-') || (s[37]!='}'))
87 return CO_E_CLASSSTRING;
89 for (i = 1; i < 37; i++) {
90 if ((i == 9) || (i == 14) || (i == 19) || (i == 24))
92 if (!(((s[i] >= '0') && (s[i] <= '9')) ||
93 ((s[i] >= 'a') && (s[i] <= 'f')) ||
94 ((s[i] >= 'A') && (s[i] <= 'F')))
96 return CO_E_CLASSSTRING;
100 TRACE("%s -> %p\n", s, id);
102 /* quick lookup table */
103 memset(table, 0, 256);
105 for (i = 0; i < 10; i++)
108 for (i = 0; i < 6; i++) {
109 table['A' + i] = i+10;
110 table['a' + i] = i+10;
113 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
116 s++; /* skip leading brace */
117 for (i = 0; i < 4; i++) {
118 p[3 - i] = table[*s]<<4 | table[*(s+1)];
124 for (i = 0; i < 2; i++) {
125 p[1-i] = table[*s]<<4 | table[*(s+1)];
131 for (i = 0; i < 2; i++) {
132 p[1-i] = table[*s]<<4 | table[*(s+1)];
138 /* these are just sequential bytes */
139 for (i = 0; i < 2; i++) {
140 *p++ = table[*s]<<4 | table[*(s+1)];
145 for (i = 0; i < 6; i++) {
146 *p++ = table[*s]<<4 | table[*(s+1)];
153 static BOOL AVIFILE_GetFileHandlerByExtension(LPCWSTR szFile, LPCLSID lpclsid)
157 LPWSTR szExt = strrchrW(szFile, '.');
158 LONG len = sizeof(szValue) / sizeof(szValue[0]);
165 wsprintfA(szRegKey, "AVIFile\\Extensions\\%.3ls", szExt);
166 if (RegQueryValueA(HKEY_CLASSES_ROOT, szRegKey, szValue, &len) != ERROR_SUCCESS)
169 return (AVIFILE_CLSIDFromString(szValue, lpclsid) == S_OK);
172 /***********************************************************************
173 * AVIFileInit (AVIFIL32.@)
174 * AVIFileInit (AVIFILE.100)
176 void WINAPI AVIFileInit(void) {
177 /* need to load ole32.dll if not already done and get some functions */
178 FIXME("(): stub!\n");
181 /***********************************************************************
182 * AVIFileExit (AVIFIL32.@)
183 * AVIFileExit (AVIFILE.101)
185 void WINAPI AVIFileExit(void) {
186 /* need to free ole32.dll if we are the last exit call */
187 FIXME("(): stub!\n");
190 /***********************************************************************
191 * AVIFileOpenA (AVIFIL32.@)
192 * AVIFileOpen (AVIFILE.102)
194 HRESULT WINAPI AVIFileOpenA(PAVIFILE *ppfile, LPCSTR szFile, UINT uMode,
197 LPWSTR wszFile = NULL;
201 TRACE("(%p,%s,0x%08X,%s)\n", ppfile, debugstr_a(szFile), uMode,
202 debugstr_guid(lpHandler));
204 /* check parameters */
205 if (ppfile == NULL || szFile == NULL)
206 return AVIERR_BADPARAM;
208 /* convert ASCII string to Unicode and call unicode function */
209 len = MultiByteToWideChar(CP_ACP, 0, szFile, -1, NULL, 0);
211 return AVIERR_BADPARAM;
213 wszFile = (LPWSTR)LocalAlloc(LPTR, len * sizeof(WCHAR));
215 return AVIERR_MEMORY;
217 MultiByteToWideChar(CP_ACP, 0, szFile, -1, wszFile, len);
219 hr = AVIFileOpenW(ppfile, wszFile, uMode, lpHandler);
221 LocalFree((HLOCAL)wszFile);
226 /***********************************************************************
227 * AVIFileOpenW (AVIFIL32.@)
229 HRESULT WINAPI AVIFileOpenW(PAVIFILE *ppfile, LPCWSTR szFile, UINT uMode,
232 IPersistFile *ppersist = NULL;
236 TRACE("(%p,%s,0x%X,%s)\n", ppfile, debugstr_w(szFile), uMode,
237 debugstr_guid(lpHandler));
239 /* check parameters */
240 if (ppfile == NULL || szFile == NULL)
241 return AVIERR_BADPARAM;
245 /* if no handler then try guessing it by extension */
246 if (lpHandler == NULL) {
247 if (! AVIFILE_GetFileHandlerByExtension(szFile, &clsidHandler))
248 return AVIERR_UNSUPPORTED;
250 memcpy(&clsidHandler, lpHandler, sizeof(clsidHandler));
252 /* crete instance of handler */
253 hr = SHCoCreateInstance(NULL, &clsidHandler, NULL,
254 &IID_IAVIFile, (LPVOID*)ppfile);
255 if (FAILED(hr) || *ppfile == NULL)
258 /* ask for IPersistFile interface for loading/creating the file */
259 hr = IAVIFile_QueryInterface(*ppfile, &IID_IPersistFile, (LPVOID*)&ppersist);
260 if (FAILED(hr) || ppersist == NULL) {
261 IAVIFile_Release(*ppfile);
266 hr = IPersistFile_Load(ppersist, szFile, uMode);
267 IPersistFile_Release(ppersist);
269 IAVIFile_Release(*ppfile);
276 /***********************************************************************
277 * AVIFileAddRef (AVIFIL32.@)
278 * AVIFileAddRef (AVIFILE.140)
280 ULONG WINAPI AVIFileAddRef(PAVIFILE pfile)
282 TRACE("(%p)\n", pfile);
285 ERR(": bad handle passed!\n");
289 return IAVIFile_AddRef(pfile);
292 /***********************************************************************
293 * AVIFileRelease (AVIFIL32.@)
294 * AVIFileRelease (AVIFILE.141)
296 ULONG WINAPI AVIFileRelease(PAVIFILE pfile)
298 TRACE("(%p)\n", pfile);
301 ERR(": bad handle passed!\n");
305 return IAVIFile_Release(pfile);
308 /***********************************************************************
309 * AVIFileInfo (AVIFIL32.@)
310 * AVIFileInfoA (AVIFIL32.@)
311 * AVIFileInfo (AVIFILE.142)
313 HRESULT WINAPI AVIFileInfoA(PAVIFILE pfile, LPAVIFILEINFOA afi, LONG size)
318 TRACE("(%p,%p,%ld)\n", pfile, afi, size);
321 return AVIERR_BADHANDLE;
322 if ((DWORD)size < sizeof(AVIFILEINFOA))
323 return AVIERR_BADSIZE;
325 hres = IAVIFile_Info(pfile, &afiw, sizeof(afiw));
327 memcpy(afi, &afiw, sizeof(*afi) - sizeof(afi->szFileType));
328 WideCharToMultiByte(CP_ACP, 0, afiw.szFileType, -1, afi->szFileType,
329 sizeof(afi->szFileType), NULL, NULL);
330 afi->szFileType[sizeof(afi->szFileType) - 1] = 0;
335 /***********************************************************************
336 * AVIFileInfoW (AVIFIL32.@)
338 HRESULT WINAPI AVIFileInfoW(PAVIFILE pfile, LPAVIFILEINFOW afiw, LONG size)
340 TRACE("(%p,%p,%ld)\n", pfile, afiw, size);
343 return AVIERR_BADHANDLE;
345 return IAVIFile_Info(pfile, afiw, size);
348 /***********************************************************************
349 * AVIFileGetStream (AVIFIL32.@)
350 * AVIFileGetStream (AVIFILE.143)
352 HRESULT WINAPI AVIFileGetStream(PAVIFILE pfile, PAVISTREAM *avis,
353 DWORD fccType, LONG lParam)
355 TRACE("(%p,%p,'%4.4s',%ld)\n", pfile, avis, (char*)&fccType, lParam);
358 return AVIERR_BADHANDLE;
360 return IAVIFile_GetStream(pfile, avis, fccType, lParam);
363 /***********************************************************************
364 * AVIFileCreateStreamA (AVIFIL32.@)
365 * AVIFileCreateStream (AVIFILE.144)
367 HRESULT WINAPI AVIFileCreateStreamA(PAVIFILE pfile, PAVISTREAM *ppavi,
368 LPAVISTREAMINFOA psi)
372 TRACE("(%p,%p,%p)\n", pfile, ppavi, psi);
375 return AVIERR_BADHANDLE;
377 /* Only the szName at the end is different */
378 memcpy(&psiw, psi, sizeof(*psi) - sizeof(psi->szName));
379 MultiByteToWideChar(CP_ACP, 0, psi->szName, -1, psiw.szName,
380 sizeof(psiw.szName) / sizeof(psiw.szName[0]));
382 return IAVIFile_CreateStream(pfile, ppavi, &psiw);
385 /***********************************************************************
386 * AVIFileCreateStreamW (AVIFIL32.@)
388 HRESULT WINAPI AVIFileCreateStreamW(PAVIFILE pfile, PAVISTREAM *avis,
389 LPAVISTREAMINFOW asi)
391 TRACE("(%p,%p,%p)\n", pfile, avis, asi);
394 return AVIERR_BADHANDLE;
396 return IAVIFile_CreateStream(pfile, avis, asi);
399 /***********************************************************************
400 * AVIFileWriteData (AVIFIL32.@)
401 * AVIFileWriteData (AVIFILE.146)
403 HRESULT WINAPI AVIFileWriteData(PAVIFILE pfile,DWORD fcc,LPVOID lp,LONG size)
405 TRACE("(%p,'%4.4s',%p,%ld)\n", pfile, (char*)&fcc, lp, size);
408 return AVIERR_BADHANDLE;
410 return IAVIFile_WriteData(pfile, fcc, lp, size);
413 /***********************************************************************
414 * AVIFileReadData (AVIFIL32.@)
415 * AVIFileReadData (AVIFILE.147)
417 HRESULT WINAPI AVIFileReadData(PAVIFILE pfile,DWORD fcc,LPVOID lp,LPLONG size)
419 TRACE("(%p,'%4.4s',%p,%p)\n", pfile, (char*)&fcc, lp, size);
422 return AVIERR_BADHANDLE;
424 return IAVIFile_ReadData(pfile, fcc, lp, size);
427 /***********************************************************************
428 * AVIFileEndRecord (AVIFIL32.@)
429 * AVIFileEndRecord (AVIFILE.148)
431 HRESULT WINAPI AVIFileEndRecord(PAVIFILE pfile)
433 TRACE("(%p)\n", pfile);
436 return AVIERR_BADHANDLE;
438 return IAVIFile_EndRecord(pfile);
441 /***********************************************************************
442 * AVIStreamAddRef (AVIFIL32.@)
443 * AVIStreamAddRef (AVIFILE.160)
445 ULONG WINAPI AVIStreamAddRef(PAVISTREAM pstream)
447 TRACE("(%p)\n", pstream);
449 if (pstream == NULL) {
450 ERR(": bad handle passed!\n");
454 return IAVIStream_AddRef(pstream);
457 /***********************************************************************
458 * AVIStreamRelease (AVIFIL32.@)
459 * AVIStreamRelease (AVIFILE.161)
461 ULONG WINAPI AVIStreamRelease(PAVISTREAM pstream)
463 TRACE("(%p)\n", pstream);
465 if (pstream == NULL) {
466 ERR(": bad handle passed!\n");
470 return IAVIStream_Release(pstream);
473 /***********************************************************************
474 * AVIStreamCreate (AVIFIL32.@)
475 * AVIStreamCreate (AVIFILE.104)
477 HRESULT WINAPI AVIStreamCreate(PAVISTREAM *ppavi, LONG lParam1, LONG lParam2,
478 LPCLSID pclsidHandler)
482 TRACE("(%p,0x%08lX,0x%08lX,%s)\n", ppavi, lParam1, lParam2,
483 debugstr_guid(pclsidHandler));
486 return AVIERR_BADPARAM;
489 if (pclsidHandler == NULL)
490 return AVIERR_UNSUPPORTED;
492 hr = SHCoCreateInstance(NULL, pclsidHandler, NULL,
493 &IID_IAVIStream, (LPVOID*)ppavi);
494 if (FAILED(hr) || *ppavi == NULL)
497 hr = IAVIStream_Create(*ppavi, lParam1, lParam2);
499 IAVIStream_Release(*ppavi);
506 /***********************************************************************
507 * AVIStreamInfo (AVIFIL32.@)
508 * AVIStreamInfoA (AVIFIL32.@)
509 * AVIStreamInfo (AVIFILE.162)
511 HRESULT WINAPI AVIStreamInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi,
517 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
520 return AVIERR_BADHANDLE;
521 if ((DWORD)size < sizeof(AVISTREAMINFOA))
522 return AVIERR_BADSIZE;
524 hres = IAVIStream_Info(pstream, &asiw, sizeof(asiw));
526 memcpy(asi, &asiw, sizeof(asiw) - sizeof(asiw.szName));
527 WideCharToMultiByte(CP_ACP, 0, asiw.szName, -1, asi->szName,
528 sizeof(asi->szName), NULL, NULL);
529 asi->szName[sizeof(asi->szName) - 1] = 0;
534 /***********************************************************************
535 * AVIStreamInfoW (AVIFIL32.@)
537 HRESULT WINAPI AVIStreamInfoW(PAVISTREAM pstream, LPAVISTREAMINFOW asi,
540 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
543 return AVIERR_BADHANDLE;
545 return IAVIStream_Info(pstream, asi, size);
548 /***********************************************************************
549 * AVIStreamFindSample (AVIFIL32.@)
550 * AVIStreamFindSample (AVIFILE.163)
552 HRESULT WINAPI AVIStreamFindSample(PAVISTREAM pstream, LONG pos, DWORD flags)
554 TRACE("(%p,%ld,0x%lX)\n", pstream, pos, flags);
559 return IAVIStream_FindSample(pstream, pos, flags);
562 /***********************************************************************
563 * AVIStreamReadFormat (AVIFIL32.@)
564 * AVIStreamReadFormat (AVIFILE.164)
566 HRESULT WINAPI AVIStreamReadFormat(PAVISTREAM pstream, LONG pos,
567 LPVOID format, LPLONG formatsize)
569 TRACE("(%p,%ld,%p,%p)\n", pstream, pos, format, formatsize);
572 return AVIERR_BADHANDLE;
574 return IAVIStream_ReadFormat(pstream, pos, format, formatsize);
577 /***********************************************************************
578 * AVIStreamSetFormat (AVIFIL32.@)
579 * AVIStreamSetFormat (AVIFILE.169)
581 HRESULT WINAPI AVIStreamSetFormat(PAVISTREAM pstream, LONG pos,
582 LPVOID format, LONG formatsize)
584 TRACE("(%p,%ld,%p,%ld)\n", pstream, pos, format, formatsize);
587 return AVIERR_BADHANDLE;
589 return IAVIStream_SetFormat(pstream, pos, format, formatsize);
592 /***********************************************************************
593 * AVIStreamRead (AVIFIL32.@)
594 * AVIStreamRead (AVIFILE.167)
596 HRESULT WINAPI AVIStreamRead(PAVISTREAM pstream, LONG start, LONG samples,
597 LPVOID buffer, LONG buffersize,
598 LPLONG bytesread, LPLONG samplesread)
600 TRACE("(%p,%ld,%ld,%p,%ld,%p,%p)\n", pstream, start, samples, buffer,
601 buffersize, bytesread, samplesread);
604 return AVIERR_BADHANDLE;
606 return IAVIStream_Read(pstream, start, samples, buffer, buffersize,
607 bytesread, samplesread);
610 /***********************************************************************
611 * AVIStreamWrite (AVIFIL32.@)
612 * AVIStreamWrite (AVIFILE.168)
614 HRESULT WINAPI AVIStreamWrite(PAVISTREAM pstream, LONG start, LONG samples,
615 LPVOID buffer, LONG buffersize, DWORD flags,
616 LPLONG sampwritten, LPLONG byteswritten)
618 TRACE("(%p,%ld,%ld,%p,%ld,0x%lX,%p,%p)\n", pstream, start, samples, buffer,
619 buffersize, flags, sampwritten, byteswritten);
622 return AVIERR_BADHANDLE;
624 return IAVIStream_Write(pstream, start, samples, buffer, buffersize,
625 flags, sampwritten, byteswritten);
628 /***********************************************************************
629 * AVIStreamReadData (AVIFIL32.@)
630 * AVIStreamReadData (AVIFILE.165)
632 HRESULT WINAPI AVIStreamReadData(PAVISTREAM pstream, DWORD fcc, LPVOID lp,
635 TRACE("(%p,'%4.4s',%p,%p)\n", pstream, (char*)&fcc, lp, lpread);
638 return AVIERR_BADHANDLE;
640 return IAVIStream_ReadData(pstream, fcc, lp, lpread);
643 /***********************************************************************
644 * AVIStreamWriteData (AVIFIL32.@)
645 * AVIStreamWriteData (AVIFILE.166)
647 HRESULT WINAPI AVIStreamWriteData(PAVISTREAM pstream, DWORD fcc, LPVOID lp,
650 TRACE("(%p,'%4.4s',%p,%ld)\n", pstream, (char*)&fcc, lp, size);
653 return AVIERR_BADHANDLE;
655 return IAVIStream_WriteData(pstream, fcc, lp, size);
658 /***********************************************************************
659 * AVIStreamGetFrameOpen (AVIFIL32.@)
660 * AVIStreamGetFrameOpen (AVIFILE.112)
662 PGETFRAME WINAPI AVIStreamGetFrameOpen(PAVISTREAM pstream,
663 LPBITMAPINFOHEADER lpbiWanted)
667 TRACE("(%p,%p)\n", pstream, lpbiWanted);
669 if (FAILED(IAVIStream_QueryInterface(pstream, &IID_IGetFrame, (LPVOID*)&pg)) ||
671 pg = AVIFILE_CreateGetFrame(pstream);
676 if (FAILED(IGetFrame_SetFormat(pg, lpbiWanted, NULL, 0, 0, -1, -1))) {
677 IGetFrame_Release(pg);
684 /***********************************************************************
685 * AVIStreamGetFrame (AVIFIL32.@)
686 * AVIStreamGetFrame (AVIFILE.110)
688 LPVOID WINAPI AVIStreamGetFrame(PGETFRAME pg, LONG pos)
690 TRACE("(%p,%ld)\n", pg, pos);
695 return IGetFrame_GetFrame(pg, pos);
698 /***********************************************************************
699 * AVIStreamGetFrameClose (AVIFIL32.@)
700 * AVIStreamGetFrameClose (AVIFILE.111)
702 HRESULT WINAPI AVIStreamGetFrameClose(PGETFRAME pg)
707 return IGetFrame_Release(pg);
711 /***********************************************************************
712 * AVIMakeCompressedStream (AVIFIL32.@)
714 HRESULT WINAPI AVIMakeCompressedStream(PAVISTREAM *ppsCompressed,
716 LPAVICOMPRESSOPTIONS aco,
717 LPCLSID pclsidHandler)
724 LONG size = sizeof(szValue);
726 TRACE("(%p,%p,%p,%s)\n", ppsCompressed, psSource, aco,
727 debugstr_guid(pclsidHandler));
729 if (ppsCompressed == NULL)
730 return AVIERR_BADPARAM;
731 if (psSource == NULL)
732 return AVIERR_BADHANDLE;
734 *ppsCompressed = NULL;
736 /* if no handler given get default ones based on streamtype */
737 if (pclsidHandler == NULL) {
738 hr = IAVIStream_Info(psSource, &asiw, sizeof(asiw));
742 wsprintfA(szRegKey, "AVIFile\\Compressors\\%4.4s", (char*)&asiw.fccType);
743 if (RegQueryValueA(HKEY_CLASSES_ROOT, szRegKey, szValue, &size) != ERROR_SUCCESS)
744 return AVIERR_UNSUPPORTED;
745 if (AVIFILE_CLSIDFromString(szValue, &clsidHandler) != S_OK)
746 return AVIERR_UNSUPPORTED;
748 memcpy(&clsidHandler, pclsidHandler, sizeof(clsidHandler));
750 hr = SHCoCreateInstance(NULL, &clsidHandler, NULL,
751 &IID_IAVIStream, (LPVOID*)ppsCompressed);
752 if (FAILED(hr) || *ppsCompressed == NULL)
755 hr = IAVIStream_Create(*ppsCompressed, (LPARAM)psSource, (LPARAM)aco);
757 IAVIStream_Release(*ppsCompressed);
758 *ppsCompressed = NULL;
764 /***********************************************************************
765 * AVIMakeFileFromStreams (AVIFIL32.@)
767 HRESULT WINAPI AVIMakeFileFromStreams(PAVIFILE *ppfile, int nStreams,
768 PAVISTREAM *ppStreams)
770 TRACE("(%p,%d,%p)\n", ppfile, nStreams, ppStreams);
772 if (nStreams < 0 || ppfile == NULL || ppStreams == NULL)
773 return AVIERR_BADPARAM;
775 *ppfile = AVIFILE_CreateAVITempFile(nStreams, ppStreams);
777 return AVIERR_MEMORY;
782 /***********************************************************************
783 * AVIStreamOpenFromFile (AVIFILE.103)
784 * AVIStreamOpenFromFileA (AVIFIL32.@)
786 HRESULT WINAPI AVIStreamOpenFromFileA(PAVISTREAM *ppavi, LPCSTR szFile,
787 DWORD fccType, LONG lParam,
788 UINT mode, LPCLSID pclsidHandler)
790 PAVIFILE pfile = NULL;
793 TRACE("(%p,%s,'%4.4s',%ld,0x%X,%s)\n", ppavi, debugstr_a(szFile),
794 (char*)&fccType, lParam, mode, debugstr_guid(pclsidHandler));
796 if (ppavi == NULL || szFile == NULL)
797 return AVIERR_BADPARAM;
801 hr = AVIFileOpenA(&pfile, szFile, mode, pclsidHandler);
802 if (FAILED(hr) || pfile == NULL)
805 hr = IAVIFile_GetStream(pfile, ppavi, fccType, lParam);
806 IAVIFile_Release(pfile);
811 /***********************************************************************
812 * AVIStreamOpenFromFileW (AVIFIL32.@)
814 HRESULT WINAPI AVIStreamOpenFromFileW(PAVISTREAM *ppavi, LPCWSTR szFile,
815 DWORD fccType, LONG lParam,
816 UINT mode, LPCLSID pclsidHandler)
818 PAVIFILE pfile = NULL;
821 TRACE("(%p,%s,'%4.4s',%ld,0x%X,%s)\n", ppavi, debugstr_w(szFile),
822 (char*)&fccType, lParam, mode, debugstr_guid(pclsidHandler));
824 if (ppavi == NULL || szFile == NULL)
825 return AVIERR_BADPARAM;
829 hr = AVIFileOpenW(&pfile, szFile, mode, pclsidHandler);
830 if (FAILED(hr) || pfile == NULL)
833 hr = IAVIFile_GetStream(pfile, ppavi, fccType, lParam);
834 IAVIFile_Release(pfile);
839 /***********************************************************************
840 * AVIStreamBeginStreaming (AVIFIL32.@)
842 LONG WINAPI AVIStreamBeginStreaming(PAVISTREAM pavi, LONG lStart, LONG lEnd, LONG lRate)
844 IAVIStreaming* pstream = NULL;
847 TRACE("(%p,%ld,%ld,%ld)\n", pavi, lStart, lEnd, lRate);
850 return AVIERR_BADHANDLE;
852 hr = IAVIStream_QueryInterface(pavi, &IID_IAVIStreaming, (LPVOID*)&pstream);
853 if (SUCCEEDED(hr) && pstream != NULL) {
854 hr = IAVIStreaming_Begin(pstream, lStart, lEnd, lRate);
855 IAVIStreaming_Release(pstream);
862 /***********************************************************************
863 * AVIStreamEndStreaming (AVIFIL32.@)
865 LONG WINAPI AVIStreamEndStreaming(PAVISTREAM pavi)
867 IAVIStreaming* pstream = NULL;
870 TRACE("(%p)\n", pavi);
872 hr = IAVIStream_QueryInterface(pavi, &IID_IAVIStreaming, (LPVOID*)&pstream);
873 if (SUCCEEDED(hr) && pstream != NULL) {
874 IAVIStreaming_End(pstream);
875 IAVIStreaming_Release(pstream);
881 /***********************************************************************
882 * AVIStreamStart (AVIFILE.130)
883 * AVIStreamStart (AVIFIL32.@)
885 LONG WINAPI AVIStreamStart(PAVISTREAM pstream)
889 TRACE("(%p)\n", pstream);
894 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
900 /***********************************************************************
901 * AVIStreamLength (AVIFILE.131)
902 * AVIStreamLength (AVIFIL32.@)
904 LONG WINAPI AVIStreamLength(PAVISTREAM pstream)
908 TRACE("(%p)\n", pstream);
913 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
916 return asiw.dwLength;
919 /***********************************************************************
920 * AVIStreamSampleToTime (AVIFILE.133)
921 * AVIStreamSampleToTime (AVIFIL32.@)
923 LONG WINAPI AVIStreamSampleToTime(PAVISTREAM pstream, LONG lSample)
928 TRACE("(%p,%ld)\n", pstream, lSample);
933 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
935 if (asiw.dwRate == 0)
938 /* limit to stream bounds */
939 if (lSample < asiw.dwStart)
940 lSample = asiw.dwStart;
941 if (lSample > asiw.dwStart + asiw.dwLength)
942 lSample = asiw.dwStart + asiw.dwLength;
944 if (asiw.dwRate / asiw.dwScale < 1000)
945 time = (LONG)(((float)lSample * asiw.dwScale * 1000) / asiw.dwRate);
947 time = (LONG)(((float)lSample * asiw.dwScale * 1000 + (asiw.dwRate - 1)) / asiw.dwRate);
949 TRACE(" -> %ld\n",time);
953 /***********************************************************************
954 * AVIStreamTimeToSample (AVIFILE.132)
955 * AVIStreamTimeToSample (AVIFIL32.@)
957 LONG WINAPI AVIStreamTimeToSample(PAVISTREAM pstream, LONG lTime)
962 TRACE("(%p,%ld)\n", pstream, lTime);
964 if (pstream == NULL || lTime < 0)
967 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
969 if (asiw.dwScale == 0)
972 if (asiw.dwRate / asiw.dwScale < 1000)
973 sample = (LONG)((((float)asiw.dwRate * lTime) / (asiw.dwScale * 1000)));
975 sample = (LONG)(((float)asiw.dwRate * lTime + (asiw.dwScale * 1000 - 1)) / (asiw.dwScale * 1000));
977 /* limit to stream bounds */
978 if (sample < asiw.dwStart)
979 sample = asiw.dwStart;
980 if (sample > asiw.dwStart + asiw.dwLength)
981 sample = asiw.dwStart + asiw.dwLength;
983 TRACE(" -> %ld\n", sample);
987 /***********************************************************************
988 * AVIBuildFilterA (AVIFIL32.@)
989 * AVIBuildFilter (AVIFILE.123)
991 HRESULT WINAPI AVIBuildFilterA(LPSTR szFilter, LONG cbFilter, BOOL fSaving)
996 TRACE("(%p,%ld,%d)\n", szFilter, cbFilter, fSaving);
998 /* check parameters */
999 if (szFilter == NULL)
1000 return AVIERR_BADPARAM;
1002 return AVIERR_BADSIZE;
1007 wszFilter = (LPWSTR)GlobalAllocPtr(GHND, cbFilter * sizeof(WCHAR));
1008 if (wszFilter == NULL)
1009 return AVIERR_MEMORY;
1011 hr = AVIBuildFilterW(wszFilter, cbFilter, fSaving);
1012 if (SUCCEEDED(hr)) {
1013 WideCharToMultiByte(CP_ACP, 0, wszFilter, cbFilter,
1014 szFilter, cbFilter, NULL, NULL);
1017 GlobalFreePtr(wszFilter);
1022 /***********************************************************************
1023 * AVIBuildFilterW (AVIFIL32.@)
1025 HRESULT WINAPI AVIBuildFilterW(LPWSTR szFilter, LONG cbFilter, BOOL fSaving)
1027 static const WCHAR szClsid[] = {'C','L','S','I','D',0};
1028 static const WCHAR szExtensionFmt[] = {';','*','.','%','s',0};
1029 static const WCHAR szAVIFileExtensions[] =
1030 {'A','V','I','F','i','l','e','\\','E','x','t','e','n','s','i','o','n','s',0};
1033 WCHAR szAllFiles[40];
1034 WCHAR szFileExt[10];
1041 TRACE("(%p,%ld,%d)\n", szFilter, cbFilter, fSaving);
1043 /* check parameters */
1044 if (szFilter == NULL)
1045 return AVIERR_BADPARAM;
1047 return AVIERR_BADSIZE;
1049 lp = (AVIFilter*)GlobalAllocPtr(GHND, MAX_FILTERS * sizeof(AVIFilter));
1051 return AVIERR_MEMORY;
1054 * 1. iterate over HKEY_CLASSES_ROOT\\AVIFile\\Extensions and collect
1055 * extensions and CLSID's
1056 * 2. iterate over collected CLSID's and copy it's description and it's
1057 * extensions to szFilter if it fits
1059 * First filter is named "All multimedia files" and it's filter is a
1060 * collection of all possible extensions except "*.*".
1062 if (RegOpenKeyW(HKEY_CLASSES_ROOT, szAVIFileExtensions, &hKey) != S_OK) {
1064 return AVIERR_ERROR;
1066 for (n = 0;RegEnumKeyW(hKey, n, szFileExt, sizeof(szFileExt)) == S_OK;n++) {
1067 /* get CLSID to extension */
1068 size = sizeof(szValue)/sizeof(szValue[0]);
1069 if (RegQueryValueW(hKey, szFileExt, szValue, &size) != S_OK)
1072 /* search if the CLSID is already known */
1073 for (i = 1; i <= count; i++) {
1074 if (lstrcmpW(lp[i].szClsid, szValue) == 0)
1075 break; /* a new one */
1078 if (count - i == -1U) {
1079 /* it's a new CLSID */
1081 /* FIXME: How do we get info's about read/write capabilities? */
1083 if (count >= MAX_FILTERS) {
1084 /* try to inform user of our full fixed size table */
1085 ERR(": More than %d filters found! Adjust MAX_FILTERS in dlls/avifil32/api.c\n", MAX_FILTERS);
1089 lstrcpyW(lp[i].szClsid, szValue);
1094 /* append extension to the filter */
1095 wsprintfW(szValue, szExtensionFmt, szFileExt);
1096 if (lp[i].szExtensions[0] == 0)
1097 lstrcatW(lp[i].szExtensions, szValue + 1);
1099 lstrcatW(lp[i].szExtensions, szValue);
1101 /* also append to the "all multimedia"-filter */
1102 if (lp[0].szExtensions[0] == 0)
1103 lstrcatW(lp[0].szExtensions, szValue + 1);
1105 lstrcatW(lp[0].szExtensions, szValue);
1109 /* 2. get descriptions for the CLSIDs and fill out szFilter */
1110 if (RegOpenKeyW(HKEY_CLASSES_ROOT, szClsid, &hKey) != S_OK) {
1112 return AVIERR_ERROR;
1114 for (n = 0; n <= count; n++) {
1115 /* first the description */
1117 size = sizeof(szValue)/sizeof(szValue[0]);
1118 if (RegQueryValueW(hKey, lp[n].szClsid, szValue, &size) == S_OK) {
1119 size = lstrlenW(szValue);
1120 lstrcpynW(szFilter, szValue, cbFilter);
1123 size = LoadStringW(AVIFILE_hModule,IDS_ALLMULTIMEDIA,szFilter,cbFilter);
1125 /* check for enough space */
1127 if (cbFilter < size + lstrlenW(lp[n].szExtensions) + 2) {
1132 return AVIERR_BUFFERTOOSMALL;
1137 /* and then the filter */
1138 lstrcpynW(szFilter, lp[n].szExtensions, cbFilter);
1139 size = lstrlenW(lp[n].szExtensions) + 1;
1147 /* add "All files" "*.*" filter if enough space left */
1148 size = LoadStringW(AVIFILE_hModule, IDS_ALLFILES,
1149 szAllFiles, sizeof(szAllFiles)) + 1;
1150 if (cbFilter > size) {
1153 /* replace '@' with \000 to separate description of filter */
1154 for (i = 0; i < size && szAllFiles[i] != 0; i++) {
1155 if (szAllFiles[i] == '@') {
1161 memcpy(szFilter, szAllFiles, size * sizeof(szAllFiles[0]));
1168 return AVIERR_BUFFERTOOSMALL;
1172 static BOOL AVISaveOptionsFmtChoose(HWND hWnd)
1174 LPAVICOMPRESSOPTIONS pOptions = SaveOpts.ppOptions[SaveOpts.nCurrent];
1175 AVISTREAMINFOW sInfo;
1177 TRACE("(%p)\n", hWnd);
1179 if (pOptions == NULL || SaveOpts.ppavis[SaveOpts.nCurrent] == NULL) {
1180 ERR(": bad state!\n");
1184 if (FAILED(AVIStreamInfoW(SaveOpts.ppavis[SaveOpts.nCurrent],
1185 &sInfo, sizeof(sInfo)))) {
1186 ERR(": AVIStreamInfoW failed!\n");
1190 if (sInfo.fccType == streamtypeVIDEO) {
1194 memset(&cv, 0, sizeof(cv));
1196 if ((pOptions->dwFlags & AVICOMPRESSF_VALID) == 0) {
1197 memset(pOptions, 0, sizeof(AVICOMPRESSOPTIONS));
1198 pOptions->fccType = streamtypeVIDEO;
1199 pOptions->fccHandler = comptypeDIB;
1200 pOptions->dwQuality = (DWORD)ICQUALITY_DEFAULT;
1203 cv.cbSize = sizeof(cv);
1204 cv.dwFlags = ICMF_COMPVARS_VALID;
1205 /*cv.fccType = pOptions->fccType; */
1206 cv.fccHandler = pOptions->fccHandler;
1207 cv.lQ = pOptions->dwQuality;
1208 cv.lpState = pOptions->lpParms;
1209 cv.cbState = pOptions->cbParms;
1210 if (pOptions->dwFlags & AVICOMPRESSF_KEYFRAMES)
1211 cv.lKey = pOptions->dwKeyFrameEvery;
1214 if (pOptions->dwFlags & AVICOMPRESSF_DATARATE)
1215 cv.lDataRate = pOptions->dwBytesPerSecond / 1024; /* need kBytes */
1219 ret = ICCompressorChoose(hWnd, SaveOpts.uFlags, NULL,
1220 SaveOpts.ppavis[SaveOpts.nCurrent], &cv, NULL);
1223 pOptions->fccHandler = cv.fccHandler;
1224 pOptions->lpParms = cv.lpState;
1225 pOptions->cbParms = cv.cbState;
1226 pOptions->dwQuality = cv.lQ;
1228 pOptions->dwKeyFrameEvery = cv.lKey;
1229 pOptions->dwFlags |= AVICOMPRESSF_KEYFRAMES;
1231 pOptions->dwFlags &= ~AVICOMPRESSF_KEYFRAMES;
1232 if (cv.lDataRate != 0) {
1233 pOptions->dwBytesPerSecond = cv.lDataRate * 1024; /* need bytes */
1234 pOptions->dwFlags |= AVICOMPRESSF_DATARATE;
1236 pOptions->dwFlags &= ~AVICOMPRESSF_DATARATE;
1237 pOptions->dwFlags |= AVICOMPRESSF_VALID;
1239 ICCompressorFree(&cv);
1242 } else if (sInfo.fccType == streamtypeAUDIO) {
1243 ACMFORMATCHOOSEW afmtc;
1247 /* FIXME: check ACM version -- Which version is needed? */
1249 memset(&afmtc, 0, sizeof(afmtc));
1250 afmtc.cbStruct = sizeof(afmtc);
1252 afmtc.hwndOwner = hWnd;
1254 acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, &size);
1255 if ((pOptions->cbFormat == 0 || pOptions->lpFormat == NULL) && size != 0) {
1256 pOptions->lpFormat = GlobalAllocPtr(GMEM_MOVEABLE, size);
1257 pOptions->cbFormat = size;
1258 } else if (pOptions->cbFormat < (DWORD)size) {
1259 pOptions->lpFormat = GlobalReAllocPtr(pOptions->lpFormat, size, GMEM_MOVEABLE);
1260 pOptions->cbFormat = size;
1262 if (pOptions->lpFormat == NULL)
1264 afmtc.pwfx = pOptions->lpFormat;
1265 afmtc.cbwfx = pOptions->cbFormat;
1268 AVIStreamFormatSize(SaveOpts.ppavis[SaveOpts.nCurrent],
1269 sInfo.dwStart, &size);
1270 if (size < (LONG)sizeof(PCMWAVEFORMAT))
1271 size = sizeof(PCMWAVEFORMAT);
1272 afmtc.pwfxEnum = GlobalAllocPtr(GHND, size);
1273 if (afmtc.pwfxEnum != NULL) {
1274 AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent],
1275 sInfo.dwStart, afmtc.pwfxEnum, &size);
1276 afmtc.fdwEnum = ACM_FORMATENUMF_CONVERT;
1279 ret = acmFormatChooseW(&afmtc);
1281 pOptions->dwFlags |= AVICOMPRESSF_VALID;
1283 if (afmtc.pwfxEnum != NULL)
1284 GlobalFreePtr(afmtc.pwfxEnum);
1286 return (ret == S_OK ? TRUE : FALSE);
1288 ERR(": unknown streamtype 0x%08lX\n", sInfo.fccType);
1293 static void AVISaveOptionsUpdate(HWND hWnd)
1295 static const WCHAR szVideoFmt[]={'%','l','d','x','%','l','d','x','%','d',0};
1296 static const WCHAR szAudioFmt[]={'%','s',' ','%','s',0};
1298 WCHAR szFormat[128];
1299 AVISTREAMINFOW sInfo;
1303 TRACE("(%p)\n", hWnd);
1305 SaveOpts.nCurrent = SendDlgItemMessageW(hWnd,IDC_STREAM,CB_GETCURSEL,0,0);
1306 if (SaveOpts.nCurrent < 0)
1309 if (FAILED(AVIStreamInfoW(SaveOpts.ppavis[SaveOpts.nCurrent], &sInfo, sizeof(sInfo))))
1312 AVIStreamFormatSize(SaveOpts.ppavis[SaveOpts.nCurrent],sInfo.dwStart,&size);
1316 /* read format to build format descriotion string */
1317 lpFormat = GlobalAllocPtr(GHND, size);
1318 if (lpFormat != NULL) {
1319 if (SUCCEEDED(AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent],sInfo.dwStart,lpFormat, &size))) {
1320 if (sInfo.fccType == streamtypeVIDEO) {
1321 LPBITMAPINFOHEADER lpbi = lpFormat;
1324 wsprintfW(szFormat, szVideoFmt, lpbi->biWidth,
1325 lpbi->biHeight, lpbi->biBitCount);
1327 if (lpbi->biCompression != BI_RGB) {
1330 hic = ICLocate(ICTYPE_VIDEO, sInfo.fccHandler, lpFormat,
1331 NULL, ICMODE_DECOMPRESS);
1333 if (ICGetInfo(hic, &icinfo, sizeof(icinfo)) == S_OK)
1334 lstrcatW(szFormat, icinfo.szDescription);
1338 LoadStringW(AVIFILE_hModule, IDS_UNCOMPRESSED,
1339 icinfo.szDescription, sizeof(icinfo.szDescription));
1340 lstrcatW(szFormat, icinfo.szDescription);
1342 } else if (sInfo.fccType == streamtypeAUDIO) {
1343 ACMFORMATTAGDETAILSW aftd;
1344 ACMFORMATDETAILSW afd;
1346 memset(&aftd, 0, sizeof(aftd));
1347 memset(&afd, 0, sizeof(afd));
1349 aftd.cbStruct = sizeof(aftd);
1350 aftd.dwFormatTag = afd.dwFormatTag =
1351 ((PWAVEFORMATEX)lpFormat)->wFormatTag;
1352 aftd.cbFormatSize = afd.cbwfx = size;
1354 afd.cbStruct = sizeof(afd);
1355 afd.pwfx = lpFormat;
1357 if (acmFormatTagDetailsW(NULL, &aftd,
1358 ACM_FORMATTAGDETAILSF_FORMATTAG) == S_OK) {
1359 if (acmFormatDetailsW(NULL,&afd,ACM_FORMATDETAILSF_FORMAT) == S_OK)
1360 wsprintfW(szFormat, szAudioFmt, afd.szFormat, aftd.szFormatTag);
1364 GlobalFreePtr(lpFormat);
1367 /* set text for format description */
1368 SetDlgItemTextW(hWnd, IDC_FORMATTEXT, szFormat);
1370 /* Disable option button for unsupported streamtypes */
1371 if (sInfo.fccType == streamtypeVIDEO ||
1372 sInfo.fccType == streamtypeAUDIO)
1373 EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), TRUE);
1375 EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), FALSE);
1380 INT_PTR CALLBACK AVISaveOptionsDlgProc(HWND hWnd, UINT uMsg,
1381 WPARAM wParam, LPARAM lParam)
1384 BOOL bIsInterleaved;
1387 /*TRACE("(%p,%u,0x%04X,0x%08lX)\n", hWnd, uMsg, wParam, lParam);*/
1391 SaveOpts.nCurrent = 0;
1392 if (SaveOpts.nStreams == 1) {
1393 EndDialog(hWnd, AVISaveOptionsFmtChoose(hWnd));
1398 for (n = 0; n < SaveOpts.nStreams; n++) {
1399 AVISTREAMINFOW sInfo;
1401 AVIStreamInfoW(SaveOpts.ppavis[n], &sInfo, sizeof(sInfo));
1402 SendDlgItemMessageW(hWnd, IDC_STREAM, CB_ADDSTRING,
1403 0L, (LPARAM)sInfo.szName);
1406 /* select first stream */
1407 SendDlgItemMessageW(hWnd, IDC_STREAM, CB_SETCURSEL, 0, 0);
1408 SendMessageW(hWnd, WM_COMMAND,
1409 GET_WM_COMMAND_MPS(IDC_STREAM, hWnd, CBN_SELCHANGE));
1411 /* initialize interleave */
1412 if (SaveOpts.ppOptions[0] != NULL &&
1413 (SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_VALID)) {
1414 bIsInterleaved = (SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_INTERLEAVE);
1415 dwInterleave = SaveOpts.ppOptions[0]->dwInterleaveEvery;
1417 bIsInterleaved = TRUE;
1420 CheckDlgButton(hWnd, IDC_INTERLEAVE, bIsInterleaved);
1421 SetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, dwInterleave, FALSE);
1422 EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY), bIsInterleaved);
1425 switch (GET_WM_COMMAND_ID(wParam, lParam)) {
1427 /* get data from controls and save them */
1428 dwInterleave = GetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, NULL, 0);
1429 bIsInterleaved = IsDlgButtonChecked(hWnd, IDC_INTERLEAVE);
1430 for (n = 0; n < SaveOpts.nStreams; n++) {
1431 if (SaveOpts.ppOptions[n] != NULL) {
1432 if (bIsInterleaved) {
1433 SaveOpts.ppOptions[n]->dwFlags |= AVICOMPRESSF_INTERLEAVE;
1434 SaveOpts.ppOptions[n]->dwInterleaveEvery = dwInterleave;
1436 SaveOpts.ppOptions[n]->dwFlags &= ~AVICOMPRESSF_INTERLEAVE;
1441 EndDialog(hWnd, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
1443 case IDC_INTERLEAVE:
1444 EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY),
1445 IsDlgButtonChecked(hWnd, IDC_INTERLEAVE));
1448 if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE) {
1449 /* update control elements */
1450 AVISaveOptionsUpdate(hWnd);
1454 AVISaveOptionsFmtChoose(hWnd);
1463 /***********************************************************************
1464 * AVISaveOptions (AVIFIL32.@)
1466 BOOL WINAPI AVISaveOptions(HWND hWnd, UINT uFlags, INT nStreams,
1467 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *ppOptions)
1469 LPAVICOMPRESSOPTIONS pSavedOptions = NULL;
1472 TRACE("(%p,0x%X,%d,%p,%p)\n", hWnd, uFlags, nStreams,
1475 /* check parameters */
1476 if (nStreams <= 0 || ppavi == NULL || ppOptions == NULL)
1477 return AVIERR_BADPARAM;
1479 /* save options for case user press cancel */
1480 if (ppOptions != NULL && nStreams > 1) {
1481 pSavedOptions = GlobalAllocPtr(GHND,nStreams * sizeof(AVICOMPRESSOPTIONS));
1482 if (pSavedOptions == NULL)
1485 for (n = 0; n < nStreams; n++) {
1486 if (ppOptions[n] != NULL)
1487 memcpy(pSavedOptions + n, ppOptions[n], sizeof(AVICOMPRESSOPTIONS));
1491 SaveOpts.uFlags = uFlags;
1492 SaveOpts.nStreams = nStreams;
1493 SaveOpts.ppavis = ppavi;
1494 SaveOpts.ppOptions = ppOptions;
1496 ret = DialogBoxW(AVIFILE_hModule, MAKEINTRESOURCEW(IDD_SAVEOPTIONS),
1497 hWnd, AVISaveOptionsDlgProc);
1502 /* restore options when user pressed cancel */
1503 if (pSavedOptions != NULL) {
1505 for (n = 0; n < nStreams; n++) {
1506 if (ppOptions[n] != NULL)
1507 memcpy(ppOptions[n], pSavedOptions + n, sizeof(AVICOMPRESSOPTIONS));
1510 GlobalFreePtr(pSavedOptions);
1516 /***********************************************************************
1517 * AVISaveOptionsFree (AVIFIL32.@)
1518 * AVISaveOptionsFree (AVIFILE.124)
1520 HRESULT WINAPI AVISaveOptionsFree(INT nStreams,LPAVICOMPRESSOPTIONS*ppOptions)
1522 TRACE("(%d,%p)\n", nStreams, ppOptions);
1524 if (nStreams < 0 || ppOptions == NULL)
1525 return AVIERR_BADPARAM;
1527 for (; nStreams > 0; nStreams--) {
1528 if (ppOptions[nStreams] != NULL) {
1529 ppOptions[nStreams]->dwFlags &= ~AVICOMPRESSF_VALID;
1531 if (ppOptions[nStreams]->lpParms != NULL) {
1532 GlobalFreePtr(ppOptions[nStreams]->lpParms);
1533 ppOptions[nStreams]->lpParms = NULL;
1534 ppOptions[nStreams]->cbParms = 0;
1536 if (ppOptions[nStreams]->lpFormat != NULL) {
1537 GlobalFreePtr(ppOptions[nStreams]->lpFormat);
1538 ppOptions[nStreams]->lpFormat = NULL;
1539 ppOptions[nStreams]->cbFormat = 0;
1547 /***********************************************************************
1548 * AVISaveVA (AVIFIL32.@)
1550 HRESULT WINAPI AVISaveVA(LPCSTR szFile, CLSID *pclsidHandler,
1551 AVISAVECALLBACK lpfnCallback, int nStream,
1552 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions)
1554 LPWSTR wszFile = NULL;
1558 TRACE("%s,%p,%p,%d,%p,%p)\n", debugstr_a(szFile), pclsidHandler,
1559 lpfnCallback, nStream, ppavi, plpOptions);
1561 if (szFile == NULL || ppavi == NULL || plpOptions == NULL)
1562 return AVIERR_BADPARAM;
1564 /* convert ASCII string to Unicode and call Unicode function */
1565 len = MultiByteToWideChar(CP_ACP, 0, szFile, -1, NULL, 0);
1567 return AVIERR_BADPARAM;
1569 wszFile = LocalAlloc(LPTR, len * sizeof(WCHAR));
1570 if (wszFile == NULL)
1571 return AVIERR_MEMORY;
1573 MultiByteToWideChar(CP_ACP, 0, szFile, -1, wszFile, len);
1575 hr = AVISaveVW(wszFile, pclsidHandler, lpfnCallback,
1576 nStream, ppavi, plpOptions);
1578 LocalFree((HLOCAL)wszFile);
1583 /***********************************************************************
1584 * AVIFILE_AVISaveDefaultCallback (internal)
1586 static BOOL WINAPI AVIFILE_AVISaveDefaultCallback(INT progress)
1588 TRACE("(%d)\n", progress);
1593 /***********************************************************************
1594 * AVISaveVW (AVIFIL32.@)
1596 HRESULT WINAPI AVISaveVW(LPCWSTR szFile, CLSID *pclsidHandler,
1597 AVISAVECALLBACK lpfnCallback, int nStreams,
1598 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions)
1600 LONG lStart[MAX_AVISTREAMS];
1601 PAVISTREAM pOutStreams[MAX_AVISTREAMS];
1602 PAVISTREAM pInStreams[MAX_AVISTREAMS];
1604 AVISTREAMINFOW sInfo;
1606 PAVIFILE pfile = NULL; /* the output AVI file */
1607 LONG lFirstVideo = -1;
1610 /* for interleaving ... */
1611 DWORD dwInterleave = 0; /* interleave rate */
1612 DWORD dwFileInitialFrames;
1616 /* for reading/writing the data ... */
1617 LPVOID lpBuffer = NULL;
1618 LONG cbBuffer; /* real size of lpBuffer */
1619 LONG lBufferSize; /* needed bytes for format(s), etc. */
1624 TRACE("(%s,%p,%p,%d,%p,%p)\n", debugstr_w(szFile), pclsidHandler,
1625 lpfnCallback, nStreams, ppavi, plpOptions);
1627 if (szFile == NULL || ppavi == NULL || plpOptions == NULL)
1628 return AVIERR_BADPARAM;
1629 if (nStreams >= MAX_AVISTREAMS) {
1630 WARN("Can't write AVI with %d streams only supports %d -- change MAX_AVISTREAMS!\n", nStreams, MAX_AVISTREAMS);
1631 return AVIERR_INTERNAL;
1634 if (lpfnCallback == NULL)
1635 lpfnCallback = AVIFILE_AVISaveDefaultCallback;
1637 /* clear local variable(s) */
1638 for (curStream = 0; curStream < nStreams; curStream++) {
1639 pInStreams[curStream] = NULL;
1640 pOutStreams[curStream] = NULL;
1643 /* open output AVI file (create it if it doesn't exist) */
1644 hres = AVIFileOpenW(&pfile, szFile, OF_CREATE|OF_SHARE_EXCLUSIVE|OF_WRITE,
1648 AVIFileInfoW(pfile, &fInfo, sizeof(fInfo)); /* for dwCaps */
1650 /* initialize our data structures part 1 */
1651 for (curStream = 0; curStream < nStreams; curStream++) {
1652 PAVISTREAM pCurStream = ppavi[curStream];
1654 hres = AVIStreamInfoW(pCurStream, &sInfo, sizeof(sInfo));
1658 /* search first video stream and check for interleaving */
1659 if (sInfo.fccType == streamtypeVIDEO) {
1660 /* remember first video stream -- needed for interleaving */
1661 if (lFirstVideo < 0)
1662 lFirstVideo = curStream;
1663 } else if (!dwInterleave && plpOptions != NULL) {
1664 /* check if any non-video stream wants to be interleaved */
1665 WARN("options.flags=0x%lX options.dwInterleave=%lu\n",plpOptions[curStream]->dwFlags,plpOptions[curStream]->dwInterleaveEvery);
1666 if (plpOptions[curStream] != NULL &&
1667 plpOptions[curStream]->dwFlags & AVICOMPRESSF_INTERLEAVE)
1668 dwInterleave = plpOptions[curStream]->dwInterleaveEvery;
1671 /* create de-/compressed stream interface if needed */
1672 pInStreams[curStream] = NULL;
1673 if (plpOptions != NULL && plpOptions[curStream] != NULL) {
1674 if (plpOptions[curStream]->fccHandler ||
1675 plpOptions[curStream]->lpFormat != NULL) {
1676 DWORD dwKeySave = plpOptions[curStream]->dwKeyFrameEvery;
1678 if (fInfo.dwCaps & AVIFILECAPS_ALLKEYFRAMES)
1679 plpOptions[curStream]->dwKeyFrameEvery = 1;
1681 hres = AVIMakeCompressedStream(&pInStreams[curStream], pCurStream,
1682 plpOptions[curStream], NULL);
1683 plpOptions[curStream]->dwKeyFrameEvery = dwKeySave;
1684 if (FAILED(hres) || pInStreams[curStream] == NULL) {
1685 pInStreams[curStream] = NULL;
1689 /* test stream interface and update stream-info */
1690 hres = AVIStreamInfoW(pInStreams[curStream], &sInfo, sizeof(sInfo));
1696 /* now handle streams which will only be copied */
1697 if (pInStreams[curStream] == NULL) {
1698 pCurStream = pInStreams[curStream] = ppavi[curStream];
1699 AVIStreamAddRef(pCurStream);
1701 pCurStream = pInStreams[curStream];
1703 lStart[curStream] = sInfo.dwStart;
1704 } /* for all streams */
1706 /* check that first video stream is the first stream */
1707 if (lFirstVideo > 0) {
1708 PAVISTREAM pTmp = pInStreams[lFirstVideo];
1709 LONG lTmp = lStart[lFirstVideo];
1711 pInStreams[lFirstVideo] = pInStreams[0];
1712 pInStreams[0] = pTmp;
1713 lStart[lFirstVideo] = lStart[0];
1718 /* allocate buffer for formats, data, etc. of an initiale size of 64 kByte */
1719 lpBuffer = GlobalAllocPtr(GPTR, cbBuffer = 0x00010000);
1720 if (lpBuffer == NULL) {
1721 hres = AVIERR_MEMORY;
1725 AVIStreamInfoW(pInStreams[0], &sInfo, sizeof(sInfo));
1726 lFileLength = sInfo.dwLength;
1727 dwFileInitialFrames = 0;
1728 if (lFirstVideo >= 0) {
1729 /* check for correct version of the format
1730 * -- need atleast BITMAPINFOHEADER or newer
1733 lBufferSize = cbBuffer;
1734 hres = AVIStreamReadFormat(pInStreams[lFirstVideo], AVIStreamStart(pInStreams[lFirstVideo]), lpBuffer, &lBufferSize);
1735 if (lBufferSize < (LONG)sizeof(BITMAPINFOHEADER))
1736 hres = AVIERR_INTERNAL;
1739 } else /* use one second blocks for interleaving if no video present */
1740 lSampleInc = AVIStreamTimeToSample(pInStreams[0], 1000000);
1742 /* create output streams */
1743 for (curStream = 0; curStream < nStreams; curStream++) {
1744 AVIStreamInfoW(pInStreams[curStream], &sInfo, sizeof(sInfo));
1746 sInfo.dwInitialFrames = 0;
1747 if (dwInterleave != 0 && curStream > 0 && sInfo.fccType != streamtypeVIDEO) {
1748 /* 750 ms initial frames for non-video streams */
1749 sInfo.dwInitialFrames = AVIStreamTimeToSample(pInStreams[0], 750);
1752 hres = AVIFileCreateStreamW(pfile, &pOutStreams[curStream], &sInfo);
1753 if (pOutStreams[curStream] != NULL && SUCCEEDED(hres)) {
1754 /* copy initial format for this stream */
1755 lBufferSize = cbBuffer;
1756 hres = AVIStreamReadFormat(pInStreams[curStream], sInfo.dwStart,
1757 lpBuffer, &lBufferSize);
1760 hres = AVIStreamSetFormat(pOutStreams[curStream], 0, lpBuffer, lBufferSize);
1764 /* try to copy stream handler data */
1765 lBufferSize = cbBuffer;
1766 hres = AVIStreamReadData(pInStreams[curStream], ckidSTREAMHANDLERDATA,
1767 lpBuffer, &lBufferSize);
1768 if (SUCCEEDED(hres) && lBufferSize > 0) {
1769 hres = AVIStreamWriteData(pOutStreams[curStream],ckidSTREAMHANDLERDATA,
1770 lpBuffer, lBufferSize);
1775 if (dwFileInitialFrames < sInfo.dwInitialFrames)
1776 dwFileInitialFrames = sInfo.dwInitialFrames;
1778 AVIStreamSampleToSample(pOutStreams[0], pInStreams[curStream],
1780 if (lFileLength < lReadBytes)
1781 lFileLength = lReadBytes;
1783 /* creation of de-/compression stream interface failed */
1784 WARN("creation of (de-)compression stream failed for stream %d\n",curStream);
1785 AVIStreamRelease(pInStreams[curStream]);
1786 if (curStream + 1 >= nStreams) {
1787 /* move the others one up */
1788 PAVISTREAM *ppas = &pInStreams[curStream];
1789 int n = nStreams - (curStream + 1);
1792 *ppas = pInStreams[curStream + 1];
1798 } /* create output streams for all input streams */
1800 /* have we still something to write, or lost everything? */
1805 LONG lCurFrame = -dwFileInitialFrames;
1807 /* interleaved file */
1808 if (dwInterleave == 1)
1809 AVIFileEndRecord(pfile);
1811 for (; lCurFrame < lFileLength; lCurFrame += lSampleInc) {
1812 for (curStream = 0; curStream < nStreams; curStream++) {
1815 hres = AVIStreamInfoW(pOutStreams[curStream], &sInfo, sizeof(sInfo));
1819 /* initial frames phase at the end for this stream? */
1820 if (-(LONG)sInfo.dwInitialFrames > lCurFrame)
1823 if ((lFileLength - lSampleInc) <= lCurFrame) {
1824 lLastSample = AVIStreamLength(pInStreams[curStream]);
1825 lFirstVideo = lLastSample + AVIStreamStart(pInStreams[curStream]);
1827 if (curStream != 0) {
1829 AVIStreamSampleToSample(pInStreams[curStream], pInStreams[0],
1830 (sInfo.fccType == streamtypeVIDEO ?
1831 (LONG)dwInterleave : lSampleInc) +
1832 sInfo.dwInitialFrames + lCurFrame);
1834 lFirstVideo = lSampleInc + (sInfo.dwInitialFrames + lCurFrame);
1836 lLastSample = AVIStreamEnd(pInStreams[curStream]);
1837 if (lLastSample <= lFirstVideo)
1838 lFirstVideo = lLastSample;
1841 /* copy needed samples now */
1842 WARN("copy from stream %d samples %ld to %ld...\n",curStream,
1843 lStart[curStream],lFirstVideo);
1844 while (lFirstVideo > lStart[curStream]) {
1847 /* copy format for case it can change */
1848 lBufferSize = cbBuffer;
1849 hres = AVIStreamReadFormat(pInStreams[curStream], lStart[curStream],
1850 lpBuffer, &lBufferSize);
1853 AVIStreamSetFormat(pOutStreams[curStream], lStart[curStream],
1854 lpBuffer, lBufferSize);
1856 /* try to read data until we got it, or error */
1858 hres = AVIStreamRead(pInStreams[curStream], lStart[curStream],
1859 lFirstVideo - lStart[curStream], lpBuffer,
1860 cbBuffer, &lReadBytes, &lReadSamples);
1861 } while ((hres == AVIERR_BUFFERTOOSMALL) &&
1862 (lpBuffer = GlobalReAllocPtr(lpBuffer, cbBuffer *= 2, GPTR)) != NULL);
1863 if (lpBuffer == NULL)
1864 hres = AVIERR_MEMORY;
1868 if (AVIStreamIsKeyFrame(pInStreams[curStream], (LONG)sInfo.dwStart))
1869 flags = AVIIF_KEYFRAME;
1870 hres = AVIStreamWrite(pOutStreams[curStream], -1, lReadSamples,
1871 lpBuffer, lReadBytes, flags, NULL, NULL);
1875 lStart[curStream] += lReadSamples;
1877 lStart[curStream] = lFirstVideo;
1878 } /* stream by stream */
1880 /* need to close this block? */
1881 if (dwInterleave == 1) {
1882 hres = AVIFileEndRecord(pfile);
1888 if (lpfnCallback(MulDiv(dwFileInitialFrames + lCurFrame, 100,
1889 dwFileInitialFrames + lFileLength))) {
1890 hres = AVIERR_USERABORT;
1893 } /* copy frame by frame */
1895 /* non-interleaved file */
1897 for (curStream = 0; curStream < nStreams; curStream++) {
1899 if (lpfnCallback(MulDiv(curStream, 100, nStreams))) {
1900 hres = AVIERR_USERABORT;
1904 AVIStreamInfoW(pInStreams[curStream], &sInfo, sizeof(sInfo));
1906 if (sInfo.dwSampleSize != 0) {
1907 /* sample-based data like audio */
1908 while (sInfo.dwStart < sInfo.dwLength) {
1909 LONG lSamples = cbBuffer / sInfo.dwSampleSize;
1911 /* copy format for case it can change */
1912 lBufferSize = cbBuffer;
1913 hres = AVIStreamReadFormat(pInStreams[curStream], sInfo.dwStart,
1914 lpBuffer, &lBufferSize);
1917 AVIStreamSetFormat(pOutStreams[curStream], sInfo.dwStart,
1918 lpBuffer, lBufferSize);
1920 /* limit to stream boundaries */
1921 if (lSamples != (LONG)(sInfo.dwLength - sInfo.dwStart))
1922 lSamples = sInfo.dwLength - sInfo.dwStart;
1924 /* now try to read until we got it, or error occures */
1926 lReadBytes = cbBuffer;
1928 hres = AVIStreamRead(pInStreams[curStream],sInfo.dwStart,lSamples,
1929 lpBuffer,cbBuffer,&lReadBytes,&lReadSamples);
1930 } while ((hres == AVIERR_BUFFERTOOSMALL) &&
1931 (lpBuffer = GlobalReAllocPtr(lpBuffer, cbBuffer *= 2, GPTR)) != NULL);
1932 if (lpBuffer == NULL)
1933 hres = AVIERR_MEMORY;
1936 if (lReadSamples != 0) {
1937 sInfo.dwStart += lReadSamples;
1938 hres = AVIStreamWrite(pOutStreams[curStream], -1, lReadSamples,
1939 lpBuffer, lReadBytes, 0, NULL , NULL);
1944 if (lpfnCallback(MulDiv(sInfo.dwStart,100,nStreams*sInfo.dwLength)+
1945 MulDiv(curStream, 100, nStreams))) {
1946 hres = AVIERR_USERABORT;
1950 if ((sInfo.dwLength - sInfo.dwStart) != 1) {
1951 hres = AVIERR_FILEREAD;
1957 /* block-based data like video */
1958 for (; sInfo.dwStart < sInfo.dwLength; sInfo.dwStart++) {
1961 /* copy format for case it can change */
1962 lBufferSize = cbBuffer;
1963 hres = AVIStreamReadFormat(pInStreams[curStream], sInfo.dwStart,
1964 lpBuffer, &lBufferSize);
1967 AVIStreamSetFormat(pOutStreams[curStream], sInfo.dwStart,
1968 lpBuffer, lBufferSize);
1970 /* try to read block and resize buffer if necessary */
1973 lReadBytes = cbBuffer;
1974 hres = AVIStreamRead(pInStreams[curStream], sInfo.dwStart, 1,
1975 lpBuffer, cbBuffer,&lReadBytes,&lReadSamples);
1976 } while ((hres == AVIERR_BUFFERTOOSMALL) &&
1977 (lpBuffer = GlobalReAllocPtr(lpBuffer, cbBuffer *= 2, GPTR)) != NULL);
1978 if (lpBuffer == NULL)
1979 hres = AVIERR_MEMORY;
1982 if (lReadSamples != 1) {
1983 hres = AVIERR_FILEREAD;
1987 if (AVIStreamIsKeyFrame(pInStreams[curStream], (LONG)sInfo.dwStart))
1988 flags = AVIIF_KEYFRAME;
1989 hres = AVIStreamWrite(pOutStreams[curStream], -1, lReadSamples,
1990 lpBuffer, lReadBytes, flags, NULL, NULL);
1995 if (lpfnCallback(MulDiv(sInfo.dwStart,100,nStreams*sInfo.dwLength)+
1996 MulDiv(curStream, 100, nStreams))) {
1997 hres = AVIERR_USERABORT;
2000 } /* copy all blocks */
2002 } /* copy data stream by stream */
2006 if (lpBuffer != NULL)
2007 GlobalFreePtr(lpBuffer);
2008 if (pfile != NULL) {
2009 for (curStream = 0; curStream < nStreams; curStream++) {
2010 if (pOutStreams[curStream] != NULL)
2011 AVIStreamRelease(pOutStreams[curStream]);
2012 if (pInStreams[curStream] != NULL)
2013 AVIStreamRelease(pInStreams[curStream]);
2016 AVIFileRelease(pfile);
2022 /***********************************************************************
2023 * CreateEditableStream (AVIFIL32.@)
2025 HRESULT WINAPI CreateEditableStream(PAVISTREAM *ppEditable, PAVISTREAM pSource)
2027 IAVIEditStream *pEdit = NULL;
2030 TRACE("(%p,%p)\n", ppEditable, pSource);
2032 if (ppEditable == NULL)
2033 return AVIERR_BADPARAM;
2037 if (pSource != NULL) {
2038 hr = IAVIStream_QueryInterface(pSource, &IID_IAVIEditStream,
2040 if (SUCCEEDED(hr) && pEdit != NULL) {
2041 hr = IAVIEditStream_Clone(pEdit, ppEditable);
2042 IAVIEditStream_Release(pEdit);
2048 /* need own implementation of IAVIEditStream */
2049 pEdit = AVIFILE_CreateEditStream(pSource);
2051 return AVIERR_MEMORY;
2053 hr = IAVIEditStream_QueryInterface(pEdit, &IID_IAVIStream,
2054 (LPVOID*)ppEditable);
2055 IAVIEditStream_Release(pEdit);
2060 /***********************************************************************
2061 * EditStreamClone (AVIFIL32.@)
2063 HRESULT WINAPI EditStreamClone(PAVISTREAM pStream, PAVISTREAM *ppResult)
2065 PAVIEDITSTREAM pEdit = NULL;
2068 TRACE("(%p,%p)\n", pStream, ppResult);
2070 if (pStream == NULL)
2071 return AVIERR_BADHANDLE;
2072 if (ppResult == NULL)
2073 return AVIERR_BADPARAM;
2077 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
2078 if (SUCCEEDED(hr) && pEdit != NULL) {
2079 hr = IAVIEditStream_Clone(pEdit, ppResult);
2081 IAVIEditStream_Release(pEdit);
2083 hr = AVIERR_UNSUPPORTED;
2088 /***********************************************************************
2089 * EditStreamCopy (AVIFIL32.@)
2091 HRESULT WINAPI EditStreamCopy(PAVISTREAM pStream, LONG *plStart,
2092 LONG *plLength, PAVISTREAM *ppResult)
2094 PAVIEDITSTREAM pEdit = NULL;
2097 TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult);
2099 if (pStream == NULL)
2100 return AVIERR_BADHANDLE;
2101 if (plStart == NULL || plLength == NULL || ppResult == NULL)
2102 return AVIERR_BADPARAM;
2106 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
2107 if (SUCCEEDED(hr) && pEdit != NULL) {
2108 hr = IAVIEditStream_Copy(pEdit, plStart, plLength, ppResult);
2110 IAVIEditStream_Release(pEdit);
2112 hr = AVIERR_UNSUPPORTED;
2117 /***********************************************************************
2118 * EditStreamCut (AVIFIL32.@)
2120 HRESULT WINAPI EditStreamCut(PAVISTREAM pStream, LONG *plStart,
2121 LONG *plLength, PAVISTREAM *ppResult)
2123 PAVIEDITSTREAM pEdit = NULL;
2126 TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult);
2128 if (ppResult != NULL)
2130 if (pStream == NULL)
2131 return AVIERR_BADHANDLE;
2132 if (plStart == NULL || plLength == NULL)
2133 return AVIERR_BADPARAM;
2135 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
2136 if (SUCCEEDED(hr) && pEdit != NULL) {
2137 hr = IAVIEditStream_Cut(pEdit, plStart, plLength, ppResult);
2139 IAVIEditStream_Release(pEdit);
2141 hr = AVIERR_UNSUPPORTED;
2146 /***********************************************************************
2147 * EditStreamPaste (AVIFIL32.@)
2149 HRESULT WINAPI EditStreamPaste(PAVISTREAM pDest, LONG *plStart, LONG *plLength,
2150 PAVISTREAM pSource, LONG lStart, LONG lEnd)
2152 PAVIEDITSTREAM pEdit = NULL;
2155 TRACE("(%p,%p,%p,%p,%ld,%ld)\n", pDest, plStart, plLength,
2156 pSource, lStart, lEnd);
2158 if (pDest == NULL || pSource == NULL)
2159 return AVIERR_BADHANDLE;
2160 if (plStart == NULL || plLength == NULL || lStart < 0)
2161 return AVIERR_BADPARAM;
2163 hr = IAVIStream_QueryInterface(pDest, &IID_IAVIEditStream,(LPVOID*)&pEdit);
2164 if (SUCCEEDED(hr) && pEdit != NULL) {
2165 hr = IAVIEditStream_Paste(pEdit, plStart, plLength, pSource, lStart, lEnd);
2167 IAVIEditStream_Release(pEdit);
2169 hr = AVIERR_UNSUPPORTED;
2174 /***********************************************************************
2175 * EditStreamSetInfoA (AVIFIL32.@)
2177 HRESULT WINAPI EditStreamSetInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi,
2180 AVISTREAMINFOW asiw;
2182 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
2184 if (pstream == NULL)
2185 return AVIERR_BADHANDLE;
2186 if ((DWORD)size < sizeof(AVISTREAMINFOA))
2187 return AVIERR_BADSIZE;
2189 memcpy(&asiw, asi, sizeof(asiw) - sizeof(asiw.szName));
2190 MultiByteToWideChar(CP_ACP, 0, asi->szName, -1,
2191 asiw.szName, sizeof(asiw.szName));
2193 return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw));
2196 /***********************************************************************
2197 * EditStreamSetInfoW (AVIFIL32.@)
2199 HRESULT WINAPI EditStreamSetInfoW(PAVISTREAM pstream, LPAVISTREAMINFOW asi,
2202 PAVIEDITSTREAM pEdit = NULL;
2205 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
2207 hr = IAVIStream_QueryInterface(pstream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
2208 if (SUCCEEDED(hr) && pEdit != NULL) {
2209 hr = IAVIEditStream_SetInfo(pEdit, asi, size);
2211 IAVIEditStream_Release(pEdit);
2213 hr = AVIERR_UNSUPPORTED;
2218 /***********************************************************************
2219 * EditStreamSetNameA (AVIFIL32.@)
2221 HRESULT WINAPI EditStreamSetNameA(PAVISTREAM pstream, LPCSTR szName)
2223 AVISTREAMINFOA asia;
2226 TRACE("(%p,%s)\n", pstream, debugstr_a(szName));
2228 if (pstream == NULL)
2229 return AVIERR_BADHANDLE;
2231 return AVIERR_BADPARAM;
2233 hres = AVIStreamInfoA(pstream, &asia, sizeof(asia));
2237 memset(asia.szName, 0, sizeof(asia.szName));
2238 lstrcpynA(asia.szName, szName, sizeof(asia.szName)/sizeof(asia.szName[0]));
2240 return EditStreamSetInfoA(pstream, &asia, sizeof(asia));
2243 /***********************************************************************
2244 * EditStreamSetNameW (AVIFIL32.@)
2246 HRESULT WINAPI EditStreamSetNameW(PAVISTREAM pstream, LPCWSTR szName)
2248 AVISTREAMINFOW asiw;
2251 TRACE("(%p,%s)\n", pstream, debugstr_w(szName));
2253 if (pstream == NULL)
2254 return AVIERR_BADHANDLE;
2256 return AVIERR_BADPARAM;
2258 hres = IAVIStream_Info(pstream, &asiw, sizeof(asiw));
2262 memset(asiw.szName, 0, sizeof(asiw.szName));
2263 lstrcpynW(asiw.szName, szName, sizeof(asiw.szName)/sizeof(asiw.szName[0]));
2265 return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw));
2268 /***********************************************************************
2269 * AVIClearClipboard (AVIFIL32.@)
2271 HRESULT WINAPI AVIClearClipboard(void)
2275 return AVIERR_UNSUPPORTED; /* OleSetClipboard(NULL); */
2278 /***********************************************************************
2279 * AVIGetFromClipboard (AVIFIL32.@)
2281 HRESULT WINAPI AVIGetFromClipboard(PAVIFILE *ppfile)
2283 FIXME("(%p), stub!\n", ppfile);
2287 return AVIERR_UNSUPPORTED;
2290 /***********************************************************************
2291 * AVIPutFileOnClipboard (AVIFIL32.@)
2293 HRESULT WINAPI AVIPutFileOnClipboard(PAVIFILE pfile)
2295 FIXME("(%p), stub!\n", pfile);
2298 return AVIERR_BADHANDLE;
2300 return AVIERR_UNSUPPORTED;