public static void RgbToHsl(int rr, int gg, int bb, HslColor hsl)
        {
            double r = (rr / 255.0);
            double g = (gg / 255.0);
            double b = (bb / 255.0);

            double min = Math.Min(Math.Min(r, g), b);
            double max = Math.Max(Math.Max(r, g), b);
            double delta = max - min;

            // get luminance value
            hsl.l = (float)(max + min) / 2;

            if (delta == 0)
            {
                // gray color
                hsl.h = 0;
                hsl.s = 0.0f;
            }
            else
            {
                // get saturation value
                hsl.s = (float)((hsl.l < 0.5) ? (delta / (max + min)) : (delta / (2 - max - min)));

                // get hue value
                double del_r = (((max - r) / 6) + (delta / 2)) / delta;
                double del_g = (((max - g) / 6) + (delta / 2)) / delta;
                double del_b = (((max - b) / 6) + (delta / 2)) / delta;
                double hue;

                if (r == max)
                    hue = del_b - del_g;
                else if (g == max)
                    hue = (1.0 / 3) + del_r - del_b;
                else
                    hue = (2.0 / 3) + del_g - del_r;

                // correct hue if needed
                if (hue < 0)
                    hue += 1;
                if (hue > 1)
                    hue -= 1;

                hsl.h = (int)(hue * 360);
            }
        }
        public Image process(Image imageIn)
        {
            int r, g, b;
            HslColor hsl = new HslColor(HueFactor, 0, 0);

            for (int x = 0; x < imageIn.getWidth(); x++) {
                for (int y = 0; y < imageIn.getHeight(); y++) {
             	    r = imageIn.getRComponent(x, y);
                    g = imageIn.getGComponent(x, y);
                    b = imageIn.getBComponent(x, y);

                    HslColor.RgbToHsl(r, g, b, hsl);
                    hsl.h = this.HueFactor;
                    int color = HslColor.HslToRgb(hsl);
                    imageIn.setPixelColor(x, y, color);
                }
            }
            return imageIn;
        }
        public static int HslToRgb(HslColor hsl)
        {
            int r, g, b;
            if (hsl.h == 0)
            {
                // gray values
                r = g = b = (byte)(hsl.l * 255);
            }
            else
            {
                double v1, v2;
                double hue = (double)hsl.h / 360;

                v2 = (hsl.l < 0.5) ?
                    (hsl.l * (1 + hsl.s)) :
                    ((hsl.l + hsl.s) - (hsl.l * hsl.s));
                v1 = 2 * hsl.l - v2;

                r = (byte)(255 * Hue_2_RGB(v1, v2, hue + (1.0 / 3)));
                g = (byte)(255 * Hue_2_RGB(v1, v2, hue));
                b = (byte)(255 * Hue_2_RGB(v1, v2, hue - (1.0 / 3)));
            }
            return (255 << 24) + (r << 16) + (g << 8) + b;
        }
 public static void RgbToHsl(int color, HslColor hsl)
 {
     RgbToHsl(0xff & (color >> 0x10), 0xff & (color >> 8), 0xff & color, hsl);
 }
 public HslColor Interpolate(HslColor c2, float amount)
 {
     return new HslColor(this.h + ((c2.h - this.h) * amount), this.s + ((c2.s - this.s) * amount), this.l + ((c2.l - this.l) * amount));
 }
 public static void RgbToHsl(int color, HslColor hsl)
 {
     RgbToHsl(0xff & (color >> 0x10), 0xff & (color >> 8), 0xff & color, hsl);
 }
 public HslColor Interpolate(HslColor c2, float amount)
 {
     return(new HslColor(this.h + ((c2.h - this.h) * amount), this.s + ((c2.s - this.s) * amount), this.l + ((c2.l - this.l) * amount)));
 }