From 02364f27c3c3ee588ec8642a43f0ef0d8096e95b Mon Sep 17 00:00:00 2001 From: "D. Bohdan" Date: Sun, 1 Oct 2023 13:11:35 +0000 Subject: [PATCH] fix: decode to values up to 255, not 256 - step 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. --- hicolor.h | 68 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 8 deletions(-) diff --git a/hicolor.h b/hicolor.h index a77dae7..740eb90 100644 --- a/hicolor.h +++ b/hicolor.h @@ -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, @@ -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; @@ -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;