]> mj.ucw.cz Git - libucw.git/blob - images/scale.c
some corrections in ImageSim config section
[libucw.git] / images / scale.c
1 /*
2  *      Image Library -- Image scaling algorithms
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 "lib/lib.h"
13 #include "images/images.h"
14 #include "images/error.h"
15
16 #include <string.h>
17
18 #define IMAGE_SCALE_PREFIX(x) image_scale_1_##x
19 #define IMAGE_SCALE_PIXEL_SIZE 1
20 #include "images/scale-gen.h"
21
22 #define IMAGE_SCALE_PREFIX(x) image_scale_2_##x
23 #define IMAGE_SCALE_PIXEL_SIZE 2
24 #include "images/scale-gen.h"
25
26 #define IMAGE_SCALE_PREFIX(x) image_scale_3_##x
27 #define IMAGE_SCALE_PIXEL_SIZE 3
28 #include "images/scale-gen.h"
29
30 #define IMAGE_SCALE_PREFIX(x) image_scale_4_##x
31 #define IMAGE_SCALE_PIXEL_SIZE 4
32 #include "images/scale-gen.h"
33
34 int
35 image_scale(struct image_context *ctx, struct image *dest, struct image *src)
36 {
37   if (src->cols < dest->cols || src->rows < dest->rows)
38     {
39       IMAGE_ERROR(ctx, IMAGE_ERROR_INVALID_DIMENSIONS, "Upsampling not supported.");
40       return 0;
41     }
42   if ((src->flags & IMAGE_PIXEL_FORMAT) != (dest->flags & IMAGE_PIXEL_FORMAT))
43     {
44       IMAGE_ERROR(ctx, IMAGE_ERROR_INVALID_PIXEL_FORMAT, "Different pixel format not supported.");
45       return 0;
46     }
47   switch (src->pixel_size)
48     {
49       /* Gray */
50       case 1:
51         image_scale_1_downsample(dest, src);
52         return 1;
53       /* GrayA */
54       case 2:
55         image_scale_2_downsample(dest, src);
56         return 1;
57       /* RGB */
58       case 3:
59         image_scale_3_downsample(dest, src);
60         return 1;
61       /* RGBA or aligned RGB */
62       case 4:
63         image_scale_4_downsample(dest, src);
64         return 1;
65       default:
66         ASSERT(0);
67     }
68 }
69
70 void
71 image_dimensions_fit_to_box(u32 *cols, u32 *rows, u32 max_cols, u32 max_rows, uns upsample)
72 {
73   ASSERT(image_dimensions_valid(*cols, *rows));
74   ASSERT(image_dimensions_valid(max_cols, max_rows));
75   if (*cols <= max_cols && *rows <= max_rows)
76     {
77       if (!upsample)
78         return;
79       if (max_cols * *rows > max_rows * *cols)
80         {
81           *cols = *cols * max_rows / *rows;
82           *cols = MIN(*cols, max_cols);
83           *rows = max_rows;
84         }
85       else
86         {
87           *rows = *rows * max_cols / *cols;
88           *rows = MIN(*rows, max_rows);
89           *cols = max_cols;
90         }
91     }
92   else if (*cols <= max_cols)
93     goto down_cols;
94   else if (*rows <= max_rows || max_rows * *cols > max_cols * *rows)
95     goto down_rows;
96 down_cols:
97   *cols = *cols * max_rows / *rows;
98   *cols = MAX(*cols, 1);
99   *rows = max_rows;
100   return;
101 down_rows:  
102   *rows = *rows * max_cols / *cols;
103   *rows = MAX(*rows, 1);
104   *cols = max_cols;
105 }