private void KMeansCPU(bool async = false)
        {
            DoubleColor[,] LABImageArray = new DoubleColor[SourceImageColorArray.GetLength(0), SourceImageColorArray.GetLength(1)];
            var cp = SourceImageColorProfile;

            var start1 = DateTime.Now;

            ColorProfileConverter.ConvertImageToLAB(SourceImageColorArray, LABImageArray, cp);
            DoubleColor[,] result;
            if (async == false)
            {
                result = KMeansCalc.CalculateKMeans(LABImageArray, KMeansParam, Globals.max_iter, Globals.eps);
            }
            else
            {
                result = KMeansCalc.CalculateKMeansAsync(LABImageArray, KMeansParam, Globals.max_iter, Globals.eps);
            }
            ColorProfileConverter.ConvertImageFromLAB(result, DestImageColorArray, cp);

            var end = DateTime.Now;

            string s = "";

            if (async == true)
            {
                s = "[ASYNC]";
            }

            Debug.WriteLine($"CPU TIME{s}: {end - start1}");

            Dispatcher.Invoke(() =>
            {
                Paint.CopyToWriteableBitmap(DestImageWB, DestImageColorArray);
            });
        }
        private void LoadWritableBitamp(BitmapSource bitmap, bool IsWindowInit)
        {
            SourceImageWB = new WriteableBitmap(bitmap);
            DestImageWB   = new WriteableBitmap(bitmap);

            int width  = SourceImageWB.PixelWidth;
            int height = SourceImageWB.PixelHeight;

            SourceImageControl.Source = SourceImageWB;
            SourceImageControl.Width  = width;
            SourceImageControl.Height = height;

            DestImageControl.Source = DestImageWB;
            DestImageControl.Width  = width;
            DestImageControl.Height = height;

            SourceImageColorArray = new SimpleColor[height, width];
            DestImageColorArray   = new SimpleColor[height, width];


            Paint.ReadColorsFromBitmap(SourceImageWB, SourceImageColorArray);
            OriginalSourceImageColorArray = (SimpleColor[, ])SourceImageColorArray.Clone();

            if (IsWindowInit == false)
            {
                ColorProfileConverter.ConvertImage(SourceImageColorArray, DestImageColorArray, (ColorProfileEnum)SourceColorSpaceComboBox.SelectedIndex, (ColorProfileEnum)DestColorSpaceComboBox.SelectedIndex);
                Paint.CopyToWriteableBitmap(DestImageWB, DestImageColorArray);
            }
            else
            {
                TryGenerate();
            }
        }
        private void DestColorSpaceComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (IsWindowInitialized == true)
            {
                var cb       = sender as ComboBox;
                int selected = cb.SelectedIndex;
                int from     = SourceColorSpaceComboBox.SelectedIndex;

                DestImageColorProfile = new ColorProfileNotifyChange(ColorProfileFactory.GetFactory().GetColorProfile((ColorProfileEnum)selected));

                ColorProfileConverter.ConvertImage(SourceImageColorArray, DestImageColorArray, (ColorProfileEnum)from, (ColorProfileEnum)selected);
                Paint.CopyToWriteableBitmap(DestImageWB, DestImageColorArray);
            }
        }
        private void TestButtonRadioButton_Click(object sender, RoutedEventArgs e)
        {
            var tab1 = new float[2];
            var tab2 = new float[2];
            var tab3 = new float[2];

            for (int i = 0; i < tab1.Length; i++)
            {
                if (i == 0)
                {
                    tab1[i] = 1f;
                    tab2[i] = 1f;
                    tab3[i] = 1f;
                }
                else
                {
                    tab1[i] = 2f;
                    tab2[i] = 2f;
                    tab3[i] = 2f;
                }
            }

            var inttab1 = new int[10];
            var inttab2 = new int[10];

            for (int i = 0; i < inttab1.Length; i++)
            {
                inttab1[i] = 3;
                inttab2[i] = 7;
            }

            DoubleColor[,] LABImageArray = new DoubleColor[SourceImageColorArray.GetLength(0), SourceImageColorArray.GetLength(1)];
            int from = SourceColorSpaceComboBox.SelectedIndex;

            ColorProfileConverter.ConvertImageToLAB(SourceImageColorArray, LABImageArray, (ColorProfileEnum)from);


            int rows = LABImageArray.GetLength(0);
            int cols = LABImageArray.GetLength(1);

            var vector_x = new float[rows * cols];
            var vector_y = new float[rows * cols];
            var vector_z = new float[rows * cols];

            for (int x = 0; x < rows; x++)
            {
                for (int y = 0; y < cols; y++)
                {
                    vector_x[y + x * cols] = (float)LABImageArray[x, y].R;
                    vector_y[y + x * cols] = (float)LABImageArray[x, y].G;
                    vector_z[y + x * cols] = (float)LABImageArray[x, y].B;
                }
            }

            using (var wrapper = new Logic())
            {
                //var result = wrapper.addParallelVectors(inttab1, inttab2, inttab1.Length);

                //for (int i = 0; i < result.Length; i++)
                //{
                //    Debug.Write($"{result[i]}, ");
                //}
                //Debug.WriteLine("");
                var iters = wrapper.KMeansGather(tab1, tab2, tab3, tab1.Length, 1, MaxIter);
                Debug.WriteLine($"KMEANS: Iters: {iters}");
                for (int i = 0; i < tab1.Length; i++)
                {
                    Debug.WriteLine($"X: {tab1[i]} Y: {tab2[i]} Z: {tab3[i]}");
                }


                var img_iters = wrapper.KMeansGather(vector_x, vector_y, vector_z, vector_x.Length, KMeansParam, MaxIter);
                Debug.WriteLine($"Image iterations: {img_iters}");
            }

            for (int x = 0; x < rows; x++)
            {
                for (int y = 0; y < cols; y++)
                {
                    LABImageArray[x, y].R = vector_x[y + x * cols];
                    LABImageArray[x, y].G = vector_y[y + x * cols];
                    LABImageArray[x, y].B = vector_z[y + x * cols];
                }
            }

            ColorProfileConverter.ConvertImageFromLAB(LABImageArray, DestImageColorArray, (ColorProfileEnum)from);

            Paint.CopyToWriteableBitmap(DestImageWB, DestImageColorArray);
        }
        private bool TryGenerate(bool paint = true)
        {
            var isValid = ValidateTextBoxes();

            if (isValid.IsSourceValid == false && isValid.IsDestValid == false)
            {
                var info = new StringBuilder();
                info.AppendLine("Error in source and destination color space!");
                MessageBox.Show(info.ToString(), Globals.WindowName, MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }
            else if (isValid.IsSourceValid == false)
            {
                var info = new StringBuilder();
                info.AppendLine("Error in source color space!");
                MessageBox.Show(info.ToString(), Globals.WindowName, MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }
            else if (isValid.IsDestValid == false)
            {
                var info = new StringBuilder();
                info.AppendLine("Error in destination color space!");
                MessageBox.Show(info.ToString(), Globals.WindowName, MessageBoxButton.OK, MessageBoxImage.Error);
                return(false);
            }
            if (SourceImageColorProfile.HasChanged == false && DestImageColorProfile.HasChanged == false)
            {
                if (paint == true)
                {
                    int from = SourceColorSpaceComboBox.SelectedIndex;
                    int to   = DestColorSpaceComboBox.SelectedIndex;
                    ColorProfileConverter.ConvertImage(SourceImageColorArray, DestImageColorArray, (ColorProfileEnum)from, (ColorProfileEnum)to);
                    Paint.CopyToWriteableBitmap(DestImageWB, DestImageColorArray);
                }
            }
            else
            {
                var sourceValidation = SourceImageColorProfile.Validate();
                var destValidation   = DestImageColorProfile.Validate();
                if (sourceValidation.isValid == false && destValidation.isValid == false)
                {
                    //error
                    var info = new StringBuilder();
                    info.AppendLine("Error in source and destination color space:");
                    info.AppendLine("Source: " + sourceValidation.info);
                    info.Append("Destination: " + destValidation.info);

                    MessageBox.Show(info.ToString(), Globals.WindowName, MessageBoxButton.OK, MessageBoxImage.Error);
                    return(false);
                }
                else if (sourceValidation.isValid == false)
                {
                    //error
                    var info = new StringBuilder();
                    info.AppendLine("Error in source color space:");
                    info.Append(sourceValidation.info);

                    MessageBox.Show(info.ToString(), Globals.WindowName, MessageBoxButton.OK, MessageBoxImage.Error);
                    return(false);
                }
                else if (destValidation.isValid == false)
                {
                    //error
                    var info = new StringBuilder();
                    info.AppendLine("Error in destination color space:");
                    info.Append(destValidation.info);

                    MessageBox.Show(info.ToString(), Globals.WindowName, MessageBoxButton.OK, MessageBoxImage.Error);
                    return(false);
                }
                else
                {
                    if (paint == true)
                    {
                        ColorProfileConverter.ConvertImage(SourceImageColorArray, DestImageColorArray, SourceImageColorProfile, DestImageColorProfile);
                        Paint.CopyToWriteableBitmap(DestImageWB, DestImageColorArray);
                    }
                }
            }
            return(true);
        }