2 using System.Collections.Generic;
\r
4 using System.Runtime.InteropServices;
\r
5 using System.Drawing;
\r
10 public class CAvi : IDisposable
\r
38 public CAvi( string filename )
\r
40 if( AVIFileOpen( out this.aviFile, filename, OpenFileFlags.OF_READ, IntPtr.Zero ) != 0 )
\r
43 throw new Exception( "AVIFileOpen failed." );
\r
45 if( AVIFileGetStream( this.aviFile, out this.aviStream, streamtypeVIDEO, 0 ) != 0 )
\r
48 throw new Exception( "AVIFileGetStream failed." );
\r
50 AVISTREAMINFO psi = new AVISTREAMINFO();
\r
51 AVIStreamInfo( this.aviStream, ref psi, Marshal.SizeOf( psi ) );
\r
52 this.dwレート = psi.dwRate;
\r
53 this.dwスケール = psi.dwScale;
\r
54 this.nフレーム幅 = psi.rcFrame.right - psi.rcFrame.left;
\r
55 this.nフレーム高さ = psi.rcFrame.bottom - psi.rcFrame.top;
\r
58 this.frame = AVIStreamGetFrameOpen( this.aviStream, 0 );
\r
63 throw new Exception( "AVIStreamGetFrameOpen failed." );
\r
70 public static void t初期化()
\r
74 public static void t終了()
\r
79 public Bitmap GetFrame( int no )
\r
81 if( this.aviStream == IntPtr.Zero )
\r
83 throw new InvalidOperationException();
\r
85 return BitmapUtil.ToBitmap( AVIStreamGetFrame( this.frame, no ) );
\r
87 public int GetFrameNoFromTime( int time )
\r
89 return (int) ( time * ( ( (double) this.dwレート ) / ( 1000.0 * this.dwスケール ) ) );
\r
91 public IntPtr GetFramePtr( int no )
\r
93 if( this.aviStream == IntPtr.Zero )
\r
95 throw new InvalidOperationException();
\r
97 return AVIStreamGetFrame( this.frame, no );
\r
99 public int GetMaxFrameCount()
\r
101 if( this.aviStream == IntPtr.Zero )
\r
103 throw new InvalidOperationException();
\r
105 return AVIStreamLength( this.aviStream );
\r
108 public unsafe void tBitmap24ToGraphicsStreamR5G6B5( BitmapUtil.BITMAPINFOHEADER* pBITMAPINFOHEADER, DataStream gs, int nWidth, int nHeight )
\r
110 int num = pBITMAPINFOHEADER->biWidthビットマップの幅dot;
\r
111 int num2 = pBITMAPINFOHEADER->biHeightビットマップの高さdot;
\r
112 int num3 = ( num * 3 ) + ( ( 4 - ( ( num * 3 ) % 4 ) ) % 4 );
\r
113 ushort* numPtr = (ushort*) gs.DataPointer.ToPointer();
\r
114 byte* numPtr2 = (byte*) ( pBITMAPINFOHEADER + 1 );
\r
115 for( int i = 0; i < num2; i++ )
\r
121 for( int j = 0; j < num; j++ )
\r
127 ushort num6 = (ushort) ( ( ( numPtr2 + ( ( ( num2 - i ) - 1 ) * num3 ) )[ j * 3 ] >> 3 ) & 0x1f );
\r
128 ushort num5 = (ushort) ( ( ( ( numPtr2 + ( ( ( num2 - i ) - 1 ) * num3 ) ) + ( j * 3 ) )[ 1 ] >> 2 ) & 0x3f );
\r
129 ushort num4 = (ushort) ( ( ( ( numPtr2 + ( ( ( num2 - i ) - 1 ) * num3 ) ) + ( j * 3 ) )[ 2 ] >> 3 ) & 0x1f );
\r
130 ( numPtr + ( i * nWidth ) )[ j ] = (ushort) ( ( ( num4 << 11 ) | ( num5 << 5 ) ) | num6 );
\r
134 public unsafe void tBitmap24ToGraphicsStreamX8R8G8B8( BitmapUtil.BITMAPINFOHEADER* pBITMAPINFOHEADER, DataStream ds, int nWidth, int nHeight )
\r
136 int num = pBITMAPINFOHEADER->biWidthビットマップの幅dot;
\r
137 int num2 = pBITMAPINFOHEADER->biHeightビットマップの高さdot;
\r
138 int num3 = ( num * 3 ) + ( ( 4 - ( ( num * 3 ) % 4 ) ) % 4 );
\r
139 uint* numPtr = (uint*) ds.DataPointer.ToPointer();
\r
140 byte* numPtr2 = (byte*) ( pBITMAPINFOHEADER + 1 );
\r
141 for( int i = 0; i < num2; i++ )
\r
147 for( int j = 0; j < num; j++ )
\r
153 uint num6 = ( numPtr2 + ( ( ( num2 - i ) - 1 ) * num3 ) )[ j * 3 ];
\r
154 uint num5 = ( ( numPtr2 + ( ( ( num2 - i ) - 1 ) * num3 ) ) + ( j * 3 ) )[ 1 ];
\r
155 uint num4 = ( ( numPtr2 + ( ( ( num2 - i ) - 1 ) * num3 ) ) + ( j * 3 ) )[ 2 ];
\r
156 ( numPtr + ( i * nWidth ) )[ j ] = ( ( num4 << 0x10 ) | ( num5 << 8 ) ) | num6;
\r
161 #region [ IDisposable+α 実装 ]
\r
162 //-----------------
\r
163 public void Dispose()
\r
165 this.Dispose( true );
\r
167 protected void Dispose( bool disposeManagedObjects )
\r
169 if( !this.bDispose完了済み )
\r
171 if( this.frame != IntPtr.Zero )
\r
173 AVIStreamGetFrameClose( this.frame );
\r
176 this.bDispose完了済み = true;
\r
181 this.Dispose( false );
\r
183 //-----------------
\r
189 #region [ Win32 AVI関連関数インポート ]
\r
190 //-----------------
\r
191 internal enum OpenFileFlags : uint
\r
194 OF_CREATE = 0x1000,
\r
198 OF_PROMPT = 0x2000,
\r
201 OF_REOPEN = 0x8000,
\r
202 OF_SHARE_COMPAT = 0,
\r
203 OF_SHARE_DENY_NONE = 0x40,
\r
204 OF_SHARE_DENY_READ = 0x30,
\r
205 OF_SHARE_DENY_WRITE = 0x20,
\r
206 OF_SHARE_EXCLUSIVE = 0x10,
\r
211 [StructLayout( LayoutKind.Sequential, Pack = 1 )]
\r
212 internal struct AVISTREAMINFO
\r
214 public uint fccType;
\r
215 public uint fccHandler;
\r
216 public uint dwFlags;
\r
217 public uint dwCaps;
\r
218 public ushort wPriority;
\r
219 public ushort wLanguage;
\r
220 public uint dwScale;
\r
221 public uint dwRate;
\r
222 public uint dwStart;
\r
223 public uint dwLength;
\r
224 public uint dwInitialFrames;
\r
225 public uint dwSuggestedBufferSize;
\r
226 public uint dwQuality;
\r
227 public uint dwSampleSize;
\r
228 public CAvi.RECT rcFrame;
\r
229 public uint dwEditCount;
\r
230 public uint dwFormatChangeCount;
\r
231 [MarshalAs( UnmanagedType.ByValArray, SizeConst = 0x40 )]
\r
232 public ushort[] szName;
\r
235 [StructLayout( LayoutKind.Sequential, Pack = 1 )]
\r
236 internal struct RECT
\r
241 public uint bottom;
\r
244 [DllImport( "AVIFIL32" )]
\r
245 private static extern void AVIFileExit();
\r
246 [DllImport( "AVIFIL32" )]
\r
247 private static extern uint AVIFileGetStream( IntPtr pfile, out IntPtr ppavi, uint fccType, int lParam );
\r
248 [DllImport( "AVIFIL32" )]
\r
249 private static extern void AVIFileInit();
\r
250 [DllImport( "AVIFIL32" )]
\r
251 private static extern uint AVIFileOpen( out IntPtr ppfile, string szFile, OpenFileFlags mode, IntPtr pclsidHandler );
\r
252 [DllImport( "AVIFIL32" )]
\r
253 private static extern int AVIFileRelease( IntPtr pfile );
\r
254 [DllImport( "AVIFIL32" )]
\r
255 private static extern IntPtr AVIStreamGetFrame( IntPtr pgf, int lPos );
\r
256 [DllImport( "AVIFIL32" )]
\r
257 private static extern uint AVIStreamGetFrameClose( IntPtr pget );
\r
258 [DllImport( "AVIFIL32" )]
\r
259 private static extern IntPtr AVIStreamGetFrameOpen( IntPtr pavi, int lpbiWanted );
\r
260 [DllImport( "AVIFIL32" )]
\r
261 private static extern int AVIStreamInfo( IntPtr pavi, ref AVISTREAMINFO psi, int lSize );
\r
262 [DllImport( "AVIFIL32" )]
\r
263 private static extern int AVIStreamLength( IntPtr pavi );
\r
264 [DllImport( "AVIFIL32" )]
\r
265 private static extern int AVIStreamRelease( IntPtr pavi );
\r
266 //-----------------
\r
269 #region [ private ]
\r
270 //-----------------
\r
271 private IntPtr aviFile = IntPtr.Zero;
\r
272 private const string AVIFILE32 = "AVIFIL32";
\r
273 private const int AVIGETFRAMEF_BESTDISPLAYFMT = 1;
\r
274 private IntPtr aviStream = IntPtr.Zero;
\r
275 private bool bDispose完了済み;
\r
276 private IntPtr frame = IntPtr.Zero;
\r
277 private static readonly uint streamtypeAUDIO = mmioFOURCC( 'a', 'u', 'd', 's' );
\r
278 private static readonly uint streamtypeMIDI = mmioFOURCC( 'm', 'i', 'd', 's' );
\r
279 private static readonly uint streamtypeTEXT = mmioFOURCC( 't', 'x', 't', 's' );
\r
280 private static readonly uint streamtypeVIDEO = mmioFOURCC( 'v', 'i', 'd', 's' );
\r
282 private static uint mmioFOURCC( char c0, char c1, char c2, char c3 )
\r
284 return ( ( ( ( (uint) c3 << 0x18 ) | ( (uint) c2 << 0x10 ) ) | ( (uint) c1 << 8 ) ) | (uint) c0 );
\r
286 private void Release()
\r
288 if( this.aviStream != IntPtr.Zero )
\r
290 AVIStreamRelease( this.aviStream );
\r
291 this.aviStream = IntPtr.Zero;
\r
293 if( this.aviFile != IntPtr.Zero )
\r
295 AVIFileRelease( this.aviFile );
\r
296 this.aviFile = IntPtr.Zero;
\r
299 //-----------------
\r