-uns
-image_dup_estimate_size(uns width, uns height)
-{
- uns cols, rows;
- for (cols = 0; (uns)(2 << cols) < width; cols++);
- for (rows = 0; (uns)(2 << rows) < height; rows++);
- return sizeof(struct image_dup) + (12 << (cols + rows));
-}
-
-void
-image_dup_init(struct image_dup *dup, struct image_data *image, struct mempool *pool)
-{
- ASSERT(image->width && image->height);
-
- dup->image = image;
- dup->width = image->width;
- dup->height = image->height;
- for (dup->cols = 0; (uns)(2 << dup->cols) < image->width; dup->cols++);
- for (dup->rows = 0; (uns)(2 << dup->rows) < image->height; dup->rows++);
- dup->buf = mp_alloc(pool, dup->buf_size = (12 << (dup->cols + dup->rows)));
- dup->line = 6 << dup->cols;
- dup->flags = 0;
- if (image->width >= image_dup_scale_min_size && image->height >= image_dup_scale_min_size)
- dup->flags |= IMAGE_DUP_FLAG_SCALE;
-
- /* Scale original image to right bottom block */
- {
- byte *d = image_dup_block(dup, dup->cols, dup->rows);
- uns width = 1 << dup->cols;
- uns height = 1 << dup->rows;
- uns line_size = 3 * image->width;
- uns src_y = 0;
- for (uns y = 0; y < height; y++)
- {
- byte *line = image->pixels + line_size * (src_y >> dup->rows);
- uns src_x = 0;
- for (uns x = 0; x < width; x++)
- {
- byte *s = line + 3 * (src_x >> dup->cols);
- d[0] = s[0];
- d[1] = s[1];
- d[2] = s[2];
- d += 3;
- src_x += image->width;
- }
- src_y += image->height;
- }
- }
-
- /* Complete bottom row */
- for (uns i = dup->cols; i--; )
- {
- byte *d = image_dup_block(dup, i, dup->rows);
- byte *s = image_dup_block(dup, i + 1, dup->rows);
- for (uns y = 0; y < (uns)(1 << dup->rows); y++)
- for (uns x = 0; x < (uns)(1 << i); x++)
- {
- pixels_average(d, s, s + 3);
- d += 3;
- s += 6;
- }
- }
-
- /* Complete remaining blocks */
- for (uns i = 0; i <= dup->cols; i++)
- {
- uns line_size = (3 << i);
- for (uns j = dup->rows; j--; )
- {
- byte *d = image_dup_block(dup, i, j);
- byte *s = image_dup_block(dup, i, j + 1);
- for (uns y = 0; y < (uns)(1 << j); y++)
- {
- for (uns x = 0; x < (uns)(1 << i); x++)
- {
- pixels_average(d, s, s + line_size);
- d += 3;
- s += 3;
- }
- s += line_size;
- }
- }
- }
-}