private void ParseIdx1(BinaryReader br, uint chunk_size, int movi_start) { long start_pos = br.BaseStream.Position; AviStream video_stream = GetVideoStream(); while (br.BaseStream.Position - start_pos < chunk_size) { IndexEntry index_entry = new IndexEntry(); index_entry.ckid = ""; for (int i = 0; i < 4; ++i) { index_entry.ckid += (char)br.ReadByte(); } index_entry.flags = br.ReadUInt32(); index_entry.chunk_offset = movi_start + br.ReadInt32() + 8; index_entry.chunk_length = br.ReadInt32(); int stream_num = (index_entry.ckid[0] - '0') * 10 + (index_entry.ckid[1] - '0'); stream_list_[stream_num].IndexSet.Add(index_entry); } if (br.BaseStream.Position < start_pos + chunk_size) { br.BaseStream.Seek(start_pos + chunk_size, SeekOrigin.Begin); } }
// 全フレームを反転させてファイルに書き込む。ファイルOpen時に is_edit を true にする必要がある public void FlipAndWriteAll() { AviStream video_stream = GetVideoStream(); if (video_stream != null) { // ヘッダの高さがマイナス値になっている場合はプラスにする //(このようにしないとVFWで読めない) byte[] buff = new byte[1024]; file_stream_.Seek(0, SeekOrigin.Begin); file_stream_.Read(buff, 0, buff.Length); for (int i = 0; i < buff.Length - 20; ++i) { if (buff[i] == 's' && buff[i + 1] == 't' && buff[i + 2] == 'r' && buff[i + 3] == 'f') { int height = buff[i + 16] + buff[i + 17] * 256 + buff[i + 18] * 256 * 256 + buff[i + 19] * 256 * 256 * 256; if (height < 0) // 高さがマイナスの場合だけ修正する { file_stream_.Seek(i + 16, SeekOrigin.Begin); BinaryWriter writer = new BinaryWriter(file_stream_); writer.Write(-height); writer.Flush(); } } } // 各画像の上下を反転させる byte[] in_buff = new byte[video_stream.IndexSet[0].chunk_length]; byte[] out_buff = new byte[video_stream.IndexSet[0].chunk_length]; for (int i = 0; i < video_stream.GetLength(); ++i) { IndexEntry index_entry = video_stream.IndexSet[i]; file_stream_.Seek(index_entry.chunk_offset, SeekOrigin.Begin); file_stream_.Read(in_buff, 0, index_entry.chunk_length); for (int j = 0; j < in_buff.Length; ++j) { out_buff[(height_ - j / (3 * width_) - 1) * 3 * width_ + j % (3 * width_)] = in_buff[j]; } file_stream_.Seek(index_entry.chunk_offset, SeekOrigin.Begin); file_stream_.Write(out_buff, 0, index_entry.chunk_length); } } }
public Bitmap GetFrame(int frame_number) { AviStream video_stream = GetVideoStream(); if (video_stream != null && frame_number < video_stream.IndexSet.Count) { IndexEntry index_entry = video_stream.IndexSet[frame_number]; byte[] buff = new byte[index_entry.chunk_length]; file_stream_.Seek(index_entry.chunk_offset, SeekOrigin.Begin); file_stream_.Read(buff, 0, index_entry.chunk_length); GCHandle handle = GCHandle.Alloc(buff, GCHandleType.Pinned); Bitmap bitmap = new Bitmap(width_, height_, width_ * 3, PixelFormat.Format24bppRgb, handle.AddrOfPinnedObject()); handle.Free(); //bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); return(bitmap); } else { return(new Bitmap(1, 1)); } }
public void Parse(Stream stream) { BinaryReader br = new BinaryReader(stream); uint riff_size = ParseHeader(br); byte[] buff1 = new byte[1024]; int movi_start = 0; AviStream video_stream = null; long start = br.BaseStream.Position; if (riff_size == 0) { riff_size = uint.MaxValue; } while (br.BaseStream.Position - start < riff_size && br.BaseStream.Position < br.BaseStream.Length) { br.Read(buff1, 0, 4); if (Util.EqualsSubString(buff1, 0, 4, "LIST")) { long list_size = (long)br.ReadUInt32() - 4; br.Read(buff1, 0, 4); if (Util.EqualsSubString(buff1, 0, 4, "hdrl")) { ParseHdrl(br, (uint)list_size); } else if (Util.EqualsSubString(buff1, 0, 4, "movi")) { movi_start = (int)br.BaseStream.Position - 4; if (list_size > 0) { br.BaseStream.Seek((long)list_size, SeekOrigin.Current); } else { br.BaseStream.Seek(0, SeekOrigin.End); break; } } else { // 無視 br.BaseStream.Seek((long)list_size, SeekOrigin.Current); } } else // チャンクなら { uint chunk_size = br.ReadUInt32(); if (Util.EqualsSubString(buff1, 0, 4, "idx1")) { video_stream = GetVideoStream(); // AVI 2.0 の場合は解析する必要なし if (video_stream != null && !video_stream.IndexSet.HasSuperIndex()) { ParseIdx1(br, chunk_size, movi_start); } } else { br.BaseStream.Seek((long)chunk_size, SeekOrigin.Current); } } } video_stream = GetVideoStream(); if (video_stream != null) { // IndexEntry が無いときは "??dc" を探してエントリーを作る if (!video_stream.IndexSet.HasEntry()) { video_stream.IndexSet.MakeIndex(br, movi_start); } } }
public byte[] GetWave() { AviStream audio_stream = GetAudioStream(); return(audio_stream != null ? audio_stream.GetAllData(file_stream_) : null); }