static Image NormalizeImage(Image image)
        {
            const int bitsPerComponent = 8;
            int       components;
            uint      flags = 0;

            byte [] buffer;

            switch (image.Format)
            {
            case ImageFormat.Rgb24:
            case ImageFormat.Bgr24:
                components = 3;
                break;

            case ImageFormat.Bgra32:
                components = 4;
                flags      = (uint)CGBitmapFlags.ByteOrder32Little | (uint)CGImageAlphaInfo.First;
                break;

            case ImageFormat.Rgba32:
                components = 4;
                flags      = (uint)CGImageAlphaInfo.Last;
                break;

            default:
                return(null);
            }

            switch (image.Format)
            {
            case ImageFormat.Bgr24:
                // FIXME: ugh, CGImage really does not want 24bpp in BGR order...
                // No CGBitmapFlags can convince it to do the channel swap unless
                // the buffer is 32bpp.
                buffer = new byte [image.Data.Length];
                Array.Copy(image.Data, buffer, buffer.Length);
                for (int i = 0; i < buffer.Length; i += components)
                {
                    var b = buffer [i];
                    buffer [i]     = buffer [i + 2];
                    buffer [i + 2] = b;
                }
                break;

            default:
                buffer = image.Data;
                break;
            }

            using (NativeExceptionHandler.Trap())
                return(new CGImage(
                           image.Width,
                           image.Height,
                           bitsPerComponent,
                           bitsPerComponent * components,
                           image.Width * components,
                           CGColorSpace.CreateDeviceRGB(),
                           (CGBitmapFlags)flags,
                           new CGDataProvider(buffer),
                           null,
                           false,
                           CGColorRenderingIntent.AbsoluteColorimetric).RemoteRepresentation());
        }
 public override IDisposable TrapNativeExceptions() => NativeExceptionHandler.Trap();