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