1 /*-----------------------------------------------------------------------
2 This file is part of aaphoto.
3
4 aaphoto is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
8
9 aaphoto is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 ------------------------------------------------------------------------*/
17
18
RESIZE(unsigned char ** image_buffer,unsigned long * image_width,unsigned long * image_height,unsigned long new_width,unsigned long new_height,int alpha_flag)19 int RESIZE(
20 unsigned char **image_buffer,
21 unsigned long *image_width,
22 unsigned long *image_height,
23 unsigned long new_width,
24 unsigned long new_height,
25 int alpha_flag)
26 {
27 unsigned int startx, endx;
28 unsigned int starty, endy;
29 unsigned int i, j, x, y;
30
31 unsigned char *bitmap_buffer2;
32 /* if there is an Alpha channel beside the RGB too */
33 /* then i need to allocate more memory for Alpha channel */
34 /* not 3x but 5x more than the number of pixels in image */
35 if (alpha_flag) { alpha_flag = 2; }
36 /*allocate memory */
37 /* print info */ STRING_PRINTV("allocating memory for uncompressed bitmap image\n");
38 bitmap_buffer2 = malloc(new_width * new_height * (3 + alpha_flag) * sizeof (*bitmap_buffer2));
39 if (bitmap_buffer2 == 0) return 1;
40
41 /* print info */ STRING_PRINTV("resizing image\n");
42
43 #ifdef __OPENMP__
44 #pragma omp parallel for private(i, j, x, y, startx, starty, endx, endy) num_threads(max_threads)
45 #endif
46 for (j=0; j<new_height; j++){
47
48 for (i=0; i<new_width; i++){
49
50 long addr = 0;
51 long rgb_avg_r = 0;
52 long rgb_avg_g = 0;
53 long rgb_avg_b = 0;
54 long rgb_avg_a = 0;
55 long rgb_counter = 0;
56
57 startx = *image_width * i / new_width;
58 endx = *image_width * (i+1) / new_width;
59 starty = *image_height * j / new_height;
60 endy = *image_height * (j+1) / new_height;
61
62 for (y=starty; y<endy; y++){
63 for (x=startx; x<endx; x++){
64
65 addr = (x + y * *image_width);
66 rgb_avg_r += (*image_buffer)[3 * addr + 0];
67 rgb_avg_g += (*image_buffer)[3 * addr + 1];
68 rgb_avg_b += (*image_buffer)[3 * addr + 2];
69 if (alpha_flag) {
70 rgb_avg_a += (*image_buffer)[(*image_width) * (*image_height) * 3 + addr + 0];
71 }
72 rgb_counter++;
73
74 }
75 }
76 if (rgb_counter > 0){
77 rgb_avg_r = rgb_avg_r / rgb_counter;
78 rgb_avg_g = rgb_avg_g / rgb_counter;
79 rgb_avg_b = rgb_avg_b / rgb_counter;
80 if (alpha_flag) { rgb_avg_a = rgb_avg_a / rgb_counter; }
81 }
82
83 addr = (i + j * new_width);
84 bitmap_buffer2[3 * addr + 0] = rgb_avg_r;
85 bitmap_buffer2[3 * addr + 1] = rgb_avg_g;
86 bitmap_buffer2[3 * addr + 2] = rgb_avg_b;
87 if (alpha_flag) {
88 bitmap_buffer2[new_width * new_height * 3 + addr + 0] = rgb_avg_a;
89 }
90
91 }
92 }
93
94 /* print info */ STRING_PRINTV("freeing uncompressed bitmap buffer\n");
95 free(*image_buffer);
96 *image_buffer = bitmap_buffer2;
97 *image_width = new_width;
98 *image_height = new_height;
99
100 return 0;
101 }
102
103
104
ROTATE90(unsigned char ** image_buffer,unsigned long * image_width,unsigned long * image_height,int alpha_flag)105 int ROTATE90(
106 unsigned char **image_buffer,
107 unsigned long *image_width,
108 unsigned long *image_height,
109 int alpha_flag)
110 {
111 unsigned char *bitmap_buffer2;
112 unsigned int x, y;
113
114 unsigned long new_width;
115 unsigned long new_height;
116 new_width = *image_width;
117 new_height = *image_height;
118
119 /*allocate memory */
120 if (alpha_flag) { alpha_flag = 2; }
121 /* print info */ STRING_PRINTV("allocating memory for uncompressed bitmap image\n");
122 bitmap_buffer2 = malloc(new_width * new_height * (3 + alpha_flag) * sizeof (*bitmap_buffer2));
123 if (bitmap_buffer2 == 0) return 1;
124
125 /* print info */ STRING_PRINTV("rotating image with 90\n");
126
127 #ifdef __OPENMP__
128 #pragma omp parallel for private(x, y) num_threads(max_threads)
129 #endif
130 for (y=0; y<new_height; y++){
131
132 for (x=0; x<new_width; x++){
133
134 long addr = 0;
135 long rgb_avg_r = 0;
136 long rgb_avg_g = 0;
137 long rgb_avg_b = 0;
138 long rgb_avg_a = 0;
139
140 addr = (x + y * new_width);
141 rgb_avg_r += (*image_buffer)[3 * addr + 0];
142 rgb_avg_g += (*image_buffer)[3 * addr + 1];
143 rgb_avg_b += (*image_buffer)[3 * addr + 2];
144 if (alpha_flag){ rgb_avg_a += (*image_buffer)[(*image_width) * (*image_height) * 3 + addr + 0]; }
145
146 addr = ((new_height - 1 - y) + x * new_height);
147 bitmap_buffer2[3 * addr + 0] = rgb_avg_r;
148 bitmap_buffer2[3 * addr + 1] = rgb_avg_g;
149 bitmap_buffer2[3 * addr + 2] = rgb_avg_b;
150 if (alpha_flag){ bitmap_buffer2[new_width * new_height * 3 + addr + 2] = rgb_avg_a; }
151 }
152 }
153
154 /* print info */ STRING_PRINTV("freeing uncompressed bitmap buffer\n");
155 free(*image_buffer);
156 *image_buffer = bitmap_buffer2;
157 *image_width = new_height;
158 *image_height = new_width;
159
160 return 0;
161 }
162
163
164
ROTATE180(unsigned char ** image_buffer,unsigned long * image_width,unsigned long * image_height,int alpha_flag)165 int ROTATE180(
166 unsigned char **image_buffer,
167 unsigned long *image_width,
168 unsigned long *image_height,
169 int alpha_flag)
170 {
171 int x, y, x_max, y_max, y_odd;
172
173 unsigned long new_width;
174 unsigned long new_height;
175 new_width = *image_width;
176 new_height = *image_height;
177
178 /* print info */ STRING_PRINTV("rotating image with 180\n");
179
180 /* is the number of lines an odd number? */
181 y_odd = new_height & 1;
182 y_max = new_height/2 + y_odd;
183
184 #ifdef __OPENMP__
185 #pragma omp parallel for private(x, y, x_max) num_threads(max_threads)
186 #endif
187 for (y=0; y<y_max; y++){
188
189 x_max = new_width;
190 /* if the height is an odd number, then the flipping should go only to the middle of the width */
191 /* in the middle line */
192 if ((y_odd) && (y == y_max-1)){ x_max = new_width/2; }
193
194 for (x=0; x<x_max; x++){
195
196 long addr1 = 0;
197 long addr2 = 0;
198 long rgb_avg_r1 = 0;
199 long rgb_avg_g1 = 0;
200 long rgb_avg_b1 = 0;
201 long rgb_avg_a1 = 0;
202 long rgb_avg_r2 = 0;
203 long rgb_avg_g2 = 0;
204 long rgb_avg_b2 = 0;
205 long rgb_avg_a2 = 0;
206
207 addr1 = (x + y * new_width);
208 addr2 = ((new_width - 1 - x) + (new_height - 1 - y) * new_width);
209
210 rgb_avg_r1 += (*image_buffer)[3 * addr1 + 0];
211 rgb_avg_g1 += (*image_buffer)[3 * addr1 + 1];
212 rgb_avg_b1 += (*image_buffer)[3 * addr1 + 2];
213 if (alpha_flag){ rgb_avg_a1 += (*image_buffer)[(*image_width) * (*image_height) * 3 + addr1 + 0]; }
214 rgb_avg_r2 += (*image_buffer)[3 * addr2 + 0];
215 rgb_avg_g2 += (*image_buffer)[3 * addr2 + 1];
216 rgb_avg_b2 += (*image_buffer)[3 * addr2 + 2];
217 if (alpha_flag){ rgb_avg_a2 += (*image_buffer)[(*image_width) * (*image_height) * 3 + addr2 + 0]; }
218
219 (*image_buffer)[3 * addr1 + 0] = rgb_avg_r2;
220 (*image_buffer)[3 * addr1 + 1] = rgb_avg_g2;
221 (*image_buffer)[3 * addr1 + 2] = rgb_avg_b2;
222 if (alpha_flag){ (*image_buffer)[(*image_width) * (*image_height) * 3 + addr1 + 0] = rgb_avg_a2; }
223 (*image_buffer)[3 * addr2 + 0] = rgb_avg_r1;
224 (*image_buffer)[3 * addr2 + 1] = rgb_avg_g1;
225 (*image_buffer)[3 * addr2 + 2] = rgb_avg_b1;
226 if (alpha_flag){ (*image_buffer)[(*image_width) * (*image_height) * 3 + addr2 + 0] = rgb_avg_a1; }
227 }
228 }
229
230 return 0;
231 }
232
233
234
ROTATE270(unsigned char ** image_buffer,unsigned long * image_width,unsigned long * image_height,int alpha_flag)235 int ROTATE270(
236 unsigned char **image_buffer,
237 unsigned long *image_width,
238 unsigned long *image_height,
239 int alpha_flag)
240 {
241 unsigned char *bitmap_buffer2;
242 unsigned int x, y;
243
244 unsigned long new_width;
245 unsigned long new_height;
246 new_width = *image_width;
247 new_height = *image_height;
248
249 /*allocate memory */
250 if (alpha_flag) { alpha_flag = 2; }
251 /* print info */ STRING_PRINTV("allocating memory for uncompressed bitmap image\n");
252 bitmap_buffer2 = malloc(new_width * new_height * (3 + alpha_flag) * sizeof (*bitmap_buffer2));
253 if (bitmap_buffer2 == 0) return 1;
254
255 /* print info */ STRING_PRINTV("rotating image with 270\n");
256
257 #ifdef __OPENMP__
258 #pragma omp parallel for private(x, y) num_threads(max_threads)
259 #endif
260 for (y=0; y<new_height; y++){
261
262 for (x=0; x<new_width; x++){
263
264 long addr = 0;
265 long rgb_avg_r = 0;
266 long rgb_avg_g = 0;
267 long rgb_avg_b = 0;
268 long rgb_avg_a = 0;
269
270 addr = (x + y * new_width);
271 rgb_avg_r += (*image_buffer)[3 * addr + 0];
272 rgb_avg_g += (*image_buffer)[3 * addr + 1];
273 rgb_avg_b += (*image_buffer)[3 * addr + 2];
274 if (alpha_flag){ rgb_avg_a += (*image_buffer)[(*image_width) * (*image_height) * 3 + addr + 0]; }
275
276 addr = (y + (new_width - 1 - x) * new_height);
277 bitmap_buffer2[3 * addr + 0] = rgb_avg_r;
278 bitmap_buffer2[3 * addr + 1] = rgb_avg_g;
279 bitmap_buffer2[3 * addr + 2] = rgb_avg_b;
280 if (alpha_flag){ bitmap_buffer2[(*image_width) * (*image_height) * 3 + addr + 0] = rgb_avg_a; }
281 }
282 }
283
284 /* print info */ STRING_PRINTV("freeing uncompressed bitmap buffer\n");
285 free(*image_buffer);
286 *image_buffer = bitmap_buffer2;
287 *image_width = new_height;
288 *image_height = new_width;
289
290 return 0;
291 }
292
293
294
FLIPX(unsigned char ** image_buffer,unsigned long * image_width,unsigned long * image_height,int alpha_flag)295 int FLIPX(
296 unsigned char **image_buffer,
297 unsigned long *image_width,
298 unsigned long *image_height,
299 int alpha_flag)
300 {
301 unsigned int x, y;
302
303 unsigned long new_width;
304 unsigned long new_height;
305 new_width = *image_width;
306 new_height = *image_height;
307
308 /* print info */ STRING_PRINTV("flipping image horizontally\n");
309
310 #ifdef __OPENMP__
311 #pragma omp parallel for private(x, y) num_threads(max_threads)
312 #endif
313 for (y=0; y<new_height; y++){
314
315 for (x=0; x<(new_width/2); x++){
316
317 long addr1 = 0;
318 long addr2 = 0;
319 long rgb_avg_r1 = 0;
320 long rgb_avg_g1 = 0;
321 long rgb_avg_b1 = 0;
322 long rgb_avg_a1 = 0;
323 long rgb_avg_r2 = 0;
324 long rgb_avg_g2 = 0;
325 long rgb_avg_b2 = 0;
326 long rgb_avg_a2 = 0;
327
328 addr1 = (x + y * new_width);
329 addr2 = ((new_width - 1 - x) + y * new_width);
330
331 rgb_avg_r1 += (*image_buffer)[3 * addr1 + 0];
332 rgb_avg_g1 += (*image_buffer)[3 * addr1 + 1];
333 rgb_avg_b1 += (*image_buffer)[3 * addr1 + 2];
334 if (alpha_flag){ rgb_avg_a1 += (*image_buffer)[(*image_width) * (*image_height) * 3 + addr1 + 0]; }
335 rgb_avg_r2 += (*image_buffer)[3 * addr2 + 0];
336 rgb_avg_g2 += (*image_buffer)[3 * addr2 + 1];
337 rgb_avg_b2 += (*image_buffer)[3 * addr2 + 2];
338 if (alpha_flag){ rgb_avg_a2 += (*image_buffer)[(*image_width) * (*image_height) * 3 + addr2 + 0]; }
339
340 (*image_buffer)[3 * addr1 + 0] = rgb_avg_r2;
341 (*image_buffer)[3 * addr1 + 1] = rgb_avg_g2;
342 (*image_buffer)[3 * addr1 + 2] = rgb_avg_b2;
343 if (alpha_flag){ (*image_buffer)[(*image_width) * (*image_height) * 3 + addr1 + 0] = rgb_avg_a2; }
344 (*image_buffer)[3 * addr2 + 0] = rgb_avg_r1;
345 (*image_buffer)[3 * addr2 + 1] = rgb_avg_g1;
346 (*image_buffer)[3 * addr2 + 2] = rgb_avg_b1;
347 if (alpha_flag){ (*image_buffer)[(*image_width) * (*image_height) * 3 + addr2 + 0] = rgb_avg_a1; }
348 }
349 }
350
351 return 0;
352 }
353
354
355
FLIPY(unsigned char ** image_buffer,unsigned long * image_width,unsigned long * image_height,int alpha_flag)356 int FLIPY(
357 unsigned char **image_buffer,
358 unsigned long *image_width,
359 unsigned long *image_height,
360 int alpha_flag)
361 {
362 unsigned int x, y;
363
364 unsigned long new_width;
365 unsigned long new_height;
366 new_width = *image_width;
367 new_height = *image_height;
368
369 /* print info */ STRING_PRINTV("flipping image vertically\n");
370
371 #ifdef __OPENMP__
372 #pragma omp parallel for private(x, y) num_threads(max_threads)
373 #endif
374 for (y=0; y<(new_height/2); y++){
375
376 for (x=0; x<new_width; x++){
377
378 long addr1 = 0;
379 long addr2 = 0;
380 long rgb_avg_r1 = 0;
381 long rgb_avg_g1 = 0;
382 long rgb_avg_b1 = 0;
383 long rgb_avg_a1 = 0;
384 long rgb_avg_r2 = 0;
385 long rgb_avg_g2 = 0;
386 long rgb_avg_b2 = 0;
387 long rgb_avg_a2 = 0;
388
389 addr1 = (x + y * new_width);
390 addr2 = (x + (new_height - 1 - y) * new_width);
391
392 rgb_avg_r1 += (*image_buffer)[3 * addr1 + 0];
393 rgb_avg_g1 += (*image_buffer)[3 * addr1 + 1];
394 rgb_avg_b1 += (*image_buffer)[3 * addr1 + 2];
395 if (alpha_flag){ rgb_avg_a1 += (*image_buffer)[(*image_width) * (*image_height) * 3 + addr1 + 0]; }
396 rgb_avg_r2 += (*image_buffer)[3 * addr2 + 0];
397 rgb_avg_g2 += (*image_buffer)[3 * addr2 + 1];
398 rgb_avg_b2 += (*image_buffer)[3 * addr2 + 2];
399 if (alpha_flag){ rgb_avg_a2 += (*image_buffer)[(*image_width) * (*image_height) * 3 + addr2 + 0]; }
400
401 (*image_buffer)[3 * addr1 + 0] = rgb_avg_r2;
402 (*image_buffer)[3 * addr1 + 1] = rgb_avg_g2;
403 (*image_buffer)[3 * addr1 + 2] = rgb_avg_b2;
404 if (alpha_flag){ (*image_buffer)[(*image_width) * (*image_height) * 3 + addr1 + 0] = rgb_avg_a2; }
405 (*image_buffer)[3 * addr2 + 0] = rgb_avg_r1;
406 (*image_buffer)[3 * addr2 + 1] = rgb_avg_g1;
407 (*image_buffer)[3 * addr2 + 2] = rgb_avg_b1;
408 if (alpha_flag){ (*image_buffer)[(*image_width) * (*image_height) * 3 + addr2 + 0] = rgb_avg_a1; }
409 }
410 }
411
412 return 0;
413 }
414
415