summaryrefslogtreecommitdiffstats
path: root/server/red_bitmap_utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'server/red_bitmap_utils.h')
-rw-r--r--server/red_bitmap_utils.h162
1 files changed, 162 insertions, 0 deletions
diff --git a/server/red_bitmap_utils.h b/server/red_bitmap_utils.h
new file mode 100644
index 00000000..6153ea2f
--- /dev/null
+++ b/server/red_bitmap_utils.h
@@ -0,0 +1,162 @@
+/*
+ Copyright (C) 2009 Red Hat, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. 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 SAMPLE_JUMP 15
+#define SAME_PIXEL(p1, p2) (GET_r(p1) == GET_r(p2) && GET_g(p1) == GET_g(p2) && \
+ GET_b(p1) == GET_b(p2))
+
+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 = ABS(GET_r(p1) - GET_r(p2));
+ int equal;
+
+ if (diff >= CONTRAST_TH) {
+ return 1;
+ }
+ equal = !diff;
+
+ diff = ABS(GET_g(p1) - GET_g(p2));
+
+ if (diff >= CONTRAST_TH) {
+ return 1;
+ }
+
+ equal = equal && !diff;
+
+ diff = ABS(GET_b(p1) - GET_b(p2));
+ if (diff >= CONTRAST_TH) {
+ return 1;
+ }
+ equal = equal && !diff;
+
+ if (equal) {
+ return 0;
+ } else {
+ return 2;
+ }
+}
+
+static inline double FNAME(pixels_square_score)(PIXEL *line1, PIXEL *line2)
+{
+ double ret = 0.0;
+ int all_ident = TRUE;
+ int cmp_res;
+ cmp_res = FNAME(pixelcmp)(*line1, line1[1]);
+ all_ident = all_ident && (!cmp_res);
+ ret += FNAME(PIX_PAIR_SCORE)[cmp_res];
+ cmp_res = FNAME(pixelcmp)(*line1, *line2);
+ all_ident = all_ident && (!cmp_res);
+ ret += FNAME(PIX_PAIR_SCORE)[cmp_res];
+ cmp_res = FNAME(pixelcmp)(*line1, line2[1]);
+ all_ident = all_ident && (!cmp_res);
+ ret += FNAME(PIX_PAIR_SCORE)[cmp_res];
+
+ // ignore squares where al pixels are identical
+ if (all_ident) {
+ ret -= (FNAME(PIX_PAIR_SCORE)[0]) * 3;
+ }
+
+ 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 SAME_PIXEL
+#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
+