public void WriteUint(uint value) { if (Endianness == Endianness.BigEndian) { value = EndianUtil.SwapEndian(value); } Stream.Write(BitConverter.GetBytes(value), 0, 4); }
/// <summary> /// Constructor for IO. I would usually think to consider the Stream as the /// Input type, however the BinaryReader exposes the owning stream. /// </summary> /// <param name="br">System.IO.BinaryReader</param> public smf_mthd(BinaryReader br, params smf_mtrk[] tracks) { bHead = br.ReadBytes(4); size = EndianUtil.Reverse(br.ReadBytes(4)); fmt = EndianUtil.Reverse(br.ReadBytes(2)); ntk = EndianUtil.Reverse(br.ReadBytes(2)); div = EndianUtil.Reverse(br.ReadBytes(2)); Tracks = tracks; //tk = br.ReadBytes(4); }
/// <summary>Read MTrk structure</summary> void ReadMThd(BinaryReader br, params MTrk[] tracks) { ByteHead = br.ReadBytes(4); ByteSize = EndianUtil.Flip(br.ReadBytes(4)); ByteFormat = EndianUtil.Flip(br.ReadBytes(2)); ByteNTrack = EndianUtil.Flip(br.ReadBytes(2)); ByteDivision = EndianUtil.Flip(br.ReadBytes(2)); Tracks = tracks; //tk = br.ReadBytes(4); }
private static unsafe byte[] SwapShortArrayToLittleEndian(byte[] values, uint count) { fixed(byte *pBytes = values) { ushort *ptr = (ushort *)pBytes; ushort *ptrEnd = ptr + count; while (ptr < ptrEnd) { *ptr = EndianUtil.Swap(*ptr); ptr++; } } return(values); }
public uint ReadUint(long offset) { byte[] array = new byte[4]; StreamPosition = offset; Stream.Read(array, 0, 4); var value = BitConverter.ToUInt32(array, 0); if (Endianness == Endianness.BigEndian) { return(EndianUtil.SwapEndian(value)); } else { return(value); } }
private static unsafe byte[] SwapRationalArrayToLittleEndian(byte[] values, uint count) { // A rational value consists of two 4-byte values, a numerator and a denominator. long itemCount = (long)count * 2; fixed(byte *pBytes = values) { uint *ptr = (uint *)pBytes; uint *ptrEnd = ptr + itemCount; while (ptr < ptrEnd) { *ptr = EndianUtil.Swap(*ptr); ptr++; } } return(values); }
/// <summary>read the track's bytes; Doesn't parse the track though.</summary> /// <param name="bi"></param> public MTrk(BinaryReader bi) { CkID = bi.ReadChars(4); SizeBytes = EndianUtil.Flip(bi.ReadBytes(4)); Data = bi.ReadBytes(BitConverter.ToInt32(SizeBytes, 0)); }
uint ReadTo32Bit(int dataOffset, int byteLength) { byte[] result = new byte[4]; Array.ConstrainedCopy(Data, dataOffset, result, 4 - byteLength, byteLength); return(BitConverter.ToUInt32(ConvertEndian ? EndianUtil.Flip(result) : result, 0)); }
public static MemoryStream Decompress(Stream data) { try { data.Position = 0; byte[] aklzBuffer = new byte[4]; data.Read(aklzBuffer, 0, 4); if (aklzBuffer[0] != 0x41 || aklzBuffer[1] != 0x4B || aklzBuffer[2] != 0x4C || aklzBuffer[3] != 0x5A) { return(new MemoryStream(StreamReaderExtensions.ToByteArray(data))); } const uint START_INDEX = 0x1000; // Compressed & Decompressed Data Information uint compressedSize = (uint)data.Length; uint decompressedSize = EndianUtil.SwapEndian(StreamReaderExtensions.ReadUInt(data, 0xC)); uint sourcePointer = 0x10; uint destPointer = 0x0; byte[] compressedData = StreamReaderExtensions.ToByteArray(data); byte[] decompressedData = new byte[decompressedSize]; // Start Decompression while (sourcePointer < compressedSize && destPointer < decompressedSize) { byte instruction = compressedData[sourcePointer]; // Compression Flag sourcePointer++; for (int i = 0; i < 8; ++i) { bool copySingleByte = (instruction & 0x01) != 0; instruction >>= 1; if (copySingleByte) // Data is not compressed { decompressedData[destPointer] = compressedData[sourcePointer]; sourcePointer++; destPointer++; } else // Data is compressed { int copyFromAddress = (compressedData[sourcePointer] | ((compressedData[sourcePointer + 1] & 0xF0) << 4)) + 0x12; int Amount = (compressedData[sourcePointer + 1] & 0x0F) + 3; sourcePointer += 2; int memCopyAddress = copyFromAddress; uint wrapCount = destPointer / START_INDEX; for (int wrap = 1; wrap <= wrapCount; ++wrap) { if (copyFromAddress + wrap * START_INDEX < destPointer) { memCopyAddress += (int)START_INDEX; } } if (memCopyAddress > destPointer) { memCopyAddress -= (int)START_INDEX; } // Copy copySize bytes from decompressedData for (int copyIndex = 0; copyIndex < Amount; ++copyIndex, ++memCopyAddress) { if (memCopyAddress < 0) { // This means 0 decompressedData[destPointer] = 0; } else { decompressedData[destPointer] = decompressedData[memCopyAddress]; } ++destPointer; if (destPointer >= decompressedData.Length) { return(new MemoryStream(decompressedData)); } } } // Check for out of range if (sourcePointer >= compressedSize || destPointer >= decompressedSize) { break; } } } return(new MemoryStream(decompressedData)); } catch { return(null); // An error occured while decompressing } }
public static MemoryStream Compress(Stream data) { try { uint DecompressedSize = (uint)data.Length; MemoryStream CompressedData = new MemoryStream(); byte[] DecompressedData = StreamReaderExtensions.ToByteArray(data); uint SourcePointer = 0x0; uint DestPointer = 0x10; // Set up the Lz Compression Dictionary LzWindowDictionary LzDictionary = new LzWindowDictionary(); LzDictionary.SetWindowSize(0x1000); LzDictionary.SetMaxMatchAmount(0xF + 3); // Start compression StreamWriterExtensions.Write(CompressedData, "AKLZ"); byte[] header = new byte[] { 0x7e, 0x3f, 0x51, 0x64, 0x3d, 0xcc, 0xcc, 0xcd }; StreamWriterExtensions.Write(CompressedData, header); StreamWriterExtensions.Write(CompressedData, EndianUtil.SwapEndian(DecompressedSize)); while (SourcePointer < DecompressedSize) { byte Flag = 0x0; uint FlagPosition = DestPointer; CompressedData.WriteByte(Flag); // It will be filled in later DestPointer++; for (int i = 0; i < 8; ++i) { int[] LzSearchMatch = LzDictionary.Search(DecompressedData, SourcePointer, DecompressedSize); if (LzSearchMatch[1] > 0) // There is a compression match { Flag |= (byte)(0 << i); int copySize = LzSearchMatch[1] - 3; int address = LzSearchMatch[0] - 0x12; byte firstByte = (byte)(address & 0x0FF); byte secondByte = (byte)(copySize | ((address & 0xF00) >> 4)); CompressedData.WriteByte(firstByte); CompressedData.WriteByte(secondByte); LzDictionary.AddEntryRange(DecompressedData, (int)SourcePointer, LzSearchMatch[1]); LzDictionary.SlideWindow(LzSearchMatch[1]); SourcePointer += (uint)LzSearchMatch[1]; DestPointer += 2; } else // There wasn't a match { Flag |= (byte)(1 << i); CompressedData.WriteByte(DecompressedData[SourcePointer]); LzDictionary.AddEntry(DecompressedData, (int)SourcePointer); LzDictionary.SlideWindow(1); SourcePointer++; DestPointer++; } // Check for out of bounds if (SourcePointer >= DecompressedSize) { break; } } // Write the flag. // Note that the original position gets reset after writing. CompressedData.Seek(FlagPosition, SeekOrigin.Begin); CompressedData.WriteByte(Flag); CompressedData.Seek(DestPointer, SeekOrigin.Begin); } return(CompressedData); } catch { return(null); // An error occured while compressing } }
/// <summary> /// read the track's bytes; Doesn't parse the track though. /// </summary> /// <param name="bi"></param> public smf_mtrk(BinaryReader bi) { title = bi.ReadChars(4); size = EndianUtil.Reverse(bi.ReadBytes(4)); track = bi.ReadBytes(BitConverter.ToInt32(size, 0)); }