Skip to content

Commit

Permalink
fix: decode to values up to 255, not 256 - step
Browse files Browse the repository at this point in the history
This commit expands the color gamut.
It does not increase color accuracy in the abstract
(it is still one value to four or eight),
but it may increase color accuracy in practice.
Images as a whole most likely have more 255 than 248 or 252 color values.

Use tables for encoding and decoding.
It makes the mapping of values visible and easier to understand.
It does not seem to reduce performance on large files.
  • Loading branch information
dbohdan committed Oct 1, 2023
1 parent 68574b7 commit 02364f2
Showing 1 changed file with 60 additions and 8 deletions.
68 changes: 60 additions & 8 deletions hicolor.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,54 @@

static const uint8_t hicolor_magic[7] = "HiColor";

static const uint8_t hicolor_256_to_32[] = {
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11,
11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13,
13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18,
18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20,
20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22,
22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24,
25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27,
27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29,
29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31,
31, 31
};

static const uint8_t hicolor_256_to_64[] = {
0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5,
6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11,
11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,
16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20,
20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24,
25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29,
29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 33,
34, 34, 34, 34, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, 38, 38,
38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42,
43, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47,
47, 47, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51,
52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 56, 56,
56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60,
61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63
};

static const uint8_t hicolor_32_to_256[] = {
0, 8, 16, 24, 33, 41, 49, 57, 66, 74, 82, 90, 99, 107, 115, 123, 132,
140, 148, 156, 165, 173, 181, 189, 198, 206, 214, 222, 231, 239, 247,
255
};

static const uint8_t hicolor_64_to_256[] = {
0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 65, 69, 73,
77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134,
138, 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190,
195, 199, 203, 207, 211, 215, 219, 223, 227, 231, 235, 239, 243, 247,
251, 255
};

static const double hicolor_bayer[HICOLOR_BAYER_SIZE * HICOLOR_BAYER_SIZE] = {
0.0/64, 48.0/64, 12.0/64, 60.0/64, 3.0/64, 51.0/64, 15.0/64, 63.0/64,
32.0/64, 16.0/64, 44.0/64, 28.0/64, 35.0/64, 19.0/64, 47.0/64, 31.0/64,
Expand Down Expand Up @@ -191,14 +239,14 @@ hicolor_result hicolor_value_to_rgb(
switch (version) {
case HICOLOR_VERSION_5:
if (value & 0x8000) return HICOLOR_INVALID_VALUE;
rgb->r = (value & 0x1f) << 3;
rgb->g = (value & 0x3ff) >> (5 - 3);
rgb->b = (value & 0x7fff) >> (10 - 3);
rgb->r = hicolor_32_to_256[value & 0x1f];
rgb->g = hicolor_32_to_256[(value & 0x3ff) >> 5];
rgb->b = hicolor_32_to_256[(value & 0x7fff) >> 10];
return HICOLOR_OK;
case HICOLOR_VERSION_6:
rgb->r = (value & 0x1f) << 3;
rgb->g = (value & 0x7ff) >> (5 - 2);
rgb->b = value >> (11 - 3);
rgb->r = hicolor_32_to_256[value & 0x1f];
rgb->g = hicolor_64_to_256[(value & 0x7ff) >> 5];
rgb->b = hicolor_32_to_256[value >> 11];
return HICOLOR_OK;
default:
return HICOLOR_UNKNOWN_VERSION;
Expand All @@ -213,10 +261,14 @@ hicolor_result hicolor_rgb_to_value(
{
switch (version) {
case HICOLOR_VERSION_5:
*value = (rgb.r >> 3) | (rgb.g >> 3 << 5) | (rgb.b >> 3 << 10);
*value = hicolor_256_to_32[rgb.r]
| hicolor_256_to_32[rgb.g] << 5
| hicolor_256_to_32[rgb.b] << 10;
return HICOLOR_OK;
case HICOLOR_VERSION_6:
*value = (rgb.r >> 3) | (rgb.g >> 2 << 5) | (rgb.b >> 3 << 11);
*value = hicolor_256_to_32[rgb.r]
| hicolor_256_to_64[rgb.g] << 5
| hicolor_256_to_32[rgb.b] << 11;
return HICOLOR_OK;
default:
return HICOLOR_UNKNOWN_VERSION;
Expand Down

0 comments on commit 02364f2

Please sign in to comment.