WriteDWORD() public static method

integer(4)のDWORD値を4byte分ファイルに書き込みます
public static WriteDWORD ( uint number, BinaryWriter fp ) : void
number uint
fp System.IO.BinaryWriter
return void
Ejemplo n.º 1
0
        /// <summary>
        /// 指定したAVI_CONTAINER構造体にAVIファイルの情報を格納すると共に,
        /// ファイルにヘッダー情報を書き込みます.
        /// </summary>
        /// <param name="file">書き込み対象のファイル</param>
        /// <param name="frameRate">AVIファイルのフレームレート</param>
        // string file, uint scale, uint rate, int width, int height, IntPtr hwnd
        public bool Open(string file, uint scale, uint rate, int width, int height, IntPtr hwnd)
        {
            m_width       = width;
            m_height      = height;
            this.m_stream = new BinaryWriter(new FileStream(file, FileMode.Create, FileAccess.Write));
            float fps = (float)rate / (float)scale;

            this.m_main_header.dwMicroSecPerFrame = (uint)(1.0e6 / fps);//  ! 1秒は10^6μ秒
            this.m_main_header.dwReserved1        = 0;
            this.m_main_header.dwFlags            = 2064;
            this.m_main_header.dwInitialFrames    = 0;
            this.m_main_header.dwStreams          = 0;
            this.m_main_header.dwScale            = scale;
            this.m_main_header.dwRate             = rate;
            this.m_main_header.dwStart            = 0;
            this.m_main_header.dwLength           = 0;
            this.m_rate  = rate;
            this.m_scale = scale;
            //this.noOfFrame = 0;
            Util.fwrite("RIFF", this.m_stream);
            Util.WriteDWORD(0, this.m_stream);
            Util.fwrite("AVI ", this.m_stream);
            Util.fwrite("LIST", this.m_stream);
            Util.WriteDWORD(0x9cc, this.m_stream);
            Util.fwrite("hdrl", this.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;
            return(true);
        }
Ejemplo n.º 2
0
        public const int BMP_MAGIC_COOKIE    = 19778;  //ascii string "BM"

        /*// <summary>
         * /// 指定されたBITMAP型変数の情報ヘッダーをファイルに書き込みます.
         * /// </summary>
         * /// <param name="bmp"></param>
         * /// <param name="fp"></param>
         * public static void bmpWriteInfoHeader( BITMAPINFOHEADER infoHeader, BinaryWriter stream ) {
         *  //type(INFO_HEADER), intent(in) :: infoHeader
         *  //type(FILE), intent(inout) :: fp
         *  Util.WriteDWORD( (uint)infoHeader.biSize, stream );
         *  Util.WriteDWORD( (uint)infoHeader.biWidth, stream );
         *  Util.WriteDWORD( (uint)infoHeader.biHeight, stream );
         *  Util.WriteWORD( (ushort)infoHeader.biPlanes, stream );
         *  Util.WriteWORD( (ushort)(infoHeader.biBitCount), stream );
         *  Util.WriteDWORD( (uint)infoHeader.biCompression, stream );
         *  Util.WriteDWORD( (uint)infoHeader.biSizeImage, stream );
         *  Util.WriteDWORD( (uint)infoHeader.biXPelsPerMeter, stream );
         *  Util.WriteDWORD( (uint)infoHeader.biYPelsPerMeter, stream );
         *  Util.WriteDWORD( (uint)infoHeader.biClrUsed, stream );
         *  Util.WriteDWORD( (uint)infoHeader.biClrImportant, stream );
         * }*/


        /// <summary>
        /// ファイルにAVIStreamHeader構造体の値を書き込みます
        /// </summary>
        public static void aviWriteStreamHeader(AVIStreamHeader streamHeader, MainAVIHeader mainHeader, BinaryWriter stream)
        {
            //type(AVI_CONTAINER), intent(inout) :: avi
            Util.fwrite("strh", stream);
            Util.WriteDWORD(56, stream);  // call bmpQWordWrite( 56, avi%fp )    !// AVIStreamHeaderのサイズ
            //fwrite( streamHeader.fccType, fp );// i = fwrite( avi%streamHeader%fccType, 1, 4, avi%fp )
            Util.WriteDWORD((uint)streamHeader.fccType, stream);
            //fwrite( streamHeader.fccHandler, fp );//            i = fwrite( streamHeader.fccHandler, 1, 4, fp );
            Util.WriteDWORD((uint)streamHeader.fccHandler, stream);
            //WriteDWORD( 0, fp );
            Util.WriteDWORD(streamHeader.dwFlags, stream);
            //WriteDWORD( streamHeader.dwReserved1, fp );
            Util.WriteWORD(0, stream);  //wPriority
            Util.WriteWORD(0, stream);  //wLanghage
            Util.WriteDWORD(streamHeader.dwInitialFrames, stream);
            Util.WriteDWORD(streamHeader.dwScale, stream);
            Util.WriteDWORD(streamHeader.dwRate, stream);
            Util.WriteDWORD(streamHeader.dwStart, stream);
            Util.WriteDWORD(streamHeader.dwLength, stream);
            Util.WriteDWORD(streamHeader.dwSuggestedBufferSize, stream);
            Util.WriteDWORD(streamHeader.dwQuality, stream);
            Util.WriteDWORD(streamHeader.dwSampleSize, stream);
            Util.WriteWORD(0, stream);                           //left
            Util.WriteWORD(0, stream);                           //top
            Util.WriteWORD((ushort)mainHeader.dwWidth, stream);  //right
            Util.WriteWORD((ushort)mainHeader.dwHeight, stream); //bottom
        }
Ejemplo n.º 3
0
 public void Write(BinaryWriter fp)
 {
     Util.fwrite(fcc, fp);
     Util.WriteDWORD((uint)cb, fp);
     Util.WriteWORD(wLongsPerEntry, fp);
     Util.WriteBYTE(bIndexSubType, fp);
     Util.WriteBYTE(bIndexType, fp);
     Util.WriteDWORD((uint)nEntriesInUse, fp);
     Util.fwrite(dwChunkId, fp);
     Util.WriteQWORD((ulong)qwBaseOffset, fp);
     Util.WriteDWORD((uint)dwReserved3, fp);
     foreach (_avistdindex_entry entry in aIndex)
     {
         Util.WriteDWORD((uint)entry.dwOffset, fp);
         Util.WriteDWORD((uint)entry.dwSize, fp);
     }
 }
Ejemplo n.º 4
0
 public void Write(BinaryWriter fp)
 {
     Util.fwrite(fcc, fp);
     Util.WriteDWORD((uint)cb, fp);  //ここほんとは(int)cb
     Util.WriteWORD(wLongsPerEntry, fp);
     Util.WriteBYTE(bIndexSubType, fp);
     Util.WriteBYTE(bIndexType, fp);
     Util.WriteDWORD((uint)nEntriesInUse, fp);
     Util.fwrite(dwChunkId, fp);
     Util.WriteDWORD((uint)dwReserved1, fp);
     Util.WriteDWORD((uint)dwReserved2, fp);
     Util.WriteDWORD((uint)dwReserved3, fp);
     foreach (_avisuperindex_entry entry in aIndex)
     {
         Util.WriteQWORD((ulong)entry.qwOffset, fp);
         Util.WriteDWORD((uint)entry.dwSize, fp);
         Util.WriteDWORD((uint)entry.dwDuration, fp);
     }
 }
Ejemplo n.º 5
0
 /// <summary>
 /// ファイルにMainAviHeader構造体の値を書き込みます
 /// </summary>
 public static void aviWriteMainHeader(MainAVIHeader mainHeader, BinaryWriter stream)
 {
     //type(AVI_CONTAINER), intent(inout) :: avi
     Util.fwrite("avih", stream);  //    i = fwrite( 'avih', 1, 4, avi%fp )
     Util.WriteDWORD(56, stream);  // MainAVIHeaderのサイズ
     Util.WriteDWORD(mainHeader.dwMicroSecPerFrame, stream);
     Util.WriteDWORD(0 /*this.mainHeader.dwMaxBytesPerSec*/, stream);
     Util.WriteDWORD(mainHeader.dwReserved1, stream);
     Util.WriteDWORD(mainHeader.dwFlags, stream);
     Util.WriteDWORD(mainHeader.dwTotalFrames, stream);
     Util.WriteDWORD(mainHeader.dwInitialFrames, stream);
     Util.WriteDWORD(mainHeader.dwStreams, stream);
     Util.WriteDWORD(0 /*this.mainHeader.dwSuggestedBufferSize*/, stream);
     Util.WriteDWORD(mainHeader.dwWidth, stream);
     Util.WriteDWORD(mainHeader.dwHeight, stream);
     Util.WriteDWORD(mainHeader.dwScale, stream);
     Util.WriteDWORD(mainHeader.dwRate, stream);
     Util.WriteDWORD(mainHeader.dwStart, stream);
     Util.WriteDWORD(mainHeader.dwLength, stream);
 }//end subroutine
Ejemplo n.º 6
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
Ejemplo n.º 7
0
        /*[Obsolete]
         * public void Open( string file, float frameRate ) {
         *  uint scale, rate;
         *  AviWriter.CalcScaleAndRate( (decimal)frameRate, out scale, out rate );
         *  Open( file, scale, rate );
         * }*/


        //todo: AVIMainHeader.dwTotalFramesに、ファイル全体のフレーム数を入れる(仕様違反)
        //todo: AVIStreamHeader.dwLengthに、ファイル全体のフレーム数を入れる(仕様違反)
        /// <summary>
        /// 全てのインデックスを更新し、ファイルが(動画ファイルとして)使用できる状態にします
        /// この関数を読んだあとでも,さらにaviAddFrame関数を使うことでフレームを追加することが出来ます.
        /// </summary>
        public void UpdateIndex()
        {
            _avisuperindex_entry entry = m_super_index.aIndex[m_current_chunk];

            entry.qwOffset = (ulong)m_stream.BaseStream.Position;
            entry.dwSize   = m_std_index.cb;
            m_super_index.aIndex[m_current_chunk] = entry;
            if (m_stream.BaseStream.Position != m_next_framedata_position)
            {
                m_stream.BaseStream.Seek(m_next_framedata_position, SeekOrigin.Begin);
            }
            m_std_index.Write(m_stream);
            int frames = (int)m_super_index.aIndex[m_current_chunk].dwDuration;

            m_avix_position = m_stream.BaseStream.Position;

            if (m_current_chunk == 0)
            {
                uint i, step, number;
                step = this.m_main_header.dwSuggestedBufferSize + 8;

                Util.fwrite("idx1", this.m_stream);
                Util.WriteDWORD((uint)(16 * frames), this.m_stream);
                for (i = 1; i <= frames; i++)
                {
                    Util.fwrite("00db", this.m_stream);
                    Util.WriteDWORD(Util.AVIF_HASINDEX, this.m_stream);
                    Util.WriteDWORD((uint)(4 + (i - 1) * step), this.m_stream);
                    Util.WriteDWORD(this.m_main_header.dwSuggestedBufferSize, this.m_stream);
                }//    end do
                m_avix_position = m_stream.BaseStream.Position;

                number = (uint)frames;
                //avi_writeIsolate( this.fp, number, 48 );    // AVIMainHeader.dwTotalFrames
                m_stream.Seek(48, SeekOrigin.Begin);
                Util.WriteDWORD(number, m_stream);
                //avi_writeIsolate( this.fp, number, 140 );   // AVIStreamHeader.dwLength
                m_stream.Seek(140, SeekOrigin.Begin);
                Util.WriteDWORD(number, m_stream);

                //odml dlmhのdwTotalFrames
                m_stream.Seek(0x8e8, SeekOrigin.Begin);
                Util.WriteDWORD((uint)frames, m_stream);

                // LIST****moviの****の数値を計算
                number  = 4;                                                          //"movi"
                number += (uint)(frames * (m_linesize * m_main_header.dwHeight + 8)); //フレーム数*(フレームのサイズ+"00db"+00dbチャンクのサイズ)
                number += 4 + 4 + (uint)m_std_index.cb;                               //ix00のサイズ
                //number += 4 + 4 + 16 * frames;//idx1のサイズ
                //avi_writeIsolate( this.fp, number, 2040 );  // LIST****movi の ****部分
                m_stream.BaseStream.Seek(m_movi_position, SeekOrigin.Begin);
                Util.WriteDWORD(number, m_stream);

                //number = 4096 + (this.mainHeader.dwSuggestedBufferSize + 24) * this.noOfFrame;
                //avi_writeIsolate( this.fp, number, 4 );     // RIFF****AVI  の ****部分
                number  = (uint)m_junk_length /* 0xff4*/;                             //JUNKの終わりまでのサイズ。これは固定
                number += 4;                                                          //"movi"
                number += (uint)(frames * (m_linesize * m_main_header.dwHeight + 8)); //00db...の合計サイズ
                number += 4 + 4 + (uint)m_std_index.cb;
                number += (uint)(4 + 4 + 16 * frames);                                //idx1のサイズ
                m_stream.BaseStream.Seek(m_riff_position, SeekOrigin.Begin);
                Util.WriteDWORD(number, m_stream);
                UpdateIndexOfIndex();
            }
            else
            {
                // LIST****moviの****を更新
                int number = 4;
                number += (int)(frames * (m_linesize * m_main_header.dwHeight + 8));
                number += 8 + (int)m_std_index.cb;
                m_stream.BaseStream.Seek(m_movi_position, SeekOrigin.Begin);
                Util.WriteDWORD((uint)number, m_stream);

                // odml dlmhのdwTotalFrames
                uint frames2 = 0;
                for (int j = 0; j <= m_current_chunk; j++)
                {
                    frames2 += (uint)m_super_index.aIndex[j].dwDuration;
                }
                m_stream.BaseStream.Seek(0x8e8, SeekOrigin.Begin);
                Util.WriteDWORD(frames2, m_stream);

                //avi_writeIsolate( this.fp, number, 48 );    // AVIMainHeader.dwTotalFrames
                m_stream.Seek(48, SeekOrigin.Begin);
                Util.WriteDWORD(frames2, m_stream);

                //avi_writeIsolate( this.fp, number, 140 );   // AVIStreamHeader.dwLength
                m_stream.Seek(140, SeekOrigin.Begin);
                Util.WriteDWORD(frames2, m_stream);

                //RIFF****AVIXの****を更新
                long num2 = m_junk_length + number;
                m_stream.BaseStream.Seek(m_riff_position, SeekOrigin.Begin);
                Util.WriteDWORD((uint)num2, m_stream);
                UpdateIndexOfIndex();
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// aviファイルにフレームを1つ追加します.
        /// </summary>
        /// <param name="bmp"></param>
        public unsafe void AddFrame(Bitmap bmp)
        {
            int        width, height, lineSize;
            BitmapData bmpDat;

            if (m_is_transparent)
            {
                bmpDat = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
                                      ImageLockMode.ReadOnly,
                                      PixelFormat.Format32bppArgb);
            }
            else
            {
                bmpDat = bmp.LockBits(new Rectangle(0, 0, (int)bmp.Width, (int)bmp.Height),
                                      ImageLockMode.ReadOnly,
                                      PixelFormat.Format24bppRgb);
            }

            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 ((m_current_chunk == 0 && chunk_size > m_split_sreshold) ||
                (m_current_chunk > 0 && chunk_size > _THRESHOLD))
            {
                // AVIXリストへの書き込みに移行
                UpdateIndex();
                m_stream.BaseStream.Seek(m_avix_position, SeekOrigin.Begin);
                Util.fwrite("RIFF", m_stream);
                m_riff_position = m_stream.BaseStream.Position;
                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)m_main_header.dwWidth;
            height = (int)m_main_header.dwHeight;
            if (width != bmpDat.Width)
            {
                return;
            }
            if (height != bmpDat.Height)
            {
                return;
            }
            lineSize = bmpDat.Stride;

            if (m_compressed)
            {
                int is_key_frame = 0;
                int size         = bmpDat.Stride * bmpDat.Height;
                try {
                    IntPtr dat = VCM.ICSeqCompressFrame(m_compvar, 0, bmpDat.Scan0, &is_key_frame, &size);
                    if (!dat.Equals(IntPtr.Zero))
                    {
                        byte[] ndat = new byte[size];
                        Marshal.Copy(dat, ndat, 0, size);
                        m_std_index.AddIndex((uint)((ulong)m_stream.BaseStream.Position - m_std_index.qwBaseOffset) + 8, (uint)size);
                        Util.fwrite("00db", m_stream);
                        Util.WriteDWORD((uint)size, m_stream);
                        m_stream.Write(ndat, 0, size);
                        m_this_movi_size += size;
                    }
                } catch {
                }
            }
            else
            {
                m_std_index.AddIndex((uint)((ulong)m_stream.BaseStream.Position - m_std_index.qwBaseOffset) + 8, (uint)(lineSize * height));
                Util.fwrite("00db", m_stream);
                int    address    = bmpDat.Scan0.ToInt32();
                byte[] bitmapData = new byte[bmpDat.Stride * bmpDat.Height];
                Marshal.Copy(new IntPtr(address), bitmapData, 0, bitmapData.Length);
                Util.WriteDWORD(m_main_header.dwSuggestedBufferSize, m_stream);
                m_stream.Write(bitmapData);
                m_this_movi_size += bitmapData.Length;
            }
            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;
            m_stream.Flush();
            bmp.UnlockBits(bmpDat);
        }
Ejemplo n.º 9
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);
        }