public void RenderCMYPlane(CMYAxisDefinitions AxisLayout, int Z, Image OutImage, double SurfaceWidth, double SurfaceHeight)
        {
            List <ColorBlenderInterface.ColorBlock> ColorBlocks = new List <ColorBlenderInterface.ColorBlock>();
            ColorBlenderInterface cbi = new ColorBlenderInterface();
            int FinalStride           = (int)SurfaceWidth * 4;

            byte[] PixelMap   = new byte[(int)SurfaceHeight * FinalStride];
            int    CellWidth  = (int)SurfaceWidth / 256;
            int    CellHeight = (int)SurfaceHeight / 256;

            for (int x = 0; x < 256; x++)
            {
                for (int y = 0; y < 256; y++)
                {
                    Color CellColor = GetCMYColorAt(x, y, Z, AxisLayout);
                    ColorBlenderInterface.ColorBlock CB = new ColorBlenderInterface.ColorBlock();
                    CB.Left       = x * CellWidth;
                    CB.Top        = y * CellHeight;
                    CB.Width      = CellWidth;
                    CB.Height     = CellHeight;
                    CB.BlockColor = CellColor.ToBGRA();
                    ColorBlocks.Add(CB);
                }
            }

            cbi.DrawColorBlocks(ref PixelMap, (int)SurfaceWidth, (int)SurfaceHeight, FinalStride, ColorBlocks, Colors.Transparent);
            if (!OutImage.Dispatcher.CheckAccess())
            {
                OutImage.Dispatcher.Invoke
                (
                    System.Windows.Threading.DispatcherPriority.Normal,
                    new Action
                    (
                        delegate()
                {
                    OutImage.Source = BitmapSource.Create((int)SurfaceWidth, (int)SurfaceHeight, 96.0, 96.0, PixelFormats.Bgra32,
                                                          null, PixelMap, FinalStride);
                }
                    )
                );
            }
            else
            {
                OutImage.Source = BitmapSource.Create((int)SurfaceWidth, (int)SurfaceHeight, 96.0, 96.0, PixelFormats.Bgra32,
                                                      null, PixelMap, FinalStride);
            }
        }
        private Color GetCMYColorAt(int C, int M, int Y, CMYAxisDefinitions AxisLayout)
        {
            byte r = 0;
            byte g = 0;
            byte b = 0;

            switch (AxisLayout)
            {
            case CMYAxisDefinitions.CMY:
                CMYtoRGB((byte)C, (byte)M, (byte)Y, out r, out g, out b);
                break;

            case CMYAxisDefinitions.CYM:
                CMYtoRGB((byte)C, (byte)Y, (byte)M, out r, out g, out b);
                break;

            case CMYAxisDefinitions.MCY:
                CMYtoRGB((byte)M, (byte)C, (byte)Y, out r, out g, out b);
                break;

            case CMYAxisDefinitions.MYC:
                CMYtoRGB((byte)M, (byte)Y, (byte)C, out r, out g, out b);
                break;

            case CMYAxisDefinitions.YCM:
                CMYtoRGB((byte)Y, (byte)C, (byte)M, out r, out g, out b);
                break;

            case CMYAxisDefinitions.YMC:
                CMYtoRGB((byte)Y, (byte)M, (byte)C, out r, out g, out b);
                break;

            default:
                throw new InvalidOperationException("Unexpected axis layout.");
            }
            return(Color.FromRgb(r, g, b));
        }