2 * Image Library -- Image scaling algorithms
4 * (c) 2006 Pavel Charvat <pchar@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
10 #ifndef IMAGE_SCALE_CHANNELS
11 # define IMAGE_SCALE_CHANNELS IMAGE_SCALE_PIXEL_SIZE
15 IMAGE_SCALE_PREFIX(downsample)(struct image *dest, struct image *src)
18 byte *rsrc = src->pixels, *psrc;
19 byte *rdest = dest->pixels, *pdest;
20 uns x_inc = (dest->cols << 16) / src->cols, x_pos, x_inc_frac = 0xffffff / x_inc;
21 uns y_inc = (dest->rows << 16) / src->rows, y_pos = 0, y_inc_frac = 0xffffff / y_inc;
22 uns final_mul = ((u64)x_inc * y_inc) >> 16;
23 uns buf_size = dest->cols * IMAGE_SCALE_CHANNELS;
24 u32 buf[buf_size], *pbuf;
25 buf_size *= sizeof(u32);
27 for (uns rows_counter = src->rows; rows_counter--; )
31 rsrc += src->row_size;
36 for (uns cols_counter = src->cols; cols_counter--; )
42 # if IMAGE_SCALE_CHANNELS >= 2
45 # if IMAGE_SCALE_CHANNELS >= 3
48 # if IMAGE_SCALE_CHANNELS >= 4
55 uns mul2 = x_pos * x_inc_frac;
56 uns mul1 = 0xffffff - mul2;
57 pbuf[0] += (psrc[0] * mul1) >> 24;
58 pbuf[0 + IMAGE_SCALE_CHANNELS] += (psrc[0] * mul2) >> 24;
59 # if IMAGE_SCALE_CHANNELS >= 2
60 pbuf[1] += (psrc[1] * mul1) >> 24;
61 pbuf[1 + IMAGE_SCALE_CHANNELS] += (psrc[1] * mul2) >> 24;
63 # if IMAGE_SCALE_CHANNELS >= 3
64 pbuf[2] += (psrc[2] * mul1) >> 24;
65 pbuf[2 + IMAGE_SCALE_CHANNELS] += (psrc[2] * mul2) >> 24;
67 # if IMAGE_SCALE_CHANNELS >= 4
68 pbuf[3] += (psrc[3] * mul1) >> 24;
69 pbuf[3 + IMAGE_SCALE_CHANNELS] += (psrc[3] * mul2) >> 24;
71 pbuf += IMAGE_SCALE_CHANNELS;
73 psrc += IMAGE_SCALE_PIXEL_SIZE;
80 rdest += dest->row_size;
81 uns mul2 = y_pos * y_inc_frac;
82 uns mul1 = 0xffffff - mul2;
84 # if IMAGE_SCALE_CHANNELS >= 2
87 # if IMAGE_SCALE_CHANNELS >= 3
90 # if IMAGE_SCALE_CHANNELS >= 4
93 for (uns cols_counter = src->cols; cols_counter--; )
98 pbuf[0] += ((psrc[0] * mul1) >> 24);
99 a0 += (psrc[0] * mul2) >> 24;
100 # if IMAGE_SCALE_CHANNELS >= 2
101 pbuf[1] += ((psrc[1] * mul1) >> 24);
102 a1 += (psrc[1] * mul2) >> 24;
104 # if IMAGE_SCALE_CHANNELS >= 3
105 pbuf[2] += ((psrc[2] * mul1) >> 24);
106 a2 += (psrc[2] * mul2) >> 24;
108 # if IMAGE_SCALE_CHANNELS >= 4
109 pbuf[3] += ((psrc[3] * mul1) >> 24);
110 a3 += (psrc[3] * mul2) >> 24;
116 uns mul4 = x_pos * x_inc_frac;
117 uns mul3 = 0xffffff - mul4;
118 uns mul13 = ((u64)mul1 * mul3) >> 24;
119 uns mul23 = ((u64)mul2 * mul3) >> 24;
120 uns mul14 = ((u64)mul1 * mul4) >> 24;
121 uns mul24 = ((u64)mul2 * mul4) >> 24;
122 pdest[0] = ((((psrc[0] * mul13) >> 24) + pbuf[0]) * final_mul) >> 16;
123 pbuf[0] = ((psrc[0] * mul23) >> 24) + a0;
124 pbuf[0 + IMAGE_SCALE_CHANNELS] += ((psrc[0 + IMAGE_SCALE_PIXEL_SIZE] * mul14) >> 24);
125 a0 = ((psrc[0 + IMAGE_SCALE_PIXEL_SIZE] * mul24) >> 24);
126 # if IMAGE_SCALE_CHANNELS >= 2
127 pdest[1] = ((((psrc[1] * mul13) >> 24) + pbuf[1]) * final_mul) >> 16;
128 pbuf[1] = ((psrc[1] * mul23) >> 24) + a1;
129 pbuf[1 + IMAGE_SCALE_CHANNELS] += ((psrc[1 + IMAGE_SCALE_PIXEL_SIZE] * mul14) >> 24);
130 a1 = ((psrc[1 + IMAGE_SCALE_PIXEL_SIZE] * mul24) >> 24);
132 # if IMAGE_SCALE_CHANNELS >= 3
133 pdest[2] = ((((psrc[2] * mul13) >> 24) + pbuf[2]) * final_mul) >> 16;
134 pbuf[2] = ((psrc[2] * mul23) >> 24) + a2;
135 pbuf[2 + IMAGE_SCALE_CHANNELS] += ((psrc[2 + IMAGE_SCALE_PIXEL_SIZE] * mul14) >> 24);
136 a2 = ((psrc[2 + IMAGE_SCALE_PIXEL_SIZE] * mul24) >> 24);
138 # if IMAGE_SCALE_CHANNELS >= 4
139 pdest[3] = ((((psrc[3] * mul13) >> 24) + pbuf[3]) * final_mul) >> 16;
140 pbuf[3] = ((psrc[3] * mul23) >> 24) + a3;
141 pbuf[3 + IMAGE_SCALE_CHANNELS] += ((psrc[3 + IMAGE_SCALE_PIXEL_SIZE] * mul14) >> 24);
142 a3 = ((psrc[3 + IMAGE_SCALE_PIXEL_SIZE] * mul24) >> 24);
144 pbuf += IMAGE_SCALE_CHANNELS;
145 pdest += IMAGE_SCALE_PIXEL_SIZE;
147 psrc += IMAGE_SCALE_PIXEL_SIZE;
149 pdest[0] = (pbuf[0] * final_mul) >> 16;
151 # if IMAGE_SCALE_CHANNELS >= 2
152 pdest[1] = (pbuf[1] * final_mul) >> 16;
155 # if IMAGE_SCALE_CHANNELS >= 3
156 pdest[2] = (pbuf[2] * final_mul) >> 16;
159 # if IMAGE_SCALE_CHANNELS >= 4
160 pdest[3] = (pbuf[3] * final_mul) >> 16;
167 for (uns cols_counter = dest->cols; cols_counter--; )
169 pdest[0] = (pbuf[0] * final_mul) >> 16;
170 # if IMAGE_SCALE_CHANNELS >= 2
171 pdest[1] = (pbuf[1] * final_mul) >> 16;
173 # if IMAGE_SCALE_CHANNELS >= 3
174 pdest[2] = (pbuf[2] * final_mul) >> 16;
176 # if IMAGE_SCALE_CHANNELS >= 4
177 pdest[3] = (pbuf[3] * final_mul) >> 16;
179 pbuf += IMAGE_SCALE_CHANNELS;
180 pdest += IMAGE_SCALE_PIXEL_SIZE;
184 #undef IMAGE_SCALE_PREFIX
185 #undef IMAGE_SCALE_PIXEL_SIZE
186 #undef IMAGE_SCALE_CHANNELS