protected override unsafe void OnUpdatePlaneImage(Bitmap bmp)
        {
            if (bmp.PixelFormat != PixelFormat.Format32bppArgb)
            {
                return;
            }
            BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
                                         ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
            ColorBgra *scan0 = (ColorBgra *)bd.Scan0;
            //draw plane image
            LAB curr = new LAB(_color.L, -128.0, 127.0);
            double
                delta_a = 255.0 / (double)bd.Width,
                delta_b = -255.0 / (double)bd.Height;

            for (int y = 0; y < bd.Height; y++, curr.a = -128.0, curr.b += delta_b)
            {
                for (int x = 0; x < bd.Width; x++, scan0++, curr.a += delta_a)
                {
                    scan0[0] = ColorBgra.FromArgb(curr.ToXYZ().ToRGB());
                }
            }
            //end
            bmp.UnlockBits(bd);
        }
        protected override unsafe void OnUpdateFaderImage(Bitmap bmp)
        {
            if (bmp.PixelFormat != PixelFormat.Format32bppArgb)
            {
                return;
            }
            BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),
                                         ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
            ColorBgra *scan0 = (ColorBgra *)bd.Scan0;
            //draw fader image
            LAB    curr    = new LAB(0.0, _color.a, _color.b);
            double delta_L = 100.0 / (double)bd.Width;

            for (int x = 0; x < bd.Width; x++, scan0++, curr.L += delta_L)
            {
                scan0[0] = ColorBgra.FromArgb(curr.ToXYZ().ToRGB());
            }
            //end
            bmp.UnlockBits(bd);
        }