fix a fence post error validating a combing mode number
[imager.git] / flip.im
1 #define IMAGER_NO_CONTEXT
2 #include "imager.h"
3
4 static void flip_h(i_img *im);
5 static void flip_v(i_img *im);
6 static void flip_hv(i_img *im);
7
8 #define XAXIS 0
9 #define YAXIS 1
10 #define XYAXIS 2
11
12 /*
13 =item i_flipxy(im, axis)
14
15 Flips the image inplace around the axis specified.
16 Returns 0 if parameters are invalid.
17
18    im   - Image pointer
19    axis - 0 = x, 1 = y, 2 = both
20
21 =cut
22 */
23
24 undef_int
25 i_flipxy(i_img *im, int direction) {
26   dIMCTXim(im);
27   i_clear_error();
28
29   im_log((aIMCTX, 1, "i_flipxy(im %p, direction %d)\n", im, direction ));
30
31   if (!im)
32     return 0;
33
34   switch (direction) {
35   case XAXIS: /* Horizontal flip */
36     flip_h(im);
37     break;
38
39   case YAXIS: /* Vertical flip */
40     flip_v(im);
41     break;
42
43   case XYAXIS: /* Horizontal and Vertical flip */
44     flip_hv(im);
45     break;
46
47   default:
48     im_log((aIMCTX, 1, "i_flipxy: direction is invalid\n" ));
49     im_push_errorf(aIMCTX, 0, "direction %d invalid", direction);
50     return 0;
51   }
52   return 1;
53 }
54
55 static void
56 flip_row_pal(i_palidx *row, i_img_dim width) {
57   i_palidx tmp;
58   i_palidx *leftp = row;
59   i_palidx *rightp = row + width - 1;
60   
61   while (leftp < rightp) {
62     tmp = *leftp;
63     *leftp = *rightp;
64     *rightp = tmp;
65     ++leftp;
66     --rightp;
67   }
68 }
69
70 #code
71
72 static void
73 IM_SUFFIX(flip_row)(IM_COLOR *row, i_img_dim width) {
74   IM_COLOR tmp;
75   IM_COLOR *leftp = row;
76   IM_COLOR *rightp = row + width - 1;
77   
78   while (leftp < rightp) {
79     tmp = *leftp;
80     *leftp = *rightp;
81     *rightp = tmp;
82     ++leftp;
83     --rightp;
84   }
85 }
86
87 #/code
88
89 static void
90 flip_h(i_img *im) {
91   i_img_dim y;
92   if (im->type == i_palette_type) {
93     i_palidx *line = mymalloc(im->xsize * sizeof(i_palidx));
94     for (y = 0; y < im->ysize; ++y) {
95       i_gpal(im, 0, im->xsize, y, line);
96       flip_row_pal(line, im->xsize);
97       i_ppal(im, 0, im->xsize, y, line);
98     }
99     myfree(line);
100   }
101   else {
102 #code im->bits == i_8_bits
103     IM_COLOR *line = mymalloc(im->xsize * sizeof(IM_COLOR));
104     for (y = 0; y < im->ysize; ++y) {
105       IM_GLIN(im, 0, im->xsize, y, line);
106       IM_SUFFIX(flip_row)(line, im->xsize);
107       IM_PLIN(im, 0, im->xsize, y, line);
108     }
109     myfree(line);
110 #/code
111   }
112 }
113
114 static void
115 flip_v(i_img *im) {
116   i_img_dim topy = 0;
117   i_img_dim boty = im->ysize - 1;
118   if (im->type == i_palette_type) {
119     i_palidx *top_line = mymalloc(im->xsize * sizeof(i_palidx));
120     i_palidx *bot_line = mymalloc(im->xsize * sizeof(i_palidx));
121     while (topy < boty) {
122       i_gpal(im, 0, im->xsize, topy, top_line);
123       i_gpal(im, 0, im->xsize, boty, bot_line);
124       i_ppal(im, 0, im->xsize, topy, bot_line);
125       i_ppal(im, 0, im->xsize, boty, top_line);
126       ++topy;
127       --boty;
128     }
129     myfree(bot_line);
130     myfree(top_line);
131   }
132   else {
133 #code im->bits == i_8_bits
134     IM_COLOR *top_line = mymalloc(im->xsize * sizeof(IM_COLOR));
135     IM_COLOR *bot_line = mymalloc(im->xsize * sizeof(IM_COLOR));
136     while (topy < boty) {
137       IM_GLIN(im, 0, im->xsize, topy, top_line);
138       IM_GLIN(im, 0, im->xsize, boty, bot_line);
139       IM_PLIN(im, 0, im->xsize, topy, bot_line);
140       IM_PLIN(im, 0, im->xsize, boty, top_line);
141       ++topy;
142       --boty;
143     }
144     myfree(top_line);
145     myfree(bot_line);
146 #/code 
147   }
148 }
149
150 static void
151 flip_hv(i_img *im) {
152   i_img_dim topy = 0;
153   i_img_dim boty = im->ysize - 1;
154   if (im->type == i_palette_type) {
155     i_palidx *top_line = mymalloc(im->xsize * sizeof(i_palidx));
156     i_palidx *bot_line = mymalloc(im->xsize * sizeof(i_palidx));
157     while (topy < boty) {
158       i_gpal(im, 0, im->xsize, topy, top_line);
159       i_gpal(im, 0, im->xsize, boty, bot_line);
160       flip_row_pal(top_line, im->xsize);
161       flip_row_pal(bot_line, im->xsize);
162       i_ppal(im, 0, im->xsize, topy, bot_line);
163       i_ppal(im, 0, im->xsize, boty, top_line);
164       ++topy;
165       --boty;
166     }
167     myfree(bot_line);
168     myfree(top_line);
169   }
170   else {
171 #code im->bits == i_8_bits
172     IM_COLOR *top_line = mymalloc(im->xsize * sizeof(IM_COLOR));
173     IM_COLOR *bot_line = mymalloc(im->xsize * sizeof(IM_COLOR));
174     while (topy < boty) {
175       IM_GLIN(im, 0, im->xsize, topy, top_line);
176       IM_GLIN(im, 0, im->xsize, boty, bot_line);
177       IM_SUFFIX(flip_row)(top_line, im->xsize);
178       IM_SUFFIX(flip_row)(bot_line, im->xsize);
179       IM_PLIN(im, 0, im->xsize, topy, bot_line);
180       IM_PLIN(im, 0, im->xsize, boty, top_line);
181       ++topy;
182       --boty;
183     }
184     if (topy == boty) {
185       IM_GLIN(im, 0, im->xsize, topy, top_line);
186       IM_SUFFIX(flip_row)(top_line, im->xsize);
187       IM_PLIN(im, 0, im->xsize, topy, top_line);
188     }
189     myfree(top_line);
190     myfree(bot_line);
191 #/code 
192   }
193 }