Write() public method

public Write ( BinaryWriter bw ) : void
bw System.IO.BinaryWriter
return void
Example #1
0
        /// <summary>
        /// 指定したAVI_CONTAINER構造体にAVIファイルの情報を格納すると共に,
        /// ファイルにヘッダー情報を書き込みます.
        /// </summary>
        /// <param name="file">書き込み対象のファイル</param>
        /// <param name="scale"></param>
        /// <param name="rate"></param>
        /// <param name="compressed"></param>
        public unsafe bool Open( string file, uint scale, uint rate, int width, int height, bool compressed, bool transparent, IntPtr hWnd ) {
#if DEBUG
            Console.WriteLine( "AviWriterEx.Open(string,uint,uint,bool,IntPtr)" );
#endif
            m_stream = new BinaryWriter( new FileStream( file, FileMode.Create, FileAccess.Write ) );
            float fps = (float)rate / (float)scale;
            m_main_header.dwMicroSecPerFrame = (uint)(1.0e6 / fps);//  ! 1秒は10^6μ秒
            m_main_header.dwReserved1 = 0;
            m_main_header.dwFlags = 2064;
            m_main_header.dwInitialFrames = 0;
            m_main_header.dwStreams = 0;
            m_main_header.dwScale = scale;
            m_main_header.dwRate = rate;
            m_main_header.dwStart = 0;
            m_main_header.dwLength = 0;
            m_rate = rate;
            m_scale = scale;
            Util.fwrite( "RIFF", m_stream );
            Util.WriteDWORD( 0, m_stream );
            Util.fwrite( "AVI ", m_stream );
            Util.fwrite( "LIST", m_stream );
            Util.WriteDWORD( 0x9cc, m_stream );
            Util.fwrite( "hdrl", m_stream );
            m_current_chunk = 0;
            m_position_in_chunk = 0L;
            m_std_index = new AVISTDINDEX( 0L );
            m_super_index = new AVISUPERINDEX( 0 );
            m_riff_position = 0x4;
            m_compressed = compressed;
            m_is_transparent = transparent;
            m_stream_fcc_handler = 0;
            m_hwnd = hWnd;
            m_file = file;
            m_opened = true;
            if ( m_is_first ) {
                int stride = 0;
                using ( Bitmap b = new Bitmap( width, height, m_is_transparent ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb ) ) {
                    BitmapData bd = b.LockBits( new Rectangle( 0, 0, width, height ),
                                                ImageLockMode.ReadOnly,
                                                b.PixelFormat );
                    stride = bd.Stride;
                    b.UnlockBits( bd );
                }
                m_is_first = false;
                m_main_header.dwWidth = (uint)width;
                m_main_header.dwHeight = (uint)height;
                m_main_header.dwMaxBytesPerSec = (uint)(stride * height * frameRate);
                m_main_header.dwStreams = 1;
                m_main_header.dwSuggestedBufferSize = (uint)(stride * height);
                m_linesize = stride;

                m_stream_header.fccType = Util.mmioFOURCC( "vids" );
                m_stream_header.fccHandler = 0;
                m_stream_header.dwFlags = 0;
                m_stream_header.dwReserved1 = 0;
                m_stream_header.dwInitialFrames = 0;
                m_stream_header.dwScale = m_scale;
                m_stream_header.dwRate = m_rate;
                m_stream_header.dwStart = 0;
                m_stream_header.dwSuggestedBufferSize = m_main_header.dwSuggestedBufferSize;
                m_stream_header.dwQuality = 0;
                m_stream_header.dwSampleSize = 0;

                Util.aviWriteMainHeader( m_main_header, m_stream );

                Util.fwrite( "LIST", m_stream );
                Util.WriteDWORD( 0x874, m_stream );
                Util.fwrite( "strl", m_stream );

                Util.aviWriteStreamHeader( m_stream_header, m_main_header, m_stream );

                Util.fwrite( "strf", m_stream );
                BITMAPINFOHEADER bih = new BITMAPINFOHEADER(); //(BITMAPINFOHEADER)Marshal.PtrToStructure( Marshal.AllocHGlobal( sizeof( BITMAPINFOHEADER ) ), typeof( BITMAPINFOHEADER ) );
                bih.biSize = (uint)(Marshal.SizeOf( bih ));
                bih.biWidth = width;
                bih.biHeight = height;
                bih.biPlanes = 1;
                bih.biBitCount = m_is_transparent ? (short)32 : (short)24;
                bih.biCompression = 0;//BI_RGB
                bih.biSizeImage = (uint)(stride * height);
                bih.biXPelsPerMeter = 0;
                bih.biYPelsPerMeter = 0;
                bih.biClrUsed = 0;
                bih.biClrImportant = 0;

                if ( m_compressed ) {
                    m_p_compvar = Marshal.AllocHGlobal( sizeof( COMPVARS ) );
                    m_compvar = (COMPVARS*)m_p_compvar.ToPointer();
                    byte[] buf = new byte[sizeof( COMPVARS )];
                    for ( int i = 0; i < buf.Length; i++ ) {
                        buf[i] = 0x0;
                    }
                    Marshal.Copy( buf, 0, m_p_compvar, buf.Length );
                    m_compvar->cbSize = sizeof( COMPVARS );
                    int ret = VCM.ICCompressorChoose( m_hwnd, 0, IntPtr.Zero, IntPtr.Zero, m_compvar, "Select Video Compressor" );
                    if ( ret == 0 ) {
                        m_opened = false;
                        Marshal.FreeHGlobal( m_p_compvar );
                        m_stream.Close();
                        return false;
                    }
                    if ( m_compvar->hic != 0 ) {
                        m_p_bitmapinfo_in = Marshal.AllocHGlobal( sizeof( BITMAPINFO ) );
                        m_bitmapinfo_in = (BITMAPINFO*)m_p_bitmapinfo_in.ToPointer();
                        buf = new byte[sizeof( BITMAPINFO )];
                        for ( int i = 0; i < buf.Length; i++ ) {
                            buf[i] = 0x0;
                        }
                        Marshal.Copy( buf, 0, m_p_bitmapinfo_in, buf.Length );
                        m_bitmapinfo_in->bmiHeader = bih;
                        uint dwSize = VCM.ICCompressGetFormatSize( m_compvar->hic, m_bitmapinfo_in );
#if DEBUG
                        Console.WriteLine( "m_compvar->hic=" + m_compvar->hic );
                        Console.WriteLine( "ICCompressGetFormatSize=" + dwSize );
#endif
                        m_p_bitmapinfo_out = Marshal.AllocHGlobal( (int)dwSize );
                        m_bitmapinfo_out = (BITMAPINFO*)m_p_bitmapinfo_out.ToPointer();
                        buf = new byte[dwSize];
                        for ( int i = 0; i < buf.Length; i++ ) {
                            buf[i] = 0x0;
                        }
                        Marshal.Copy( buf, 0, m_p_bitmapinfo_out, buf.Length );
                        VCM.ICCompressGetFormat( m_compvar->hic, m_bitmapinfo_in, m_bitmapinfo_out );
                        m_bih_compression = m_bitmapinfo_out->bmiHeader.biCompression;
#if DEBUG
                        Console.WriteLine( "AddFrame(Bitmap)" );
                        Console.WriteLine( "    biout.biSize=" + m_bitmapinfo_out->bmiHeader.biSize );
#endif
                        VCM.ICSeqCompressFrameStart( m_compvar, m_bitmapinfo_in );
                        bih = m_bitmapinfo_out->bmiHeader;
                        Util.WriteDWORD( bih.biSize, m_stream );// infoHeaderのサイズ
                        m_bitmapinfo_out->Write( m_stream );
                    } else {
                        m_compressed = false;
                        Util.WriteDWORD( bih.biSize, m_stream );// infoHeaderのサイズ
                        bih.Write( m_stream );
                    }
                } else {
                    Util.WriteDWORD( bih.biSize, m_stream );// infoHeaderのサイズ
                    bih.Write( m_stream );
                }

                m_super_index_position = m_stream.BaseStream.Position;
                Util.fwrite( "indx", m_stream );          //fcc
                Util.WriteDWORD( 0x7f8, m_stream );       // cb
                Util.WriteWORD( (byte)0x4, m_stream );    // wLongsPerEntry
                Util.WriteBYTE( 0x0, m_stream );          // bIndexSubType
                Util.WriteBYTE( Util.AVI_INDEX_OF_INDEXES, m_stream );// bIndexType
                Util.WriteDWORD( 0x0, m_stream );         // nEntriesInUse
                Util.fwrite( "00db", m_stream );          // dwChunkId
                Util.WriteDWORD( 0x0, m_stream );
                Util.WriteDWORD( 0x0, m_stream );
                Util.WriteDWORD( 0x0, m_stream );
                for ( int ii = 1; ii <= 126; ii++ ) {
                    Util.WriteQWORD( 0x0, m_stream );
                    Util.WriteDWORD( 0x0, m_stream );
                    Util.WriteDWORD( 0x0, m_stream );
                }

                Util.fwrite( "LIST", m_stream );
                Util.WriteDWORD( 0x104, m_stream );
                Util.fwrite( "odml", m_stream );
                Util.fwrite( "dmlh", m_stream );
                Util.WriteDWORD( 0xf8, m_stream );
                Util.WriteDWORD( 0x0, m_stream );//ここ後で更新するべき
                for ( int ii = 1; ii <= 61; ii++ ) {
                    Util.WriteDWORD( 0x0, m_stream );
                }

                Util.fwrite( "JUNK", m_stream );
                Util.WriteDWORD( 0x60c, m_stream );
                Util.WriteDWORD( 0, m_stream );//"This"が将来登録されたらやばいので
                string msg = "This file was generated by [email protected];VfwBugCompatible=" + VfwBugCompatible;
                const int tlen = 1544;
                int remain = tlen - msg.Length;
                Util.fwrite( msg, m_stream );
                for ( int i = 1; i <= remain; i++ ) {
                    m_stream.Write( (byte)0 );
                }
                m_junk_length = 0xff4;

                Util.fwrite( "LIST", m_stream );
                m_movi_position = m_stream.BaseStream.Position;
                Util.WriteDWORD( 0, m_stream );// call bmpQWordWrite( 0, avi%fp )     !// ******************ココの数字は一番最後に書き換える必要あり2040~2043あとdwTotalFrames(48~51)も
                Util.fwrite( "movi", m_stream );
                m_next_framedata_position = m_stream.BaseStream.Position;

                m_std_index.SetBaseOffset( (ulong)m_next_framedata_position );
                m_super_index.nEntriesInUse++;
            }
            return true;
        }
