2 * Copyright 1999 Marcus Meissner
3 * Copyright 2002-2003 Michael Günnewig
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #define COM_NO_WINDOWS_H
41 #include "avifile_private.h"
43 #include "wine/debug.h"
44 #include "wine/unicode.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(avifile
);
49 /***********************************************************************
50 * for AVIBuildFilterW -- uses fixed size table
52 #define MAX_FILTERS 30 /* 30 => 7kB */
54 typedef struct _AVIFilter
{
56 WCHAR szExtensions
[MAX_FILTERS
* 7];
59 /***********************************************************************
66 LPAVICOMPRESSOPTIONS
*ppOptions
;
70 /***********************************************************************
71 * copied from dlls/ole32/compobj.c
73 static HRESULT
AVIFILE_CLSIDFromString(LPCSTR idstr
, LPCLSID id
)
81 memset(id
, 0, sizeof(CLSID
));
85 /* validate the CLSID string */
86 if (lstrlenA(idstr
) != 38)
87 return CO_E_CLASSSTRING
;
89 s
= (BYTE
const*)idstr
;
90 if ((s
[0]!='{') || (s
[9]!='-') || (s
[14]!='-') || (s
[19]!='-') ||
91 (s
[24]!='-') || (s
[37]!='}'))
92 return CO_E_CLASSSTRING
;
94 for (i
= 1; i
< 37; i
++) {
95 if ((i
== 9) || (i
== 14) || (i
== 19) || (i
== 24))
97 if (!(((s
[i
] >= '0') && (s
[i
] <= '9')) ||
98 ((s
[i
] >= 'a') && (s
[i
] <= 'f')) ||
99 ((s
[i
] >= 'A') && (s
[i
] <= 'F')))
101 return CO_E_CLASSSTRING
;
104 TRACE("%s -> %p\n", s
, id
);
106 /* quick lookup table */
107 memset(table
, 0, 256);
109 for (i
= 0; i
< 10; i
++)
112 for (i
= 0; i
< 6; i
++) {
113 table
['A' + i
] = i
+10;
114 table
['a' + i
] = i
+10;
117 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
120 s
++; /* skip leading brace */
121 for (i
= 0; i
< 4; i
++) {
122 p
[3 - i
] = table
[*s
]<<4 | table
[*(s
+1)];
128 for (i
= 0; i
< 2; i
++) {
129 p
[1-i
] = table
[*s
]<<4 | table
[*(s
+1)];
135 for (i
= 0; i
< 2; i
++) {
136 p
[1-i
] = table
[*s
]<<4 | table
[*(s
+1)];
142 /* these are just sequential bytes */
143 for (i
= 0; i
< 2; i
++) {
144 *p
++ = table
[*s
]<<4 | table
[*(s
+1)];
149 for (i
= 0; i
< 6; i
++) {
150 *p
++ = table
[*s
]<<4 | table
[*(s
+1)];
157 static BOOL
AVIFILE_GetFileHandlerByExtension(LPCWSTR szFile
, LPCLSID lpclsid
)
161 LPWSTR szExt
= strrchrW(szFile
, '.');
162 LONG len
= sizeof(szValue
) / sizeof(szValue
[0]);
169 wsprintfA(szRegKey
, "AVIFile\\Extensions\\%.3ls", szExt
);
170 if (RegQueryValueA(HKEY_CLASSES_ROOT
, szRegKey
, szValue
, &len
) != ERROR_SUCCESS
)
173 return (AVIFILE_CLSIDFromString(szValue
, lpclsid
) == S_OK
);
176 /***********************************************************************
177 * AVIFileInit (AVIFIL32.@)
178 * AVIFileInit (AVIFILE.100)
180 void WINAPI
AVIFileInit(void) {
184 /***********************************************************************
185 * AVIFileExit (AVIFIL32.@)
186 * AVIFileExit (AVIFILE.101)
188 void WINAPI
AVIFileExit(void) {
189 /* need to free ole32.dll if we are the last exit call */
190 /* OleUnitialize() */
191 FIXME("(): stub!\n");
194 /***********************************************************************
195 * AVIFileOpen (AVIFIL32.@)
196 * AVIFileOpenA (AVIFIL32.@)
197 * AVIFileOpen (AVIFILE.102)
199 HRESULT WINAPI
AVIFileOpenA(PAVIFILE
*ppfile
, LPCSTR szFile
, UINT uMode
,
202 LPWSTR wszFile
= NULL
;
206 TRACE("(%p,%s,0x%08X,%s)\n", ppfile
, debugstr_a(szFile
), uMode
,
207 debugstr_guid(lpHandler
));
209 /* check parameters */
210 if (ppfile
== NULL
|| szFile
== NULL
)
211 return AVIERR_BADPARAM
;
213 /* convert ASCII string to Unicode and call unicode function */
214 len
= MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, NULL
, 0);
216 return AVIERR_BADPARAM
;
218 wszFile
= (LPWSTR
)LocalAlloc(LPTR
, len
* sizeof(WCHAR
));
220 return AVIERR_MEMORY
;
222 MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, wszFile
, len
);
224 hr
= AVIFileOpenW(ppfile
, wszFile
, uMode
, lpHandler
);
226 LocalFree((HLOCAL
)wszFile
);
231 /***********************************************************************
232 * AVIFileOpenW (AVIFIL32.@)
234 HRESULT WINAPI
AVIFileOpenW(PAVIFILE
*ppfile
, LPCWSTR szFile
, UINT uMode
,
237 IPersistFile
*ppersist
= NULL
;
241 TRACE("(%p,%s,0x%X,%s)\n", ppfile
, debugstr_w(szFile
), uMode
,
242 debugstr_guid(lpHandler
));
244 /* check parameters */
245 if (ppfile
== NULL
|| szFile
== NULL
)
246 return AVIERR_BADPARAM
;
250 /* if no handler then try guessing it by extension */
251 if (lpHandler
== NULL
) {
252 if (! AVIFILE_GetFileHandlerByExtension(szFile
, &clsidHandler
))
253 return AVIERR_UNSUPPORTED
;
255 memcpy(&clsidHandler
, lpHandler
, sizeof(clsidHandler
));
257 /* create instance of handler */
258 hr
= CoCreateInstance(&clsidHandler
, NULL
, CLSCTX_INPROC
, &IID_IAVIFile
, (LPVOID
*)ppfile
);
259 if (FAILED(hr
) || *ppfile
== NULL
)
262 /* ask for IPersistFile interface for loading/creating the file */
263 hr
= IAVIFile_QueryInterface(*ppfile
, &IID_IPersistFile
, (LPVOID
*)&ppersist
);
264 if (FAILED(hr
) || ppersist
== NULL
) {
265 IAVIFile_Release(*ppfile
);
270 hr
= IPersistFile_Load(ppersist
, szFile
, uMode
);
271 IPersistFile_Release(ppersist
);
273 IAVIFile_Release(*ppfile
);
280 /***********************************************************************
281 * AVIFileAddRef (AVIFIL32.@)
282 * AVIFileAddRef (AVIFILE.140)
284 ULONG WINAPI
AVIFileAddRef(PAVIFILE pfile
)
286 TRACE("(%p)\n", pfile
);
289 ERR(": bad handle passed!\n");
293 return IAVIFile_AddRef(pfile
);
296 /***********************************************************************
297 * AVIFileRelease (AVIFIL32.@)
298 * AVIFileRelease (AVIFILE.141)
300 ULONG WINAPI
AVIFileRelease(PAVIFILE pfile
)
302 TRACE("(%p)\n", pfile
);
305 ERR(": bad handle passed!\n");
309 return IAVIFile_Release(pfile
);
312 /***********************************************************************
313 * AVIFileInfo (AVIFIL32.@)
314 * AVIFileInfoA (AVIFIL32.@)
315 * AVIFileInfo (AVIFILE.142)
317 HRESULT WINAPI
AVIFileInfoA(PAVIFILE pfile
, LPAVIFILEINFOA afi
, LONG size
)
322 TRACE("(%p,%p,%ld)\n", pfile
, afi
, size
);
325 return AVIERR_BADHANDLE
;
326 if ((DWORD
)size
< sizeof(AVIFILEINFOA
))
327 return AVIERR_BADSIZE
;
329 hres
= IAVIFile_Info(pfile
, &afiw
, sizeof(afiw
));
331 memcpy(afi
, &afiw
, sizeof(*afi
) - sizeof(afi
->szFileType
));
332 WideCharToMultiByte(CP_ACP
, 0, afiw
.szFileType
, -1, afi
->szFileType
,
333 sizeof(afi
->szFileType
), NULL
, NULL
);
334 afi
->szFileType
[sizeof(afi
->szFileType
) - 1] = 0;
339 /***********************************************************************
340 * AVIFileInfoW (AVIFIL32.@)
342 HRESULT WINAPI
AVIFileInfoW(PAVIFILE pfile
, LPAVIFILEINFOW afiw
, LONG size
)
344 TRACE("(%p,%p,%ld)\n", pfile
, afiw
, size
);
347 return AVIERR_BADHANDLE
;
349 return IAVIFile_Info(pfile
, afiw
, size
);
352 /***********************************************************************
353 * AVIFileGetStream (AVIFIL32.@)
354 * AVIFileGetStream (AVIFILE.143)
356 HRESULT WINAPI
AVIFileGetStream(PAVIFILE pfile
, PAVISTREAM
*avis
,
357 DWORD fccType
, LONG lParam
)
359 TRACE("(%p,%p,'%4.4s',%ld)\n", pfile
, avis
, (char*)&fccType
, lParam
);
362 return AVIERR_BADHANDLE
;
364 return IAVIFile_GetStream(pfile
, avis
, fccType
, lParam
);
367 /***********************************************************************
368 * AVIFileCreateStream (AVIFIL32.@)
369 * AVIFileCreateStreamA (AVIFIL32.@)
370 * AVIFileCreateStream (AVIFILE.144)
372 HRESULT WINAPI
AVIFileCreateStreamA(PAVIFILE pfile
, PAVISTREAM
*ppavi
,
373 LPAVISTREAMINFOA psi
)
377 TRACE("(%p,%p,%p)\n", pfile
, ppavi
, psi
);
380 return AVIERR_BADHANDLE
;
382 /* Only the szName at the end is different */
383 memcpy(&psiw
, psi
, sizeof(*psi
) - sizeof(psi
->szName
));
384 MultiByteToWideChar(CP_ACP
, 0, psi
->szName
, -1, psiw
.szName
,
385 sizeof(psiw
.szName
) / sizeof(psiw
.szName
[0]));
387 return IAVIFile_CreateStream(pfile
, ppavi
, &psiw
);
390 /***********************************************************************
391 * AVIFileCreateStreamW (AVIFIL32.@)
393 HRESULT WINAPI
AVIFileCreateStreamW(PAVIFILE pfile
, PAVISTREAM
*avis
,
394 LPAVISTREAMINFOW asi
)
396 TRACE("(%p,%p,%p)\n", pfile
, avis
, asi
);
399 return AVIERR_BADHANDLE
;
401 return IAVIFile_CreateStream(pfile
, avis
, asi
);
404 /***********************************************************************
405 * AVIFileWriteData (AVIFIL32.@)
406 * AVIFileWriteData (AVIFILE.146)
408 HRESULT WINAPI
AVIFileWriteData(PAVIFILE pfile
,DWORD fcc
,LPVOID lp
,LONG size
)
410 TRACE("(%p,'%4.4s',%p,%ld)\n", pfile
, (char*)&fcc
, lp
, size
);
413 return AVIERR_BADHANDLE
;
415 return IAVIFile_WriteData(pfile
, fcc
, lp
, size
);
418 /***********************************************************************
419 * AVIFileReadData (AVIFIL32.@)
420 * AVIFileReadData (AVIFILE.147)
422 HRESULT WINAPI
AVIFileReadData(PAVIFILE pfile
,DWORD fcc
,LPVOID lp
,LPLONG size
)
424 TRACE("(%p,'%4.4s',%p,%p)\n", pfile
, (char*)&fcc
, lp
, size
);
427 return AVIERR_BADHANDLE
;
429 return IAVIFile_ReadData(pfile
, fcc
, lp
, size
);
432 /***********************************************************************
433 * AVIFileEndRecord (AVIFIL32.@)
434 * AVIFileEndRecord (AVIFILE.148)
436 HRESULT WINAPI
AVIFileEndRecord(PAVIFILE pfile
)
438 TRACE("(%p)\n", pfile
);
441 return AVIERR_BADHANDLE
;
443 return IAVIFile_EndRecord(pfile
);
446 /***********************************************************************
447 * AVIStreamAddRef (AVIFIL32.@)
448 * AVIStreamAddRef (AVIFILE.160)
450 ULONG WINAPI
AVIStreamAddRef(PAVISTREAM pstream
)
452 TRACE("(%p)\n", pstream
);
454 if (pstream
== NULL
) {
455 ERR(": bad handle passed!\n");
459 return IAVIStream_AddRef(pstream
);
462 /***********************************************************************
463 * AVIStreamRelease (AVIFIL32.@)
464 * AVIStreamRelease (AVIFILE.161)
466 ULONG WINAPI
AVIStreamRelease(PAVISTREAM pstream
)
468 TRACE("(%p)\n", pstream
);
470 if (pstream
== NULL
) {
471 ERR(": bad handle passed!\n");
475 return IAVIStream_Release(pstream
);
478 /***********************************************************************
479 * AVIStreamCreate (AVIFIL32.@)
480 * AVIStreamCreate (AVIFILE.104)
482 HRESULT WINAPI
AVIStreamCreate(PAVISTREAM
*ppavi
, LONG lParam1
, LONG lParam2
,
483 LPCLSID pclsidHandler
)
487 TRACE("(%p,0x%08lX,0x%08lX,%s)\n", ppavi
, lParam1
, lParam2
,
488 debugstr_guid(pclsidHandler
));
491 return AVIERR_BADPARAM
;
494 if (pclsidHandler
== NULL
)
495 return AVIERR_UNSUPPORTED
;
497 hr
= CoCreateInstance(pclsidHandler
, NULL
, CLSCTX_INPROC
, &IID_IAVIStream
, (LPVOID
*)ppavi
);
498 if (FAILED(hr
) || *ppavi
== NULL
)
501 hr
= IAVIStream_Create(*ppavi
, lParam1
, lParam2
);
503 IAVIStream_Release(*ppavi
);
510 /***********************************************************************
511 * AVIStreamInfo (AVIFIL32.@)
512 * AVIStreamInfoA (AVIFIL32.@)
513 * AVIStreamInfo (AVIFILE.162)
515 HRESULT WINAPI
AVIStreamInfoA(PAVISTREAM pstream
, LPAVISTREAMINFOA asi
,
521 TRACE("(%p,%p,%ld)\n", pstream
, asi
, size
);
524 return AVIERR_BADHANDLE
;
525 if ((DWORD
)size
< sizeof(AVISTREAMINFOA
))
526 return AVIERR_BADSIZE
;
528 hres
= IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
));
530 memcpy(asi
, &asiw
, sizeof(asiw
) - sizeof(asiw
.szName
));
531 WideCharToMultiByte(CP_ACP
, 0, asiw
.szName
, -1, asi
->szName
,
532 sizeof(asi
->szName
), NULL
, NULL
);
533 asi
->szName
[sizeof(asi
->szName
) - 1] = 0;
538 /***********************************************************************
539 * AVIStreamInfoW (AVIFIL32.@)
541 HRESULT WINAPI
AVIStreamInfoW(PAVISTREAM pstream
, LPAVISTREAMINFOW asi
,
544 TRACE("(%p,%p,%ld)\n", pstream
, asi
, size
);
547 return AVIERR_BADHANDLE
;
549 return IAVIStream_Info(pstream
, asi
, size
);
552 /***********************************************************************
553 * AVIStreamFindSample (AVIFIL32.@)
554 * AVIStreamFindSample (AVIFILE.163)
556 HRESULT WINAPI
AVIStreamFindSample(PAVISTREAM pstream
, LONG pos
, DWORD flags
)
558 TRACE("(%p,%ld,0x%lX)\n", pstream
, pos
, flags
);
563 return IAVIStream_FindSample(pstream
, pos
, flags
);
566 /***********************************************************************
567 * AVIStreamReadFormat (AVIFIL32.@)
568 * AVIStreamReadFormat (AVIFILE.164)
570 HRESULT WINAPI
AVIStreamReadFormat(PAVISTREAM pstream
, LONG pos
,
571 LPVOID format
, LPLONG formatsize
)
573 TRACE("(%p,%ld,%p,%p)\n", pstream
, pos
, format
, formatsize
);
576 return AVIERR_BADHANDLE
;
578 return IAVIStream_ReadFormat(pstream
, pos
, format
, formatsize
);
581 /***********************************************************************
582 * AVIStreamSetFormat (AVIFIL32.@)
583 * AVIStreamSetFormat (AVIFILE.169)
585 HRESULT WINAPI
AVIStreamSetFormat(PAVISTREAM pstream
, LONG pos
,
586 LPVOID format
, LONG formatsize
)
588 TRACE("(%p,%ld,%p,%ld)\n", pstream
, pos
, format
, formatsize
);
591 return AVIERR_BADHANDLE
;
593 return IAVIStream_SetFormat(pstream
, pos
, format
, formatsize
);
596 /***********************************************************************
597 * AVIStreamRead (AVIFIL32.@)
598 * AVIStreamRead (AVIFILE.167)
600 HRESULT WINAPI
AVIStreamRead(PAVISTREAM pstream
, LONG start
, LONG samples
,
601 LPVOID buffer
, LONG buffersize
,
602 LPLONG bytesread
, LPLONG samplesread
)
604 TRACE("(%p,%ld,%ld,%p,%ld,%p,%p)\n", pstream
, start
, samples
, buffer
,
605 buffersize
, bytesread
, samplesread
);
608 return AVIERR_BADHANDLE
;
610 return IAVIStream_Read(pstream
, start
, samples
, buffer
, buffersize
,
611 bytesread
, samplesread
);
614 /***********************************************************************
615 * AVIStreamWrite (AVIFIL32.@)
616 * AVIStreamWrite (AVIFILE.168)
618 HRESULT WINAPI
AVIStreamWrite(PAVISTREAM pstream
, LONG start
, LONG samples
,
619 LPVOID buffer
, LONG buffersize
, DWORD flags
,
620 LPLONG sampwritten
, LPLONG byteswritten
)
622 TRACE("(%p,%ld,%ld,%p,%ld,0x%lX,%p,%p)\n", pstream
, start
, samples
, buffer
,
623 buffersize
, flags
, sampwritten
, byteswritten
);
626 return AVIERR_BADHANDLE
;
628 return IAVIStream_Write(pstream
, start
, samples
, buffer
, buffersize
,
629 flags
, sampwritten
, byteswritten
);
632 /***********************************************************************
633 * AVIStreamReadData (AVIFIL32.@)
634 * AVIStreamReadData (AVIFILE.165)
636 HRESULT WINAPI
AVIStreamReadData(PAVISTREAM pstream
, DWORD fcc
, LPVOID lp
,
639 TRACE("(%p,'%4.4s',%p,%p)\n", pstream
, (char*)&fcc
, lp
, lpread
);
642 return AVIERR_BADHANDLE
;
644 return IAVIStream_ReadData(pstream
, fcc
, lp
, lpread
);
647 /***********************************************************************
648 * AVIStreamWriteData (AVIFIL32.@)
649 * AVIStreamWriteData (AVIFILE.166)
651 HRESULT WINAPI
AVIStreamWriteData(PAVISTREAM pstream
, DWORD fcc
, LPVOID lp
,
654 TRACE("(%p,'%4.4s',%p,%ld)\n", pstream
, (char*)&fcc
, lp
, size
);
657 return AVIERR_BADHANDLE
;
659 return IAVIStream_WriteData(pstream
, fcc
, lp
, size
);
662 /***********************************************************************
663 * AVIStreamGetFrameOpen (AVIFIL32.@)
664 * AVIStreamGetFrameOpen (AVIFILE.112)
666 PGETFRAME WINAPI
AVIStreamGetFrameOpen(PAVISTREAM pstream
,
667 LPBITMAPINFOHEADER lpbiWanted
)
671 TRACE("(%p,%p)\n", pstream
, lpbiWanted
);
673 if (FAILED(IAVIStream_QueryInterface(pstream
, &IID_IGetFrame
, (LPVOID
*)&pg
)) ||
675 pg
= AVIFILE_CreateGetFrame(pstream
);
680 if (FAILED(IGetFrame_SetFormat(pg
, lpbiWanted
, NULL
, 0, 0, -1, -1))) {
681 IGetFrame_Release(pg
);
688 /***********************************************************************
689 * AVIStreamGetFrame (AVIFIL32.@)
690 * AVIStreamGetFrame (AVIFILE.110)
692 LPVOID WINAPI
AVIStreamGetFrame(PGETFRAME pg
, LONG pos
)
694 TRACE("(%p,%ld)\n", pg
, pos
);
699 return IGetFrame_GetFrame(pg
, pos
);
702 /***********************************************************************
703 * AVIStreamGetFrameClose (AVIFIL32.@)
704 * AVIStreamGetFrameClose (AVIFILE.111)
706 HRESULT WINAPI
AVIStreamGetFrameClose(PGETFRAME pg
)
711 return IGetFrame_Release(pg
);
715 /***********************************************************************
716 * AVIMakeCompressedStream (AVIFIL32.@)
718 HRESULT WINAPI
AVIMakeCompressedStream(PAVISTREAM
*ppsCompressed
,
720 LPAVICOMPRESSOPTIONS aco
,
721 LPCLSID pclsidHandler
)
728 LONG size
= sizeof(szValue
);
730 TRACE("(%p,%p,%p,%s)\n", ppsCompressed
, psSource
, aco
,
731 debugstr_guid(pclsidHandler
));
733 if (ppsCompressed
== NULL
)
734 return AVIERR_BADPARAM
;
735 if (psSource
== NULL
)
736 return AVIERR_BADHANDLE
;
738 *ppsCompressed
= NULL
;
740 /* if no handler given get default ones based on streamtype */
741 if (pclsidHandler
== NULL
) {
742 hr
= IAVIStream_Info(psSource
, &asiw
, sizeof(asiw
));
746 wsprintfA(szRegKey
, "AVIFile\\Compressors\\%4.4s", (char*)&asiw
.fccType
);
747 if (RegQueryValueA(HKEY_CLASSES_ROOT
, szRegKey
, szValue
, &size
) != ERROR_SUCCESS
)
748 return AVIERR_UNSUPPORTED
;
749 if (AVIFILE_CLSIDFromString(szValue
, &clsidHandler
) != S_OK
)
750 return AVIERR_UNSUPPORTED
;
752 memcpy(&clsidHandler
, pclsidHandler
, sizeof(clsidHandler
));
754 hr
= CoCreateInstance(&clsidHandler
, NULL
, CLSCTX_INPROC
, &IID_IAVIStream
, (LPVOID
*)ppsCompressed
);
755 if (FAILED(hr
) || *ppsCompressed
== NULL
)
758 hr
= IAVIStream_Create(*ppsCompressed
, (LPARAM
)psSource
, (LPARAM
)aco
);
760 IAVIStream_Release(*ppsCompressed
);
761 *ppsCompressed
= NULL
;
767 /***********************************************************************
768 * AVIMakeFileFromStreams (AVIFIL32.@)
770 HRESULT WINAPI
AVIMakeFileFromStreams(PAVIFILE
*ppfile
, int nStreams
,
771 PAVISTREAM
*ppStreams
)
773 TRACE("(%p,%d,%p)\n", ppfile
, nStreams
, ppStreams
);
775 if (nStreams
< 0 || ppfile
== NULL
|| ppStreams
== NULL
)
776 return AVIERR_BADPARAM
;
778 *ppfile
= AVIFILE_CreateAVITempFile(nStreams
, ppStreams
);
780 return AVIERR_MEMORY
;
785 /***********************************************************************
786 * AVIStreamOpenFromFile (AVIFIL32.@)
787 * AVIStreamOpenFromFileA (AVIFIL32.@)
788 * AVIStreamOpenFromFile (AVIFILE.103)
790 HRESULT WINAPI
AVIStreamOpenFromFileA(PAVISTREAM
*ppavi
, LPCSTR szFile
,
791 DWORD fccType
, LONG lParam
,
792 UINT mode
, LPCLSID pclsidHandler
)
794 PAVIFILE pfile
= NULL
;
797 TRACE("(%p,%s,'%4.4s',%ld,0x%X,%s)\n", ppavi
, debugstr_a(szFile
),
798 (char*)&fccType
, lParam
, mode
, debugstr_guid(pclsidHandler
));
800 if (ppavi
== NULL
|| szFile
== NULL
)
801 return AVIERR_BADPARAM
;
805 hr
= AVIFileOpenA(&pfile
, szFile
, mode
, pclsidHandler
);
806 if (FAILED(hr
) || pfile
== NULL
)
809 hr
= IAVIFile_GetStream(pfile
, ppavi
, fccType
, lParam
);
810 IAVIFile_Release(pfile
);
815 /***********************************************************************
816 * AVIStreamOpenFromFileW (AVIFIL32.@)
818 HRESULT WINAPI
AVIStreamOpenFromFileW(PAVISTREAM
*ppavi
, LPCWSTR szFile
,
819 DWORD fccType
, LONG lParam
,
820 UINT mode
, LPCLSID pclsidHandler
)
822 PAVIFILE pfile
= NULL
;
825 TRACE("(%p,%s,'%4.4s',%ld,0x%X,%s)\n", ppavi
, debugstr_w(szFile
),
826 (char*)&fccType
, lParam
, mode
, debugstr_guid(pclsidHandler
));
828 if (ppavi
== NULL
|| szFile
== NULL
)
829 return AVIERR_BADPARAM
;
833 hr
= AVIFileOpenW(&pfile
, szFile
, mode
, pclsidHandler
);
834 if (FAILED(hr
) || pfile
== NULL
)
837 hr
= IAVIFile_GetStream(pfile
, ppavi
, fccType
, lParam
);
838 IAVIFile_Release(pfile
);
843 /***********************************************************************
844 * AVIStreamBeginStreaming (AVIFIL32.@)
846 LONG WINAPI
AVIStreamBeginStreaming(PAVISTREAM pavi
, LONG lStart
, LONG lEnd
, LONG lRate
)
848 IAVIStreaming
* pstream
= NULL
;
851 TRACE("(%p,%ld,%ld,%ld)\n", pavi
, lStart
, lEnd
, lRate
);
854 return AVIERR_BADHANDLE
;
856 hr
= IAVIStream_QueryInterface(pavi
, &IID_IAVIStreaming
, (LPVOID
*)&pstream
);
857 if (SUCCEEDED(hr
) && pstream
!= NULL
) {
858 hr
= IAVIStreaming_Begin(pstream
, lStart
, lEnd
, lRate
);
859 IAVIStreaming_Release(pstream
);
866 /***********************************************************************
867 * AVIStreamEndStreaming (AVIFIL32.@)
869 LONG WINAPI
AVIStreamEndStreaming(PAVISTREAM pavi
)
871 IAVIStreaming
* pstream
= NULL
;
874 TRACE("(%p)\n", pavi
);
876 hr
= IAVIStream_QueryInterface(pavi
, &IID_IAVIStreaming
, (LPVOID
*)&pstream
);
877 if (SUCCEEDED(hr
) && pstream
!= NULL
) {
878 IAVIStreaming_End(pstream
);
879 IAVIStreaming_Release(pstream
);
885 /***********************************************************************
886 * AVIStreamStart (AVIFILE.130)
887 * AVIStreamStart (AVIFIL32.@)
889 LONG WINAPI
AVIStreamStart(PAVISTREAM pstream
)
893 TRACE("(%p)\n", pstream
);
898 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
904 /***********************************************************************
905 * AVIStreamLength (AVIFILE.131)
906 * AVIStreamLength (AVIFIL32.@)
908 LONG WINAPI
AVIStreamLength(PAVISTREAM pstream
)
912 TRACE("(%p)\n", pstream
);
917 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
920 return asiw
.dwLength
;
923 /***********************************************************************
924 * AVIStreamSampleToTime (AVIFILE.133)
925 * AVIStreamSampleToTime (AVIFIL32.@)
927 LONG WINAPI
AVIStreamSampleToTime(PAVISTREAM pstream
, LONG lSample
)
932 TRACE("(%p,%ld)\n", pstream
, lSample
);
937 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
939 if (asiw
.dwRate
== 0)
942 /* limit to stream bounds */
943 if (lSample
< asiw
.dwStart
)
944 lSample
= asiw
.dwStart
;
945 if (lSample
> asiw
.dwStart
+ asiw
.dwLength
)
946 lSample
= asiw
.dwStart
+ asiw
.dwLength
;
948 if (asiw
.dwRate
/ asiw
.dwScale
< 1000)
949 time
= (LONG
)(((float)lSample
* asiw
.dwScale
* 1000) / asiw
.dwRate
);
951 time
= (LONG
)(((float)lSample
* asiw
.dwScale
* 1000 + (asiw
.dwRate
- 1)) / asiw
.dwRate
);
953 TRACE(" -> %ld\n",time
);
957 /***********************************************************************
958 * AVIStreamTimeToSample (AVIFILE.132)
959 * AVIStreamTimeToSample (AVIFIL32.@)
961 LONG WINAPI
AVIStreamTimeToSample(PAVISTREAM pstream
, LONG lTime
)
966 TRACE("(%p,%ld)\n", pstream
, lTime
);
968 if (pstream
== NULL
|| lTime
< 0)
971 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
973 if (asiw
.dwScale
== 0)
976 if (asiw
.dwRate
/ asiw
.dwScale
< 1000)
977 sample
= (LONG
)((((float)asiw
.dwRate
* lTime
) / (asiw
.dwScale
* 1000)));
979 sample
= (LONG
)(((float)asiw
.dwRate
* lTime
+ (asiw
.dwScale
* 1000 - 1)) / (asiw
.dwScale
* 1000));
981 /* limit to stream bounds */
982 if (sample
< asiw
.dwStart
)
983 sample
= asiw
.dwStart
;
984 if (sample
> asiw
.dwStart
+ asiw
.dwLength
)
985 sample
= asiw
.dwStart
+ asiw
.dwLength
;
987 TRACE(" -> %ld\n", sample
);
991 /***********************************************************************
992 * AVIBuildFilter (AVIFIL32.@)
993 * AVIBuildFilterA (AVIFIL32.@)
994 * AVIBuildFilter (AVIFILE.123)
996 HRESULT WINAPI
AVIBuildFilterA(LPSTR szFilter
, LONG cbFilter
, BOOL fSaving
)
1001 TRACE("(%p,%ld,%d)\n", szFilter
, cbFilter
, fSaving
);
1003 /* check parameters */
1004 if (szFilter
== NULL
)
1005 return AVIERR_BADPARAM
;
1007 return AVIERR_BADSIZE
;
1012 wszFilter
= (LPWSTR
)GlobalAllocPtr(GHND
, cbFilter
* sizeof(WCHAR
));
1013 if (wszFilter
== NULL
)
1014 return AVIERR_MEMORY
;
1016 hr
= AVIBuildFilterW(wszFilter
, cbFilter
, fSaving
);
1017 if (SUCCEEDED(hr
)) {
1018 WideCharToMultiByte(CP_ACP
, 0, wszFilter
, cbFilter
,
1019 szFilter
, cbFilter
, NULL
, NULL
);
1022 GlobalFreePtr(wszFilter
);
1027 /***********************************************************************
1028 * AVIBuildFilterW (AVIFIL32.@)
1030 HRESULT WINAPI
AVIBuildFilterW(LPWSTR szFilter
, LONG cbFilter
, BOOL fSaving
)
1032 static const WCHAR szClsid
[] = {'C','L','S','I','D',0};
1033 static const WCHAR szExtensionFmt
[] = {';','*','.','%','s',0};
1034 static const WCHAR szAVIFileExtensions
[] =
1035 {'A','V','I','F','i','l','e','\\','E','x','t','e','n','s','i','o','n','s',0};
1038 WCHAR szAllFiles
[40];
1039 WCHAR szFileExt
[10];
1046 TRACE("(%p,%ld,%d)\n", szFilter
, cbFilter
, fSaving
);
1048 /* check parameters */
1049 if (szFilter
== NULL
)
1050 return AVIERR_BADPARAM
;
1052 return AVIERR_BADSIZE
;
1054 lp
= (AVIFilter
*)GlobalAllocPtr(GHND
, MAX_FILTERS
* sizeof(AVIFilter
));
1056 return AVIERR_MEMORY
;
1059 * 1. iterate over HKEY_CLASSES_ROOT\\AVIFile\\Extensions and collect
1060 * extensions and CLSID's
1061 * 2. iterate over collected CLSID's and copy its description and its
1062 * extensions to szFilter if it fits
1064 * First filter is named "All multimedia files" and its filter is a
1065 * collection of all possible extensions except "*.*".
1067 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, szAVIFileExtensions
, &hKey
) != S_OK
) {
1069 return AVIERR_ERROR
;
1071 for (n
= 0;RegEnumKeyW(hKey
, n
, szFileExt
, sizeof(szFileExt
)) == S_OK
;n
++) {
1072 /* get CLSID to extension */
1073 size
= sizeof(szValue
)/sizeof(szValue
[0]);
1074 if (RegQueryValueW(hKey
, szFileExt
, szValue
, &size
) != S_OK
)
1077 /* search if the CLSID is already known */
1078 for (i
= 1; i
<= count
; i
++) {
1079 if (lstrcmpW(lp
[i
].szClsid
, szValue
) == 0)
1080 break; /* a new one */
1083 if (count
- i
== -1U) {
1084 /* it's a new CLSID */
1086 /* FIXME: How do we get info's about read/write capabilities? */
1088 if (count
>= MAX_FILTERS
) {
1089 /* try to inform user of our full fixed size table */
1090 ERR(": More than %d filters found! Adjust MAX_FILTERS in dlls/avifil32/api.c\n", MAX_FILTERS
);
1094 lstrcpyW(lp
[i
].szClsid
, szValue
);
1099 /* append extension to the filter */
1100 wsprintfW(szValue
, szExtensionFmt
, szFileExt
);
1101 if (lp
[i
].szExtensions
[0] == 0)
1102 lstrcatW(lp
[i
].szExtensions
, szValue
+ 1);
1104 lstrcatW(lp
[i
].szExtensions
, szValue
);
1106 /* also append to the "all multimedia"-filter */
1107 if (lp
[0].szExtensions
[0] == 0)
1108 lstrcatW(lp
[0].szExtensions
, szValue
+ 1);
1110 lstrcatW(lp
[0].szExtensions
, szValue
);
1114 /* 2. get descriptions for the CLSIDs and fill out szFilter */
1115 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, szClsid
, &hKey
) != S_OK
) {
1117 return AVIERR_ERROR
;
1119 for (n
= 0; n
<= count
; n
++) {
1120 /* first the description */
1122 size
= sizeof(szValue
)/sizeof(szValue
[0]);
1123 if (RegQueryValueW(hKey
, lp
[n
].szClsid
, szValue
, &size
) == S_OK
) {
1124 size
= lstrlenW(szValue
);
1125 lstrcpynW(szFilter
, szValue
, cbFilter
);
1128 size
= LoadStringW(AVIFILE_hModule
,IDS_ALLMULTIMEDIA
,szFilter
,cbFilter
);
1130 /* check for enough space */
1132 if (cbFilter
< size
+ lstrlenW(lp
[n
].szExtensions
) + 2) {
1137 return AVIERR_BUFFERTOOSMALL
;
1142 /* and then the filter */
1143 lstrcpynW(szFilter
, lp
[n
].szExtensions
, cbFilter
);
1144 size
= lstrlenW(lp
[n
].szExtensions
) + 1;
1152 /* add "All files" "*.*" filter if enough space left */
1153 size
= LoadStringW(AVIFILE_hModule
, IDS_ALLFILES
,
1154 szAllFiles
, sizeof(szAllFiles
)) + 1;
1155 if (cbFilter
> size
) {
1158 /* replace '@' with \000 to separate description of filter */
1159 for (i
= 0; i
< size
&& szAllFiles
[i
] != 0; i
++) {
1160 if (szAllFiles
[i
] == '@') {
1166 memcpy(szFilter
, szAllFiles
, size
* sizeof(szAllFiles
[0]));
1173 return AVIERR_BUFFERTOOSMALL
;
1177 static BOOL
AVISaveOptionsFmtChoose(HWND hWnd
)
1179 LPAVICOMPRESSOPTIONS pOptions
= SaveOpts
.ppOptions
[SaveOpts
.nCurrent
];
1180 AVISTREAMINFOW sInfo
;
1182 TRACE("(%p)\n", hWnd
);
1184 if (pOptions
== NULL
|| SaveOpts
.ppavis
[SaveOpts
.nCurrent
] == NULL
) {
1185 ERR(": bad state!\n");
1189 if (FAILED(AVIStreamInfoW(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1190 &sInfo
, sizeof(sInfo
)))) {
1191 ERR(": AVIStreamInfoW failed!\n");
1195 if (sInfo
.fccType
== streamtypeVIDEO
) {
1199 memset(&cv
, 0, sizeof(cv
));
1201 if ((pOptions
->dwFlags
& AVICOMPRESSF_VALID
) == 0) {
1202 memset(pOptions
, 0, sizeof(AVICOMPRESSOPTIONS
));
1203 pOptions
->fccType
= streamtypeVIDEO
;
1204 pOptions
->fccHandler
= comptypeDIB
;
1205 pOptions
->dwQuality
= (DWORD
)ICQUALITY_DEFAULT
;
1208 cv
.cbSize
= sizeof(cv
);
1209 cv
.dwFlags
= ICMF_COMPVARS_VALID
;
1210 /*cv.fccType = pOptions->fccType; */
1211 cv
.fccHandler
= pOptions
->fccHandler
;
1212 cv
.lQ
= pOptions
->dwQuality
;
1213 cv
.lpState
= pOptions
->lpParms
;
1214 cv
.cbState
= pOptions
->cbParms
;
1215 if (pOptions
->dwFlags
& AVICOMPRESSF_KEYFRAMES
)
1216 cv
.lKey
= pOptions
->dwKeyFrameEvery
;
1219 if (pOptions
->dwFlags
& AVICOMPRESSF_DATARATE
)
1220 cv
.lDataRate
= pOptions
->dwBytesPerSecond
/ 1024; /* need kBytes */
1224 ret
= ICCompressorChoose(hWnd
, SaveOpts
.uFlags
, NULL
,
1225 SaveOpts
.ppavis
[SaveOpts
.nCurrent
], &cv
, NULL
);
1228 pOptions
->fccHandler
= cv
.fccHandler
;
1229 pOptions
->lpParms
= cv
.lpState
;
1230 pOptions
->cbParms
= cv
.cbState
;
1231 pOptions
->dwQuality
= cv
.lQ
;
1233 pOptions
->dwKeyFrameEvery
= cv
.lKey
;
1234 pOptions
->dwFlags
|= AVICOMPRESSF_KEYFRAMES
;
1236 pOptions
->dwFlags
&= ~AVICOMPRESSF_KEYFRAMES
;
1237 if (cv
.lDataRate
!= 0) {
1238 pOptions
->dwBytesPerSecond
= cv
.lDataRate
* 1024; /* need bytes */
1239 pOptions
->dwFlags
|= AVICOMPRESSF_DATARATE
;
1241 pOptions
->dwFlags
&= ~AVICOMPRESSF_DATARATE
;
1242 pOptions
->dwFlags
|= AVICOMPRESSF_VALID
;
1244 ICCompressorFree(&cv
);
1247 } else if (sInfo
.fccType
== streamtypeAUDIO
) {
1248 ACMFORMATCHOOSEW afmtc
;
1252 /* FIXME: check ACM version -- Which version is needed? */
1254 memset(&afmtc
, 0, sizeof(afmtc
));
1255 afmtc
.cbStruct
= sizeof(afmtc
);
1257 afmtc
.hwndOwner
= hWnd
;
1259 acmMetrics(NULL
, ACM_METRIC_MAX_SIZE_FORMAT
, &size
);
1260 if ((pOptions
->cbFormat
== 0 || pOptions
->lpFormat
== NULL
) && size
!= 0) {
1261 pOptions
->lpFormat
= GlobalAllocPtr(GMEM_MOVEABLE
, size
);
1262 pOptions
->cbFormat
= size
;
1263 } else if (pOptions
->cbFormat
< (DWORD
)size
) {
1264 pOptions
->lpFormat
= GlobalReAllocPtr(pOptions
->lpFormat
, size
, GMEM_MOVEABLE
);
1265 pOptions
->cbFormat
= size
;
1267 if (pOptions
->lpFormat
== NULL
)
1269 afmtc
.pwfx
= pOptions
->lpFormat
;
1270 afmtc
.cbwfx
= pOptions
->cbFormat
;
1273 AVIStreamFormatSize(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1274 sInfo
.dwStart
, &size
);
1275 if (size
< (LONG
)sizeof(PCMWAVEFORMAT
))
1276 size
= sizeof(PCMWAVEFORMAT
);
1277 afmtc
.pwfxEnum
= GlobalAllocPtr(GHND
, size
);
1278 if (afmtc
.pwfxEnum
!= NULL
) {
1279 AVIStreamReadFormat(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1280 sInfo
.dwStart
, afmtc
.pwfxEnum
, &size
);
1281 afmtc
.fdwEnum
= ACM_FORMATENUMF_CONVERT
;
1284 ret
= acmFormatChooseW(&afmtc
);
1286 pOptions
->dwFlags
|= AVICOMPRESSF_VALID
;
1288 if (afmtc
.pwfxEnum
!= NULL
)
1289 GlobalFreePtr(afmtc
.pwfxEnum
);
1291 return (ret
== S_OK
? TRUE
: FALSE
);
1293 ERR(": unknown streamtype 0x%08lX\n", sInfo
.fccType
);
1298 static void AVISaveOptionsUpdate(HWND hWnd
)
1300 static const WCHAR szVideoFmt
[]={'%','l','d','x','%','l','d','x','%','d',0};
1301 static const WCHAR szAudioFmt
[]={'%','s',' ','%','s',0};
1303 WCHAR szFormat
[128];
1304 AVISTREAMINFOW sInfo
;
1308 TRACE("(%p)\n", hWnd
);
1310 SaveOpts
.nCurrent
= SendDlgItemMessageW(hWnd
,IDC_STREAM
,CB_GETCURSEL
,0,0);
1311 if (SaveOpts
.nCurrent
< 0)
1314 if (FAILED(AVIStreamInfoW(SaveOpts
.ppavis
[SaveOpts
.nCurrent
], &sInfo
, sizeof(sInfo
))))
1317 AVIStreamFormatSize(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],sInfo
.dwStart
,&size
);
1321 /* read format to build format description string */
1322 lpFormat
= GlobalAllocPtr(GHND
, size
);
1323 if (lpFormat
!= NULL
) {
1324 if (SUCCEEDED(AVIStreamReadFormat(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],sInfo
.dwStart
,lpFormat
, &size
))) {
1325 if (sInfo
.fccType
== streamtypeVIDEO
) {
1326 LPBITMAPINFOHEADER lpbi
= lpFormat
;
1329 wsprintfW(szFormat
, szVideoFmt
, lpbi
->biWidth
,
1330 lpbi
->biHeight
, lpbi
->biBitCount
);
1332 if (lpbi
->biCompression
!= BI_RGB
) {
1335 hic
= ICLocate(ICTYPE_VIDEO
, sInfo
.fccHandler
, lpFormat
,
1336 NULL
, ICMODE_DECOMPRESS
);
1338 if (ICGetInfo(hic
, &icinfo
, sizeof(icinfo
)) == S_OK
)
1339 lstrcatW(szFormat
, icinfo
.szDescription
);
1343 LoadStringW(AVIFILE_hModule
, IDS_UNCOMPRESSED
,
1344 icinfo
.szDescription
, sizeof(icinfo
.szDescription
));
1345 lstrcatW(szFormat
, icinfo
.szDescription
);
1347 } else if (sInfo
.fccType
== streamtypeAUDIO
) {
1348 ACMFORMATTAGDETAILSW aftd
;
1349 ACMFORMATDETAILSW afd
;
1351 memset(&aftd
, 0, sizeof(aftd
));
1352 memset(&afd
, 0, sizeof(afd
));
1354 aftd
.cbStruct
= sizeof(aftd
);
1355 aftd
.dwFormatTag
= afd
.dwFormatTag
=
1356 ((PWAVEFORMATEX
)lpFormat
)->wFormatTag
;
1357 aftd
.cbFormatSize
= afd
.cbwfx
= size
;
1359 afd
.cbStruct
= sizeof(afd
);
1360 afd
.pwfx
= lpFormat
;
1362 if (acmFormatTagDetailsW(NULL
, &aftd
,
1363 ACM_FORMATTAGDETAILSF_FORMATTAG
) == S_OK
) {
1364 if (acmFormatDetailsW(NULL
,&afd
,ACM_FORMATDETAILSF_FORMAT
) == S_OK
)
1365 wsprintfW(szFormat
, szAudioFmt
, afd
.szFormat
, aftd
.szFormatTag
);
1369 GlobalFreePtr(lpFormat
);
1372 /* set text for format description */
1373 SetDlgItemTextW(hWnd
, IDC_FORMATTEXT
, szFormat
);
1375 /* Disable option button for unsupported streamtypes */
1376 if (sInfo
.fccType
== streamtypeVIDEO
||
1377 sInfo
.fccType
== streamtypeAUDIO
)
1378 EnableWindow(GetDlgItem(hWnd
, IDC_OPTIONS
), TRUE
);
1380 EnableWindow(GetDlgItem(hWnd
, IDC_OPTIONS
), FALSE
);
1385 static INT_PTR CALLBACK
AVISaveOptionsDlgProc(HWND hWnd
, UINT uMsg
,
1386 WPARAM wParam
, LPARAM lParam
)
1389 BOOL bIsInterleaved
;
1392 /*TRACE("(%p,%u,0x%04X,0x%08lX)\n", hWnd, uMsg, wParam, lParam);*/
1396 SaveOpts
.nCurrent
= 0;
1397 if (SaveOpts
.nStreams
== 1) {
1398 EndDialog(hWnd
, AVISaveOptionsFmtChoose(hWnd
));
1403 for (n
= 0; n
< SaveOpts
.nStreams
; n
++) {
1404 AVISTREAMINFOW sInfo
;
1406 AVIStreamInfoW(SaveOpts
.ppavis
[n
], &sInfo
, sizeof(sInfo
));
1407 SendDlgItemMessageW(hWnd
, IDC_STREAM
, CB_ADDSTRING
,
1408 0L, (LPARAM
)sInfo
.szName
);
1411 /* select first stream */
1412 SendDlgItemMessageW(hWnd
, IDC_STREAM
, CB_SETCURSEL
, 0, 0);
1413 SendMessageW(hWnd
, WM_COMMAND
,
1414 GET_WM_COMMAND_MPS(IDC_STREAM
, hWnd
, CBN_SELCHANGE
));
1416 /* initialize interleave */
1417 if (SaveOpts
.ppOptions
[0] != NULL
&&
1418 (SaveOpts
.ppOptions
[0]->dwFlags
& AVICOMPRESSF_VALID
)) {
1419 bIsInterleaved
= (SaveOpts
.ppOptions
[0]->dwFlags
& AVICOMPRESSF_INTERLEAVE
);
1420 dwInterleave
= SaveOpts
.ppOptions
[0]->dwInterleaveEvery
;
1422 bIsInterleaved
= TRUE
;
1425 CheckDlgButton(hWnd
, IDC_INTERLEAVE
, bIsInterleaved
);
1426 SetDlgItemInt(hWnd
, IDC_INTERLEAVEEVERY
, dwInterleave
, FALSE
);
1427 EnableWindow(GetDlgItem(hWnd
, IDC_INTERLEAVEEVERY
), bIsInterleaved
);
1430 switch (GET_WM_COMMAND_ID(wParam
, lParam
)) {
1432 /* get data from controls and save them */
1433 dwInterleave
= GetDlgItemInt(hWnd
, IDC_INTERLEAVEEVERY
, NULL
, 0);
1434 bIsInterleaved
= IsDlgButtonChecked(hWnd
, IDC_INTERLEAVE
);
1435 for (n
= 0; n
< SaveOpts
.nStreams
; n
++) {
1436 if (SaveOpts
.ppOptions
[n
] != NULL
) {
1437 if (bIsInterleaved
) {
1438 SaveOpts
.ppOptions
[n
]->dwFlags
|= AVICOMPRESSF_INTERLEAVE
;
1439 SaveOpts
.ppOptions
[n
]->dwInterleaveEvery
= dwInterleave
;
1441 SaveOpts
.ppOptions
[n
]->dwFlags
&= ~AVICOMPRESSF_INTERLEAVE
;
1446 EndDialog(hWnd
, GET_WM_COMMAND_ID(wParam
, lParam
) == IDOK
);
1448 case IDC_INTERLEAVE
:
1449 EnableWindow(GetDlgItem(hWnd
, IDC_INTERLEAVEEVERY
),
1450 IsDlgButtonChecked(hWnd
, IDC_INTERLEAVE
));
1453 if (GET_WM_COMMAND_CMD(wParam
, lParam
) == CBN_SELCHANGE
) {
1454 /* update control elements */
1455 AVISaveOptionsUpdate(hWnd
);
1459 AVISaveOptionsFmtChoose(hWnd
);
1468 /***********************************************************************
1469 * AVISaveOptions (AVIFIL32.@)
1471 BOOL WINAPI
AVISaveOptions(HWND hWnd
, UINT uFlags
, INT nStreams
,
1472 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*ppOptions
)
1474 LPAVICOMPRESSOPTIONS pSavedOptions
= NULL
;
1477 TRACE("(%p,0x%X,%d,%p,%p)\n", hWnd
, uFlags
, nStreams
,
1480 /* check parameters */
1481 if (nStreams
<= 0 || ppavi
== NULL
|| ppOptions
== NULL
)
1482 return AVIERR_BADPARAM
;
1484 /* save options in case the user presses cancel */
1485 if (ppOptions
!= NULL
&& nStreams
> 1) {
1486 pSavedOptions
= GlobalAllocPtr(GHND
,nStreams
* sizeof(AVICOMPRESSOPTIONS
));
1487 if (pSavedOptions
== NULL
)
1490 for (n
= 0; n
< nStreams
; n
++) {
1491 if (ppOptions
[n
] != NULL
)
1492 memcpy(pSavedOptions
+ n
, ppOptions
[n
], sizeof(AVICOMPRESSOPTIONS
));
1496 SaveOpts
.uFlags
= uFlags
;
1497 SaveOpts
.nStreams
= nStreams
;
1498 SaveOpts
.ppavis
= ppavi
;
1499 SaveOpts
.ppOptions
= ppOptions
;
1501 ret
= DialogBoxW(AVIFILE_hModule
, MAKEINTRESOURCEW(IDD_SAVEOPTIONS
),
1502 hWnd
, AVISaveOptionsDlgProc
);
1507 /* restore options when user pressed cancel */
1508 if (pSavedOptions
!= NULL
) {
1510 for (n
= 0; n
< nStreams
; n
++) {
1511 if (ppOptions
[n
] != NULL
)
1512 memcpy(ppOptions
[n
], pSavedOptions
+ n
, sizeof(AVICOMPRESSOPTIONS
));
1515 GlobalFreePtr(pSavedOptions
);
1521 /***********************************************************************
1522 * AVISaveOptionsFree (AVIFIL32.@)
1523 * AVISaveOptionsFree (AVIFILE.124)
1525 HRESULT WINAPI
AVISaveOptionsFree(INT nStreams
,LPAVICOMPRESSOPTIONS
*ppOptions
)
1527 TRACE("(%d,%p)\n", nStreams
, ppOptions
);
1529 if (nStreams
< 0 || ppOptions
== NULL
)
1530 return AVIERR_BADPARAM
;
1532 for (; nStreams
> 0; nStreams
--) {
1533 if (ppOptions
[nStreams
] != NULL
) {
1534 ppOptions
[nStreams
]->dwFlags
&= ~AVICOMPRESSF_VALID
;
1536 if (ppOptions
[nStreams
]->lpParms
!= NULL
) {
1537 GlobalFreePtr(ppOptions
[nStreams
]->lpParms
);
1538 ppOptions
[nStreams
]->lpParms
= NULL
;
1539 ppOptions
[nStreams
]->cbParms
= 0;
1541 if (ppOptions
[nStreams
]->lpFormat
!= NULL
) {
1542 GlobalFreePtr(ppOptions
[nStreams
]->lpFormat
);
1543 ppOptions
[nStreams
]->lpFormat
= NULL
;
1544 ppOptions
[nStreams
]->cbFormat
= 0;
1552 /***********************************************************************
1553 * AVISaveVA (AVIFIL32.@)
1555 HRESULT WINAPI
AVISaveVA(LPCSTR szFile
, CLSID
*pclsidHandler
,
1556 AVISAVECALLBACK lpfnCallback
, int nStream
,
1557 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*plpOptions
)
1559 LPWSTR wszFile
= NULL
;
1563 TRACE("%s,%p,%p,%d,%p,%p)\n", debugstr_a(szFile
), pclsidHandler
,
1564 lpfnCallback
, nStream
, ppavi
, plpOptions
);
1566 if (szFile
== NULL
|| ppavi
== NULL
|| plpOptions
== NULL
)
1567 return AVIERR_BADPARAM
;
1569 /* convert ASCII string to Unicode and call Unicode function */
1570 len
= MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, NULL
, 0);
1572 return AVIERR_BADPARAM
;
1574 wszFile
= LocalAlloc(LPTR
, len
* sizeof(WCHAR
));
1575 if (wszFile
== NULL
)
1576 return AVIERR_MEMORY
;
1578 MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, wszFile
, len
);
1580 hr
= AVISaveVW(wszFile
, pclsidHandler
, lpfnCallback
,
1581 nStream
, ppavi
, plpOptions
);
1583 LocalFree((HLOCAL
)wszFile
);
1588 /***********************************************************************
1589 * AVIFILE_AVISaveDefaultCallback (internal)
1591 static BOOL WINAPI
AVIFILE_AVISaveDefaultCallback(INT progress
)
1593 TRACE("(%d)\n", progress
);
1598 /***********************************************************************
1599 * AVISaveVW (AVIFIL32.@)
1601 HRESULT WINAPI
AVISaveVW(LPCWSTR szFile
, CLSID
*pclsidHandler
,
1602 AVISAVECALLBACK lpfnCallback
, int nStreams
,
1603 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*plpOptions
)
1605 LONG lStart
[MAX_AVISTREAMS
];
1606 PAVISTREAM pOutStreams
[MAX_AVISTREAMS
];
1607 PAVISTREAM pInStreams
[MAX_AVISTREAMS
];
1609 AVISTREAMINFOW sInfo
;
1611 PAVIFILE pfile
= NULL
; /* the output AVI file */
1612 LONG lFirstVideo
= -1;
1615 /* for interleaving ... */
1616 DWORD dwInterleave
= 0; /* interleave rate */
1617 DWORD dwFileInitialFrames
;
1621 /* for reading/writing the data ... */
1622 LPVOID lpBuffer
= NULL
;
1623 LONG cbBuffer
; /* real size of lpBuffer */
1624 LONG lBufferSize
; /* needed bytes for format(s), etc. */
1629 TRACE("(%s,%p,%p,%d,%p,%p)\n", debugstr_w(szFile
), pclsidHandler
,
1630 lpfnCallback
, nStreams
, ppavi
, plpOptions
);
1632 if (szFile
== NULL
|| ppavi
== NULL
|| plpOptions
== NULL
)
1633 return AVIERR_BADPARAM
;
1634 if (nStreams
>= MAX_AVISTREAMS
) {
1635 WARN("Can't write AVI with %d streams only supports %d -- change MAX_AVISTREAMS!\n", nStreams
, MAX_AVISTREAMS
);
1636 return AVIERR_INTERNAL
;
1639 if (lpfnCallback
== NULL
)
1640 lpfnCallback
= AVIFILE_AVISaveDefaultCallback
;
1642 /* clear local variable(s) */
1643 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1644 pInStreams
[curStream
] = NULL
;
1645 pOutStreams
[curStream
] = NULL
;
1648 /* open output AVI file (create it if it doesn't exist) */
1649 hres
= AVIFileOpenW(&pfile
, szFile
, OF_CREATE
|OF_SHARE_EXCLUSIVE
|OF_WRITE
,
1653 AVIFileInfoW(pfile
, &fInfo
, sizeof(fInfo
)); /* for dwCaps */
1655 /* initialize our data structures part 1 */
1656 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1657 PAVISTREAM pCurStream
= ppavi
[curStream
];
1659 hres
= AVIStreamInfoW(pCurStream
, &sInfo
, sizeof(sInfo
));
1663 /* search first video stream and check for interleaving */
1664 if (sInfo
.fccType
== streamtypeVIDEO
) {
1665 /* remember first video stream -- needed for interleaving */
1666 if (lFirstVideo
< 0)
1667 lFirstVideo
= curStream
;
1668 } else if (!dwInterleave
&& plpOptions
!= NULL
) {
1669 /* check if any non-video stream wants to be interleaved */
1670 WARN("options.flags=0x%lX options.dwInterleave=%lu\n",plpOptions
[curStream
]->dwFlags
,plpOptions
[curStream
]->dwInterleaveEvery
);
1671 if (plpOptions
[curStream
] != NULL
&&
1672 plpOptions
[curStream
]->dwFlags
& AVICOMPRESSF_INTERLEAVE
)
1673 dwInterleave
= plpOptions
[curStream
]->dwInterleaveEvery
;
1676 /* create de-/compressed stream interface if needed */
1677 pInStreams
[curStream
] = NULL
;
1678 if (plpOptions
!= NULL
&& plpOptions
[curStream
] != NULL
) {
1679 if (plpOptions
[curStream
]->fccHandler
||
1680 plpOptions
[curStream
]->lpFormat
!= NULL
) {
1681 DWORD dwKeySave
= plpOptions
[curStream
]->dwKeyFrameEvery
;
1683 if (fInfo
.dwCaps
& AVIFILECAPS_ALLKEYFRAMES
)
1684 plpOptions
[curStream
]->dwKeyFrameEvery
= 1;
1686 hres
= AVIMakeCompressedStream(&pInStreams
[curStream
], pCurStream
,
1687 plpOptions
[curStream
], NULL
);
1688 plpOptions
[curStream
]->dwKeyFrameEvery
= dwKeySave
;
1689 if (FAILED(hres
) || pInStreams
[curStream
] == NULL
) {
1690 pInStreams
[curStream
] = NULL
;
1694 /* test stream interface and update stream-info */
1695 hres
= AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1701 /* now handle streams which will only be copied */
1702 if (pInStreams
[curStream
] == NULL
) {
1703 pCurStream
= pInStreams
[curStream
] = ppavi
[curStream
];
1704 AVIStreamAddRef(pCurStream
);
1706 pCurStream
= pInStreams
[curStream
];
1708 lStart
[curStream
] = sInfo
.dwStart
;
1709 } /* for all streams */
1711 /* check that first video stream is the first stream */
1712 if (lFirstVideo
> 0) {
1713 PAVISTREAM pTmp
= pInStreams
[lFirstVideo
];
1714 LONG lTmp
= lStart
[lFirstVideo
];
1716 pInStreams
[lFirstVideo
] = pInStreams
[0];
1717 pInStreams
[0] = pTmp
;
1718 lStart
[lFirstVideo
] = lStart
[0];
1723 /* allocate buffer for formats, data, etc. of an initial size of 64 kBytes*/
1724 lpBuffer
= GlobalAllocPtr(GPTR
, cbBuffer
= 0x00010000);
1725 if (lpBuffer
== NULL
) {
1726 hres
= AVIERR_MEMORY
;
1730 AVIStreamInfoW(pInStreams
[0], &sInfo
, sizeof(sInfo
));
1731 lFileLength
= sInfo
.dwLength
;
1732 dwFileInitialFrames
= 0;
1733 if (lFirstVideo
>= 0) {
1734 /* check for correct version of the format
1735 * -- need at least BITMAPINFOHEADER or newer
1738 lBufferSize
= cbBuffer
;
1739 hres
= AVIStreamReadFormat(pInStreams
[lFirstVideo
], AVIStreamStart(pInStreams
[lFirstVideo
]), lpBuffer
, &lBufferSize
);
1740 if (lBufferSize
< (LONG
)sizeof(BITMAPINFOHEADER
))
1741 hres
= AVIERR_INTERNAL
;
1744 } else /* use one second blocks for interleaving if no video present */
1745 lSampleInc
= AVIStreamTimeToSample(pInStreams
[0], 1000000);
1747 /* create output streams */
1748 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1749 AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1751 sInfo
.dwInitialFrames
= 0;
1752 if (dwInterleave
!= 0 && curStream
> 0 && sInfo
.fccType
!= streamtypeVIDEO
) {
1753 /* 750 ms initial frames for non-video streams */
1754 sInfo
.dwInitialFrames
= AVIStreamTimeToSample(pInStreams
[0], 750);
1757 hres
= AVIFileCreateStreamW(pfile
, &pOutStreams
[curStream
], &sInfo
);
1758 if (pOutStreams
[curStream
] != NULL
&& SUCCEEDED(hres
)) {
1759 /* copy initial format for this stream */
1760 lBufferSize
= cbBuffer
;
1761 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1762 lpBuffer
, &lBufferSize
);
1765 hres
= AVIStreamSetFormat(pOutStreams
[curStream
], 0, lpBuffer
, lBufferSize
);
1769 /* try to copy stream handler data */
1770 lBufferSize
= cbBuffer
;
1771 hres
= AVIStreamReadData(pInStreams
[curStream
], ckidSTREAMHANDLERDATA
,
1772 lpBuffer
, &lBufferSize
);
1773 if (SUCCEEDED(hres
) && lBufferSize
> 0) {
1774 hres
= AVIStreamWriteData(pOutStreams
[curStream
],ckidSTREAMHANDLERDATA
,
1775 lpBuffer
, lBufferSize
);
1780 if (dwFileInitialFrames
< sInfo
.dwInitialFrames
)
1781 dwFileInitialFrames
= sInfo
.dwInitialFrames
;
1783 AVIStreamSampleToSample(pOutStreams
[0], pInStreams
[curStream
],
1785 if (lFileLength
< lReadBytes
)
1786 lFileLength
= lReadBytes
;
1788 /* creation of de-/compression stream interface failed */
1789 WARN("creation of (de-)compression stream failed for stream %d\n",curStream
);
1790 AVIStreamRelease(pInStreams
[curStream
]);
1791 if (curStream
+ 1 >= nStreams
) {
1792 /* move the others one up */
1793 PAVISTREAM
*ppas
= &pInStreams
[curStream
];
1794 int n
= nStreams
- (curStream
+ 1);
1797 *ppas
= pInStreams
[curStream
+ 1];
1803 } /* create output streams for all input streams */
1805 /* have we still something to write, or lost everything? */
1810 LONG lCurFrame
= -dwFileInitialFrames
;
1812 /* interleaved file */
1813 if (dwInterleave
== 1)
1814 AVIFileEndRecord(pfile
);
1816 for (; lCurFrame
< lFileLength
; lCurFrame
+= lSampleInc
) {
1817 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1820 hres
= AVIStreamInfoW(pOutStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1824 /* initial frames phase at the end for this stream? */
1825 if (-(LONG
)sInfo
.dwInitialFrames
> lCurFrame
)
1828 if ((lFileLength
- lSampleInc
) <= lCurFrame
) {
1829 lLastSample
= AVIStreamLength(pInStreams
[curStream
]);
1830 lFirstVideo
= lLastSample
+ AVIStreamStart(pInStreams
[curStream
]);
1832 if (curStream
!= 0) {
1834 AVIStreamSampleToSample(pInStreams
[curStream
], pInStreams
[0],
1835 (sInfo
.fccType
== streamtypeVIDEO
?
1836 (LONG
)dwInterleave
: lSampleInc
) +
1837 sInfo
.dwInitialFrames
+ lCurFrame
);
1839 lFirstVideo
= lSampleInc
+ (sInfo
.dwInitialFrames
+ lCurFrame
);
1841 lLastSample
= AVIStreamEnd(pInStreams
[curStream
]);
1842 if (lLastSample
<= lFirstVideo
)
1843 lFirstVideo
= lLastSample
;
1846 /* copy needed samples now */
1847 WARN("copy from stream %d samples %ld to %ld...\n",curStream
,
1848 lStart
[curStream
],lFirstVideo
);
1849 while (lFirstVideo
> lStart
[curStream
]) {
1852 /* copy format in case it can change */
1853 lBufferSize
= cbBuffer
;
1854 hres
= AVIStreamReadFormat(pInStreams
[curStream
], lStart
[curStream
],
1855 lpBuffer
, &lBufferSize
);
1858 AVIStreamSetFormat(pOutStreams
[curStream
], lStart
[curStream
],
1859 lpBuffer
, lBufferSize
);
1861 /* try to read data until we got it, or error */
1863 hres
= AVIStreamRead(pInStreams
[curStream
], lStart
[curStream
],
1864 lFirstVideo
- lStart
[curStream
], lpBuffer
,
1865 cbBuffer
, &lReadBytes
, &lReadSamples
);
1866 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1867 (lpBuffer
= GlobalReAllocPtr(lpBuffer
, cbBuffer
*= 2, GPTR
)) != NULL
);
1868 if (lpBuffer
== NULL
)
1869 hres
= AVIERR_MEMORY
;
1873 if (AVIStreamIsKeyFrame(pInStreams
[curStream
], (LONG
)sInfo
.dwStart
))
1874 flags
= AVIIF_KEYFRAME
;
1875 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1876 lpBuffer
, lReadBytes
, flags
, NULL
, NULL
);
1880 lStart
[curStream
] += lReadSamples
;
1882 lStart
[curStream
] = lFirstVideo
;
1883 } /* stream by stream */
1885 /* need to close this block? */
1886 if (dwInterleave
== 1) {
1887 hres
= AVIFileEndRecord(pfile
);
1893 if (lpfnCallback(MulDiv(dwFileInitialFrames
+ lCurFrame
, 100,
1894 dwFileInitialFrames
+ lFileLength
))) {
1895 hres
= AVIERR_USERABORT
;
1898 } /* copy frame by frame */
1900 /* non-interleaved file */
1902 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1904 if (lpfnCallback(MulDiv(curStream
, 100, nStreams
))) {
1905 hres
= AVIERR_USERABORT
;
1909 AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1911 if (sInfo
.dwSampleSize
!= 0) {
1912 /* sample-based data like audio */
1913 while (sInfo
.dwStart
< sInfo
.dwLength
) {
1914 LONG lSamples
= cbBuffer
/ sInfo
.dwSampleSize
;
1916 /* copy format in case it can change */
1917 lBufferSize
= cbBuffer
;
1918 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1919 lpBuffer
, &lBufferSize
);
1922 AVIStreamSetFormat(pOutStreams
[curStream
], sInfo
.dwStart
,
1923 lpBuffer
, lBufferSize
);
1925 /* limit to stream boundaries */
1926 if (lSamples
!= (LONG
)(sInfo
.dwLength
- sInfo
.dwStart
))
1927 lSamples
= sInfo
.dwLength
- sInfo
.dwStart
;
1929 /* now try to read until we get it, or an error occurs */
1931 lReadBytes
= cbBuffer
;
1933 hres
= AVIStreamRead(pInStreams
[curStream
],sInfo
.dwStart
,lSamples
,
1934 lpBuffer
,cbBuffer
,&lReadBytes
,&lReadSamples
);
1935 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1936 (lpBuffer
= GlobalReAllocPtr(lpBuffer
, cbBuffer
*= 2, GPTR
)) != NULL
);
1937 if (lpBuffer
== NULL
)
1938 hres
= AVIERR_MEMORY
;
1941 if (lReadSamples
!= 0) {
1942 sInfo
.dwStart
+= lReadSamples
;
1943 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1944 lpBuffer
, lReadBytes
, 0, NULL
, NULL
);
1949 if (lpfnCallback(MulDiv(sInfo
.dwStart
,100,nStreams
*sInfo
.dwLength
)+
1950 MulDiv(curStream
, 100, nStreams
))) {
1951 hres
= AVIERR_USERABORT
;
1955 if ((sInfo
.dwLength
- sInfo
.dwStart
) != 1) {
1956 hres
= AVIERR_FILEREAD
;
1962 /* block-based data like video */
1963 for (; sInfo
.dwStart
< sInfo
.dwLength
; sInfo
.dwStart
++) {
1966 /* copy format in case it can change */
1967 lBufferSize
= cbBuffer
;
1968 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1969 lpBuffer
, &lBufferSize
);
1972 AVIStreamSetFormat(pOutStreams
[curStream
], sInfo
.dwStart
,
1973 lpBuffer
, lBufferSize
);
1975 /* try to read block and resize buffer if necessary */
1978 lReadBytes
= cbBuffer
;
1979 hres
= AVIStreamRead(pInStreams
[curStream
], sInfo
.dwStart
, 1,
1980 lpBuffer
, cbBuffer
,&lReadBytes
,&lReadSamples
);
1981 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1982 (lpBuffer
= GlobalReAllocPtr(lpBuffer
, cbBuffer
*= 2, GPTR
)) != NULL
);
1983 if (lpBuffer
== NULL
)
1984 hres
= AVIERR_MEMORY
;
1987 if (lReadSamples
!= 1) {
1988 hres
= AVIERR_FILEREAD
;
1992 if (AVIStreamIsKeyFrame(pInStreams
[curStream
], (LONG
)sInfo
.dwStart
))
1993 flags
= AVIIF_KEYFRAME
;
1994 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1995 lpBuffer
, lReadBytes
, flags
, NULL
, NULL
);
2000 if (lpfnCallback(MulDiv(sInfo
.dwStart
,100,nStreams
*sInfo
.dwLength
)+
2001 MulDiv(curStream
, 100, nStreams
))) {
2002 hres
= AVIERR_USERABORT
;
2005 } /* copy all blocks */
2007 } /* copy data stream by stream */
2011 if (lpBuffer
!= NULL
)
2012 GlobalFreePtr(lpBuffer
);
2013 if (pfile
!= NULL
) {
2014 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
2015 if (pOutStreams
[curStream
] != NULL
)
2016 AVIStreamRelease(pOutStreams
[curStream
]);
2017 if (pInStreams
[curStream
] != NULL
)
2018 AVIStreamRelease(pInStreams
[curStream
]);
2021 AVIFileRelease(pfile
);
2027 /***********************************************************************
2028 * CreateEditableStream (AVIFIL32.@)
2030 HRESULT WINAPI
CreateEditableStream(PAVISTREAM
*ppEditable
, PAVISTREAM pSource
)
2032 IAVIEditStream
*pEdit
= NULL
;
2035 TRACE("(%p,%p)\n", ppEditable
, pSource
);
2037 if (ppEditable
== NULL
)
2038 return AVIERR_BADPARAM
;
2042 if (pSource
!= NULL
) {
2043 hr
= IAVIStream_QueryInterface(pSource
, &IID_IAVIEditStream
,
2045 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2046 hr
= IAVIEditStream_Clone(pEdit
, ppEditable
);
2047 IAVIEditStream_Release(pEdit
);
2053 /* need own implementation of IAVIEditStream */
2054 pEdit
= AVIFILE_CreateEditStream(pSource
);
2056 return AVIERR_MEMORY
;
2058 hr
= IAVIEditStream_QueryInterface(pEdit
, &IID_IAVIStream
,
2059 (LPVOID
*)ppEditable
);
2060 IAVIEditStream_Release(pEdit
);
2065 /***********************************************************************
2066 * EditStreamClone (AVIFIL32.@)
2068 HRESULT WINAPI
EditStreamClone(PAVISTREAM pStream
, PAVISTREAM
*ppResult
)
2070 PAVIEDITSTREAM pEdit
= NULL
;
2073 TRACE("(%p,%p)\n", pStream
, ppResult
);
2075 if (pStream
== NULL
)
2076 return AVIERR_BADHANDLE
;
2077 if (ppResult
== NULL
)
2078 return AVIERR_BADPARAM
;
2082 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2083 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2084 hr
= IAVIEditStream_Clone(pEdit
, ppResult
);
2086 IAVIEditStream_Release(pEdit
);
2088 hr
= AVIERR_UNSUPPORTED
;
2093 /***********************************************************************
2094 * EditStreamCopy (AVIFIL32.@)
2096 HRESULT WINAPI
EditStreamCopy(PAVISTREAM pStream
, LONG
*plStart
,
2097 LONG
*plLength
, PAVISTREAM
*ppResult
)
2099 PAVIEDITSTREAM pEdit
= NULL
;
2102 TRACE("(%p,%p,%p,%p)\n", pStream
, plStart
, plLength
, ppResult
);
2104 if (pStream
== NULL
)
2105 return AVIERR_BADHANDLE
;
2106 if (plStart
== NULL
|| plLength
== NULL
|| ppResult
== NULL
)
2107 return AVIERR_BADPARAM
;
2111 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2112 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2113 hr
= IAVIEditStream_Copy(pEdit
, plStart
, plLength
, ppResult
);
2115 IAVIEditStream_Release(pEdit
);
2117 hr
= AVIERR_UNSUPPORTED
;
2122 /***********************************************************************
2123 * EditStreamCut (AVIFIL32.@)
2125 HRESULT WINAPI
EditStreamCut(PAVISTREAM pStream
, LONG
*plStart
,
2126 LONG
*plLength
, PAVISTREAM
*ppResult
)
2128 PAVIEDITSTREAM pEdit
= NULL
;
2131 TRACE("(%p,%p,%p,%p)\n", pStream
, plStart
, plLength
, ppResult
);
2133 if (ppResult
!= NULL
)
2135 if (pStream
== NULL
)
2136 return AVIERR_BADHANDLE
;
2137 if (plStart
== NULL
|| plLength
== NULL
)
2138 return AVIERR_BADPARAM
;
2140 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2141 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2142 hr
= IAVIEditStream_Cut(pEdit
, plStart
, plLength
, ppResult
);
2144 IAVIEditStream_Release(pEdit
);
2146 hr
= AVIERR_UNSUPPORTED
;
2151 /***********************************************************************
2152 * EditStreamPaste (AVIFIL32.@)
2154 HRESULT WINAPI
EditStreamPaste(PAVISTREAM pDest
, LONG
*plStart
, LONG
*plLength
,
2155 PAVISTREAM pSource
, LONG lStart
, LONG lEnd
)
2157 PAVIEDITSTREAM pEdit
= NULL
;
2160 TRACE("(%p,%p,%p,%p,%ld,%ld)\n", pDest
, plStart
, plLength
,
2161 pSource
, lStart
, lEnd
);
2163 if (pDest
== NULL
|| pSource
== NULL
)
2164 return AVIERR_BADHANDLE
;
2165 if (plStart
== NULL
|| plLength
== NULL
|| lStart
< 0)
2166 return AVIERR_BADPARAM
;
2168 hr
= IAVIStream_QueryInterface(pDest
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2169 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2170 hr
= IAVIEditStream_Paste(pEdit
, plStart
, plLength
, pSource
, lStart
, lEnd
);
2172 IAVIEditStream_Release(pEdit
);
2174 hr
= AVIERR_UNSUPPORTED
;
2179 /***********************************************************************
2180 * EditStreamSetInfoA (AVIFIL32.@)
2182 HRESULT WINAPI
EditStreamSetInfoA(PAVISTREAM pstream
, LPAVISTREAMINFOA asi
,
2185 AVISTREAMINFOW asiw
;
2187 TRACE("(%p,%p,%ld)\n", pstream
, asi
, size
);
2189 if (pstream
== NULL
)
2190 return AVIERR_BADHANDLE
;
2191 if ((DWORD
)size
< sizeof(AVISTREAMINFOA
))
2192 return AVIERR_BADSIZE
;
2194 memcpy(&asiw
, asi
, sizeof(asiw
) - sizeof(asiw
.szName
));
2195 MultiByteToWideChar(CP_ACP
, 0, asi
->szName
, -1,
2196 asiw
.szName
, sizeof(asiw
.szName
));
2198 return EditStreamSetInfoW(pstream
, &asiw
, sizeof(asiw
));
2201 /***********************************************************************
2202 * EditStreamSetInfoW (AVIFIL32.@)
2204 HRESULT WINAPI
EditStreamSetInfoW(PAVISTREAM pstream
, LPAVISTREAMINFOW asi
,
2207 PAVIEDITSTREAM pEdit
= NULL
;
2210 TRACE("(%p,%p,%ld)\n", pstream
, asi
, size
);
2212 hr
= IAVIStream_QueryInterface(pstream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2213 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2214 hr
= IAVIEditStream_SetInfo(pEdit
, asi
, size
);
2216 IAVIEditStream_Release(pEdit
);
2218 hr
= AVIERR_UNSUPPORTED
;
2223 /***********************************************************************
2224 * EditStreamSetNameA (AVIFIL32.@)
2226 HRESULT WINAPI
EditStreamSetNameA(PAVISTREAM pstream
, LPCSTR szName
)
2228 AVISTREAMINFOA asia
;
2231 TRACE("(%p,%s)\n", pstream
, debugstr_a(szName
));
2233 if (pstream
== NULL
)
2234 return AVIERR_BADHANDLE
;
2236 return AVIERR_BADPARAM
;
2238 hres
= AVIStreamInfoA(pstream
, &asia
, sizeof(asia
));
2242 memset(asia
.szName
, 0, sizeof(asia
.szName
));
2243 lstrcpynA(asia
.szName
, szName
, sizeof(asia
.szName
)/sizeof(asia
.szName
[0]));
2245 return EditStreamSetInfoA(pstream
, &asia
, sizeof(asia
));
2248 /***********************************************************************
2249 * EditStreamSetNameW (AVIFIL32.@)
2251 HRESULT WINAPI
EditStreamSetNameW(PAVISTREAM pstream
, LPCWSTR szName
)
2253 AVISTREAMINFOW asiw
;
2256 TRACE("(%p,%s)\n", pstream
, debugstr_w(szName
));
2258 if (pstream
== NULL
)
2259 return AVIERR_BADHANDLE
;
2261 return AVIERR_BADPARAM
;
2263 hres
= IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
));
2267 memset(asiw
.szName
, 0, sizeof(asiw
.szName
));
2268 lstrcpynW(asiw
.szName
, szName
, sizeof(asiw
.szName
)/sizeof(asiw
.szName
[0]));
2270 return EditStreamSetInfoW(pstream
, &asiw
, sizeof(asiw
));
2273 /***********************************************************************
2274 * AVIClearClipboard (AVIFIL32.@)
2276 HRESULT WINAPI
AVIClearClipboard(void)
2280 return AVIERR_UNSUPPORTED
; /* OleSetClipboard(NULL); */
2283 /***********************************************************************
2284 * AVIGetFromClipboard (AVIFIL32.@)
2286 HRESULT WINAPI
AVIGetFromClipboard(PAVIFILE
*ppfile
)
2288 FIXME("(%p), stub!\n", ppfile
);
2292 return AVIERR_UNSUPPORTED
;
2295 /***********************************************************************
2296 * AVIMakeStreamFromClipboard (AVIFIL32.@)
2298 HRESULT WINAPI
AVIMakeStreamFromClipboard(UINT cfFormat
, HANDLE hGlobal
,
2299 PAVISTREAM
* ppstream
)
2301 FIXME("(0x%08x,%p,%p), stub!\n", cfFormat
, hGlobal
, ppstream
);
2303 if (ppstream
== NULL
)
2304 return AVIERR_BADHANDLE
;
2306 return AVIERR_UNSUPPORTED
;
2309 /***********************************************************************
2310 * AVIPutFileOnClipboard (AVIFIL32.@)
2312 HRESULT WINAPI
AVIPutFileOnClipboard(PAVIFILE pfile
)
2314 FIXME("(%p), stub!\n", pfile
);
2317 return AVIERR_BADHANDLE
;
2319 return AVIERR_UNSUPPORTED
;
2322 HRESULT CDECL
AVISaveA(LPCSTR szFile
, CLSID
* pclsidHandler
, AVISAVECALLBACK lpfnCallback
,
2323 int nStreams
, PAVISTREAM pavi
, LPAVICOMPRESSOPTIONS lpOptions
, ...)
2325 FIXME("(%s,%p,%p,0x%08x,%p,%p), stub!\n", debugstr_a(szFile
), pclsidHandler
, lpfnCallback
,
2326 nStreams
, pavi
, lpOptions
);
2328 return AVIERR_UNSUPPORTED
;
2331 HRESULT CDECL
AVISaveW(LPCWSTR szFile
, CLSID
* pclsidHandler
, AVISAVECALLBACK lpfnCallback
,
2332 int nStreams
, PAVISTREAM pavi
, LPAVICOMPRESSOPTIONS lpOptions
, ...)
2334 FIXME("(%s,%p,%p,0x%08x,%p,%p), stub!\n", debugstr_w(szFile
), pclsidHandler
, lpfnCallback
,
2335 nStreams
, pavi
, lpOptions
);
2337 return AVIERR_UNSUPPORTED
;