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