Last active
October 22, 2022 00:04
-
-
Save mandarinx/e4df9a7766b003e909ed1001086cf3dc to your computer and use it in GitHub Desktop.
Quantize color channels
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static int Quantize(float value, int bits) { | |
return (int)(value * (Math.Pow(2, bits) - 1)); | |
} | |
public static int JoinColors(int maskWidth, params int[] colors) { | |
int joined = colors[0]; | |
for (int i=1; i<colors.Length; ++i) { | |
joined = JoinColor(joined, colors[i], i, maskWidth); | |
} | |
return joined; | |
} | |
public static int JoinColor(int joined, int color, int i, int maskWidth) { | |
return joined |= color << (i * maskWidth); | |
} | |
public static float EncodeQuantized(int quantized, int maxValue) { | |
return (float)quantized / ((float)maxValue - 1f); | |
} | |
public static int DecodeQuantized(float encoded, int maxValue) { | |
return (int)(Math.Min(maxValue - 1, (int)(encoded * maxValue))); | |
} | |
public static int ExtractQuantized(int decoded, int num, int mask, int maskWidth) { | |
return (decoded & (mask << (num * maskWidth))) >> (num * maskWidth); | |
} | |
public static float ToColor(int quantized, int bits) { | |
return (float)quantized / ((int)Math.Pow(2, bits) - 1); | |
} | |
public static int GetMask(int bits) { | |
int mask = 0; | |
for (int i=0; i<bits; ++i) { | |
mask |= (1 << i); | |
} | |
return mask; | |
} | |
public static float EncodeChannel(int channel, int colorBits, int maxBits, params Color[] colors) { | |
int j = 0; | |
for (int i=0; i<colors.Length; ++i) { | |
int q = Quantize(colors[i][channel], colorBits); | |
j = JoinColor(j, q, i, colorBits); | |
} | |
return EncodeQuantized(j, maxBits); | |
} | |
public static float DecodeChannel(float encodedChannel, int num, int maxBits, int colorBits, int channelMask) { | |
int decoded = DecodeQuantized(encodedChannel, maxBits); | |
int q = ExtractQuantized(decoded, num, channelMask, colorBits); | |
return ToColor(q, colorBits); | |
} | |
public static string Bits(int value) { | |
return Convert.ToString(value, 2).PadLeft(32, '0'); | |
} | |
public static void PrintBits(string label, int value) { | |
Console.WriteLine($"{label}: {Bits(value)}"); | |
} | |
public static void Run() { | |
int colorBits = 8; | |
int numColors = 2; | |
int channelMask = GetMask(colorBits); | |
int maxBits = (int)Math.Pow(2, (numColors * colorBits)); | |
Console.WriteLine($"..channelMask: {Bits(channelMask)} dec : {channelMask}"); | |
// Create two colors | |
Color a = new Color(1f, 0f, 0f); | |
Color b = new Color(0f, 1f, 0f); | |
// Encode each channel og both colors | |
float encodedR = EncodeChannel((int)Channel.RED, colorBits, maxBits, a, b); | |
float encodedG = EncodeChannel((int)Channel.GREEN, colorBits, maxBits, a, b); | |
float encodedB = EncodeChannel((int)Channel.BLUE, colorBits, maxBits, a, b); | |
Console.WriteLine($"Color a.r {a.r} b.r {b.r} : {encodedR}"); | |
Console.WriteLine($"Color a.g {a.g} b.g {b.g} : {encodedG}"); | |
Console.WriteLine($"Color a.b {a.b} b.b {b.b} : {encodedB}"); | |
// extract two colors | |
float r0 = DecodeChannel(encodedR, 0, maxBits, colorBits, channelMask); | |
Console.WriteLine($"...........r0: {r0}"); | |
float r1 = DecodeChannel(encodedR, 1, maxBits, colorBits, channelMask); | |
Console.WriteLine($"...........r1: {r1}"); | |
float g0 = DecodeChannel(encodedG, 0, maxBits, colorBits, channelMask); | |
Console.WriteLine($"...........g0: {g0}"); | |
float g1 = DecodeChannel(encodedG, 1, maxBits, colorBits, channelMask); | |
Console.WriteLine($"...........g1: {g1}"); | |
float b0 = DecodeChannel(encodedB, 0, maxBits, colorBits, channelMask); | |
Console.WriteLine($"...........b0: {b0}"); | |
float b1 = DecodeChannel(encodedB, 1, maxBits, colorBits, channelMask); | |
Console.WriteLine($"...........b1: {b1}"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment