71 lines
1.8 KiB
C
71 lines
1.8 KiB
C
#include "hsv.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#define FAIL -1
|
|
#define OK 0
|
|
|
|
int test_conv(int r, int g, int b, double tolerance) {
|
|
vec3 rgb = {r/255.0, g/255.0, b/255.0};
|
|
double hsv[3];
|
|
vec3 out;
|
|
int test[3];
|
|
rgb_to_hsv(rgb, hsv);
|
|
hsv_to_rgb(hsv, out);
|
|
test[0] = out[0]*255.0;
|
|
test[1] = out[1]*255.0;
|
|
test[2] = out[2]*255.0;
|
|
|
|
if(fabs(rgb[0] - out[0]) > tolerance || fabs(rgb[1] - out[1]) > tolerance || fabs(rgb[2] - out[2]) > tolerance) {
|
|
fprintf(stderr, "FAIL:\t#%02X%02X%02X -> #%02X%02X%02X\nIN:\t(%.12f %.12f %.12f)\nOUT:\t(%.12f %.12f %.12f)\nDIF:\t(%.12f %.12f %.12f)\n",
|
|
r, g, b,
|
|
test[0], test[1], test[2],
|
|
rgb[0], rgb[1], rgb[2],
|
|
out[0], out[1], out[2],
|
|
rgb[0]-out[0], rgb[1]-out[1], rgb[2]-out[2]);
|
|
return FAIL;
|
|
} else {
|
|
return OK;
|
|
}
|
|
}
|
|
|
|
int main() {
|
|
for(int r = 0; r < 256; r++) {
|
|
for(int g = 0; g < 256; g++) {
|
|
for(int b = 0; b < 256; b++) {
|
|
if(test_conv(r, g, b, 0.001) != OK) {
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// To RGB steps:
|
|
// 1. C = V * S <- maps to 3 in inv
|
|
// 2. H' = H * 6 <- maps to 7 in inv
|
|
// 3. X = C * (1 - abs(H' - 2*floor(H'/2) - 1))
|
|
// 4. M = V - C <- maps to 4 in inv
|
|
// 5. R = V, G = X + M, B = M
|
|
|
|
// To HSV steps:
|
|
// 1. V = max(R, G, B) <- maps to 5,R in inv
|
|
// 2. M = min(R, G, B) <- maps to 5,B in inv
|
|
// 3. S = C / V <- maps to 1 in inv
|
|
// 4. C = V - M <- maps to 4 in inv
|
|
// 5. X = G - M
|
|
// 6. H' = X/C
|
|
// 7. H = H'/6 <- maps to 2 in inv
|
|
//
|
|
// So out of the two algos, the only step that doest match exactly so far is
|
|
// RGB: X = C * (1 - abs(H' - 2*floor(H'/2) - 1))
|
|
// HSV: X = G - M, H' = X/C
|
|
//
|
|
// After floor():
|
|
// RGB: X = C * (1 - abs(H' - 1))
|
|
//
|
|
// After abs() assuming H' = [0, 1]:
|
|
// RGB: X = C * (1 - (1 - H'))
|
|
// RGB: X = C * H'
|