} //********************** end ColorToGray **********************

        public int ColorToGray(CImage inp)

        /* Transforms the colors of the color image "inp" in luminance=(r+g+b)/3
         * and puts these values to this.Grid. --------- */
        {
            int c, sum, x, y;

            if (inp.N_Bits != 24)
            {
                return(-1);
            }
            N_Bits = 8; NX = inp.NX; NY = inp.NY;
            Grid   = new byte[NX * NY * 8];
            for (y = 0; y < NY; y++)     //=========================
            {
                for (x = 0; x < NX; x++) // =====================
                {
                    sum = 0;
                    for (c = 0; c < 3; c++)
                    {
                        sum += inp.Grid[c + 3 * (x + NX * y)];
                    }
                    Grid[y * NX + x] = (byte)(sum / 3);
                } // ========== for (x.  ====================
            }
            return(1);
        } //********************** end ColorToGray **********************
        public int ColorToGrayMC(CImage inp, Form1 fm1)

        /* Transforms the colors of the color image "inp" in lightness=MaxC(R, G, B)
         * and puts these values to this.Grid. --------- */
        {
            int gv, x, y;

            if (inp.N_Bits != 24)
            {
                return(-1);
            }
            N_Bits = 8; NX = inp.NX; NY = inp.NY;
            Grid   = new byte[NX * NY * 8];
            for (y = 0; y < NY; y++)     //=========================
            {
                for (x = 0; x < NX; x++) // =====================
                {
                    gv = MaxC(inp.Grid[2 + 3 * (x + NX * y)],
                              inp.Grid[1 + 3 * (x + NX * y)],
                              inp.Grid[0 + 3 * (x + NX * y)]);
                    Grid[y * NX + x] = (byte)gv;
                } // ========== for (x.  ====================
            }
            return(1);
        } //********************** end ColorToGrayMC **********************
 public void Copy(CImage inp)
 {
     NX     = inp.NX;
     NY     = inp.NY;
     N_Bits = inp.N_Bits;
     for (int i = 0; i < NX * NY * N_Bits / 8; i++)
     {
         Grid[i] = inp.Grid[i];
     }
 }
        private void button1_Click(object sender, EventArgs e) // Open image
        {
            label1.Visible = false;
            label2.Visible = false;
            label3.Visible = false;
            OpenFileDialog openFileDialog1 = new OpenFileDialog();

            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    OpenImageFile     = openFileDialog1.FileName;
                    origBmp           = new Bitmap(OpenImageFile);
                    pictureBox1.Image = origBmp;
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error: Could not read file from disk. Original error: " +
                                    ex.Message);
                    return;
                }
            }
            else
            {
                return;
            }

            width  = origBmp.Width;
            height = origBmp.Height;

            origIm     = new CImage(width, height, 24);
            origGrayIm = new CImage(width, height, 8); // grayscale version of origIm
            contrastIm = new CImage(width, height, 24);

            label3.Text    = "Opened image:" + openFileDialog1.FileName;
            label3.Visible = true;


            progressBar1.Visible = true;
            progressBar1.Value   = 0;
            progressBar1.Step    = 1;
            if (origBmp.PixelFormat == PixelFormat.Format8bppIndexed)
            {
                BMP_Graph            = false;
                progressBar1.Visible = true;
                Color color;
                int   y2 = height / 100 + 1;
                nbyte = 3;
                int jump, Len = height, nStep = 50;
                if (Len > 2 * nStep)
                {
                    jump = Len / nStep;
                }
                else
                {
                    jump = 2;
                }
                for (int y = 0; y < height; y++) //==============================================
                {
                    if ((y % jump) == jump - 1)
                    {
                        progressBar1.PerformStep();
                    }
                    for (int x = 0; x < width; x++)
                    {
                        int i = x + width * y;
                        color = origBmp.GetPixel(i % width, i / width);
                        for (int c = 0; c < nbyte; c++)
                        {
                            if (c == 0)
                            {
                                origIm.Grid[nbyte * i] = color.B;
                            }
                            if (c == 1)
                            {
                                origIm.Grid[nbyte * i + 1] = color.G;
                            }
                            if (c == 2)
                            {
                                origIm.Grid[nbyte * i + 2] = color.R;
                            }
                        }
                    }
                } //=============================== end for ( int y... =========================
            }
            else
            if (origBmp.PixelFormat == PixelFormat.Format24bppRgb)
            {
                BMP_Graph = true;
                BitmapToGrid(origBmp, origIm.Grid);
            }
            else
            {
                MessageBox.Show("Form1: Inappropriate pixel format. Returning.");
                return;
            }

            ContrastBmp       = new Bitmap(origBmp.Width, origBmp.Height, PixelFormat.Format24bppRgb);
            pictureBox2.Image = ContrastBmp;
            BmpPictBox3       = new Bitmap(256, 256);
            pictureBox2.Image = BmpPictBox3;
            if (BMP_Graph)
            {
                g2 = Graphics.FromImage(ContrastBmp);
                g3 = Graphics.FromImage(BmpPictBox3);
            }
            else
            {
                g2 = pictureBox2.CreateGraphics();
                g3 = pictureBox3.CreateGraphics();
            }

            // Calculating the histogram:
            origGrayIm.ColorToGrayMC(origIm, this);
            for (int gv = 0; gv < 256; gv++)
            {
                histo[gv] = 0;
            }
            for (int i = 0; i < width * height; i++)
            {
                histo[origGrayIm.Grid[i]]++;
            }
            MaxHist = 0;
            for (int gv = 0; gv < 256; gv++)
            {
                if (histo[gv] > MaxHist)
                {
                    MaxHist = histo[gv];
                }
            }
            MinGV = 255;
            MaxGV = 0;
            for (MinGV = 0; MinGV < 256; MinGV++)
            {
                if (histo[MinGV] > 0)
                {
                    break;
                }
            }
            for (MaxGV = 255; MaxGV >= 0; MaxGV--)
            {
                if (histo[MaxGV] > 0)
                {
                    break;
                }
            }

            // Drawing the histogram:
            SolidBrush myBrush = new SolidBrush(Color.LightGray);
            Rectangle  rect    = new Rectangle(0, 0, 256, 256);

            g3.FillRectangle(myBrush, rect);
            myPen = new Pen(Color.Red);
            Pen greenPen = new Pen(Color.Green);

            for (int gv = 0; gv < 256; gv++)
            {
                int hh = histo[gv] * 255 / MaxHist;
                if (histo[gv] > 0 && hh < 1)
                {
                    hh = 1;
                }
                g3.DrawLine(myPen, gv, 255, gv, 255 - hh);
                if (gv == MinGV || gv == MaxGV)
                {
                    g3.DrawLine(greenPen, gv, 255, gv, 255 - hh);
                }
            }
            if (BMP_Graph)
            {
                pictureBox3.Image = BmpPictBox3;
            }

            // Calculating the standard LUT:
            int[] LUT = new int[256];
            int   X   = (MinGV + MaxGV) / 2;
            int   Y   = 128;

            for (int gv = 0; gv < 256; gv++)
            {
                if (gv <= MinGV)
                {
                    LUT[gv] = 0;
                }
                if (gv > MinGV && gv <= X)
                {
                    LUT[gv] = (gv - MinGV) * Y / (X - MinGV);
                }
                if (gv > X && gv <= MaxGV)
                {
                    LUT[gv] = Y + (gv - X) * (255 - Y) / (MaxGV - X);
                }
                if (gv >= MaxGV)
                {
                    LUT[gv] = 255;
                }
            }

            int yy      = 255;
            Pen bluePen = new Pen(Color.Blue);

            g3.DrawLine(bluePen, 0, yy, MinGV, yy);
            g3.DrawLine(bluePen, MinGV, yy, X, yy - Y);
            g3.DrawLine(bluePen, X, yy - Y, MaxGV, 0);
            g3.DrawLine(bluePen, MaxGV, 0, yy, 0);
            if (BMP_Graph)
            {
                pictureBox3.Image = BmpPictBox3;
            }
            // nbyte = 3;  origIm and contrastIm are both 24-bit images
            for (int i = 0; i < nbyte * width * height; i++)
            {
                contrastIm.Grid[i] = (byte)LUT[(int)origIm.Grid[i]];
            }

            //ContrastBmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            progressBar1.Visible = true;
            GridToBitmap(ContrastBmp, contrastIm.Grid);
            cntClick = 0;
            if (BMP_Graph)
            {
                pictureBox3.Image = BmpPictBox3;
            }
            pictureBox2.Image    = ContrastBmp;
            label1.Visible       = true;
            progressBar1.Visible = false;
        } //******************************* end Open image ******************************************