Example #2
0
        /// <summary>
        /// aviファイルにフレームを1つ追加します.
        /// </summary>
        /// <param name="bmp"></param>
        public void AddFrame( Bitmap bmp ) {
            int i, width, height, lineSize;

            if ( bmp.Width != m_width || bmp.Height != m_height ) {
                throw new Exception( "bitmap size mismatch" );
            }

            // BitmapDataからビットマップデータと、BITMPAINFOHEADERを取り出す
            BitmapData bmpDat = bmp.LockBits(
                    new Rectangle( 0, 0, (int)bmp.Width, (int)bmp.Height ), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb );
            int address = bmpDat.Scan0.ToInt32();
            byte[] bitmapData = new byte[bmpDat.Stride * bmpDat.Height];
            Marshal.Copy( new IntPtr( address ), bitmapData, 0, bitmapData.Length );

            if ( m_is_first ) {//then
                m_is_first = false;
                this.m_main_header.dwWidth = (uint)m_width;
                this.m_main_header.dwHeight = (uint)m_height;
                this.m_main_header.dwMaxBytesPerSec = (uint)(bmpDat.Stride * bmpDat.Height * this.frameRate);// bmp%infoHeader%SizeImage * avi%frameRate
                this.m_main_header.dwStreams = 1;
                this.m_main_header.dwSuggestedBufferSize = (uint)(bmpDat.Stride * bmpDat.Height);// bmp.infoHeader%SizeImage
                m_linesize = bmpDat.Stride;

                this.m_stream_header.fccType = Util.mmioFOURCC( "vids" );
                this.m_stream_header.fccHandler = 0;
                this.m_stream_header.dwFlags = 0;
                this.m_stream_header.dwReserved1 = 0;
                this.m_stream_header.dwInitialFrames = 0;
                this.m_stream_header.dwScale = m_scale;
                this.m_stream_header.dwRate = m_rate;
                this.m_stream_header.dwStart = 0;
                this.m_stream_header.dwSuggestedBufferSize = this.m_main_header.dwSuggestedBufferSize;
                this.m_stream_header.dwQuality = 0;
                this.m_stream_header.dwSampleSize = 0;

                Util.aviWriteMainHeader( m_main_header, m_stream );

                Util.fwrite( "LIST", this.m_stream );// i = fwrite( 'LIST', 1, 4, avi%fp )
                Util.WriteDWORD( 0x874, this.m_stream );// call bmpQWordWrite( 130, avi%fp )
                Util.fwrite( "strl", this.m_stream );// i = fwrite( 'strl', 1, 4, avi%fp )

                Util.aviWriteStreamHeader( m_stream_header, m_main_header, m_stream );// avi )

                Util.fwrite( "strf", this.m_stream );// i = fwrite( 'strf', 1, 4, avi%fp )
                Util.WriteDWORD( 0x28, this.m_stream ); //call bmpQWordWrite( 40, avi%fp )    !// infoHeaderのサイズ
                BITMAPINFOHEADER bih = new BITMAPINFOHEADER();
                bih.biSize = (uint)(Marshal.SizeOf( bih ));
                bih.biWidth = bmpDat.Width;
                bih.biHeight = bmpDat.Height;
                bih.biPlanes = 1;
                bih.biBitCount = 24;
                bih.biCompression = 0;//BI_RGB
                bih.biSizeImage = (uint)(bmpDat.Stride * bmpDat.Height);
                bih.biXPelsPerMeter = 0;
                bih.biYPelsPerMeter = 0;
                bih.biClrUsed = 0;
                bih.biClrImportant = 0;
                bih.Write( m_stream );

                /*fwrite( "strn", this.fp );
                WriteDWORD( 6, this.fp );
                fwrite( "VIDEO", this.fp );
                WriteBYTE( 0, this.fp );*/
                Util.fwrite( "indx", this.m_stream );          //fcc
                Util.WriteDWORD( 0x7f8, this.m_stream );       // cb
                Util.WriteWORD( (byte)0x4, this.m_stream );    // wLongsPerEntry
                Util.WriteBYTE( 0x0, this.m_stream );          // bIndexSubType
                Util.WriteBYTE( Util.AVI_INDEX_OF_INDEXES, this.m_stream );// bIndexType
                Util.WriteDWORD( 0x0, this.m_stream );         // nEntriesInUse
                Util.fwrite( "00db", this.m_stream );          // dwChunkId
                Util.WriteDWORD( 0x0, this.m_stream );
                Util.WriteDWORD( 0x0, this.m_stream );
                Util.WriteDWORD( 0x0, this.m_stream );
                for ( int ii = 1; ii <= 126; ii++ ) {
                    Util.WriteQWORD( 0x0, this.m_stream );
                    Util.WriteDWORD( 0x0, this.m_stream );
                    Util.WriteDWORD( 0x0, this.m_stream );
                }

                Util.fwrite( "LIST", this.m_stream );
                Util.WriteDWORD( 0x104, m_stream );
                Util.fwrite( "odml", this.m_stream );
                Util.fwrite( "dmlh", m_stream );
                Util.WriteDWORD( 0xf8, m_stream );
                Util.WriteDWORD( 0x0, m_stream );//ここ後で更新するべき
                for ( int ii = 1; ii <= 61; ii++ ) {
                    Util.WriteDWORD( 0x0, m_stream );
                }

                Util.fwrite( "JUNK", this.m_stream );// i = fwrite( 'JUNK', 1, 4, avi%fp )
                Util.WriteDWORD( 0x60c, m_stream );
                Util.WriteDWORD( 0, m_stream );//"This"が将来登録されたらやばいので
                Util.fwrite( "This file was generated by RawAvi@LipSync", this.m_stream );
                //WriteDWORD( 1503, this.fp );// call bmpQWordWrite( 1802, avi%fp )
                for ( i = 1; i <= 1503; i++ ) {//do i = 1, 1802
                    this.m_stream.Write( (byte)0 );// call fputc( 0, avi%fp )
                }//end do
                m_junk_length = 0xff4;

                Util.fwrite( "LIST", this.m_stream );//      i = fwrite( 'LIST', 1, 4, avi%fp )
                m_movi_position = m_stream.BaseStream.Position;
                Util.WriteDWORD( 0, this.m_stream );// call bmpQWordWrite( 0, avi%fp )     !// ******************ココの数字は一番最後に書き換える必要あり2040~2043あとdwTotalFrames(48~51)も
                Util.fwrite( "movi", this.m_stream );// i = fwrite( 'movi', 1, 4, avi%fp )
                m_next_framedata_position = m_stream.BaseStream.Position;

                m_std_index.SetBaseOffset( (ulong)m_next_framedata_position );
                m_super_index.nEntriesInUse++;
            }//end if

            if ( m_next_framedata_position != m_stream.BaseStream.Position ) {
                m_stream.BaseStream.Seek( m_next_framedata_position, SeekOrigin.Begin );
            }

            long chunk_size = m_next_framedata_position - m_riff_position;
#if DEBUG
//            MessageBox.Show( "chunk_size=" + chunk_size );
#endif
            if ( (m_current_chunk == 0 && chunk_size > m_split_sreshold) ||
                 (m_current_chunk > 0 && chunk_size > SRESHOLD )) {
                // AVIXリストへの書き込みに移行
                UpdateIndex();
                m_stream.BaseStream.Seek( m_avix_position, SeekOrigin.Begin );
                Util.fwrite( "RIFF", m_stream );
                m_riff_position = m_stream.BaseStream.Position;
#if DEBUG
//                fp.Flush();
//                MessageBox.Show( "m_riff_position=" + m_riff_position );
#endif
                Util.WriteDWORD( 0, m_stream );
                Util.fwrite( "AVIX", m_stream );
                long current = m_stream.BaseStream.Position;
                if ( (current + 12) % 0x800 != 0 ) {
                    long additional = (current + 20) % 0x800;
                    additional = 0x800 - ((current + 20) % 0x800);
                    m_junk_length = (int)additional + 20;
                    Util.fwrite( "JUNK", m_stream );
                    Util.WriteDWORD( (uint)additional, m_stream );
                    for ( long ii = 0; ii < additional; ii++ ) {
                        Util.WriteBYTE( (byte)0, m_stream );
                    }
                } else {
                    m_junk_length = 0;
                }
                m_junk_length = 0;

                Util.fwrite( "LIST", m_stream );
                m_movi_position = m_stream.BaseStream.Position;
                Util.WriteDWORD( 0, m_stream );//後で更新するべき
                Util.fwrite( "movi", m_stream );
                m_next_framedata_position = m_stream.BaseStream.Position;
                m_std_index.aIndex.Clear();
                m_std_index.SetBaseOffset( (ulong)m_next_framedata_position );
                m_current_chunk++;
                m_super_index.nEntriesInUse++;
            }

            // フレームを書き込む処理
            width = (int)this.m_main_header.dwWidth;
            height = (int)this.m_main_header.dwHeight;
            if ( width != bmpDat.Width ) {//then
                //aviAddFrame = -1
                return;
            }//end if
            if ( height != bmpDat.Height ) {//then
                //aviAddframe = -1
                return;
            }//end if
            lineSize = bmpDat.Stride;// int( (width * 24 + 31) / 32 ) * 4

            m_std_index.AddIndex( (uint)((ulong)m_stream.BaseStream.Position - m_std_index.qwBaseOffset) + 8, (uint)(lineSize * height) );
            Util.fwrite( "00db", this.m_stream );//    i = fwrite( '00db', 1, 4, avi%fp )
            Util.WriteDWORD( m_main_header.dwSuggestedBufferSize, m_stream );// call bmpQWordWrite( avi%mainHeader%dwSuggestedBufferSize, avi%fp )
            m_stream.Write( bitmapData );
            m_next_framedata_position = m_stream.BaseStream.Position;
            _avisuperindex_entry entry = m_super_index.aIndex[m_current_chunk];
            entry.dwDuration++;
            m_super_index.aIndex[m_current_chunk] = entry;//    avi%noOfFrame = avi%noOfFrame + 1
            this.m_stream.Flush();// aviAddFrame = fflush( avi%fp )
            bmp.UnlockBits( bmpDat );
        }//  end function
