diff --git a/src/img/imlib.c b/src/img/imlib.c index b5b540b2e..8b41fca6c 100644 --- a/src/img/imlib.c +++ b/src/img/imlib.c @@ -63,31 +63,51 @@ const uint8_t xyz_table[256]= { 93.868573, 94.730654, 95.597335, 96.468625, 97.344529, 98.225055, 99.110210, 100.000000, }; -uint16_t imlib_lab_distance(struct color *c0, struct color *c1) +float vsqrt(float x) { - uint16_t sum=0; + asm volatile ( + "vsqrt.f32 %[r], %[x]\n" + : [r] "=t" (x) + : [x] "t" (x)); + return x; +} + +/* This is slightly faster the VSQRT */ +uint32_t fsqrt(float x) + { + uint32_t i = *(uint32_t*) &x; + // adjust bias + i += 127 << 23; + // approximation of square root + i >>= 1; + return (uint32_t) *(float*) &i; +} + +uint32_t imlib_lab_distance(struct color *c0, struct color *c1) +{ + uint32_t sum=0; sum += (c0->L - c1->L) * (c0->L - c1->L); sum += (c0->A - c1->A) * (c0->A - c1->A); sum += (c0->B - c1->B) * (c0->B - c1->B); - return (uint16_t) sqrtf(sum); + return fsqrt(sum); } -uint16_t imlib_rgb_distance(struct color *c0, struct color *c1) +uint32_t imlib_rgb_distance(struct color *c0, struct color *c1) { - uint16_t sum=0; + uint32_t sum=0; sum += (c0->r - c1->r) * (c0->r - c1->r); sum += (c0->g - c1->g) * (c0->g - c1->g); sum += (c0->b - c1->b) * (c0->b - c1->b); - return (uint16_t) sqrtf(sum); + return fsqrt(sum); } -uint16_t imlib_hsv_distance(struct color *c0, struct color *c1) +uint32_t imlib_hsv_distance(struct color *c0, struct color *c1) { - uint16_t sum=0; + uint32_t sum=0; sum += (c0->h - c1->h) * (c0->h - c1->h); sum += (c0->s - c1->s) * (c0->s - c1->s); sum += (c0->v - c1->v) * (c0->v - c1->v); - return (uint16_t) sqrtf(sum); + return fsqrt(sum); } void imlib_rgb_to_lab(struct color *rgb, struct color *lab) diff --git a/src/img/imlib.h b/src/img/imlib.h index 181951d54..059ae2c46 100644 --- a/src/img/imlib.h +++ b/src/img/imlib.h @@ -152,6 +152,9 @@ typedef struct cascade { int8_t *rectangles_array; } cascade_t; +float vsqrt(float x); +uint32_t fsqrt(float x); + /* Point functions */ point_t *point_alloc(int x, int y); int point_equal(point_t *p1, point_t *p2); @@ -169,9 +172,9 @@ struct array *rectangle_merge(struct array *r); array_t *cluster_kmeans(array_t *points, int k); /* Dela E on RGB/HSV/LAB */ -uint16_t imlib_lab_distance(struct color *c0, struct color *c1); -uint16_t imlib_rgb_distance(struct color *c0, struct color *c1); -uint16_t imlib_rgb_distance(struct color *c0, struct color *c1); +uint32_t imlib_lab_distance(struct color *c0, struct color *c1); +uint32_t imlib_rgb_distance(struct color *c0, struct color *c1); +uint32_t imlib_rgb_distance(struct color *c0, struct color *c1); /* Color space conversion */ void imlib_rgb_to_lab(struct color *rgb, struct color *lab);