/* * VCM.cs * Copyright (c) 2007-2009 kbinani * * This file is part of Boare.Lib.Media. * * Boare.Lib.Media is free software; you can redistribute it and/or * modify it under the terms of the BSD License. * * Boare.Lib.Media is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.IO; using bocoree; namespace Boare.Lib.Media { public class VCM { public const uint ICMODE_QUERY = 4; public const uint ICMF_CHOOSE_ALLCOMPRESSORS = 0x08; public static readonly uint ICTYPE_VIDEO = Util.mmioFOURCC( 'v', 'i', 'd', 'c' ); public static readonly uint ICTYPE_AUDIO = Util.mmioFOURCC( 'a', 'u', 'd', 'c' ); public const uint ICM_COMPRESS_GET_FORMAT = 0x4004; [DllImport( "msvfw32.dll" )] public static extern UInt32 ICOpen( UInt32 fccType, UInt32 fccHandler, uint wMode ); [DllImport( "msvfw32.dll" )] public static unsafe extern int ICGetInfo( UInt32 hic, ICINFO* icinfo, int size ); /*unsafe public static int ICGetInfo( UInt32 hic, ref ICINFO icinfo, int size ) { IntPtr pt = new IntPtr( 0 ); int r = w_ICGetInfo( hic, &pt, size ); ICINFO result = new ICINFO(); result = (ICINFO)Marshal.PtrToStructure( pt, result.GetType() ); icinfo = result; return r; }*/ [DllImport( "msvfw32.dll" )] public static extern int ICClose( UInt32 hic ); [DllImport( "msvfw32.dll" )] public static unsafe extern int ICCompressorChoose( IntPtr hwnd, UInt32 uiFlags, IntPtr pvIn, IntPtr lpData, COMPVARS* pc, string lpszTitle ); [DllImport( "msvfw32.dll" )] public static unsafe extern int ICSeqCompressFrameStart( COMPVARS* pc, BITMAPINFO* lpbiIn ); [DllImport( "msvfw32.dll" )] public static unsafe extern void ICSeqCompressFrameEnd( COMPVARS* pc ); [DllImport( "msvfw32.dll" )] public static unsafe extern void ICCompressorFree( COMPVARS* pc ); [DllImport( "msvfw32.dll" )] public static unsafe extern IntPtr ICSeqCompressFrame( COMPVARS* pc, UInt32 uiFlags, IntPtr lpBits, Int32* pfKey, Int32* plSize ); [DllImport( "msvfw32.dll" )] public static unsafe extern UIntPtr ICSendMessage( UInt32 hic, UInt32 wMsg, IntPtr dw1, IntPtr dw2 ); public static unsafe uint ICCompressGetFormatSize( UInt32 hic, BITMAPINFO* lpbi ) { return ICCompressGetFormat( hic, lpbi, (BITMAPINFO*)0 ); } public static unsafe uint ICCompressGetFormat( UInt32 hic, BITMAPINFO* lpbiInput, BITMAPINFO* lpbiOutput ) { return (uint)ICSendMessage( hic, ICM_COMPRESS_GET_FORMAT, (IntPtr)lpbiInput, (IntPtr)lpbiOutput ); } } [StructLayout( LayoutKind.Sequential, Pack = 1 )] public struct ICINFO { public UInt32 dwSize; public UInt32 fccType; public UInt32 fccHandler; public UInt32 dwFlags; public UInt32 dwVersion; public UInt32 dwVersionICM; private sz16 szName; private sz128 szDescription; private sz128 szDriver; public string Name { get { string t = szName.Value; //return t.ToCharArray(); return t; } } public string Description { get { string t = szDescription.Value; //return t.ToCharArray(); return t; } } public string Driver { get { string t = szDriver.Value; //return t.ToCharArray(); return t; } } [StructLayout( LayoutKind.Sequential, Pack = 1 )] private struct sz4 { UInt16 UInt16_1; UInt16 UInt16_2; UInt16 UInt16_3; UInt16 UInt16_4; public string Value { get { return "" + (char)UInt16_1 + (char)UInt16_2 + (char)UInt16_3 + (char)UInt16_4; } } } [StructLayout( LayoutKind.Sequential, Pack = 1 )] private struct sz16 { sz4 sz4_1; sz4 sz4_2; sz4 sz4_3; sz4 sz4_4; public string Value { get { return sz4_1.Value + sz4_2.Value + sz4_3.Value + sz4_4.Value; } } } [StructLayout( LayoutKind.Sequential, Pack = 1 )] private struct sz64 { sz16 sz16_1; sz16 sz16_2; sz16 sz16_3; sz16 sz16_4; public string Value { get { return sz16_1.Value + sz16_2.Value + sz16_3.Value + sz16_4.Value; } } } [StructLayout( LayoutKind.Sequential, Pack = 1 )] private struct sz128 { sz64 sz64_1; sz64 sz64_2; public string Value { get { return sz64_1.Value + sz64_2.Value; } } } } [StructLayout( LayoutKind.Sequential, Pack = 1 )] public unsafe struct COMPVARS { public Int32 cbSize; public UInt32 dwFlags; public UInt32 hic; // 元はHIC public UInt32 fccType; public UInt32 fccHandler; public BITMAPINFOHEADER* lpbiIn; public BITMAPINFOHEADER* lpbiOut; public void* lpBitsOut; public void* lpBitsPrev; public Int32 lFrame; public Int32 lKey; public Int32 lDataRate; public Int32 lQ; public Int32 lKeyCount; public void* lpState; public Int32 cbState; public override string ToString() { return "{cbSize=" + cbSize + ",dwFlags=" + dwFlags + ",hic=" + hic + ",fccType=" + fccType + ",fccHandler=" + fccHandler + ",lpbiIn=" + ((int)lpbiIn).ToString() + ",lpbiOut=" + ((int)lpbiOut).ToString() + ",lpBitsOut=" + ((int)lpBitsOut).ToString() + ",lpBitsPrev=" + ((int)lpBitsPrev).ToString() + ",lFrame=" + lFrame + ",lKey=" + lKey + ",lDataRate=" + lDataRate + ",lQ=" + lQ + ",lKeyCount=" + lKeyCount + ",lpState=" + ((int)lpState).ToString() + ",cbState=" + cbState + "}"; } } [StructLayout(LayoutKind.Sequential, Pack=1)] public struct BITMAPINFO { public BITMAPINFOHEADER bmiHeader; public RGBQUAD bmiColors; public unsafe void Write( BinaryWriter bw ) { bmiHeader.Write( bw ); int remain = (int)((bmiHeader.biSize - sizeof( BITMAPINFOHEADER )) / sizeof( RGBQUAD )); fixed ( RGBQUAD* rgbq = &bmiColors ) { // これ以外に,「落ちないやり方」が無かった.メモリーが連続していることを祈るのみ for ( int i = 0; i < remain; i++ ) { bw.Write( rgbq[i].rgbBlue ); bw.Write( rgbq[i].rgbGreen ); bw.Write( rgbq[i].rgbRed ); bw.Write( rgbq[i].rgbReserved ); } } } } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct RGBQUAD { public byte rgbBlue; public byte rgbGreen; public byte rgbRed; public byte rgbReserved; } }