diff options
-rw-r--r-- | src/libclut.h | 60 | ||||
-rw-r--r-- | src/test.c | 96 |
2 files changed, 113 insertions, 43 deletions
diff --git a/src/libclut.h b/src/libclut.h index 0d63d4a..d355d13 100644 --- a/src/libclut.h +++ b/src/libclut.h @@ -45,9 +45,9 @@ #define libclut_rgb_contrast(clut, max, type, r, g, b) \ do \ { \ - if ((r) != 1.0) libclut__(clut, red, type, LIBCLUT_VALUE - (max) * 0.5 * (r) + (max) * 0.5); \ - if ((g) != 1.0) libclut__(clut, green, type, LIBCLUT_VALUE - (max) * 0.5 * (g) + (max) * 0.5); \ - if ((b) != 1.0) libclut__(clut, blue, type, LIBCLUT_VALUE - (max) * 0.5 * (b) + (max) * 0.5); \ + if ((r) != 1.0) libclut__(clut, red, type, (LIBCLUT_VALUE - (max) * 0.5) * (r) + (max) * 0.5); \ + if ((g) != 1.0) libclut__(clut, green, type, (LIBCLUT_VALUE - (max) * 0.5) * (g) + (max) * 0.5); \ + if ((b) != 1.0) libclut__(clut, blue, type, (LIBCLUT_VALUE - (max) * 0.5) * (b) + (max) * 0.5); \ } \ while (0) @@ -346,15 +346,15 @@ double m__ = (double)(max); \ size_t i__; \ if (rp) \ - for (i__ = 0; i++ < (clut)->red_size; i__++) \ + for (i__ = 0; i__ < (clut)->red_size; i__++) \ if ((clut)->red[i__] && ((clut)->red[i__] != (max))) \ (clut)->red[i__] = (type)(m__ * (0.5 - log(m__ / (clut)->red[i__] - 1.0) / r__)); \ if (gp) \ - for (i__ = 0; i++ < (clut)->green_size; i__++) \ + for (i__ = 0; i__ < (clut)->green_size; i__++) \ if ((clut)->green[i__] && ((clut)->green[i__] != (max))) \ (clut)->green[i__] = (type)(m__ * (0.5 - log(m__ / (clut)->green[i__] - 1.0) / g__)); \ if (bp) \ - for (i__ = 0; i++ < (clut)->blue_size; i__++) \ + for (i__ = 0; i__ < (clut)->blue_size; i__++) \ if ((clut)->blue[i__] && ((clut)->blue[i__] != (max))) \ (clut)->blue[i__] = (type)(m__ * (0.5 - log(m__ / (clut)->blue[i__] - 1.0) / b__)); \ } \ @@ -621,31 +621,29 @@ */ #define libclut_lower_resolution__(clut, channel, max, type, x, y) \ do \ - { \ - if ((x) || (y)) \ - { \ - size_t x__, y__, i__, n__ = (clut)->channel##_size; \ - double xm__ = (double)((x) - 1), ym__ = (double)((y) - 1); \ - double m__ = (double)(max); \ - type c__[n__]; /* Do not use alloca! */ \ - for (i__ = 0; i__ < n__; i__++) \ - { \ - if ((x__ = i__), (x)) \ - { \ - x__ = (size_t)((double)i__ * (x) / n__); \ - x__ = (size_t)((double)x__ * i__ / xm__); \ - } \ - if (!(y)) \ - c__[i__] = (clut)->channel[x__]; \ - else \ - { \ - y__ = (size_t)((double)((clut)->channel[x__]) / (max) * ym__ + 0.5); \ - c__[i__] = (type)((double)y__ / ym__ * m__); \ - } \ - } \ - memcpy((clut)->channel, c__, n__ * sizeof(type)); \ - } \ - } \ + if ((x) || (y)) \ + { \ + size_t x__, y__, i__, n__ = (clut)->channel##_size; \ + double xm__ = (double)((x) - 1), ym__ = (double)((y) - 1); \ + double m__ = (double)(max), nm__ = (double)(n__ - 1); \ + type c__[n__]; /* Do not use alloca! */ \ + for (i__ = 0; i__ < n__; i__++) \ + { \ + if ((x__ = i__), (x)) \ + { \ + x__ = (size_t)((double)i__ * (x) / n__); \ + x__ = (size_t)((double)x__ * nm__ / xm__); \ + } \ + if (!(y)) \ + c__[i__] = (clut)->channel[x__]; \ + else \ + { \ + y__ = (size_t)((double)((clut)->channel[x__]) / (max) * ym__ + 0.5); \ + c__[i__] = (type)((double)y__ / ym__ * m__); \ + } \ + } \ + memcpy((clut)->channel, c__, n__ * sizeof(type)); \ + } \ while (0) @@ -22,6 +22,8 @@ #include <stdlib.h> #include <string.h> +#include <math.h> + struct clut @@ -36,9 +38,23 @@ struct clut -static inline int clutcmp(const struct clut *a, const struct clut *b) +static inline int clutcmp(const struct clut *a, const struct clut *b, uint16_t tol) { - return memcmp(a->red, b->red, 3 * 256 * sizeof(uint16_t)); + size_t i; + if (tol == 0) + return memcmp(a->red, b->red, 3 * 256 * sizeof(uint16_t)); + for (i = 0; i < 3 * 256; i++) + if (a->red[i] > b->red[i]) + { + if (a->red[i] - b->red[i] > tol) + return +1; + } + else if (a->red[i] < b->red[i]) + { + if (b->red[i] - a->red[i] > tol) + return -1; + } + return 0; } @@ -50,6 +66,7 @@ static int dumpcluts(const struct clut *a, const struct clut *b) i, i, a->red[i], b->red[i], a->green[i], b->green[i], a->blue[i], b->blue[i]); } + static double make_double(double x) { return x * 2; @@ -68,6 +85,7 @@ int main(int argc, char *argv[]) struct clut t1, t2, t3; size_t i, j; int rc = 0; + double param; t1. red_size = t2. red_size = t3. red_size = 256; t1.green_size = t2.green_size = t3.green_size = 256; @@ -83,7 +101,7 @@ int main(int argc, char *argv[]) libclut_start_over(&t1, UINT16_MAX, uint16_t, 1, 1, 1); for (i = 0; i < 256; i++) t2.blue[i] = t2.green[i] = t2.red[i] = (uint16_t)((i << 8) | i); - if (clutcmp(&t1, &t2)) + if (clutcmp(&t1, &t2, 0)) printf("libclut_start_over failed\n"), rc = 1; @@ -93,7 +111,7 @@ int main(int argc, char *argv[]) t2.blue[j] = t2.green[j] = t2.red[j] = (uint16_t)i; } libclut_negative(&t1, UINT16_MAX, uint16_t, 1, 1, 1); - if (clutcmp(&t1, &t2)) + if (clutcmp(&t1, &t2, 0)) printf("libclut_negative failed\n"), rc = 1; @@ -103,7 +121,7 @@ int main(int argc, char *argv[]) t2.blue[i] = t2.green[i] = t2.red[i] = UINT16_MAX - (uint16_t)i; } libclut_rgb_invert(&t1, UINT16_MAX, uint16_t, 1, 1, 1); - if (clutcmp(&t1, &t2)) + if (clutcmp(&t1, &t2, 0)) printf("libclut_rgb_invert failed\n"), rc = 1; @@ -113,7 +131,7 @@ int main(int argc, char *argv[]) t2.blue[i] = 1 + (t2.green[i] = 1 + (t2.red[i] = 1000 + (uint16_t)i)); } libclut_rgb_limits(&t1, UINT16_MAX, uint16_t, 1000, 1255, 1001, 1256, 1002, 1257); - if (clutcmp(&t1, &t2)) + if (clutcmp(&t1, &t2, 0)) printf("libclut_rgb_limits failed\n"), rc = 1; @@ -125,7 +143,7 @@ int main(int argc, char *argv[]) t2.blue[i] = t1.blue[i] * 4; } libclut_rgb_brightness(&t1, UINT16_MAX, uint16_t, 2, 3, 4); - if (clutcmp(&t1, &t2)) + if (clutcmp(&t1, &t2, 0)) printf("libclut_rgb_brightness failed\n"), rc = 1; @@ -135,9 +153,67 @@ int main(int argc, char *argv[]) t2.blue[i] = t2.green[i] = 2 * (t2.red[i] = (uint16_t)i); } libclut_manipulate(&t1, UINT16_MAX, uint16_t, (double (*)(double))(NULL), make_double, make_double); - if (clutcmp(&t1, &t2)) + if (clutcmp(&t1, &t2, 0)) printf("libclut_manipulate failed\n"), rc = 1; + + for (i = 0; i < 256; i++) + { + t1.blue[i] = t1.green[i] = t1.red[i] = (uint16_t)i; + t2.blue[i] = t2.green[i] = t2.red[i] = (uint16_t)(pow((double)i / UINT16_MAX, 1.0 / 1.1) * UINT16_MAX); + } + libclut_gamma(&t1, UINT16_MAX, uint16_t, 1.1, 1.1, 1.1); + if (clutcmp(&t1, &t2, 0)) + printf("libclut_gamma failed\n"), rc = 1; + + + for (i = 0; i < 256; i++) + { + t1.blue[i] = t1.green[i] = t1.red[i] = (uint16_t)((i << 8) | i); + t2.blue[i] = t2.green[i] = t2.red[i] = (t1.red[i] - UINT16_MAX / 2) / 2 + UINT16_MAX / 2; + } + libclut_rgb_contrast(&t1, UINT16_MAX, uint16_t, 0.5, 0.5, 0.5); + if (clutcmp(&t1, &t2, 1)) + printf("libclut_rgb_contrast failed\n"), rc = 1; + + + param = 2.0; + for (i = 0; i < 256; i++) + { + double x = i / 255.0; + if (i % 255) + { + x = 1.0 / x - 1.0; + x = log(x); + x = 0.5 - x / param; + } + t1.blue[i] = t1.green[i] = t1.red[i] = (uint16_t)((i << 8) | i); + t2.blue[i] = t2.green[i] = t2.red[i] = (uint16_t)(x * UINT16_MAX); + } + libclut_sigmoid(&t1, UINT16_MAX, uint16_t, ¶m, ¶m, ¶m); + if (clutcmp(&t1, &t2, 0)) + printf("libclut_sigmoid failed\n"), rc = 1; + + + for (i = 0; i < 256; i++) + { + t1.blue[i] = t1.green[i] = t1.red[i] = (uint16_t)((i << 8) | i); + t2.blue[i] = t2.green[i] = t2.red[i] = t1.red[i & ~15] | (t1.red[i & ~15] >> 4); + } + libclut_lower_resolution(&t1, UINT16_MAX, uint16_t, 16, 0, 16, 0, 16, 0); + if (clutcmp(&t1, &t2, 0)) + printf("libclut_lower_resolution (x) failed\n"), rc = 1; + + + for (i = 0; i < 256; i++) + { + t1.blue[i] = t1.green[i] = t1.red[i] = (uint16_t)((i << 8) | i); + t2.blue[i] = t2.green[i] = t2.red[i] = (uint16_t)(i / 255.0 * 15.0 + 0.5) * UINT16_MAX / 15; + } + libclut_lower_resolution(&t1, UINT16_MAX, uint16_t, 0, 16, 0, 16, 0, 16); + if (clutcmp(&t1, &t2, 0)) + printf("libclut_lower_resolution (y) failed\n"), rc = 1; + if (!rc) printf("everything is fine\n"); @@ -150,18 +226,14 @@ int main(int argc, char *argv[]) /* - libclut_rgb_contrast libclut_cie_contrast libclut_cie_brightness libclut_linearise libclut_standardise - libclut_gamma libclut_cie_invert - libclut_sigmoid libclut_cie_limits libclut_cie_manipulate libclut_clip - libclut_lower_resolution libclut_apply libclut_cie_apply */ |