Example #3
0
        private static void SaveCor( Bitmap item, Point hotspot, Stream stream, ushort type, Color transp ) {
            IconFileHeader ifh = new IconFileHeader();
            ifh.icoReserved = 0x0;
            ifh.icoResourceCount = 1;
            ifh.icoResourceType = type;
            ifh.Write( stream );
            IconInfoHeader iif = new IconInfoHeader();
            BITMAPINFOHEADER bih = new BITMAPINFOHEADER();
            iif.Width = (byte)item.Width;
            iif.Height = (byte)item.Height;
            iif.ColorCount = 0;
            iif.Reserved1 = 0;
            iif.Reserved2 = (ushort)hotspot.X;
            iif.Reserved3 = (ushort)hotspot.Y;
#if RGB24
            int linesize = ((item.Width * 24 + 31) / 32) * 4;
#else
            int linesize = ((item.Width * 32 + 31) / 32) * 4;
#endif
            int linesize_mask = ((item.Width * 1 + 31) / 32) * 4;
            int size = linesize * item.Height + linesize_mask * item.Height + 40;
#if DEBUG
            Console.WriteLine( "linesize=" + linesize );
#endif
            iif.icoDIBSize = (uint)size;
            iif.icoDIBOffset = 0x16;
            iif.Write( stream );
            bih.biSize = 40;
            bih.biWidth = item.Width;
#if RGB24
            bih.biHeight = item.Height * 2;
#else
            bih.biHeight = item.Height * 2;
#endif
            bih.biPlanes = 1;
#if RGB24
            bih.biBitCount = 24;
#else
            bih.biBitCount = 32;
#endif
            bih.biCompression = 0;
            bih.biSizeImage = (uint)(linesize * item.Height);
            bih.biXPelsPerMeter = 0;//            (int)(item.HorizontalResolution / 2.54e-2);
            bih.biYPelsPerMeter = 0;//            (int)(item.VerticalResolution / 2.54e-2);
            bih.biClrUsed = 0;
            bih.biClrImportant = 0;
            bih.Write( stream );
            for ( int y = item.Height - 1; y >= 0; y-- ) {
                int count = 0;
                for ( int x = 0; x < item.Width; x++ ) {
                    Color c = item.GetPixel( x, y );
                    stream.WriteByte( (byte)c.B );
                    stream.WriteByte( (byte)c.G );
                    stream.WriteByte( (byte)c.R );
#if DEBUG
                    if ( c.R != transp.R || c.G != transp.G || c.B != transp.B ) {
                        Console.WriteLine( "color=" + c );
                    }
#endif
#if RGB24
                    count += 3;
#else
                    stream.WriteByte( (byte)c.A );
                    count += 4;
#endif
                }
                for ( int i = count; i < linesize; i++ ) {
                    stream.WriteByte( 0x0 );
                }
            }

            for ( int y = item.Height - 1; y >= 0; y-- ) {
                int count = 0;
                byte v = 0x0;
                int tcount = 0;
                for ( int x = 0; x < item.Width; x++ ) {
                    Color c = item.GetPixel( x, y );
                    byte tr = 0x0;
                    if ( c.R == transp.R && c.G == transp.G && c.B == transp.B ){
                        tr = 0x1;
                    }
                    v = (byte)((byte)(v << 1) | (byte)(tr & 0x1));
                    tcount++;
                    if ( tcount == 8 ) {
                        stream.WriteByte( v );
                        count++;
                        tcount = 0;
                        v = 0x0;
                    }
                }
                if ( 0 < tcount ) {
                    v = (byte)(v << (9 - tcount));
                    stream.WriteByte( v );
                    count++;
                }
                for ( int i = count; i < linesize_mask; i++ ) {
                    stream.WriteByte( 0x0 );
                }
            }
        }