/// Init the color block from an array of colors. public ColorBlock(uint[] linearImage) : this() { for (uint i = 0; i < 16; i++) { Data[(int)i] = new Color32(linearImage[i]); } }
public Color32(Color32 c) { b = 0; g = 0; r = 0; a = 0; u = c.u; }
public RawImage(Color32[] data, uint width, uint height) { if (data == null) _data = new Color32[width * height * 4]; // sizeof(Color32) == 4 else _data = data; Width = width; Height = height; }
public Color32[] Scanline(uint line) { Color32[] tmp = new Color32[Width]; Array.Copy(Data, line * Width, tmp, 0, Width); return tmp; }
public bool Equals(Color32 other) { return b == other.b && g == other.g && r == other.r && a == other.a && u == other.u; }
static uint colorLuminance(Color32 c) { return (uint)(c.r + c.g + c.b); }
// Get the euclidean distance between the given colors. static uint colorDistance(Color32 c0, Color32 c1) { return (uint)((c0.r - c1.r) * (c0.r - c1.r) + (c0.g - c1.g) * (c0.g - c1.g) + (c0.b - c1.b) * (c0.b - c1.b)); }
void swizzleDXT5n() { for (int i = 0; i < 16; i++) { Color32 c = Data[i]; Data[i] = new Color32(0xFF, c.g, 0, c.r); } }
void splatY() { for (int i = 0; i < 16; i++) { byte y = Data[i].g; Data[i] = new Color32(y, y, y, y); } }
void splatX() { for (int i = 0; i < 16; i++) { byte x = Data[i].r; Data[i] = new Color32(x, x, x, x); } }
/// Get luminance color range. void luminanceRange(Color32 start, Color32 end) { if (start == null) throw new ArgumentNullException("start"); if (end == null) throw new ArgumentNullException("end"); Color32 minColor = new Color32(); Color32 maxColor = new Color32(); uint minLuminance, maxLuminance; maxLuminance = minLuminance = colorLuminance(Data[0]); for (uint i = 1; i < 16; i++) { uint luminance = colorLuminance(Data[i]); if (luminance > maxLuminance) { maxLuminance = luminance; maxColor = Data[i]; } else if (luminance < minLuminance) { minLuminance = luminance; minColor = Data[i]; } } start = minColor; end = maxColor; }
/// Returns true if the block has a single color. bool isSingleColor() { Color32 mask = new Color32(0xFF, 0xFF, 0xFF, 0x00); uint u = Data[0].u & mask.u; for (int i = 1; i < 16; i++) { if (u != (Data[i].u & mask.u)) { return false; } } return true; }
/// Get diameter color range. void diameterRange(ref Color32 start, ref Color32 end) { //if (start == null) // throw new ArgumentNullException("start"); //if (end == null) // throw new ArgumentNullException("end"); Color32 c0 = new Color32(); Color32 c1 = new Color32(); uint best_dist = 0; for (int i = 0; i < 16; i++) { for (int j = i + 1; j < 16; j++) { uint dist = colorDistance(Data[i], Data[j]); if (dist > best_dist) { best_dist = dist; c0 = Data[i]; c1 = Data[j]; } } } start = c0; end = c1; }
/// Get color range based on the bounding box. void boundsRangeAlpha(Color32 start, Color32 end) { if (start == null) throw new ArgumentNullException("start"); if (end == null) throw new ArgumentNullException("end"); Color32 minColor = new Color32(255, 255, 255, 255); Color32 maxColor = new Color32(0, 0, 0, 0); for (uint i = 0; i < 16; i++) { if (Data[i].r < minColor.r) { minColor.r = Data[i].r; } if (Data[i].g < minColor.g) { minColor.g = Data[i].g; } if (Data[i].b < minColor.b) { minColor.b = Data[i].b; } if (Data[i].a < minColor.a) { minColor.a = Data[i].a; } if (Data[i].r > maxColor.r) { maxColor.r = Data[i].r; } if (Data[i].g > maxColor.g) { maxColor.g = Data[i].g; } if (Data[i].b > maxColor.b) { maxColor.b = Data[i].b; } if (Data[i].a > maxColor.a) { maxColor.a = Data[i].a; } } // Offset range by 1/16 of the extents Color32 inset = new Color32(); inset.r = (byte)((maxColor.r - minColor.r) >> 4); inset.g = (byte)((maxColor.g - minColor.g) >> 4); inset.b = (byte)((maxColor.b - minColor.b) >> 4); inset.a = (byte)((maxColor.a - minColor.a) >> 4); minColor.r = (byte)((minColor.r + inset.r <= 255) ? minColor.r + inset.r : 255); minColor.g = (byte)((minColor.g + inset.g <= 255) ? minColor.g + inset.g : 255); minColor.b = (byte)((minColor.b + inset.b <= 255) ? minColor.b + inset.b : 255); minColor.a = (byte)((minColor.a + inset.a <= 255) ? minColor.a + inset.a : 255); maxColor.r = (byte)((maxColor.r >= inset.r) ? maxColor.r - inset.r : 0); maxColor.g = (byte)((maxColor.g >= inset.g) ? maxColor.g - inset.g : 0); maxColor.b = (byte)((maxColor.b >= inset.b) ? maxColor.b - inset.b : 0); maxColor.a = (byte)((maxColor.a >= inset.a) ? maxColor.a - inset.a : 0); start = minColor; end = maxColor; }