private void init(byte[] data)
        {
            OtherCodesIgnoredInSameFile = 0;
            IgnoredMetadata             = false;
            int index = -1;

            for (int line = 0; line < data.Length; line += 8)
            {
                if (ByteUtilities.ByteArrayEquals(data, line, SSS_HEADER, 0, SSS_HEADER.Length))
                {
                    if (index != -1)
                    {
                        OtherCodesIgnoredInSameFile++;
                    }

                    index = line;
                }
            }

            if (index < 0)
            {
                if (data.Length > 0)
                {
                    MessageBox.Show("No custom SSS code found. A default code will be used.");
                }

                DataBefore = gctheader.ToArray();
                sss1       = ByteUtilities.StringToByteArray(
                    "00010203 04050709 080A0B0C 0D0E0F10 11141516 1A191217 0618131D 1E1B1C");
                sss2 = ByteUtilities.StringToByteArray("1F202122 23242526 2728");
                sss3 = ByteUtilities.StringToByteArray(
                    "01010202 03030404 05050606 07070808 0909330A 0B0B0C0C 0D0D0E0E 130F1410 " +
                    "15111612 17131814 19151C16 1D171E18 1F19201A 211B221C 231D241E 251F2932 " +
                    "2A332B34 2C352D36 2F373038 3139323A 2E3BFFFF");
                DataAfter = data.Skip(gctheader.Length).ToArray();
            }
            else
            {
                int start = index;
                DataBefore = new byte[start];
                Array.ConstrainedCopy(data, 0, DataBefore, 0, start);

                index += 14 * 8;
                byte sss1_count = data[index - 1];
                sss1 = new byte[sss1_count];
                Array.ConstrainedCopy(data, index, sss1, 0, sss1_count);

                index += sss1_count;
                while (index % 8 != 0)
                {
                    index++;
                }

                index += 2 * 8;
                byte sss2_count = data[index - 1];
                sss2 = new byte[sss2_count];
                Array.ConstrainedCopy(data, index, sss2, 0, sss2_count);

                index += sss2_count;
                while (index % 8 != 0)
                {
                    index++;
                }

                index += 1 * 8;
                byte sss3_count = data[index - 1];
                sss3 = new byte[sss3_count];
                Array.ConstrainedCopy(data, index, sss3, 0, sss3_count);

                index += sss3_count;
                while (index % 8 != 0)
                {
                    index++;
                }

                DataAfter = new byte[data.Length - index];
                Array.ConstrainedCopy(data, index, DataAfter, 0, data.Length - index);
            }

            bool footer_found = false;

            for (int i = 0; i < DataAfter.Length; i += 8)
            {
                if (footer_found)
                {
                    IgnoredMetadata = true;
                    DataAfter       = DataAfter.Take(i).ToArray();
                    break;
                }
                else
                {
                    if (ByteUtilities.ByteArrayEquals(DataAfter, i, gctfooter, 0, 8))
                    {
                        footer_found = true;
                    }
                }
            }
        }
        private void init(byte[] data)
        {
            Settings = new Dictionary <ushort, byte>();

            int index = -1;

            for (int line = 0; line < data.Length; line += 8)
            {
                if (ByteUtilities.ByteArrayEquals(data, line, CSV_HEADER, 0, CSV_HEADER.Length))
                {
                    index = line;
                }
            }

            if (index < 0)
            {
                Console.WriteLine("No Custom Song Volume code found. An empty code will be created.");

                DataBefore = gctheader.ToArray();
                DataAfter  = data.Skip(gctheader.Length).ToArray();
            }
            else
            {
                int start = index;
                DataBefore = new byte[start];
                Array.ConstrainedCopy(data, 0, DataBefore, 0, start);

                index += 9 * 8;
                byte byte_count       = data[index - 1];
                bool found_terminator = false;
                for (int i = 0; i < byte_count; i += 4)
                {
                    ushort u = (ushort)(data[index + i] * 0x100 + data[index + i + 1]);
                    if (u == 0x7FFF)
                    {
                        if (found_terminator)
                        {
                            throw new InvalidDataException("Two terminators");
                        }
                        found_terminator = true;
                    }
                    else
                    {
                        Settings.Add(u, data[index + i + 3]);
                    }
                }
                if (!found_terminator)
                {
                    throw new InvalidDataException("No terminators");
                }

                index += byte_count;
                while (index % 8 != 0)
                {
                    index++;
                }

                DataAfter = new byte[data.Length - index];
                Array.ConstrainedCopy(data, index, DataAfter, 0, data.Length - index);
            }

            bool footer_found = false;

            for (int i = 0; i < DataAfter.Length; i += 8)
            {
                if (footer_found)
                {
                    MessageBox.Show("Extra data found after GCT footer - this will be discarded if you save the GCT.");
                    DataAfter = DataAfter.Take(i).ToArray();
                    break;
                }
                else
                {
                    if (ByteUtilities.ByteArrayEquals(DataAfter, i, gctfooter, 0, 8))
                    {
                        footer_found = true;
                    }
                }
            }
        }