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

Size
3.9 KB
Lines
87
Language
csharp
SHA-256
dc4643823541…
View on GitHub

Sign in with GitHub to download. Each download is recorded with your GitHub username.

1using System;
2using OpenCKey.Interop;
3
4namespace 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 &gt; 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 (&lt; 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}