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"
41 #include "wine/unicode.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(avifile
);
46 /***********************************************************************
47 * for AVIBuildFilterW -- uses fixed size table
49 #define MAX_FILTERS 30 /* 30 => 7kB */
51 typedef struct _AVIFilter
{
53 WCHAR szExtensions
[MAX_FILTERS
* 7];
56 /***********************************************************************
63 LPAVICOMPRESSOPTIONS
*ppOptions
;
67 /***********************************************************************
68 * copied from dlls/ole32/compobj.c
70 static HRESULT
AVIFILE_CLSIDFromString(LPCSTR idstr
, LPCLSID id
)
78 memset(id
, 0, sizeof(CLSID
));
82 /* validate the CLSID string */
83 if (lstrlenA(idstr
) != 38)
84 return CO_E_CLASSSTRING
;
86 s
= (BYTE
const*)idstr
;
87 if ((s
[0]!='{') || (s
[9]!='-') || (s
[14]!='-') || (s
[19]!='-') ||
88 (s
[24]!='-') || (s
[37]!='}'))
89 return CO_E_CLASSSTRING
;
91 for (i
= 1; i
< 37; i
++) {
92 if ((i
== 9) || (i
== 14) || (i
== 19) || (i
== 24))
94 if (!(((s
[i
] >= '0') && (s
[i
] <= '9')) ||
95 ((s
[i
] >= 'a') && (s
[i
] <= 'f')) ||
96 ((s
[i
] >= 'A') && (s
[i
] <= 'F')))
98 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) {
181 /***********************************************************************
182 * AVIFileExit (AVIFIL32.@)
183 * AVIFileExit (AVIFILE.101)
185 void WINAPI
AVIFileExit(void) {
186 /* need to free ole32.dll if we are the last exit call */
187 /* OleUninitialize() */
188 FIXME("(): stub!\n");
191 /***********************************************************************
192 * AVIFileOpen (AVIFIL32.@)
193 * AVIFileOpenA (AVIFIL32.@)
194 * AVIFileOpen (AVIFILE.102)
196 HRESULT WINAPI
AVIFileOpenA(PAVIFILE
*ppfile
, LPCSTR szFile
, UINT uMode
,
199 LPWSTR wszFile
= NULL
;
203 TRACE("(%p,%s,0x%08X,%s)\n", ppfile
, debugstr_a(szFile
), uMode
,
204 debugstr_guid(lpHandler
));
206 /* check parameters */
207 if (ppfile
== NULL
|| szFile
== NULL
)
208 return AVIERR_BADPARAM
;
210 /* convert ASCII string to Unicode and call unicode function */
211 len
= MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, NULL
, 0);
213 return AVIERR_BADPARAM
;
215 wszFile
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
217 return AVIERR_MEMORY
;
219 MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, wszFile
, len
);
221 hr
= AVIFileOpenW(ppfile
, wszFile
, uMode
, lpHandler
);
223 HeapFree(GetProcessHeap(), 0, 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 /* create instance of handler */
255 hr
= CoCreateInstance(&clsidHandler
, NULL
, CLSCTX_INPROC
, &IID_IAVIFile
, (LPVOID
*)ppfile
);
256 if (FAILED(hr
) || *ppfile
== NULL
)
259 /* ask for IPersistFile interface for loading/creating the file */
260 hr
= IAVIFile_QueryInterface(*ppfile
, &IID_IPersistFile
, (LPVOID
*)&ppersist
);
261 if (FAILED(hr
) || ppersist
== NULL
) {
262 IAVIFile_Release(*ppfile
);
267 hr
= IPersistFile_Load(ppersist
, szFile
, uMode
);
268 IPersistFile_Release(ppersist
);
270 IAVIFile_Release(*ppfile
);
277 /***********************************************************************
278 * AVIFileAddRef (AVIFIL32.@)
279 * AVIFileAddRef (AVIFILE.140)
281 ULONG WINAPI
AVIFileAddRef(PAVIFILE pfile
)
283 TRACE("(%p)\n", pfile
);
286 ERR(": bad handle passed!\n");
290 return IAVIFile_AddRef(pfile
);
293 /***********************************************************************
294 * AVIFileRelease (AVIFIL32.@)
295 * AVIFileRelease (AVIFILE.141)
297 ULONG WINAPI
AVIFileRelease(PAVIFILE pfile
)
299 TRACE("(%p)\n", pfile
);
302 ERR(": bad handle passed!\n");
306 return IAVIFile_Release(pfile
);
309 /***********************************************************************
310 * AVIFileInfo (AVIFIL32.@)
311 * AVIFileInfoA (AVIFIL32.@)
312 * AVIFileInfo (AVIFILE.142)
314 HRESULT WINAPI
AVIFileInfoA(PAVIFILE pfile
, LPAVIFILEINFOA afi
, LONG size
)
319 TRACE("(%p,%p,%d)\n", pfile
, afi
, size
);
322 return AVIERR_BADHANDLE
;
323 if ((DWORD
)size
< sizeof(AVIFILEINFOA
))
324 return AVIERR_BADSIZE
;
326 hres
= IAVIFile_Info(pfile
, &afiw
, sizeof(afiw
));
328 memcpy(afi
, &afiw
, sizeof(*afi
) - sizeof(afi
->szFileType
));
329 WideCharToMultiByte(CP_ACP
, 0, afiw
.szFileType
, -1, afi
->szFileType
,
330 sizeof(afi
->szFileType
), NULL
, NULL
);
331 afi
->szFileType
[sizeof(afi
->szFileType
) - 1] = 0;
336 /***********************************************************************
337 * AVIFileInfoW (AVIFIL32.@)
339 HRESULT WINAPI
AVIFileInfoW(PAVIFILE pfile
, LPAVIFILEINFOW afiw
, LONG size
)
341 TRACE("(%p,%p,%d)\n", pfile
, afiw
, size
);
344 return AVIERR_BADHANDLE
;
346 return IAVIFile_Info(pfile
, afiw
, size
);
349 /***********************************************************************
350 * AVIFileGetStream (AVIFIL32.@)
351 * AVIFileGetStream (AVIFILE.143)
353 HRESULT WINAPI
AVIFileGetStream(PAVIFILE pfile
, PAVISTREAM
*avis
,
354 DWORD fccType
, LONG lParam
)
356 TRACE("(%p,%p,'%4.4s',%d)\n", pfile
, avis
, (char*)&fccType
, lParam
);
359 return AVIERR_BADHANDLE
;
361 return IAVIFile_GetStream(pfile
, avis
, fccType
, lParam
);
364 /***********************************************************************
365 * AVIFileCreateStream (AVIFIL32.@)
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
);
396 return AVIERR_BADHANDLE
;
398 return IAVIFile_CreateStream(pfile
, avis
, asi
);
401 /***********************************************************************
402 * AVIFileWriteData (AVIFIL32.@)
403 * AVIFileWriteData (AVIFILE.146)
405 HRESULT WINAPI
AVIFileWriteData(PAVIFILE pfile
,DWORD fcc
,LPVOID lp
,LONG size
)
407 TRACE("(%p,'%4.4s',%p,%d)\n", pfile
, (char*)&fcc
, lp
, size
);
410 return AVIERR_BADHANDLE
;
412 return IAVIFile_WriteData(pfile
, fcc
, lp
, size
);
415 /***********************************************************************
416 * AVIFileReadData (AVIFIL32.@)
417 * AVIFileReadData (AVIFILE.147)
419 HRESULT WINAPI
AVIFileReadData(PAVIFILE pfile
,DWORD fcc
,LPVOID lp
,LPLONG size
)
421 TRACE("(%p,'%4.4s',%p,%p)\n", pfile
, (char*)&fcc
, lp
, size
);
424 return AVIERR_BADHANDLE
;
426 return IAVIFile_ReadData(pfile
, fcc
, lp
, size
);
429 /***********************************************************************
430 * AVIFileEndRecord (AVIFIL32.@)
431 * AVIFileEndRecord (AVIFILE.148)
433 HRESULT WINAPI
AVIFileEndRecord(PAVIFILE pfile
)
435 TRACE("(%p)\n", pfile
);
438 return AVIERR_BADHANDLE
;
440 return IAVIFile_EndRecord(pfile
);
443 /***********************************************************************
444 * AVIStreamAddRef (AVIFIL32.@)
445 * AVIStreamAddRef (AVIFILE.160)
447 ULONG WINAPI
AVIStreamAddRef(PAVISTREAM pstream
)
449 TRACE("(%p)\n", pstream
);
451 if (pstream
== NULL
) {
452 ERR(": bad handle passed!\n");
456 return IAVIStream_AddRef(pstream
);
459 /***********************************************************************
460 * AVIStreamRelease (AVIFIL32.@)
461 * AVIStreamRelease (AVIFILE.161)
463 ULONG WINAPI
AVIStreamRelease(PAVISTREAM pstream
)
465 TRACE("(%p)\n", pstream
);
467 if (pstream
== NULL
) {
468 ERR(": bad handle passed!\n");
472 return IAVIStream_Release(pstream
);
475 /***********************************************************************
476 * AVIStreamCreate (AVIFIL32.@)
477 * AVIStreamCreate (AVIFILE.104)
479 HRESULT WINAPI
AVIStreamCreate(PAVISTREAM
*ppavi
, LONG lParam1
, LONG lParam2
,
480 LPCLSID pclsidHandler
)
484 TRACE("(%p,0x%08X,0x%08X,%s)\n", ppavi
, lParam1
, lParam2
,
485 debugstr_guid(pclsidHandler
));
488 return AVIERR_BADPARAM
;
491 if (pclsidHandler
== NULL
)
492 return AVIERR_UNSUPPORTED
;
494 hr
= CoCreateInstance(pclsidHandler
, NULL
, CLSCTX_INPROC
, &IID_IAVIStream
, (LPVOID
*)ppavi
);
495 if (FAILED(hr
) || *ppavi
== NULL
)
498 hr
= IAVIStream_Create(*ppavi
, lParam1
, lParam2
);
500 IAVIStream_Release(*ppavi
);
507 /***********************************************************************
508 * AVIStreamInfo (AVIFIL32.@)
509 * AVIStreamInfoA (AVIFIL32.@)
510 * AVIStreamInfo (AVIFILE.162)
512 HRESULT WINAPI
AVIStreamInfoA(PAVISTREAM pstream
, LPAVISTREAMINFOA asi
,
518 TRACE("(%p,%p,%d)\n", pstream
, asi
, size
);
521 return AVIERR_BADHANDLE
;
522 if ((DWORD
)size
< sizeof(AVISTREAMINFOA
))
523 return AVIERR_BADSIZE
;
525 hres
= IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
));
527 memcpy(asi
, &asiw
, sizeof(asiw
) - sizeof(asiw
.szName
));
528 WideCharToMultiByte(CP_ACP
, 0, asiw
.szName
, -1, asi
->szName
,
529 sizeof(asi
->szName
), NULL
, NULL
);
530 asi
->szName
[sizeof(asi
->szName
) - 1] = 0;
535 /***********************************************************************
536 * AVIStreamInfoW (AVIFIL32.@)
538 HRESULT WINAPI
AVIStreamInfoW(PAVISTREAM pstream
, LPAVISTREAMINFOW asi
,
541 TRACE("(%p,%p,%d)\n", pstream
, asi
, size
);
544 return AVIERR_BADHANDLE
;
546 return IAVIStream_Info(pstream
, asi
, size
);
549 /***********************************************************************
550 * AVIStreamFindSample (AVIFIL32.@)
551 * AVIStreamFindSample (AVIFILE.163)
553 HRESULT WINAPI
AVIStreamFindSample(PAVISTREAM pstream
, LONG pos
, DWORD flags
)
555 TRACE("(%p,%d,0x%X)\n", pstream
, pos
, flags
);
560 return IAVIStream_FindSample(pstream
, pos
, flags
);
563 /***********************************************************************
564 * AVIStreamReadFormat (AVIFIL32.@)
565 * AVIStreamReadFormat (AVIFILE.164)
567 HRESULT WINAPI
AVIStreamReadFormat(PAVISTREAM pstream
, LONG pos
,
568 LPVOID format
, LPLONG formatsize
)
570 TRACE("(%p,%d,%p,%p)\n", pstream
, pos
, format
, formatsize
);
573 return AVIERR_BADHANDLE
;
575 return IAVIStream_ReadFormat(pstream
, pos
, format
, formatsize
);
578 /***********************************************************************
579 * AVIStreamSetFormat (AVIFIL32.@)
580 * AVIStreamSetFormat (AVIFILE.169)
582 HRESULT WINAPI
AVIStreamSetFormat(PAVISTREAM pstream
, LONG pos
,
583 LPVOID format
, LONG formatsize
)
585 TRACE("(%p,%d,%p,%d)\n", pstream
, pos
, format
, formatsize
);
588 return AVIERR_BADHANDLE
;
590 return IAVIStream_SetFormat(pstream
, pos
, format
, formatsize
);
593 /***********************************************************************
594 * AVIStreamRead (AVIFIL32.@)
595 * AVIStreamRead (AVIFILE.167)
597 HRESULT WINAPI
AVIStreamRead(PAVISTREAM pstream
, LONG start
, LONG samples
,
598 LPVOID buffer
, LONG buffersize
,
599 LPLONG bytesread
, LPLONG samplesread
)
601 TRACE("(%p,%d,%d,%p,%d,%p,%p)\n", pstream
, start
, samples
, buffer
,
602 buffersize
, bytesread
, samplesread
);
605 return AVIERR_BADHANDLE
;
607 return IAVIStream_Read(pstream
, start
, samples
, buffer
, buffersize
,
608 bytesread
, samplesread
);
611 /***********************************************************************
612 * AVIStreamWrite (AVIFIL32.@)
613 * AVIStreamWrite (AVIFILE.168)
615 HRESULT WINAPI
AVIStreamWrite(PAVISTREAM pstream
, LONG start
, LONG samples
,
616 LPVOID buffer
, LONG buffersize
, DWORD flags
,
617 LPLONG sampwritten
, LPLONG byteswritten
)
619 TRACE("(%p,%d,%d,%p,%d,0x%X,%p,%p)\n", pstream
, start
, samples
, buffer
,
620 buffersize
, flags
, sampwritten
, byteswritten
);
623 return AVIERR_BADHANDLE
;
625 return IAVIStream_Write(pstream
, start
, samples
, buffer
, buffersize
,
626 flags
, sampwritten
, byteswritten
);
629 /***********************************************************************
630 * AVIStreamReadData (AVIFIL32.@)
631 * AVIStreamReadData (AVIFILE.165)
633 HRESULT WINAPI
AVIStreamReadData(PAVISTREAM pstream
, DWORD fcc
, LPVOID lp
,
636 TRACE("(%p,'%4.4s',%p,%p)\n", pstream
, (char*)&fcc
, lp
, lpread
);
639 return AVIERR_BADHANDLE
;
641 return IAVIStream_ReadData(pstream
, fcc
, lp
, lpread
);
644 /***********************************************************************
645 * AVIStreamWriteData (AVIFIL32.@)
646 * AVIStreamWriteData (AVIFILE.166)
648 HRESULT WINAPI
AVIStreamWriteData(PAVISTREAM pstream
, DWORD fcc
, LPVOID lp
,
651 TRACE("(%p,'%4.4s',%p,%d)\n", pstream
, (char*)&fcc
, lp
, size
);
654 return AVIERR_BADHANDLE
;
656 return IAVIStream_WriteData(pstream
, fcc
, lp
, size
);
659 /***********************************************************************
660 * AVIStreamGetFrameOpen (AVIFIL32.@)
661 * AVIStreamGetFrameOpen (AVIFILE.112)
663 PGETFRAME WINAPI
AVIStreamGetFrameOpen(PAVISTREAM pstream
,
664 LPBITMAPINFOHEADER lpbiWanted
)
668 TRACE("(%p,%p)\n", pstream
, lpbiWanted
);
670 if (FAILED(IAVIStream_QueryInterface(pstream
, &IID_IGetFrame
, (LPVOID
*)&pg
)) ||
672 pg
= AVIFILE_CreateGetFrame(pstream
);
677 if (FAILED(IGetFrame_SetFormat(pg
, lpbiWanted
, NULL
, 0, 0, -1, -1))) {
678 IGetFrame_Release(pg
);
685 /***********************************************************************
686 * AVIStreamGetFrame (AVIFIL32.@)
687 * AVIStreamGetFrame (AVIFILE.110)
689 LPVOID WINAPI
AVIStreamGetFrame(PGETFRAME pg
, LONG pos
)
691 TRACE("(%p,%d)\n", pg
, pos
);
696 return IGetFrame_GetFrame(pg
, pos
);
699 /***********************************************************************
700 * AVIStreamGetFrameClose (AVIFIL32.@)
701 * AVIStreamGetFrameClose (AVIFILE.111)
703 HRESULT WINAPI
AVIStreamGetFrameClose(PGETFRAME pg
)
708 return IGetFrame_Release(pg
);
712 /***********************************************************************
713 * AVIMakeCompressedStream (AVIFIL32.@)
715 HRESULT WINAPI
AVIMakeCompressedStream(PAVISTREAM
*ppsCompressed
,
717 LPAVICOMPRESSOPTIONS aco
,
718 LPCLSID pclsidHandler
)
725 LONG size
= sizeof(szValue
);
727 TRACE("(%p,%p,%p,%s)\n", ppsCompressed
, psSource
, aco
,
728 debugstr_guid(pclsidHandler
));
730 if (ppsCompressed
== NULL
)
731 return AVIERR_BADPARAM
;
732 if (psSource
== NULL
)
733 return AVIERR_BADHANDLE
;
735 *ppsCompressed
= NULL
;
737 /* if no handler given get default ones based on streamtype */
738 if (pclsidHandler
== NULL
) {
739 hr
= IAVIStream_Info(psSource
, &asiw
, sizeof(asiw
));
743 wsprintfA(szRegKey
, "AVIFile\\Compressors\\%4.4s", (char*)&asiw
.fccType
);
744 if (RegQueryValueA(HKEY_CLASSES_ROOT
, szRegKey
, szValue
, &size
) != ERROR_SUCCESS
)
745 return AVIERR_UNSUPPORTED
;
746 if (AVIFILE_CLSIDFromString(szValue
, &clsidHandler
) != S_OK
)
747 return AVIERR_UNSUPPORTED
;
749 memcpy(&clsidHandler
, pclsidHandler
, sizeof(clsidHandler
));
751 hr
= CoCreateInstance(&clsidHandler
, NULL
, CLSCTX_INPROC
, &IID_IAVIStream
, (LPVOID
*)ppsCompressed
);
752 if (FAILED(hr
) || *ppsCompressed
== NULL
)
755 hr
= IAVIStream_Create(*ppsCompressed
, (LPARAM
)psSource
, (LPARAM
)aco
);
757 IAVIStream_Release(*ppsCompressed
);
758 *ppsCompressed
= NULL
;
764 /***********************************************************************
765 * AVIMakeFileFromStreams (AVIFIL32.@)
767 HRESULT WINAPI
AVIMakeFileFromStreams(PAVIFILE
*ppfile
, int nStreams
,
768 PAVISTREAM
*ppStreams
)
770 TRACE("(%p,%d,%p)\n", ppfile
, nStreams
, ppStreams
);
772 if (nStreams
< 0 || ppfile
== NULL
|| ppStreams
== NULL
)
773 return AVIERR_BADPARAM
;
775 *ppfile
= AVIFILE_CreateAVITempFile(nStreams
, ppStreams
);
777 return AVIERR_MEMORY
;
782 /***********************************************************************
783 * AVIStreamOpenFromFile (AVIFIL32.@)
784 * AVIStreamOpenFromFileA (AVIFIL32.@)
785 * AVIStreamOpenFromFile (AVIFILE.103)
787 HRESULT WINAPI
AVIStreamOpenFromFileA(PAVISTREAM
*ppavi
, LPCSTR szFile
,
788 DWORD fccType
, LONG lParam
,
789 UINT mode
, LPCLSID pclsidHandler
)
791 PAVIFILE pfile
= NULL
;
794 TRACE("(%p,%s,'%4.4s',%d,0x%X,%s)\n", ppavi
, debugstr_a(szFile
),
795 (char*)&fccType
, lParam
, mode
, debugstr_guid(pclsidHandler
));
797 if (ppavi
== NULL
|| szFile
== NULL
)
798 return AVIERR_BADPARAM
;
802 hr
= AVIFileOpenA(&pfile
, szFile
, mode
, pclsidHandler
);
803 if (FAILED(hr
) || pfile
== NULL
)
806 hr
= IAVIFile_GetStream(pfile
, ppavi
, fccType
, lParam
);
807 IAVIFile_Release(pfile
);
812 /***********************************************************************
813 * AVIStreamOpenFromFileW (AVIFIL32.@)
815 HRESULT WINAPI
AVIStreamOpenFromFileW(PAVISTREAM
*ppavi
, LPCWSTR szFile
,
816 DWORD fccType
, LONG lParam
,
817 UINT mode
, LPCLSID pclsidHandler
)
819 PAVIFILE pfile
= NULL
;
822 TRACE("(%p,%s,'%4.4s',%d,0x%X,%s)\n", ppavi
, debugstr_w(szFile
),
823 (char*)&fccType
, lParam
, mode
, debugstr_guid(pclsidHandler
));
825 if (ppavi
== NULL
|| szFile
== NULL
)
826 return AVIERR_BADPARAM
;
830 hr
= AVIFileOpenW(&pfile
, szFile
, mode
, pclsidHandler
);
831 if (FAILED(hr
) || pfile
== NULL
)
834 hr
= IAVIFile_GetStream(pfile
, ppavi
, fccType
, lParam
);
835 IAVIFile_Release(pfile
);
840 /***********************************************************************
841 * AVIStreamBeginStreaming (AVIFIL32.@)
843 LONG WINAPI
AVIStreamBeginStreaming(PAVISTREAM pavi
, LONG lStart
, LONG lEnd
, LONG lRate
)
845 IAVIStreaming
* pstream
= NULL
;
848 TRACE("(%p,%d,%d,%d)\n", pavi
, lStart
, lEnd
, lRate
);
851 return AVIERR_BADHANDLE
;
853 hr
= IAVIStream_QueryInterface(pavi
, &IID_IAVIStreaming
, (LPVOID
*)&pstream
);
854 if (SUCCEEDED(hr
) && pstream
!= NULL
) {
855 hr
= IAVIStreaming_Begin(pstream
, lStart
, lEnd
, lRate
);
856 IAVIStreaming_Release(pstream
);
863 /***********************************************************************
864 * AVIStreamEndStreaming (AVIFIL32.@)
866 LONG WINAPI
AVIStreamEndStreaming(PAVISTREAM pavi
)
868 IAVIStreaming
* pstream
= NULL
;
871 TRACE("(%p)\n", pavi
);
873 hr
= IAVIStream_QueryInterface(pavi
, &IID_IAVIStreaming
, (LPVOID
*)&pstream
);
874 if (SUCCEEDED(hr
) && pstream
!= NULL
) {
875 IAVIStreaming_End(pstream
);
876 IAVIStreaming_Release(pstream
);
882 /***********************************************************************
883 * AVIStreamStart (AVIFILE.130)
884 * AVIStreamStart (AVIFIL32.@)
886 LONG WINAPI
AVIStreamStart(PAVISTREAM pstream
)
890 TRACE("(%p)\n", pstream
);
895 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
901 /***********************************************************************
902 * AVIStreamLength (AVIFILE.131)
903 * AVIStreamLength (AVIFIL32.@)
905 LONG WINAPI
AVIStreamLength(PAVISTREAM pstream
)
909 TRACE("(%p)\n", pstream
);
914 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
917 return asiw
.dwLength
;
920 /***********************************************************************
921 * AVIStreamSampleToTime (AVIFILE.133)
922 * AVIStreamSampleToTime (AVIFIL32.@)
924 LONG WINAPI
AVIStreamSampleToTime(PAVISTREAM pstream
, LONG lSample
)
929 TRACE("(%p,%d)\n", pstream
, lSample
);
934 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
936 if (asiw
.dwRate
== 0)
939 /* limit to stream bounds */
940 if (lSample
< asiw
.dwStart
)
941 lSample
= asiw
.dwStart
;
942 if (lSample
> asiw
.dwStart
+ asiw
.dwLength
)
943 lSample
= asiw
.dwStart
+ asiw
.dwLength
;
945 if (asiw
.dwRate
/ asiw
.dwScale
< 1000)
946 time
= (LONG
)(((float)lSample
* asiw
.dwScale
* 1000) / asiw
.dwRate
);
948 time
= (LONG
)(((float)lSample
* asiw
.dwScale
* 1000 + (asiw
.dwRate
- 1)) / asiw
.dwRate
);
950 TRACE(" -> %d\n",time
);
954 /***********************************************************************
955 * AVIStreamTimeToSample (AVIFILE.132)
956 * AVIStreamTimeToSample (AVIFIL32.@)
958 LONG WINAPI
AVIStreamTimeToSample(PAVISTREAM pstream
, LONG lTime
)
963 TRACE("(%p,%d)\n", pstream
, lTime
);
965 if (pstream
== NULL
|| lTime
< 0)
968 if (FAILED(IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
))))
970 if (asiw
.dwScale
== 0)
973 if (asiw
.dwRate
/ asiw
.dwScale
< 1000)
974 sample
= (LONG
)((((float)asiw
.dwRate
* lTime
) / (asiw
.dwScale
* 1000)));
976 sample
= (LONG
)(((float)asiw
.dwRate
* lTime
+ (asiw
.dwScale
* 1000 - 1)) / (asiw
.dwScale
* 1000));
978 /* limit to stream bounds */
979 if (sample
< asiw
.dwStart
)
980 sample
= asiw
.dwStart
;
981 if (sample
> asiw
.dwStart
+ asiw
.dwLength
)
982 sample
= asiw
.dwStart
+ asiw
.dwLength
;
984 TRACE(" -> %d\n", sample
);
988 /***********************************************************************
989 * AVIBuildFilter (AVIFIL32.@)
990 * AVIBuildFilterA (AVIFIL32.@)
991 * AVIBuildFilter (AVIFILE.123)
993 HRESULT WINAPI
AVIBuildFilterA(LPSTR szFilter
, LONG cbFilter
, BOOL fSaving
)
998 TRACE("(%p,%d,%d)\n", szFilter
, cbFilter
, fSaving
);
1000 /* check parameters */
1001 if (szFilter
== NULL
)
1002 return AVIERR_BADPARAM
;
1004 return AVIERR_BADSIZE
;
1009 wszFilter
= HeapAlloc(GetProcessHeap(), 0, cbFilter
* sizeof(WCHAR
));
1010 if (wszFilter
== NULL
)
1011 return AVIERR_MEMORY
;
1013 hr
= AVIBuildFilterW(wszFilter
, cbFilter
, fSaving
);
1014 if (SUCCEEDED(hr
)) {
1015 WideCharToMultiByte(CP_ACP
, 0, wszFilter
, cbFilter
,
1016 szFilter
, cbFilter
, NULL
, NULL
);
1019 HeapFree(GetProcessHeap(), 0, wszFilter
);
1024 /***********************************************************************
1025 * AVIBuildFilterW (AVIFIL32.@)
1027 HRESULT WINAPI
AVIBuildFilterW(LPWSTR szFilter
, LONG cbFilter
, BOOL fSaving
)
1029 static const WCHAR szClsid
[] = {'C','L','S','I','D',0};
1030 static const WCHAR szExtensionFmt
[] = {';','*','.','%','s',0};
1031 static const WCHAR szAVIFileExtensions
[] =
1032 {'A','V','I','F','i','l','e','\\','E','x','t','e','n','s','i','o','n','s',0};
1035 WCHAR szAllFiles
[40];
1036 WCHAR szFileExt
[10];
1043 TRACE("(%p,%d,%d)\n", szFilter
, cbFilter
, fSaving
);
1045 /* check parameters */
1046 if (szFilter
== NULL
)
1047 return AVIERR_BADPARAM
;
1049 return AVIERR_BADSIZE
;
1051 lp
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, MAX_FILTERS
* sizeof(AVIFilter
));
1053 return AVIERR_MEMORY
;
1056 * 1. iterate over HKEY_CLASSES_ROOT\\AVIFile\\Extensions and collect
1057 * extensions and CLSID's
1058 * 2. iterate over collected CLSID's and copy its description and its
1059 * extensions to szFilter if it fits
1061 * First filter is named "All multimedia files" and its filter is a
1062 * collection of all possible extensions except "*.*".
1064 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, szAVIFileExtensions
, &hKey
) != S_OK
) {
1065 HeapFree(GetProcessHeap(), 0, lp
);
1066 return AVIERR_ERROR
;
1068 for (n
= 0;RegEnumKeyW(hKey
, n
, szFileExt
, sizeof(szFileExt
)) == S_OK
;n
++) {
1069 /* get CLSID to extension */
1070 size
= sizeof(szValue
)/sizeof(szValue
[0]);
1071 if (RegQueryValueW(hKey
, szFileExt
, szValue
, &size
) != S_OK
)
1074 /* search if the CLSID is already known */
1075 for (i
= 1; i
<= count
; i
++) {
1076 if (lstrcmpW(lp
[i
].szClsid
, szValue
) == 0)
1077 break; /* a new one */
1080 if (count
- i
== -1U) {
1081 /* it's a new CLSID */
1083 /* FIXME: How do we get info's about read/write capabilities? */
1085 if (count
>= MAX_FILTERS
) {
1086 /* try to inform user of our full fixed size table */
1087 ERR(": More than %d filters found! Adjust MAX_FILTERS in dlls/avifil32/api.c\n", MAX_FILTERS
);
1091 lstrcpyW(lp
[i
].szClsid
, szValue
);
1096 /* append extension to the filter */
1097 wsprintfW(szValue
, szExtensionFmt
, szFileExt
);
1098 if (lp
[i
].szExtensions
[0] == 0)
1099 lstrcatW(lp
[i
].szExtensions
, szValue
+ 1);
1101 lstrcatW(lp
[i
].szExtensions
, szValue
);
1103 /* also append to the "all multimedia"-filter */
1104 if (lp
[0].szExtensions
[0] == 0)
1105 lstrcatW(lp
[0].szExtensions
, szValue
+ 1);
1107 lstrcatW(lp
[0].szExtensions
, szValue
);
1111 /* 2. get descriptions for the CLSIDs and fill out szFilter */
1112 if (RegOpenKeyW(HKEY_CLASSES_ROOT
, szClsid
, &hKey
) != S_OK
) {
1113 HeapFree(GetProcessHeap(), 0, lp
);
1114 return AVIERR_ERROR
;
1116 for (n
= 0; n
<= count
; n
++) {
1117 /* first the description */
1119 size
= sizeof(szValue
)/sizeof(szValue
[0]);
1120 if (RegQueryValueW(hKey
, lp
[n
].szClsid
, szValue
, &size
) == S_OK
) {
1121 size
= lstrlenW(szValue
);
1122 lstrcpynW(szFilter
, szValue
, cbFilter
);
1125 size
= LoadStringW(AVIFILE_hModule
,IDS_ALLMULTIMEDIA
,szFilter
,cbFilter
);
1127 /* check for enough space */
1129 if (cbFilter
< size
+ lstrlenW(lp
[n
].szExtensions
) + 2) {
1132 HeapFree(GetProcessHeap(), 0, lp
);
1134 return AVIERR_BUFFERTOOSMALL
;
1139 /* and then the filter */
1140 lstrcpynW(szFilter
, lp
[n
].szExtensions
, cbFilter
);
1141 size
= lstrlenW(lp
[n
].szExtensions
) + 1;
1147 HeapFree(GetProcessHeap(), 0, lp
);
1149 /* add "All files" "*.*" filter if enough space left */
1150 size
= LoadStringW(AVIFILE_hModule
, IDS_ALLFILES
,
1151 szAllFiles
, sizeof(szAllFiles
)) + 1;
1152 if (cbFilter
> size
) {
1155 /* replace '@' with \000 to separate description of filter */
1156 for (i
= 0; i
< size
&& szAllFiles
[i
] != 0; i
++) {
1157 if (szAllFiles
[i
] == '@') {
1163 memcpy(szFilter
, szAllFiles
, size
* sizeof(szAllFiles
[0]));
1170 return AVIERR_BUFFERTOOSMALL
;
1174 static BOOL
AVISaveOptionsFmtChoose(HWND hWnd
)
1176 LPAVICOMPRESSOPTIONS pOptions
= SaveOpts
.ppOptions
[SaveOpts
.nCurrent
];
1177 AVISTREAMINFOW sInfo
;
1179 TRACE("(%p)\n", hWnd
);
1181 if (pOptions
== NULL
|| SaveOpts
.ppavis
[SaveOpts
.nCurrent
] == NULL
) {
1182 ERR(": bad state!\n");
1186 if (FAILED(AVIStreamInfoW(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1187 &sInfo
, sizeof(sInfo
)))) {
1188 ERR(": AVIStreamInfoW failed!\n");
1192 if (sInfo
.fccType
== streamtypeVIDEO
) {
1196 memset(&cv
, 0, sizeof(cv
));
1198 if ((pOptions
->dwFlags
& AVICOMPRESSF_VALID
) == 0) {
1199 memset(pOptions
, 0, sizeof(AVICOMPRESSOPTIONS
));
1200 pOptions
->fccType
= streamtypeVIDEO
;
1201 pOptions
->fccHandler
= comptypeDIB
;
1202 pOptions
->dwQuality
= (DWORD
)ICQUALITY_DEFAULT
;
1205 cv
.cbSize
= sizeof(cv
);
1206 cv
.dwFlags
= ICMF_COMPVARS_VALID
;
1207 /*cv.fccType = pOptions->fccType; */
1208 cv
.fccHandler
= pOptions
->fccHandler
;
1209 cv
.lQ
= pOptions
->dwQuality
;
1210 cv
.lpState
= pOptions
->lpParms
;
1211 cv
.cbState
= pOptions
->cbParms
;
1212 if (pOptions
->dwFlags
& AVICOMPRESSF_KEYFRAMES
)
1213 cv
.lKey
= pOptions
->dwKeyFrameEvery
;
1216 if (pOptions
->dwFlags
& AVICOMPRESSF_DATARATE
)
1217 cv
.lDataRate
= pOptions
->dwBytesPerSecond
/ 1024; /* need kBytes */
1221 ret
= ICCompressorChoose(hWnd
, SaveOpts
.uFlags
, NULL
,
1222 SaveOpts
.ppavis
[SaveOpts
.nCurrent
], &cv
, NULL
);
1225 pOptions
->fccHandler
= cv
.fccHandler
;
1226 pOptions
->lpParms
= cv
.lpState
;
1227 pOptions
->cbParms
= cv
.cbState
;
1228 pOptions
->dwQuality
= cv
.lQ
;
1230 pOptions
->dwKeyFrameEvery
= cv
.lKey
;
1231 pOptions
->dwFlags
|= AVICOMPRESSF_KEYFRAMES
;
1233 pOptions
->dwFlags
&= ~AVICOMPRESSF_KEYFRAMES
;
1234 if (cv
.lDataRate
!= 0) {
1235 pOptions
->dwBytesPerSecond
= cv
.lDataRate
* 1024; /* need bytes */
1236 pOptions
->dwFlags
|= AVICOMPRESSF_DATARATE
;
1238 pOptions
->dwFlags
&= ~AVICOMPRESSF_DATARATE
;
1239 pOptions
->dwFlags
|= AVICOMPRESSF_VALID
;
1241 ICCompressorFree(&cv
);
1244 } else if (sInfo
.fccType
== streamtypeAUDIO
) {
1245 ACMFORMATCHOOSEW afmtc
;
1249 /* FIXME: check ACM version -- Which version is needed? */
1251 memset(&afmtc
, 0, sizeof(afmtc
));
1252 afmtc
.cbStruct
= sizeof(afmtc
);
1254 afmtc
.hwndOwner
= hWnd
;
1256 acmMetrics(NULL
, ACM_METRIC_MAX_SIZE_FORMAT
, &size
);
1257 if ((pOptions
->cbFormat
== 0 || pOptions
->lpFormat
== NULL
) && size
!= 0) {
1258 pOptions
->lpFormat
= HeapAlloc(GetProcessHeap(), 0, size
);
1259 pOptions
->cbFormat
= size
;
1260 } else if (pOptions
->cbFormat
< (DWORD
)size
) {
1261 pOptions
->lpFormat
= HeapReAlloc(GetProcessHeap(), 0, pOptions
->lpFormat
, size
);
1262 pOptions
->cbFormat
= size
;
1264 if (pOptions
->lpFormat
== NULL
)
1266 afmtc
.pwfx
= pOptions
->lpFormat
;
1267 afmtc
.cbwfx
= pOptions
->cbFormat
;
1270 AVIStreamFormatSize(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1271 sInfo
.dwStart
, &size
);
1272 if (size
< (LONG
)sizeof(PCMWAVEFORMAT
))
1273 size
= sizeof(PCMWAVEFORMAT
);
1274 afmtc
.pwfxEnum
= HeapAlloc(GetProcessHeap(), 0, size
);
1275 if (afmtc
.pwfxEnum
!= NULL
) {
1276 AVIStreamReadFormat(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],
1277 sInfo
.dwStart
, afmtc
.pwfxEnum
, &size
);
1278 afmtc
.fdwEnum
= ACM_FORMATENUMF_CONVERT
;
1281 ret
= acmFormatChooseW(&afmtc
);
1283 pOptions
->dwFlags
|= AVICOMPRESSF_VALID
;
1285 HeapFree(GetProcessHeap(), 0, afmtc
.pwfxEnum
);
1286 return (ret
== S_OK
? TRUE
: FALSE
);
1288 ERR(": unknown streamtype 0x%08X\n", sInfo
.fccType
);
1293 static void AVISaveOptionsUpdate(HWND hWnd
)
1295 static const WCHAR szVideoFmt
[]={'%','l','d','x','%','l','d','x','%','d',0};
1296 static const WCHAR szAudioFmt
[]={'%','s',' ','%','s',0};
1298 WCHAR szFormat
[128];
1299 AVISTREAMINFOW sInfo
;
1303 TRACE("(%p)\n", hWnd
);
1305 SaveOpts
.nCurrent
= SendDlgItemMessageW(hWnd
,IDC_STREAM
,CB_GETCURSEL
,0,0);
1306 if (SaveOpts
.nCurrent
< 0)
1309 if (FAILED(AVIStreamInfoW(SaveOpts
.ppavis
[SaveOpts
.nCurrent
], &sInfo
, sizeof(sInfo
))))
1312 AVIStreamFormatSize(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],sInfo
.dwStart
,&size
);
1316 /* read format to build format description string */
1317 lpFormat
= HeapAlloc(GetProcessHeap(), 0, size
);
1318 if (lpFormat
!= NULL
) {
1319 if (SUCCEEDED(AVIStreamReadFormat(SaveOpts
.ppavis
[SaveOpts
.nCurrent
],sInfo
.dwStart
,lpFormat
, &size
))) {
1320 if (sInfo
.fccType
== streamtypeVIDEO
) {
1321 LPBITMAPINFOHEADER lpbi
= lpFormat
;
1324 wsprintfW(szFormat
, szVideoFmt
, lpbi
->biWidth
,
1325 lpbi
->biHeight
, lpbi
->biBitCount
);
1327 if (lpbi
->biCompression
!= BI_RGB
) {
1330 hic
= ICLocate(ICTYPE_VIDEO
, sInfo
.fccHandler
, lpFormat
,
1331 NULL
, ICMODE_DECOMPRESS
);
1333 if (ICGetInfo(hic
, &icinfo
, sizeof(icinfo
)) == S_OK
)
1334 lstrcatW(szFormat
, icinfo
.szDescription
);
1338 LoadStringW(AVIFILE_hModule
, IDS_UNCOMPRESSED
,
1339 icinfo
.szDescription
, sizeof(icinfo
.szDescription
));
1340 lstrcatW(szFormat
, icinfo
.szDescription
);
1342 } else if (sInfo
.fccType
== streamtypeAUDIO
) {
1343 ACMFORMATTAGDETAILSW aftd
;
1344 ACMFORMATDETAILSW afd
;
1346 memset(&aftd
, 0, sizeof(aftd
));
1347 memset(&afd
, 0, sizeof(afd
));
1349 aftd
.cbStruct
= sizeof(aftd
);
1350 aftd
.dwFormatTag
= afd
.dwFormatTag
=
1351 ((PWAVEFORMATEX
)lpFormat
)->wFormatTag
;
1352 aftd
.cbFormatSize
= afd
.cbwfx
= size
;
1354 afd
.cbStruct
= sizeof(afd
);
1355 afd
.pwfx
= lpFormat
;
1357 if (acmFormatTagDetailsW(NULL
, &aftd
,
1358 ACM_FORMATTAGDETAILSF_FORMATTAG
) == S_OK
) {
1359 if (acmFormatDetailsW(NULL
,&afd
,ACM_FORMATDETAILSF_FORMAT
) == S_OK
)
1360 wsprintfW(szFormat
, szAudioFmt
, afd
.szFormat
, aftd
.szFormatTag
);
1364 HeapFree(GetProcessHeap(), 0, lpFormat
);
1367 /* set text for format description */
1368 SetDlgItemTextW(hWnd
, IDC_FORMATTEXT
, szFormat
);
1370 /* Disable option button for unsupported streamtypes */
1371 if (sInfo
.fccType
== streamtypeVIDEO
||
1372 sInfo
.fccType
== streamtypeAUDIO
)
1373 EnableWindow(GetDlgItem(hWnd
, IDC_OPTIONS
), TRUE
);
1375 EnableWindow(GetDlgItem(hWnd
, IDC_OPTIONS
), FALSE
);
1380 static INT_PTR CALLBACK
AVISaveOptionsDlgProc(HWND hWnd
, UINT uMsg
,
1381 WPARAM wParam
, LPARAM lParam
)
1384 BOOL bIsInterleaved
;
1387 /*TRACE("(%p,%u,0x%04X,0x%08lX)\n", hWnd, uMsg, wParam, lParam);*/
1391 SaveOpts
.nCurrent
= 0;
1392 if (SaveOpts
.nStreams
== 1) {
1393 EndDialog(hWnd
, AVISaveOptionsFmtChoose(hWnd
));
1398 for (n
= 0; n
< SaveOpts
.nStreams
; n
++) {
1399 AVISTREAMINFOW sInfo
;
1401 AVIStreamInfoW(SaveOpts
.ppavis
[n
], &sInfo
, sizeof(sInfo
));
1402 SendDlgItemMessageW(hWnd
, IDC_STREAM
, CB_ADDSTRING
,
1403 0L, (LPARAM
)sInfo
.szName
);
1406 /* select first stream */
1407 SendDlgItemMessageW(hWnd
, IDC_STREAM
, CB_SETCURSEL
, 0, 0);
1408 SendMessageW(hWnd
, WM_COMMAND
, MAKELONG(IDC_STREAM
, CBN_SELCHANGE
), (LPARAM
)hWnd
);
1410 /* initialize interleave */
1411 if (SaveOpts
.ppOptions
[0] != NULL
&&
1412 (SaveOpts
.ppOptions
[0]->dwFlags
& AVICOMPRESSF_VALID
)) {
1413 bIsInterleaved
= (SaveOpts
.ppOptions
[0]->dwFlags
& AVICOMPRESSF_INTERLEAVE
);
1414 dwInterleave
= SaveOpts
.ppOptions
[0]->dwInterleaveEvery
;
1416 bIsInterleaved
= TRUE
;
1419 CheckDlgButton(hWnd
, IDC_INTERLEAVE
, bIsInterleaved
);
1420 SetDlgItemInt(hWnd
, IDC_INTERLEAVEEVERY
, dwInterleave
, FALSE
);
1421 EnableWindow(GetDlgItem(hWnd
, IDC_INTERLEAVEEVERY
), bIsInterleaved
);
1424 switch (LOWORD(wParam
)) {
1426 /* get data from controls and save them */
1427 dwInterleave
= GetDlgItemInt(hWnd
, IDC_INTERLEAVEEVERY
, NULL
, 0);
1428 bIsInterleaved
= IsDlgButtonChecked(hWnd
, IDC_INTERLEAVE
);
1429 for (n
= 0; n
< SaveOpts
.nStreams
; n
++) {
1430 if (SaveOpts
.ppOptions
[n
] != NULL
) {
1431 if (bIsInterleaved
) {
1432 SaveOpts
.ppOptions
[n
]->dwFlags
|= AVICOMPRESSF_INTERLEAVE
;
1433 SaveOpts
.ppOptions
[n
]->dwInterleaveEvery
= dwInterleave
;
1435 SaveOpts
.ppOptions
[n
]->dwFlags
&= ~AVICOMPRESSF_INTERLEAVE
;
1440 EndDialog(hWnd
, LOWORD(wParam
) == IDOK
);
1442 case IDC_INTERLEAVE
:
1443 EnableWindow(GetDlgItem(hWnd
, IDC_INTERLEAVEEVERY
),
1444 IsDlgButtonChecked(hWnd
, IDC_INTERLEAVE
));
1447 if (HIWORD(wParam
) == CBN_SELCHANGE
) {
1448 /* update control elements */
1449 AVISaveOptionsUpdate(hWnd
);
1453 AVISaveOptionsFmtChoose(hWnd
);
1462 /***********************************************************************
1463 * AVISaveOptions (AVIFIL32.@)
1465 BOOL WINAPI
AVISaveOptions(HWND hWnd
, UINT uFlags
, INT nStreams
,
1466 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*ppOptions
)
1468 LPAVICOMPRESSOPTIONS pSavedOptions
= NULL
;
1471 TRACE("(%p,0x%X,%d,%p,%p)\n", hWnd
, uFlags
, nStreams
,
1474 /* check parameters */
1475 if (nStreams
<= 0 || ppavi
== NULL
|| ppOptions
== NULL
)
1476 return AVIERR_BADPARAM
;
1478 /* save options in case the user presses cancel */
1479 if (ppOptions
!= NULL
&& nStreams
> 1) {
1480 pSavedOptions
= HeapAlloc(GetProcessHeap(), 0, nStreams
* sizeof(AVICOMPRESSOPTIONS
));
1481 if (pSavedOptions
== NULL
)
1484 for (n
= 0; n
< nStreams
; n
++) {
1485 if (ppOptions
[n
] != NULL
)
1486 memcpy(pSavedOptions
+ n
, ppOptions
[n
], sizeof(AVICOMPRESSOPTIONS
));
1490 SaveOpts
.uFlags
= uFlags
;
1491 SaveOpts
.nStreams
= nStreams
;
1492 SaveOpts
.ppavis
= ppavi
;
1493 SaveOpts
.ppOptions
= ppOptions
;
1495 ret
= DialogBoxW(AVIFILE_hModule
, MAKEINTRESOURCEW(IDD_SAVEOPTIONS
),
1496 hWnd
, AVISaveOptionsDlgProc
);
1501 /* restore options when user pressed cancel */
1502 if (pSavedOptions
!= NULL
) {
1504 for (n
= 0; n
< nStreams
; n
++) {
1505 if (ppOptions
[n
] != NULL
)
1506 memcpy(ppOptions
[n
], pSavedOptions
+ n
, sizeof(AVICOMPRESSOPTIONS
));
1509 HeapFree(GetProcessHeap(), 0, pSavedOptions
);
1515 /***********************************************************************
1516 * AVISaveOptionsFree (AVIFIL32.@)
1517 * AVISaveOptionsFree (AVIFILE.124)
1519 HRESULT WINAPI
AVISaveOptionsFree(INT nStreams
,LPAVICOMPRESSOPTIONS
*ppOptions
)
1521 TRACE("(%d,%p)\n", nStreams
, ppOptions
);
1523 if (nStreams
< 0 || ppOptions
== NULL
)
1524 return AVIERR_BADPARAM
;
1526 for (; nStreams
> 0; nStreams
--) {
1527 if (ppOptions
[nStreams
] != NULL
) {
1528 ppOptions
[nStreams
]->dwFlags
&= ~AVICOMPRESSF_VALID
;
1530 if (ppOptions
[nStreams
]->lpParms
!= NULL
) {
1531 HeapFree(GetProcessHeap(), 0, ppOptions
[nStreams
]->lpParms
);
1532 ppOptions
[nStreams
]->lpParms
= NULL
;
1533 ppOptions
[nStreams
]->cbParms
= 0;
1535 if (ppOptions
[nStreams
]->lpFormat
!= NULL
) {
1536 HeapFree(GetProcessHeap(), 0, ppOptions
[nStreams
]->lpFormat
);
1537 ppOptions
[nStreams
]->lpFormat
= NULL
;
1538 ppOptions
[nStreams
]->cbFormat
= 0;
1546 /***********************************************************************
1547 * AVISaveVA (AVIFIL32.@)
1549 HRESULT WINAPI
AVISaveVA(LPCSTR szFile
, CLSID
*pclsidHandler
,
1550 AVISAVECALLBACK lpfnCallback
, int nStream
,
1551 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*plpOptions
)
1553 LPWSTR wszFile
= NULL
;
1557 TRACE("%s,%p,%p,%d,%p,%p)\n", debugstr_a(szFile
), pclsidHandler
,
1558 lpfnCallback
, nStream
, ppavi
, plpOptions
);
1560 if (szFile
== NULL
|| ppavi
== NULL
|| plpOptions
== NULL
)
1561 return AVIERR_BADPARAM
;
1563 /* convert ASCII string to Unicode and call Unicode function */
1564 len
= MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, NULL
, 0);
1566 return AVIERR_BADPARAM
;
1568 wszFile
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
));
1569 if (wszFile
== NULL
)
1570 return AVIERR_MEMORY
;
1572 MultiByteToWideChar(CP_ACP
, 0, szFile
, -1, wszFile
, len
);
1574 hr
= AVISaveVW(wszFile
, pclsidHandler
, lpfnCallback
,
1575 nStream
, ppavi
, plpOptions
);
1577 HeapFree(GetProcessHeap(), 0, wszFile
);
1582 /***********************************************************************
1583 * AVIFILE_AVISaveDefaultCallback (internal)
1585 static BOOL WINAPI
AVIFILE_AVISaveDefaultCallback(INT progress
)
1587 TRACE("(%d)\n", progress
);
1592 /***********************************************************************
1593 * AVISaveVW (AVIFIL32.@)
1595 HRESULT WINAPI
AVISaveVW(LPCWSTR szFile
, CLSID
*pclsidHandler
,
1596 AVISAVECALLBACK lpfnCallback
, int nStreams
,
1597 PAVISTREAM
*ppavi
, LPAVICOMPRESSOPTIONS
*plpOptions
)
1599 LONG lStart
[MAX_AVISTREAMS
];
1600 PAVISTREAM pOutStreams
[MAX_AVISTREAMS
];
1601 PAVISTREAM pInStreams
[MAX_AVISTREAMS
];
1603 AVISTREAMINFOW sInfo
;
1605 PAVIFILE pfile
= NULL
; /* the output AVI file */
1606 LONG lFirstVideo
= -1;
1609 /* for interleaving ... */
1610 DWORD dwInterleave
= 0; /* interleave rate */
1611 DWORD dwFileInitialFrames
;
1615 /* for reading/writing the data ... */
1616 LPVOID lpBuffer
= NULL
;
1617 LONG cbBuffer
; /* real size of lpBuffer */
1618 LONG lBufferSize
; /* needed bytes for format(s), etc. */
1623 TRACE("(%s,%p,%p,%d,%p,%p)\n", debugstr_w(szFile
), pclsidHandler
,
1624 lpfnCallback
, nStreams
, ppavi
, plpOptions
);
1626 if (szFile
== NULL
|| ppavi
== NULL
|| plpOptions
== NULL
)
1627 return AVIERR_BADPARAM
;
1628 if (nStreams
>= MAX_AVISTREAMS
) {
1629 WARN("Can't write AVI with %d streams only supports %d -- change MAX_AVISTREAMS!\n", nStreams
, MAX_AVISTREAMS
);
1630 return AVIERR_INTERNAL
;
1633 if (lpfnCallback
== NULL
)
1634 lpfnCallback
= AVIFILE_AVISaveDefaultCallback
;
1636 /* clear local variable(s) */
1637 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1638 pInStreams
[curStream
] = NULL
;
1639 pOutStreams
[curStream
] = NULL
;
1642 /* open output AVI file (create it if it doesn't exist) */
1643 hres
= AVIFileOpenW(&pfile
, szFile
, OF_CREATE
|OF_SHARE_EXCLUSIVE
|OF_WRITE
,
1647 AVIFileInfoW(pfile
, &fInfo
, sizeof(fInfo
)); /* for dwCaps */
1649 /* initialize our data structures part 1 */
1650 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1651 PAVISTREAM pCurStream
= ppavi
[curStream
];
1653 hres
= AVIStreamInfoW(pCurStream
, &sInfo
, sizeof(sInfo
));
1657 /* search first video stream and check for interleaving */
1658 if (sInfo
.fccType
== streamtypeVIDEO
) {
1659 /* remember first video stream -- needed for interleaving */
1660 if (lFirstVideo
< 0)
1661 lFirstVideo
= curStream
;
1662 } else if (!dwInterleave
&& plpOptions
!= NULL
) {
1663 /* check if any non-video stream wants to be interleaved */
1664 WARN("options.flags=0x%X options.dwInterleave=%u\n",plpOptions
[curStream
]->dwFlags
,plpOptions
[curStream
]->dwInterleaveEvery
);
1665 if (plpOptions
[curStream
] != NULL
&&
1666 plpOptions
[curStream
]->dwFlags
& AVICOMPRESSF_INTERLEAVE
)
1667 dwInterleave
= plpOptions
[curStream
]->dwInterleaveEvery
;
1670 /* create de-/compressed stream interface if needed */
1671 pInStreams
[curStream
] = NULL
;
1672 if (plpOptions
!= NULL
&& plpOptions
[curStream
] != NULL
) {
1673 if (plpOptions
[curStream
]->fccHandler
||
1674 plpOptions
[curStream
]->lpFormat
!= NULL
) {
1675 DWORD dwKeySave
= plpOptions
[curStream
]->dwKeyFrameEvery
;
1677 if (fInfo
.dwCaps
& AVIFILECAPS_ALLKEYFRAMES
)
1678 plpOptions
[curStream
]->dwKeyFrameEvery
= 1;
1680 hres
= AVIMakeCompressedStream(&pInStreams
[curStream
], pCurStream
,
1681 plpOptions
[curStream
], NULL
);
1682 plpOptions
[curStream
]->dwKeyFrameEvery
= dwKeySave
;
1683 if (FAILED(hres
) || pInStreams
[curStream
] == NULL
) {
1684 pInStreams
[curStream
] = NULL
;
1688 /* test stream interface and update stream-info */
1689 hres
= AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1695 /* now handle streams which will only be copied */
1696 if (pInStreams
[curStream
] == NULL
) {
1697 pCurStream
= pInStreams
[curStream
] = ppavi
[curStream
];
1698 AVIStreamAddRef(pCurStream
);
1700 pCurStream
= pInStreams
[curStream
];
1702 lStart
[curStream
] = sInfo
.dwStart
;
1703 } /* for all streams */
1705 /* check that first video stream is the first stream */
1706 if (lFirstVideo
> 0) {
1707 PAVISTREAM pTmp
= pInStreams
[lFirstVideo
];
1708 LONG lTmp
= lStart
[lFirstVideo
];
1710 pInStreams
[lFirstVideo
] = pInStreams
[0];
1711 pInStreams
[0] = pTmp
;
1712 lStart
[lFirstVideo
] = lStart
[0];
1717 /* allocate buffer for formats, data, etc. of an initial size of 64 kBytes*/
1718 cbBuffer
= 0x00010000;
1719 lpBuffer
= HeapAlloc(GetProcessHeap(), 0, cbBuffer
);
1720 if (lpBuffer
== NULL
) {
1721 hres
= AVIERR_MEMORY
;
1725 AVIStreamInfoW(pInStreams
[0], &sInfo
, sizeof(sInfo
));
1726 lFileLength
= sInfo
.dwLength
;
1727 dwFileInitialFrames
= 0;
1728 if (lFirstVideo
>= 0) {
1729 /* check for correct version of the format
1730 * -- need at least BITMAPINFOHEADER or newer
1733 lBufferSize
= cbBuffer
;
1734 hres
= AVIStreamReadFormat(pInStreams
[lFirstVideo
], AVIStreamStart(pInStreams
[lFirstVideo
]), lpBuffer
, &lBufferSize
);
1735 if (lBufferSize
< (LONG
)sizeof(BITMAPINFOHEADER
))
1736 hres
= AVIERR_INTERNAL
;
1739 } else /* use one second blocks for interleaving if no video present */
1740 lSampleInc
= AVIStreamTimeToSample(pInStreams
[0], 1000000);
1742 /* create output streams */
1743 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1744 AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1746 sInfo
.dwInitialFrames
= 0;
1747 if (dwInterleave
!= 0 && curStream
> 0 && sInfo
.fccType
!= streamtypeVIDEO
) {
1748 /* 750 ms initial frames for non-video streams */
1749 sInfo
.dwInitialFrames
= AVIStreamTimeToSample(pInStreams
[0], 750);
1752 hres
= AVIFileCreateStreamW(pfile
, &pOutStreams
[curStream
], &sInfo
);
1753 if (pOutStreams
[curStream
] != NULL
&& SUCCEEDED(hres
)) {
1754 /* copy initial format for this stream */
1755 lBufferSize
= cbBuffer
;
1756 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1757 lpBuffer
, &lBufferSize
);
1760 hres
= AVIStreamSetFormat(pOutStreams
[curStream
], 0, lpBuffer
, lBufferSize
);
1764 /* try to copy stream handler data */
1765 lBufferSize
= cbBuffer
;
1766 hres
= AVIStreamReadData(pInStreams
[curStream
], ckidSTREAMHANDLERDATA
,
1767 lpBuffer
, &lBufferSize
);
1768 if (SUCCEEDED(hres
) && lBufferSize
> 0) {
1769 hres
= AVIStreamWriteData(pOutStreams
[curStream
],ckidSTREAMHANDLERDATA
,
1770 lpBuffer
, lBufferSize
);
1775 if (dwFileInitialFrames
< sInfo
.dwInitialFrames
)
1776 dwFileInitialFrames
= sInfo
.dwInitialFrames
;
1778 AVIStreamSampleToSample(pOutStreams
[0], pInStreams
[curStream
],
1780 if (lFileLength
< lReadBytes
)
1781 lFileLength
= lReadBytes
;
1783 /* creation of de-/compression stream interface failed */
1784 WARN("creation of (de-)compression stream failed for stream %d\n",curStream
);
1785 AVIStreamRelease(pInStreams
[curStream
]);
1786 if (curStream
+ 1 >= nStreams
) {
1787 /* move the others one up */
1788 PAVISTREAM
*ppas
= &pInStreams
[curStream
];
1789 int n
= nStreams
- (curStream
+ 1);
1792 *ppas
= pInStreams
[curStream
+ 1];
1798 } /* create output streams for all input streams */
1800 /* have we still something to write, or lost everything? */
1805 LONG lCurFrame
= -dwFileInitialFrames
;
1807 /* interleaved file */
1808 if (dwInterleave
== 1)
1809 AVIFileEndRecord(pfile
);
1811 for (; lCurFrame
< lFileLength
; lCurFrame
+= lSampleInc
) {
1812 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1815 hres
= AVIStreamInfoW(pOutStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1819 /* initial frames phase at the end for this stream? */
1820 if (-(LONG
)sInfo
.dwInitialFrames
> lCurFrame
)
1823 if ((lFileLength
- lSampleInc
) <= lCurFrame
) {
1824 lLastSample
= AVIStreamLength(pInStreams
[curStream
]);
1825 lFirstVideo
= lLastSample
+ AVIStreamStart(pInStreams
[curStream
]);
1827 if (curStream
!= 0) {
1829 AVIStreamSampleToSample(pInStreams
[curStream
], pInStreams
[0],
1830 (sInfo
.fccType
== streamtypeVIDEO
?
1831 (LONG
)dwInterleave
: lSampleInc
) +
1832 sInfo
.dwInitialFrames
+ lCurFrame
);
1834 lFirstVideo
= lSampleInc
+ (sInfo
.dwInitialFrames
+ lCurFrame
);
1836 lLastSample
= AVIStreamEnd(pInStreams
[curStream
]);
1837 if (lLastSample
<= lFirstVideo
)
1838 lFirstVideo
= lLastSample
;
1841 /* copy needed samples now */
1842 WARN("copy from stream %d samples %d to %d...\n",curStream
,
1843 lStart
[curStream
],lFirstVideo
);
1844 while (lFirstVideo
> lStart
[curStream
]) {
1847 /* copy format in case it can change */
1848 lBufferSize
= cbBuffer
;
1849 hres
= AVIStreamReadFormat(pInStreams
[curStream
], lStart
[curStream
],
1850 lpBuffer
, &lBufferSize
);
1853 AVIStreamSetFormat(pOutStreams
[curStream
], lStart
[curStream
],
1854 lpBuffer
, lBufferSize
);
1856 /* try to read data until we got it, or error */
1858 hres
= AVIStreamRead(pInStreams
[curStream
], lStart
[curStream
],
1859 lFirstVideo
- lStart
[curStream
], lpBuffer
,
1860 cbBuffer
, &lReadBytes
, &lReadSamples
);
1861 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1862 (lpBuffer
= HeapReAlloc(GetProcessHeap(), 0, lpBuffer
, cbBuffer
*= 2)) != NULL
);
1863 if (lpBuffer
== NULL
)
1864 hres
= AVIERR_MEMORY
;
1868 if (AVIStreamIsKeyFrame(pInStreams
[curStream
], (LONG
)sInfo
.dwStart
))
1869 flags
= AVIIF_KEYFRAME
;
1870 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1871 lpBuffer
, lReadBytes
, flags
, NULL
, NULL
);
1875 lStart
[curStream
] += lReadSamples
;
1877 lStart
[curStream
] = lFirstVideo
;
1878 } /* stream by stream */
1880 /* need to close this block? */
1881 if (dwInterleave
== 1) {
1882 hres
= AVIFileEndRecord(pfile
);
1888 if (lpfnCallback(MulDiv(dwFileInitialFrames
+ lCurFrame
, 100,
1889 dwFileInitialFrames
+ lFileLength
))) {
1890 hres
= AVIERR_USERABORT
;
1893 } /* copy frame by frame */
1895 /* non-interleaved file */
1897 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
1899 if (lpfnCallback(MulDiv(curStream
, 100, nStreams
))) {
1900 hres
= AVIERR_USERABORT
;
1904 AVIStreamInfoW(pInStreams
[curStream
], &sInfo
, sizeof(sInfo
));
1906 if (sInfo
.dwSampleSize
!= 0) {
1907 /* sample-based data like audio */
1908 while (sInfo
.dwStart
< sInfo
.dwLength
) {
1909 LONG lSamples
= cbBuffer
/ sInfo
.dwSampleSize
;
1911 /* copy format in case it can change */
1912 lBufferSize
= cbBuffer
;
1913 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1914 lpBuffer
, &lBufferSize
);
1917 AVIStreamSetFormat(pOutStreams
[curStream
], sInfo
.dwStart
,
1918 lpBuffer
, lBufferSize
);
1920 /* limit to stream boundaries */
1921 if (lSamples
!= (LONG
)(sInfo
.dwLength
- sInfo
.dwStart
))
1922 lSamples
= sInfo
.dwLength
- sInfo
.dwStart
;
1924 /* now try to read until we get it, or an error occurs */
1926 lReadBytes
= cbBuffer
;
1928 hres
= AVIStreamRead(pInStreams
[curStream
],sInfo
.dwStart
,lSamples
,
1929 lpBuffer
,cbBuffer
,&lReadBytes
,&lReadSamples
);
1930 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1931 (lpBuffer
= HeapReAlloc(GetProcessHeap(), 0, lpBuffer
, cbBuffer
*= 2)) != NULL
);
1932 if (lpBuffer
== NULL
)
1933 hres
= AVIERR_MEMORY
;
1936 if (lReadSamples
!= 0) {
1937 sInfo
.dwStart
+= lReadSamples
;
1938 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1939 lpBuffer
, lReadBytes
, 0, NULL
, NULL
);
1944 if (lpfnCallback(MulDiv(sInfo
.dwStart
,100,nStreams
*sInfo
.dwLength
)+
1945 MulDiv(curStream
, 100, nStreams
))) {
1946 hres
= AVIERR_USERABORT
;
1950 if ((sInfo
.dwLength
- sInfo
.dwStart
) != 1) {
1951 hres
= AVIERR_FILEREAD
;
1957 /* block-based data like video */
1958 for (; sInfo
.dwStart
< sInfo
.dwLength
; sInfo
.dwStart
++) {
1961 /* copy format in case it can change */
1962 lBufferSize
= cbBuffer
;
1963 hres
= AVIStreamReadFormat(pInStreams
[curStream
], sInfo
.dwStart
,
1964 lpBuffer
, &lBufferSize
);
1967 AVIStreamSetFormat(pOutStreams
[curStream
], sInfo
.dwStart
,
1968 lpBuffer
, lBufferSize
);
1970 /* try to read block and resize buffer if necessary */
1973 lReadBytes
= cbBuffer
;
1974 hres
= AVIStreamRead(pInStreams
[curStream
], sInfo
.dwStart
, 1,
1975 lpBuffer
, cbBuffer
,&lReadBytes
,&lReadSamples
);
1976 } while ((hres
== AVIERR_BUFFERTOOSMALL
) &&
1977 (lpBuffer
= HeapReAlloc(GetProcessHeap(), 0, lpBuffer
, cbBuffer
*= 2)) != NULL
);
1978 if (lpBuffer
== NULL
)
1979 hres
= AVIERR_MEMORY
;
1982 if (lReadSamples
!= 1) {
1983 hres
= AVIERR_FILEREAD
;
1987 if (AVIStreamIsKeyFrame(pInStreams
[curStream
], (LONG
)sInfo
.dwStart
))
1988 flags
= AVIIF_KEYFRAME
;
1989 hres
= AVIStreamWrite(pOutStreams
[curStream
], -1, lReadSamples
,
1990 lpBuffer
, lReadBytes
, flags
, NULL
, NULL
);
1995 if (lpfnCallback(MulDiv(sInfo
.dwStart
,100,nStreams
*sInfo
.dwLength
)+
1996 MulDiv(curStream
, 100, nStreams
))) {
1997 hres
= AVIERR_USERABORT
;
2000 } /* copy all blocks */
2002 } /* copy data stream by stream */
2006 HeapFree(GetProcessHeap(), 0, lpBuffer
);
2007 if (pfile
!= NULL
) {
2008 for (curStream
= 0; curStream
< nStreams
; curStream
++) {
2009 if (pOutStreams
[curStream
] != NULL
)
2010 AVIStreamRelease(pOutStreams
[curStream
]);
2011 if (pInStreams
[curStream
] != NULL
)
2012 AVIStreamRelease(pInStreams
[curStream
]);
2015 AVIFileRelease(pfile
);
2021 /***********************************************************************
2022 * CreateEditableStream (AVIFIL32.@)
2024 HRESULT WINAPI
CreateEditableStream(PAVISTREAM
*ppEditable
, PAVISTREAM pSource
)
2026 IAVIEditStream
*pEdit
= NULL
;
2029 TRACE("(%p,%p)\n", ppEditable
, pSource
);
2031 if (ppEditable
== NULL
)
2032 return AVIERR_BADPARAM
;
2036 if (pSource
!= NULL
) {
2037 hr
= IAVIStream_QueryInterface(pSource
, &IID_IAVIEditStream
,
2039 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2040 hr
= IAVIEditStream_Clone(pEdit
, ppEditable
);
2041 IAVIEditStream_Release(pEdit
);
2047 /* need own implementation of IAVIEditStream */
2048 pEdit
= AVIFILE_CreateEditStream(pSource
);
2050 return AVIERR_MEMORY
;
2052 hr
= IAVIEditStream_QueryInterface(pEdit
, &IID_IAVIStream
,
2053 (LPVOID
*)ppEditable
);
2054 IAVIEditStream_Release(pEdit
);
2059 /***********************************************************************
2060 * EditStreamClone (AVIFIL32.@)
2062 HRESULT WINAPI
EditStreamClone(PAVISTREAM pStream
, PAVISTREAM
*ppResult
)
2064 PAVIEDITSTREAM pEdit
= NULL
;
2067 TRACE("(%p,%p)\n", pStream
, ppResult
);
2069 if (pStream
== NULL
)
2070 return AVIERR_BADHANDLE
;
2071 if (ppResult
== NULL
)
2072 return AVIERR_BADPARAM
;
2076 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2077 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2078 hr
= IAVIEditStream_Clone(pEdit
, ppResult
);
2080 IAVIEditStream_Release(pEdit
);
2082 hr
= AVIERR_UNSUPPORTED
;
2087 /***********************************************************************
2088 * EditStreamCopy (AVIFIL32.@)
2090 HRESULT WINAPI
EditStreamCopy(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_Copy(pEdit
, plStart
, plLength
, ppResult
);
2109 IAVIEditStream_Release(pEdit
);
2111 hr
= AVIERR_UNSUPPORTED
;
2116 /***********************************************************************
2117 * EditStreamCut (AVIFIL32.@)
2119 HRESULT WINAPI
EditStreamCut(PAVISTREAM pStream
, LONG
*plStart
,
2120 LONG
*plLength
, PAVISTREAM
*ppResult
)
2122 PAVIEDITSTREAM pEdit
= NULL
;
2125 TRACE("(%p,%p,%p,%p)\n", pStream
, plStart
, plLength
, ppResult
);
2127 if (ppResult
!= NULL
)
2129 if (pStream
== NULL
)
2130 return AVIERR_BADHANDLE
;
2131 if (plStart
== NULL
|| plLength
== NULL
)
2132 return AVIERR_BADPARAM
;
2134 hr
= IAVIStream_QueryInterface(pStream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2135 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2136 hr
= IAVIEditStream_Cut(pEdit
, plStart
, plLength
, ppResult
);
2138 IAVIEditStream_Release(pEdit
);
2140 hr
= AVIERR_UNSUPPORTED
;
2145 /***********************************************************************
2146 * EditStreamPaste (AVIFIL32.@)
2148 HRESULT WINAPI
EditStreamPaste(PAVISTREAM pDest
, LONG
*plStart
, LONG
*plLength
,
2149 PAVISTREAM pSource
, LONG lStart
, LONG lEnd
)
2151 PAVIEDITSTREAM pEdit
= NULL
;
2154 TRACE("(%p,%p,%p,%p,%d,%d)\n", pDest
, plStart
, plLength
,
2155 pSource
, lStart
, lEnd
);
2157 if (pDest
== NULL
|| pSource
== NULL
)
2158 return AVIERR_BADHANDLE
;
2159 if (plStart
== NULL
|| plLength
== NULL
|| lStart
< 0)
2160 return AVIERR_BADPARAM
;
2162 hr
= IAVIStream_QueryInterface(pDest
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2163 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2164 hr
= IAVIEditStream_Paste(pEdit
, plStart
, plLength
, pSource
, lStart
, lEnd
);
2166 IAVIEditStream_Release(pEdit
);
2168 hr
= AVIERR_UNSUPPORTED
;
2173 /***********************************************************************
2174 * EditStreamSetInfoA (AVIFIL32.@)
2176 HRESULT WINAPI
EditStreamSetInfoA(PAVISTREAM pstream
, LPAVISTREAMINFOA asi
,
2179 AVISTREAMINFOW asiw
;
2181 TRACE("(%p,%p,%d)\n", pstream
, asi
, size
);
2183 if (pstream
== NULL
)
2184 return AVIERR_BADHANDLE
;
2185 if ((DWORD
)size
< sizeof(AVISTREAMINFOA
))
2186 return AVIERR_BADSIZE
;
2188 memcpy(&asiw
, asi
, sizeof(asiw
) - sizeof(asiw
.szName
));
2189 MultiByteToWideChar(CP_ACP
, 0, asi
->szName
, -1,
2190 asiw
.szName
, sizeof(asiw
.szName
)/sizeof(WCHAR
));
2192 return EditStreamSetInfoW(pstream
, &asiw
, sizeof(asiw
));
2195 /***********************************************************************
2196 * EditStreamSetInfoW (AVIFIL32.@)
2198 HRESULT WINAPI
EditStreamSetInfoW(PAVISTREAM pstream
, LPAVISTREAMINFOW asi
,
2201 PAVIEDITSTREAM pEdit
= NULL
;
2204 TRACE("(%p,%p,%d)\n", pstream
, asi
, size
);
2206 hr
= IAVIStream_QueryInterface(pstream
, &IID_IAVIEditStream
,(LPVOID
*)&pEdit
);
2207 if (SUCCEEDED(hr
) && pEdit
!= NULL
) {
2208 hr
= IAVIEditStream_SetInfo(pEdit
, asi
, size
);
2210 IAVIEditStream_Release(pEdit
);
2212 hr
= AVIERR_UNSUPPORTED
;
2217 /***********************************************************************
2218 * EditStreamSetNameA (AVIFIL32.@)
2220 HRESULT WINAPI
EditStreamSetNameA(PAVISTREAM pstream
, LPCSTR szName
)
2222 AVISTREAMINFOA asia
;
2225 TRACE("(%p,%s)\n", pstream
, debugstr_a(szName
));
2227 if (pstream
== NULL
)
2228 return AVIERR_BADHANDLE
;
2230 return AVIERR_BADPARAM
;
2232 hres
= AVIStreamInfoA(pstream
, &asia
, sizeof(asia
));
2236 memset(asia
.szName
, 0, sizeof(asia
.szName
));
2237 lstrcpynA(asia
.szName
, szName
, sizeof(asia
.szName
)/sizeof(asia
.szName
[0]));
2239 return EditStreamSetInfoA(pstream
, &asia
, sizeof(asia
));
2242 /***********************************************************************
2243 * EditStreamSetNameW (AVIFIL32.@)
2245 HRESULT WINAPI
EditStreamSetNameW(PAVISTREAM pstream
, LPCWSTR szName
)
2247 AVISTREAMINFOW asiw
;
2250 TRACE("(%p,%s)\n", pstream
, debugstr_w(szName
));
2252 if (pstream
== NULL
)
2253 return AVIERR_BADHANDLE
;
2255 return AVIERR_BADPARAM
;
2257 hres
= IAVIStream_Info(pstream
, &asiw
, sizeof(asiw
));
2261 memset(asiw
.szName
, 0, sizeof(asiw
.szName
));
2262 lstrcpynW(asiw
.szName
, szName
, sizeof(asiw
.szName
)/sizeof(asiw
.szName
[0]));
2264 return EditStreamSetInfoW(pstream
, &asiw
, sizeof(asiw
));
2267 /***********************************************************************
2268 * AVIClearClipboard (AVIFIL32.@)
2270 HRESULT WINAPI
AVIClearClipboard(void)
2274 return AVIERR_UNSUPPORTED
; /* OleSetClipboard(NULL); */
2277 /***********************************************************************
2278 * AVIGetFromClipboard (AVIFIL32.@)
2280 HRESULT WINAPI
AVIGetFromClipboard(PAVIFILE
*ppfile
)
2282 FIXME("(%p), stub!\n", ppfile
);
2286 return AVIERR_UNSUPPORTED
;
2289 /***********************************************************************
2290 * AVIMakeStreamFromClipboard (AVIFIL32.@)
2292 HRESULT WINAPI
AVIMakeStreamFromClipboard(UINT cfFormat
, HANDLE hGlobal
,
2293 PAVISTREAM
* ppstream
)
2295 FIXME("(0x%08x,%p,%p), stub!\n", cfFormat
, hGlobal
, ppstream
);
2297 if (ppstream
== NULL
)
2298 return AVIERR_BADHANDLE
;
2300 return AVIERR_UNSUPPORTED
;
2303 /***********************************************************************
2304 * AVIPutFileOnClipboard (AVIFIL32.@)
2306 HRESULT WINAPI
AVIPutFileOnClipboard(PAVIFILE pfile
)
2308 FIXME("(%p), stub!\n", pfile
);
2311 return AVIERR_BADHANDLE
;
2313 return AVIERR_UNSUPPORTED
;
2316 HRESULT WINAPIV
AVISaveA(LPCSTR szFile
, CLSID
* pclsidHandler
, AVISAVECALLBACK lpfnCallback
,
2317 int nStreams
, PAVISTREAM pavi
, LPAVICOMPRESSOPTIONS lpOptions
, ...)
2319 FIXME("(%s,%p,%p,0x%08x,%p,%p), stub!\n", debugstr_a(szFile
), pclsidHandler
, lpfnCallback
,
2320 nStreams
, pavi
, lpOptions
);
2322 return AVIERR_UNSUPPORTED
;
2325 HRESULT WINAPIV
AVISaveW(LPCWSTR szFile
, CLSID
* pclsidHandler
, AVISAVECALLBACK lpfnCallback
,
2326 int nStreams
, PAVISTREAM pavi
, LPAVICOMPRESSOPTIONS lpOptions
, ...)
2328 FIXME("(%s,%p,%p,0x%08x,%p,%p), stub!\n", debugstr_w(szFile
), pclsidHandler
, lpfnCallback
,
2329 nStreams
, pavi
, lpOptions
);
2331 return AVIERR_UNSUPPORTED
;