/// <summary>
        ///  Writes the bitmap buffer to <paramref name="pngFile"/> and optional performs expansion if
        ///  <paramref name="expand"/> is true.
        /// </summary>
        /// <param name="buffer">The buffer to the image bits.</param>
        /// <param name="std">The HG3STDINFO containing image dimensions, etc.</param>
        /// <param name="expand">True if the image should be expanded to its full size.</param>
        /// <param name="pngFile">The path to the file to save to.</param>
        private static void WriteJpegToPng(byte[] buffer, HG3STDINFO std, HgxOptions options, string pngFile)
        {
            int         depthBytes   = (std.DepthBits + 7) / 8;
            int         stride       = (std.Width * depthBytes + 3) & ~3;
            PixelFormat expandFormat = PixelFormat.Format32bppArgb;
            // Do expansion here, and up to 32 bits if not 32 bits already.
            bool expand = options.HasFlag(HgxOptions.Expand);

            if (expand && (std.Width != std.TotalWidth || std.Height != std.TotalHeight))
            {
                using (var ms = new MemoryStream(buffer))
                    using (var jpeg = (Bitmap)Image.FromStream(ms))
                        using (var bitmapExpand = new Bitmap(std.TotalWidth, std.TotalHeight, expandFormat))
                            using (Graphics g = Graphics.FromImage(bitmapExpand)) {
                                if (options.HasFlag(HgxOptions.Flip))
                                {
                                    jpeg.RotateFlip(RotateFlipType.RotateNoneFlipY);
                                }
                                g.DrawImageUnscaled(jpeg, std.OffsetX, std.OffsetY);
                                bitmapExpand.Save(pngFile, ImageFormat.Png);
                            }
            }
            else
            {
                using (var ms = new MemoryStream(buffer))
                    using (var jpeg = (Bitmap)Image.FromStream(ms)) {
                        if (options.HasFlag(HgxOptions.Flip))
                        {
                            jpeg.RotateFlip(RotateFlipType.RotateNoneFlipY);
                        }
                        jpeg.Save(pngFile, ImageFormat.Png);
                    }
            }
        }
        /// <summary>
        ///  Writes the bitmap buffer to <paramref name="pngFile"/> and optional performs expansion if
        ///  <paramref name="expand"/> is true.
        /// </summary>
        /// <param name="buffer">The buffer to the image bits.</param>
        /// <param name="std">The HG3STDINFO containing image dimensions, etc.</param>
        /// <param name="expand">True if the image should be expanded to its full size.</param>
        /// <param name="pngFile">The path to the file to save to.</param>
        private static void WritePng(byte[] buffer, HG2IMG std, HgxOptions options, string pngFile)
        {
            GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);

            try {
                IntPtr      scan0 = handle.AddrOfPinnedObject();
                int         depthBytes = (std.DepthBits + 7) / 8;
                int         stride = (std.Width * depthBytes + 3) & ~3;
                PixelFormat format, expandFormat = PixelFormat.Format32bppArgb;
                switch (std.DepthBits)
                {
                case 24: format = PixelFormat.Format24bppRgb; break;

                case 32: format = PixelFormat.Format32bppArgb; break;

                default: throw new HgxException($"Unsupported depth bits {std.DepthBits}!");
                }
                // Do expansion here, and up to 32 bits if not 32 bits already.
                bool expand = options.HasFlag(HgxOptions.Expand);
                if (expand && (std.Width != std.TotalWidth || std.Height != std.TotalHeight))
                {
                    using (var bitmap = new Bitmap(std.Width, std.Height, stride, format, scan0))
                        using (var bitmapExpand = new Bitmap(std.TotalWidth, std.TotalHeight, expandFormat))
                            using (Graphics g = Graphics.FromImage(bitmapExpand)) {
                                if (options.HasFlag(HgxOptions.Flip))
                                {
                                    bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
                                }
                                g.DrawImageUnscaled(bitmap, std.OffsetX, std.OffsetY);
                                bitmapExpand.Save(pngFile, ImageFormat.Png);
                            }
                }
                else
                {
                    using (var bitmap = new Bitmap(std.Width, std.Height, stride, format, scan0)) {
                        if (options.HasFlag(HgxOptions.Flip))
                        {
                            bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
                        }
                        bitmap.Save(pngFile, ImageFormat.Png);
                    }
                }
            } finally {
                // Thing to note that gave me headaches earlier:
                //  Once this handle is freed, the bitmap loaded from
                //  scan0 will be invalidated after garbage collection.
                handle.Free();
            }
        }
        /// <summary>
        ///  Writes the bitmap buffer to <paramref name="pngFile"/> and optional performs expansion if
        ///  <paramref name="expand"/> is true.
        /// </summary>
        /// <param name="buffer">The buffer to the image bits.</param>
        /// <param name="std">The HG3STDINFO containing image dimensions, etc.</param>
        /// <param name="expand">True if the image should be expanded to its full size.</param>
        /// <param name="pngFile">The path to the file to save to.</param>
        private static unsafe void WriteJpegAlphaMaskToPng(byte[] buffer, byte[] alpha, HG3STDINFO std,
                                                           HgxOptions options, string pngFile)
        {
            bool expand = options.HasFlag(HgxOptions.Expand);

            expand = expand && (std.Width != std.TotalWidth || std.Height != std.TotalHeight);
            int offsetX = (expand ? std.OffsetX : 0);
            int offsetY = (expand ? std.OffsetY : 0);
            int width   = (expand ? std.TotalWidth  : std.Width);
            int height  = (expand ? std.TotalHeight : std.Height);

            int        depthBytes = 4;
            int        jpgStride = std.Width * depthBytes;
            int        stride = width * depthBytes;
            int        bufferSize = height * stride;
            int        alphaStride = std.Width;
            BitmapData jpgData = null, bmpData = null;

            using (var ms = new MemoryStream(buffer))
                using (var jpeg = (Bitmap)Image.FromStream(ms))
                    using (var bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb)) {
                        try {
                            Rectangle rect = new Rectangle(0, 0, std.Width, std.Height);
                            jpgData = jpeg.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                            bmpData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                            byte *pJpg = (byte *)jpgData.Scan0.ToPointer();
                            byte *pBmp = (byte *)bmpData.Scan0.ToPointer();

                            // Copy over the jpeg pixels first
                            if (expand)
                            {
                                for (int y = 0; y < std.Height; y++)
                                {
                                    int src = y * jpgStride;
                                    int dst = (y + offsetY) * stride + offsetX * depthBytes;
                                    Buffer.MemoryCopy(pJpg + src, pBmp + dst, bufferSize, jpgStride);
                                }
                            }
                            else
                            {
                                Buffer.MemoryCopy(pJpg, pBmp, bufferSize, bufferSize);
                            }

                            // Now apply the alpha to the pixels
                            for (int y = 0; y < std.Height; y++)
                            {
                                int src = y * alphaStride;
                                int dst = (y + offsetY) * stride;
                                for (int x = 0; x < std.Width; x++)
                                {
                                    int alphaIndex = src + x;
                                    int pixelIndex = dst + (x + offsetX) * depthBytes;

                                    pBmp[pixelIndex + 3] = alpha[alphaIndex];
                                }
                            }
                        } finally {
                            if (jpgData != null)
                            {
                                jpeg.UnlockBits(jpgData);
                            }
                            if (bmpData != null)
                            {
                                bitmap.UnlockBits(bmpData);
                            }
                        }
                        if (options.HasFlag(HgxOptions.Flip))
                        {
                            bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
                        }
                        bitmap.Save(pngFile, ImageFormat.Png);
                    }
        }