diff options
Diffstat (limited to 'server/red_bitmap_utils_tmpl.c')
-rw-r--r-- | server/red_bitmap_utils_tmpl.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/server/red_bitmap_utils_tmpl.c b/server/red_bitmap_utils_tmpl.c new file mode 100644 index 00000000..df13c815 --- /dev/null +++ b/server/red_bitmap_utils_tmpl.c @@ -0,0 +1,157 @@ +/* + Copyright (C) 2009 Red Hat, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifdef RED_BITMAP_UTILS_RGB16 +#define PIXEL rgb16_pixel_t +#define FNAME(name) name##_rgb16 +#define GET_r(pix) (((pix) >> 10) & 0x1f) +#define GET_g(pix) (((pix) >> 5) & 0x1f) +#define GET_b(pix) ((pix) & 0x1f) +#endif + +#if defined(RED_BITMAP_UTILS_RGB24) || defined(RED_BITMAP_UTILS_RGB32) +#define GET_r(pix) ((pix).r) +#define GET_g(pix) ((pix).g) +#define GET_b(pix) ((pix).b) +#endif + +#ifdef RED_BITMAP_UTILS_RGB24 +#define PIXEL rgb24_pixel_t +#define FNAME(name) name##_rgb24 +#endif + +#ifdef RED_BITMAP_UTILS_RGB32 +#define PIXEL rgb32_pixel_t +#define FNAME(name) name##_rgb32 +#endif + + +#define SAME_PIXEL_WEIGHT 0.5 +#define NOT_CONTRAST_PIXELS_WEIGHT -0.25 +#define CONTRAST_PIXELS_WEIGHT 1.0 + +#ifndef RED_BITMAP_UTILS_RGB16 +#define CONTRAST_TH 60 +#else +#define CONTRAST_TH 8 +#endif +#define CONTRASTING(n) ((n) <= -CONTRAST_TH || (n) >= CONTRAST_TH) + + +#define SAMPLE_JUMP 15 + +static const double FNAME(PIX_PAIR_SCORE)[] = { + SAME_PIXEL_WEIGHT, + CONTRAST_PIXELS_WEIGHT, + NOT_CONTRAST_PIXELS_WEIGHT, +}; + +// return 0 - equal, 1 - for contrast, 2 for no contrast (PIX_PAIR_SCORE is defined accordingly) +static inline int FNAME(pixelcmp)(PIXEL p1, PIXEL p2) +{ + int diff, any_different; + + diff = GET_r(p1) - GET_r(p2); + any_different = diff; + if (CONTRASTING(diff)) { + return 1; + } + + diff = GET_g(p1) - GET_g(p2); + any_different |= diff; + if (CONTRASTING(diff)) { + return 1; + } + + diff = GET_b(p1) - GET_b(p2); + any_different |= diff; + if (CONTRASTING(diff)) { + return 1; + } + + if (!any_different) { + return 0; + } else { + return 2; + } +} + +static inline double FNAME(pixels_square_score)(PIXEL *line1, PIXEL *line2) +{ + double ret; + int any_different = 0; + int cmp_res; + cmp_res = FNAME(pixelcmp)(*line1, line1[1]); + any_different |= cmp_res; + ret = FNAME(PIX_PAIR_SCORE)[cmp_res]; + cmp_res = FNAME(pixelcmp)(*line1, *line2); + any_different |= cmp_res; + ret += FNAME(PIX_PAIR_SCORE)[cmp_res]; + cmp_res = FNAME(pixelcmp)(*line1, line2[1]); + any_different |= cmp_res; + ret += FNAME(PIX_PAIR_SCORE)[cmp_res]; + + // ignore squares where all pixels are identical + if (!any_different) { + ret = 0; + } + + return ret; +} + +static void FNAME(compute_lines_gradual_score)(PIXEL *lines, int width, int num_lines, + double *o_samples_sum_score, int *o_num_samples) +{ + int jump = (SAMPLE_JUMP % width) ? SAMPLE_JUMP : SAMPLE_JUMP - 1; + PIXEL *cur_pix = lines + width / 2; + PIXEL *bottom_pix; + PIXEL *last_line = lines + (num_lines - 1) * width; + + if ((width <= 1) || (num_lines <= 1)) { + *o_num_samples = 1; + *o_samples_sum_score = 1.0; + return; + } + + *o_samples_sum_score = 0; + *o_num_samples = 0; + + while (cur_pix < last_line) { + if ((cur_pix + 1 - lines) % width == 0) { // last pixel in the row + cur_pix--; // jump is bigger than 1 so we will not enter endless loop + } + bottom_pix = cur_pix + width; + (*o_samples_sum_score) += FNAME(pixels_square_score)(cur_pix, bottom_pix); + (*o_num_samples)++; + cur_pix += jump; + } + + (*o_num_samples) *= 3; +} + +#undef PIXEL +#undef FNAME +#undef GET_r +#undef GET_g +#undef GET_b +#undef RED_BITMAP_UTILS_RGB16 +#undef RED_BITMAP_UTILS_RGB24 +#undef RED_BITMAP_UTILS_RGB32 +#undef SAMPLE_JUMP +#undef CONTRAST_TH +#undef SAME_PIXEL_WEIGHT +#undef NOT_CONTRAST_PIXELS_WEIGHT |