OSDN Git Service

リポジトリの中間ファイルをすべて削除し、再構築。
[dtxmania/dtxmania.git] / FDK17プロジェクト / コード / 04.グラフィック / CAvi.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Text;\r
4 using System.Runtime.InteropServices;\r
5 using System.Drawing;\r
6 using SlimDX;\r
7 \r
8 namespace FDK\r
9 {\r
10         public class CAvi : IDisposable\r
11         {\r
12                 // プロパティ\r
13 \r
14                 public uint dwスケール \r
15                 {\r
16                         get;\r
17                         set; \r
18                 }\r
19                 public uint dwレート\r
20                 {\r
21                         get;\r
22                         set;\r
23                 }\r
24                 public uint nフレーム高さ\r
25                 { \r
26                         get;\r
27                         set;\r
28                 }\r
29                 public uint nフレーム幅\r
30                 {\r
31                         get;\r
32                         set; \r
33                 }\r
34 \r
35 \r
36                 // コンストラクタ\r
37 \r
38                 public CAvi( string filename )\r
39                 {\r
40                         if( AVIFileOpen( out this.aviFile, filename, OpenFileFlags.OF_READ, IntPtr.Zero ) != 0 )\r
41                         {\r
42                                 this.Release();\r
43                                 throw new Exception( "AVIFileOpen failed." );\r
44                         }\r
45                         if( AVIFileGetStream( this.aviFile, out this.aviStream, streamtypeVIDEO, 0 ) != 0 )\r
46                         {\r
47                                 this.Release();\r
48                                 throw new Exception( "AVIFileGetStream failed." );\r
49                         }\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
56                         try\r
57                         {\r
58                                 this.frame = AVIStreamGetFrameOpen( this.aviStream, 0 );\r
59                         }\r
60                         catch\r
61                         {\r
62                                 this.Release();\r
63                                 throw new Exception( "AVIStreamGetFrameOpen failed." );\r
64                         }\r
65                 }\r
66 \r
67         \r
68                 // メソッド\r
69 \r
70                 public static void t初期化()\r
71                 {\r
72                         AVIFileInit();\r
73                 }\r
74                 public static void t終了()\r
75                 {\r
76                         AVIFileExit();\r
77                 }\r
78                 \r
79                 public Bitmap GetFrame( int no )\r
80                 {\r
81                         if( this.aviStream == IntPtr.Zero )\r
82                         {\r
83                                 throw new InvalidOperationException();\r
84                         }\r
85                         return BitmapUtil.ToBitmap( AVIStreamGetFrame( this.frame, no ) );\r
86                 }\r
87                 public int GetFrameNoFromTime( int time )\r
88                 {\r
89                         return (int) ( time * ( ( (double) this.dwレート ) / ( 1000.0 * this.dwスケール ) ) );\r
90                 }\r
91                 public IntPtr GetFramePtr( int no )\r
92                 {\r
93                         if( this.aviStream == IntPtr.Zero )\r
94                         {\r
95                                 throw new InvalidOperationException();\r
96                         }\r
97                         return AVIStreamGetFrame( this.frame, no );\r
98                 }\r
99                 public int GetMaxFrameCount()\r
100                 {\r
101                         if( this.aviStream == IntPtr.Zero )\r
102                         {\r
103                                 throw new InvalidOperationException();\r
104                         }\r
105                         return AVIStreamLength( this.aviStream );\r
106                 }\r
107                 \r
108                 public unsafe void tBitmap24ToGraphicsStreamR5G6B5( BitmapUtil.BITMAPINFOHEADER* pBITMAPINFOHEADER, DataStream gs, int nWidth, int nHeight )\r
109                 {\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
116                         {\r
117                                 if( i >= nHeight )\r
118                                 {\r
119                                         return;\r
120                                 }\r
121                                 for( int j = 0; j < num; j++ )\r
122                                 {\r
123                                         if( j >= nWidth )\r
124                                         {\r
125                                                 break;\r
126                                         }\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
131                                 }\r
132                         }\r
133                 }\r
134                 public unsafe void tBitmap24ToGraphicsStreamX8R8G8B8( BitmapUtil.BITMAPINFOHEADER* pBITMAPINFOHEADER, DataStream ds, int nWidth, int nHeight )\r
135                 {\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
142                         {\r
143                                 if( i >= nHeight )\r
144                                 {\r
145                                         return;\r
146                                 }\r
147                                 for( int j = 0; j < num; j++ )\r
148                                 {\r
149                                         if( j >= nWidth )\r
150                                         {\r
151                                                 break;\r
152                                         }\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
157                                 }\r
158                         }\r
159                 }\r
160 \r
161                 #region [ IDisposable+α 実装 ]\r
162                 //-----------------\r
163                 public void Dispose()\r
164                 {\r
165                         this.Dispose( true );\r
166                 }\r
167                 protected void Dispose( bool disposeManagedObjects )\r
168                 {\r
169                         if( !this.bDispose完了済み )\r
170                         {\r
171                                 if( this.frame != IntPtr.Zero )\r
172                                 {\r
173                                         AVIStreamGetFrameClose( this.frame );\r
174                                 }\r
175                                 this.Release();\r
176                                 this.bDispose完了済み = true;\r
177                         }\r
178                 }\r
179                 ~CAvi()\r
180                 {\r
181                         this.Dispose( false );\r
182                 }\r
183                 //-----------------\r
184                 #endregion\r
185 \r
186 \r
187                 // その他\r
188 \r
189                 #region [ Win32 AVI関連関数インポート ]\r
190                 //-----------------\r
191                 internal enum OpenFileFlags : uint\r
192                 {\r
193                         OF_CANCEL = 0x800,\r
194                         OF_CREATE = 0x1000,\r
195                         OF_DELETE = 0x200,\r
196                         OF_EXIST = 0x4000,\r
197                         OF_PARSE = 0x100,\r
198                         OF_PROMPT = 0x2000,\r
199                         OF_READ = 0,\r
200                         OF_READWRITE = 2,\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
207                         OF_VERIFY = 0x400,\r
208                         OF_WRITE = 1\r
209                 }\r
210 \r
211                 [StructLayout( LayoutKind.Sequential, Pack = 1 )]\r
212                 internal struct AVISTREAMINFO\r
213                 {\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
233                 }\r
234 \r
235                 [StructLayout( LayoutKind.Sequential, Pack = 1 )]\r
236                 internal struct RECT\r
237                 {\r
238                         public uint left;\r
239                         public uint top;\r
240                         public uint right;\r
241                         public uint bottom;\r
242                 }\r
243 \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
267                 #endregion\r
268 \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
281 \r
282                 private static uint mmioFOURCC( char c0, char c1, char c2, char c3 )\r
283                 {\r
284                         return ( ( ( ( (uint) c3 << 0x18 ) | ( (uint) c2 << 0x10 ) ) | ( (uint) c1 << 8 ) ) | (uint) c0 );\r
285                 }\r
286                 private void Release()\r
287                 {\r
288                         if( this.aviStream != IntPtr.Zero )\r
289                         {\r
290                                 AVIStreamRelease( this.aviStream );\r
291                                 this.aviStream = IntPtr.Zero;\r
292                         }\r
293                         if( this.aviFile != IntPtr.Zero )\r
294                         {\r
295                                 AVIFileRelease( this.aviFile );\r
296                                 this.aviFile = IntPtr.Zero;\r
297                         }\r
298                 }\r
299                 //-----------------\r
300                 #endregion\r
301         }\r
302 }\r