public static double[][] BMPRead(BinaryFile bmpfile, ref int y, ref int x)
    {
        int iy     = 0;     // various iterators
        int ix     = 0;
        int ic     = 0;
        int offset = 0;

        double[][] image;
        byte       zerobytes = new byte();
        byte       val       = new byte();

                #if DEBUG
        Console.Write("BMPRead...\n");
                #endif

        if (GlobalMembersUtil.ReadUInt16(bmpfile) != 19778)         // "BM" format tag check
        {
            Console.Error.WriteLine("This file is not in BMP format\n");
            GlobalMembersUtil.WinReturn();
            Environment.Exit(1);
        }

        bmpfile.Seek(8, SeekOrigin.Current);                      // skipping useless tags

        offset = (int)GlobalMembersUtil.ReadUInt32(bmpfile) - 54; // header offset

        bmpfile.Seek(4, SeekOrigin.Current);                      // skipping useless tags

        x = (int)GlobalMembersUtil.ReadUInt32(bmpfile);
        y = (int)GlobalMembersUtil.ReadUInt32(bmpfile);

        bmpfile.Seek(2, SeekOrigin.Current);             // skipping useless tags

        if (GlobalMembersUtil.ReadUInt16(bmpfile) != 24) // Only format supported
        {
            Console.Error.WriteLine("Wrong BMP format, BMP images must be in 24-bit colour\n");
            GlobalMembersUtil.WinReturn();
            Environment.Exit(1);
        }

        bmpfile.Seek(24 + offset, SeekOrigin.Current);       // skipping useless tags

        // image allocation
        image = new double[y][];

        for (iy = 0; iy < y; iy++)
        {
            image[iy] = new double[x];
        }

        zerobytes = (byte)(4 - ((x * 3) & 3));
        if (zerobytes == 4)
        {
            zerobytes = 0;
        }

        for (iy = y - 1; iy != -1; iy--)       // backwards reading
        {
            for (ix = 0; ix < x; ix++)
            {
                for (ic = 2; ic != -1; ic--)
                {
                    val            = bmpfile.ReadByte();
                    image[iy][ix] += (double)val * (1.0 / (255.0 * 3.0));                    // Conversion to grey by averaging the three channels
                }
            }

            bmpfile.Seek(zerobytes, SeekOrigin.Current);             // skipping padding bytes
        }

        bmpfile.Close();
        return(image);
    }
    public static double[][] ReadWaveFile(BinaryFile wavfile, ref int channels, ref int samplecount, ref int samplerate)
    {
        double[][] sound;
        int        i  = 0;
        int        ic = 0;

        int[] tag = new int[13];

        //			Size  Description                  Value
        // tag[0]	4	  RIFF Header				   RIFF (1179011410)
        // tag[1]   4	  RIFF data size
        // tag[2]   4	  form-type (WAVE etc)			(1163280727)
        // tag[3]   4     Chunk ID                     "fmt " (0x666D7420) = 544501094
        // tag[4]	4     Chunk Data Size              16 + extra format bytes
        // tag[5]	2     Compression code             1 - 65,535
        // tag[6]	2     Number of channels           1 - 65,535
        // tag[7]	4     Sample rate                  1 - 0xFFFFFFFF
        // tag[8]	4     Average bytes per second     1 - 0xFFFFFFFF
        // tag[9]	2     Block align                  1 - 65,535 (4)
        // tag[10]	2     Significant bits per sample  2 - 65,535 (32)
        // tag[11]	4	  IEEE = 1952670054 (0x74636166) = fact chunk
        //                PCM = 1635017060 (0x61746164)  (datachunk = 1635017060)
        // tag[12]  4	  IEEE = 4 ,                        PCM = 5292000 (0x0050BFE0)

                #if DEBUG
        Console.Write("ReadWaveFile...\n");
                #endif

        for (i = 0; i < 13; i++)       // tag reading
        {
            tag[i] = 0;

            if ((i == 5) || (i == 6) || (i == 9) || (i == 10))
            {
                tag[i] = GlobalMembersUtil.ReadUInt16(wavfile);
            }
            else
            {
                tag[i] = (int)GlobalMembersUtil.ReadUInt32(wavfile);
            }
        }

        //********File format checking********
        if (tag[0] != 1179011410 || tag[2] != 1163280727)
        {
            Console.Error.WriteLine("This file is not in WAVE format\n");
            GlobalMembersUtil.WinReturn();
            Environment.Exit(1);
        }

        if (tag[3] != 544501094 || tag[4] != 16 || tag[11] != 1635017060)   //
        {
            Console.Error.WriteLine("This WAVE file format is not currently supported\n");
            GlobalMembersUtil.WinReturn();
            Environment.Exit(1);
        }

        if (tag[10] == 24)
        {
            Console.Error.WriteLine("24 bit PCM WAVE files is not currently supported\n");
            GlobalMembersUtil.WinReturn();
            Environment.Exit(1);
        }

        if (tag[5] != WAVE_FORMAT_PCM)
        {
            Console.Error.WriteLine("Non PCM WAVE files is not currently supported\n");
            GlobalMembersUtil.WinReturn();
            Environment.Exit(1);
        }

        //--------File format checking--------

        channels = tag[6];

        samplecount = tag[12] / (tag[10] / 8) / channels;
        samplerate  = tag[7];

        sound = new double[channels][];

        for (ic = 0; ic < channels; ic++)
        {
            sound[ic] = new double[samplecount];
        }

        //********Data loading********
        if (tag[10] == 8)
        {
            Read8Bit(wavfile, sound, samplecount, channels);
        }
        if (tag[10] == 16)
        {
            Read16Bit(wavfile, sound, samplecount, channels);
        }
        if (tag[10] == 32)
        {
            if (tag[5] == WAVE_FORMAT_PCM)
            {
                Read32Bit(wavfile, sound, samplecount, channels);
            }
            else if (tag[5] == WAVE_FORMAT_IEEE_FLOAT)
            {
                Read32BitFloat(wavfile, sound, samplecount, channels);
            }
        }

        //--------Data loading--------

        wavfile.Close();
        return(sound);
    }