/*public RGBA[] byteToRGBA(byte[] input, int width, int height)
        {
            RGBA[] output = new RGBA[width * height];

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    try
                    {
                        output[x + y * width] = new RGBA();
                        output[x + y * width].B = (input[4 * x + y * (4 * width) + 0] / 255.0);
                        output[x + y * width].G = (input[4 * x + y * (4 * width) + 1] / 255.0);
                        output[x + y * width].R = (input[4 * x + y * (4 * width) + 2] / 255.0);
                        output[x + y * width].A = 255; // (input[4 * x + y * (4 * width) + 3]);
                        // For now, the tools are applied by capturing the current screen, manipulate the resulting image and save it onto a new overlay.
                        // alpha channel is set to 255 to prevent "double layer" effect created by nonconsistency between the original image and the new overlay.
                        // ALPHA CHANNEL SHOULD BE SET TO THE INPUT ALPHA CHANNEL WHEN MANIPULATING THE ORIGINAL IMAGE
                    }
                    catch (NullReferenceException e)
                    {
                        MessageBox.Show(e.Message);
                    }
                }
            }
            return output;
        }

        public byte[] RGBAToByte(RGBA[] input)
        {
            byte[] output = new byte[input.Length * 4];
            for (int x = 0; x < ImageWidth; x++)
            {
                for (int y = 0; y < ImageHeight; y++)
                {
                    int inputIndex = (ImageWidth - 1 - x) + (ImageHeight - 1 - y) * ImageWidth;
                    int outputIndex = 4 * (x) + (y) * (4 * ImageWidth);
                    output[outputIndex + 2] = (byte)(input[inputIndex].R * 255.0);
                    output[outputIndex + 1] = (byte)(input[inputIndex].G * 255.0);
                    output[outputIndex + 0] = (byte)(input[inputIndex].B * 255.0);
                    output[outputIndex + 3] = (byte)(input[inputIndex].A);
                }
            }
            return output;
        }*/
        /// <summary>
        /// Change from RGB color to HSV color
        /// not used.
        /// </summary>
        public HSV[] RGBtoHSV(RGBA[] input)
        {
            HSV[] output = new HSV[input.Length];
            double min, max, delta;
            double r, g, b, h, s, v;

            for (int x = 0; x < ImageWidth; x++)
            {
                for (int y = 0; y < ImageHeight; y++)
                {
                    output[x + y * ImageWidth] = new HSV();
                    r = input[x + y * ImageWidth].R;
                    g = input[x + y * ImageWidth].G;
                    b = input[x + y * ImageWidth].B;

                    min = Utils.min(r, g, b);
                    max = Utils.max(r, g, b);
                    v = max;				// v

                    delta = max - min;

                    if (max != 0)
                    {
                        s = delta / max;		// s
                        if (r == max)
                            h = (g - b) / delta;		// between yellow & magenta
                        else if (g == max)
                            h = 2 + (b - r) / delta;	// between cyan & yellow
                        else
                            h = 4 + (r - g) / delta;	// between magenta & cyan
                        h *= 60;				// degrees
                        if (h < 0)
                            h += 360;
                    }
                    else
                    {
                        // r = g = b = 0		// s = 0, v is undefined
                        s = 0;
                        h = -1;
                    }

                    output[x + y * ImageWidth].H = h;
                    output[x + y * ImageWidth].S = s;
                    output[x + y * ImageWidth].V = v;

                }
            }
            return output;
        }
        /// <summary>
        /// change from HSV to RGB
        /// not used.
        /// </summary>
        public RGBA[] HSVtoRGB(HSV[] input)
        {
            RGBA[] output = new RGBA[input.Length];

            int i;
            double f, p, q, t;
            double h, s, v, r, g, b;

            for (int x = 0; x < ImageWidth; x++)
            {
                for (int y = 0; y < ImageHeight; y++)
                {
                    output[x + y * ImageWidth] = new RGBA();
                    h = input[x + y * ImageWidth].H;
                    s = input[x + y * ImageWidth].S;
                    v = input[x + y * ImageWidth].V;

                    r = g = b = 0;

                    if (s == 0)
                    {
                        // achromatic (grey)
                        r = g = b = v;

                    }
                    else
                    {

                        h /= 60.0;			// sector 0 to 5
                        i = (int)h;
                        f = h - i;			// factorial part of h
                        p = v * (1 - s);
                        q = v * (1 - s * f);
                        t = v * (1 - s * (1 - f));

                        switch (i)
                        {
                            case 0:
                                r = v;
                                g = t;
                                b = p;
                                break;
                            case 1:
                                r = q;
                                g = v;
                                b = p;
                                break;
                            case 2:
                                r = p;
                                g = v;
                                b = t;
                                break;
                            case 3:
                                r = p;
                                g = q;
                                b = v;
                                break;
                            case 4:
                                r = t;
                                g = p;
                                b = v;
                                break;
                            case 5:		// case 5:
                                r = v;
                                g = p;
                                b = q;
                                break;
                            case 6:
                                r = v;
                                g = p;
                                b = q;
                                break;
                        }
                    }
                    output[x + y * ImageWidth].R = r;
                    output[x + y * ImageWidth].G = g;
                    output[x + y * ImageWidth].B = b;
                    // output[x + y * ImageWidth].A = 255;
                }
            }
            return output;
        }