]> mj.ucw.cz Git - libucw.git/blob - images/dup-init.c
Merge with git+ssh://git.ucw.cz/projects/sherlock/GIT/sherlock.git#v3.10
[libucw.git] / images / dup-init.c
1 /*
2  *      Image Library -- Duplicates Comparison
3  *
4  *      (c) 2006 Pavel Charvat <pchar@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #undef LOCAL_DEBUG
11
12 #include "sherlock/sherlock.h"
13 #include "lib/mempool.h"
14 #include "lib/fastbuf.h"
15 #include "images/images.h"
16 #include "images/color.h"
17 #include "images/duplicates.h"
18
19 #include <fcntl.h>
20
21 static uns image_dup_tab_limit = 8;
22
23 static inline struct image *
24 image_dup_subimage(struct image_context *ctx, struct image_dup *dup, struct image *block, uns tab_col, uns tab_row)
25 {
26   return image_init_matrix(ctx, block, image_dup_block(dup, tab_col, tab_row),
27       1 << tab_col, 1 << tab_row, 3 << tab_col, COLOR_SPACE_RGB);
28 }
29
30 static inline void
31 pixels_average(byte *dest, byte *src1, byte *src2)
32 {
33   dest[0] = ((uns)src1[0] + (uns)src2[0]) >> 1;
34   dest[1] = ((uns)src1[1] + (uns)src2[1]) >> 1;
35   dest[2] = ((uns)src1[2] + (uns)src2[2]) >> 1;
36 }
37
38 uns
39 image_dup_estimate_size(uns cols, uns rows)
40 {
41   uns tab_cols, tab_rows;
42   for (tab_cols = 0; (uns)(2 << tab_cols) < cols && tab_cols < image_dup_tab_limit; tab_cols++);
43   for (tab_rows = 0; (uns)(2 << tab_rows) < rows && tab_rows < image_dup_tab_limit; tab_rows++);
44   return sizeof(struct image) + cols * rows * 3 + sizeof(struct image_dup) + (12 << (tab_cols + tab_rows)) + 64;
45 }
46
47 uns
48 image_dup_init(struct image_context *ctx, struct image_dup *dup, struct image *img, struct mempool *pool)
49 {
50   DBG("image_dup_init()");
51
52   ASSERT((img->flags & IMAGE_PIXEL_FORMAT) == COLOR_SPACE_RGB);
53
54   dup->image = img;
55   for (dup->tab_cols = 0; (uns)(2 << dup->tab_cols) < img->cols && dup->tab_cols < image_dup_tab_limit; dup->tab_cols++);
56   for (dup->tab_rows = 0; (uns)(2 << dup->tab_rows) < img->rows && dup->tab_rows < image_dup_tab_limit; dup->tab_rows++);
57   dup->tab_pixels = mp_alloc(pool, dup->tab_size = (12 << (dup->tab_cols + dup->tab_rows)));
58   dup->tab_row_size = 6 << dup->tab_cols;
59
60   /* Scale original image to right bottom block */
61   {
62     struct image block;
63     if (!image_dup_subimage(ctx, dup, &block, dup->tab_cols, dup->tab_rows))
64       return 0;
65     if (!image_scale(ctx, &block, img))
66       return 0;
67   }
68
69   /* Complete bottom row */
70   for (uns i = dup->tab_cols; i--; )
71     {
72       byte *d = image_dup_block(dup, i, dup->tab_rows);
73       byte *s = image_dup_block(dup, i + 1, dup->tab_rows);
74       for (uns y = 0; y < (uns)(1 << dup->tab_rows); y++)
75         for (uns x = 0; x < (uns)(1 << i); x++)
76           {
77             pixels_average(d, s, s + 3);
78             d += 3;
79             s += 6;
80           }
81     }
82
83   /* Complete remaining blocks */
84   for (uns i = 0; i <= dup->tab_cols; i++)
85     {
86       uns line_size = (3 << i);
87       for (uns j = dup->tab_rows; j--; )
88         {
89           byte *d = image_dup_block(dup, i, j);
90           byte *s = image_dup_block(dup, i, j + 1);
91           for (uns y = 0; y < (uns)(1 << j); y++)
92             {
93               for (uns x = 0; x < (uns)(1 << i); x++)
94                 {
95                   pixels_average(d, s, s + line_size);
96                   d += 3;
97                   s += 3;
98                 }
99               s += line_size;
100             }
101         }
102     }
103
104   return 1;
105 }