/// <summary> /// Initializes a new instance of the <see cref="PngDecoder"/> class. /// </summary> /// <param name="stream"> /// A <see cref="Stream"/> which contains a PNG image. /// </param> public PngDecoder(Stream stream) { this.Stream = stream ?? throw new ArgumentNullException(nameof(stream)); this.version = NativeMethods.png_get_libpng_ver(IntPtr.Zero); this.Version = Marshal.PtrToStringAnsi(this.version); this.errorCallback = new NativeMethods.png_error(OnError); this.warningCallback = new NativeMethods.png_error(OnWarning); this.pngPtr = NativeMethods.png_create_read_struct(this.version, new IntPtr(1), this.errorCallback, this.warningCallback); ThrowOnZero(this.pngPtr); this.infoPtr = NativeMethods.png_create_info_struct(this.pngPtr); ThrowOnZero(this.infoPtr); // Set the callback function this.readCallback = new NativeMethods.png_rw(this.Read); NativeMethods.png_set_read_fn(this.pngPtr, IntPtr.Zero, this.readCallback); // Get basic image properties. // This will process all chunks up to but not including the image data. NativeMethods.png_read_info(this.pngPtr, this.infoPtr); this.RefreshProperties(); }
/// <summary> /// Initializes a new instance of the <see cref="PngReader"/> class. /// </summary> /// <param name="stream"> /// A <see cref="pngStream"/> which contains a PNG image. /// </param> public PngReader(String FileName) { using (Stream stream = File.OpenRead(FileName)) { pngStream = stream ?? throw new ArgumentNullException(nameof(stream)); Version = Marshal.PtrToStringAnsi(verPtr = NativeMethods.png_get_libpng_ver(IntPtr.Zero)); errorCallback = new NativeMethods.png_error(OnError); warningCallback = new NativeMethods.png_error(OnWarning); // Creat structures ThrowOnZero(pngPtr = NativeMethods.png_create_read_struct(verPtr, IntPtr.Zero, errorCallback, warningCallback)); // ?IntPtr(1)? ThrowOnZero(infoPtr = NativeMethods.png_create_info_struct(pngPtr)); // Set the callback function NativeMethods.png_set_read_fn(pngPtr, IntPtr.Zero, readCallback = new NativeMethods.png_rw(ReadBlock)); // Get basic image properties try { NativeMethods.png_read_info(pngPtr, infoPtr); Width = (int)NativeMethods.png_get_image_width(pngPtr, infoPtr); Height = (int)NativeMethods.png_get_image_height(pngPtr, infoPtr); BitDepth = NativeMethods.png_get_bit_depth(pngPtr, infoPtr); Channels = NativeMethods.png_get_channels(pngPtr, infoPtr); BytesPerRow = (int)NativeMethods.png_get_rowbytes(pngPtr, infoPtr); ColorType = NativeMethods.png_get_color_type(pngPtr, infoPtr); DecompressedSize = BytesPerRow * Height; // Get image data ScanLine = new byte[DecompressedSize]; fixed(byte *ptr = ScanLine) { IntPtr[] rowPtrs = new IntPtr[Height]; IntPtr rowPtr = (IntPtr)ptr; for (int i = 0; i < Height; i++) { rowPtrs[i] = rowPtr; rowPtr += BytesPerRow; } NativeMethods.png_read_image(pngPtr, rowPtrs); } // Read the end_info data NativeMethods.png_read_end(pngPtr, endInfoPtr); } catch (Exception exc) { throw exc; } } }
public PngWriter(String FileName, byte[] ScanLine, int Width, int Height, int Channels, int BitDepth, PngColorType ColorType) { if (ScanLine == null) { throw new ArgumentNullException(nameof(ScanLine)); } using (Stream stream = File.OpenWrite(FileName)) { BytesPerRow = Width * Channels * BitDepth / 8; pngStream = stream ?? throw new ArgumentNullException(nameof(stream)); Version = Marshal.PtrToStringAnsi(verPtr = NativeMethods.png_get_libpng_ver(IntPtr.Zero)); errorCallback = new NativeMethods.png_error(OnError); warningCallback = new NativeMethods.png_error(OnWarning); // Creat structures ThrowOnZero(pngPtr = NativeMethods.png_create_write_struct(verPtr, IntPtr.Zero, errorCallback, warningCallback)); ThrowOnZero(infoPtr = NativeMethods.png_create_info_struct(pngPtr)); // Set the callback function NativeMethods.png_set_write_fn(pngPtr, IntPtr.Zero, writeCallback = new NativeMethods.png_rw(WriteBlock), flushCallback = new NativeMethods.png_flush(FlushBlock)); // Init image NativeMethods.png_set_IHDR(pngPtr, infoPtr, Width, Height, BitDepth, ColorType, PngInterlaceType.None, PngCompressionType.Base, PngFillerFlags.Before); // Write basic image properties NativeMethods.png_write_info(pngPtr, infoPtr); // Write image data fixed(byte *ptr = ScanLine) { IntPtr[] rowPtrs = new IntPtr[Height]; IntPtr rowPtr = (IntPtr)ptr; for (int i = 0; i < Height; i++) { rowPtrs[i] = rowPtr; rowPtr += BytesPerRow; } NativeMethods.png_write_image(pngPtr, rowPtrs); } // Write end_info data NativeMethods.png_write_end(pngPtr, endInfoPtr); } }