- Fixed some signed/unsigned mismatches.
[wine/dcerpc.git] / dlls / avifil32 / api.c
blobc4fdcee7bc663076d3ef8496546ef917c4571fde
1 /*
2 * Copyright 1999 Marcus Meissner
3 * Copyright 2002 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
21 #include <assert.h>
23 #include "winbase.h"
24 #include "winnls.h"
25 #include "winuser.h"
26 #include "winreg.h"
27 #include "winerror.h"
28 #include "windowsx.h"
30 #include "ole2.h"
31 #include "shellapi.h"
32 #include "vfw.h"
33 #include "msacm.h"
35 #include "avifile_private.h"
37 #include "wine/debug.h"
38 #include "wine/unicode.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(avifile);
42 /***********************************************************************
43 * copied from dlls/shell32/undocshell.h
45 HRESULT WINAPI SHCoCreateInstance(LPCSTR lpszClsid,REFCLSID rClsid,
46 LPUNKNOWN pUnkOuter,REFIID riid,LPVOID *ppv);
48 /***********************************************************************
49 * for AVIBuildFilterW -- uses fixed size table
51 #define MAX_FILTERS 30 /* 30 => 7kB */
53 typedef struct _AVIFilter {
54 WCHAR szClsid[40];
55 WCHAR szExtensions[MAX_FILTERS * 7];
56 } AVIFilter;
58 /***********************************************************************
59 * for AVISaveOptions
61 static struct {
62 UINT uFlags;
63 INT nStreams;
64 PAVISTREAM *ppavis;
65 LPAVICOMPRESSOPTIONS *ppOptions;
66 INT nCurrent;
67 } SaveOpts;
69 /***********************************************************************
70 * copied from dlls/ole32/compobj.c
72 static HRESULT AVIFILE_CLSIDFromString(LPCSTR idstr, LPCLSID id)
74 BYTE const *s = (BYTE const*)idstr;
75 BYTE *p;
76 INT i;
77 BYTE table[256];
79 if (!s) {
80 memset(id, 0, sizeof(CLSID));
81 return S_OK;
82 } else { /* validate the CLSID string */
83 if (lstrlenA(s) != 38)
84 return CO_E_CLASSSTRING;
86 if ((s[0]!='{') || (s[9]!='-') || (s[14]!='-') || (s[19]!='-') ||
87 (s[24]!='-') || (s[37]!='}'))
88 return CO_E_CLASSSTRING;
90 for (i = 1; i < 37; i++) {
91 if ((i == 9) || (i == 14) || (i == 19) || (i == 24))
92 continue;
93 if (!(((s[i] >= '0') && (s[i] <= '9')) ||
94 ((s[i] >= 'a') && (s[i] <= 'f')) ||
95 ((s[i] >= 'A') && (s[i] <= 'F')))
97 return CO_E_CLASSSTRING;
101 TRACE("%s -> %p\n", s, id);
103 /* quick lookup table */
104 memset(table, 0, 256);
106 for (i = 0; i < 10; i++)
107 table['0' + i] = i;
109 for (i = 0; i < 6; i++) {
110 table['A' + i] = i+10;
111 table['a' + i] = i+10;
114 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
115 p = (BYTE *) id;
117 s++; /* skip leading brace */
118 for (i = 0; i < 4; i++) {
119 p[3 - i] = table[*s]<<4 | table[*(s+1)];
120 s += 2;
122 p += 4;
123 s++; /* skip - */
125 for (i = 0; i < 2; i++) {
126 p[1-i] = table[*s]<<4 | table[*(s+1)];
127 s += 2;
129 p += 2;
130 s++; /* skip - */
132 for (i = 0; i < 2; i++) {
133 p[1-i] = table[*s]<<4 | table[*(s+1)];
134 s += 2;
136 p += 2;
137 s++; /* skip - */
139 /* these are just sequential bytes */
140 for (i = 0; i < 2; i++) {
141 *p++ = table[*s]<<4 | table[*(s+1)];
142 s += 2;
144 s++; /* skip - */
146 for (i = 0; i < 6; i++) {
147 *p++ = table[*s]<<4 | table[*(s+1)];
148 s += 2;
151 return S_OK;
154 static BOOL AVIFILE_GetFileHandlerByExtension(LPCWSTR szFile, LPCLSID lpclsid)
156 CHAR szRegKey[25];
157 CHAR szValue[100];
158 LPWSTR szExt = strrchrW(szFile, '.');
159 LONG len = sizeof(szValue) / sizeof(szValue[0]);
161 if (szExt == NULL)
162 return FALSE;
164 szExt++;
166 wsprintfA(szRegKey, "AVIFile\\Extensions\\%.3ls", szExt);
167 if (RegQueryValueA(HKEY_CLASSES_ROOT, szRegKey, szValue, &len) != ERROR_SUCCESS)
168 return FALSE;
170 return (AVIFILE_CLSIDFromString(szValue, lpclsid) == S_OK);
173 /***********************************************************************
174 * AVIFileInit (AVIFIL32.@)
175 * AVIFileInit (AVIFILE.100)
177 void WINAPI AVIFileInit(void) {
178 /* need to load ole32.dll if not already done and get some functions */
179 FIXME("(): stub!\n");
182 /***********************************************************************
183 * AVIFileExit (AVIFIL32.@)
184 * AVIFileExit (AVIFILE.101)
186 void WINAPI AVIFileExit(void) {
187 /* need to free ole32.dll if we are the last exit call */
188 FIXME("(): stub!\n");
191 /***********************************************************************
192 * AVIFileOpenA (AVIFIL32.@)
193 * AVIFileOpen (AVIFILE.102)
195 HRESULT WINAPI AVIFileOpenA(PAVIFILE *ppfile, LPCSTR szFile, UINT uMode,
196 LPCLSID lpHandler)
198 LPWSTR wszFile = NULL;
199 HRESULT hr;
200 int len;
202 TRACE("(%p,%s,0x%08X,%s)\n", ppfile, debugstr_a(szFile), uMode,
203 debugstr_guid(lpHandler));
205 /* check parameters */
206 if (ppfile == NULL || szFile == NULL)
207 return AVIERR_BADPARAM;
209 /* convert ASCII string to Unicode and call unicode function */
210 len = lstrlenA(szFile);
211 if (len <= 0)
212 return AVIERR_BADPARAM;
214 wszFile = (LPWSTR)LocalAlloc(LPTR, (len + 1) * sizeof(WCHAR));
215 if (wszFile == NULL)
216 return AVIERR_MEMORY;
218 MultiByteToWideChar(CP_ACP, 0, szFile, -1, wszFile, len + 1);
219 wszFile[len + 1] = 0;
221 hr = AVIFileOpenW(ppfile, wszFile, uMode, lpHandler);
223 LocalFree((HLOCAL)wszFile);
225 return hr;
228 /***********************************************************************
229 * AVIFileOpenW (AVIFIL32.@)
231 HRESULT WINAPI AVIFileOpenW(PAVIFILE *ppfile, LPCWSTR szFile, UINT uMode,
232 LPCLSID lpHandler)
234 IPersistFile *ppersist = NULL;
235 CLSID clsidHandler;
236 HRESULT hr;
238 TRACE("(%p,%s,0x%X,%s)\n", ppfile, debugstr_w(szFile), uMode,
239 debugstr_guid(lpHandler));
241 /* check parameters */
242 if (ppfile == NULL || szFile == NULL)
243 return AVIERR_BADPARAM;
245 *ppfile = NULL;
247 /* if no handler then try guessing it by extension */
248 if (lpHandler == NULL) {
249 if (! AVIFILE_GetFileHandlerByExtension(szFile, &clsidHandler))
250 return AVIERR_UNSUPPORTED;
251 } else
252 memcpy(&clsidHandler, lpHandler, sizeof(clsidHandler));
254 /* crete instance of handler */
255 hr = SHCoCreateInstance(NULL, &clsidHandler, NULL,
256 &IID_IAVIFile, (LPVOID*)ppfile);
257 if (FAILED(hr) || *ppfile == NULL)
258 return hr;
260 /* ask for IPersistFile interface for loading/creating the file */
261 hr = IAVIFile_QueryInterface(*ppfile, &IID_IPersistFile, (LPVOID*)&ppersist);
262 if (FAILED(hr) || ppersist == NULL) {
263 IAVIFile_Release(*ppfile);
264 *ppfile = NULL;
265 return hr;
268 hr = IPersistFile_Load(ppersist, szFile, uMode);
269 IPersistFile_Release(ppersist);
270 if (FAILED(hr)) {
271 IAVIFile_Release(*ppfile);
272 *ppfile = NULL;
275 return hr;
278 /***********************************************************************
279 * AVIFileAddRef (AVIFIL32.@)
280 * AVIFileAddRef (AVIFILE.140)
282 ULONG WINAPI AVIFileAddRef(PAVIFILE pfile)
284 TRACE("(%p)\n", pfile);
286 if (pfile == NULL) {
287 ERR(": bad handle passed!\n");
288 return 0;
291 return IAVIFile_AddRef(pfile);
294 /***********************************************************************
295 * AVIFileRelease (AVIFIL32.@)
296 * AVIFileRelease (AVIFILE.141)
298 ULONG WINAPI AVIFileRelease(PAVIFILE pfile)
300 TRACE("(%p)\n", pfile);
302 if (pfile == NULL) {
303 ERR(": bad handle passed!\n");
304 return 0;
307 return IAVIFile_Release(pfile);
310 /***********************************************************************
311 * AVIFileInfo (AVIFIL32.@)
312 * AVIFileInfoA (AVIFIL32.@)
313 * AVIFileInfo (AVIFILE.142)
315 HRESULT WINAPI AVIFileInfoA(PAVIFILE pfile, LPAVIFILEINFOA afi, LONG size)
317 AVIFILEINFOW afiw;
318 HRESULT hres;
320 TRACE("(%p,%p,%ld)\n", pfile, afi, size);
322 if (pfile == NULL)
323 return AVIERR_BADHANDLE;
324 if ((DWORD)size < sizeof(AVIFILEINFOA))
325 return AVIERR_BADSIZE;
327 hres = IAVIFile_Info(pfile, &afiw, sizeof(afiw));
329 memcpy(afi, &afiw, sizeof(*afi) - sizeof(afi->szFileType));
330 WideCharToMultiByte(CP_ACP, 0, afiw.szFileType, -1, afi->szFileType,
331 sizeof(afi->szFileType), NULL, NULL);
332 afi->szFileType[sizeof(afi->szFileType) - 1] = 0;
334 return hres;
337 /***********************************************************************
338 * AVIFileInfoW (AVIFIL32.@)
340 HRESULT WINAPI AVIFileInfoW(PAVIFILE pfile, LPAVIFILEINFOW afiw, LONG size)
342 TRACE("(%p,%p,%ld)\n", pfile, afiw, size);
344 if (pfile == NULL)
345 return AVIERR_BADHANDLE;
347 return IAVIFile_Info(pfile, afiw, size);
350 /***********************************************************************
351 * AVIFileGetStream (AVIFIL32.@)
352 * AVIFileGetStream (AVIFILE.143)
354 HRESULT WINAPI AVIFileGetStream(PAVIFILE pfile, PAVISTREAM *avis,
355 DWORD fccType, LONG lParam)
357 TRACE("(%p,%p,'%4.4s',%ld)\n", pfile, avis, (char*)&fccType, lParam);
359 if (pfile == NULL)
360 return AVIERR_BADHANDLE;
362 return IAVIFile_GetStream(pfile, avis, fccType, lParam);
365 /***********************************************************************
366 * AVIFileCreateStreamA (AVIFIL32.@)
367 * AVIFileCreateStream (AVIFILE.144)
369 HRESULT WINAPI AVIFileCreateStreamA(PAVIFILE pfile, PAVISTREAM *ppavi,
370 LPAVISTREAMINFOA psi)
372 AVISTREAMINFOW psiw;
374 TRACE("(%p,%p,%p)\n", pfile, ppavi, psi);
376 if (pfile == NULL)
377 return AVIERR_BADHANDLE;
379 /* Only the szName at the end is different */
380 memcpy(&psiw, psi, sizeof(*psi) - sizeof(psi->szName));
381 MultiByteToWideChar(CP_ACP, 0, psi->szName, -1, psiw.szName,
382 sizeof(psiw.szName) / sizeof(psiw.szName[0]));
384 return IAVIFile_CreateStream(pfile, ppavi, &psiw);
387 /***********************************************************************
388 * AVIFileCreateStreamW (AVIFIL32.@)
390 HRESULT WINAPI AVIFileCreateStreamW(PAVIFILE pfile, PAVISTREAM *avis,
391 LPAVISTREAMINFOW asi)
393 TRACE("(%p,%p,%p)\n", pfile, avis, asi);
395 return IAVIFile_CreateStream(pfile, avis, asi);
398 /***********************************************************************
399 * AVIFileWriteData (AVIFIL32.@)
400 * AVIFileWriteData (AVIFILE.146)
402 HRESULT WINAPI AVIFileWriteData(PAVIFILE pfile,DWORD fcc,LPVOID lp,LONG size)
404 TRACE("(%p,'%4.4s',%p,%ld)\n", pfile, (char*)&fcc, lp, size);
406 if (pfile == NULL)
407 return AVIERR_BADHANDLE;
409 return IAVIFile_WriteData(pfile, fcc, lp, size);
412 /***********************************************************************
413 * AVIFileReadData (AVIFIL32.@)
414 * AVIFileReadData (AVIFILE.147)
416 HRESULT WINAPI AVIFileReadData(PAVIFILE pfile,DWORD fcc,LPVOID lp,LPLONG size)
418 TRACE("(%p,'%4.4s',%p,%p)\n", pfile, (char*)&fcc, lp, size);
420 if (pfile == NULL)
421 return AVIERR_BADHANDLE;
423 return IAVIFile_ReadData(pfile, fcc, lp, size);
426 /***********************************************************************
427 * AVIFileEndRecord (AVIFIL32.@)
428 * AVIFileEndRecord (AVIFILE.148)
430 HRESULT WINAPI AVIFileEndRecord(PAVIFILE pfile)
432 TRACE("(%p)\n", pfile);
434 if (pfile == NULL)
435 return AVIERR_BADHANDLE;
437 return IAVIFile_EndRecord(pfile);
440 /***********************************************************************
441 * AVIStreamAddRef (AVIFIL32.@)
442 * AVIStreamAddRef (AVIFILE.160)
444 ULONG WINAPI AVIStreamAddRef(PAVISTREAM pstream)
446 TRACE("(%p)\n", pstream);
448 if (pstream == NULL) {
449 ERR(": bad handle passed!\n");
450 return 0;
453 return IAVIStream_AddRef(pstream);
456 /***********************************************************************
457 * AVIStreamRelease (AVIFIL32.@)
458 * AVIStreamRelease (AVIFILE.161)
460 ULONG WINAPI AVIStreamRelease(PAVISTREAM pstream)
462 TRACE("(%p)\n", pstream);
464 if (pstream == NULL) {
465 ERR(": bad handle passed!\n");
466 return 0;
469 return IAVIStream_Release(pstream);
472 /***********************************************************************
473 * AVIStreamCreate (AVIFIL32.@)
474 * AVIStreamCreate (AVIFILE.104)
476 HRESULT WINAPI AVIStreamCreate(PAVISTREAM *ppavi, LONG lParam1, LONG lParam2,
477 LPCLSID pclsidHandler)
479 HRESULT hr;
481 TRACE("(%p,0x%08lX,0x%08lX,%s)\n", ppavi, lParam1, lParam2,
482 debugstr_guid(pclsidHandler));
484 if (ppavi == NULL)
485 return AVIERR_BADPARAM;
487 *ppavi = NULL;
488 if (pclsidHandler == NULL)
489 return AVIERR_UNSUPPORTED;
491 hr = SHCoCreateInstance(NULL, pclsidHandler, NULL,
492 &IID_IAVIStream, (LPVOID*)ppavi);
493 if (FAILED(hr) || *ppavi == NULL)
494 return hr;
496 hr = IAVIStream_Create(*ppavi, lParam1, lParam2);
497 if (FAILED(hr)) {
498 IAVIStream_Release(*ppavi);
499 *ppavi = NULL;
502 return hr;
505 /***********************************************************************
506 * AVIStreamInfoA (AVIFIL32.@)
507 * AVIStreamInfo (AVIFILE.162)
509 HRESULT WINAPI AVIStreamInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi,
510 LONG size)
512 AVISTREAMINFOW asiw;
513 HRESULT hres;
515 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
517 if (pstream == NULL)
518 return AVIERR_BADHANDLE;
519 if ((DWORD)size < sizeof(AVISTREAMINFOA))
520 return AVIERR_BADSIZE;
522 hres = IAVIStream_Info(pstream, &asiw, sizeof(asiw));
524 memcpy(asi, &asiw, sizeof(asiw) - sizeof(asiw.szName));
525 WideCharToMultiByte(CP_ACP, 0, asiw.szName, -1, asi->szName,
526 sizeof(asi->szName), NULL, NULL);
527 asi->szName[sizeof(asi->szName) - 1] = 0;
529 return hres;
532 /***********************************************************************
533 * AVIStreamInfoW (AVIFIL32.@)
535 HRESULT WINAPI AVIStreamInfoW(PAVISTREAM pstream, LPAVISTREAMINFOW asi,
536 LONG size)
538 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
540 if (pstream == NULL)
541 return AVIERR_BADHANDLE;
543 return IAVIStream_Info(pstream, asi, size);
546 /***********************************************************************
547 * AVIStreamFindSample (AVIFIL32.@)
548 * AVIStreamFindSample (AVIFILE.163)
550 HRESULT WINAPI AVIStreamFindSample(PAVISTREAM pstream, LONG pos, DWORD flags)
552 TRACE("(%p,%ld,0x%lX)\n", pstream, pos, flags);
554 if (pstream == NULL)
555 return -1;
557 return IAVIStream_FindSample(pstream, pos, flags);
560 /***********************************************************************
561 * AVIStreamReadFormat (AVIFIL32.@)
562 * AVIStreamReadFormat (AVIFILE.164)
564 HRESULT WINAPI AVIStreamReadFormat(PAVISTREAM pstream, LONG pos,
565 LPVOID format, LPLONG formatsize)
567 TRACE("(%p,%ld,%p,%p)\n", pstream, pos, format, formatsize);
569 if (pstream == NULL)
570 return AVIERR_BADHANDLE;
572 return IAVIStream_ReadFormat(pstream, pos, format, formatsize);
575 /***********************************************************************
576 * AVIStreamSetFormat (AVIFIL32.@)
577 * AVIStreamSetFormat (AVIFILE.169)
579 HRESULT WINAPI AVIStreamSetFormat(PAVISTREAM pstream, LONG pos,
580 LPVOID format, LONG formatsize)
582 TRACE("(%p,%ld,%p,%ld)\n", pstream, pos, format, formatsize);
584 if (pstream == NULL)
585 return AVIERR_BADHANDLE;
587 return IAVIStream_SetFormat(pstream, pos, format, formatsize);
590 /***********************************************************************
591 * AVIStreamRead (AVIFIL32.@)
592 * AVIStreamRead (AVIFILE.167)
594 HRESULT WINAPI AVIStreamRead(PAVISTREAM pstream, LONG start, LONG samples,
595 LPVOID buffer, LONG buffersize,
596 LPLONG bytesread, LPLONG samplesread)
598 TRACE("(%p,%ld,%ld,%p,%ld,%p,%p)\n", pstream, start, samples, buffer,
599 buffersize, bytesread, samplesread);
601 if (pstream == NULL)
602 return AVIERR_BADHANDLE;
604 return IAVIStream_Read(pstream, start, samples, buffer, buffersize,
605 bytesread, samplesread);
608 /***********************************************************************
609 * AVIStreamWrite (AVIFIL32.@)
610 * AVIStreamWrite (AVIFILE.168)
612 HRESULT WINAPI AVIStreamWrite(PAVISTREAM pstream, LONG start, LONG samples,
613 LPVOID buffer, LONG buffersize, DWORD flags,
614 LPLONG sampwritten, LPLONG byteswritten)
616 TRACE("(%p,%ld,%ld,%p,%ld,0x%lX,%p,%p)\n", pstream, start, samples, buffer,
617 buffersize, flags, sampwritten, byteswritten);
619 if (pstream == NULL)
620 return AVIERR_BADHANDLE;
622 return IAVIStream_Write(pstream, start, samples, buffer, buffersize,
623 flags, sampwritten, byteswritten);
626 /***********************************************************************
627 * AVIStreamReadData (AVIFIL32.@)
628 * AVIStreamReadData (AVIFILE.165)
630 HRESULT WINAPI AVIStreamReadData(PAVISTREAM pstream, DWORD fcc, LPVOID lp,
631 LPLONG lpread)
633 TRACE("(%p,'%4.4s',%p,%p)\n", pstream, (char*)&fcc, lp, lpread);
635 if (pstream == NULL)
636 return AVIERR_BADHANDLE;
638 return IAVIStream_ReadData(pstream, fcc, lp, lpread);
641 /***********************************************************************
642 * AVIStreamWriteData (AVIFIL32.@)
643 * AVIStreamWriteData (AVIFILE.166)
645 HRESULT WINAPI AVIStreamWriteData(PAVISTREAM pstream, DWORD fcc, LPVOID lp,
646 LONG size)
648 TRACE("(%p,'%4.4s',%p,%ld)\n", pstream, (char*)&fcc, lp, size);
650 if (pstream == NULL)
651 return AVIERR_BADHANDLE;
653 return IAVIStream_WriteData(pstream, fcc, lp, size);
656 /***********************************************************************
657 * AVIStreamGetFrameOpen (AVIFIL32.@)
658 * AVIStreamGetFrameOpen (AVIFILE.112)
660 PGETFRAME WINAPI AVIStreamGetFrameOpen(PAVISTREAM pstream,
661 LPBITMAPINFOHEADER lpbiWanted)
663 PGETFRAME pg = NULL;
665 TRACE("(%p,%p)\n", pstream, lpbiWanted);
667 if (FAILED(IAVIStream_QueryInterface(pstream, &IID_IGetFrame, (LPVOID*)&pg)) ||
668 pg == NULL) {
669 pg = AVIFILE_CreateGetFrame(pstream);
670 if (pg == NULL)
671 return NULL;
674 if (FAILED(IGetFrame_SetFormat(pg, lpbiWanted, NULL, 0, 0, -1, -1))) {
675 IGetFrame_Release(pg);
676 return NULL;
679 return pg;
682 /***********************************************************************
683 * AVIStreamGetFrame (AVIFIL32.@)
684 * AVIStreamGetFrame (AVIFILE.110)
686 LPVOID WINAPI AVIStreamGetFrame(PGETFRAME pg, LONG pos)
688 TRACE("(%p,%ld)\n", pg, pos);
690 if (pg == NULL)
691 return NULL;
693 return IGetFrame_GetFrame(pg, pos);
696 /***********************************************************************
697 * AVIStreamGetFrameClose (AVIFIL32.@)
698 * AVIStreamGetFrameClose (AVIFILE.111)
700 HRESULT WINAPI AVIStreamGetFrameClose(PGETFRAME pg)
702 TRACE("(%p)\n", pg);
704 if (pg != NULL)
705 return IGetFrame_Release(pg);
706 return 0;
709 /***********************************************************************
710 * AVIMakeCompressedStream (AVIFIL32.@)
712 HRESULT WINAPI AVIMakeCompressedStream(PAVISTREAM *ppsCompressed,
713 PAVISTREAM psSource,
714 LPAVICOMPRESSOPTIONS aco,
715 LPCLSID pclsidHandler)
717 AVISTREAMINFOW asiw;
718 CHAR szRegKey[25];
719 CHAR szValue[100];
720 CLSID clsidHandler;
721 HRESULT hr;
722 LONG size = sizeof(szValue);
724 TRACE("(%p,%p,%p,%s)\n", ppsCompressed, psSource, aco,
725 debugstr_guid(pclsidHandler));
727 if (ppsCompressed == NULL)
728 return AVIERR_BADPARAM;
729 if (psSource == NULL)
730 return AVIERR_BADHANDLE;
732 *ppsCompressed = NULL;
734 /* if no handler given get default ones based on streamtype */
735 if (pclsidHandler == NULL) {
736 hr = IAVIStream_Info(psSource, &asiw, sizeof(asiw));
737 if (FAILED(hr))
738 return hr;
740 wsprintfA(szRegKey, "AVIFile\\Compressors\\%4.4s", (char*)&asiw.fccType);
741 if (RegQueryValueA(HKEY_CLASSES_ROOT, szRegKey, szValue, &size) != ERROR_SUCCESS)
742 return AVIERR_UNSUPPORTED;
743 if (AVIFILE_CLSIDFromString(szValue, &clsidHandler) != S_OK)
744 return AVIERR_UNSUPPORTED;
745 } else
746 memcpy(&clsidHandler, pclsidHandler, sizeof(clsidHandler));
748 hr = SHCoCreateInstance(NULL, &clsidHandler, NULL,
749 &IID_IAVIStream, (LPVOID*)ppsCompressed);
750 if (FAILED(hr) || *ppsCompressed == NULL)
751 return hr;
753 hr = IAVIStream_Create(*ppsCompressed, (LPARAM)psSource, (LPARAM)aco);
754 if (FAILED(hr)) {
755 IAVIStream_Release(*ppsCompressed);
756 *ppsCompressed = NULL;
759 return hr;
762 /***********************************************************************
763 * AVIMakeFileFromStreams (AVIFIL32.@)
765 HRESULT WINAPI AVIMakeFileFromStreams(PAVIFILE *ppfile, int nStreams,
766 PAVISTREAM *ppStreams)
768 TRACE("(%p,%d,%p)\n", ppfile, nStreams, ppStreams);
770 if (nStreams < 0 || ppfile == NULL || ppStreams == NULL)
771 return AVIERR_BADPARAM;
773 *ppfile = AVIFILE_CreateAVITempFile(nStreams, ppStreams);
774 if (*ppfile == NULL)
775 return AVIERR_MEMORY;
777 return AVIERR_OK;
780 /***********************************************************************
781 * AVIStreamOpenFromFile (AVIFILE.103)
782 * AVIStreamOpenFromFileA (AVIFIL32.@)
784 HRESULT WINAPI AVIStreamOpenFromFileA(PAVISTREAM *ppavi, LPCSTR szFile,
785 DWORD fccType, LONG lParam,
786 UINT mode, LPCLSID pclsidHandler)
788 PAVIFILE pfile = NULL;
789 HRESULT hr;
791 TRACE("(%p,%s,'%4.4s',%ld,0x%X,%s)\n", ppavi, debugstr_a(szFile),
792 (char*)&fccType, lParam, mode, debugstr_guid(pclsidHandler));
794 if (ppavi == NULL || szFile == NULL)
795 return AVIERR_BADPARAM;
797 *ppavi = NULL;
799 hr = AVIFileOpenA(&pfile, szFile, mode, pclsidHandler);
800 if (FAILED(hr) || pfile == NULL)
801 return hr;
803 hr = IAVIFile_GetStream(pfile, ppavi, fccType, lParam);
804 IAVIFile_Release(pfile);
806 return hr;
809 /***********************************************************************
810 * AVIStreamOpenFromFileW (AVIFIL32.@)
812 HRESULT WINAPI AVIStreamOpenFromFileW(PAVISTREAM *ppavi, LPCWSTR szFile,
813 DWORD fccType, LONG lParam,
814 UINT mode, LPCLSID pclsidHandler)
816 PAVIFILE pfile = NULL;
817 HRESULT hr;
819 TRACE("(%p,%s,'%4.4s',%ld,0x%X,%s)\n", ppavi, debugstr_w(szFile),
820 (char*)&fccType, lParam, mode, debugstr_guid(pclsidHandler));
822 if (ppavi == NULL || szFile == NULL)
823 return AVIERR_BADPARAM;
825 *ppavi = NULL;
827 hr = AVIFileOpenW(&pfile, szFile, mode, pclsidHandler);
828 if (FAILED(hr) || pfile == NULL)
829 return hr;
831 hr = IAVIFile_GetStream(pfile, ppavi, fccType, lParam);
832 IAVIFile_Release(pfile);
834 return hr;
837 /***********************************************************************
838 * AVIStreamStart (AVIFILE.130)
839 * AVIStreamStart (AVIFIL32.@)
841 LONG WINAPI AVIStreamStart(PAVISTREAM pstream)
843 AVISTREAMINFOW asiw;
845 TRACE("(%p)\n", pstream);
847 if (pstream == NULL)
848 return 0;
850 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
851 return 0;
853 return asiw.dwStart;
856 /***********************************************************************
857 * AVIStreamLength (AVIFILE.131)
858 * AVIStreamLength (AVIFIL32.@)
860 LONG WINAPI AVIStreamLength(PAVISTREAM pstream)
862 AVISTREAMINFOW asiw;
864 TRACE("(%p)\n", pstream);
866 if (pstream == NULL)
867 return 0;
869 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
870 return 0;
872 return asiw.dwLength;
875 /***********************************************************************
876 * AVIStreamSampleToTime (AVIFILE.133)
877 * AVIStreamSampleToTime (AVIFIL32.@)
879 LONG WINAPI AVIStreamSampleToTime(PAVISTREAM pstream, LONG lSample)
881 AVISTREAMINFOW asiw;
883 TRACE("(%p,%ld)\n", pstream, lSample);
885 if (pstream == NULL)
886 return -1;
888 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
889 return -1;
890 if (asiw.dwRate == 0)
891 return -1;
893 return (LONG)(((float)lSample * asiw.dwScale * 1000.0) / asiw.dwRate);
896 /***********************************************************************
897 * AVIStreamTimeToSample (AVIFILE.132)
898 * AVIStreamTimeToSample (AVIFIL32.@)
900 LONG WINAPI AVIStreamTimeToSample(PAVISTREAM pstream, LONG lTime)
902 AVISTREAMINFOW asiw;
904 TRACE("(%p,%ld)\n", pstream, lTime);
906 if (pstream == NULL)
907 return -1;
909 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
910 return -1;
911 if (asiw.dwScale == 0)
912 return -1;
914 return (LONG)(((float)lTime * asiw.dwRate) / asiw.dwScale / 1000.0);
917 /***********************************************************************
918 * AVIBuildFilterA (AVIFIL32.@)
919 * AVIBuildFilter (AVIFILE.123)
921 HRESULT WINAPI AVIBuildFilterA(LPSTR szFilter, LONG cbFilter, BOOL fSaving)
923 LPWSTR wszFilter;
924 HRESULT hr;
926 TRACE("(%p,%ld,%d)\n", szFilter, cbFilter, fSaving);
928 /* check parameters */
929 if (szFilter == NULL)
930 return AVIERR_BADPARAM;
931 if (cbFilter < 2)
932 return AVIERR_BADSIZE;
934 szFilter[0] = 0;
935 szFilter[1] = 0;
937 wszFilter = (LPWSTR)GlobalAllocPtr(GHND, cbFilter);
938 if (wszFilter == NULL)
939 return AVIERR_MEMORY;
941 hr = AVIBuildFilterW(wszFilter, cbFilter, fSaving);
942 if (SUCCEEDED(hr)) {
943 WideCharToMultiByte(CP_ACP, 0, wszFilter, cbFilter,
944 szFilter, cbFilter, NULL, NULL);
947 GlobalFreePtr(wszFilter);
949 return hr;
952 /***********************************************************************
953 * AVIBuildFilterW (AVIFIL32.@)
955 HRESULT WINAPI AVIBuildFilterW(LPWSTR szFilter, LONG cbFilter, BOOL fSaving)
957 static const WCHAR szClsid[] = {'C','L','S','I','D',0};
958 static const WCHAR szExtensionFmt[] = {';','*','.','%','s',0};
959 static const WCHAR szAVIFileExtensions[] =
960 {'A','V','I','F','i','l','e','\\','E','x','t','e','n','s','i','o','n','s',0};
962 AVIFilter *lp;
963 WCHAR szAllFiles[40];
964 WCHAR szFileExt[10];
965 WCHAR szValue[128];
966 HKEY hKey;
967 DWORD n, i;
968 LONG size;
969 DWORD count = 0;
971 TRACE("(%p,%ld,%d)\n", szFilter, cbFilter, fSaving);
973 /* check parameters */
974 if (szFilter == NULL)
975 return AVIERR_BADPARAM;
976 if (cbFilter < 2)
977 return AVIERR_BADSIZE;
979 lp = (AVIFilter*)GlobalAllocPtr(GHND, MAX_FILTERS * sizeof(AVIFilter));
980 if (lp == NULL)
981 return AVIERR_MEMORY;
984 * 1. iterate over HKEY_CLASSES_ROOT\\AVIFile\\Extensions and collect
985 * extensions and CLSID's
986 * 2. iterate over collected CLSID's and copy it's description and it's
987 * extensions to szFilter if it fits
989 * First filter is named "All multimedia files" and it's filter is a
990 * collection of all possible extensions except "*.*".
992 if (RegOpenKeyW(HKEY_CLASSES_ROOT, szAVIFileExtensions, &hKey) != S_OK) {
993 GlobalFreePtr(lp);
994 return AVIERR_ERROR;
996 for (n = 0;RegEnumKeyW(hKey, n, szFileExt, sizeof(szFileExt)) == S_OK;n++) {
997 /* get CLSID to extension */
998 size = sizeof(szValue)/sizeof(szValue[0]);
999 if (RegQueryValueW(hKey, szFileExt, szValue, &size) != S_OK)
1000 break;
1002 /* search if the CLSID is already known */
1003 for (i = 1; i <= count; i++) {
1004 if (lstrcmpW(lp[i].szClsid, szValue) == 0)
1005 break; /* a new one */
1008 if (count - i == -1U) {
1009 /* it's a new CLSID */
1011 /* FIXME: How do we get info's about read/write capabilities? */
1013 if (count >= MAX_FILTERS) {
1014 /* try to inform user of our full fixed size table */
1015 ERR(": More than %d filters found! Adjust MAX_FILTERS in dlls/avifil32/api.c\n", MAX_FILTERS);
1016 break;
1019 lstrcpyW(lp[i].szClsid, szValue);
1021 count++;
1024 /* append extension to the filter */
1025 wsprintfW(szValue, szExtensionFmt, szFileExt);
1026 if (lp[i].szExtensions[0] == 0)
1027 lstrcatW(lp[i].szExtensions, szValue + 1);
1028 else
1029 lstrcatW(lp[i].szExtensions, szValue);
1031 /* also append to the "all multimedia"-filter */
1032 if (lp[0].szExtensions[0] == 0)
1033 lstrcatW(lp[0].szExtensions, szValue + 1);
1034 else
1035 lstrcatW(lp[0].szExtensions, szValue);
1037 RegCloseKey(hKey);
1039 /* 2. get descriptions for the CLSIDs and fill out szFilter */
1040 if (RegOpenKeyW(HKEY_CLASSES_ROOT, szClsid, &hKey) != S_OK) {
1041 GlobalFreePtr(lp);
1042 return AVIERR_ERROR;
1044 for (n = 0; n <= count; n++) {
1045 /* first the description */
1046 if (n != 0) {
1047 size = sizeof(szValue)/sizeof(szValue[0]);
1048 if (RegQueryValueW(hKey, lp[n].szClsid, szValue, &size) == S_OK) {
1049 size = lstrlenW(szValue);
1050 lstrcpynW(szFilter, szValue, cbFilter);
1052 } else
1053 size = LoadStringW(AVIFILE_hModule,IDS_ALLMULTIMEDIA,szFilter,cbFilter);
1055 /* check for enough space */
1056 size++;
1057 if (cbFilter < size + lstrlenW(lp[n].szExtensions) + 2) {
1058 szFilter[0] = 0;
1059 szFilter[1] = 0;
1060 GlobalFreePtr(lp);
1061 RegCloseKey(hKey);
1062 return AVIERR_BUFFERTOOSMALL;
1064 cbFilter -= size;
1065 szFilter += size;
1067 /* and then the filter */
1068 lstrcpynW(szFilter, lp[n].szExtensions, cbFilter);
1069 size = lstrlenW(lp[n].szExtensions) + 1;
1070 cbFilter -= size;
1071 szFilter += size;
1074 RegCloseKey(hKey);
1075 GlobalFreePtr(lp);
1077 /* add "All files" "*.*" filter if enough space left */
1078 size = LoadStringW(AVIFILE_hModule, IDS_ALLFILES,
1079 szAllFiles, sizeof(szAllFiles)) + 1;
1080 if (cbFilter > size) {
1081 int i;
1083 /* replace '@' with \000 to separate description of filter */
1084 for (i = 0; i < size && szAllFiles[i] != 0; i++) {
1085 if (szAllFiles[i] == '@') {
1086 szAllFiles[i] = 0;
1087 break;
1091 memcpy(szFilter, szAllFiles, size * sizeof(szAllFiles[0]));
1092 szFilter += size;
1093 szFilter[0] = 0;
1095 return AVIERR_OK;
1096 } else {
1097 szFilter[0] = 0;
1098 return AVIERR_BUFFERTOOSMALL;
1102 static BOOL AVISaveOptionsFmtChoose(HWND hWnd)
1104 LPAVICOMPRESSOPTIONS pOptions = SaveOpts.ppOptions[SaveOpts.nCurrent];
1105 AVISTREAMINFOW sInfo;
1107 TRACE("(%p)\n", hWnd);
1109 if (pOptions == NULL || SaveOpts.ppavis[SaveOpts.nCurrent] == NULL) {
1110 ERR(": bad state!\n");
1111 return FALSE;
1114 if (FAILED(AVIStreamInfoW(SaveOpts.ppavis[SaveOpts.nCurrent],
1115 &sInfo, sizeof(sInfo)))) {
1116 ERR(": AVIStreamInfoW failed!\n");
1117 return FALSE;
1120 if (sInfo.fccType == streamtypeVIDEO) {
1121 COMPVARS cv;
1122 BOOL ret;
1124 memset(&cv, 0, sizeof(cv));
1126 if ((pOptions->dwFlags & AVICOMPRESSF_VALID) == 0) {
1127 memset(pOptions, 0, sizeof(AVICOMPRESSOPTIONS));
1128 pOptions->fccType = streamtypeVIDEO;
1129 pOptions->fccHandler = comptypeDIB;
1130 pOptions->dwQuality = (DWORD)ICQUALITY_DEFAULT;
1133 cv.cbSize = sizeof(cv);
1134 cv.dwFlags = ICMF_COMPVARS_VALID;
1135 /*cv.fccType = pOptions->fccType; */
1136 cv.fccHandler = pOptions->fccHandler;
1137 cv.lQ = pOptions->dwQuality;
1138 cv.lpState = pOptions->lpParms;
1139 cv.cbState = pOptions->cbParms;
1140 if (pOptions->dwFlags & AVICOMPRESSF_KEYFRAMES)
1141 cv.lKey = pOptions->dwKeyFrameEvery;
1142 else
1143 cv.lKey = 0;
1144 if (pOptions->dwFlags & AVICOMPRESSF_DATARATE)
1145 cv.lDataRate = pOptions->dwBytesPerSecond / 1024; /* need kBytes */
1146 else
1147 cv.lDataRate = 0;
1149 ret = ICCompressorChoose(hWnd, SaveOpts.uFlags, NULL,
1150 SaveOpts.ppavis[SaveOpts.nCurrent], &cv, NULL);
1152 if (ret) {
1153 pOptions->fccHandler = cv.fccHandler;
1154 pOptions->lpParms = cv.lpState;
1155 pOptions->cbParms = cv.cbState;
1156 pOptions->dwQuality = cv.lQ;
1157 if (cv.lKey != 0) {
1158 pOptions->dwKeyFrameEvery = cv.lKey;
1159 pOptions->dwFlags |= AVICOMPRESSF_KEYFRAMES;
1160 } else
1161 pOptions->dwFlags &= ~AVICOMPRESSF_KEYFRAMES;
1162 if (cv.lDataRate != 0) {
1163 pOptions->dwBytesPerSecond = cv.lDataRate * 1024; /* need bytes */
1164 pOptions->dwFlags |= AVICOMPRESSF_DATARATE;
1165 } else
1166 pOptions->dwFlags &= ~AVICOMPRESSF_DATARATE;
1167 pOptions->dwFlags |= AVICOMPRESSF_VALID;
1169 ICCompressorFree(&cv);
1171 return ret;
1172 } else if (sInfo.fccType == streamtypeAUDIO) {
1173 ACMFORMATCHOOSEW afmtc;
1174 MMRESULT ret;
1175 LONG size;
1177 /* FIXME: check ACM version -- Which version is needed? */
1179 memset(&afmtc, 0, sizeof(afmtc));
1180 afmtc.cbStruct = sizeof(afmtc);
1181 afmtc.fdwStyle = 0;
1182 afmtc.hwndOwner = hWnd;
1184 acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, &size);
1185 if ((pOptions->cbFormat == 0 || pOptions->lpFormat == NULL) && size != 0) {
1186 pOptions->lpFormat = GlobalAllocPtr(GMEM_MOVEABLE, size);
1187 pOptions->cbFormat = size;
1188 } else if (pOptions->cbFormat < (DWORD)size) {
1189 pOptions->lpFormat = GlobalReAllocPtr(pOptions->lpFormat, size, GMEM_MOVEABLE);
1190 pOptions->cbFormat = size;
1192 if (pOptions->lpFormat == NULL)
1193 return FALSE;
1194 afmtc.pwfx = pOptions->lpFormat;
1195 afmtc.cbwfx = pOptions->cbFormat;
1197 size = 0;
1198 AVIStreamFormatSize(SaveOpts.ppavis[SaveOpts.nCurrent],
1199 sInfo.dwStart, &size);
1200 if (size < (LONG)sizeof(PCMWAVEFORMAT))
1201 size = sizeof(PCMWAVEFORMAT);
1202 afmtc.pwfxEnum = GlobalAllocPtr(GHND, size);
1203 if (afmtc.pwfxEnum != NULL) {
1204 AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent],
1205 sInfo.dwStart, afmtc.pwfxEnum, &size);
1206 afmtc.fdwEnum = ACM_FORMATENUMF_CONVERT;
1209 ret = acmFormatChooseW(&afmtc);
1210 if (ret == S_OK)
1211 pOptions->dwFlags |= AVICOMPRESSF_VALID;
1213 if (afmtc.pwfxEnum != NULL)
1214 GlobalFreePtr(afmtc.pwfxEnum);
1216 return (ret == S_OK ? TRUE : FALSE);
1217 } else {
1218 ERR(": unknown streamtype 0x%08lX\n", sInfo.fccType);
1219 return FALSE;
1223 static void AVISaveOptionsUpdate(HWND hWnd)
1225 static const WCHAR szVideoFmt[]={'%','l','d','x','%','l','d','x','%','d',0};
1226 static const WCHAR szAudioFmt[]={'%','s',' ','%','s',0};
1228 WCHAR szFormat[128];
1229 AVISTREAMINFOW sInfo;
1230 LPVOID lpFormat;
1231 LONG size;
1233 TRACE("(%p)\n", hWnd);
1235 SaveOpts.nCurrent = SendDlgItemMessageW(hWnd,IDC_STREAM,CB_GETCURSEL,0,0);
1236 if (SaveOpts.nCurrent < 0)
1237 return;
1239 if (FAILED(AVIStreamInfoW(SaveOpts.ppavis[SaveOpts.nCurrent], &sInfo, sizeof(sInfo))))
1240 return;
1242 AVIStreamFormatSize(SaveOpts.ppavis[SaveOpts.nCurrent],sInfo.dwStart,&size);
1243 if (size > 0) {
1244 szFormat[0] = 0;
1246 /* read format to build format descriotion string */
1247 lpFormat = GlobalAllocPtr(GHND, size);
1248 if (lpFormat != NULL) {
1249 if (SUCCEEDED(AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent],sInfo.dwStart,lpFormat, &size))) {
1250 if (sInfo.fccType == streamtypeVIDEO) {
1251 LPBITMAPINFOHEADER lpbi = lpFormat;
1252 ICINFO icinfo;
1254 wsprintfW(szFormat, szVideoFmt, lpbi->biWidth,
1255 lpbi->biHeight, lpbi->biBitCount);
1257 if (lpbi->biCompression != BI_RGB) {
1258 HIC hic;
1260 hic = ICLocate(ICTYPE_VIDEO, sInfo.fccHandler, lpFormat,
1261 NULL, ICMODE_DECOMPRESS);
1262 if (hic != NULL) {
1263 if (ICGetInfo(hic, &icinfo, sizeof(icinfo)) == S_OK)
1264 lstrcatW(szFormat, icinfo.szDescription);
1265 ICClose(hic);
1267 } else {
1268 LoadStringW(AVIFILE_hModule, IDS_UNCOMPRESSED,
1269 icinfo.szDescription, sizeof(icinfo.szDescription));
1270 lstrcatW(szFormat, icinfo.szDescription);
1272 } else if (sInfo.fccType == streamtypeAUDIO) {
1273 ACMFORMATTAGDETAILSW aftd;
1274 ACMFORMATDETAILSW afd;
1276 memset(&aftd, 0, sizeof(aftd));
1277 memset(&afd, 0, sizeof(afd));
1279 aftd.cbStruct = sizeof(aftd);
1280 aftd.dwFormatTag = afd.dwFormatTag =
1281 ((PWAVEFORMATEX)lpFormat)->wFormatTag;
1282 aftd.cbFormatSize = afd.cbwfx = size;
1284 afd.cbStruct = sizeof(afd);
1285 afd.pwfx = lpFormat;
1287 if (acmFormatTagDetailsW(NULL, &aftd,
1288 ACM_FORMATTAGDETAILSF_FORMATTAG) == S_OK) {
1289 if (acmFormatDetailsW(NULL,&afd,ACM_FORMATDETAILSF_FORMAT) == S_OK)
1290 wsprintfW(szFormat, szAudioFmt, afd.szFormat, aftd.szFormatTag);
1294 GlobalFreePtr(lpFormat);
1297 /* set text for format description */
1298 SetDlgItemTextW(hWnd, IDC_FORMATTEXT, szFormat);
1300 /* Disable option button for unsupported streamtypes */
1301 if (sInfo.fccType == streamtypeVIDEO ||
1302 sInfo.fccType == streamtypeAUDIO)
1303 EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), TRUE);
1304 else
1305 EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), FALSE);
1310 INT_PTR CALLBACK AVISaveOptionsDlgProc(HWND hWnd, UINT uMsg,
1311 WPARAM wParam, LPARAM lParam)
1313 DWORD dwInterleave;
1314 BOOL bIsInterleaved;
1315 INT n;
1317 /*TRACE("(%p,%u,0x%04X,0x%08lX)\n", hWnd, uMsg, wParam, lParam);*/
1319 switch (uMsg) {
1320 case WM_INITDIALOG:
1321 SaveOpts.nCurrent = 0;
1322 if (SaveOpts.nStreams == 1) {
1323 EndDialog(hWnd, AVISaveOptionsFmtChoose(hWnd));
1324 return TRUE;
1327 /* add streams */
1328 for (n = 0; n < SaveOpts.nStreams; n++) {
1329 AVISTREAMINFOW sInfo;
1331 AVIStreamInfoW(SaveOpts.ppavis[n], &sInfo, sizeof(sInfo));
1332 SendDlgItemMessageW(hWnd, IDC_STREAM, CB_ADDSTRING,
1333 0L, (LPARAM)sInfo.szName);
1336 /* select first stream */
1337 SendDlgItemMessageW(hWnd, IDC_STREAM, CB_SETCURSEL, 0, 0);
1338 SendMessageW(hWnd, WM_COMMAND,
1339 GET_WM_COMMAND_MPS(IDC_STREAM, hWnd, CBN_SELCHANGE));
1341 /* initialize interleave */
1342 if (SaveOpts.ppOptions[0] != NULL &&
1343 (SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_VALID)) {
1344 bIsInterleaved = (SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_INTERLEAVE);
1345 dwInterleave = SaveOpts.ppOptions[0]->dwInterleaveEvery;
1346 } else {
1347 bIsInterleaved = TRUE;
1348 dwInterleave = 0;
1350 CheckDlgButton(hWnd, IDC_INTERLEAVE, bIsInterleaved);
1351 SetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, dwInterleave, FALSE);
1352 EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY), bIsInterleaved);
1353 break;
1354 case WM_COMMAND:
1355 switch (GET_WM_COMMAND_ID(wParam, lParam)) {
1356 case IDOK:
1357 /* get data from controls and save them */
1358 dwInterleave = GetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, NULL, 0);
1359 bIsInterleaved = IsDlgButtonChecked(hWnd, IDC_INTERLEAVE);
1360 for (n = 0; n < SaveOpts.nStreams; n++) {
1361 if (SaveOpts.ppOptions[n] != NULL) {
1362 if (bIsInterleaved) {
1363 SaveOpts.ppOptions[n]->dwFlags |= AVICOMPRESSF_INTERLEAVE;
1364 SaveOpts.ppOptions[n]->dwInterleaveEvery = dwInterleave;
1365 } else
1366 SaveOpts.ppOptions[n]->dwFlags &= ~AVICOMPRESSF_INTERLEAVE;
1369 /* fall through */
1370 case IDCANCEL:
1371 EndDialog(hWnd, GET_WM_COMMAND_CMD(wParam, lParam) == IDOK);
1372 break;
1373 case IDC_INTERLEAVE:
1374 EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY),
1375 IsDlgButtonChecked(hWnd, IDC_INTERLEAVE));
1376 break;
1377 case IDC_STREAM:
1378 if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE) {
1379 /* update control elements */
1380 AVISaveOptionsUpdate(hWnd);
1382 break;
1383 case IDC_OPTIONS:
1384 AVISaveOptionsFmtChoose(hWnd);
1385 break;
1387 return TRUE;
1390 return FALSE;
1393 /***********************************************************************
1394 * AVISaveOptions (AVIFIL32.@)
1396 BOOL WINAPI AVISaveOptions(HWND hWnd, UINT uFlags, INT nStreams,
1397 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *ppOptions)
1399 LPAVICOMPRESSOPTIONS pSavedOptions = NULL;
1400 INT ret, n;
1402 TRACE("(%p,0x%X,%d,%p,%p)\n", hWnd, uFlags, nStreams,
1403 ppavi, ppOptions);
1405 /* check parameters */
1406 if (nStreams <= 0 || ppavi == NULL || ppOptions == NULL)
1407 return AVIERR_BADPARAM;
1409 /* save options for case user press cancel */
1410 if (ppOptions != NULL && nStreams > 1) {
1411 pSavedOptions = GlobalAllocPtr(GHND,nStreams * sizeof(AVICOMPRESSOPTIONS));
1412 if (pSavedOptions == NULL)
1413 return FALSE;
1415 for (n = 0; n < nStreams; n++) {
1416 if (ppOptions[n] != NULL)
1417 memcpy(pSavedOptions + n, ppOptions[n], sizeof(AVICOMPRESSOPTIONS));
1421 SaveOpts.uFlags = uFlags;
1422 SaveOpts.nStreams = nStreams;
1423 SaveOpts.ppavis = ppavi;
1424 SaveOpts.ppOptions = ppOptions;
1426 ret = DialogBoxW(AVIFILE_hModule, MAKEINTRESOURCEW(IDD_SAVEOPTIONS),
1427 hWnd, AVISaveOptionsDlgProc);
1429 if (ret == -1)
1430 ret = FALSE;
1432 /* restore options when user pressed cancel */
1433 if (pSavedOptions != NULL && ret == FALSE) {
1434 for (n = 0; n < nStreams; n++) {
1435 if (ppOptions[n] != NULL)
1436 memcpy(ppOptions[n], pSavedOptions + n, sizeof(AVICOMPRESSOPTIONS));
1438 GlobalFreePtr(pSavedOptions);
1441 return (BOOL)ret;
1444 /***********************************************************************
1445 * AVISaveOptionsFree (AVIFIL32.@)
1446 * AVISaveOptionsFree (AVIFILE.124)
1448 HRESULT WINAPI AVISaveOptionsFree(INT nStreams,LPAVICOMPRESSOPTIONS*ppOptions)
1450 TRACE("(%d,%p)\n", nStreams, ppOptions);
1452 if (nStreams < 0 || ppOptions == NULL)
1453 return AVIERR_BADPARAM;
1455 for (; nStreams > 0; nStreams--) {
1456 if (ppOptions[nStreams] != NULL) {
1457 ppOptions[nStreams]->dwFlags &= ~AVICOMPRESSF_VALID;
1459 if (ppOptions[nStreams]->lpParms != NULL) {
1460 GlobalFreePtr(ppOptions[nStreams]->lpParms);
1461 ppOptions[nStreams]->lpParms = NULL;
1462 ppOptions[nStreams]->cbParms = 0;
1464 if (ppOptions[nStreams]->lpFormat != NULL) {
1465 GlobalFreePtr(ppOptions[nStreams]->lpFormat);
1466 ppOptions[nStreams]->lpFormat = NULL;
1467 ppOptions[nStreams]->cbFormat = 0;
1472 return AVIERR_OK;
1475 /***********************************************************************
1476 * AVISaveVA (AVIFIL32.@)
1478 HRESULT WINAPI AVISaveVA(LPCSTR szFile, CLSID *pclsidHandler,
1479 AVISAVECALLBACK lpfnCallback, int nStream,
1480 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions)
1482 LPWSTR wszFile = NULL;
1483 HRESULT hr;
1484 int len;
1486 TRACE("%s,%p,%p,%d,%p,%p)\n", debugstr_a(szFile), pclsidHandler,
1487 lpfnCallback, nStream, ppavi, plpOptions);
1489 if (szFile == NULL || ppavi == NULL || plpOptions == NULL)
1490 return AVIERR_BADPARAM;
1492 /* convert ASCII string to Unicode and call Unicode function */
1493 len = lstrlenA(szFile);
1494 if (len <= 0)
1495 return AVIERR_BADPARAM;
1497 wszFile = (LPWSTR)LocalAlloc(LPTR, (len + 1) * sizeof(WCHAR));
1498 if (wszFile == NULL)
1499 return AVIERR_MEMORY;
1501 MultiByteToWideChar(CP_ACP, 0, szFile, -1, wszFile, len + 1);
1502 wszFile[len + 1] = 0;
1504 hr = AVISaveVW(wszFile, pclsidHandler, lpfnCallback,
1505 nStream, ppavi, plpOptions);
1507 LocalFree((HLOCAL)wszFile);
1509 return hr;
1512 /***********************************************************************
1513 * AVISaveVW (AVIFIL32.@)
1515 HRESULT WINAPI AVISaveVW(LPCWSTR szFile, CLSID *pclsidHandler,
1516 AVISAVECALLBACK lpfnCallback, int nStream,
1517 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions)
1519 FIXME("(%s,%p,%p,%d,%p,%p), stub!\n", debugstr_w(szFile), pclsidHandler,
1520 lpfnCallback, nStream, ppavi, plpOptions);
1522 if (szFile == NULL || ppavi == NULL || plpOptions == NULL)
1523 return AVIERR_BADPARAM;
1525 return AVIERR_UNSUPPORTED;
1528 /***********************************************************************
1529 * CreateEditableStream (AVIFIL32.@)
1531 HRESULT WINAPI CreateEditableStream(PAVISTREAM *ppEditable, PAVISTREAM pSource)
1533 FIXME("(%p,%p), stub!\n", ppEditable, pSource);
1535 if (pSource == NULL)
1536 return AVIERR_BADHANDLE;
1537 if (ppEditable == NULL)
1538 return AVIERR_BADPARAM;
1540 *ppEditable = NULL;
1542 return AVIERR_UNSUPPORTED;
1545 /***********************************************************************
1546 * EditStreamClone (AVIFIL32.@)
1548 HRESULT WINAPI EditStreamClone(PAVISTREAM pStream, PAVISTREAM *ppResult)
1550 PAVIEDITSTREAM pEdit = NULL;
1551 HRESULT hr;
1553 TRACE("(%p,%p)\n", pStream, ppResult);
1555 if (pStream == NULL)
1556 return AVIERR_BADHANDLE;
1557 if (ppResult == NULL)
1558 return AVIERR_BADPARAM;
1560 *ppResult = NULL;
1562 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1563 if (SUCCEEDED(hr) && pEdit != NULL) {
1564 hr = IAVIEditStream_Clone(pEdit, ppResult);
1566 IAVIEditStream_Release(pEdit);
1567 } else
1568 hr = AVIERR_UNSUPPORTED;
1570 return hr;
1573 /***********************************************************************
1574 * EditStreamCopy (AVIFIL32.@)
1576 HRESULT WINAPI EditStreamCopy(PAVISTREAM pStream, LONG *plStart,
1577 LONG *plLength, PAVISTREAM *ppResult)
1579 PAVIEDITSTREAM pEdit = NULL;
1580 HRESULT hr;
1582 TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult);
1584 if (pStream == NULL)
1585 return AVIERR_BADHANDLE;
1586 if (plStart == NULL || plLength == NULL || ppResult == NULL)
1587 return AVIERR_BADPARAM;
1589 *ppResult = NULL;
1591 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1592 if (SUCCEEDED(hr) && pEdit != NULL) {
1593 hr = IAVIEditStream_Copy(pEdit, plStart, plLength, ppResult);
1595 IAVIEditStream_Release(pEdit);
1596 } else
1597 hr = AVIERR_UNSUPPORTED;
1599 return hr;
1602 /***********************************************************************
1603 * EditStreamCut (AVIFIL32.@)
1605 HRESULT WINAPI EditStreamCut(PAVISTREAM pStream, LONG *plStart,
1606 LONG *plLength, PAVISTREAM *ppResult)
1608 PAVIEDITSTREAM pEdit = NULL;
1609 HRESULT hr;
1611 TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult);
1613 if (pStream == NULL)
1614 return AVIERR_BADHANDLE;
1615 if (plStart == NULL || plLength == NULL || ppResult == NULL)
1616 return AVIERR_BADPARAM;
1618 *ppResult = NULL;
1620 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1621 if (SUCCEEDED(hr) && pEdit != NULL) {
1622 hr = IAVIEditStream_Cut(pEdit, plStart, plLength, ppResult);
1624 IAVIEditStream_Release(pEdit);
1625 } else
1626 hr = AVIERR_UNSUPPORTED;
1628 return hr;
1631 /***********************************************************************
1632 * EditStreamPaste (AVIFIL32.@)
1634 HRESULT WINAPI EditStreamPaste(PAVISTREAM pDest, LONG *plStart, LONG *plLength,
1635 PAVISTREAM pSource, LONG lStart, LONG lEnd)
1637 PAVIEDITSTREAM pEdit = NULL;
1638 HRESULT hr;
1640 TRACE("(%p,%p,%p,%p,%ld,%ld)\n", pDest, plStart, plLength,
1641 pSource, lStart, lEnd);
1643 if (pDest == NULL || pSource == NULL)
1644 return AVIERR_BADHANDLE;
1645 if (plStart == NULL || plLength == NULL || lStart < 0)
1646 return AVIERR_BADPARAM;
1648 hr = IAVIStream_QueryInterface(pDest, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1649 if (SUCCEEDED(hr) && pEdit != NULL) {
1650 hr = IAVIEditStream_Paste(pEdit, plStart, plLength, pSource, lStart, lEnd);
1652 IAVIEditStream_Release(pEdit);
1653 } else
1654 hr = AVIERR_UNSUPPORTED;
1656 return hr;
1659 /***********************************************************************
1660 * EditStreamSetInfoA (AVIFIL32.@)
1662 HRESULT WINAPI EditStreamSetInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi,
1663 LONG size)
1665 AVISTREAMINFOW asiw;
1667 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
1669 if (pstream == NULL)
1670 return AVIERR_BADHANDLE;
1671 if ((DWORD)size < sizeof(AVISTREAMINFOA))
1672 return AVIERR_BADSIZE;
1674 memcpy(&asiw, asi, sizeof(asi) - sizeof(asi->szName));
1675 MultiByteToWideChar(CP_ACP, 0, asi->szName, -1,
1676 asiw.szName, sizeof(asiw.szName));
1678 return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw));
1681 /***********************************************************************
1682 * EditStreamSetInfoW (AVIFIL32.@)
1684 HRESULT WINAPI EditStreamSetInfoW(PAVISTREAM pstream, LPAVISTREAMINFOW asi,
1685 LONG size)
1687 PAVIEDITSTREAM pEdit = NULL;
1688 HRESULT hr;
1690 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
1692 hr = IAVIStream_QueryInterface(pstream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1693 if (SUCCEEDED(hr) && pEdit != NULL) {
1694 hr = IAVIEditStream_SetInfo(pEdit, asi, size);
1696 IAVIEditStream_Release(pEdit);
1697 } else
1698 hr = AVIERR_UNSUPPORTED;
1700 return hr;
1703 /***********************************************************************
1704 * EditStreamSetNameA (AVIFIL32.@)
1706 HRESULT WINAPI EditStreamSetNameA(PAVISTREAM pstream, LPCSTR szName)
1708 AVISTREAMINFOA asia;
1709 HRESULT hres;
1711 TRACE("(%p,%s)\n", pstream, debugstr_a(szName));
1713 if (pstream == NULL)
1714 return AVIERR_BADHANDLE;
1715 if (szName == NULL)
1716 return AVIERR_BADPARAM;
1718 hres = AVIStreamInfoA(pstream, &asia, sizeof(asia));
1719 if (FAILED(hres))
1720 return hres;
1722 memset(asia.szName, 0, sizeof(asia.szName));
1723 lstrcpynA(asia.szName, szName, sizeof(asia.szName)/sizeof(asia.szName[0]));
1725 return EditStreamSetInfoA(pstream, &asia, sizeof(asia));
1728 /***********************************************************************
1729 * EditStreamSetNameW (AVIFIL32.@)
1731 HRESULT WINAPI EditStreamSetNameW(PAVISTREAM pstream, LPCWSTR szName)
1733 AVISTREAMINFOW asiw;
1734 HRESULT hres;
1736 TRACE("(%p,%s)\n", pstream, debugstr_w(szName));
1738 if (pstream == NULL)
1739 return AVIERR_BADHANDLE;
1740 if (szName == NULL)
1741 return AVIERR_BADPARAM;
1743 hres = IAVIStream_Info(pstream, &asiw, sizeof(asiw));
1744 if (FAILED(hres))
1745 return hres;
1747 memset(asiw.szName, 0, sizeof(asiw.szName));
1748 lstrcpynW(asiw.szName, szName, sizeof(asiw.szName)/sizeof(asiw.szName[0]));
1750 return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw));
1753 /***********************************************************************
1754 * AVIClearClipboard (AVIFIL32.@)
1756 HRESULT WINAPI AVIClearClipboard(void)
1758 TRACE("()\n");
1760 return AVIERR_UNSUPPORTED; /* OleSetClipboard(NULL); */
1763 /***********************************************************************
1764 * AVIGetFromClipboard (AVIFIL32.@)
1766 HRESULT WINAPI AVIGetFromClipboard(PAVIFILE *ppfile)
1768 FIXME("(%p), stub!\n", ppfile);
1770 *ppfile = NULL;
1772 return AVIERR_UNSUPPORTED;
1775 /***********************************************************************
1776 * AVIPutFileOnClipboard (AVIFIL32.@)
1778 HRESULT WINAPI AVIPutFileOnClipboard(PAVIFILE pfile)
1780 FIXME("(%p), stub!\n", pfile);
1782 if (pfile == NULL)
1783 return AVIERR_BADHANDLE;
1785 return AVIERR_UNSUPPORTED;