2 * Copyright 1999 Marcus Meissner
3 * Copyright 2002-2003 Michael Günnewig
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #define COM_NO_WINDOWS_H
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
{
55 WCHAR szExtensions
[MAX_FILTERS
* 7];
58 /***********************************************************************
65 LPAVICOMPRESSOPTIONS
*ppOptions
;
69 /***********************************************************************
70 * copied from dlls/ole32/compobj.c
72 static HRESULT
AVIFILE_CLSIDFromString(LPCSTR idstr
, LPCLSID id
)
74 BYTE
const *s
= (BYTE
const*)idstr
;
80 memset(id
, 0, sizeof(CLSID
));
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))
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
++)
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} */
117 s
++; /* skip leading brace */
118 for (i
= 0; i
< 4; i
++) {
119 p
[3 - i
] = table
[*s
]<<4 | table
[*(s
+1)];
125 for (i
= 0; i
< 2; i
++) {
126 p
[1-i
] = table
[*s
]<<4 | table
[*(s
+1)];
132 for (i
= 0; i
< 2; i
++) {
133 p
[1-i
] = table
[*s
]<<4 | table
[*(s
+1)];
139 /* these are just sequential bytes */
140 for (i
= 0; i
< 2; i
++) {
141 *p
++ = table
[*s
]<<4 | table
[*(s
+1)];
146 for (i
= 0; i
< 6; i
++) {
147 *p
++ = table
[*s
]<<4 | table
[*(s
+1)];
154 static BOOL
AVIFILE_GetFileHandlerByExtension(LPCWSTR szFile
, LPCLSID lpclsid
)
158 LPWSTR szExt
= strrchrW(szFile
, '.');
159 LONG len
= sizeof(szValue
) / sizeof(szValue
[0]);
166 wsprintfA(szRegKey
, "AVIFile\\Extensions\\%.3ls", szExt
);
167 if (RegQueryValueA(HKEY_CLASSES_ROOT
, szRegKey
, szValue
, &len
) != ERROR_SUCCESS
)
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
,
198 LPWSTR wszFile
= NULL
;
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
);
212 return AVIERR_BADPARAM
;
214 wszFile
= (LPWSTR
)LocalAlloc(LPTR
, (len
+ 1) * sizeof(WCHAR
));
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
);
228 /***********************************************************************
229 * AVIFileOpenW (AVIFIL32.@)
231 HRESULT WINAPI
AVIFileOpenW(PAVIFILE
*ppfile
, LPCWSTR szFile
, UINT uMode
,
234 IPersistFile
*ppersist
= NULL
;
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
;
247 /* if no handler then try guessing it by extension */
248 if (lpHandler
== NULL
) {
249 if (! AVIFILE_GetFileHandlerByExtension(szFile
, &clsidHandler
))
250 return AVIERR_UNSUPPORTED
;
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
)
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
);
268 hr
= IPersistFile_Load(ppersist
, szFile
, uMode
);
269 IPersistFile_Release(ppersist
);
271 IAVIFile_Release(*ppfile
);
278 /***********************************************************************
279 * AVIFileAddRef (AVIFIL32.@)
280 * AVIFileAddRef (AVIFILE.140)
282 ULONG WINAPI
AVIFileAddRef(PAVIFILE pfile
)
284 TRACE("(%p)\n", pfile
);
287 ERR(": bad handle passed!\n");
291 return IAVIFile_AddRef(pfile
);
294 /***********************************************************************
295 * AVIFileRelease (AVIFIL32.@)
296 * AVIFileRelease (AVIFILE.141)
298 ULONG WINAPI
AVIFileRelease(PAVIFILE pfile
)
300 TRACE("(%p)\n", pfile
);
303 ERR(": bad handle passed!\n");
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
)
320 TRACE("(%p,%p,%ld)\n", pfile
, afi
, size
);
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;
337 /***********************************************************************
338 * AVIFileInfoW (AVIFIL32.@)
340 HRESULT WINAPI
AVIFileInfoW(PAVIFILE pfile
, LPAVIFILEINFOW afiw
, LONG size
)
342 TRACE("(%p,%p,%ld)\n", pfile
, afiw
, size
);
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
);
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
)
374 TRACE("(%p,%p,%p)\n", pfile
, ppavi
, psi
);
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
);
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
);
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
);
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");
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");
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
)
481 TRACE("(%p,0x%08lX,0x%08lX,%s)\n", ppavi
, lParam1
, lParam2
,
482 debugstr_guid(pclsidHandler
));
485 return AVIERR_BADPARAM
;
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
)
496 hr
= IAVIStream_Create(*ppavi
, lParam1
, lParam2
);
498 IAVIStream_Release(*ppavi
);
505 /***********************************************************************
506 * AVIStreamInfoA (AVIFIL32.@)
507 * AVIStreamInfo (AVIFILE.162)
509 HRESULT WINAPI
AVIStreamInfoA(PAVISTREAM pstream
, LPAVISTREAMINFOA asi
,
515 TRACE("(%p,%p,%ld)\n", pstream
, asi
, size
);
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;
532 /***********************************************************************
533 * AVIStreamInfoW (AVIFIL32.@)
535 HRESULT WINAPI
AVIStreamInfoW(PAVISTREAM pstream
, LPAVISTREAMINFOW asi
,
538 TRACE("(%p,%p,%ld)\n", pstream
, asi
, size
);
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
);
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
);
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
);
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
);
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
);
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
,
633 TRACE("(%p,'%4.4s',%p,%p)\n", pstream
, (char*)&fcc
, lp
, lpread
);
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
,
648 TRACE("(%p,'%4.4s',%p,%ld)\n", pstream
, (char*)&fcc
, lp
, size
);
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
)
665 TRACE("(%p,%p)\n", pstream
, lpbiWanted
);
667 if (FAILED(IAVIStream_QueryInterface(pstream
, &IID_IGetFrame
, (LPVOID
*)&pg
)) ||
669 pg
= AVIFILE_CreateGetFrame(pstream
);
674 if (FAILED(IGetFrame_SetFormat(pg
, lpbiWanted
, NULL
, 0, 0, -1, -1))) {
675 IGetFrame_Release(pg
);
682 /***********************************************************************
683 * AVIStreamGetFrame (AVIFIL32.@)
684 * AVIStreamGetFrame (AVIFILE.110)
686 LPVOID WINAPI
AVIStreamGetFrame(PGETFRAME pg
, LONG pos
)
688 TRACE("(%p,%ld)\n", pg
, pos
);
693 return IGetFrame_GetFrame(pg
, pos
);
696 /***********************************************************************
697 * AVIStreamGetFrameClose (AVIFIL32.@)
698 * AVIStreamGetFrameClose (AVIFILE.111)
700 HRESULT WINAPI
AVIStreamGetFrameClose(PGETFRAME pg
)
705 return IGetFrame_Release(pg
);
709 /***********************************************************************
710 * AVIMakeCompressedStream (AVIFIL32.@)
712 HRESULT WINAPI
AVIMakeCompressedStream(PAVISTREAM
*ppsCompressed
,
714 LPAVICOMPRESSOPTIONS aco
,
715 LPCLSID pclsidHandler
)
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
));
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
;
746 memcpy(&clsidHandler
, pclsidHandler
, sizeof(clsidHandler
));
748 hr
= SHCoCreateInstance(NULL
, &clsidHandler
, NULL
,
749 &IID_IAVIStream
, (LPVOID
*)ppsCompressed
);
750 if (FAILED(hr
) || *ppsCompressed
== NULL
)
753 hr
= IAVIStream_Create(*ppsCompressed
, (LPARAM
)psSource
, (LPARAM
)aco
);
755 IAVIStream_Release(*ppsCompressed
);
756 *ppsCompressed
= NULL
;
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
);
775 return AVIERR_MEMORY
;
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
;
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
;
799 hr
= AVIFileOpenA(&pfile
, szFile
, mode
, pclsidHandler
);
800 if (FAILED(hr
) || pfile
== NULL
)
803 hr
= IAVIFile_GetStream(pfile
, ppavi
, fccType
, lParam
);
804 IAVIFile_Release(pfile
);
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
;
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
;
827 hr
= AVIFileOpenW(&pfile
, szFile
, mode
, pclsidHandler
);
828 if (FAILED(hr
) || pfile
== NULL
)
831 hr
= IAVIFile_GetStream(pfile
, ppavi
, fccType
, lParam
);
832 IAVIFile_Release(pfile
);
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
);
847 /***********************************************************************
848 * AVIStreamEndStreaming (AVIFIL32.@)
850 LONG WINAPI
AVIStreamEndStreaming(PAVISTREAM pavi
)
852 FIXME("(%p)\n", pavi
);
857 /***********************************************************************
858 * AVIStreamStart (AVIFILE.130)
859 * AVIStreamStart (AVIFIL32.@)
861 LONG WINAPI
AVIStreamStart(PAVISTREAM pstream
)
865 TRACE("(%p)\n", pstream
);
870 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
876 /***********************************************************************
877 * AVIStreamLength (AVIFILE.131)
878 * AVIStreamLength (AVIFIL32.@)
880 LONG WINAPI
AVIStreamLength(PAVISTREAM pstream
)
884 TRACE("(%p)\n", pstream
);
889 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
892 return asiw
.dwLength
;
895 /***********************************************************************
896 * AVIStreamSampleToTime (AVIFILE.133)
897 * AVIStreamSampleToTime (AVIFIL32.@)
899 LONG WINAPI
AVIStreamSampleToTime(PAVISTREAM pstream
, LONG lSample
)
904 TRACE("(%p,%ld)\n", pstream
, lSample
);
909 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
911 if (asiw
.dwRate
== 0)
914 /* limit to stream bounds */
915 if (lSample
< asiw
.dwStart
)
916 lSample
= asiw
.dwStart
;
917 if (lSample
> asiw
.dwStart
+ asiw
.dwLength
)
918 lSample
= asiw
.dwStart
+ asiw
.dwLength
;
920 if (asiw
.dwRate
/ asiw
.dwScale
< 1000)
921 time
= (LONG
)(((float)lSample
* asiw
.dwScale
* 1000) / asiw
.dwRate
);
923 time
= (LONG
)(((float)lSample
* asiw
.dwScale
* 1000 + (asiw
.dwRate
- 1)) / asiw
.dwRate
);
925 TRACE(" -> %ld\n",time
);
929 /***********************************************************************
930 * AVIStreamTimeToSample (AVIFILE.132)
931 * AVIStreamTimeToSample (AVIFIL32.@)
933 LONG WINAPI
AVIStreamTimeToSample(PAVISTREAM pstream
, LONG lTime
)
938 TRACE("(%p,%ld)\n", pstream
, lTime
);
940 if (pstream
== NULL
|| lTime
< 0)
943 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
945 if (asiw
.dwScale
== 0)
948 if (asiw
.dwRate
/ asiw
.dwScale
< 1000)
949 sample
= (LONG
)((((float)asiw
.dwRate
* lTime
) / (asiw
.dwScale
* 1000)));
951 sample
= (LONG
)(((float)asiw
.dwRate
* lTime
+ (asiw
.dwScale
* 1000 - 1)) / (asiw
.dwScale
* 1000));
953 /* limit to stream bounds */
954 if (sample
< asiw
.dwStart
)
955 sample
= asiw
.dwStart
;
956 if (sample
> asiw
.dwStart
+ asiw
.dwLength
)
957 sample
= asiw
.dwStart
+ asiw
.dwLength
;
959 TRACE(" -> %ld\n", sample
);
963 /***********************************************************************
964 * AVIBuildFilterA (AVIFIL32.@)
965 * AVIBuildFilter (AVIFILE.123)
967 HRESULT WINAPI
AVIBuildFilterA(LPSTR szFilter
, LONG cbFilter
, BOOL fSaving
)
972 TRACE("(%p,%ld,%d)\n", szFilter
, cbFilter
, fSaving
);
974 /* check parameters */
975 if (szFilter
== NULL
)
976 return AVIERR_BADPARAM
;
978 return AVIERR_BADSIZE
;
983 wszFilter
= (LPWSTR
)GlobalAllocPtr(GHND
, cbFilter
);
984 if (wszFilter
== NULL
)
985 return AVIERR_MEMORY
;
987 hr
= AVIBuildFilterW(wszFilter
, cbFilter
, fSaving
);
989 WideCharToMultiByte(CP_ACP
, 0, wszFilter
, cbFilter
,
990 szFilter
, cbFilter
, NULL
, NULL
);
993 GlobalFreePtr(wszFilter
);
998 /***********************************************************************
999 * AVIBuildFilterW (AVIFIL32.@)
1001 HRESULT WINAPI
AVIBuildFilterW(LPWSTR szFilter
, LONG cbFilter
, BOOL fSaving
)
1003 static const WCHAR szClsid
[] = {'C','L','S','I','D',0};
1004 static const WCHAR szExtensionFmt
[] = {';','*','.','%','s',0};
1005 static const WCHAR szAVIFileExtensions
[] =
1006 {'A','V','I','F','i','l','e','\\','E','x','t','e','n','s','i','o','n','s',0};
1009 WCHAR szAllFiles
[40];
1010 WCHAR szFileExt
[10];
1017 TRACE("(%p,%ld,%d)\n", szFilter
, cbFilter
, fSaving
);
1019 /* check parameters */
1020 if (szFilter
== NULL
)
1021 return AVIERR_BADPARAM
;
1023 return AVIERR_BADSIZE
;
1025 lp
= (AVIFilter
*)GlobalAllocPtr(GHND
, MAX_FILTERS
* sizeof(AVIFilter
));
1027 return AVIERR_MEMORY
;
1030 * 1. iterate over HKEY_CLASSES_ROOT\\AVIFile\\Extensions and collect
1031 * extensions and CLSID's
1032 * 2. iterate over collected CLSID's and copy it's description and it's
1033 * extensions to szFilter if it fits
1035 * First filter is named "All multimedia files" and it's filter is a
1036 * collection of all possible extensions except "*.*".
1038 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, szAVIFileExtensions
, &hKey
) != S_OK
) {
1040 return AVIERR_ERROR
;
1042 for (n
= 0;RegEnumKeyW(hKey
, n
, szFileExt
, sizeof(szFileExt
)) == S_OK
;n
++) {
1043 /* get CLSID to extension */
1044 size
= sizeof(szValue
)/sizeof(szValue
[0]);
1045 if (RegQueryValueW(hKey
, szFileExt
, szValue
, &size
) != S_OK
)
1048 /* search if the CLSID is already known */
1049 for (i
= 1; i
<= count
; i
++) {
1050 if (lstrcmpW(lp
[i
].szClsid
, szValue
) == 0)
1051 break; /* a new one */
1054 if (count
- i
== -1U) {
1055 /* it's a new CLSID */
1057 /* FIXME: How do we get info's about read/write capabilities? */
1059 if (count
>= MAX_FILTERS
) {
1060 /* try to inform user of our full fixed size table */
1061 ERR(": More than %d filters found! Adjust MAX_FILTERS in dlls/avifil32/api.c\n", MAX_FILTERS
);
1065 lstrcpyW(lp
[i
].szClsid
, szValue
);
1070 /* append extension to the filter */
1071 wsprintfW(szValue
, szExtensionFmt
, szFileExt
);
1072 if (lp
[i
].szExtensions
[0] == 0)
1073 lstrcatW(lp
[i
].szExtensions
, szValue
+ 1);
1075 lstrcatW(lp
[i
].szExtensions
, szValue
);
1077 /* also append to the "all multimedia"-filter */
1078 if (lp
[0].szExtensions
[0] == 0)
1079 lstrcatW(lp
[0].szExtensions
, szValue
+ 1);
1081 lstrcatW(lp
[0].szExtensions
, szValue
);
1085 /* 2. get descriptions for the CLSIDs and fill out szFilter */
1086 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, szClsid
, &hKey
) != S_OK
) {
1088 return AVIERR_ERROR
;
1090 for (n
= 0; n
<= count
; n
++) {
1091 /* first the description */
1093 size
= sizeof(szValue
)/sizeof(szValue
[0]);
1094 if (RegQueryValueW(hKey
, lp
[n
].szClsid
, szValue
, &size
) == S_OK
) {
1095 size
= lstrlenW(szValue
);
1096 lstrcpynW(szFilter
, szValue
, cbFilter
);
1099 size
= LoadStringW(AVIFILE_hModule
,IDS_ALLMULTIMEDIA
,szFilter
,cbFilter
);
1101 /* check for enough space */
1103 if (cbFilter
< size
+ lstrlenW(lp
[n
].szExtensions
) + 2) {
1108 return AVIERR_BUFFERTOOSMALL
;
1113 /* and then the filter */
1114 lstrcpynW(szFilter
, lp
[n
].szExtensions
, cbFilter
);
1115 size
= lstrlenW(lp
[n
].szExtensions
) + 1;
1123 /* add "All files" "*.*" filter if enough space left */
1124 size
= LoadStringW(AVIFILE_hModule
, IDS_ALLFILES
,
1125 szAllFiles
, sizeof(szAllFiles
)) + 1;
1126 if (cbFilter
> size
) {
1129 /* replace '@' with \000 to separate description of filter */
1130 for (i
= 0; i
< size
&& szAllFiles
[i
] != 0; i
++) {
1131 if (szAllFiles
[i
] == '@') {
1137 memcpy(szFilter
, szAllFiles
, size
* sizeof(szAllFiles
[0]));
1144 return AVIERR_BUFFERTOOSMALL
;
1148 static BOOL
AVISaveOptionsFmtChoose(HWND hWnd
)
1150 LPAVICOMPRESSOPTIONS pOptions
= SaveOpts
.ppOptions
[SaveOpts
.nCurrent
];
1151 AVISTREAMINFOW sInfo
;
1153 TRACE("(%p)\n", hWnd
);
1155 if (pOptions
== NULL
|| SaveOpts
.ppavis
[SaveOpts
.nCurrent
] == NULL
) {
1156 ERR(": bad state!\n");
1160 if (FAILED(AVIStreamInfoW(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1161 &sInfo
, sizeof(sInfo
)))) {
1162 ERR(": AVIStreamInfoW failed!\n");
1166 if (sInfo
.fccType
== streamtypeVIDEO
) {
1170 memset(&cv
, 0, sizeof(cv
));
1172 if ((pOptions
->dwFlags
& AVICOMPRESSF_VALID
) == 0) {
1173 memset(pOptions
, 0, sizeof(AVICOMPRESSOPTIONS
));
1174 pOptions
->fccType
= streamtypeVIDEO
;
1175 pOptions
->fccHandler
= comptypeDIB
;
1176 pOptions
->dwQuality
= (DWORD
)ICQUALITY_DEFAULT
;
1179 cv
.cbSize
= sizeof(cv
);
1180 cv
.dwFlags
= ICMF_COMPVARS_VALID
;
1181 /*cv.fccType = pOptions->fccType; */
1182 cv
.fccHandler
= pOptions
->fccHandler
;
1183 cv
.lQ
= pOptions
->dwQuality
;
1184 cv
.lpState
= pOptions
->lpParms
;
1185 cv
.cbState
= pOptions
->cbParms
;
1186 if (pOptions
->dwFlags
& AVICOMPRESSF_KEYFRAMES
)
1187 cv
.lKey
= pOptions
->dwKeyFrameEvery
;
1190 if (pOptions
->dwFlags
& AVICOMPRESSF_DATARATE
)
1191 cv
.lDataRate
= pOptions
->dwBytesPerSecond
/ 1024; /* need kBytes */
1195 ret
= ICCompressorChoose(hWnd
, SaveOpts
.uFlags
, NULL
,
1196 SaveOpts
.ppavis
[SaveOpts
.nCurrent
], &cv
, NULL
);
1199 pOptions
->fccHandler
= cv
.fccHandler
;
1200 pOptions
->lpParms
= cv
.lpState
;
1201 pOptions
->cbParms
= cv
.cbState
;
1202 pOptions
->dwQuality
= cv
.lQ
;
1204 pOptions
->dwKeyFrameEvery
= cv
.lKey
;
1205 pOptions
->dwFlags
|= AVICOMPRESSF_KEYFRAMES
;
1207 pOptions
->dwFlags
&= ~AVICOMPRESSF_KEYFRAMES
;
1208 if (cv
.lDataRate
!= 0) {
1209 pOptions
->dwBytesPerSecond
= cv
.lDataRate
* 1024; /* need bytes */
1210 pOptions
->dwFlags
|= AVICOMPRESSF_DATARATE
;
1212 pOptions
->dwFlags
&= ~AVICOMPRESSF_DATARATE
;
1213 pOptions
->dwFlags
|= AVICOMPRESSF_VALID
;
1215 ICCompressorFree(&cv
);
1218 } else if (sInfo
.fccType
== streamtypeAUDIO
) {
1219 ACMFORMATCHOOSEW afmtc
;
1223 /* FIXME: check ACM version -- Which version is needed? */
1225 memset(&afmtc
, 0, sizeof(afmtc
));
1226 afmtc
.cbStruct
= sizeof(afmtc
);
1228 afmtc
.hwndOwner
= hWnd
;
1230 acmMetrics(NULL
, ACM_METRIC_MAX_SIZE_FORMAT
, &size
);
1231 if ((pOptions
->cbFormat
== 0 || pOptions
->lpFormat
== NULL
) && size
!= 0) {
1232 pOptions
->lpFormat
= GlobalAllocPtr(GMEM_MOVEABLE
, size
);
1233 pOptions
->cbFormat
= size
;
1234 } else if (pOptions
->cbFormat
< (DWORD
)size
) {
1235 pOptions
->lpFormat
= GlobalReAllocPtr(pOptions
->lpFormat
, size
, GMEM_MOVEABLE
);
1236 pOptions
->cbFormat
= size
;
1238 if (pOptions
->lpFormat
== NULL
)
1240 afmtc
.pwfx
= pOptions
->lpFormat
;
1241 afmtc
.cbwfx
= pOptions
->cbFormat
;
1244 AVIStreamFormatSize(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1245 sInfo
.dwStart
, &size
);
1246 if (size
< (LONG
)sizeof(PCMWAVEFORMAT
))
1247 size
= sizeof(PCMWAVEFORMAT
);
1248 afmtc
.pwfxEnum
= GlobalAllocPtr(GHND
, size
);
1249 if (afmtc
.pwfxEnum
!= NULL
) {
1250 AVIStreamReadFormat(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1251 sInfo
.dwStart
, afmtc
.pwfxEnum
, &size
);
1252 afmtc
.fdwEnum
= ACM_FORMATENUMF_CONVERT
;
1255 ret
= acmFormatChooseW(&afmtc
);
1257 pOptions
->dwFlags
|= AVICOMPRESSF_VALID
;
1259 if (afmtc
.pwfxEnum
!= NULL
)
1260 GlobalFreePtr(afmtc
.pwfxEnum
);
1262 return (ret
== S_OK
? TRUE
: FALSE
);
1264 ERR(": unknown streamtype 0x%08lX\n", sInfo
.fccType
);
1269 static void AVISaveOptionsUpdate(HWND hWnd
)
1271 static const WCHAR szVideoFmt
[]={'%','l','d','x','%','l','d','x','%','d',0};
1272 static const WCHAR szAudioFmt
[]={'%','s',' ','%','s',0};
1274 WCHAR szFormat
[128];
1275 AVISTREAMINFOW sInfo
;
1279 TRACE("(%p)\n", hWnd
);
1281 SaveOpts
.nCurrent
= SendDlgItemMessageW(hWnd
,IDC_STREAM
,CB_GETCURSEL
,0,0);
1282 if (SaveOpts
.nCurrent
< 0)
1285 if (FAILED(AVIStreamInfoW(SaveOpts
.ppavis
[SaveOpts
.nCurrent
], &sInfo
, sizeof(sInfo
))))
1288 AVIStreamFormatSize(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],sInfo
.dwStart
,&size
);
1292 /* read format to build format descriotion string */
1293 lpFormat
= GlobalAllocPtr(GHND
, size
);
1294 if (lpFormat
!= NULL
) {
1295 if (SUCCEEDED(AVIStreamReadFormat(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],sInfo
.dwStart
,lpFormat
, &size
))) {
1296 if (sInfo
.fccType
== streamtypeVIDEO
) {
1297 LPBITMAPINFOHEADER lpbi
= lpFormat
;
1300 wsprintfW(szFormat
, szVideoFmt
, lpbi
->biWidth
,
1301 lpbi
->biHeight
, lpbi
->biBitCount
);
1303 if (lpbi
->biCompression
!= BI_RGB
) {
1306 hic
= ICLocate(ICTYPE_VIDEO
, sInfo
.fccHandler
, lpFormat
,
1307 NULL
, ICMODE_DECOMPRESS
);
1309 if (ICGetInfo(hic
, &icinfo
, sizeof(icinfo
)) == S_OK
)
1310 lstrcatW(szFormat
, icinfo
.szDescription
);
1314 LoadStringW(AVIFILE_hModule
, IDS_UNCOMPRESSED
,
1315 icinfo
.szDescription
, sizeof(icinfo
.szDescription
));
1316 lstrcatW(szFormat
, icinfo
.szDescription
);
1318 } else if (sInfo
.fccType
== streamtypeAUDIO
) {
1319 ACMFORMATTAGDETAILSW aftd
;
1320 ACMFORMATDETAILSW afd
;
1322 memset(&aftd
, 0, sizeof(aftd
));
1323 memset(&afd
, 0, sizeof(afd
));
1325 aftd
.cbStruct
= sizeof(aftd
);
1326 aftd
.dwFormatTag
= afd
.dwFormatTag
=
1327 ((PWAVEFORMATEX
)lpFormat
)->wFormatTag
;
1328 aftd
.cbFormatSize
= afd
.cbwfx
= size
;
1330 afd
.cbStruct
= sizeof(afd
);
1331 afd
.pwfx
= lpFormat
;
1333 if (acmFormatTagDetailsW(NULL
, &aftd
,
1334 ACM_FORMATTAGDETAILSF_FORMATTAG
) == S_OK
) {
1335 if (acmFormatDetailsW(NULL
,&afd
,ACM_FORMATDETAILSF_FORMAT
) == S_OK
)
1336 wsprintfW(szFormat
, szAudioFmt
, afd
.szFormat
, aftd
.szFormatTag
);
1340 GlobalFreePtr(lpFormat
);
1343 /* set text for format description */
1344 SetDlgItemTextW(hWnd
, IDC_FORMATTEXT
, szFormat
);
1346 /* Disable option button for unsupported streamtypes */
1347 if (sInfo
.fccType
== streamtypeVIDEO
||
1348 sInfo
.fccType
== streamtypeAUDIO
)
1349 EnableWindow(GetDlgItem(hWnd
, IDC_OPTIONS
), TRUE
);
1351 EnableWindow(GetDlgItem(hWnd
, IDC_OPTIONS
), FALSE
);
1356 INT_PTR CALLBACK
AVISaveOptionsDlgProc(HWND hWnd
, UINT uMsg
,
1357 WPARAM wParam
, LPARAM lParam
)
1360 BOOL bIsInterleaved
;
1363 /*TRACE("(%p,%u,0x%04X,0x%08lX)\n", hWnd, uMsg, wParam, lParam);*/
1367 SaveOpts
.nCurrent
= 0;
1368 if (SaveOpts
.nStreams
== 1) {
1369 EndDialog(hWnd
, AVISaveOptionsFmtChoose(hWnd
));
1374 for (n
= 0; n
< SaveOpts
.nStreams
; n
++) {
1375 AVISTREAMINFOW sInfo
;
1377 AVIStreamInfoW(SaveOpts
.ppavis
[n
], &sInfo
, sizeof(sInfo
));
1378 SendDlgItemMessageW(hWnd
, IDC_STREAM
, CB_ADDSTRING
,
1379 0L, (LPARAM
)sInfo
.szName
);
1382 /* select first stream */
1383 SendDlgItemMessageW(hWnd
, IDC_STREAM
, CB_SETCURSEL
, 0, 0);
1384 SendMessageW(hWnd
, WM_COMMAND
,
1385 GET_WM_COMMAND_MPS(IDC_STREAM
, hWnd
, CBN_SELCHANGE
));
1387 /* initialize interleave */
1388 if (SaveOpts
.ppOptions
[0] != NULL
&&
1389 (SaveOpts
.ppOptions
[0]->dwFlags
& AVICOMPRESSF_VALID
)) {
1390 bIsInterleaved
= (SaveOpts
.ppOptions
[0]->dwFlags
& AVICOMPRESSF_INTERLEAVE
);
1391 dwInterleave
= SaveOpts
.ppOptions
[0]->dwInterleaveEvery
;
1393 bIsInterleaved
= TRUE
;
1396 CheckDlgButton(hWnd
, IDC_INTERLEAVE
, bIsInterleaved
);
1397 SetDlgItemInt(hWnd
, IDC_INTERLEAVEEVERY
, dwInterleave
, FALSE
);
1398 EnableWindow(GetDlgItem(hWnd
, IDC_INTERLEAVEEVERY
), bIsInterleaved
);
1401 switch (GET_WM_COMMAND_ID(wParam
, lParam
)) {
1403 /* get data from controls and save them */
1404 dwInterleave
= GetDlgItemInt(hWnd
, IDC_INTERLEAVEEVERY
, NULL
, 0);
1405 bIsInterleaved
= IsDlgButtonChecked(hWnd
, IDC_INTERLEAVE
);
1406 for (n
= 0; n
< SaveOpts
.nStreams
; n
++) {
1407 if (SaveOpts
.ppOptions
[n
] != NULL
) {
1408 if (bIsInterleaved
) {
1409 SaveOpts
.ppOptions
[n
]->dwFlags
|= AVICOMPRESSF_INTERLEAVE
;
1410 SaveOpts
.ppOptions
[n
]->dwInterleaveEvery
= dwInterleave
;
1412 SaveOpts
.ppOptions
[n
]->dwFlags
&= ~AVICOMPRESSF_INTERLEAVE
;
1417 EndDialog(hWnd
, GET_WM_COMMAND_ID(wParam
, lParam
) == IDOK
);
1419 case IDC_INTERLEAVE
:
1420 EnableWindow(GetDlgItem(hWnd
, IDC_INTERLEAVEEVERY
),
1421 IsDlgButtonChecked(hWnd
, IDC_INTERLEAVE
));
1424 if (GET_WM_COMMAND_CMD(wParam
, lParam
) == CBN_SELCHANGE
) {
1425 /* update control elements */
1426 AVISaveOptionsUpdate(hWnd
);
1430 AVISaveOptionsFmtChoose(hWnd
);
1439 /***********************************************************************
1440 * AVISaveOptions (AVIFIL32.@)
1442 BOOL WINAPI
AVISaveOptions(HWND hWnd
, UINT uFlags
, INT nStreams
,
1443 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*ppOptions
)
1445 LPAVICOMPRESSOPTIONS pSavedOptions
= NULL
;
1448 TRACE("(%p,0x%X,%d,%p,%p)\n", hWnd
, uFlags
, nStreams
,
1451 /* check parameters */
1452 if (nStreams
<= 0 || ppavi
== NULL
|| ppOptions
== NULL
)
1453 return AVIERR_BADPARAM
;
1455 /* save options for case user press cancel */
1456 if (ppOptions
!= NULL
&& nStreams
> 1) {
1457 pSavedOptions
= GlobalAllocPtr(GHND
,nStreams
* sizeof(AVICOMPRESSOPTIONS
));
1458 if (pSavedOptions
== NULL
)
1461 for (n
= 0; n
< nStreams
; n
++) {
1462 if (ppOptions
[n
] != NULL
)
1463 memcpy(pSavedOptions
+ n
, ppOptions
[n
], sizeof(AVICOMPRESSOPTIONS
));
1467 SaveOpts
.uFlags
= uFlags
;
1468 SaveOpts
.nStreams
= nStreams
;
1469 SaveOpts
.ppavis
= ppavi
;
1470 SaveOpts
.ppOptions
= ppOptions
;
1472 ret
= DialogBoxW(AVIFILE_hModule
, MAKEINTRESOURCEW(IDD_SAVEOPTIONS
),
1473 hWnd
, AVISaveOptionsDlgProc
);
1478 /* restore options when user pressed cancel */
1479 if (pSavedOptions
!= NULL
) {
1481 for (n
= 0; n
< nStreams
; n
++) {
1482 if (ppOptions
[n
] != NULL
)
1483 memcpy(ppOptions
[n
], pSavedOptions
+ n
, sizeof(AVICOMPRESSOPTIONS
));
1486 GlobalFreePtr(pSavedOptions
);
1492 /***********************************************************************
1493 * AVISaveOptionsFree (AVIFIL32.@)
1494 * AVISaveOptionsFree (AVIFILE.124)
1496 HRESULT WINAPI
AVISaveOptionsFree(INT nStreams
,LPAVICOMPRESSOPTIONS
*ppOptions
)
1498 TRACE("(%d,%p)\n", nStreams
, ppOptions
);
1500 if (nStreams
< 0 || ppOptions
== NULL
)
1501 return AVIERR_BADPARAM
;
1503 for (; nStreams
> 0; nStreams
--) {
1504 if (ppOptions
[nStreams
] != NULL
) {
1505 ppOptions
[nStreams
]->dwFlags
&= ~AVICOMPRESSF_VALID
;
1507 if (ppOptions
[nStreams
]->lpParms
!= NULL
) {
1508 GlobalFreePtr(ppOptions
[nStreams
]->lpParms
);
1509 ppOptions
[nStreams
]->lpParms
= NULL
;
1510 ppOptions
[nStreams
]->cbParms
= 0;
1512 if (ppOptions
[nStreams
]->lpFormat
!= NULL
) {
1513 GlobalFreePtr(ppOptions
[nStreams
]->lpFormat
);
1514 ppOptions
[nStreams
]->lpFormat
= NULL
;
1515 ppOptions
[nStreams
]->cbFormat
= 0;
1523 /***********************************************************************
1524 * AVISaveVA (AVIFIL32.@)
1526 HRESULT WINAPI
AVISaveVA(LPCSTR szFile
, CLSID
*pclsidHandler
,
1527 AVISAVECALLBACK lpfnCallback
, int nStream
,
1528 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*plpOptions
)
1530 LPWSTR wszFile
= NULL
;
1534 TRACE("%s,%p,%p,%d,%p,%p)\n", debugstr_a(szFile
), pclsidHandler
,
1535 lpfnCallback
, nStream
, ppavi
, plpOptions
);
1537 if (szFile
== NULL
|| ppavi
== NULL
|| plpOptions
== NULL
)
1538 return AVIERR_BADPARAM
;
1540 /* convert ASCII string to Unicode and call Unicode function */
1541 len
= lstrlenA(szFile
);
1543 return AVIERR_BADPARAM
;
1545 wszFile
= (LPWSTR
)LocalAlloc(LPTR
, (len
+ 1) * sizeof(WCHAR
));
1546 if (wszFile
== NULL
)
1547 return AVIERR_MEMORY
;
1549 MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, wszFile
, len
+ 1);
1550 wszFile
[len
+ 1] = 0;
1552 hr
= AVISaveVW(wszFile
, pclsidHandler
, lpfnCallback
,
1553 nStream
, ppavi
, plpOptions
);
1555 LocalFree((HLOCAL
)wszFile
);
1560 /***********************************************************************
1561 * AVIFILE_AVISaveDefaultCallback (internal)
1563 static BOOL WINAPI
AVIFILE_AVISaveDefaultCallback(INT progress
)
1565 TRACE("(%d)\n", progress
);
1570 /***********************************************************************
1571 * AVISaveVW (AVIFIL32.@)
1573 HRESULT WINAPI
AVISaveVW(LPCWSTR szFile
, CLSID
*pclsidHandler
,
1574 AVISAVECALLBACK lpfnCallback
, int nStreams
,
1575 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*plpOptions
)
1577 LONG lStart
[MAX_AVISTREAMS
];
1578 PAVISTREAM pOutStreams
[MAX_AVISTREAMS
];
1579 PAVISTREAM pInStreams
[MAX_AVISTREAMS
];
1581 AVISTREAMINFOW sInfo
;
1583 PAVIFILE pfile
= NULL
; /* the output AVI file */
1584 LONG lFirstVideo
= -1;
1587 /* for interleaving ... */
1588 DWORD dwInterleave
= 0; /* interleave rate */
1589 DWORD dwFileInitialFrames
;
1593 /* for reading/writing the data ... */
1594 LPVOID lpBuffer
= NULL
;
1595 LONG cbBuffer
; /* real size of lpBuffer */
1596 LONG lBufferSize
; /* needed bytes for format(s), etc. */
1601 TRACE("(%s,%p,%p,%d,%p,%p)\n", debugstr_w(szFile
), pclsidHandler
,
1602 lpfnCallback
, nStreams
, ppavi
, plpOptions
);
1604 if (szFile
== NULL
|| ppavi
== NULL
|| plpOptions
== NULL
)
1605 return AVIERR_BADPARAM
;
1606 if (nStreams
>= MAX_AVISTREAMS
) {
1607 WARN("Can't write AVI with %d streams only supports %d -- change MAX_AVISTREAMS!\n", nStreams
, MAX_AVISTREAMS
);
1608 return AVIERR_INTERNAL
;
1611 if (lpfnCallback
== NULL
)
1612 lpfnCallback
= AVIFILE_AVISaveDefaultCallback
;
1614 /* clear local variable(s) */
1615 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1616 pInStreams
[curStream
] = NULL
;
1617 pOutStreams
[curStream
] = NULL
;
1620 /* open output AVI file (create it if it doesn't exist) */
1621 hres
= AVIFileOpenW(&pfile
, szFile
, OF_CREATE
|OF_SHARE_EXCLUSIVE
|OF_WRITE
,
1625 AVIFileInfoW(pfile
, &fInfo
, sizeof(fInfo
)); /* for dwCaps */
1627 /* initialize our data structures part 1 */
1628 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1629 PAVISTREAM pCurStream
= ppavi
[curStream
];
1631 hres
= AVIStreamInfoW(pCurStream
, &sInfo
, sizeof(sInfo
));
1635 /* search first video stream and check for interleaving */
1636 if (sInfo
.fccType
== streamtypeVIDEO
) {
1637 /* remember first video stream -- needed for interleaving */
1638 if (lFirstVideo
< 0)
1639 lFirstVideo
= curStream
;
1640 } else if (!dwInterleave
&& plpOptions
!= NULL
) {
1641 /* check if any non-video stream wants to be interleaved */
1642 WARN("options.flags=0x%lX options.dwInterleave=%lu\n",plpOptions
[curStream
]->dwFlags
,plpOptions
[curStream
]->dwInterleaveEvery
);
1643 if (plpOptions
[curStream
] != NULL
&&
1644 plpOptions
[curStream
]->dwFlags
& AVICOMPRESSF_INTERLEAVE
)
1645 dwInterleave
= plpOptions
[curStream
]->dwInterleaveEvery
;
1648 /* create de-/compressed stream interface if needed */
1649 pInStreams
[curStream
] = NULL
;
1650 if (plpOptions
!= NULL
&& plpOptions
[curStream
] != NULL
) {
1651 if (plpOptions
[curStream
]->fccHandler
||
1652 plpOptions
[curStream
]->lpFormat
!= NULL
) {
1653 DWORD dwKeySave
= plpOptions
[curStream
]->dwKeyFrameEvery
;
1655 if (fInfo
.dwCaps
& AVIFILECAPS_ALLKEYFRAMES
)
1656 plpOptions
[curStream
]->dwKeyFrameEvery
= 1;
1658 hres
= AVIMakeCompressedStream(&pInStreams
[curStream
], pCurStream
,
1659 plpOptions
[curStream
], NULL
);
1660 plpOptions
[curStream
]->dwKeyFrameEvery
= dwKeySave
;
1661 if (FAILED(hres
) || pInStreams
[curStream
] == NULL
) {
1662 pInStreams
[curStream
] = NULL
;
1666 /* test stream interface and update stream-info */
1667 hres
= AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1673 /* now handle streams which will only be copied */
1674 if (pInStreams
[curStream
] == NULL
) {
1675 pCurStream
= pInStreams
[curStream
] = ppavi
[curStream
];
1676 AVIStreamAddRef(pCurStream
);
1678 pCurStream
= pInStreams
[curStream
];
1680 lStart
[curStream
] = sInfo
.dwStart
;
1681 } /* for all streams */
1683 /* check that first video stream is the first stream */
1684 if (lFirstVideo
> 0) {
1685 PAVISTREAM pTmp
= pInStreams
[lFirstVideo
];
1686 LONG lTmp
= lStart
[lFirstVideo
];
1688 pInStreams
[lFirstVideo
] = pInStreams
[0];
1689 pInStreams
[0] = pTmp
;
1690 lStart
[lFirstVideo
] = lStart
[0];
1695 /* allocate buffer for formats, data, etc. of an initiale size of 64 kByte */
1696 lpBuffer
= GlobalAllocPtr(GPTR
, cbBuffer
= 0x00010000);
1697 if (lpBuffer
== NULL
) {
1698 hres
= AVIERR_MEMORY
;
1702 AVIStreamInfoW(pInStreams
[0], &sInfo
, sizeof(sInfo
));
1703 lFileLength
= sInfo
.dwLength
;
1704 dwFileInitialFrames
= 0;
1705 if (lFirstVideo
>= 0) {
1706 /* check for correct version of the format
1707 * -- need atleast BITMAPINFOHEADER or newer
1710 lBufferSize
= cbBuffer
;
1711 hres
= AVIStreamReadFormat(pInStreams
[lFirstVideo
], AVIStreamStart(pInStreams
[lFirstVideo
]), lpBuffer
, &lBufferSize
);
1712 if (lBufferSize
< (LONG
)sizeof(BITMAPINFOHEADER
))
1713 hres
= AVIERR_INTERNAL
;
1716 } else /* use one second blocks for interleaving if no video present */
1717 lSampleInc
= AVIStreamTimeToSample(pInStreams
[0], 1000000);
1719 /* create output streams */
1720 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1721 AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1723 sInfo
.dwInitialFrames
= 0;
1724 if (dwInterleave
!= 0 && curStream
> 0 && sInfo
.fccType
!= streamtypeVIDEO
) {
1725 /* 750 ms initial frames for non-video streams */
1726 sInfo
.dwInitialFrames
= AVIStreamTimeToSample(pInStreams
[0], 750);
1729 hres
= AVIFileCreateStreamW(pfile
, &pOutStreams
[curStream
], &sInfo
);
1730 if (pOutStreams
[curStream
] != NULL
&& SUCCEEDED(hres
)) {
1731 /* copy initial format for this stream */
1732 lBufferSize
= cbBuffer
;
1733 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1734 lpBuffer
, &lBufferSize
);
1737 hres
= AVIStreamSetFormat(pOutStreams
[curStream
], 0, lpBuffer
, lBufferSize
);
1741 /* try to copy stream handler data */
1742 lBufferSize
= cbBuffer
;
1743 hres
= AVIStreamReadData(pInStreams
[curStream
], ckidSTREAMHANDLERDATA
,
1744 lpBuffer
, &lBufferSize
);
1745 if (SUCCEEDED(hres
) && lBufferSize
> 0) {
1746 hres
= AVIStreamWriteData(pOutStreams
[curStream
],ckidSTREAMHANDLERDATA
,
1747 lpBuffer
, lBufferSize
);
1752 if (dwFileInitialFrames
< sInfo
.dwInitialFrames
)
1753 dwFileInitialFrames
= sInfo
.dwInitialFrames
;
1755 AVIStreamSampleToSample(pOutStreams
[0], pInStreams
[curStream
],
1757 if (lFileLength
< lReadBytes
)
1758 lFileLength
= lReadBytes
;
1760 /* creation of de-/compression stream interface failed */
1761 WARN("creation of (de-)compression stream failed for stream %d\n",curStream
);
1762 AVIStreamRelease(pInStreams
[curStream
]);
1763 if (curStream
+ 1 >= nStreams
) {
1764 /* move the others one up */
1765 PAVISTREAM
*ppas
= &pInStreams
[curStream
];
1766 int n
= nStreams
- (curStream
+ 1);
1769 *ppas
= pInStreams
[curStream
+ 1];
1775 } /* create output streams for all input streams */
1777 /* have we still something to write, or lost everything? */
1782 LONG lCurFrame
= -dwFileInitialFrames
;
1784 /* interleaved file */
1785 if (dwInterleave
== 1)
1786 AVIFileEndRecord(pfile
);
1788 for (; lCurFrame
< lFileLength
; lCurFrame
+= lSampleInc
) {
1789 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1792 hres
= AVIStreamInfoW(pOutStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1796 /* initial frames phase at the end for this stream? */
1797 if (-(LONG
)sInfo
.dwInitialFrames
> lCurFrame
)
1800 if ((lFileLength
- lSampleInc
) <= lCurFrame
) {
1801 lLastSample
= AVIStreamLength(pInStreams
[curStream
]);
1802 lFirstVideo
= lLastSample
+ AVIStreamStart(pInStreams
[curStream
]);
1804 if (curStream
!= 0) {
1806 AVIStreamSampleToSample(pInStreams
[curStream
], pInStreams
[0],
1807 (sInfo
.fccType
== streamtypeVIDEO
?
1808 (LONG
)dwInterleave
: lSampleInc
) +
1809 sInfo
.dwInitialFrames
+ lCurFrame
);
1811 lFirstVideo
= lSampleInc
+ (sInfo
.dwInitialFrames
+ lCurFrame
);
1813 lLastSample
= AVIStreamEnd(pInStreams
[curStream
]);
1814 if (lLastSample
<= lFirstVideo
)
1815 lFirstVideo
= lLastSample
;
1818 /* copy needed samples now */
1819 WARN("copy from stream %d samples %ld to %ld...\n",curStream
,
1820 lStart
[curStream
],lFirstVideo
);
1821 while (lFirstVideo
> lStart
[curStream
]) {
1824 /* copy format for case it can change */
1825 lBufferSize
= cbBuffer
;
1826 hres
= AVIStreamReadFormat(pInStreams
[curStream
], lStart
[curStream
],
1827 lpBuffer
, &lBufferSize
);
1830 AVIStreamSetFormat(pOutStreams
[curStream
], lStart
[curStream
],
1831 lpBuffer
, lBufferSize
);
1833 /* try to read data until we got it, or error */
1835 hres
= AVIStreamRead(pInStreams
[curStream
], lStart
[curStream
],
1836 lFirstVideo
- lStart
[curStream
], lpBuffer
,
1837 cbBuffer
, &lReadBytes
, &lReadSamples
);
1838 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1839 (lpBuffer
= GlobalReAllocPtr(lpBuffer
, cbBuffer
*= 2, GPTR
)) != NULL
);
1840 if (lpBuffer
== NULL
)
1841 hres
= AVIERR_MEMORY
;
1845 if (AVIStreamIsKeyFrame(pInStreams
[curStream
], (LONG
)sInfo
.dwStart
))
1846 flags
= AVIIF_KEYFRAME
;
1847 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1848 lpBuffer
, lReadBytes
, flags
, NULL
, NULL
);
1852 lStart
[curStream
] += lReadSamples
;
1854 lStart
[curStream
] = lFirstVideo
;
1855 } /* stream by stream */
1857 /* need to close this block? */
1858 if (dwInterleave
== 1) {
1859 hres
= AVIFileEndRecord(pfile
);
1865 if (lpfnCallback(MulDiv(dwFileInitialFrames
+ lCurFrame
, 100,
1866 dwFileInitialFrames
+ lFileLength
))) {
1867 hres
= AVIERR_USERABORT
;
1870 } /* copy frame by frame */
1872 /* non-interleaved file */
1874 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1876 if (lpfnCallback(MulDiv(curStream
, 100, nStreams
))) {
1877 hres
= AVIERR_USERABORT
;
1881 AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1883 if (sInfo
.dwSampleSize
!= 0) {
1884 /* sample-based data like audio */
1885 while (sInfo
.dwStart
< sInfo
.dwLength
) {
1886 LONG lSamples
= cbBuffer
/ sInfo
.dwSampleSize
;
1888 /* copy format for case it can change */
1889 lBufferSize
= cbBuffer
;
1890 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1891 lpBuffer
, &lBufferSize
);
1894 AVIStreamSetFormat(pOutStreams
[curStream
], sInfo
.dwStart
,
1895 lpBuffer
, lBufferSize
);
1897 /* limit to stream boundaries */
1898 if (lSamples
!= (LONG
)(sInfo
.dwLength
- sInfo
.dwStart
))
1899 lSamples
= sInfo
.dwLength
- sInfo
.dwStart
;
1901 /* now try to read until we got it, or error occures */
1903 lReadBytes
= cbBuffer
;
1905 hres
= AVIStreamRead(pInStreams
[curStream
],sInfo
.dwStart
,lSamples
,
1906 lpBuffer
,cbBuffer
,&lReadBytes
,&lReadSamples
);
1907 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1908 (lpBuffer
= GlobalReAllocPtr(lpBuffer
, cbBuffer
*= 2, GPTR
)) != NULL
);
1909 if (lpBuffer
== NULL
)
1910 hres
= AVIERR_MEMORY
;
1913 if (lReadSamples
!= 0) {
1914 sInfo
.dwStart
+= lReadSamples
;
1915 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1916 lpBuffer
, lReadBytes
, 0, NULL
, NULL
);
1921 if (lpfnCallback(MulDiv(sInfo
.dwStart
,100,nStreams
*sInfo
.dwLength
)+
1922 MulDiv(curStream
, 100, nStreams
))) {
1923 hres
= AVIERR_USERABORT
;
1927 if ((sInfo
.dwLength
- sInfo
.dwStart
) != 1) {
1928 hres
= AVIERR_FILEREAD
;
1934 /* block-based data like video */
1935 for (; sInfo
.dwStart
< sInfo
.dwLength
; sInfo
.dwStart
++) {
1938 /* copy format for case it can change */
1939 lBufferSize
= cbBuffer
;
1940 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1941 lpBuffer
, &lBufferSize
);
1944 AVIStreamSetFormat(pOutStreams
[curStream
], sInfo
.dwStart
,
1945 lpBuffer
, lBufferSize
);
1947 /* try to read block and resize buffer if necessary */
1950 lReadBytes
= cbBuffer
;
1951 hres
= AVIStreamRead(pInStreams
[curStream
], sInfo
.dwStart
, 1,
1952 lpBuffer
, cbBuffer
,&lReadBytes
,&lReadSamples
);
1953 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1954 (lpBuffer
= GlobalReAllocPtr(lpBuffer
, cbBuffer
*= 2, GPTR
)) != NULL
);
1955 if (lpBuffer
== NULL
)
1956 hres
= AVIERR_MEMORY
;
1959 if (lReadSamples
!= 1) {
1960 hres
= AVIERR_FILEREAD
;
1964 if (AVIStreamIsKeyFrame(pInStreams
[curStream
], (LONG
)sInfo
.dwStart
))
1965 flags
= AVIIF_KEYFRAME
;
1966 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1967 lpBuffer
, lReadBytes
, flags
, NULL
, NULL
);
1972 if (lpfnCallback(MulDiv(sInfo
.dwStart
,100,nStreams
*sInfo
.dwLength
)+
1973 MulDiv(curStream
, 100, nStreams
))) {
1974 hres
= AVIERR_USERABORT
;
1977 } /* copy all blocks */
1979 } /* copy data stream by stream */
1983 if (lpBuffer
!= NULL
)
1984 GlobalFreePtr(lpBuffer
);
1985 if (pfile
!= NULL
) {
1986 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1987 if (pOutStreams
[curStream
] != NULL
)
1988 AVIStreamRelease(pOutStreams
[curStream
]);
1989 if (pInStreams
[curStream
] != NULL
)
1990 AVIStreamRelease(pInStreams
[curStream
]);
1993 AVIFileRelease(pfile
);
1999 /***********************************************************************
2000 * CreateEditableStream (AVIFIL32.@)
2002 HRESULT WINAPI
CreateEditableStream(PAVISTREAM
*ppEditable
, PAVISTREAM pSource
)
2004 IAVIEditStream
*pEdit
= NULL
;
2007 FIXME("(%p,%p), semi stub!\n", ppEditable
, pSource
);
2009 if (ppEditable
== NULL
)
2010 return AVIERR_BADPARAM
;
2014 if (pSource
!= NULL
) {
2015 hr
= IAVIStream_QueryInterface(pSource
, &IID_IAVIEditStream
,
2017 if (FAILED(hr
) || pEdit
== NULL
) {
2018 /* need own implementation of IAVIEditStream */
2020 return AVIERR_UNSUPPORTED
;
2024 hr
= IAVIEditStream_Clone(pEdit
, ppEditable
);
2025 IAVIEditStream_Release(pEdit
);
2030 /***********************************************************************
2031 * EditStreamClone (AVIFIL32.@)
2033 HRESULT WINAPI
EditStreamClone(PAVISTREAM pStream
, PAVISTREAM
*ppResult
)
2035 PAVIEDITSTREAM pEdit
= NULL
;
2038 TRACE("(%p,%p)\n", pStream
, ppResult
);
2040 if (pStream
== NULL
)
2041 return AVIERR_BADHANDLE
;
2042 if (ppResult
== NULL
)
2043 return AVIERR_BADPARAM
;
2047 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2048 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2049 hr
= IAVIEditStream_Clone(pEdit
, ppResult
);
2051 IAVIEditStream_Release(pEdit
);
2053 hr
= AVIERR_UNSUPPORTED
;
2058 /***********************************************************************
2059 * EditStreamCopy (AVIFIL32.@)
2061 HRESULT WINAPI
EditStreamCopy(PAVISTREAM pStream
, LONG
*plStart
,
2062 LONG
*plLength
, PAVISTREAM
*ppResult
)
2064 PAVIEDITSTREAM pEdit
= NULL
;
2067 TRACE("(%p,%p,%p,%p)\n", pStream
, plStart
, plLength
, ppResult
);
2069 if (pStream
== NULL
)
2070 return AVIERR_BADHANDLE
;
2071 if (plStart
== NULL
|| plLength
== NULL
|| ppResult
== NULL
)
2072 return AVIERR_BADPARAM
;
2076 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2077 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2078 hr
= IAVIEditStream_Copy(pEdit
, plStart
, plLength
, ppResult
);
2080 IAVIEditStream_Release(pEdit
);
2082 hr
= AVIERR_UNSUPPORTED
;
2087 /***********************************************************************
2088 * EditStreamCut (AVIFIL32.@)
2090 HRESULT WINAPI
EditStreamCut(PAVISTREAM pStream
, LONG
*plStart
,
2091 LONG
*plLength
, PAVISTREAM
*ppResult
)
2093 PAVIEDITSTREAM pEdit
= NULL
;
2096 TRACE("(%p,%p,%p,%p)\n", pStream
, plStart
, plLength
, ppResult
);
2098 if (pStream
== NULL
)
2099 return AVIERR_BADHANDLE
;
2100 if (plStart
== NULL
|| plLength
== NULL
|| ppResult
== NULL
)
2101 return AVIERR_BADPARAM
;
2105 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2106 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2107 hr
= IAVIEditStream_Cut(pEdit
, plStart
, plLength
, ppResult
);
2109 IAVIEditStream_Release(pEdit
);
2111 hr
= AVIERR_UNSUPPORTED
;
2116 /***********************************************************************
2117 * EditStreamPaste (AVIFIL32.@)
2119 HRESULT WINAPI
EditStreamPaste(PAVISTREAM pDest
, LONG
*plStart
, LONG
*plLength
,
2120 PAVISTREAM pSource
, LONG lStart
, LONG lEnd
)
2122 PAVIEDITSTREAM pEdit
= NULL
;
2125 TRACE("(%p,%p,%p,%p,%ld,%ld)\n", pDest
, plStart
, plLength
,
2126 pSource
, lStart
, lEnd
);
2128 if (pDest
== NULL
|| pSource
== NULL
)
2129 return AVIERR_BADHANDLE
;
2130 if (plStart
== NULL
|| plLength
== NULL
|| lStart
< 0)
2131 return AVIERR_BADPARAM
;
2133 hr
= IAVIStream_QueryInterface(pDest
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2134 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2135 hr
= IAVIEditStream_Paste(pEdit
, plStart
, plLength
, pSource
, lStart
, lEnd
);
2137 IAVIEditStream_Release(pEdit
);
2139 hr
= AVIERR_UNSUPPORTED
;
2144 /***********************************************************************
2145 * EditStreamSetInfoA (AVIFIL32.@)
2147 HRESULT WINAPI
EditStreamSetInfoA(PAVISTREAM pstream
, LPAVISTREAMINFOA asi
,
2150 AVISTREAMINFOW asiw
;
2152 TRACE("(%p,%p,%ld)\n", pstream
, asi
, size
);
2154 if (pstream
== NULL
)
2155 return AVIERR_BADHANDLE
;
2156 if ((DWORD
)size
< sizeof(AVISTREAMINFOA
))
2157 return AVIERR_BADSIZE
;
2159 memcpy(&asiw
, asi
, sizeof(asi
) - sizeof(asi
->szName
));
2160 MultiByteToWideChar(CP_ACP
, 0, asi
->szName
, -1,
2161 asiw
.szName
, sizeof(asiw
.szName
));
2163 return EditStreamSetInfoW(pstream
, &asiw
, sizeof(asiw
));
2166 /***********************************************************************
2167 * EditStreamSetInfoW (AVIFIL32.@)
2169 HRESULT WINAPI
EditStreamSetInfoW(PAVISTREAM pstream
, LPAVISTREAMINFOW asi
,
2172 PAVIEDITSTREAM pEdit
= NULL
;
2175 TRACE("(%p,%p,%ld)\n", pstream
, asi
, size
);
2177 hr
= IAVIStream_QueryInterface(pstream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2178 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2179 hr
= IAVIEditStream_SetInfo(pEdit
, asi
, size
);
2181 IAVIEditStream_Release(pEdit
);
2183 hr
= AVIERR_UNSUPPORTED
;
2188 /***********************************************************************
2189 * EditStreamSetNameA (AVIFIL32.@)
2191 HRESULT WINAPI
EditStreamSetNameA(PAVISTREAM pstream
, LPCSTR szName
)
2193 AVISTREAMINFOA asia
;
2196 TRACE("(%p,%s)\n", pstream
, debugstr_a(szName
));
2198 if (pstream
== NULL
)
2199 return AVIERR_BADHANDLE
;
2201 return AVIERR_BADPARAM
;
2203 hres
= AVIStreamInfoA(pstream
, &asia
, sizeof(asia
));
2207 memset(asia
.szName
, 0, sizeof(asia
.szName
));
2208 lstrcpynA(asia
.szName
, szName
, sizeof(asia
.szName
)/sizeof(asia
.szName
[0]));
2210 return EditStreamSetInfoA(pstream
, &asia
, sizeof(asia
));
2213 /***********************************************************************
2214 * EditStreamSetNameW (AVIFIL32.@)
2216 HRESULT WINAPI
EditStreamSetNameW(PAVISTREAM pstream
, LPCWSTR szName
)
2218 AVISTREAMINFOW asiw
;
2221 TRACE("(%p,%s)\n", pstream
, debugstr_w(szName
));
2223 if (pstream
== NULL
)
2224 return AVIERR_BADHANDLE
;
2226 return AVIERR_BADPARAM
;
2228 hres
= IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
));
2232 memset(asiw
.szName
, 0, sizeof(asiw
.szName
));
2233 lstrcpynW(asiw
.szName
, szName
, sizeof(asiw
.szName
)/sizeof(asiw
.szName
[0]));
2235 return EditStreamSetInfoW(pstream
, &asiw
, sizeof(asiw
));
2238 /***********************************************************************
2239 * AVIClearClipboard (AVIFIL32.@)
2241 HRESULT WINAPI
AVIClearClipboard(void)
2245 return AVIERR_UNSUPPORTED
; /* OleSetClipboard(NULL); */
2248 /***********************************************************************
2249 * AVIGetFromClipboard (AVIFIL32.@)
2251 HRESULT WINAPI
AVIGetFromClipboard(PAVIFILE
*ppfile
)
2253 FIXME("(%p), stub!\n", ppfile
);
2257 return AVIERR_UNSUPPORTED
;
2260 /***********************************************************************
2261 * AVIPutFileOnClipboard (AVIFIL32.@)
2263 HRESULT WINAPI
AVIPutFileOnClipboard(PAVIFILE pfile
)
2265 FIXME("(%p), stub!\n", pfile
);
2268 return AVIERR_BADHANDLE
;
2270 return AVIERR_UNSUPPORTED
;