public override SoundInput TryOpen(IBinaryStream file) { var header = file.ReadHeader(0x23); int bits1_length = header.ToInt32(0x13); int bits2_length = header.ToInt32(0x17); var data = file.ReadBytes(bits1_length + bits2_length); CgfDecoder.Decrypt(data, bits1_length); int unpacked_length = header.ToInt32(5); uint sample_rate = header.ToUInt32(0xD); int sample_count = unpacked_length >> 1; var bits1 = new byte[(sample_count + 7) >> 3]; var bits2 = new byte[sample_count >> 1]; using (var mem = new MemoryStream(data, 4, bits1_length - 4)) using (var input = new ZLibStream(mem, CompressionMode.Decompress)) input.Read(bits1, 0, bits1.Length); using (var mem = new MemoryStream(data, bits1_length + 4, bits2_length - 4)) using (var input = new ZLibStream(mem, CompressionMode.Decompress)) input.Read(bits2, 0, bits2.Length); short init = header.ToInt16(0x11); var decoded = new short[sample_count]; DecodeAdp(bits2, decoded, sample_count, init); var output = new byte[unpacked_length]; byte bit = 0x80; int src = 0; int dst = 0; for (int i = 0; i < decoded.Length; ++i) { short sample = Math.Max(decoded[i], (short)0); if ((bit & bits1[src]) != 0) { sample = (short)-sample; } LittleEndian.Pack(sample, output, dst); dst += 2; bit >>= 1; if (0 == bit) { ++src; bit = 0x80; } } var format = new WaveFormat { FormatTag = 1, Channels = 1, SamplesPerSecond = sample_rate, BlockAlign = 2, BitsPerSample = 16, }; format.SetBPS(); var pcm = new MemoryStream(output); return(new RawPcmInput(pcm, format)); }
public byte[] ReadBytes(int count) { return(m_input.ReadBytes(count)); }
bool ReadHeader(bool encrypted) { m_input.Position = 4; m_version = m_input.ReadUInt16(); m_flags = m_input.ReadUInt16(); if (encrypted && m_version < 3) { m_flags = 2; } int header_size = m_version > 3 ? 0x30 : 0x20; var header = m_input.ReadBytes(header_size); if (encrypted && 0 != (m_flags & 1)) { if (m_version > 3) { Decrypt(header, 0, 0x24); Decrypt(header, 0x24, 0xC); } else { Decrypt(header, 0, 0x20); } } m_names = LittleEndian.ToInt32(header, 0x04); // 0x08 m_strings = LittleEndian.ToInt32(header, 0x08); // 0x0C m_strings_data = LittleEndian.ToInt32(header, 0x0C); // 0x10 m_chunk_offsets = LittleEndian.ToInt32(header, 0x10); // 0x14 m_chunk_lengths = LittleEndian.ToInt32(header, 0x14); // 0x18 m_chunk_data = LittleEndian.ToInt32(header, 0x18); // 0x1C m_root = LittleEndian.ToInt32(header, 0x1C); // 0x20 if (m_version > 3) { m_extra_offsets = LittleEndian.ToInt32(header, 0x24); m_extra_lengths = LittleEndian.ToInt32(header, 0x28); m_extra_data = LittleEndian.ToInt32(header, 0x2C); } int buffer_length = (int)m_input.Length; if (!(m_names >= 0x28 && m_names < m_chunk_data && m_strings >= 0x28 && m_strings < m_chunk_data && m_strings_data >= 0x28 && m_strings_data < m_chunk_data && m_chunk_offsets >= 0x28 && m_chunk_offsets < m_chunk_data && m_chunk_lengths >= 0x28 && m_chunk_lengths < m_chunk_data && m_chunk_data >= 0x28 && m_chunk_data <= buffer_length && m_root >= 0x28 && m_root < m_chunk_data)) { return(false); } if (null == m_data || m_data.Length < m_chunk_data) { m_data = new byte[m_chunk_data]; } int data_pos = (int)m_input.Position; m_input.Read(m_data, data_pos, m_chunk_data - data_pos); if (encrypted && 0 != (m_flags & 2)) { Decrypt(m_data, m_names, m_chunk_offsets - m_names); } // root object is a dictionary return(0x21 == m_data[m_root]); }
List <Sample> ReadSamples() { var header = m_input.ReadHeader(0x3C); int version = header.ToInt32(4); int sample_count = header.ToInt32(8); m_sample_header_size = header.ToInt32(0xC); m_name_table_size = header.ToInt32(0x10); m_data_size = header.ToInt32(0x14); m_format = (SoundFormat)header.ToInt32(0x18); if (!Supported.Contains(m_format)) { throw new NotSupportedException(); } if (0 == version) { m_input.ReadInt32(); } var samples = new List <Sample> (sample_count); m_header_size = (int)m_input.Position; for (int i = 0; i < sample_count; ++i) { long raw = m_input.ReadInt64(); bool next_chunk = 0 != (raw & 1); int sample_rate = (int)((raw >> 1) & 0xF); ushort channels = (ushort)(((raw >> 5) & 1) + 1); long data_offset = ((raw >> 6) & 0xFFFFFFF) * 0x10; int count = (int)((raw >> 34) & 0x3FFFFFFF); var chunks = new Dictionary <ChunkType, object>(); while (next_chunk) { int d = m_input.ReadInt32(); next_chunk = 0 != (d & 1); int chunk_size = (d >> 1) & 0xFFFFFF; var chunk_type = (ChunkType)((d >> 25) & 0x7F); object chunk; switch (chunk_type) { case ChunkType.Channels: chunk = m_input.ReadUInt8(); break; case ChunkType.SampleRate: chunk = m_input.ReadInt32(); break; case ChunkType.Loop: int v1 = m_input.ReadInt32(); int v2 = m_input.ReadInt32(); chunk = Tuple.Create(v1, v2); break; case ChunkType.VorbisData: chunk = new VorbisData { Crc32 = m_input.ReadUInt32(), Data = m_input.ReadBytes(chunk_size - 4) // XXX unused }; break; default: chunk = m_input.ReadBytes(chunk_size); break; } chunks[chunk_type] = chunk; } if (chunks.ContainsKey(ChunkType.SampleRate)) { sample_rate = (int)chunks[ChunkType.SampleRate]; } else if (SampleRates.ContainsKey(sample_rate)) { sample_rate = SampleRates[sample_rate]; } else { throw new InvalidFormatException("Invalid FSB5 sample rate."); } var sample = new Sample { SampleRate = sample_rate, Channels = channels, DataOffset = data_offset, SampleCount = count, MetaData = chunks, Data = null }; samples.Add(sample); } return(samples); }
public List <Entry> ReadIndex() { m_input.Position = 0x10; int n = 0; var type_buf = new byte[0x10]; while (0x10 == m_input.Read(type_buf, 0, 0x10)) { if (Binary.AsciiEqual(type_buf, "abdata")) { uint size = m_input.ReadUInt32(); var entry = new Entry { Name = string.Format("{0}#{1}.dat", m_base_name, n++), Offset = m_input.Position, Size = size, }; m_dir.Add(entry); Skip(size); } else if (Binary.AsciiEqual(type_buf, "abimage10\0") || Binary.AsciiEqual(type_buf, "absound10\0")) { int count = m_input.ReadByte(); for (int i = 0; i < count; ++i) { if (0x10 != m_input.Read(type_buf, 0, 0x10)) { break; } var tag = Binary.GetCString(type_buf, 0, 0x10, Encoding.ASCII); string name = null; if ("abimgdat15" == tag) { Skip(4); int name_length = m_input.ReadUInt16(); if (name_length > 0) { var name_bytes = m_input.ReadBytes(name_length * 2); name = Encoding.Unicode.GetString(name_bytes); } name_length = m_input.ReadUInt16(); if (name_length > 0) { if (string.IsNullOrEmpty(name)) { name = m_input.ReadCString(name_length); } else { Skip((uint)name_length); } } byte type = m_input.ReadUInt8(); /* * case 0: ".bmp" * case 1: ".jpg" * case 2: * case 3: ".png" * case 4: ".m" * case 5: ".argb" * case 6: ".b" * case 7: ".ogv" * case 8: ".mdl" */ Skip(0x11); } else { int name_length = m_input.ReadUInt16(); name = m_input.ReadCString(name_length); if (tag != "abimgdat10" && tag != "absnddat10") { Skip(m_input.ReadUInt16()); if ("abimgdat13" == tag) { Skip(0x0C); } else if ("abimgdat14" == tag) { Skip(0x4C); } } m_input.ReadByte(); } var size = m_input.ReadUInt32(); if (0 != size) { if (string.IsNullOrEmpty(name)) { name = string.Format("{0}#{1}", m_base_name, n++); } else { name = s_InvalidChars.Replace(name, "_"); } var entry = new Entry { Name = name, Type = tag.StartsWith("abimg") ? "image" : tag.StartsWith("absnd") ? "audio" : "", Offset = m_input.Position, Size = size, }; if (entry.CheckPlacement(m_file.MaxOffset)) { DetectFileType(m_file, entry); m_dir.Add(entry); } } Skip(size); } } else { var entry = new Entry { Name = string.Format("{0}#{1}#{2}", m_base_name, n++, GetTypeName(type_buf)), Offset = m_input.Position, Size = (uint)(m_file.MaxOffset - m_input.Position), }; m_dir.Add(entry); Skip(entry.Size); } } return(m_dir); }
protected byte[] ReadKey() { int key_length = m_input.ReadInt32(); return(m_input.ReadBytes(key_length)); }
void UnpackRefFrame(IBinaryStream input, byte[] output) { int header_size = input.ReadInt32(); if (header_size < 4) { throw new InvalidFormatException(); } var header = input.ReadBytes(header_size - 4); using (var chunks = new BinMemoryStream(header)) { int count = 0; int last = -1; int dst = 0; while (dst < output.Length) { int length = ReadInteger(chunks); if (-1 == length) { break; } while (length-- > 0) { if (0 == count) { input.Read(output, dst, 3); int color = output[dst] | output[dst + 1] << 8 | output[dst + 2] << 16; dst += 3; if (color == last) { count = ReadInteger(input); if (-1 == count) { return; } if (count > 2) { count -= 2; } else { count = 0; } } last = color; } else { count--; output[dst++] = (byte)last; output[dst++] = (byte)(last >> 8); output[dst++] = (byte)(last >> 16); } } length = ReadInteger(chunks); if (-1 == length) { break; } length = Math.Min(length * 3, output.Length - dst); dst += length; } } }
} // 'WPX' public override SoundInput TryOpen(IBinaryStream file) { var header = file.ReadHeader(0x10); if (!header.AsciiEqual(4, "WAV")) { return(null); } int count = header[0xE]; int dir_size = header[0xF]; if (1 != header[0xC] || 0 == count || 0 == dir_size) { return(null); } file.Position = 0x10; var index = file.ReadBytes(count * dir_size); var section = WpxSection.Find(index, 0x20, count, dir_size); if (null == section || section.UnpackedSize < 0x10 || section.DataFormat != 0x80) { throw new InvalidFormatException(); } file.Position = section.Offset; var fmt = file.ReadBytes(section.UnpackedSize); section = WpxSection.Find(index, 0x21, count, dir_size); if (null == section) { throw new InvalidFormatException(); } var reader = new WwaReader(file.AsStream, section); var data = reader.Unpack(section.DataFormat); if (null == data) { throw new InvalidFormatException(); } int total_size = 20 + fmt.Length + data.Length; using (var wav_file = new MemoryStream(20 + fmt.Length)) using (var wav = new BinaryWriter(wav_file)) { wav.Write(Wav.Signature); wav.Write(total_size); wav.Write(0x45564157); // 'WAVE' wav.Write(0x20746d66); // 'fmt ' wav.Write(fmt.Length); wav.Write(fmt); wav.Write(0x61746164); // 'data' wav.Write(data.Length); var wav_header = wav_file.ToArray(); var data_stream = new MemoryStream(data); var source = new PrefixStream(wav_header, data_stream); var sound = new WaveInput(source); file.Dispose(); return(sound); } }
public override ImageData Read(IBinaryStream file, ImageMetaData info) { var meta = (BjrMetaData)info; int height = (int)meta.Height; int stride = ((int)meta.Width * (meta.BPP / 8) + 3) & ~3; file.Position = meta.ImageOffset; var source = file.ReadBytes(stride * height); var name_bytes = Encodings.cp932.GetBytes(Path.GetFileName(meta.FileName)); int line_key = 0; int even_key = 0xFF; int odd_key = 0; for (int i = 0; i < name_bytes.Length; ++i) { line_key ^= name_bytes[i]; even_key += name_bytes[i]; odd_key -= name_bytes[i]; } var pixels = new byte[source.Length]; int dst = 0; for (int y = 0; y < height; ++y) { line_key += 7; int src = (line_key % height) * stride; for (int x = 0; x < stride; ++x) { if ((x & 1) == 0) { pixels[dst + x] = (byte)(even_key - source[src + x]); } else { pixels[dst + x] = (byte)(odd_key + source[src + x]); } } dst += stride; } PixelFormat format; if (24 == meta.BPP) { format = PixelFormats.Bgr24; } else if (32 == meta.BPP) { format = PixelFormats.Bgr32; } else // FIXME read palette { format = PixelFormats.Gray8; } if (meta.IsFlipped) { return(ImageData.CreateFlipped(info, format, null, pixels, stride)); } else { return(ImageData.Create(info, format, null, pixels, stride)); } }
/// <summary> /// Read <paramref name="length"/> bytes from stream and return them in a byte array. /// May return less than <paramref name="length"/> bytes if end of file was encountered. /// </summary> public byte[] ReadBytes(int length) { return(m_input.ReadBytes(length)); }
public List <Entry> ReadIndex() { if (!ArchiveFormat.IsSaneCount(Count)) { return(null); } var sections = ReadSections(m_section_count); var list = new List <Entry> (Count); foreach (var section in sections) { m_input.Position = section.IndexOffset; var dir_names = m_input.ReadBytes(section.DirNamesSize); if (section.DirNamesSize != dir_names.Length) { return(null); } byte section_key = dir_names[section.DirNameLength - 1]; DecryptNames(dir_names, section_key); var dirs = new TcdDirEntry[section.DirCount]; for (int i = 0; i < dirs.Length; ++i) { dirs[i].FileCount = m_input.ReadInt32(); dirs[i].NamesOffset = m_input.ReadInt32(); dirs[i].FirstIndex = m_input.ReadInt32(); m_input.ReadInt32(); } var file_names = m_input.ReadBytes(section.FileNamesSize); if (file_names.Length != section.FileNamesSize) { return(null); } DecryptNames(file_names, section_key); var offsets = new uint[section.FileCount + 1]; for (int i = 0; i < offsets.Length; ++i) { offsets[i] = m_input.ReadUInt32(); } int dir_name_offset = 0; foreach (var dir in dirs) { string dir_name = GetName(dir_names, section.DirNameLength, ref dir_name_offset); int index = dir.FirstIndex; int name_offset = dir.NamesOffset; for (int i = 0; i < dir.FileCount; ++i) { string name = GetName(file_names, section.FileNameLength, ref name_offset); name = Path.Combine(dir_name, name); name = Path.ChangeExtension(name, section.Extension); var entry = FormatCatalog.Instance.Create <TcdEntry> (name); entry.Offset = offsets[index]; entry.Size = offsets[index + 1] - offsets[index]; entry.Index = index; ++index; list.Add(entry); } } } return(list); }
public override ImageMetaData ReadMetaData(IBinaryStream file) { file.ReadUInt32(); if (file.ReadUInt32() != 0x0a1a0a0d) { return(null); } uint chunk_size = Binary.BigEndian(file.ReadUInt32()); byte[] chunk_type = file.ReadBytes(4); if (!Binary.AsciiEqual(chunk_type, "IHDR")) { return(null); } var meta = new ImageMetaData(); meta.Width = Binary.BigEndian(file.ReadUInt32()); meta.Height = Binary.BigEndian(file.ReadUInt32()); int bpp = file.ReadByte(); if (bpp != 1 && bpp != 2 && bpp != 4 && bpp != 8 && bpp != 16) { return(null); } int color_type = file.ReadByte(); switch (color_type) { case 2: meta.BPP = bpp * 3; break; case 3: meta.BPP = 24; break; case 4: meta.BPP = bpp * 2; break; case 6: meta.BPP = bpp * 4; break; case 0: meta.BPP = bpp; break; default: return(null); } SkipBytes(file, 7); for (;;) { chunk_size = Binary.BigEndian(file.ReadUInt32()); file.Read(chunk_type, 0, 4); if (Binary.AsciiEqual(chunk_type, "IDAT") || Binary.AsciiEqual(chunk_type, "IEND")) { break; } if (Binary.AsciiEqual(chunk_type, "oFFs")) { int x = Binary.BigEndian(file.ReadInt32()); int y = Binary.BigEndian(file.ReadInt32()); if (0 == file.ReadByte()) { meta.OffsetX = x; meta.OffsetY = y; } break; } SkipBytes(file, chunk_size + 4); } return(meta); }
void UnpackFlat() { var channel = new byte[m_width * m_height]; for (int i = 0; i < 3; ++i) { m_input.Position = bits_pos[i]; var bits = m_input.ReadBytes(bits_pos[i + 1] - bits_pos[i]); m_input.Position = data_pos[i]; if (1 == m_info.Method) { int bits_src = 0; int bit_mask = 0x80; int cdst = 0; while (cdst < channel.Length) { if (0 == bit_mask) { ++bits_src; bit_mask = 0x80; } if ((bits[bits_src] & bit_mask) != 0) { int offset = m_input.ReadUInt16(); int count = (offset & 0xF) + 3; offset = (offset >> 4) + 1; Binary.CopyOverlapped(channel, cdst - offset, cdst, count); cdst += count; } else { channel[cdst++] = m_input.ReadUInt8(); } bit_mask >>= 1; } } else if (2 == m_info.Method) { LzssUnpack(bits, 0, channel, channel.Length); } int dst = i; byte accum = 0; for (int csrc = 0; csrc < channel.Length; ++csrc) { accum += channel[csrc]; m_output[dst] = accum; dst += 4; } } if (4 == m_channels) { m_input.Position = data_pos[3]; int dst = 3; while (dst < m_output.Length) { byte a = m_input.ReadUInt8(); int count = 1; if (a == 0 || a == 0xFF) { count += m_input.ReadUInt8(); } while (count-- > 0) { m_output[dst] = a; dst += 4; } } } }
void UnpackV0() { Format = 3 == m_channels ? PixelFormats.Bgr24 : PixelFormats.Bgra32; m_stride = m_width * m_channels; m_output = m_input.ReadBytes(m_stride * m_height); }
public override ImageMetaData ReadMetaData(IBinaryStream stream) { var header = stream.ReadHeader(0x20); int type = header.ToUInt16(0x10); if (0x0C == type) { int count = header.ToInt32(0); if (!ArchiveFormat.IsSaneCount(count)) { return(null); } int block_size = header.ToInt32(4); if (block_size <= 0) { return(null); } int bpp = header.ToUInt16(0x12); uint width = header.ToUInt16(0x14); uint height = header.ToUInt16(0x16); if (bpp != 32 || 0 == width || 0 == height) { return(null); } return(new PxMetaData { Width = width, Height = height, BPP = bpp, Type = type, FrameCount = count, BlockSize = block_size, BlocksWidth = header.ToUInt16(0x1C), BlocksHeight = header.ToUInt16(0x1E), }); } else if (0x90 == type) { if (!header.AsciiEqual(0x14, "Leaf")) { return(null); } int count = header.ToInt32(4); if (!ArchiveFormat.IsSaneCount(count)) { return(null); } var header_ex = stream.ReadBytes(0x20); if (0x20 != header_ex.Length) { return(null); } if (0x0A != LittleEndian.ToUInt16(header_ex, 0x10)) { return(null); } return(new PxMetaData { Width = LittleEndian.ToUInt32(header_ex, 0), Height = LittleEndian.ToUInt32(header_ex, 4), BPP = LittleEndian.ToUInt16(header_ex, 0x12), Type = type, FrameCount = count, }); } else if (0x40 == type || 0x44 == type) { int count = header.ToInt32(0); if (!ArchiveFormat.IsSaneCount(count)) { return(null); } return(new PxMetaData { Width = header.ToUInt32(0x14), Height = header.ToUInt32(0x18), Type = 0x40, BPP = 32, FrameCount = count, }); } else if (1 == type || 4 == type || 7 == type) { int bpp = header.ToUInt16(0x12); if (bpp != 32 && bpp != 8) { return(null); } return(new PxMetaData { Width = header.ToUInt32(0x14), Height = header.ToUInt32(0x18), Type = type, BPP = bpp, FrameCount = 1, }); } return(null); }
void CopyV0(int data_size) { int plane_size = (int)Info.Width * (int)Info.Height; if (plane_size == data_size) { Info.BPP = 8; m_output = m_input.ReadBytes(data_size); } else if (3 * plane_size == data_size) { Info.BPP = 24; m_output = m_input.ReadBytes(data_size); } else if (4 * plane_size == data_size) { Info.BPP = 32; m_output = m_input.ReadBytes(data_size); } else { Info.BPP = 24; int dst_stride = (int)Info.Width * 3; int src_stride = (dst_stride + 3) & ~3; if (src_stride * (int)Info.Height != data_size) { throw new InvalidFormatException(); } m_output = new byte[dst_stride * (int)Info.Height]; var gap = new byte[src_stride - dst_stride]; int dst = 0; for (uint y = 0; y < Info.Height; ++y) { m_input.Read(m_output, dst, dst_stride); m_input.Read(gap, 0, gap.Length); dst += dst_stride; } } }
byte[] Unpack8bpp() { if (8 == Info.BPP) { Format = PixelFormats.Indexed8; Palette = DefaultPalette; } else { Format = PixelFormats.BlackWhite; } int pixel_count = Info.iHeight * Stride; if (m_info.IsCompressed) { return(m_input.ReadBytes(pixel_count)); } var output = new byte[pixel_count]; int dst = 0; byte[] frame = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0xFF }; int count = pixel_count; int extra_count = pixel_count; while (pixel_count > 0) { byte pixel; int frame_pos; byte ctl = m_input.ReadUInt8(); int hi = ctl >> 4; int lo = ctl & 0xF; if (hi != 0) { frame_pos = hi - 1; pixel = frame[frame_pos]; count = lo + 1; } else { switch (lo) { default: count = lo + 1; break; case 10: count = m_input.ReadUInt8() + 11; break; case 11: count = m_input.ReadUInt16() + 267; break; case 12: count = m_input.ReadInt32() + 65803; break; case 13: extra_count = 0x10; count = m_input.ReadUInt8(); break; case 14: extra_count = 0x120; count = m_input.ReadUInt16(); break; case 15: extra_count = 0x10130; count = m_input.ReadInt32(); break; } pixel = m_input.ReadUInt8(); if (lo < 13) { frame_pos = 14; } else { lo = pixel & 0xF; frame_pos = (pixel >> 4) - 1; pixel = frame[frame_pos]; count = extra_count + 16 * count + lo + 1; } } if (count > pixel_count) { count = pixel_count; } pixel_count -= count; for (int i = 0; i < count; ++i) { output[dst++] = pixel; } Buffer.BlockCopy(frame, 0, frame, 1, frame_pos); frame[0] = pixel; } return(output); }