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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
38 #include "avifile_private.h"
40 #include "wine/debug.h"
42 WINE_DEFAULT_DEBUG_CHANNEL(avifile
);
45 /***********************************************************************
46 * for AVIBuildFilterW -- uses fixed size table
48 #define MAX_FILTERS 30 /* 30 => 7kB */
50 typedef struct _AVIFilter
{
52 WCHAR szExtensions
[MAX_FILTERS
* 7];
55 /***********************************************************************
62 LPAVICOMPRESSOPTIONS
*ppOptions
;
66 /***********************************************************************
67 * copied from dlls/ole32/compobj.c
69 static HRESULT
AVIFILE_CLSIDFromString(LPCSTR idstr
, LPCLSID id
)
77 memset(id
, 0, sizeof(CLSID
));
81 /* validate the CLSID string */
82 if (lstrlenA(idstr
) != 38)
83 return CO_E_CLASSSTRING
;
85 s
= (BYTE
const*)idstr
;
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
;
100 TRACE("%s -> %p\n", s
, id
);
102 /* quick lookup table */
103 memset(table
, 0, 256);
105 for (i
= 0; i
< 10; i
++)
108 for (i
= 0; i
< 6; i
++) {
109 table
['A' + i
] = i
+10;
110 table
['a' + i
] = i
+10;
113 /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
116 s
++; /* skip leading brace */
117 for (i
= 0; i
< 4; i
++) {
118 p
[3 - i
] = table
[*s
]<<4 | table
[*(s
+1)];
124 for (i
= 0; i
< 2; i
++) {
125 p
[1-i
] = table
[*s
]<<4 | table
[*(s
+1)];
131 for (i
= 0; i
< 2; i
++) {
132 p
[1-i
] = table
[*s
]<<4 | table
[*(s
+1)];
138 /* these are just sequential bytes */
139 for (i
= 0; i
< 2; i
++) {
140 *p
++ = table
[*s
]<<4 | table
[*(s
+1)];
145 for (i
= 0; i
< 6; i
++) {
146 *p
++ = table
[*s
]<<4 | table
[*(s
+1)];
153 static BOOL
AVIFILE_GetFileHandlerByExtension(LPCWSTR szFile
, LPCLSID lpclsid
)
157 LPWSTR szExt
= wcsrchr(szFile
, '.');
158 LONG len
= ARRAY_SIZE(szValue
);
165 wsprintfA(szRegKey
, "AVIFile\\Extensions\\%.3ls", szExt
);
166 if (RegQueryValueA(HKEY_CLASSES_ROOT
, szRegKey
, szValue
, &len
) != ERROR_SUCCESS
)
169 return (AVIFILE_CLSIDFromString(szValue
, lpclsid
) == S_OK
);
172 /***********************************************************************
173 * AVIFileInit (AVIFIL32.@)
175 void WINAPI
AVIFileInit(void) {
179 /***********************************************************************
180 * AVIFileExit (AVIFIL32.@)
182 void WINAPI
AVIFileExit(void) {
183 /* need to free ole32.dll if we are the last exit call */
184 /* OleUninitialize() */
185 FIXME("(): stub!\n");
188 /***********************************************************************
189 * AVIFileOpen (AVIFIL32.@)
190 * AVIFileOpenA (AVIFIL32.@)
192 HRESULT WINAPI
AVIFileOpenA(PAVIFILE
*ppfile
, LPCSTR szFile
, UINT uMode
,
195 LPWSTR wszFile
= NULL
;
199 TRACE("(%p,%s,0x%08X,%s)\n", ppfile
, debugstr_a(szFile
), uMode
,
200 debugstr_guid(lpHandler
));
202 /* check parameters */
203 if (ppfile
== NULL
|| szFile
== NULL
)
204 return AVIERR_BADPARAM
;
206 /* convert ASCII string to Unicode and call unicode function */
207 len
= MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, NULL
, 0);
209 return AVIERR_BADPARAM
;
211 wszFile
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
213 return AVIERR_MEMORY
;
215 MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, wszFile
, len
);
217 hr
= AVIFileOpenW(ppfile
, wszFile
, uMode
, lpHandler
);
219 HeapFree(GetProcessHeap(), 0, wszFile
);
224 /***********************************************************************
225 * AVIFileOpenW (AVIFIL32.@)
227 HRESULT WINAPI
AVIFileOpenW(PAVIFILE
*ppfile
, LPCWSTR szFile
, UINT uMode
,
230 IPersistFile
*ppersist
= NULL
;
234 TRACE("(%p,%s,0x%X,%s)\n", ppfile
, debugstr_w(szFile
), uMode
,
235 debugstr_guid(lpHandler
));
237 /* check parameters */
238 if (ppfile
== NULL
|| szFile
== NULL
)
239 return AVIERR_BADPARAM
;
243 /* if no handler then try guessing it by extension */
244 if (lpHandler
== NULL
) {
245 if (! AVIFILE_GetFileHandlerByExtension(szFile
, &clsidHandler
))
246 clsidHandler
= CLSID_AVIFile
;
248 clsidHandler
= *lpHandler
;
250 /* create instance of handler */
251 hr
= CoCreateInstance(&clsidHandler
, NULL
, CLSCTX_INPROC
, &IID_IAVIFile
, (LPVOID
*)ppfile
);
252 if (FAILED(hr
) || *ppfile
== NULL
)
255 /* ask for IPersistFile interface for loading/creating the file */
256 hr
= IAVIFile_QueryInterface(*ppfile
, &IID_IPersistFile
, (LPVOID
*)&ppersist
);
257 if (FAILED(hr
) || ppersist
== NULL
) {
258 IAVIFile_Release(*ppfile
);
263 hr
= IPersistFile_Load(ppersist
, szFile
, uMode
);
264 IPersistFile_Release(ppersist
);
266 IAVIFile_Release(*ppfile
);
273 /***********************************************************************
274 * AVIFileAddRef (AVIFIL32.@)
276 ULONG WINAPI
AVIFileAddRef(PAVIFILE pfile
)
278 TRACE("(%p)\n", pfile
);
281 ERR(": bad handle passed!\n");
285 return IAVIFile_AddRef(pfile
);
288 /***********************************************************************
289 * AVIFileRelease (AVIFIL32.@)
291 ULONG WINAPI
AVIFileRelease(PAVIFILE pfile
)
293 TRACE("(%p)\n", pfile
);
296 ERR(": bad handle passed!\n");
300 return IAVIFile_Release(pfile
);
303 /***********************************************************************
304 * AVIFileInfo (AVIFIL32.@)
305 * AVIFileInfoA (AVIFIL32.@)
307 HRESULT WINAPI
AVIFileInfoA(PAVIFILE pfile
, LPAVIFILEINFOA afi
, LONG size
)
312 TRACE("(%p,%p,%d)\n", pfile
, afi
, size
);
315 return AVIERR_BADHANDLE
;
316 if ((DWORD
)size
< sizeof(AVIFILEINFOA
))
317 return AVIERR_BADSIZE
;
319 hres
= IAVIFile_Info(pfile
, &afiw
, sizeof(afiw
));
321 memcpy(afi
, &afiw
, sizeof(*afi
) - sizeof(afi
->szFileType
));
322 WideCharToMultiByte(CP_ACP
, 0, afiw
.szFileType
, -1, afi
->szFileType
,
323 sizeof(afi
->szFileType
), NULL
, NULL
);
324 afi
->szFileType
[sizeof(afi
->szFileType
) - 1] = 0;
329 /***********************************************************************
330 * AVIFileInfoW (AVIFIL32.@)
332 HRESULT WINAPI
AVIFileInfoW(PAVIFILE pfile
, LPAVIFILEINFOW afiw
, LONG size
)
334 TRACE("(%p,%p,%d)\n", pfile
, afiw
, size
);
337 return AVIERR_BADHANDLE
;
339 return IAVIFile_Info(pfile
, afiw
, size
);
342 /***********************************************************************
343 * AVIFileGetStream (AVIFIL32.@)
345 HRESULT WINAPI
AVIFileGetStream(PAVIFILE pfile
, PAVISTREAM
*avis
,
346 DWORD fccType
, LONG lParam
)
348 TRACE("(%p,%p,'%4.4s',%d)\n", pfile
, avis
, (char*)&fccType
, lParam
);
351 return AVIERR_BADHANDLE
;
353 return IAVIFile_GetStream(pfile
, avis
, fccType
, lParam
);
356 /***********************************************************************
357 * AVIFileCreateStream (AVIFIL32.@)
358 * AVIFileCreateStreamA (AVIFIL32.@)
360 HRESULT WINAPI
AVIFileCreateStreamA(PAVIFILE pfile
, PAVISTREAM
*ppavi
,
361 LPAVISTREAMINFOA psi
)
365 TRACE("(%p,%p,%p)\n", pfile
, ppavi
, psi
);
368 return AVIERR_BADHANDLE
;
370 /* Only the szName at the end is different */
371 memcpy(&psiw
, psi
, sizeof(*psi
) - sizeof(psi
->szName
));
372 MultiByteToWideChar(CP_ACP
, 0, psi
->szName
, -1, psiw
.szName
,
373 ARRAY_SIZE(psiw
.szName
));
375 return IAVIFile_CreateStream(pfile
, ppavi
, &psiw
);
378 /***********************************************************************
379 * AVIFileCreateStreamW (AVIFIL32.@)
381 HRESULT WINAPI
AVIFileCreateStreamW(PAVIFILE pfile
, PAVISTREAM
*avis
,
382 LPAVISTREAMINFOW asi
)
384 TRACE("(%p,%p,%p)\n", pfile
, avis
, asi
);
387 return AVIERR_BADHANDLE
;
389 return IAVIFile_CreateStream(pfile
, avis
, asi
);
392 /***********************************************************************
393 * AVIFileWriteData (AVIFIL32.@)
395 HRESULT WINAPI
AVIFileWriteData(PAVIFILE pfile
,DWORD fcc
,LPVOID lp
,LONG size
)
397 TRACE("(%p,'%4.4s',%p,%d)\n", pfile
, (char*)&fcc
, lp
, size
);
400 return AVIERR_BADHANDLE
;
402 return IAVIFile_WriteData(pfile
, fcc
, lp
, size
);
405 /***********************************************************************
406 * AVIFileReadData (AVIFIL32.@)
408 HRESULT WINAPI
AVIFileReadData(PAVIFILE pfile
,DWORD fcc
,LPVOID lp
,LPLONG size
)
410 TRACE("(%p,'%4.4s',%p,%p)\n", pfile
, (char*)&fcc
, lp
, size
);
413 return AVIERR_BADHANDLE
;
415 return IAVIFile_ReadData(pfile
, fcc
, lp
, size
);
418 /***********************************************************************
419 * AVIFileEndRecord (AVIFIL32.@)
421 HRESULT WINAPI
AVIFileEndRecord(PAVIFILE pfile
)
423 TRACE("(%p)\n", pfile
);
426 return AVIERR_BADHANDLE
;
428 return IAVIFile_EndRecord(pfile
);
431 /***********************************************************************
432 * AVIStreamAddRef (AVIFIL32.@)
434 ULONG WINAPI
AVIStreamAddRef(PAVISTREAM pstream
)
436 TRACE("(%p)\n", pstream
);
438 if (pstream
== NULL
) {
439 ERR(": bad handle passed!\n");
443 return IAVIStream_AddRef(pstream
);
446 /***********************************************************************
447 * AVIStreamRelease (AVIFIL32.@)
449 ULONG WINAPI
AVIStreamRelease(PAVISTREAM pstream
)
451 TRACE("(%p)\n", pstream
);
453 if (pstream
== NULL
) {
454 ERR(": bad handle passed!\n");
458 return IAVIStream_Release(pstream
);
461 /***********************************************************************
462 * AVIStreamCreate (AVIFIL32.@)
464 HRESULT WINAPI
AVIStreamCreate(PAVISTREAM
*ppavi
, LONG lParam1
, LONG lParam2
,
465 LPCLSID pclsidHandler
)
469 TRACE("(%p,0x%08X,0x%08X,%s)\n", ppavi
, lParam1
, lParam2
,
470 debugstr_guid(pclsidHandler
));
473 return AVIERR_BADPARAM
;
476 if (pclsidHandler
== NULL
)
477 return AVIERR_UNSUPPORTED
;
479 hr
= CoCreateInstance(pclsidHandler
, NULL
, CLSCTX_INPROC
, &IID_IAVIStream
, (LPVOID
*)ppavi
);
480 if (FAILED(hr
) || *ppavi
== NULL
)
483 hr
= IAVIStream_Create(*ppavi
, lParam1
, lParam2
);
485 IAVIStream_Release(*ppavi
);
492 /***********************************************************************
493 * AVIStreamInfo (AVIFIL32.@)
494 * AVIStreamInfoA (AVIFIL32.@)
496 HRESULT WINAPI
AVIStreamInfoA(PAVISTREAM pstream
, LPAVISTREAMINFOA asi
,
502 TRACE("(%p,%p,%d)\n", pstream
, asi
, size
);
505 return AVIERR_BADHANDLE
;
506 if ((DWORD
)size
< sizeof(AVISTREAMINFOA
))
507 return AVIERR_BADSIZE
;
509 hres
= IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
));
511 memcpy(asi
, &asiw
, sizeof(asiw
) - sizeof(asiw
.szName
));
512 WideCharToMultiByte(CP_ACP
, 0, asiw
.szName
, -1, asi
->szName
,
513 sizeof(asi
->szName
), NULL
, NULL
);
514 asi
->szName
[sizeof(asi
->szName
) - 1] = 0;
519 /***********************************************************************
520 * AVIStreamInfoW (AVIFIL32.@)
522 HRESULT WINAPI
AVIStreamInfoW(PAVISTREAM pstream
, LPAVISTREAMINFOW asi
,
525 TRACE("(%p,%p,%d)\n", pstream
, asi
, size
);
528 return AVIERR_BADHANDLE
;
530 return IAVIStream_Info(pstream
, asi
, size
);
533 /***********************************************************************
534 * AVIStreamFindSample (AVIFIL32.@)
536 LONG WINAPI
AVIStreamFindSample(PAVISTREAM pstream
, LONG pos
, LONG flags
)
538 TRACE("(%p,%d,0x%X)\n", pstream
, pos
, flags
);
543 return IAVIStream_FindSample(pstream
, pos
, flags
);
546 /***********************************************************************
547 * AVIStreamReadFormat (AVIFIL32.@)
549 HRESULT WINAPI
AVIStreamReadFormat(PAVISTREAM pstream
, LONG pos
,
550 LPVOID format
, LPLONG formatsize
)
552 TRACE("(%p,%d,%p,%p)\n", pstream
, pos
, format
, formatsize
);
555 return AVIERR_BADHANDLE
;
557 return IAVIStream_ReadFormat(pstream
, pos
, format
, formatsize
);
560 /***********************************************************************
561 * AVIStreamSetFormat (AVIFIL32.@)
563 HRESULT WINAPI
AVIStreamSetFormat(PAVISTREAM pstream
, LONG pos
,
564 LPVOID format
, LONG formatsize
)
566 TRACE("(%p,%d,%p,%d)\n", pstream
, pos
, format
, formatsize
);
569 return AVIERR_BADHANDLE
;
571 return IAVIStream_SetFormat(pstream
, pos
, format
, formatsize
);
574 /***********************************************************************
575 * AVIStreamRead (AVIFIL32.@)
577 HRESULT WINAPI
AVIStreamRead(PAVISTREAM pstream
, LONG start
, LONG samples
,
578 LPVOID buffer
, LONG buffersize
,
579 LPLONG bytesread
, LPLONG samplesread
)
581 TRACE("(%p,%d,%d,%p,%d,%p,%p)\n", pstream
, start
, samples
, buffer
,
582 buffersize
, bytesread
, samplesread
);
585 return AVIERR_BADHANDLE
;
587 return IAVIStream_Read(pstream
, start
, samples
, buffer
, buffersize
,
588 bytesread
, samplesread
);
591 /***********************************************************************
592 * AVIStreamWrite (AVIFIL32.@)
594 HRESULT WINAPI
AVIStreamWrite(PAVISTREAM pstream
, LONG start
, LONG samples
,
595 LPVOID buffer
, LONG buffersize
, DWORD flags
,
596 LPLONG sampwritten
, LPLONG byteswritten
)
598 TRACE("(%p,%d,%d,%p,%d,0x%X,%p,%p)\n", pstream
, start
, samples
, buffer
,
599 buffersize
, flags
, sampwritten
, byteswritten
);
602 return AVIERR_BADHANDLE
;
604 return IAVIStream_Write(pstream
, start
, samples
, buffer
, buffersize
,
605 flags
, sampwritten
, byteswritten
);
608 /***********************************************************************
609 * AVIStreamReadData (AVIFIL32.@)
611 HRESULT WINAPI
AVIStreamReadData(PAVISTREAM pstream
, DWORD fcc
, LPVOID lp
,
614 TRACE("(%p,'%4.4s',%p,%p)\n", pstream
, (char*)&fcc
, lp
, lpread
);
617 return AVIERR_BADHANDLE
;
619 return IAVIStream_ReadData(pstream
, fcc
, lp
, lpread
);
622 /***********************************************************************
623 * AVIStreamWriteData (AVIFIL32.@)
625 HRESULT WINAPI
AVIStreamWriteData(PAVISTREAM pstream
, DWORD fcc
, LPVOID lp
,
628 TRACE("(%p,'%4.4s',%p,%d)\n", pstream
, (char*)&fcc
, lp
, size
);
631 return AVIERR_BADHANDLE
;
633 return IAVIStream_WriteData(pstream
, fcc
, lp
, size
);
636 /***********************************************************************
637 * AVIStreamGetFrameOpen (AVIFIL32.@)
639 PGETFRAME WINAPI
AVIStreamGetFrameOpen(PAVISTREAM pstream
,
640 LPBITMAPINFOHEADER lpbiWanted
)
644 TRACE("(%p,%p)\n", pstream
, lpbiWanted
);
646 if (FAILED(IAVIStream_QueryInterface(pstream
, &IID_IGetFrame
, (LPVOID
*)&pg
)) ||
648 pg
= AVIFILE_CreateGetFrame(pstream
);
653 if (FAILED(IGetFrame_SetFormat(pg
, lpbiWanted
, NULL
, 0, 0, -1, -1))) {
654 IGetFrame_Release(pg
);
661 /***********************************************************************
662 * AVIStreamGetFrame (AVIFIL32.@)
664 LPVOID WINAPI
AVIStreamGetFrame(PGETFRAME pg
, LONG pos
)
666 TRACE("(%p,%d)\n", pg
, pos
);
671 return IGetFrame_GetFrame(pg
, pos
);
674 /***********************************************************************
675 * AVIStreamGetFrameClose (AVIFIL32.@)
677 HRESULT WINAPI
AVIStreamGetFrameClose(PGETFRAME pg
)
682 return IGetFrame_Release(pg
);
686 /***********************************************************************
687 * AVIMakeCompressedStream (AVIFIL32.@)
689 HRESULT WINAPI
AVIMakeCompressedStream(PAVISTREAM
*ppsCompressed
,
691 LPAVICOMPRESSOPTIONS aco
,
692 LPCLSID pclsidHandler
)
699 LONG size
= sizeof(szValue
);
701 TRACE("(%p,%p,%p,%s)\n", ppsCompressed
, psSource
, aco
,
702 debugstr_guid(pclsidHandler
));
704 if (ppsCompressed
== NULL
)
705 return AVIERR_BADPARAM
;
706 if (psSource
== NULL
)
707 return AVIERR_BADHANDLE
;
709 *ppsCompressed
= NULL
;
711 /* if no handler given get default ones based on streamtype */
712 if (pclsidHandler
== NULL
) {
713 hr
= IAVIStream_Info(psSource
, &asiw
, sizeof(asiw
));
717 wsprintfA(szRegKey
, "AVIFile\\Compressors\\%4.4s", (char*)&asiw
.fccType
);
718 if (RegQueryValueA(HKEY_CLASSES_ROOT
, szRegKey
, szValue
, &size
) != ERROR_SUCCESS
)
719 return AVIERR_UNSUPPORTED
;
720 if (AVIFILE_CLSIDFromString(szValue
, &clsidHandler
) != S_OK
)
721 return AVIERR_UNSUPPORTED
;
723 clsidHandler
= *pclsidHandler
;
725 hr
= CoCreateInstance(&clsidHandler
, NULL
, CLSCTX_INPROC
, &IID_IAVIStream
, (LPVOID
*)ppsCompressed
);
726 if (FAILED(hr
) || *ppsCompressed
== NULL
)
729 hr
= IAVIStream_Create(*ppsCompressed
, (LPARAM
)psSource
, (LPARAM
)aco
);
731 IAVIStream_Release(*ppsCompressed
);
732 *ppsCompressed
= NULL
;
738 /***********************************************************************
739 * AVIMakeFileFromStreams (AVIFIL32.@)
741 HRESULT WINAPI
AVIMakeFileFromStreams(PAVIFILE
*ppfile
, int nStreams
,
742 PAVISTREAM
*ppStreams
)
744 TRACE("(%p,%d,%p)\n", ppfile
, nStreams
, ppStreams
);
746 if (nStreams
< 0 || ppfile
== NULL
|| ppStreams
== NULL
)
747 return AVIERR_BADPARAM
;
749 *ppfile
= AVIFILE_CreateAVITempFile(nStreams
, ppStreams
);
751 return AVIERR_MEMORY
;
756 /***********************************************************************
757 * AVIStreamOpenFromFile (AVIFIL32.@)
758 * AVIStreamOpenFromFileA (AVIFIL32.@)
760 HRESULT WINAPI
AVIStreamOpenFromFileA(PAVISTREAM
*ppavi
, LPCSTR szFile
,
761 DWORD fccType
, LONG lParam
,
762 UINT mode
, LPCLSID pclsidHandler
)
764 PAVIFILE pfile
= NULL
;
767 TRACE("(%p,%s,'%4.4s',%d,0x%X,%s)\n", ppavi
, debugstr_a(szFile
),
768 (char*)&fccType
, lParam
, mode
, debugstr_guid(pclsidHandler
));
770 if (ppavi
== NULL
|| szFile
== NULL
)
771 return AVIERR_BADPARAM
;
775 hr
= AVIFileOpenA(&pfile
, szFile
, mode
, pclsidHandler
);
776 if (FAILED(hr
) || pfile
== NULL
)
779 hr
= IAVIFile_GetStream(pfile
, ppavi
, fccType
, lParam
);
780 IAVIFile_Release(pfile
);
785 /***********************************************************************
786 * AVIStreamOpenFromFileW (AVIFIL32.@)
788 HRESULT WINAPI
AVIStreamOpenFromFileW(PAVISTREAM
*ppavi
, LPCWSTR szFile
,
789 DWORD fccType
, LONG lParam
,
790 UINT mode
, LPCLSID pclsidHandler
)
792 PAVIFILE pfile
= NULL
;
795 TRACE("(%p,%s,'%4.4s',%d,0x%X,%s)\n", ppavi
, debugstr_w(szFile
),
796 (char*)&fccType
, lParam
, mode
, debugstr_guid(pclsidHandler
));
798 if (ppavi
== NULL
|| szFile
== NULL
)
799 return AVIERR_BADPARAM
;
803 hr
= AVIFileOpenW(&pfile
, szFile
, mode
, pclsidHandler
);
804 if (FAILED(hr
) || pfile
== NULL
)
807 hr
= IAVIFile_GetStream(pfile
, ppavi
, fccType
, lParam
);
808 IAVIFile_Release(pfile
);
813 /***********************************************************************
814 * AVIStreamBeginStreaming (AVIFIL32.@)
816 LONG WINAPI
AVIStreamBeginStreaming(PAVISTREAM pavi
, LONG lStart
, LONG lEnd
, LONG lRate
)
818 IAVIStreaming
* pstream
= NULL
;
821 TRACE("(%p,%d,%d,%d)\n", pavi
, lStart
, lEnd
, lRate
);
824 return AVIERR_BADHANDLE
;
826 hr
= IAVIStream_QueryInterface(pavi
, &IID_IAVIStreaming
, (LPVOID
*)&pstream
);
827 if (SUCCEEDED(hr
) && pstream
!= NULL
) {
828 hr
= IAVIStreaming_Begin(pstream
, lStart
, lEnd
, lRate
);
829 IAVIStreaming_Release(pstream
);
836 /***********************************************************************
837 * AVIStreamEndStreaming (AVIFIL32.@)
839 LONG WINAPI
AVIStreamEndStreaming(PAVISTREAM pavi
)
841 IAVIStreaming
* pstream
= NULL
;
844 TRACE("(%p)\n", pavi
);
846 hr
= IAVIStream_QueryInterface(pavi
, &IID_IAVIStreaming
, (LPVOID
*)&pstream
);
847 if (SUCCEEDED(hr
) && pstream
!= NULL
) {
848 IAVIStreaming_End(pstream
);
849 IAVIStreaming_Release(pstream
);
855 /***********************************************************************
856 * AVIStreamStart (AVIFIL32.@)
858 LONG WINAPI
AVIStreamStart(PAVISTREAM pstream
)
862 TRACE("(%p)\n", pstream
);
867 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
873 /***********************************************************************
874 * AVIStreamLength (AVIFIL32.@)
876 LONG WINAPI
AVIStreamLength(PAVISTREAM pstream
)
880 TRACE("(%p)\n", pstream
);
885 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
888 return asiw
.dwLength
;
891 /***********************************************************************
892 * AVIStreamSampleToTime (AVIFIL32.@)
894 LONG WINAPI
AVIStreamSampleToTime(PAVISTREAM pstream
, LONG lSample
)
899 TRACE("(%p,%d)\n", pstream
, lSample
);
904 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
906 if (asiw
.dwRate
== 0)
909 /* limit to stream bounds */
910 if (lSample
< asiw
.dwStart
)
911 lSample
= asiw
.dwStart
;
912 if (lSample
> asiw
.dwStart
+ asiw
.dwLength
)
913 lSample
= asiw
.dwStart
+ asiw
.dwLength
;
915 if (asiw
.dwRate
/ asiw
.dwScale
< 1000)
916 time
= (LONG
)(((float)lSample
* asiw
.dwScale
* 1000) / asiw
.dwRate
);
918 time
= (LONG
)(((float)lSample
* asiw
.dwScale
* 1000 + (asiw
.dwRate
- 1)) / asiw
.dwRate
);
920 TRACE(" -> %d\n",time
);
924 /***********************************************************************
925 * AVIStreamTimeToSample (AVIFIL32.@)
927 LONG WINAPI
AVIStreamTimeToSample(PAVISTREAM pstream
, LONG lTime
)
932 TRACE("(%p,%d)\n", pstream
, lTime
);
934 if (pstream
== NULL
|| lTime
< 0)
937 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
939 if (asiw
.dwScale
== 0)
942 if (asiw
.dwRate
/ asiw
.dwScale
< 1000)
943 sample
= (LONG
)((((float)asiw
.dwRate
* lTime
) / (asiw
.dwScale
* 1000)));
945 sample
= (LONG
)(((float)asiw
.dwRate
* lTime
+ (asiw
.dwScale
* 1000 - 1)) / (asiw
.dwScale
* 1000));
947 /* limit to stream bounds */
948 if (sample
< asiw
.dwStart
)
949 sample
= asiw
.dwStart
;
950 if (sample
> asiw
.dwStart
+ asiw
.dwLength
)
951 sample
= asiw
.dwStart
+ asiw
.dwLength
;
953 TRACE(" -> %d\n", sample
);
957 /***********************************************************************
958 * AVIBuildFilter (AVIFIL32.@)
959 * AVIBuildFilterA (AVIFIL32.@)
961 HRESULT WINAPI
AVIBuildFilterA(LPSTR szFilter
, LONG cbFilter
, BOOL fSaving
)
966 TRACE("(%p,%d,%d)\n", szFilter
, cbFilter
, fSaving
);
968 /* check parameters */
969 if (szFilter
== NULL
)
970 return AVIERR_BADPARAM
;
972 return AVIERR_BADSIZE
;
977 wszFilter
= HeapAlloc(GetProcessHeap(), 0, cbFilter
* sizeof(WCHAR
));
978 if (wszFilter
== NULL
)
979 return AVIERR_MEMORY
;
981 hr
= AVIBuildFilterW(wszFilter
, cbFilter
, fSaving
);
983 WideCharToMultiByte(CP_ACP
, 0, wszFilter
, cbFilter
,
984 szFilter
, cbFilter
, NULL
, NULL
);
987 HeapFree(GetProcessHeap(), 0, wszFilter
);
992 /***********************************************************************
993 * AVIBuildFilterW (AVIFIL32.@)
995 HRESULT WINAPI
AVIBuildFilterW(LPWSTR szFilter
, LONG cbFilter
, BOOL fSaving
)
997 static const WCHAR all_files
[] = L
"*.*\0";
1000 WCHAR szAllFiles
[40];
1001 WCHAR szFileExt
[10];
1008 TRACE("(%p,%d,%d)\n", szFilter
, cbFilter
, fSaving
);
1010 /* check parameters */
1011 if (szFilter
== NULL
)
1012 return AVIERR_BADPARAM
;
1014 return AVIERR_BADSIZE
;
1016 lp
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, MAX_FILTERS
* sizeof(AVIFilter
));
1018 return AVIERR_MEMORY
;
1021 * 1. iterate over HKEY_CLASSES_ROOT\\AVIFile\\Extensions and collect
1022 * extensions and CLSIDs
1023 * 2. iterate over collected CLSIDs and copy its description and its
1024 * extensions to szFilter if it fits
1026 * First filter is named "All multimedia files" and its filter is a
1027 * collection of all possible extensions except "*.*".
1029 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, L
"AVIFile\\Extensions", &hKey
) != ERROR_SUCCESS
) {
1030 HeapFree(GetProcessHeap(), 0, lp
);
1031 return AVIERR_ERROR
;
1033 for (n
= 0;RegEnumKeyW(hKey
, n
, szFileExt
, ARRAY_SIZE(szFileExt
)) == ERROR_SUCCESS
;n
++) {
1036 /* get CLSID to extension */
1037 size
= sizeof(clsidW
);
1038 if (RegQueryValueW(hKey
, szFileExt
, clsidW
, &size
) != ERROR_SUCCESS
)
1041 /* search if the CLSID is already known */
1042 for (i
= 1; i
<= count
; i
++) {
1043 if (lstrcmpW(lp
[i
].szClsid
, clsidW
) == 0)
1044 break; /* a new one */
1047 if (i
== count
+ 1) {
1048 /* it's a new CLSID */
1050 /* FIXME: How do we get info's about read/write capabilities? */
1052 if (count
>= MAX_FILTERS
) {
1053 /* try to inform user of our full fixed size table */
1054 ERR(": More than %d filters found! Adjust MAX_FILTERS in dlls/avifil32/api.c\n", MAX_FILTERS
);
1058 lstrcpyW(lp
[i
].szClsid
, clsidW
);
1063 /* append extension to the filter */
1064 wsprintfW(szValue
, L
";*.%s", szFileExt
);
1065 if (lp
[i
].szExtensions
[0] == 0)
1066 lstrcatW(lp
[i
].szExtensions
, szValue
+ 1);
1068 lstrcatW(lp
[i
].szExtensions
, szValue
);
1070 /* also append to the "all multimedia"-filter */
1071 if (lp
[0].szExtensions
[0] == 0)
1072 lstrcatW(lp
[0].szExtensions
, szValue
+ 1);
1074 lstrcatW(lp
[0].szExtensions
, szValue
);
1078 /* 2. get descriptions for the CLSIDs and fill out szFilter */
1079 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, L
"CLSID", &hKey
) != ERROR_SUCCESS
) {
1080 HeapFree(GetProcessHeap(), 0, lp
);
1081 return AVIERR_ERROR
;
1083 for (n
= 0; n
<= count
; n
++) {
1084 /* first the description */
1086 size
= sizeof(szValue
);
1087 if (RegQueryValueW(hKey
, lp
[n
].szClsid
, szValue
, &size
) == ERROR_SUCCESS
) {
1088 size
= lstrlenW(szValue
);
1089 lstrcpynW(szFilter
, szValue
, cbFilter
);
1092 size
= LoadStringW(AVIFILE_hModule
,IDS_ALLMULTIMEDIA
,szFilter
,cbFilter
);
1094 /* check for enough space */
1096 if (cbFilter
< size
+ lstrlenW(lp
[n
].szExtensions
) + 2) {
1099 HeapFree(GetProcessHeap(), 0, lp
);
1101 return AVIERR_BUFFERTOOSMALL
;
1106 /* and then the filter */
1107 lstrcpynW(szFilter
, lp
[n
].szExtensions
, cbFilter
);
1108 size
= lstrlenW(lp
[n
].szExtensions
) + 1;
1114 HeapFree(GetProcessHeap(), 0, lp
);
1116 /* add "All files" "*.*" filter if enough space left */
1117 size
= LoadStringW(AVIFILE_hModule
, IDS_ALLFILES
, szAllFiles
,
1118 ARRAY_SIZE(szAllFiles
) - ARRAY_SIZE(all_files
)) + 1;
1119 memcpy( szAllFiles
+ size
, all_files
, sizeof(all_files
) );
1120 size
+= ARRAY_SIZE(all_files
);
1122 if (cbFilter
> size
) {
1123 memcpy(szFilter
, szAllFiles
, size
* sizeof(szAllFiles
[0]));
1127 return AVIERR_BUFFERTOOSMALL
;
1131 static BOOL
AVISaveOptionsFmtChoose(HWND hWnd
)
1133 LPAVICOMPRESSOPTIONS pOptions
= SaveOpts
.ppOptions
[SaveOpts
.nCurrent
];
1134 AVISTREAMINFOW sInfo
;
1136 TRACE("(%p)\n", hWnd
);
1138 if (pOptions
== NULL
|| SaveOpts
.ppavis
[SaveOpts
.nCurrent
] == NULL
) {
1139 ERR(": bad state!\n");
1143 if (FAILED(AVIStreamInfoW(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1144 &sInfo
, sizeof(sInfo
)))) {
1145 ERR(": AVIStreamInfoW failed!\n");
1149 if (sInfo
.fccType
== streamtypeVIDEO
) {
1153 memset(&cv
, 0, sizeof(cv
));
1155 if ((pOptions
->dwFlags
& AVICOMPRESSF_VALID
) == 0) {
1156 memset(pOptions
, 0, sizeof(AVICOMPRESSOPTIONS
));
1157 pOptions
->fccType
= streamtypeVIDEO
;
1158 pOptions
->fccHandler
= comptypeDIB
;
1159 pOptions
->dwQuality
= (DWORD
)ICQUALITY_DEFAULT
;
1162 cv
.cbSize
= sizeof(cv
);
1163 cv
.dwFlags
= ICMF_COMPVARS_VALID
;
1164 /*cv.fccType = pOptions->fccType; */
1165 cv
.fccHandler
= pOptions
->fccHandler
;
1166 cv
.lQ
= pOptions
->dwQuality
;
1167 cv
.lpState
= pOptions
->lpParms
;
1168 cv
.cbState
= pOptions
->cbParms
;
1169 if (pOptions
->dwFlags
& AVICOMPRESSF_KEYFRAMES
)
1170 cv
.lKey
= pOptions
->dwKeyFrameEvery
;
1173 if (pOptions
->dwFlags
& AVICOMPRESSF_DATARATE
)
1174 cv
.lDataRate
= pOptions
->dwBytesPerSecond
/ 1024; /* need kBytes */
1178 ret
= ICCompressorChoose(hWnd
, SaveOpts
.uFlags
, NULL
,
1179 SaveOpts
.ppavis
[SaveOpts
.nCurrent
], &cv
, NULL
);
1182 pOptions
->fccHandler
= cv
.fccHandler
;
1183 pOptions
->lpParms
= cv
.lpState
;
1184 pOptions
->cbParms
= cv
.cbState
;
1185 pOptions
->dwQuality
= cv
.lQ
;
1187 pOptions
->dwKeyFrameEvery
= cv
.lKey
;
1188 pOptions
->dwFlags
|= AVICOMPRESSF_KEYFRAMES
;
1190 pOptions
->dwFlags
&= ~AVICOMPRESSF_KEYFRAMES
;
1191 if (cv
.lDataRate
!= 0) {
1192 pOptions
->dwBytesPerSecond
= cv
.lDataRate
* 1024; /* need bytes */
1193 pOptions
->dwFlags
|= AVICOMPRESSF_DATARATE
;
1195 pOptions
->dwFlags
&= ~AVICOMPRESSF_DATARATE
;
1196 pOptions
->dwFlags
|= AVICOMPRESSF_VALID
;
1198 ICCompressorFree(&cv
);
1201 } else if (sInfo
.fccType
== streamtypeAUDIO
) {
1202 ACMFORMATCHOOSEW afmtc
;
1206 /* FIXME: check ACM version -- Which version is needed? */
1208 memset(&afmtc
, 0, sizeof(afmtc
));
1209 afmtc
.cbStruct
= sizeof(afmtc
);
1211 afmtc
.hwndOwner
= hWnd
;
1213 acmMetrics(NULL
, ACM_METRIC_MAX_SIZE_FORMAT
, &size
);
1214 if ((pOptions
->cbFormat
== 0 || pOptions
->lpFormat
== NULL
) && size
!= 0) {
1215 pOptions
->lpFormat
= HeapAlloc(GetProcessHeap(), 0, size
);
1216 if (!pOptions
->lpFormat
) return FALSE
;
1217 pOptions
->cbFormat
= size
;
1218 } else if (pOptions
->cbFormat
< (DWORD
)size
) {
1219 void *new_buffer
= HeapReAlloc(GetProcessHeap(), 0, pOptions
->lpFormat
, size
);
1220 if (!new_buffer
) return FALSE
;
1221 pOptions
->lpFormat
= new_buffer
;
1222 pOptions
->cbFormat
= size
;
1224 afmtc
.pwfx
= pOptions
->lpFormat
;
1225 afmtc
.cbwfx
= pOptions
->cbFormat
;
1228 AVIStreamFormatSize(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1229 sInfo
.dwStart
, &size
);
1230 if (size
< (LONG
)sizeof(PCMWAVEFORMAT
))
1231 size
= sizeof(PCMWAVEFORMAT
);
1232 afmtc
.pwfxEnum
= HeapAlloc(GetProcessHeap(), 0, size
);
1233 if (afmtc
.pwfxEnum
!= NULL
) {
1234 AVIStreamReadFormat(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1235 sInfo
.dwStart
, afmtc
.pwfxEnum
, &size
);
1236 afmtc
.fdwEnum
= ACM_FORMATENUMF_CONVERT
;
1239 ret
= acmFormatChooseW(&afmtc
);
1241 pOptions
->dwFlags
|= AVICOMPRESSF_VALID
;
1243 HeapFree(GetProcessHeap(), 0, afmtc
.pwfxEnum
);
1246 ERR(": unknown streamtype 0x%08X\n", sInfo
.fccType
);
1251 static void AVISaveOptionsUpdate(HWND hWnd
)
1253 WCHAR szFormat
[128];
1254 AVISTREAMINFOW sInfo
;
1258 TRACE("(%p)\n", hWnd
);
1260 SaveOpts
.nCurrent
= SendDlgItemMessageW(hWnd
,IDC_STREAM
,CB_GETCURSEL
,0,0);
1261 if (SaveOpts
.nCurrent
< 0)
1264 if (FAILED(AVIStreamInfoW(SaveOpts
.ppavis
[SaveOpts
.nCurrent
], &sInfo
, sizeof(sInfo
))))
1267 AVIStreamFormatSize(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],sInfo
.dwStart
,&size
);
1271 /* read format to build format description string */
1272 lpFormat
= HeapAlloc(GetProcessHeap(), 0, size
);
1273 if (lpFormat
!= NULL
) {
1274 if (SUCCEEDED(AVIStreamReadFormat(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],sInfo
.dwStart
,lpFormat
, &size
))) {
1275 if (sInfo
.fccType
== streamtypeVIDEO
) {
1276 LPBITMAPINFOHEADER lpbi
= lpFormat
;
1279 wsprintfW(szFormat
, L
"%ldx%ldx%d", lpbi
->biWidth
,
1280 lpbi
->biHeight
, lpbi
->biBitCount
);
1282 if (lpbi
->biCompression
!= BI_RGB
) {
1285 hic
= ICLocate(ICTYPE_VIDEO
, sInfo
.fccHandler
, lpFormat
,
1286 NULL
, ICMODE_DECOMPRESS
);
1288 if (ICGetInfo(hic
, &icinfo
, sizeof(icinfo
)) == S_OK
)
1289 lstrcatW(szFormat
, icinfo
.szDescription
);
1293 LoadStringW(AVIFILE_hModule
, IDS_UNCOMPRESSED
,
1294 icinfo
.szDescription
,
1295 ARRAY_SIZE(icinfo
.szDescription
));
1296 lstrcatW(szFormat
, icinfo
.szDescription
);
1298 } else if (sInfo
.fccType
== streamtypeAUDIO
) {
1299 ACMFORMATTAGDETAILSW aftd
;
1300 ACMFORMATDETAILSW afd
;
1302 memset(&aftd
, 0, sizeof(aftd
));
1303 memset(&afd
, 0, sizeof(afd
));
1305 aftd
.cbStruct
= sizeof(aftd
);
1306 aftd
.dwFormatTag
= afd
.dwFormatTag
=
1307 ((PWAVEFORMATEX
)lpFormat
)->wFormatTag
;
1308 aftd
.cbFormatSize
= afd
.cbwfx
= size
;
1310 afd
.cbStruct
= sizeof(afd
);
1311 afd
.pwfx
= lpFormat
;
1313 if (acmFormatTagDetailsW(NULL
, &aftd
,
1314 ACM_FORMATTAGDETAILSF_FORMATTAG
) == S_OK
) {
1315 if (acmFormatDetailsW(NULL
,&afd
,ACM_FORMATDETAILSF_FORMAT
) == S_OK
)
1316 wsprintfW(szFormat
, L
"%s %s", afd
.szFormat
, aftd
.szFormatTag
);
1320 HeapFree(GetProcessHeap(), 0, lpFormat
);
1323 /* set text for format description */
1324 SetDlgItemTextW(hWnd
, IDC_FORMATTEXT
, szFormat
);
1326 /* Disable option button for unsupported streamtypes */
1327 if (sInfo
.fccType
== streamtypeVIDEO
||
1328 sInfo
.fccType
== streamtypeAUDIO
)
1329 EnableWindow(GetDlgItem(hWnd
, IDC_OPTIONS
), TRUE
);
1331 EnableWindow(GetDlgItem(hWnd
, IDC_OPTIONS
), FALSE
);
1336 static INT_PTR CALLBACK
AVISaveOptionsDlgProc(HWND hWnd
, UINT uMsg
,
1337 WPARAM wParam
, LPARAM lParam
)
1340 BOOL bIsInterleaved
;
1343 /*TRACE("(%p,%u,0x%04X,0x%08lX)\n", hWnd, uMsg, wParam, lParam);*/
1347 SaveOpts
.nCurrent
= 0;
1348 if (SaveOpts
.nStreams
== 1) {
1349 EndDialog(hWnd
, AVISaveOptionsFmtChoose(hWnd
));
1354 for (n
= 0; n
< SaveOpts
.nStreams
; n
++) {
1355 AVISTREAMINFOW sInfo
;
1357 AVIStreamInfoW(SaveOpts
.ppavis
[n
], &sInfo
, sizeof(sInfo
));
1358 SendDlgItemMessageW(hWnd
, IDC_STREAM
, CB_ADDSTRING
,
1359 0L, (LPARAM
)sInfo
.szName
);
1362 /* select first stream */
1363 SendDlgItemMessageW(hWnd
, IDC_STREAM
, CB_SETCURSEL
, 0, 0);
1364 SendMessageW(hWnd
, WM_COMMAND
, MAKELONG(IDC_STREAM
, CBN_SELCHANGE
), (LPARAM
)hWnd
);
1366 /* initialize interleave */
1367 if (SaveOpts
.ppOptions
[0] != NULL
&&
1368 (SaveOpts
.ppOptions
[0]->dwFlags
& AVICOMPRESSF_VALID
)) {
1369 bIsInterleaved
= (SaveOpts
.ppOptions
[0]->dwFlags
& AVICOMPRESSF_INTERLEAVE
);
1370 dwInterleave
= SaveOpts
.ppOptions
[0]->dwInterleaveEvery
;
1372 bIsInterleaved
= TRUE
;
1375 CheckDlgButton(hWnd
, IDC_INTERLEAVE
, bIsInterleaved
);
1376 SetDlgItemInt(hWnd
, IDC_INTERLEAVEEVERY
, dwInterleave
, FALSE
);
1377 EnableWindow(GetDlgItem(hWnd
, IDC_INTERLEAVEEVERY
), bIsInterleaved
);
1380 switch (LOWORD(wParam
)) {
1382 /* get data from controls and save them */
1383 dwInterleave
= GetDlgItemInt(hWnd
, IDC_INTERLEAVEEVERY
, NULL
, 0);
1384 bIsInterleaved
= IsDlgButtonChecked(hWnd
, IDC_INTERLEAVE
);
1385 for (n
= 0; n
< SaveOpts
.nStreams
; n
++) {
1386 if (SaveOpts
.ppOptions
[n
] != NULL
) {
1387 if (bIsInterleaved
) {
1388 SaveOpts
.ppOptions
[n
]->dwFlags
|= AVICOMPRESSF_INTERLEAVE
;
1389 SaveOpts
.ppOptions
[n
]->dwInterleaveEvery
= dwInterleave
;
1391 SaveOpts
.ppOptions
[n
]->dwFlags
&= ~AVICOMPRESSF_INTERLEAVE
;
1396 EndDialog(hWnd
, LOWORD(wParam
) == IDOK
);
1398 case IDC_INTERLEAVE
:
1399 EnableWindow(GetDlgItem(hWnd
, IDC_INTERLEAVEEVERY
),
1400 IsDlgButtonChecked(hWnd
, IDC_INTERLEAVE
));
1403 if (HIWORD(wParam
) == CBN_SELCHANGE
) {
1404 /* update control elements */
1405 AVISaveOptionsUpdate(hWnd
);
1409 AVISaveOptionsFmtChoose(hWnd
);
1418 /***********************************************************************
1419 * AVISaveOptions (AVIFIL32.@)
1421 BOOL WINAPI
AVISaveOptions(HWND hWnd
, UINT uFlags
, INT nStreams
,
1422 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*ppOptions
)
1424 LPAVICOMPRESSOPTIONS pSavedOptions
= NULL
;
1427 TRACE("(%p,0x%X,%d,%p,%p)\n", hWnd
, uFlags
, nStreams
,
1430 /* check parameters */
1431 if (nStreams
<= 0 || ppavi
== NULL
|| ppOptions
== NULL
)
1432 return AVIERR_BADPARAM
;
1434 /* save options in case the user presses cancel */
1436 pSavedOptions
= HeapAlloc(GetProcessHeap(), 0, nStreams
* sizeof(AVICOMPRESSOPTIONS
));
1437 if (pSavedOptions
== NULL
)
1440 for (n
= 0; n
< nStreams
; n
++) {
1441 if (ppOptions
[n
] != NULL
)
1442 memcpy(pSavedOptions
+ n
, ppOptions
[n
], sizeof(AVICOMPRESSOPTIONS
));
1446 SaveOpts
.uFlags
= uFlags
;
1447 SaveOpts
.nStreams
= nStreams
;
1448 SaveOpts
.ppavis
= ppavi
;
1449 SaveOpts
.ppOptions
= ppOptions
;
1451 ret
= DialogBoxW(AVIFILE_hModule
, MAKEINTRESOURCEW(IDD_SAVEOPTIONS
),
1452 hWnd
, AVISaveOptionsDlgProc
);
1457 /* restore options when user pressed cancel */
1458 if (pSavedOptions
!= NULL
) {
1460 for (n
= 0; n
< nStreams
; n
++) {
1461 if (ppOptions
[n
] != NULL
)
1462 memcpy(ppOptions
[n
], pSavedOptions
+ n
, sizeof(AVICOMPRESSOPTIONS
));
1465 HeapFree(GetProcessHeap(), 0, pSavedOptions
);
1471 /***********************************************************************
1472 * AVISaveOptionsFree (AVIFIL32.@)
1474 HRESULT WINAPI
AVISaveOptionsFree(INT nStreams
,LPAVICOMPRESSOPTIONS
*ppOptions
)
1476 TRACE("(%d,%p)\n", nStreams
, ppOptions
);
1478 if (nStreams
< 0 || ppOptions
== NULL
)
1479 return AVIERR_BADPARAM
;
1481 for (nStreams
--; nStreams
>= 0; nStreams
--) {
1482 if (ppOptions
[nStreams
] != NULL
) {
1483 ppOptions
[nStreams
]->dwFlags
&= ~AVICOMPRESSF_VALID
;
1485 if (ppOptions
[nStreams
]->lpParms
!= NULL
) {
1486 HeapFree(GetProcessHeap(), 0, ppOptions
[nStreams
]->lpParms
);
1487 ppOptions
[nStreams
]->lpParms
= NULL
;
1488 ppOptions
[nStreams
]->cbParms
= 0;
1490 if (ppOptions
[nStreams
]->lpFormat
!= NULL
) {
1491 HeapFree(GetProcessHeap(), 0, ppOptions
[nStreams
]->lpFormat
);
1492 ppOptions
[nStreams
]->lpFormat
= NULL
;
1493 ppOptions
[nStreams
]->cbFormat
= 0;
1501 /***********************************************************************
1502 * AVISaveVA (AVIFIL32.@)
1504 HRESULT WINAPI
AVISaveVA(LPCSTR szFile
, CLSID
*pclsidHandler
,
1505 AVISAVECALLBACK lpfnCallback
, int nStream
,
1506 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*plpOptions
)
1508 LPWSTR wszFile
= NULL
;
1512 TRACE("(%s,%p,%p,%d,%p,%p)\n", debugstr_a(szFile
), pclsidHandler
,
1513 lpfnCallback
, nStream
, ppavi
, plpOptions
);
1515 if (szFile
== NULL
|| ppavi
== NULL
|| plpOptions
== NULL
)
1516 return AVIERR_BADPARAM
;
1518 /* convert ASCII string to Unicode and call Unicode function */
1519 len
= MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, NULL
, 0);
1521 return AVIERR_BADPARAM
;
1523 wszFile
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1524 if (wszFile
== NULL
)
1525 return AVIERR_MEMORY
;
1527 MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, wszFile
, len
);
1529 hr
= AVISaveVW(wszFile
, pclsidHandler
, lpfnCallback
,
1530 nStream
, ppavi
, plpOptions
);
1532 HeapFree(GetProcessHeap(), 0, wszFile
);
1537 /***********************************************************************
1538 * AVIFILE_AVISaveDefaultCallback (internal)
1540 static BOOL WINAPI
AVIFILE_AVISaveDefaultCallback(INT progress
)
1542 TRACE("(%d)\n", progress
);
1547 /***********************************************************************
1548 * AVISaveVW (AVIFIL32.@)
1550 HRESULT WINAPI
AVISaveVW(LPCWSTR szFile
, CLSID
*pclsidHandler
,
1551 AVISAVECALLBACK lpfnCallback
, int nStreams
,
1552 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*plpOptions
)
1554 LONG lStart
[MAX_AVISTREAMS
];
1555 PAVISTREAM pOutStreams
[MAX_AVISTREAMS
];
1556 PAVISTREAM pInStreams
[MAX_AVISTREAMS
];
1558 AVISTREAMINFOW sInfo
;
1560 PAVIFILE pfile
= NULL
; /* the output AVI file */
1561 LONG lFirstVideo
= -1;
1564 /* for interleaving ... */
1565 DWORD dwInterleave
= 0; /* interleave rate */
1566 DWORD dwFileInitialFrames
;
1570 /* for reading/writing the data ... */
1571 LPVOID lpBuffer
= NULL
;
1572 LONG cbBuffer
; /* real size of lpBuffer */
1573 LONG lBufferSize
; /* needed bytes for format(s), etc. */
1578 TRACE("(%s,%p,%p,%d,%p,%p)\n", debugstr_w(szFile
), pclsidHandler
,
1579 lpfnCallback
, nStreams
, ppavi
, plpOptions
);
1581 if (szFile
== NULL
|| ppavi
== NULL
|| plpOptions
== NULL
)
1582 return AVIERR_BADPARAM
;
1583 if (nStreams
>= MAX_AVISTREAMS
) {
1584 WARN("Can't write AVI with %d streams only supports %d -- change MAX_AVISTREAMS!\n", nStreams
, MAX_AVISTREAMS
);
1585 return AVIERR_INTERNAL
;
1588 if (lpfnCallback
== NULL
)
1589 lpfnCallback
= AVIFILE_AVISaveDefaultCallback
;
1591 /* clear local variable(s) */
1592 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1593 pInStreams
[curStream
] = NULL
;
1594 pOutStreams
[curStream
] = NULL
;
1597 /* open output AVI file (create it if it doesn't exist) */
1598 hres
= AVIFileOpenW(&pfile
, szFile
, OF_CREATE
|OF_SHARE_EXCLUSIVE
|OF_WRITE
,
1602 AVIFileInfoW(pfile
, &fInfo
, sizeof(fInfo
)); /* for dwCaps */
1604 /* initialize our data structures part 1 */
1605 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1606 PAVISTREAM pCurStream
= ppavi
[curStream
];
1608 hres
= AVIStreamInfoW(pCurStream
, &sInfo
, sizeof(sInfo
));
1612 /* search first video stream and check for interleaving */
1613 if (sInfo
.fccType
== streamtypeVIDEO
) {
1614 /* remember first video stream -- needed for interleaving */
1615 if (lFirstVideo
< 0)
1616 lFirstVideo
= curStream
;
1617 } else if (!dwInterleave
) {
1618 /* check if any non-video stream wants to be interleaved */
1619 WARN("options.flags=0x%X options.dwInterleave=%u\n",plpOptions
[curStream
]->dwFlags
,plpOptions
[curStream
]->dwInterleaveEvery
);
1620 if (plpOptions
[curStream
] != NULL
&&
1621 plpOptions
[curStream
]->dwFlags
& AVICOMPRESSF_INTERLEAVE
)
1622 dwInterleave
= plpOptions
[curStream
]->dwInterleaveEvery
;
1625 /* create de-/compressed stream interface if needed */
1626 pInStreams
[curStream
] = NULL
;
1627 if (plpOptions
[curStream
] != NULL
) {
1628 if (plpOptions
[curStream
]->fccHandler
||
1629 plpOptions
[curStream
]->lpFormat
!= NULL
) {
1630 DWORD dwKeySave
= plpOptions
[curStream
]->dwKeyFrameEvery
;
1632 if (fInfo
.dwCaps
& AVIFILECAPS_ALLKEYFRAMES
)
1633 plpOptions
[curStream
]->dwKeyFrameEvery
= 1;
1635 hres
= AVIMakeCompressedStream(&pInStreams
[curStream
], pCurStream
,
1636 plpOptions
[curStream
], NULL
);
1637 plpOptions
[curStream
]->dwKeyFrameEvery
= dwKeySave
;
1638 if (FAILED(hres
) || pInStreams
[curStream
] == NULL
) {
1639 pInStreams
[curStream
] = NULL
;
1643 /* test stream interface and update stream-info */
1644 hres
= AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1650 /* now handle streams which will only be copied */
1651 if (pInStreams
[curStream
] == NULL
) {
1652 pCurStream
= pInStreams
[curStream
] = ppavi
[curStream
];
1653 AVIStreamAddRef(pCurStream
);
1655 pCurStream
= pInStreams
[curStream
];
1657 lStart
[curStream
] = sInfo
.dwStart
;
1658 } /* for all streams */
1660 /* check that first video stream is the first stream */
1661 if (lFirstVideo
> 0) {
1662 PAVISTREAM pTmp
= pInStreams
[lFirstVideo
];
1663 LONG lTmp
= lStart
[lFirstVideo
];
1665 pInStreams
[lFirstVideo
] = pInStreams
[0];
1666 pInStreams
[0] = pTmp
;
1667 lStart
[lFirstVideo
] = lStart
[0];
1672 /* allocate buffer for formats, data, etc. of an initial size of 64 kBytes*/
1673 cbBuffer
= 0x00010000;
1674 lpBuffer
= HeapAlloc(GetProcessHeap(), 0, cbBuffer
);
1675 if (lpBuffer
== NULL
) {
1676 hres
= AVIERR_MEMORY
;
1680 AVIStreamInfoW(pInStreams
[0], &sInfo
, sizeof(sInfo
));
1681 lFileLength
= sInfo
.dwLength
;
1682 dwFileInitialFrames
= 0;
1683 if (lFirstVideo
>= 0) {
1684 /* check for correct version of the format
1685 * -- need at least BITMAPINFOHEADER or newer
1688 lBufferSize
= cbBuffer
;
1689 hres
= AVIStreamReadFormat(pInStreams
[lFirstVideo
], AVIStreamStart(pInStreams
[lFirstVideo
]), lpBuffer
, &lBufferSize
);
1690 if (lBufferSize
< (LONG
)sizeof(BITMAPINFOHEADER
))
1691 hres
= AVIERR_INTERNAL
;
1694 } else /* use one second blocks for interleaving if no video present */
1695 lSampleInc
= AVIStreamTimeToSample(pInStreams
[0], 1000000);
1697 /* create output streams */
1698 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1699 AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1701 sInfo
.dwInitialFrames
= 0;
1702 if (dwInterleave
!= 0 && curStream
> 0 && sInfo
.fccType
!= streamtypeVIDEO
) {
1703 /* 750 ms initial frames for non-video streams */
1704 sInfo
.dwInitialFrames
= AVIStreamTimeToSample(pInStreams
[0], 750);
1707 hres
= AVIFileCreateStreamW(pfile
, &pOutStreams
[curStream
], &sInfo
);
1708 if (pOutStreams
[curStream
] != NULL
&& SUCCEEDED(hres
)) {
1709 /* copy initial format for this stream */
1710 lBufferSize
= cbBuffer
;
1711 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1712 lpBuffer
, &lBufferSize
);
1715 hres
= AVIStreamSetFormat(pOutStreams
[curStream
], 0, lpBuffer
, lBufferSize
);
1719 /* try to copy stream handler data */
1720 lBufferSize
= cbBuffer
;
1721 hres
= AVIStreamReadData(pInStreams
[curStream
], ckidSTREAMHANDLERDATA
,
1722 lpBuffer
, &lBufferSize
);
1723 if (SUCCEEDED(hres
) && lBufferSize
> 0) {
1724 hres
= AVIStreamWriteData(pOutStreams
[curStream
],ckidSTREAMHANDLERDATA
,
1725 lpBuffer
, lBufferSize
);
1730 if (dwFileInitialFrames
< sInfo
.dwInitialFrames
)
1731 dwFileInitialFrames
= sInfo
.dwInitialFrames
;
1733 AVIStreamSampleToSample(pOutStreams
[0], pInStreams
[curStream
],
1735 if (lFileLength
< lReadBytes
)
1736 lFileLength
= lReadBytes
;
1738 /* creation of de-/compression stream interface failed */
1739 WARN("creation of (de-)compression stream failed for stream %d\n",curStream
);
1740 AVIStreamRelease(pInStreams
[curStream
]);
1741 if (curStream
+ 1 >= nStreams
) {
1742 /* move the others one up */
1743 PAVISTREAM
*ppas
= &pInStreams
[curStream
];
1744 int n
= nStreams
- (curStream
+ 1);
1747 *ppas
= pInStreams
[curStream
+ 1];
1753 } /* create output streams for all input streams */
1755 /* have we still something to write, or lost everything? */
1760 LONG lCurFrame
= -dwFileInitialFrames
;
1762 /* interleaved file */
1763 if (dwInterleave
== 1)
1764 AVIFileEndRecord(pfile
);
1766 for (; lCurFrame
< lFileLength
; lCurFrame
+= lSampleInc
) {
1767 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1770 hres
= AVIStreamInfoW(pOutStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1774 /* initial frames phase at the end for this stream? */
1775 if (-(LONG
)sInfo
.dwInitialFrames
> lCurFrame
)
1778 if ((lFileLength
- lSampleInc
) <= lCurFrame
) {
1779 lLastSample
= AVIStreamLength(pInStreams
[curStream
]);
1780 lFirstVideo
= lLastSample
+ AVIStreamStart(pInStreams
[curStream
]);
1782 if (curStream
!= 0) {
1784 AVIStreamSampleToSample(pInStreams
[curStream
], pInStreams
[0],
1785 (sInfo
.fccType
== streamtypeVIDEO
?
1786 (LONG
)dwInterleave
: lSampleInc
) +
1787 sInfo
.dwInitialFrames
+ lCurFrame
);
1789 lFirstVideo
= lSampleInc
+ (sInfo
.dwInitialFrames
+ lCurFrame
);
1791 lLastSample
= AVIStreamEnd(pInStreams
[curStream
]);
1792 if (lLastSample
<= lFirstVideo
)
1793 lFirstVideo
= lLastSample
;
1796 /* copy needed samples now */
1797 WARN("copy from stream %d samples %d to %d...\n",curStream
,
1798 lStart
[curStream
],lFirstVideo
);
1799 while (lFirstVideo
> lStart
[curStream
]) {
1802 /* copy format in case it can change */
1803 lBufferSize
= cbBuffer
;
1804 hres
= AVIStreamReadFormat(pInStreams
[curStream
], lStart
[curStream
],
1805 lpBuffer
, &lBufferSize
);
1808 AVIStreamSetFormat(pOutStreams
[curStream
], lStart
[curStream
],
1809 lpBuffer
, lBufferSize
);
1811 /* try to read data until we got it, or error */
1813 hres
= AVIStreamRead(pInStreams
[curStream
], lStart
[curStream
],
1814 lFirstVideo
- lStart
[curStream
], lpBuffer
,
1815 cbBuffer
, &lReadBytes
, &lReadSamples
);
1816 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1817 (lpBuffer
= HeapReAlloc(GetProcessHeap(), 0, lpBuffer
, cbBuffer
*= 2)) != NULL
);
1818 if (lpBuffer
== NULL
)
1819 hres
= AVIERR_MEMORY
;
1823 if (AVIStreamIsKeyFrame(pInStreams
[curStream
], (LONG
)sInfo
.dwStart
))
1824 flags
= AVIIF_KEYFRAME
;
1825 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1826 lpBuffer
, lReadBytes
, flags
, NULL
, NULL
);
1830 lStart
[curStream
] += lReadSamples
;
1832 lStart
[curStream
] = lFirstVideo
;
1833 } /* stream by stream */
1835 /* need to close this block? */
1836 if (dwInterleave
== 1) {
1837 hres
= AVIFileEndRecord(pfile
);
1843 if (lpfnCallback(MulDiv(dwFileInitialFrames
+ lCurFrame
, 100,
1844 dwFileInitialFrames
+ lFileLength
))) {
1845 hres
= AVIERR_USERABORT
;
1848 } /* copy frame by frame */
1850 /* non-interleaved file */
1852 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1854 if (lpfnCallback(MulDiv(curStream
, 100, nStreams
))) {
1855 hres
= AVIERR_USERABORT
;
1859 AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1861 if (sInfo
.dwSampleSize
!= 0) {
1862 /* sample-based data like audio */
1863 while (sInfo
.dwStart
< sInfo
.dwLength
) {
1864 LONG lSamples
= cbBuffer
/ sInfo
.dwSampleSize
;
1866 /* copy format in case it can change */
1867 lBufferSize
= cbBuffer
;
1868 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1869 lpBuffer
, &lBufferSize
);
1872 AVIStreamSetFormat(pOutStreams
[curStream
], sInfo
.dwStart
,
1873 lpBuffer
, lBufferSize
);
1875 /* limit to stream boundaries */
1876 if (lSamples
!= (LONG
)(sInfo
.dwLength
- sInfo
.dwStart
))
1877 lSamples
= sInfo
.dwLength
- sInfo
.dwStart
;
1879 /* now try to read until we get it, or an error occurs */
1881 lReadBytes
= cbBuffer
;
1883 hres
= AVIStreamRead(pInStreams
[curStream
],sInfo
.dwStart
,lSamples
,
1884 lpBuffer
,cbBuffer
,&lReadBytes
,&lReadSamples
);
1885 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1886 (lpBuffer
= HeapReAlloc(GetProcessHeap(), 0, lpBuffer
, cbBuffer
*= 2)) != NULL
);
1887 if (lpBuffer
== NULL
)
1888 hres
= AVIERR_MEMORY
;
1891 if (lReadSamples
!= 0) {
1892 sInfo
.dwStart
+= lReadSamples
;
1893 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1894 lpBuffer
, lReadBytes
, 0, NULL
, NULL
);
1899 if (lpfnCallback(MulDiv(sInfo
.dwStart
,100,nStreams
*sInfo
.dwLength
)+
1900 MulDiv(curStream
, 100, nStreams
))) {
1901 hres
= AVIERR_USERABORT
;
1905 if ((sInfo
.dwLength
- sInfo
.dwStart
) != 1) {
1906 hres
= AVIERR_FILEREAD
;
1912 /* block-based data like video */
1913 for (; sInfo
.dwStart
< sInfo
.dwLength
; sInfo
.dwStart
++) {
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 /* try to read block and resize buffer if necessary */
1928 lReadBytes
= cbBuffer
;
1929 hres
= AVIStreamRead(pInStreams
[curStream
], sInfo
.dwStart
, 1,
1930 lpBuffer
, cbBuffer
,&lReadBytes
,&lReadSamples
);
1931 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1932 (lpBuffer
= HeapReAlloc(GetProcessHeap(), 0, lpBuffer
, cbBuffer
*= 2)) != NULL
);
1933 if (lpBuffer
== NULL
)
1934 hres
= AVIERR_MEMORY
;
1937 if (lReadSamples
!= 1) {
1938 hres
= AVIERR_FILEREAD
;
1942 if (AVIStreamIsKeyFrame(pInStreams
[curStream
], (LONG
)sInfo
.dwStart
))
1943 flags
= AVIIF_KEYFRAME
;
1944 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1945 lpBuffer
, lReadBytes
, flags
, NULL
, NULL
);
1950 if (lpfnCallback(MulDiv(sInfo
.dwStart
,100,nStreams
*sInfo
.dwLength
)+
1951 MulDiv(curStream
, 100, nStreams
))) {
1952 hres
= AVIERR_USERABORT
;
1955 } /* copy all blocks */
1957 } /* copy data stream by stream */
1961 HeapFree(GetProcessHeap(), 0, lpBuffer
);
1962 if (pfile
!= NULL
) {
1963 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1964 if (pOutStreams
[curStream
] != NULL
)
1965 AVIStreamRelease(pOutStreams
[curStream
]);
1966 if (pInStreams
[curStream
] != NULL
)
1967 AVIStreamRelease(pInStreams
[curStream
]);
1970 AVIFileRelease(pfile
);
1976 /***********************************************************************
1977 * EditStreamClone (AVIFIL32.@)
1979 HRESULT WINAPI
EditStreamClone(PAVISTREAM pStream
, PAVISTREAM
*ppResult
)
1981 PAVIEDITSTREAM pEdit
= NULL
;
1984 TRACE("(%p,%p)\n", pStream
, ppResult
);
1986 if (pStream
== NULL
)
1987 return AVIERR_BADHANDLE
;
1988 if (ppResult
== NULL
)
1989 return AVIERR_BADPARAM
;
1993 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
1994 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
1995 hr
= IAVIEditStream_Clone(pEdit
, ppResult
);
1997 IAVIEditStream_Release(pEdit
);
1999 hr
= AVIERR_UNSUPPORTED
;
2004 /***********************************************************************
2005 * EditStreamCopy (AVIFIL32.@)
2007 HRESULT WINAPI
EditStreamCopy(PAVISTREAM pStream
, LONG
*plStart
,
2008 LONG
*plLength
, PAVISTREAM
*ppResult
)
2010 PAVIEDITSTREAM pEdit
= NULL
;
2013 TRACE("(%p,%p,%p,%p)\n", pStream
, plStart
, plLength
, ppResult
);
2015 if (pStream
== NULL
)
2016 return AVIERR_BADHANDLE
;
2017 if (plStart
== NULL
|| plLength
== NULL
|| ppResult
== NULL
)
2018 return AVIERR_BADPARAM
;
2022 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2023 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2024 hr
= IAVIEditStream_Copy(pEdit
, plStart
, plLength
, ppResult
);
2026 IAVIEditStream_Release(pEdit
);
2028 hr
= AVIERR_UNSUPPORTED
;
2033 /***********************************************************************
2034 * EditStreamCut (AVIFIL32.@)
2036 HRESULT WINAPI
EditStreamCut(PAVISTREAM pStream
, LONG
*plStart
,
2037 LONG
*plLength
, PAVISTREAM
*ppResult
)
2039 PAVIEDITSTREAM pEdit
= NULL
;
2042 TRACE("(%p,%p,%p,%p)\n", pStream
, plStart
, plLength
, ppResult
);
2044 if (ppResult
!= NULL
)
2046 if (pStream
== NULL
)
2047 return AVIERR_BADHANDLE
;
2048 if (plStart
== NULL
|| plLength
== NULL
)
2049 return AVIERR_BADPARAM
;
2051 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2052 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2053 hr
= IAVIEditStream_Cut(pEdit
, plStart
, plLength
, ppResult
);
2055 IAVIEditStream_Release(pEdit
);
2057 hr
= AVIERR_UNSUPPORTED
;
2062 /***********************************************************************
2063 * EditStreamPaste (AVIFIL32.@)
2065 HRESULT WINAPI
EditStreamPaste(PAVISTREAM pDest
, LONG
*plStart
, LONG
*plLength
,
2066 PAVISTREAM pSource
, LONG lStart
, LONG lEnd
)
2068 PAVIEDITSTREAM pEdit
= NULL
;
2071 TRACE("(%p,%p,%p,%p,%d,%d)\n", pDest
, plStart
, plLength
,
2072 pSource
, lStart
, lEnd
);
2074 if (pDest
== NULL
|| pSource
== NULL
)
2075 return AVIERR_BADHANDLE
;
2076 if (plStart
== NULL
|| plLength
== NULL
|| lStart
< 0)
2077 return AVIERR_BADPARAM
;
2079 hr
= IAVIStream_QueryInterface(pDest
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2080 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2081 hr
= IAVIEditStream_Paste(pEdit
, plStart
, plLength
, pSource
, lStart
, lEnd
);
2083 IAVIEditStream_Release(pEdit
);
2085 hr
= AVIERR_UNSUPPORTED
;
2090 /***********************************************************************
2091 * EditStreamSetInfoA (AVIFIL32.@)
2093 HRESULT WINAPI
EditStreamSetInfoA(PAVISTREAM pstream
, LPAVISTREAMINFOA asi
,
2096 AVISTREAMINFOW asiw
;
2098 TRACE("(%p,%p,%d)\n", pstream
, asi
, size
);
2100 if (size
>= 0 && size
< sizeof(AVISTREAMINFOA
))
2101 return AVIERR_BADSIZE
;
2103 memcpy(&asiw
, asi
, sizeof(asiw
) - sizeof(asiw
.szName
));
2104 MultiByteToWideChar(CP_ACP
, 0, asi
->szName
, -1, asiw
.szName
, ARRAY_SIZE(asiw
.szName
));
2106 return EditStreamSetInfoW(pstream
, &asiw
, sizeof(asiw
));
2109 /***********************************************************************
2110 * EditStreamSetInfoW (AVIFIL32.@)
2112 HRESULT WINAPI
EditStreamSetInfoW(PAVISTREAM pstream
, LPAVISTREAMINFOW asi
,
2115 PAVIEDITSTREAM pEdit
= NULL
;
2118 TRACE("(%p,%p,%d)\n", pstream
, asi
, size
);
2120 if (size
>= 0 && size
< sizeof(AVISTREAMINFOA
))
2121 return AVIERR_BADSIZE
;
2123 hr
= IAVIStream_QueryInterface(pstream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2124 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2125 hr
= IAVIEditStream_SetInfo(pEdit
, asi
, size
);
2127 IAVIEditStream_Release(pEdit
);
2129 hr
= AVIERR_UNSUPPORTED
;
2134 /***********************************************************************
2135 * EditStreamSetNameA (AVIFIL32.@)
2137 HRESULT WINAPI
EditStreamSetNameA(PAVISTREAM pstream
, LPCSTR szName
)
2139 AVISTREAMINFOA asia
;
2142 TRACE("(%p,%s)\n", pstream
, debugstr_a(szName
));
2144 if (pstream
== NULL
)
2145 return AVIERR_BADHANDLE
;
2147 return AVIERR_BADPARAM
;
2149 hres
= AVIStreamInfoA(pstream
, &asia
, sizeof(asia
));
2153 memset(asia
.szName
, 0, sizeof(asia
.szName
));
2154 lstrcpynA(asia
.szName
, szName
, ARRAY_SIZE(asia
.szName
));
2156 return EditStreamSetInfoA(pstream
, &asia
, sizeof(asia
));
2159 /***********************************************************************
2160 * EditStreamSetNameW (AVIFIL32.@)
2162 HRESULT WINAPI
EditStreamSetNameW(PAVISTREAM pstream
, LPCWSTR szName
)
2164 AVISTREAMINFOW asiw
;
2167 TRACE("(%p,%s)\n", pstream
, debugstr_w(szName
));
2169 if (pstream
== NULL
)
2170 return AVIERR_BADHANDLE
;
2172 return AVIERR_BADPARAM
;
2174 hres
= IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
));
2178 memset(asiw
.szName
, 0, sizeof(asiw
.szName
));
2179 lstrcpynW(asiw
.szName
, szName
, ARRAY_SIZE(asiw
.szName
));
2181 return EditStreamSetInfoW(pstream
, &asiw
, sizeof(asiw
));
2184 /***********************************************************************
2185 * AVIClearClipboard (AVIFIL32.@)
2187 HRESULT WINAPI
AVIClearClipboard(void)
2191 return AVIERR_UNSUPPORTED
; /* OleSetClipboard(NULL); */
2194 /***********************************************************************
2195 * AVIGetFromClipboard (AVIFIL32.@)
2197 HRESULT WINAPI
AVIGetFromClipboard(PAVIFILE
*ppfile
)
2199 FIXME("(%p), stub!\n", ppfile
);
2203 return AVIERR_UNSUPPORTED
;
2206 /***********************************************************************
2207 * AVIMakeStreamFromClipboard (AVIFIL32.@)
2209 HRESULT WINAPI
AVIMakeStreamFromClipboard(UINT cfFormat
, HANDLE hGlobal
,
2210 PAVISTREAM
* ppstream
)
2212 FIXME("(0x%08x,%p,%p), stub!\n", cfFormat
, hGlobal
, ppstream
);
2214 if (ppstream
== NULL
)
2215 return AVIERR_BADHANDLE
;
2217 return AVIERR_UNSUPPORTED
;
2220 /***********************************************************************
2221 * AVIPutFileOnClipboard (AVIFIL32.@)
2223 HRESULT WINAPI
AVIPutFileOnClipboard(PAVIFILE pfile
)
2225 FIXME("(%p), stub!\n", pfile
);
2228 return AVIERR_BADHANDLE
;
2230 return AVIERR_UNSUPPORTED
;
2233 HRESULT WINAPIV
AVISaveA(LPCSTR szFile
, CLSID
* pclsidHandler
, AVISAVECALLBACK lpfnCallback
,
2234 int nStreams
, PAVISTREAM pavi
, LPAVICOMPRESSOPTIONS lpOptions
, ...)
2239 PAVISTREAM
*streams
;
2240 LPAVICOMPRESSOPTIONS
*options
;
2242 TRACE("(%s,%p,%p,%d,%p,%p)\n", debugstr_a(szFile
), pclsidHandler
, lpfnCallback
,
2243 nStreams
, pavi
, lpOptions
);
2245 if (nStreams
<= 0) return AVIERR_BADPARAM
;
2247 streams
= HeapAlloc(GetProcessHeap(), 0, nStreams
* sizeof(*streams
));
2248 options
= HeapAlloc(GetProcessHeap(), 0, nStreams
* sizeof(*options
));
2249 if (!streams
|| !options
)
2251 ret
= AVIERR_MEMORY
;
2256 options
[0] = lpOptions
;
2258 __ms_va_start(vl
, lpOptions
);
2259 for (i
= 1; i
< nStreams
; i
++)
2261 streams
[i
] = va_arg(vl
, PAVISTREAM
);
2262 options
[i
] = va_arg(vl
, PAVICOMPRESSOPTIONS
);
2266 for (i
= 0; i
< nStreams
; i
++)
2267 TRACE("Pair[%d] - Stream = %p, Options = %p\n", i
, streams
[i
], options
[i
]);
2269 ret
= AVISaveVA(szFile
, pclsidHandler
, lpfnCallback
, nStreams
, streams
, options
);
2271 HeapFree(GetProcessHeap(), 0, streams
);
2272 HeapFree(GetProcessHeap(), 0, options
);
2276 HRESULT WINAPIV
AVISaveW(LPCWSTR szFile
, CLSID
* pclsidHandler
, AVISAVECALLBACK lpfnCallback
,
2277 int nStreams
, PAVISTREAM pavi
, LPAVICOMPRESSOPTIONS lpOptions
, ...)
2282 PAVISTREAM
*streams
;
2283 LPAVICOMPRESSOPTIONS
*options
;
2285 TRACE("(%s,%p,%p,%d,%p,%p)\n", debugstr_w(szFile
), pclsidHandler
, lpfnCallback
,
2286 nStreams
, pavi
, lpOptions
);
2288 if (nStreams
<= 0) return AVIERR_BADPARAM
;
2290 streams
= HeapAlloc(GetProcessHeap(), 0, nStreams
* sizeof(*streams
));
2291 options
= HeapAlloc(GetProcessHeap(), 0, nStreams
* sizeof(*options
));
2292 if (!streams
|| !options
)
2294 ret
= AVIERR_MEMORY
;
2299 options
[0] = lpOptions
;
2301 __ms_va_start(vl
, lpOptions
);
2302 for (i
= 1; i
< nStreams
; i
++)
2304 streams
[i
] = va_arg(vl
, PAVISTREAM
);
2305 options
[i
] = va_arg(vl
, PAVICOMPRESSOPTIONS
);
2309 for (i
= 0; i
< nStreams
; i
++)
2310 TRACE("Pair[%d] - Stream = %p, Options = %p\n", i
, streams
[i
], options
[i
]);
2312 ret
= AVISaveVW(szFile
, pclsidHandler
, lpfnCallback
, nStreams
, streams
, options
);
2314 HeapFree(GetProcessHeap(), 0, streams
);
2315 HeapFree(GetProcessHeap(), 0, options
);