Ensure MIPMAP levels is reset when rebinding an existing texture to a
[wine/dcerpc.git] / dlls / avifil32 / api.c
blob8ad311a9294a2c0d7aab39193f2367a71d4d01dd
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 * AVIStreamBeginStreaming (AVIFIL32.@)
840 LONG WINAPI AVIStreamBeginStreaming(PAVISTREAM pavi, LONG lStart, LONG lEnd, LONG lRate)
842 FIXME("(%p)->(%ld,%ld,%ld)\n", pavi, lStart, lEnd, lRate);
844 return AVIERR_OK;
847 /***********************************************************************
848 * AVIStreamEndStreaming (AVIFIL32.@)
850 LONG WINAPI AVIStreamEndStreaming(PAVISTREAM pavi)
852 FIXME("(%p)\n", pavi);
854 return AVIERR_OK;
857 /***********************************************************************
858 * AVIStreamStart (AVIFILE.130)
859 * AVIStreamStart (AVIFIL32.@)
861 LONG WINAPI AVIStreamStart(PAVISTREAM pstream)
863 AVISTREAMINFOW asiw;
865 TRACE("(%p)\n", pstream);
867 if (pstream == NULL)
868 return 0;
870 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
871 return 0;
873 return asiw.dwStart;
876 /***********************************************************************
877 * AVIStreamLength (AVIFILE.131)
878 * AVIStreamLength (AVIFIL32.@)
880 LONG WINAPI AVIStreamLength(PAVISTREAM pstream)
882 AVISTREAMINFOW asiw;
884 TRACE("(%p)\n", pstream);
886 if (pstream == NULL)
887 return 0;
889 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
890 return 0;
892 return asiw.dwLength;
895 /***********************************************************************
896 * AVIStreamSampleToTime (AVIFILE.133)
897 * AVIStreamSampleToTime (AVIFIL32.@)
899 LONG WINAPI AVIStreamSampleToTime(PAVISTREAM pstream, LONG lSample)
901 AVISTREAMINFOW asiw;
903 TRACE("(%p,%ld)\n", pstream, lSample);
905 if (pstream == NULL)
906 return -1;
908 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
909 return -1;
910 if (asiw.dwRate == 0)
911 return -1;
913 return (LONG)(((float)lSample * asiw.dwScale * 1000.0) / asiw.dwRate);
916 /***********************************************************************
917 * AVIStreamTimeToSample (AVIFILE.132)
918 * AVIStreamTimeToSample (AVIFIL32.@)
920 LONG WINAPI AVIStreamTimeToSample(PAVISTREAM pstream, LONG lTime)
922 AVISTREAMINFOW asiw;
924 TRACE("(%p,%ld)\n", pstream, lTime);
926 if (pstream == NULL)
927 return -1;
929 if (FAILED(IAVIStream_Info(pstream, &asiw, sizeof(asiw))))
930 return -1;
931 if (asiw.dwScale == 0)
932 return -1;
934 return (LONG)(((float)lTime * asiw.dwRate) / asiw.dwScale / 1000.0);
937 /***********************************************************************
938 * AVIBuildFilterA (AVIFIL32.@)
939 * AVIBuildFilter (AVIFILE.123)
941 HRESULT WINAPI AVIBuildFilterA(LPSTR szFilter, LONG cbFilter, BOOL fSaving)
943 LPWSTR wszFilter;
944 HRESULT hr;
946 TRACE("(%p,%ld,%d)\n", szFilter, cbFilter, fSaving);
948 /* check parameters */
949 if (szFilter == NULL)
950 return AVIERR_BADPARAM;
951 if (cbFilter < 2)
952 return AVIERR_BADSIZE;
954 szFilter[0] = 0;
955 szFilter[1] = 0;
957 wszFilter = (LPWSTR)GlobalAllocPtr(GHND, cbFilter);
958 if (wszFilter == NULL)
959 return AVIERR_MEMORY;
961 hr = AVIBuildFilterW(wszFilter, cbFilter, fSaving);
962 if (SUCCEEDED(hr)) {
963 WideCharToMultiByte(CP_ACP, 0, wszFilter, cbFilter,
964 szFilter, cbFilter, NULL, NULL);
967 GlobalFreePtr(wszFilter);
969 return hr;
972 /***********************************************************************
973 * AVIBuildFilterW (AVIFIL32.@)
975 HRESULT WINAPI AVIBuildFilterW(LPWSTR szFilter, LONG cbFilter, BOOL fSaving)
977 static const WCHAR szClsid[] = {'C','L','S','I','D',0};
978 static const WCHAR szExtensionFmt[] = {';','*','.','%','s',0};
979 static const WCHAR szAVIFileExtensions[] =
980 {'A','V','I','F','i','l','e','\\','E','x','t','e','n','s','i','o','n','s',0};
982 AVIFilter *lp;
983 WCHAR szAllFiles[40];
984 WCHAR szFileExt[10];
985 WCHAR szValue[128];
986 HKEY hKey;
987 DWORD n, i;
988 LONG size;
989 DWORD count = 0;
991 TRACE("(%p,%ld,%d)\n", szFilter, cbFilter, fSaving);
993 /* check parameters */
994 if (szFilter == NULL)
995 return AVIERR_BADPARAM;
996 if (cbFilter < 2)
997 return AVIERR_BADSIZE;
999 lp = (AVIFilter*)GlobalAllocPtr(GHND, MAX_FILTERS * sizeof(AVIFilter));
1000 if (lp == NULL)
1001 return AVIERR_MEMORY;
1004 * 1. iterate over HKEY_CLASSES_ROOT\\AVIFile\\Extensions and collect
1005 * extensions and CLSID's
1006 * 2. iterate over collected CLSID's and copy it's description and it's
1007 * extensions to szFilter if it fits
1009 * First filter is named "All multimedia files" and it's filter is a
1010 * collection of all possible extensions except "*.*".
1012 if (RegOpenKeyW(HKEY_CLASSES_ROOT, szAVIFileExtensions, &hKey) != S_OK) {
1013 GlobalFreePtr(lp);
1014 return AVIERR_ERROR;
1016 for (n = 0;RegEnumKeyW(hKey, n, szFileExt, sizeof(szFileExt)) == S_OK;n++) {
1017 /* get CLSID to extension */
1018 size = sizeof(szValue)/sizeof(szValue[0]);
1019 if (RegQueryValueW(hKey, szFileExt, szValue, &size) != S_OK)
1020 break;
1022 /* search if the CLSID is already known */
1023 for (i = 1; i <= count; i++) {
1024 if (lstrcmpW(lp[i].szClsid, szValue) == 0)
1025 break; /* a new one */
1028 if (count - i == -1U) {
1029 /* it's a new CLSID */
1031 /* FIXME: How do we get info's about read/write capabilities? */
1033 if (count >= MAX_FILTERS) {
1034 /* try to inform user of our full fixed size table */
1035 ERR(": More than %d filters found! Adjust MAX_FILTERS in dlls/avifil32/api.c\n", MAX_FILTERS);
1036 break;
1039 lstrcpyW(lp[i].szClsid, szValue);
1041 count++;
1044 /* append extension to the filter */
1045 wsprintfW(szValue, szExtensionFmt, szFileExt);
1046 if (lp[i].szExtensions[0] == 0)
1047 lstrcatW(lp[i].szExtensions, szValue + 1);
1048 else
1049 lstrcatW(lp[i].szExtensions, szValue);
1051 /* also append to the "all multimedia"-filter */
1052 if (lp[0].szExtensions[0] == 0)
1053 lstrcatW(lp[0].szExtensions, szValue + 1);
1054 else
1055 lstrcatW(lp[0].szExtensions, szValue);
1057 RegCloseKey(hKey);
1059 /* 2. get descriptions for the CLSIDs and fill out szFilter */
1060 if (RegOpenKeyW(HKEY_CLASSES_ROOT, szClsid, &hKey) != S_OK) {
1061 GlobalFreePtr(lp);
1062 return AVIERR_ERROR;
1064 for (n = 0; n <= count; n++) {
1065 /* first the description */
1066 if (n != 0) {
1067 size = sizeof(szValue)/sizeof(szValue[0]);
1068 if (RegQueryValueW(hKey, lp[n].szClsid, szValue, &size) == S_OK) {
1069 size = lstrlenW(szValue);
1070 lstrcpynW(szFilter, szValue, cbFilter);
1072 } else
1073 size = LoadStringW(AVIFILE_hModule,IDS_ALLMULTIMEDIA,szFilter,cbFilter);
1075 /* check for enough space */
1076 size++;
1077 if (cbFilter < size + lstrlenW(lp[n].szExtensions) + 2) {
1078 szFilter[0] = 0;
1079 szFilter[1] = 0;
1080 GlobalFreePtr(lp);
1081 RegCloseKey(hKey);
1082 return AVIERR_BUFFERTOOSMALL;
1084 cbFilter -= size;
1085 szFilter += size;
1087 /* and then the filter */
1088 lstrcpynW(szFilter, lp[n].szExtensions, cbFilter);
1089 size = lstrlenW(lp[n].szExtensions) + 1;
1090 cbFilter -= size;
1091 szFilter += size;
1094 RegCloseKey(hKey);
1095 GlobalFreePtr(lp);
1097 /* add "All files" "*.*" filter if enough space left */
1098 size = LoadStringW(AVIFILE_hModule, IDS_ALLFILES,
1099 szAllFiles, sizeof(szAllFiles)) + 1;
1100 if (cbFilter > size) {
1101 int i;
1103 /* replace '@' with \000 to separate description of filter */
1104 for (i = 0; i < size && szAllFiles[i] != 0; i++) {
1105 if (szAllFiles[i] == '@') {
1106 szAllFiles[i] = 0;
1107 break;
1111 memcpy(szFilter, szAllFiles, size * sizeof(szAllFiles[0]));
1112 szFilter += size;
1113 szFilter[0] = 0;
1115 return AVIERR_OK;
1116 } else {
1117 szFilter[0] = 0;
1118 return AVIERR_BUFFERTOOSMALL;
1122 static BOOL AVISaveOptionsFmtChoose(HWND hWnd)
1124 LPAVICOMPRESSOPTIONS pOptions = SaveOpts.ppOptions[SaveOpts.nCurrent];
1125 AVISTREAMINFOW sInfo;
1127 TRACE("(%p)\n", hWnd);
1129 if (pOptions == NULL || SaveOpts.ppavis[SaveOpts.nCurrent] == NULL) {
1130 ERR(": bad state!\n");
1131 return FALSE;
1134 if (FAILED(AVIStreamInfoW(SaveOpts.ppavis[SaveOpts.nCurrent],
1135 &sInfo, sizeof(sInfo)))) {
1136 ERR(": AVIStreamInfoW failed!\n");
1137 return FALSE;
1140 if (sInfo.fccType == streamtypeVIDEO) {
1141 COMPVARS cv;
1142 BOOL ret;
1144 memset(&cv, 0, sizeof(cv));
1146 if ((pOptions->dwFlags & AVICOMPRESSF_VALID) == 0) {
1147 memset(pOptions, 0, sizeof(AVICOMPRESSOPTIONS));
1148 pOptions->fccType = streamtypeVIDEO;
1149 pOptions->fccHandler = comptypeDIB;
1150 pOptions->dwQuality = (DWORD)ICQUALITY_DEFAULT;
1153 cv.cbSize = sizeof(cv);
1154 cv.dwFlags = ICMF_COMPVARS_VALID;
1155 /*cv.fccType = pOptions->fccType; */
1156 cv.fccHandler = pOptions->fccHandler;
1157 cv.lQ = pOptions->dwQuality;
1158 cv.lpState = pOptions->lpParms;
1159 cv.cbState = pOptions->cbParms;
1160 if (pOptions->dwFlags & AVICOMPRESSF_KEYFRAMES)
1161 cv.lKey = pOptions->dwKeyFrameEvery;
1162 else
1163 cv.lKey = 0;
1164 if (pOptions->dwFlags & AVICOMPRESSF_DATARATE)
1165 cv.lDataRate = pOptions->dwBytesPerSecond / 1024; /* need kBytes */
1166 else
1167 cv.lDataRate = 0;
1169 ret = ICCompressorChoose(hWnd, SaveOpts.uFlags, NULL,
1170 SaveOpts.ppavis[SaveOpts.nCurrent], &cv, NULL);
1172 if (ret) {
1173 pOptions->fccHandler = cv.fccHandler;
1174 pOptions->lpParms = cv.lpState;
1175 pOptions->cbParms = cv.cbState;
1176 pOptions->dwQuality = cv.lQ;
1177 if (cv.lKey != 0) {
1178 pOptions->dwKeyFrameEvery = cv.lKey;
1179 pOptions->dwFlags |= AVICOMPRESSF_KEYFRAMES;
1180 } else
1181 pOptions->dwFlags &= ~AVICOMPRESSF_KEYFRAMES;
1182 if (cv.lDataRate != 0) {
1183 pOptions->dwBytesPerSecond = cv.lDataRate * 1024; /* need bytes */
1184 pOptions->dwFlags |= AVICOMPRESSF_DATARATE;
1185 } else
1186 pOptions->dwFlags &= ~AVICOMPRESSF_DATARATE;
1187 pOptions->dwFlags |= AVICOMPRESSF_VALID;
1189 ICCompressorFree(&cv);
1191 return ret;
1192 } else if (sInfo.fccType == streamtypeAUDIO) {
1193 ACMFORMATCHOOSEW afmtc;
1194 MMRESULT ret;
1195 LONG size;
1197 /* FIXME: check ACM version -- Which version is needed? */
1199 memset(&afmtc, 0, sizeof(afmtc));
1200 afmtc.cbStruct = sizeof(afmtc);
1201 afmtc.fdwStyle = 0;
1202 afmtc.hwndOwner = hWnd;
1204 acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT, &size);
1205 if ((pOptions->cbFormat == 0 || pOptions->lpFormat == NULL) && size != 0) {
1206 pOptions->lpFormat = GlobalAllocPtr(GMEM_MOVEABLE, size);
1207 pOptions->cbFormat = size;
1208 } else if (pOptions->cbFormat < (DWORD)size) {
1209 pOptions->lpFormat = GlobalReAllocPtr(pOptions->lpFormat, size, GMEM_MOVEABLE);
1210 pOptions->cbFormat = size;
1212 if (pOptions->lpFormat == NULL)
1213 return FALSE;
1214 afmtc.pwfx = pOptions->lpFormat;
1215 afmtc.cbwfx = pOptions->cbFormat;
1217 size = 0;
1218 AVIStreamFormatSize(SaveOpts.ppavis[SaveOpts.nCurrent],
1219 sInfo.dwStart, &size);
1220 if (size < (LONG)sizeof(PCMWAVEFORMAT))
1221 size = sizeof(PCMWAVEFORMAT);
1222 afmtc.pwfxEnum = GlobalAllocPtr(GHND, size);
1223 if (afmtc.pwfxEnum != NULL) {
1224 AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent],
1225 sInfo.dwStart, afmtc.pwfxEnum, &size);
1226 afmtc.fdwEnum = ACM_FORMATENUMF_CONVERT;
1229 ret = acmFormatChooseW(&afmtc);
1230 if (ret == S_OK)
1231 pOptions->dwFlags |= AVICOMPRESSF_VALID;
1233 if (afmtc.pwfxEnum != NULL)
1234 GlobalFreePtr(afmtc.pwfxEnum);
1236 return (ret == S_OK ? TRUE : FALSE);
1237 } else {
1238 ERR(": unknown streamtype 0x%08lX\n", sInfo.fccType);
1239 return FALSE;
1243 static void AVISaveOptionsUpdate(HWND hWnd)
1245 static const WCHAR szVideoFmt[]={'%','l','d','x','%','l','d','x','%','d',0};
1246 static const WCHAR szAudioFmt[]={'%','s',' ','%','s',0};
1248 WCHAR szFormat[128];
1249 AVISTREAMINFOW sInfo;
1250 LPVOID lpFormat;
1251 LONG size;
1253 TRACE("(%p)\n", hWnd);
1255 SaveOpts.nCurrent = SendDlgItemMessageW(hWnd,IDC_STREAM,CB_GETCURSEL,0,0);
1256 if (SaveOpts.nCurrent < 0)
1257 return;
1259 if (FAILED(AVIStreamInfoW(SaveOpts.ppavis[SaveOpts.nCurrent], &sInfo, sizeof(sInfo))))
1260 return;
1262 AVIStreamFormatSize(SaveOpts.ppavis[SaveOpts.nCurrent],sInfo.dwStart,&size);
1263 if (size > 0) {
1264 szFormat[0] = 0;
1266 /* read format to build format descriotion string */
1267 lpFormat = GlobalAllocPtr(GHND, size);
1268 if (lpFormat != NULL) {
1269 if (SUCCEEDED(AVIStreamReadFormat(SaveOpts.ppavis[SaveOpts.nCurrent],sInfo.dwStart,lpFormat, &size))) {
1270 if (sInfo.fccType == streamtypeVIDEO) {
1271 LPBITMAPINFOHEADER lpbi = lpFormat;
1272 ICINFO icinfo;
1274 wsprintfW(szFormat, szVideoFmt, lpbi->biWidth,
1275 lpbi->biHeight, lpbi->biBitCount);
1277 if (lpbi->biCompression != BI_RGB) {
1278 HIC hic;
1280 hic = ICLocate(ICTYPE_VIDEO, sInfo.fccHandler, lpFormat,
1281 NULL, ICMODE_DECOMPRESS);
1282 if (hic != NULL) {
1283 if (ICGetInfo(hic, &icinfo, sizeof(icinfo)) == S_OK)
1284 lstrcatW(szFormat, icinfo.szDescription);
1285 ICClose(hic);
1287 } else {
1288 LoadStringW(AVIFILE_hModule, IDS_UNCOMPRESSED,
1289 icinfo.szDescription, sizeof(icinfo.szDescription));
1290 lstrcatW(szFormat, icinfo.szDescription);
1292 } else if (sInfo.fccType == streamtypeAUDIO) {
1293 ACMFORMATTAGDETAILSW aftd;
1294 ACMFORMATDETAILSW afd;
1296 memset(&aftd, 0, sizeof(aftd));
1297 memset(&afd, 0, sizeof(afd));
1299 aftd.cbStruct = sizeof(aftd);
1300 aftd.dwFormatTag = afd.dwFormatTag =
1301 ((PWAVEFORMATEX)lpFormat)->wFormatTag;
1302 aftd.cbFormatSize = afd.cbwfx = size;
1304 afd.cbStruct = sizeof(afd);
1305 afd.pwfx = lpFormat;
1307 if (acmFormatTagDetailsW(NULL, &aftd,
1308 ACM_FORMATTAGDETAILSF_FORMATTAG) == S_OK) {
1309 if (acmFormatDetailsW(NULL,&afd,ACM_FORMATDETAILSF_FORMAT) == S_OK)
1310 wsprintfW(szFormat, szAudioFmt, afd.szFormat, aftd.szFormatTag);
1314 GlobalFreePtr(lpFormat);
1317 /* set text for format description */
1318 SetDlgItemTextW(hWnd, IDC_FORMATTEXT, szFormat);
1320 /* Disable option button for unsupported streamtypes */
1321 if (sInfo.fccType == streamtypeVIDEO ||
1322 sInfo.fccType == streamtypeAUDIO)
1323 EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), TRUE);
1324 else
1325 EnableWindow(GetDlgItem(hWnd, IDC_OPTIONS), FALSE);
1330 INT_PTR CALLBACK AVISaveOptionsDlgProc(HWND hWnd, UINT uMsg,
1331 WPARAM wParam, LPARAM lParam)
1333 DWORD dwInterleave;
1334 BOOL bIsInterleaved;
1335 INT n;
1337 /*TRACE("(%p,%u,0x%04X,0x%08lX)\n", hWnd, uMsg, wParam, lParam);*/
1339 switch (uMsg) {
1340 case WM_INITDIALOG:
1341 SaveOpts.nCurrent = 0;
1342 if (SaveOpts.nStreams == 1) {
1343 EndDialog(hWnd, AVISaveOptionsFmtChoose(hWnd));
1344 return TRUE;
1347 /* add streams */
1348 for (n = 0; n < SaveOpts.nStreams; n++) {
1349 AVISTREAMINFOW sInfo;
1351 AVIStreamInfoW(SaveOpts.ppavis[n], &sInfo, sizeof(sInfo));
1352 SendDlgItemMessageW(hWnd, IDC_STREAM, CB_ADDSTRING,
1353 0L, (LPARAM)sInfo.szName);
1356 /* select first stream */
1357 SendDlgItemMessageW(hWnd, IDC_STREAM, CB_SETCURSEL, 0, 0);
1358 SendMessageW(hWnd, WM_COMMAND,
1359 GET_WM_COMMAND_MPS(IDC_STREAM, hWnd, CBN_SELCHANGE));
1361 /* initialize interleave */
1362 if (SaveOpts.ppOptions[0] != NULL &&
1363 (SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_VALID)) {
1364 bIsInterleaved = (SaveOpts.ppOptions[0]->dwFlags & AVICOMPRESSF_INTERLEAVE);
1365 dwInterleave = SaveOpts.ppOptions[0]->dwInterleaveEvery;
1366 } else {
1367 bIsInterleaved = TRUE;
1368 dwInterleave = 0;
1370 CheckDlgButton(hWnd, IDC_INTERLEAVE, bIsInterleaved);
1371 SetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, dwInterleave, FALSE);
1372 EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY), bIsInterleaved);
1373 break;
1374 case WM_COMMAND:
1375 switch (GET_WM_COMMAND_ID(wParam, lParam)) {
1376 case IDOK:
1377 /* get data from controls and save them */
1378 dwInterleave = GetDlgItemInt(hWnd, IDC_INTERLEAVEEVERY, NULL, 0);
1379 bIsInterleaved = IsDlgButtonChecked(hWnd, IDC_INTERLEAVE);
1380 for (n = 0; n < SaveOpts.nStreams; n++) {
1381 if (SaveOpts.ppOptions[n] != NULL) {
1382 if (bIsInterleaved) {
1383 SaveOpts.ppOptions[n]->dwFlags |= AVICOMPRESSF_INTERLEAVE;
1384 SaveOpts.ppOptions[n]->dwInterleaveEvery = dwInterleave;
1385 } else
1386 SaveOpts.ppOptions[n]->dwFlags &= ~AVICOMPRESSF_INTERLEAVE;
1389 /* fall through */
1390 case IDCANCEL:
1391 EndDialog(hWnd, GET_WM_COMMAND_CMD(wParam, lParam) == IDOK);
1392 break;
1393 case IDC_INTERLEAVE:
1394 EnableWindow(GetDlgItem(hWnd, IDC_INTERLEAVEEVERY),
1395 IsDlgButtonChecked(hWnd, IDC_INTERLEAVE));
1396 break;
1397 case IDC_STREAM:
1398 if (GET_WM_COMMAND_CMD(wParam, lParam) == CBN_SELCHANGE) {
1399 /* update control elements */
1400 AVISaveOptionsUpdate(hWnd);
1402 break;
1403 case IDC_OPTIONS:
1404 AVISaveOptionsFmtChoose(hWnd);
1405 break;
1407 return TRUE;
1410 return FALSE;
1413 /***********************************************************************
1414 * AVISaveOptions (AVIFIL32.@)
1416 BOOL WINAPI AVISaveOptions(HWND hWnd, UINT uFlags, INT nStreams,
1417 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *ppOptions)
1419 LPAVICOMPRESSOPTIONS pSavedOptions = NULL;
1420 INT ret, n;
1422 TRACE("(%p,0x%X,%d,%p,%p)\n", hWnd, uFlags, nStreams,
1423 ppavi, ppOptions);
1425 /* check parameters */
1426 if (nStreams <= 0 || ppavi == NULL || ppOptions == NULL)
1427 return AVIERR_BADPARAM;
1429 /* save options for case user press cancel */
1430 if (ppOptions != NULL && nStreams > 1) {
1431 pSavedOptions = GlobalAllocPtr(GHND,nStreams * sizeof(AVICOMPRESSOPTIONS));
1432 if (pSavedOptions == NULL)
1433 return FALSE;
1435 for (n = 0; n < nStreams; n++) {
1436 if (ppOptions[n] != NULL)
1437 memcpy(pSavedOptions + n, ppOptions[n], sizeof(AVICOMPRESSOPTIONS));
1441 SaveOpts.uFlags = uFlags;
1442 SaveOpts.nStreams = nStreams;
1443 SaveOpts.ppavis = ppavi;
1444 SaveOpts.ppOptions = ppOptions;
1446 ret = DialogBoxW(AVIFILE_hModule, MAKEINTRESOURCEW(IDD_SAVEOPTIONS),
1447 hWnd, AVISaveOptionsDlgProc);
1449 if (ret == -1)
1450 ret = FALSE;
1452 /* restore options when user pressed cancel */
1453 if (pSavedOptions != NULL && ret == FALSE) {
1454 for (n = 0; n < nStreams; n++) {
1455 if (ppOptions[n] != NULL)
1456 memcpy(ppOptions[n], pSavedOptions + n, sizeof(AVICOMPRESSOPTIONS));
1458 GlobalFreePtr(pSavedOptions);
1461 return (BOOL)ret;
1464 /***********************************************************************
1465 * AVISaveOptionsFree (AVIFIL32.@)
1466 * AVISaveOptionsFree (AVIFILE.124)
1468 HRESULT WINAPI AVISaveOptionsFree(INT nStreams,LPAVICOMPRESSOPTIONS*ppOptions)
1470 TRACE("(%d,%p)\n", nStreams, ppOptions);
1472 if (nStreams < 0 || ppOptions == NULL)
1473 return AVIERR_BADPARAM;
1475 for (; nStreams > 0; nStreams--) {
1476 if (ppOptions[nStreams] != NULL) {
1477 ppOptions[nStreams]->dwFlags &= ~AVICOMPRESSF_VALID;
1479 if (ppOptions[nStreams]->lpParms != NULL) {
1480 GlobalFreePtr(ppOptions[nStreams]->lpParms);
1481 ppOptions[nStreams]->lpParms = NULL;
1482 ppOptions[nStreams]->cbParms = 0;
1484 if (ppOptions[nStreams]->lpFormat != NULL) {
1485 GlobalFreePtr(ppOptions[nStreams]->lpFormat);
1486 ppOptions[nStreams]->lpFormat = NULL;
1487 ppOptions[nStreams]->cbFormat = 0;
1492 return AVIERR_OK;
1495 /***********************************************************************
1496 * AVISaveVA (AVIFIL32.@)
1498 HRESULT WINAPI AVISaveVA(LPCSTR szFile, CLSID *pclsidHandler,
1499 AVISAVECALLBACK lpfnCallback, int nStream,
1500 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions)
1502 LPWSTR wszFile = NULL;
1503 HRESULT hr;
1504 int len;
1506 TRACE("%s,%p,%p,%d,%p,%p)\n", debugstr_a(szFile), pclsidHandler,
1507 lpfnCallback, nStream, ppavi, plpOptions);
1509 if (szFile == NULL || ppavi == NULL || plpOptions == NULL)
1510 return AVIERR_BADPARAM;
1512 /* convert ASCII string to Unicode and call Unicode function */
1513 len = lstrlenA(szFile);
1514 if (len <= 0)
1515 return AVIERR_BADPARAM;
1517 wszFile = (LPWSTR)LocalAlloc(LPTR, (len + 1) * sizeof(WCHAR));
1518 if (wszFile == NULL)
1519 return AVIERR_MEMORY;
1521 MultiByteToWideChar(CP_ACP, 0, szFile, -1, wszFile, len + 1);
1522 wszFile[len + 1] = 0;
1524 hr = AVISaveVW(wszFile, pclsidHandler, lpfnCallback,
1525 nStream, ppavi, plpOptions);
1527 LocalFree((HLOCAL)wszFile);
1529 return hr;
1532 /***********************************************************************
1533 * AVISaveVW (AVIFIL32.@)
1535 HRESULT WINAPI AVISaveVW(LPCWSTR szFile, CLSID *pclsidHandler,
1536 AVISAVECALLBACK lpfnCallback, int nStream,
1537 PAVISTREAM *ppavi, LPAVICOMPRESSOPTIONS *plpOptions)
1539 FIXME("(%s,%p,%p,%d,%p,%p), stub!\n", debugstr_w(szFile), pclsidHandler,
1540 lpfnCallback, nStream, ppavi, plpOptions);
1542 if (szFile == NULL || ppavi == NULL || plpOptions == NULL)
1543 return AVIERR_BADPARAM;
1545 return AVIERR_UNSUPPORTED;
1548 /***********************************************************************
1549 * CreateEditableStream (AVIFIL32.@)
1551 HRESULT WINAPI CreateEditableStream(PAVISTREAM *ppEditable, PAVISTREAM pSource)
1553 FIXME("(%p,%p), stub!\n", ppEditable, pSource);
1555 if (pSource == NULL)
1556 return AVIERR_BADHANDLE;
1557 if (ppEditable == NULL)
1558 return AVIERR_BADPARAM;
1560 *ppEditable = NULL;
1562 return AVIERR_UNSUPPORTED;
1565 /***********************************************************************
1566 * EditStreamClone (AVIFIL32.@)
1568 HRESULT WINAPI EditStreamClone(PAVISTREAM pStream, PAVISTREAM *ppResult)
1570 PAVIEDITSTREAM pEdit = NULL;
1571 HRESULT hr;
1573 TRACE("(%p,%p)\n", pStream, ppResult);
1575 if (pStream == NULL)
1576 return AVIERR_BADHANDLE;
1577 if (ppResult == NULL)
1578 return AVIERR_BADPARAM;
1580 *ppResult = NULL;
1582 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1583 if (SUCCEEDED(hr) && pEdit != NULL) {
1584 hr = IAVIEditStream_Clone(pEdit, ppResult);
1586 IAVIEditStream_Release(pEdit);
1587 } else
1588 hr = AVIERR_UNSUPPORTED;
1590 return hr;
1593 /***********************************************************************
1594 * EditStreamCopy (AVIFIL32.@)
1596 HRESULT WINAPI EditStreamCopy(PAVISTREAM pStream, LONG *plStart,
1597 LONG *plLength, PAVISTREAM *ppResult)
1599 PAVIEDITSTREAM pEdit = NULL;
1600 HRESULT hr;
1602 TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult);
1604 if (pStream == NULL)
1605 return AVIERR_BADHANDLE;
1606 if (plStart == NULL || plLength == NULL || ppResult == NULL)
1607 return AVIERR_BADPARAM;
1609 *ppResult = NULL;
1611 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1612 if (SUCCEEDED(hr) && pEdit != NULL) {
1613 hr = IAVIEditStream_Copy(pEdit, plStart, plLength, ppResult);
1615 IAVIEditStream_Release(pEdit);
1616 } else
1617 hr = AVIERR_UNSUPPORTED;
1619 return hr;
1622 /***********************************************************************
1623 * EditStreamCut (AVIFIL32.@)
1625 HRESULT WINAPI EditStreamCut(PAVISTREAM pStream, LONG *plStart,
1626 LONG *plLength, PAVISTREAM *ppResult)
1628 PAVIEDITSTREAM pEdit = NULL;
1629 HRESULT hr;
1631 TRACE("(%p,%p,%p,%p)\n", pStream, plStart, plLength, ppResult);
1633 if (pStream == NULL)
1634 return AVIERR_BADHANDLE;
1635 if (plStart == NULL || plLength == NULL || ppResult == NULL)
1636 return AVIERR_BADPARAM;
1638 *ppResult = NULL;
1640 hr = IAVIStream_QueryInterface(pStream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1641 if (SUCCEEDED(hr) && pEdit != NULL) {
1642 hr = IAVIEditStream_Cut(pEdit, plStart, plLength, ppResult);
1644 IAVIEditStream_Release(pEdit);
1645 } else
1646 hr = AVIERR_UNSUPPORTED;
1648 return hr;
1651 /***********************************************************************
1652 * EditStreamPaste (AVIFIL32.@)
1654 HRESULT WINAPI EditStreamPaste(PAVISTREAM pDest, LONG *plStart, LONG *plLength,
1655 PAVISTREAM pSource, LONG lStart, LONG lEnd)
1657 PAVIEDITSTREAM pEdit = NULL;
1658 HRESULT hr;
1660 TRACE("(%p,%p,%p,%p,%ld,%ld)\n", pDest, plStart, plLength,
1661 pSource, lStart, lEnd);
1663 if (pDest == NULL || pSource == NULL)
1664 return AVIERR_BADHANDLE;
1665 if (plStart == NULL || plLength == NULL || lStart < 0)
1666 return AVIERR_BADPARAM;
1668 hr = IAVIStream_QueryInterface(pDest, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1669 if (SUCCEEDED(hr) && pEdit != NULL) {
1670 hr = IAVIEditStream_Paste(pEdit, plStart, plLength, pSource, lStart, lEnd);
1672 IAVIEditStream_Release(pEdit);
1673 } else
1674 hr = AVIERR_UNSUPPORTED;
1676 return hr;
1679 /***********************************************************************
1680 * EditStreamSetInfoA (AVIFIL32.@)
1682 HRESULT WINAPI EditStreamSetInfoA(PAVISTREAM pstream, LPAVISTREAMINFOA asi,
1683 LONG size)
1685 AVISTREAMINFOW asiw;
1687 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
1689 if (pstream == NULL)
1690 return AVIERR_BADHANDLE;
1691 if ((DWORD)size < sizeof(AVISTREAMINFOA))
1692 return AVIERR_BADSIZE;
1694 memcpy(&asiw, asi, sizeof(asi) - sizeof(asi->szName));
1695 MultiByteToWideChar(CP_ACP, 0, asi->szName, -1,
1696 asiw.szName, sizeof(asiw.szName));
1698 return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw));
1701 /***********************************************************************
1702 * EditStreamSetInfoW (AVIFIL32.@)
1704 HRESULT WINAPI EditStreamSetInfoW(PAVISTREAM pstream, LPAVISTREAMINFOW asi,
1705 LONG size)
1707 PAVIEDITSTREAM pEdit = NULL;
1708 HRESULT hr;
1710 TRACE("(%p,%p,%ld)\n", pstream, asi, size);
1712 hr = IAVIStream_QueryInterface(pstream, &IID_IAVIEditStream,(LPVOID*)&pEdit);
1713 if (SUCCEEDED(hr) && pEdit != NULL) {
1714 hr = IAVIEditStream_SetInfo(pEdit, asi, size);
1716 IAVIEditStream_Release(pEdit);
1717 } else
1718 hr = AVIERR_UNSUPPORTED;
1720 return hr;
1723 /***********************************************************************
1724 * EditStreamSetNameA (AVIFIL32.@)
1726 HRESULT WINAPI EditStreamSetNameA(PAVISTREAM pstream, LPCSTR szName)
1728 AVISTREAMINFOA asia;
1729 HRESULT hres;
1731 TRACE("(%p,%s)\n", pstream, debugstr_a(szName));
1733 if (pstream == NULL)
1734 return AVIERR_BADHANDLE;
1735 if (szName == NULL)
1736 return AVIERR_BADPARAM;
1738 hres = AVIStreamInfoA(pstream, &asia, sizeof(asia));
1739 if (FAILED(hres))
1740 return hres;
1742 memset(asia.szName, 0, sizeof(asia.szName));
1743 lstrcpynA(asia.szName, szName, sizeof(asia.szName)/sizeof(asia.szName[0]));
1745 return EditStreamSetInfoA(pstream, &asia, sizeof(asia));
1748 /***********************************************************************
1749 * EditStreamSetNameW (AVIFIL32.@)
1751 HRESULT WINAPI EditStreamSetNameW(PAVISTREAM pstream, LPCWSTR szName)
1753 AVISTREAMINFOW asiw;
1754 HRESULT hres;
1756 TRACE("(%p,%s)\n", pstream, debugstr_w(szName));
1758 if (pstream == NULL)
1759 return AVIERR_BADHANDLE;
1760 if (szName == NULL)
1761 return AVIERR_BADPARAM;
1763 hres = IAVIStream_Info(pstream, &asiw, sizeof(asiw));
1764 if (FAILED(hres))
1765 return hres;
1767 memset(asiw.szName, 0, sizeof(asiw.szName));
1768 lstrcpynW(asiw.szName, szName, sizeof(asiw.szName)/sizeof(asiw.szName[0]));
1770 return EditStreamSetInfoW(pstream, &asiw, sizeof(asiw));
1773 /***********************************************************************
1774 * AVIClearClipboard (AVIFIL32.@)
1776 HRESULT WINAPI AVIClearClipboard(void)
1778 TRACE("()\n");
1780 return AVIERR_UNSUPPORTED; /* OleSetClipboard(NULL); */
1783 /***********************************************************************
1784 * AVIGetFromClipboard (AVIFIL32.@)
1786 HRESULT WINAPI AVIGetFromClipboard(PAVIFILE *ppfile)
1788 FIXME("(%p), stub!\n", ppfile);
1790 *ppfile = NULL;
1792 return AVIERR_UNSUPPORTED;
1795 /***********************************************************************
1796 * AVIPutFileOnClipboard (AVIFIL32.@)
1798 HRESULT WINAPI AVIPutFileOnClipboard(PAVIFILE pfile)
1800 FIXME("(%p), stub!\n", pfile);
1802 if (pfile == NULL)
1803 return AVIERR_BADHANDLE;
1805 return AVIERR_UNSUPPORTED;