source: OniSplit/Imaging/Color.cs

Last change on this file was 1114, checked in by iritscen, 5 years ago

Adding OniSplit source code (v0.9.99.0). Many thanks to Neo for all his work over the years.

File size: 8.4 KB
Line 
1using System;
2using System.Globalization;
3
4namespace Oni.Imaging
5{
6 internal struct Color : IEquatable<Color>
7 {
8 private byte b, g, r, a;
9
10 public Color(byte r, byte g, byte b)
11 : this(r, g, b, 255)
12 {
13 }
14
15 public Color(byte r, byte g, byte b, byte a)
16 {
17 this.b = b;
18 this.g = g;
19 this.r = r;
20 this.a = a;
21 }
22
23 public Color(Vector3 v)
24 {
25 r = (byte)(v.X * 255.0f);
26 g = (byte)(v.Y * 255.0f);
27 b = (byte)(v.Z * 255.0f);
28 a = 255;
29 }
30
31 public Color(Vector4 v)
32 {
33 r = (byte)(v.X * 255.0f);
34 g = (byte)(v.Y * 255.0f);
35 b = (byte)(v.Z * 255.0f);
36 a = (byte)(v.W * 255.0f);
37 }
38
39 public bool IsTransparent => a != 255;
40
41 public byte R => r;
42 public byte G => g;
43 public byte B => b;
44 public byte A => a;
45
46 public int ToBgra32() => b | (g << 8) | (r << 16) | (a << 24);
47 public int ToBgr565() => (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8);
48
49 public Vector3 ToVector3() => new Vector3(r, g, b) / 255.0f;
50 public Vector4 ToVector4() => new Vector4(r, g, b, a) / 255.0f;
51
52 public static bool operator ==(Color a, Color b) => a.Equals(b);
53 public static bool operator !=(Color a, Color b) => !a.Equals(b);
54
55 public bool Equals(Color color) => r == color.r && g == color.g && b == color.b && a == color.a;
56 public override bool Equals(object obj) => obj is Color && Equals((Color)obj);
57 public override int GetHashCode() => r.GetHashCode() ^ g.GetHashCode() ^ b.GetHashCode() ^ a.GetHashCode();
58
59 public override string ToString() => string.Format(CultureInfo.InvariantCulture, "{{R:{0} G:{1} B:{2} A:{3}}}", new object[] { r, g, b, a });
60
61 public static Color ReadBgra4444(byte[] data, int index)
62 {
63 int pixel = data[index + 0];
64 byte b = (byte)((pixel << 4) & 0xf0);
65 byte g = (byte)(pixel & 0xf0);
66 pixel = data[index + 1];
67 byte r = (byte)((pixel << 4) & 0xf0);
68 byte a = (byte)(pixel & 0xf0);
69
70 return new Color(r, g, b, a);
71 }
72
73 public static void WriteBgra4444(Color color, byte[] data, int index)
74 {
75 data[index + 0] = (byte)((color.b >> 4) | (color.g & 0xf0));
76 data[index + 1] = (byte)((color.r >> 4) | (color.a & 0xf0));
77 }
78
79 public static Color ReadBgrx5551(byte[] data, int index)
80 {
81 int pixel = data[index + 0] | (data[index + 1] << 8);
82 byte b = (byte)((pixel << 3) & 0xf8);
83 byte g = (byte)((pixel >> 2) & 0xf8);
84 byte r = (byte)((pixel >> 7) & 0xf8);
85
86 return new Color(r, g, b);
87 }
88
89 public static void WriteBgrx5551(Color color, byte[] data, int index)
90 {
91 data[index + 0] = (byte)((color.b >> 3) | ((color.g & 0x38) << 2));
92 data[index + 1] = (byte)((color.g >> 6) | ((color.r & 0xf8) >> 1) | 0x80);
93 }
94
95 public static Color ReadBgra5551(byte[] data, int index)
96 {
97 int pixel = data[index + 0] | (data[index + 1] << 8);
98 byte b = (byte)((pixel << 3) & 0xf8);
99 byte g = (byte)((pixel >> 2) & 0xf8);
100 byte r = (byte)((pixel >> 7) & 0xf8);
101 byte a = (byte)((pixel >> 15) * 255);
102
103 return new Color(r, g, b, a);
104 }
105
106 public static void WriteBgra5551(Color color, byte[] data, int index)
107 {
108 data[index + 0] = (byte)((color.b >> 3) | ((color.g & 0x38) << 2));
109 data[index + 1] = (byte)((color.g >> 6) | ((color.r & 0xf8) >> 1) | (color.a & 0x80));
110 }
111
112 public static Color ReadBgr565(byte[] data, int index)
113 {
114 int pixel = data[index + 0] | (data[index + 1] << 8);
115 byte b = (byte)((pixel << 3) & 0xf8);
116 byte g = (byte)((pixel >> 3) & 0xfc);
117 byte r = (byte)((pixel >> 8) & 0xf8);
118
119 return new Color(r, g, b);
120 }
121
122 public static void WriteBgr565(Color color, byte[] data, int index)
123 {
124 data[index + 0] = (byte)((color.b >> 3) | ((color.g & 0x1C) << 3));
125 data[index + 1] = (byte)((color.g >> 5) | (color.r & 0xf8));
126 }
127
128 public static Color ReadBgrx(byte[] data, int index)
129 {
130 byte b = data[index + 0];
131 byte g = data[index + 1];
132 byte r = data[index + 2];
133
134 return new Color(r, g, b);
135 }
136
137 public static void WriteBgrx(Color color, byte[] data, int index)
138 {
139 data[index + 0] = color.b;
140 data[index + 1] = color.g;
141 data[index + 2] = color.r;
142 data[index + 3] = 255;
143 }
144
145 public static Color ReadBgra(byte[] data, int index)
146 {
147 byte b = data[index + 0];
148 byte g = data[index + 1];
149 byte r = data[index + 2];
150 byte a = data[index + 3];
151
152 return new Color(r, g, b, a);
153 }
154
155 public static void WriteBgra(Color color, byte[] data, int index)
156 {
157 data[index + 0] = color.b;
158 data[index + 1] = color.g;
159 data[index + 2] = color.r;
160 data[index + 3] = color.a;
161 }
162
163 public static Color ReadRgbx(byte[] data, int index)
164 {
165 byte r = data[index + 0];
166 byte g = data[index + 1];
167 byte b = data[index + 2];
168
169 return new Color(r, g, b);
170 }
171
172 public static void WriteRgbx(Color color, byte[] data, int index)
173 {
174 data[index + 0] = color.r;
175 data[index + 1] = color.g;
176 data[index + 2] = color.b;
177 data[index + 3] = 255;
178 }
179
180 public static Color ReadRgba(byte[] data, int index)
181 {
182 byte r = data[index + 0];
183 byte g = data[index + 1];
184 byte b = data[index + 2];
185 byte a = data[index + 3];
186
187 return new Color(r, g, b, a);
188 }
189
190 public static void WriteRgba(Color color, byte[] data, int index)
191 {
192 data[index + 0] = color.r;
193 data[index + 1] = color.g;
194 data[index + 2] = color.b;
195 data[index + 3] = color.a;
196 }
197
198 public static Color Lerp(Color x, Color y, float amount)
199 {
200 byte r = (byte)MathHelper.Lerp(x.r, y.r, amount);
201 byte g = (byte)MathHelper.Lerp(x.g, y.g, amount);
202 byte b = (byte)MathHelper.Lerp(x.b, y.b, amount);
203 byte a = (byte)MathHelper.Lerp(x.a, y.a, amount);
204
205 return new Color(r, g, b, a);
206 }
207
208 private static readonly Color black = new Color(0, 0, 0, 255);
209 private static readonly Color white = new Color(255, 255, 255, 255);
210 private static readonly Color transparent = new Color(0, 0, 0, 0);
211
212 public static Color White => white;
213 public static Color Black => black;
214 public static Color Transparent => transparent;
215
216 public static bool TryParse(string s, out Color color)
217 {
218 color = new Color();
219 color.a = 255;
220
221 if (string.IsNullOrEmpty(s))
222 return false;
223
224 var tokens = s.Split(new char[0], StringSplitOptions.RemoveEmptyEntries);
225
226 if (tokens.Length < 3 || tokens.Length > 4)
227 return false;
228
229 if (!byte.TryParse(tokens[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out color.r))
230 return false;
231
232 if (!byte.TryParse(tokens[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out color.g))
233 return false;
234
235 if (!byte.TryParse(tokens[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out color.b))
236 return false;
237
238 if (tokens.Length > 3 && !byte.TryParse(tokens[3], NumberStyles.Integer, CultureInfo.InvariantCulture, out color.a))
239 return false;
240
241 return true;
242 }
243
244 public static Color Parse(string s)
245 {
246 Color c;
247
248 if (!TryParse(s, out c))
249 throw new FormatException(string.Format("'{0}' is not a color", s));
250
251 return c;
252 }
253 }
254}
Note: See TracBrowser for help on using the repository browser.