public static bool HasFooter(GBAROM rom)
 {
     Stream stream = rom.GetStream();
     stream.Seek(-12, SeekOrigin.End);
     bool result = true;
     using (BinaryReader reader = new BinaryReader(stream))
     {
         int length = reader.ReadInt32();
         int signature = reader.ReadInt32();
         uint crc32 = reader.ReadUInt32();
         result = signature == 0x1270D1FE;
     }
     return result;
 }
        public static void RemoveAndReadFooter(GBAROM rom, GBAMemoryManager memMan)
        {
            Stream stream = rom.GetStream();
            stream.Seek(-12, SeekOrigin.End);
            int length;
            uint crc32;
            using (BinaryReader reader = new BinaryReader(stream))
            {
                length = reader.ReadInt32();
                int signature = reader.ReadInt32();
                crc32 = reader.ReadUInt32();
                if (signature != 0x1270D1FE)
                {
                    throw new Exception("No footer present");
                }

                stream.Seek(12 + length + 12, SeekOrigin.End);

                byte[] version = reader.ReadBytes(12); //Like we care

                while (stream.Position < stream.Length - 12)
                {
                    byte[] rawid = reader.ReadBytes(4);
                    string id = new string(Array.ConvertAll(rawid, Convert.ToChar));
                    int chunkLength = reader.ReadInt32();
                    if (id == "Free")
                    {
                        long endOffset = stream.Position + length;
                        int offset = 0;
                        while (stream.Position < endOffset)
                        {
                            int relativeOffset = reader.ReadEncodedInteger();
                            offset += relativeOffset;
                            int freeLength = reader.ReadEncodedInteger();
                            memMan.AddManagedSpace(offset, freeLength);
                            offset += freeLength;
                        }
                    }
                    else
                    {
                        stream.Seek(chunkLength, SeekOrigin.Current);
                    }
                }
            }

            rom.Length -= 12 + length + 12; //Remove footer
        }