Example #1
0
 public void WriteUint(uint value)
 {
     if (Endianness == Endianness.BigEndian)
     {
         value = EndianUtil.SwapEndian(value);
     }
     Stream.Write(BitConverter.GetBytes(value), 0, 4);
 }
Example #2
0
 /// <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);
 }
Example #3
0
 /// <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);
 }
Example #4
0
        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);
        }
Example #5
0
        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);
            }
        }
Example #6
0
        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);
        }
Example #7
0
 /// <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));
 }
Example #8
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));
 }
Example #9
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
            }
        }
Example #10
0
        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
            }
        }
Example #11
0
 /// <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));
 }