public static bool Scramble(ref Bitmap bmp, int zone)
        {
            if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
                return false;

            if ((zone < 2) | (zone > 30)) return false;

            int w = bmp.Width;
            int h = bmp.Height;

            int num = zone * zone;

            byte[] rr = new byte[num];
            byte[] gg = new byte[num];
            byte[] bb = new byte[num];
            int[] ra = new int[num];

            int indx;
            Random rnd = new Random();
            int j, t;

            BmpProc24 src = new BmpProc24(bmp);

            for (int y = 0; y < h - 1; y += zone)
                for (int x = 0; x < w - 1; x += zone)
                {

                    indx = 0;

                    for (int iy = y; iy < y + zone; iy++)
                        for (int ix = x; ix < x + zone; ix++)
                        {
                            if ((ix > w - 1) | (iy > h - 1)) continue;
                            src.SetXY(ix, iy);
                            rr[indx] = src.R;
                            gg[indx] = src.G;
                            bb[indx] = src.B;
                            indx++;
                        }

                    for (int i = 0; i < indx; i++) ra[i] = i;

                    for (int i = 0; i < indx - 1; i++)
                    {
                        j = rnd.Next(i, indx);
                        t = ra[i];
                        ra[i] = ra[j];
                        ra[j] = t;
                    }

                    indx = 0;

                    for (int iy = y; iy < y + zone; iy++)
                        for (int ix = x; ix < x + zone; ix++)
                        {
                            if ((ix > w - 1) | (iy > h - 1)) continue;
                            src.SetXY(ix, iy);
                            src.R = rr[ra[indx]];
                            src.G = gg[ra[indx]];
                            src.B = bb[ra[indx]];
                            indx++;
                        }
                }

            src.Dispose();

            return true;
        }
        public static bool RGBHistogram(Bitmap bmp, out Bitmap bmpHist)
        {
            if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
            {
                bmpHist = null;
                return false;
            }

            int w = bmp.Width;
            int h = bmp.Height;

            int[] hist = new int[256];
            int[] rh = new int[256];
            int[] gh = new int[256];
            int[] bh = new int[256];

            int ir, indx;

            BmpProc24 bd = new BmpProc24(bmp);

            for (int y = 0; y < h; y++)
                for (int x = 0; x < w; x++)
                {
                    ir = bd.IndexR(x, y);
                    rh[bd[ir]]++;
                    gh[bd[ir - 1]]++;
                    bh[bd[ir - 2]]++;
                    indx = (int)(bd[ir] * 0.299 + bd[ir - 1] * 0.587 +
                                                           bd[ir - 2] * 0.114);
                    hist[indx]++;
                }

            bd.Dispose();

            int max = -1;
            for (int i = 0; i < 256; i++)
            {
                if (rh[i] > max) max = rh[i];
                if (gh[i] > max) max = gh[i];
                if (bh[i] > max) max = bh[i];
                if (hist[i] > max) max = hist[i];
            }

            PointF[] pt = new PointF[256];

            bmpHist = new Bitmap(275, 160, PixelFormat.Format24bppRgb);

            Graphics g = Graphics.FromImage(bmpHist);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.Clear(Color.AntiqueWhite);

            Pen pen = new Pen(Color.Red, 1.5F);
            for (int i = 0; i < 256; i++)
            {
                pt[i].X = 10 + i;
                pt[i].Y = (float)(150 - rh[i] * 140f / max);
            }

            g.DrawLines(pen, pt);

            pen.Color = Color.ForestGreen;
            for (int i = 0; i < 256; i++)
                pt[i].Y = (float)(150 - gh[i] * 140f / max);

            g.DrawLines(pen, pt);

            pen.Color = Color.Blue;
            for (int i = 0; i < 256; i++)
                pt[i].Y = (float)(150 - bh[i] * 140f / max);

            g.DrawLines(pen, pt);

            pen.Color = Color.Black;
            for (int i = 0; i < 256; i++)
                pt[i].Y = (float)(150 - hist[i] * 140f / max);

            g.DrawLines(pen, pt);

            pen.Color = Color.Black;

            g.DrawLine(pen, 8, 150, 8, 10);

            for (int i = 0; i <= 20; i++)
                if ((i % 2) == 0)
                    g.DrawLine(pen, 8, 150 - 7 * i, 4, 150 - 7 * i);
                else
                    g.DrawLine(pen, 8, 150 - 7 * i, 6, 150 - 7 * i);

            g.DrawLine(pen, 10, 150, 10 + 255, 150);

            for (int i = 0; i <= 51; i++)
                if ((i % 2) == 0)
                    g.DrawLine(pen, 10 + 5 * i, 150, 10 + 5 * i, 154);
                else
                    g.DrawLine(pen, 10 + 5 * i, 150, 10 + 5 * i, 152);

            g.Dispose();

            return true;
        }
        public static bool SaturationHistogram(Bitmap bmp, out Bitmap bmpHist)
        {
            if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
            {
                bmpHist = null;
                return false;
            }

            int w = bmp.Width;
            int h = bmp.Height;

            int[] hist = new int[256];

            int hue, satu, lumi;
            byte rr, gg, bb;

            BmpProc24 src = new BmpProc24(bmp);

            for (int y = 0; y < h; y++)
                for (int x = 0; x < w; x++)
                {
                    src.SetXY(x, y);

                    rr = src.R; gg = src.G; bb = src.B;
                    ImageUtils.RGBToHSL(rr, gg, bb, out hue, out satu, out lumi);

                    hist[satu]++;
                }

            src.Dispose();

            int max = -1;
            for (int i = 0; i < 256; i++)
                if (hist[i] > max) max = hist[i];

            for (int i = 0; i < 256; i++)
                hist[i] = hist[i] * 140 / max;

            bmpHist = new Bitmap(275, 160, PixelFormat.Format24bppRgb);

            Graphics g = Graphics.FromImage(bmpHist);
            g.Clear(Color.AntiqueWhite);

            Pen pen = new Pen(Color.Gray, 1F);

            for (int i = 0; i < 256; i++)
                g.DrawLine(pen, 10 + i, 150, 10 + i, 150 - hist[i]);

            pen.Color = Color.Black;

            g.DrawLine(pen, 8, 150, 8, 10);

            for (int i = 0; i <= 20; i++)
                if ((i % 2) == 0)
                    g.DrawLine(pen, 8, 150 - 7 * i, 4, 150 - 7 * i);
                else
                    g.DrawLine(pen, 8, 150 - 7 * i, 6, 150 - 7 * i);

            g.DrawLine(pen, 10, 150, 10 + 255, 150);

            for (int i = 0; i <= 51; i++)
                if ((i % 10) == 0)
                    g.DrawLine(pen, 10 + 5 * i, 150, 10 + 5 * i, 156);
                else
                    if ((i % 5) == 0)
                        g.DrawLine(pen, 10 + 5 * i, 150, 10 + 5 * i, 154);
                    else
                        g.DrawLine(pen, 10 + 5 * i, 150, 10 + 5 * i, 152);

            g.Dispose();

            return true;
        }
        public static bool Pixelate2(ref Bitmap bmp, int zone)
        {
            if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
                return false;

            if ((zone < 2) | (zone > 30)) return false;

            int w = bmp.Width;
            int h = bmp.Height;

            int ir, count, sumr, sumg, sumb;

            byte[,] rr = new byte[w / zone + 1, h / zone + 1];
            byte[,] gg = new byte[w / zone + 1, h / zone + 1];
            byte[,] bb = new byte[w / zone + 1, h / zone + 1];

            int countX, countY;

            byte rrr, ggg, bbb;

            countY = 0;

            BmpProc24 src = new BmpProc24(bmp);

            for (int y = 0; y < h; y += zone)
            {
                countX = 0;

                for (int x = 0; x < w; x += zone)
                {
                    count = sumr = sumg = sumb = 0;

                    for (int iy = y; iy < y + zone; iy++)
                        for (int ix = x; ix < x + zone; ix++)
                        {
                            if ((iy > h - 1) | (ix > w - 1)) continue;

                            count++;

                            ir = src.IndexR(ix, iy);
                            sumr += src[ir];
                            sumg += src[ir - 1];
                            sumb += src[ir - 2];
                        }

                    sumr = sumr / count;
                    sumg = sumg / count;
                    sumb = sumb / count;

                    rr[countX, countY] = (byte)sumr;
                    gg[countX, countY] = (byte)sumg;
                    bb[countX, countY] = (byte)sumb;

                    if (sumr > 127)
                    { rrr = (byte)(sumr * 0.8); }
                    else
                    { rrr = (byte)(sumr * 1.2); }

                    if (sumg > 127)
                    { ggg = (byte)(sumg * 0.8); }
                    else
                    { ggg = (byte)(sumg * 1.2); }

                    if (sumb > 127)
                    { bbb = (byte)(sumb * 0.8); }
                    else
                    { bbb = (byte)(sumb * 1.2); }

                    for (int iy = y; iy < y + zone; iy++)
                        for (int ix = x; ix < x + zone; ix++)
                        {
                            if ((iy > h - 1) | (ix > w - 1)) continue;

                            ir = src.IndexR(ix, iy);
                            src[ir] = rrr;
                            src[ir - 1] = ggg;
                            src[ir - 2] = bbb;
                        }

                    countX++;

                }

                countY++;
            }

            src.Dispose();

            countY = 0;

            SolidBrush br = new SolidBrush(Color.Black);

            Rectangle rct = new Rectangle(0, 0, zone, zone);

            Graphics g = Graphics.FromImage(bmp);
            g.SmoothingMode = SmoothingMode.AntiAlias;

            for (int y = 0; y < h; y += zone)
            {
                countX = 0;

                for (int x = 0; x < w; x += zone)
                {
                    br.Color = Color.FromArgb(rr[countX, countY], gg[countX, countY],
                                                                   bb[countX, countY]);
                    rct.X = x; rct.Y = y;
                    g.FillEllipse(br, rct);

                    countX++;
                }

                countY++;
            }

            g.Dispose();
            br.Dispose();

            return true;
        }
        public static bool Pixelate3(ref Bitmap bmp, int zone)
        {
            if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
                return false;

            if ((zone < 2) | (zone > 30)) return false;

            int w = bmp.Width;
            int h = bmp.Height;

            int ir, count, sumr, sumg, sumb;

            byte[,] rr = new byte[w / zone + 1, h / zone + 1];
            byte[,] gg = new byte[w / zone + 1, h / zone + 1];
            byte[,] bb = new byte[w / zone + 1, h / zone + 1];

            int countX, countY;

            byte rrr, ggg, bbb;

            countY = 0;

            BmpProc24 src = new BmpProc24(bmp);

            for (int y = 0; y < h; y += zone)
            {
                countX = 0;

                for (int x = 0; x < w; x += zone)
                {
                    count = sumr = sumg = sumb = 0;

                    for (int iy = y; iy < y + zone; iy++)
                        for (int ix = x; ix < x + zone; ix++)
                        {
                            if ((iy > h - 1) | (ix > w - 1)) continue;

                            count++;

                            ir = src.IndexR(ix, iy);
                            sumr += src[ir];
                            sumg += src[ir - 1];
                            sumb += src[ir - 2];
                        }

                    sumr = sumr / count;
                    sumg = sumg / count;
                    sumb = sumb / count;

                    rr[countX, countY] = (byte)sumr;
                    gg[countX, countY] = (byte)sumg;
                    bb[countX, countY] = (byte)sumb;

                    rrr = (byte)sumr;
                    ggg = (byte)sumg;
                    bbb = (byte)sumb;

                    if ((sumr < 230) & (sumr > 15)) { rrr = (byte)(sumr - 15); }
                    if ((sumg < 230) & (sumg > 15)) { ggg = (byte)(sumg - 15); }
                    if ((sumb < 230) & (sumb > 15)) { bbb = (byte)(sumb - 15); }

                    for (int iy = y; iy < y + zone; iy++)
                        for (int ix = x; ix < x + zone; ix++)
                        {
                            if ((iy > h - 1) | (ix > w - 1)) continue;

                            ir = src.IndexR(ix, iy);
                            src[ir] = rrr;
                            src[ir - 1] = ggg;
                            src[ir - 2] = bbb;
                        }

                    countX++;

                }

                countY++;
            }

            src.Dispose();

            countY = 0;

            SolidBrush br = new SolidBrush(Color.Black);

            Point[] pt = new Point[3];

            Graphics g = Graphics.FromImage(bmp);
            g.SmoothingMode = SmoothingMode.AntiAlias;

            for (int y = 0; y < h; y += zone)
            {
                countX = 0;

                for (int x = 0; x < w; x += zone)
                {
                    rrr = rr[countX, countY]; ggg = gg[countX, countY];
                    bbb = bb[countX, countY];
                    if ((rrr < 230) & (rrr > 15)) { rrr = (byte)(rrr + 15); }
                    if ((ggg < 230) & (ggg > 15)) { ggg = (byte)(ggg + 15); }
                    if ((bbb < 230) & (bbb > 15)) { bbb = (byte)(bbb + 15); }
                    br.Color = Color.FromArgb(rrr, ggg, bbb);
                    pt[0].X = x; pt[0].Y = y;
                    pt[1].X = x + zone; pt[1].Y = y;
                    pt[2].X = x; pt[2].Y = y + zone;
                    g.FillPolygon(br, pt);

                    countX++;
                }

                countY++;
            }

            g.Dispose();
            br.Dispose();

            return true;
        }
        public static bool Pixelate(ref Bitmap bmp, int zone)
        {
            if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
                return false;

            if ((zone < 2) | (zone > 30)) return false;

            int w = bmp.Width;
            int h = bmp.Height;

            int ir, count, sumr, sumg, sumb;

            BmpProc24 src = new BmpProc24(bmp);

            for (int y = 0; y < h; y += zone)
                for (int x = 0; x < w; x += zone)
                {
                    count = sumr = sumg = sumb = 0;

                    for (int iy = y; iy < y + zone; iy++)
                        for (int ix = x; ix < x + zone; ix++)
                        {
                            if ((iy > h - 1) | (ix > w - 1)) continue;

                            count++;

                            ir = src.IndexR(ix, iy);
                            sumr += src[ir];
                            sumg += src[ir - 1];
                            sumb += src[ir - 2];
                        }

                    sumr = sumr / count;
                    sumg = sumg / count;
                    sumb = sumb / count;

                    for (int iy = y; iy < y + zone; iy++)
                        for (int ix = x; ix < x + zone; ix++)
                        {
                            if ((iy > h - 1) | (ix > w - 1)) continue;

                            ir = src.IndexR(ix, iy);
                            src[ir] = (byte)sumr;
                            src[ir - 1] = (byte)sumg;
                            src[ir - 2] = (byte)sumb;
                        }
                }

            src.Dispose();

            return true;
        }
        public static bool P2PCore(ref Bitmap bmp, P2PFunc func, params double[] param)
        {
            if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
                return false;

            int w = bmp.Width;
            int h = bmp.Height;

            byte r, g, b;
            int ir;

            BmpProc24 bd = new BmpProc24(bmp);

            for (int y = 0; y < h; y++)
                for (int x = 0; x < w; x++)
                {
                    ir = bd.IndexR(x, y);

                    r = bd[ir]; g = bd[ir - 1]; b = bd[ir - 2];

                    func(ref r, ref g, ref b, param);

                    bd[ir] = r; bd[ir - 1] = g; bd[ir - 2] = b;
                }

            bd.Dispose();

            return true;
        }
        public static bool HistoStretch24(ref Bitmap bmp, params double[] limit)
        {
            if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
                return false;

            int w = bmp.Width;
            int h = bmp.Height;

            double stretchfactor = 1.00;

            int threshold = (int)(w * h * 0.015);

            if (limit.Length != 0) threshold = (int)(w * h * limit[0] / 100);

            int hue, sat, lum, lt, ht;
            byte rr, gg, bb;

            double originalrange, stretchedrange, scalefactor;

            int[] hist = new int[256];

            BmpProc24 src = new BmpProc24(bmp);

            for (int y = 0; y < h; y++)
                for (int x = 0; x < w; x++)
                {
                    src.SetXY(x, y);
                    RGBToHSL(src.R, src.G, src.B, out hue, out sat, out lum);
                    hist[lum]++;
                }

            lt = 0;
            for (int i = 0; i < 256; i++)
            {
                lt += hist[i];
                if (lt > threshold)
                {
                    lt = i;
                    break;
                }
            }

            ht = 0;
            for (int i = 255; i >= 0; i--)
            {
                ht += hist[i];
                if (ht > threshold)
                {
                    ht = i;
                    break;
                }
            }

            originalrange = ht - lt + 1;
            stretchedrange = originalrange + stretchfactor * (255 - originalrange);
            scalefactor = stretchedrange / originalrange;

            for (int i = 0; i < 256; i++)
                hist[i] = AdjustByte(scalefactor * (i - lt));

            for (int y = 0; y < h; y++)
                for (int x = 0; x < w; x++)
                {
                    src.SetXY(x, y);
                    RGBToHSL(src.R, src.G, src.B, out hue, out sat, out lum);
                    lum = hist[lum];
                    HSLToRGB(hue, sat, lum, out rr, out gg, out bb);
                    src.R = rr;
                    src.G = gg;
                    src.B = bb;
                }

            src.Dispose();

            return true;
        }
        public static int CountColors(Bitmap bmp)
        {
            if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
                return -1;

            int w = bmp.Width;
            int h = bmp.Height;
            int num = w * h;

            int[] colors = new int[num];

            int indx = 0;
            int ir;

            BmpProc24 src = new BmpProc24(bmp);

            for (int y = 0; y < h; y++)
                for (int x = 0; x < w; x++)
                {
                    ir = src.IndexR(x, y);
                    colors[indx] =
                      (int)((((src[ir] << 8) | src[ir - 1]) << 8) | src[ir - 2]);
                    indx++;
                }

            src.Dispose();

            Array.Sort(colors);

            int count = 1;

            for (int i = 1; i < num; i++)
                if (colors[i - 1] != colors[i]) count++;

            return count;
        }
        public static bool BrightnessHistogram(Bitmap bmp, out Bitmap bmpHist)
        {
            if (bmp.PixelFormat != PixelFormat.Format24bppRgb)
            {
                bmpHist = null;
                return false;
            }

            int w = bmp.Width;
            int h = bmp.Height;

            int[] hist = new int[256];
            hist.Initialize();

            int ir, indx;

            BmpProc24 bd = new BmpProc24(bmp);

            for (int y = 0; y < h; y++)
                for (int x = 0; x < w; x++)
                {
                    ir = bd.IndexR(x, y);
                    indx = (int)(bd[ir] * 0.299 + bd[ir - 1] * 0.587 +
                                                           bd[ir - 2] * 0.114);
                    hist[indx]++;
                }

            bd.Dispose();

            int max = -1;
            for (int i = 0; i < 256; i++)
                if (hist[i] > max) max = hist[i];

            for (int i = 0; i < 256; i++)
                hist[i] = hist[i] * 140 / max;

            bmpHist = new Bitmap(275, 160, PixelFormat.Format24bppRgb);

            Graphics g = Graphics.FromImage(bmpHist);
            g.Clear(Color.AntiqueWhite);

            Pen pen = new Pen(Color.Gray, 1F);

            for (int i = 0; i < 256; i++)
                g.DrawLine(pen, 10 + i, 150, 10 + i, 150 - hist[i]);

            pen.Color = Color.Black;

            g.DrawLine(pen, 10, 150, 10, 10);

            for (int i = 0; i <= 20; i++)
                if ((i % 2) == 0)
                    g.DrawLine(pen, 10, 150 - 7 * i, 6, 150 - 7 * i);
                else
                    g.DrawLine(pen, 10, 150 - 7 * i, 8, 150 - 7 * i);

            g.DrawLine(pen, 10, 150, 10 + 255, 150);

            for (int i = 0; i <= 51; i++)
                if ((i % 2) == 0)
                    g.DrawLine(pen, 10 + 5 * i, 150, 10 + 5 * i, 154);
                else
                    g.DrawLine(pen, 10 + 5 * i, 150, 10 + 5 * i, 152);

            g.Dispose();

            return true;
        }