public static PlanarImage FromBitmap(Bitmap source, PixelAlignmentType format, ColorSpace colorspace = ColorSpace.DEFAULT)
        {
            IntPtr context = SwScale.sws_getContext(source.Width, source.Height, m_rgbMapper[source.PixelFormat],
                                                    source.Width, source.Height, m_pixelTypeMapper[format],
                                                    SwScale.ConvertionFlags.SWS_BICUBIC, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);

            int *pCoef = SwScale.sws_getCoefficients(colorspace);
            int *inv_table;
            int *table;
            int  srcRange, dstRange, brightness, contrast, saturation;

            int result = SwScale.sws_getColorspaceDetails(context, out inv_table, out srcRange, out table, out dstRange, out brightness, out contrast, out saturation);

            if (result != -1)
            {
                result = SwScale.sws_setColorspaceDetails(context, pCoef, srcRange, table, dstRange, brightness, contrast, saturation);
            }

            PlanarImage yuv  = new PlanarImage(source.Width, source.Height, format);
            BitmapData  data = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, source.PixelFormat);

            unsafe
            {
                pInput[0] = (byte *)data.Scan0.ToPointer();
                result    = SwScale.sws_scale(context, pInput, new int[] { data.Stride, 0, 0, 0 }, 0, source.Height, yuv.PixelDataPointer, yuv.Pitches);
                if (result != yuv.Height)
                {
                    throw new InvalidOperationException();
                }
            }

            source.UnlockBits(data);
            SwScale.sws_freeContext(context);
            return(yuv);
        }
        public static Bitmap ToBitmap(PlanarImage source, PixelFormat format, ColorSpace colorspace = ColorSpace.DEFAULT)
        {
            IntPtr context = SwScale.sws_getContext(source.Width, source.Height, m_pixelTypeMapper[source.PixelType],
                                                    source.Width, source.Height, m_rgbMapper[format],
                                                    SwScale.ConvertionFlags.SWS_BICUBIC, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);


            int *pCoef = SwScale.sws_getCoefficients(colorspace);
            int *inv_table;
            int *table;
            int  srcRange, dstRange, brightness, contrast, saturation;

            int result = SwScale.sws_getColorspaceDetails(context, out inv_table, out srcRange, out table, out dstRange, out brightness, out contrast, out saturation);

            if (result != -1)
            {
                result = SwScale.sws_setColorspaceDetails(context, pCoef, srcRange, pCoef, dstRange, brightness, contrast, saturation);
            }

            Bitmap     bmp  = new Bitmap(source.Width, source.Height, format);
            BitmapData data = bmp.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadWrite, format);

            unsafe
            {
                pInput[0] = (byte *)data.Scan0.ToPointer();

                result = SwScale.sws_scale(context, source.PixelDataPointer, source.Pitches, 0, source.Height, pInput, new int[] { data.Stride, 0, 0, 0 });
                if (result != source.Height)
                {
                    throw new InvalidOperationException();
                }
            }

            bmp.UnlockBits(data);
            if (bmp.Palette != null && bmp.Palette.Entries != null && bmp.Palette.Entries.Length > 0)
            {
                ColorPalette cp = bmp.Palette;
                for (int i = 0; i < cp.Entries.Length; i++)
                {
                    cp.Entries[i] = Color.FromArgb(i, i, i);
                }
                bmp.Palette = cp;
            }

            SwScale.sws_freeContext(context);
            return(bmp);
        }