private void button5_Click(object sender, EventArgs e) // Encode
        {
            if (!OPEN)
            {
                MessageBox.Show("Please open an image");
                return;
            }

            if (!IMPULSE)
            {
                MessageBox.Show("Please click 'Impulse noise'");
                return;
            }

            if (!SEGMENTED)
            {
                MessageBox.Show("Please click 'Segment'");
                return;
            }

            if (!DETECTED)
            {
                MessageBox.Show("Please click 'Detect edges'");
                return;
            }

            List = new CListLines(200000, 200000, 2000000, CombIm.width, CombIm.height, ExtremIm.N_Bits);

            int nByte = List.SearchLin(ref CombIm, this);

            if (nByte < 0)
            {
                Application.Exit();
            }

            LiCod = new CListCode(OrigIm.width, OrigIm.height, OrigIm.N_Bits, List);

            nCode = LiCod.Transform(OrigIm.width, OrigIm.height, OrigIm.N_Bits, Palet, CombIm, List, this);

            double CompressRate = (double)(OrigIm.width * OrigIm.height * (OrigIm.N_Bits / 8)) / (double)nCode;

            MessageBox.Show("Image encoded. nLine2=" + LiCod.nLine2 + " Code length=" + nCode +
                            " bytes. Comression rate=" + Math.Round(CompressRate, 1));
            progressBar1.Visible = false;
            button6.Visible      = true;
            label7.Text          = "Click 'Restore'";
            label7.Visible       = true;
            CODED = true;
        } //**************************** end Encode ************************************************
        public CListCode(int nx, int ny, int nbits, CListLines L) // Constructor
        {
            this.width  = nx;                                     //nLine1, nLine2, nByte;
            this.height = ny;
            this.nBits  = nbits;

            this.nLine1 = L.nLine1;
            this.Line1  = new CCrack[nLine1];
            for (int i = 0; i < nLine1; i++)
            {
                Line1[i] = new CCrack();
            }

            this.nLine2 = L.nLine2;
            this.Line   = new CLine[nLine2];
            for (int i = 0; i < nLine2; i++)
            {
                Line[i] = new CLine();
            }

            this.nByte = L.nByte;
            this.Byte  = new byte[nByte];

            this.Corner   = new byte[4];
            this.Param    = new int[6];
            this.Param[0] = nx;
            this.Param[1] = ny;
            this.Param[2] = nbits;
            this.Param[3] = L.nLine1;
            this.Param[4] = L.nLine2;
            this.Param[5] = L.nByte;

            this.Step = new iVect2[4];
            for (int i = 0; i < 4; i++)
            {
                Step[i] = new iVect2();
            }
            this.Step[0].X = 1; this.Step[0].Y = 0;
            this.Step[1].X = 0; this.Step[1].Y = 1;
            this.Step[2].X = -1; this.Step[2].Y = 0;
            this.Step[3].X = 0; this.Step[3].Y = -1;
        }
        }            // Default destructor

        public int Transform(int nx, int ny, int nbits, int[] Palet, CImage Image, CListLines L, Form1 fm1)
        // Transforms the provisional list "L" to an object of the class "CListCode".
        {
            int i, ib, il, nCode = 0;

            width           = nx; height = ny; nBits = nbits;
            nCode          += 3 * 4;
            nLine1          = L.nLine1; nLine2 = L.nLine2; nByte = L.nByte;
            nCode          += 3 * 4;
            nCodeAfterLine2 = nCode;
            Palette         = new int[256];
            for (i = 0; i < 256; i++)
            {
                Palette[i] = Palet[i];
            }

            nCode    += 256 * 4;
            Corner[0] = Image.Grid[1 + (2 * width + 1) * 1]; // this is a gray value or a palette index
            Corner[1] = Image.Grid[2 * width - 1 + (2 * width + 1) * 1];
            Corner[2] = Image.Grid[2 * width - 1 + (2 * width + 1) * (2 * height - 1)];
            Corner[3] = Image.Grid[1 + (2 * width + 1) * (2 * height - 1)];

            nCode += 4;
            int jump;

            if (nLine1 > 300)
            {
                jump = nLine1 / 33;
            }
            else
            {
                jump = 2;
            }
            fm1.progressBar1.Step    = 1;
            fm1.progressBar1.Value   = 0;
            fm1.progressBar1.Visible = true;
            for (il = 0; il < nLine1; il++)
            {
                Line1[il] = L.Line1[il];
                if ((il % jump) == jump - 1)
                {
                    fm1.progressBar1.PerformStep();
                }
            }

            nCode += nLine1 * 6; // "6" is the sizeof(CCrack);

            if (nLine2 > 300)
            {
                jump = nLine2 / 33;
            }
            else
            {
                jump = 2;
            }

            for (il = 0; il < nLine2; il++)
            {
                Line[il] = L.Line[il];
                if ((il % jump) == jump - 1)
                {
                    fm1.progressBar1.PerformStep();
                }
            }

            nCode += nLine2 * 14; // sizeof(CLine);

            if (nByte > 300)
            {
                jump = nByte / 34;
            }
            else
            {
                jump = 2;
            }
            for (ib = 0; ib < nByte; ib++)
            {
                Byte[ib] = L.Byte[ib];
                if ((ib % jump) == jump - 1)
                {
                    fm1.progressBar1.PerformStep();
                }
            }

            nCode += nByte;

            // The following code is necessary to avoid "Serialize":
            ByteNew = new byte[nCode + 4];
            for (int ik = 0; ik < nCode + 4; ik++)
            {
                ByteNew[ik] = 0;
            }
            int j = 0;

            ByteNew[j] = (byte)(nCode & 255); j++;
            ByteNew[j] = (byte)((nCode >> 8) & 255); j++;
            ByteNew[j] = (byte)((nCode >> 16) & 255); j++;
            ByteNew[j] = (byte)((nCode >> 24) & 255); j++;

            ByteNew[j] = (byte)(nx & 255); j++;
            ByteNew[j] = (byte)((nx >> 8) & 255); j++;
            ByteNew[j] = (byte)((nx >> 16) & 255); j++;
            ByteNew[j] = (byte)((nx >> 24) & 255); j++;

            ByteNew[j] = (byte)(ny & 255); j++;
            ByteNew[j] = (byte)((ny >> 8) & 255); j++;
            ByteNew[j] = (byte)((ny >> 16) & 255); j++;
            ByteNew[j] = (byte)((ny >> 24) & 255); j++;

            ByteNew[j] = (byte)(nbits & 255); j++;
            ByteNew[j] = (byte)((nbits >> 8) & 255); j++;
            ByteNew[j] = (byte)((nbits >> 16) & 255); j++;
            ByteNew[j] = (byte)((nbits >> 24) & 255); j++;

            ByteNew[j] = (byte)(nLine1 & 255); j++;
            ByteNew[j] = (byte)((nLine1 >> 8) & 255); j++;
            ByteNew[j] = (byte)((nLine1 >> 16) & 255); j++;
            ByteNew[j] = (byte)((nLine1 >> 24) & 255); j++;

            ByteNew[j] = (byte)(nLine2 & 255); j++;
            ByteNew[j] = (byte)((nLine2 >> 8) & 255); j++;
            ByteNew[j] = (byte)((nLine2 >> 16) & 255); j++;
            ByteNew[j] = (byte)((nLine2 >> 24) & 255); j++;

            ByteNew[j] = (byte)(nByte & 255); j++;
            ByteNew[j] = (byte)((nByte >> 8) & 255); j++;
            ByteNew[j] = (byte)((nByte >> 16) & 255); j++;
            ByteNew[j] = (byte)((nByte >> 24) & 255); j++;

            for (int ii = 0; ii < 256; ii++)
            {
                ByteNew[j] = (byte)(Palet[ii] & 255); j++;
                ByteNew[j] = (byte)((Palet[ii] >> 8) & 255); j++;
                ByteNew[j] = (byte)((Palet[ii] >> 16) & 255); j++;
                ByteNew[j] = (byte)((Palet[ii] >> 24) & 255); j++;
            }

            for (int i1 = 0; i1 < 4; i1++)
            {
                ByteNew[j + i1] = Corner[i1];
            }
            j += 4;

            for (int i2 = 0; i2 < nLine1; i2++)
            {
                ByteNew[j] = (byte)(L.Line1[i2].x & 255); j++;
                ByteNew[j] = (byte)((L.Line1[i2].x >> 8) & 255); j++;
                ByteNew[j] = (byte)(L.Line1[i2].y & 255); j++;
                ByteNew[j] = (byte)((L.Line1[i2].y >> 8) & 255); j++;
                ByteNew[j] = L.Line1[i2].Ind0; j++;
                ByteNew[j] = L.Line1[i2].Ind1; j++;
            }

            for (int i3 = 0; i3 < nLine2; i3++)
            {
                ByteNew[j] = (byte)(L.Line[i3].EndByte & 255); j++;
                ByteNew[j] = (byte)((L.Line[i3].EndByte >> 8) & 255); j++;
                ByteNew[j] = (byte)((L.Line[i3].EndByte >> 16) & 255); j++;
                ByteNew[j] = (byte)((L.Line[i3].EndByte >> 248) & 255); j++;
                ByteNew[j] = (byte)(L.Line[i3].x & 255); j++;
                ByteNew[j] = (byte)((L.Line[i3].x >> 8) & 255); j++;
                ByteNew[j] = (byte)(L.Line[i3].y & 255); j++;
                ByteNew[j] = (byte)((L.Line[i3].y >> 8) & 255); j++;
                ByteNew[j] = (byte)(L.Line[i3].nCrack & 255); j++;
                ByteNew[j] = (byte)((L.Line[i3].nCrack >> 8) & 255); j++;
                ByteNew[j] = L.Line[i3].Ind0; j++;
                ByteNew[j] = L.Line[i3].Ind1; j++;
                ByteNew[j] = L.Line[i3].Ind2; j++;
                ByteNew[j] = L.Line[i3].Ind3; j++;
            }

            for (int i4 = 0; i4 < nByte; i4++)
            {
                ByteNew[j + i4] = L.Byte[i4];
            }
            j += nByte;
            fm1.progressBar1.Visible = false;
            return(nCode);
        } //**************************** end Transform ********************************************