public long AllocateImage()
        {
            var size = ComputeTotalImageSize();

            image = SKMask.AllocateImage(size);
            return(size);
        }
        public static SKMask Create(byte[] image, SKRectI bounds, UInt32 rowBytes, SKMaskFormat format)
        {
            // create the mask
            var mask = new SKMask(bounds, rowBytes, format);

            // is there the right amount of space in the mask
            if (image.Length != mask.ComputeTotalImageSize())
            {
                // Note: buffer.Length must match bounds.Height * rowBytes
                var expectedHeight = bounds.Height * rowBytes;
                var message        = $"Length of image ({image.Length}) does not match the computed size of the mask ({expectedHeight}). Check the {nameof(bounds)} and {nameof(rowBytes)}.";
                throw new ArgumentException(message);
            }

            // copy the image data
            mask.AllocateImage();
            Marshal.Copy(image, 0, mask.image, image.Length);

            // return the mask
            return(mask);
        }