/// <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>
        ///  Extracts the <see cref="HG2IMG"/> from the HG-2 file.
        /// </summary>
        /// <param name="reader">The binary reader for the file.</param>
        /// <param name="std">The HG3STDINFO containing image dimensions, etc.</param>
        /// <param name="img">The image header used to process the image.</param>
        /// <param name="expand">True if the image should be expanded to its full size.</param>
        /// <param name="pngFile">The path to the PNG file to save to.</param>
        private static void ExtractHg2Image(BinaryReader reader, Hg2FrameInfo frameInfo, HgxOptions options,
                                            string pngFile)
        {
            HG2IMG img = frameInfo.Img;

            reader.BaseStream.Position = frameInfo.Offset;
            int depthBytes = (img.DepthBits + 7) / 8;
            int stride     = (img.Width * depthBytes + 3) & ~3;

            byte[] pixelBuffer = ProcessImage(reader, img.Width, img.Height, img.DepthBits, img.Data);

            if (!CatDebug.SpeedTestHgx)
            {
                // This image type is normally flipped, so reverse the option
                options ^= HgxOptions.Flip;
                WritePng(pixelBuffer, img, options, pngFile);
            }
        }
        private static Hg2FrameInfo ReadHg2FrameInfo(BinaryReader reader, HGXHDR hdr, bool frameOnly)
        {
            Stream stream      = reader.BaseStream;
            long   frameOffset = reader.BaseStream.Position;

            HG2IMG      img     = reader.ReadUnmanaged <HG2IMG>();
            HG2IMG_BASE?imgBase = null;

            if (hdr.Type == 0x25)
            {
                if (frameOnly)
                {
                    stream.Position += HG2IMG_BASE.CbSize;
                }
                else
                {
                    imgBase = reader.ReadUnmanaged <HG2IMG_BASE>();
                }
            }

            return(new Hg2FrameInfo(reader.BaseStream, img, imgBase, frameOffset));
        }