/// <summary>
        /// Allocates a new native CVPixelBuffer object using the pixels of the specified WebCamTexture.
        /// This factory method will not throw, and instead returns a value indicating whether the allocation was successful.
        /// </summary>
        /// <param name="fromWebCamTexture">A managed byte buffer containing the pixels of this texture will get extracted and retained.</param>
        /// <param name="result">A managed wrapper instance of the native CVPixelBuffer object.</param>
        /// <param name="alignPixelFormat">Set this argument to true, if the resulting pixel buffer needs to be color accurate.</param>
        /// <returns>The result of the Core Video operation.</returns>
        public static CVReturn TryCreate(WebCamTexture fromWebCamTexture, out CVPixelBuffer result, bool alignPixelFormat = true)
        {
            var buffer = fromWebCamTexture.GetPixels32().ToByteArray();

            if (alignPixelFormat)
            {
                ShiftRGBAToARGB(ref buffer);
            }

            return(TryCreate(buffer, fromWebCamTexture.width, fromWebCamTexture.height, PixelFormat.ARGB32, out result));
        }
        /// <summary>
        /// Allocates a new native CVPixelBuffer object that will reference the specified buffer.
        /// The specified array is retained and will not be released until the managed wrapper object is not disposed.
        /// This factory method will not throw, and instead returns a value indicating whether the allocation was successful.
        /// </summary>
        /// <param name="fromBuffer">A flattened 2D array. Each 4 values represent a single pixel. Pixels are laid out left to right, bottom to top (i.e. row after row).</param>
        /// <param name="width">The width of the image that the specified buffer represents.</param>
        /// <param name="height">The height of the image that the specified buffer represents.</param>
        /// <param name="format">The color layout of an individual pixel.</param>
        /// <param name="result">A managed wrapper instance of the native CVPixelBuffer object.</param>
        /// <returns>The result of the Core Video operation.</returns>
        public static CVReturn TryCreate(byte[] fromBuffer, int width, int height, PixelFormat format, out CVPixelBuffer result)
        {
            // Capture the managed buffer object
            var handle = GCHandle.Alloc(fromBuffer, GCHandleType.Pinned);

            // This will contain the address of the native CVPixelBuffer object, if created
            IntPtr pixelBufferPtr;

            // Attempt to create the native buffer, using texture data from the captured array
            var operationResult = (CVReturn)_vision_allocateCVPixelBuffer(
                address: handle.AddrOfPinnedObject(),
                width: width, height: height, format: (int)format,
                outPixelBufferPtr: out pixelBufferPtr);

            result = new CVPixelBuffer
            {
                _nativePtr           = pixelBufferPtr,
                _managedBufferHandle = handle
            };

            return(operationResult);
        }