Viewing is open to everyone. Downloading and starring need a GitHub sign-in.
Sign in with GitHub
CKeyImage.cs
v0.1.0-build.85
Latest
Commit ede38f5
Sign in with GitHub to download. Each download is recorded with your GitHub username.
| 1 | using System; |
| 2 | using OpenCKey.Interop; |
| 3 | |
| 4 | namespace OpenCKey |
| 5 | { |
| 6 | /// <summary> |
| 7 | /// A native RGBA8 pixel buffer: rows top to bottom with no padding, straight |
| 8 | /// (non-premultiplied) sRGB alpha. Hand it to a host image type (for WPF, |
| 9 | /// see the CKey.Wpf package) or export it with <see cref="ToPng"/>. |
| 10 | /// </summary> |
| 11 | public sealed class CKeyImage |
| 12 | { |
| 13 | /// <summary>Wraps an RGBA8 buffer of width * height * 4 bytes (not copied).</summary> |
| 14 | public CKeyImage(int width, int height, byte[] rgba) |
| 15 | { |
| 16 | if (width <= 0) throw new ArgumentOutOfRangeException(nameof(width)); |
| 17 | if (height <= 0) throw new ArgumentOutOfRangeException(nameof(height)); |
| 18 | if (rgba == null) throw new ArgumentNullException(nameof(rgba)); |
| 19 | if (rgba.Length != (long)width * height * 4) throw new ArgumentException("rgba must hold width * height * 4 bytes.", nameof(rgba)); |
| 20 | Width = width; |
| 21 | Height = height; |
| 22 | Rgba = rgba; |
| 23 | } |
| 24 | |
| 25 | /// <summary>Width in pixels.</summary> |
| 26 | public int Width { get; } |
| 27 | /// <summary>Height in pixels.</summary> |
| 28 | public int Height { get; } |
| 29 | /// <summary>RGBA8 pixels, straight alpha, stride Width * 4.</summary> |
| 30 | public byte[] Rgba { get; } |
| 31 | |
| 32 | /// <summary>Encodes the pixels as an RGBA PNG. dpi > 0 records the physical resolution.</summary> |
| 33 | public byte[] ToPng(double dpi = 0) => Png.Encode(Rgba, Width, Height, Width * 4, NativeConstants.PngRgba8, dpi); |
| 34 | } |
| 35 | |
| 36 | /// <summary>An 8-bit grayscale pixel buffer: rows top to bottom with no padding.</summary> |
| 37 | public sealed class CKeyGrayImage |
| 38 | { |
| 39 | /// <summary>Wraps a gray buffer of width * height bytes (not copied).</summary> |
| 40 | public CKeyGrayImage(int width, int height, byte[] gray) |
| 41 | { |
| 42 | if (width <= 0) throw new ArgumentOutOfRangeException(nameof(width)); |
| 43 | if (height <= 0) throw new ArgumentOutOfRangeException(nameof(height)); |
| 44 | if (gray == null) throw new ArgumentNullException(nameof(gray)); |
| 45 | if (gray.Length != (long)width * height) throw new ArgumentException("gray must hold width * height bytes.", nameof(gray)); |
| 46 | Width = width; |
| 47 | Height = height; |
| 48 | Gray = gray; |
| 49 | } |
| 50 | |
| 51 | /// <summary>Width in pixels.</summary> |
| 52 | public int Width { get; } |
| 53 | /// <summary>Height in pixels.</summary> |
| 54 | public int Height { get; } |
| 55 | /// <summary>Gray pixels (0 black .. 255 white), stride Width.</summary> |
| 56 | public byte[] Gray { get; } |
| 57 | |
| 58 | /// <summary> |
| 59 | /// Encodes the pixels as a PNG: 8-bit gray, or with <paramref name="oneBit"/> |
| 60 | /// a 1-bit image (< 128 is black) for print bitmaps. |
| 61 | /// </summary> |
| 62 | public byte[] ToPng(double dpi = 0, bool oneBit = false) => |
| 63 | Png.Encode(Gray, Width, Height, Width, oneBit ? NativeConstants.PngGray1 : NativeConstants.PngGray8, dpi); |
| 64 | } |
| 65 | |
| 66 | internal static unsafe class Png |
| 67 | { |
| 68 | internal static byte[] Encode(byte[] pixels, int width, int height, int stride, int format, double dpi) |
| 69 | { |
| 70 | Native.EnsureAbi(); |
| 71 | nuint required = 0; |
| 72 | fixed (byte* p = pixels) |
| 73 | { |
| 74 | int status = NativeMethods.ckey_encode_png(p, (uint)width, (uint)height, (nuint)stride, format, dpi, null, 0, &required); |
| 75 | if (status != (int)CKeyStatus.InsufficientBuffer) Native.Check(status, "ckey_encode_png"); |
| 76 | var png = new byte[Native.ToInt32Length(required, "PNG")]; |
| 77 | fixed (byte* o = png) |
| 78 | { |
| 79 | Native.Check(NativeMethods.ckey_encode_png(p, (uint)width, (uint)height, (nuint)stride, format, dpi, o, (nuint)png.Length, &required), |
| 80 | "ckey_encode_png"); |
| 81 | } |
| 82 | if ((int)required != png.Length) Array.Resize(ref png, (int)required); |
| 83 | return png; |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 | } |