1 /* $Id$ */
2
3 #include "IPAsupp.h"
4 #include "Geometry.h"
5 #include "Geometry.inc"
6 #include "GeometrySupp.h"
7
IPA__Geometry_mirror(PImage img,HV * profile)8 PImage IPA__Geometry_mirror(PImage img,HV *profile)
9 {
10 dPROFILE;
11 const char *method="IPA::Geometry::mirror";
12 PImage oimg;
13 int mType=0;
14 int y;
15
16 if ( !img || !kind_of(( Handle) img, CImage))
17 croak("%s: not an image passed", method);
18
19 if (pexist(type)) {
20 mType=pget_i(type);
21 }
22
23 switch (mType) {
24 case HORIZONTAL:
25 {
26 Byte *pi,*po;
27 oimg=createNamedImage(img->w,img->h,img->type,method);
28 if ((oimg->type & imGrayScale)==0) {
29 memcpy(oimg->palette,img->palette,img->palSize*sizeof(RGBColor));
30 oimg->palSize=img->palSize;
31 }
32 if (!oimg) {
33 croak("%s: can't create output image",method);
34 }
35 for (y=0,pi=img->data,po=(oimg->data+oimg->lineSize*(oimg->h-1)); y<img->h; y++,pi+=img->lineSize,po-=oimg->lineSize) {
36 memcpy(po,pi,img->lineSize);
37 }
38 }
39 break;
40 case VERTICAL:
41 {
42 int x;
43 oimg=createNamedImage(img->w,img->h,img->type,method);
44 if ((oimg->type & imGrayScale)==0) {
45 memcpy(oimg->palette,img->palette,img->palSize*sizeof(RGBColor));
46 oimg->palSize=img->palSize;
47 }
48 switch (img->type & imBPP) {
49 case imbpp1:
50 {
51 Byte *pi,*po;
52 int x1;
53 for (y=0,pi=img->data,po=oimg->data; y<img->h; y++,pi+=img->lineSize,po+=oimg->lineSize) {
54 po[(oimg->w-1)>>3]=0;
55 for (x=0,x1=(oimg->w-1); x<img->w; x++,x1--) {
56 if ((x1%8)==7) {
57 po[x1>>3]=0;
58 }
59 po[x1>>3]|=((pi[x>>3] >> (7-(x & 7))) & 1)<<(7-(x1 & 7));
60 }
61 }
62 }
63 break;
64 case imbpp4:
65 {
66 Byte *pi,*po,p;
67 int x1;
68 for (y=0,pi=img->data,po=oimg->data; y<img->h; y++,pi+=img->lineSize,po+=oimg->lineSize) {
69 po[(oimg->w-1)>>1]=0;
70 for (x=0,x1=(oimg->w-1); x<img->w; x++,x1--) {
71 p=pi[x>>1];
72 p=(x&1 ? p : (p>>4)) & 0x0f;
73 if (x1&1) {
74 po[x1>>1]=p;
75 }
76 else {
77 po[x1>>1]|=p<<4;
78 }
79 }
80 }
81 }
82 break;
83 case imbpp8:
84 {
85 Byte *pi,*po;
86 for (y=0,pi=img->data,po=oimg->data; y<img->h; y++,pi+=img->lineSize,po+=oimg->lineSize) {
87 for (x=0; x<img->w; x++) {
88 po[img->w-x-1]=pi[x];
89 }
90 }
91 }
92 break;
93 case imbpp16:
94 {
95 Short *pi,*po;
96 for (y=0,pi=(Short*)img->data,po=(Short*)oimg->data; y<img->h; y++,(*((Byte**)&pi))+=img->lineSize,(*((Byte**)&po))+=oimg->lineSize) {
97 for (x=0; x<img->w; x++) {
98 po[img->w-x-1]=pi[x];
99 }
100 }
101 }
102 break;
103 case imbpp24:
104 {
105 PRGBColor pi,po;
106 for (y=0,pi=(PRGBColor)img->data,po=(PRGBColor)oimg->data; y<img->h; y++,(*((Byte**)&pi))+=img->lineSize,(*((Byte**)&po))+=oimg->lineSize) {
107 for (x=0; x<img->w; x++) {
108 po[img->w-x-1]=pi[x];
109 }
110 }
111 }
112 break;
113 case imbpp32:
114 {
115 U32 *pi,*po;
116 for (y=0,pi=(U32*)img->data,po=(U32*)oimg->data; y<img->h; y++,(*((Byte**)&pi))+=img->lineSize,(*((Byte**)&po))+=oimg->lineSize) {
117 for (x=0; x<img->w; x++) {
118 po[img->w-x-1]=pi[x];
119 }
120 }
121 }
122 break;
123 case imbpp64:
124 {
125 typedef Byte pix64[8];
126 pix64 *pi,*po;
127 for (y=0,pi=(pix64*)img->data,po=(pix64*)oimg->data; y<img->h; y++,(*((Byte**)&pi))+=img->lineSize,(*((Byte**)&po))+=oimg->lineSize) {
128 for (x=0; x<img->w; x++) {
129 memcpy(po,pi,sizeof(pix64));
130 }
131 }
132 }
133 break;
134 case imbpp128:
135 {
136 typedef Byte pix128[8];
137 pix128 *pi,*po;
138 for (y=0,pi=(pix128*)img->data,po=(pix128*)oimg->data; y<img->h; y++,(*((Byte**)&pi))+=img->lineSize,(*((Byte**)&po))+=oimg->lineSize) {
139 for (x=0; x<img->w; x++) {
140 memcpy(po,pi,sizeof(pix128));
141 }
142 }
143 }
144 break;
145 default:
146 croak("%s: unsupported image type",method);
147 }
148 }
149 break;
150 default:
151 croak("%s: %d is unknown type of mirroring",method,mType);
152 }
153
154 return oimg;
155 }
156
IPA__Geometry_rotate90(PImage img,Bool clockwise)157 PImage IPA__Geometry_rotate90(PImage img, Bool clockwise)
158 {
159 const char *method="IPA::Geometry::rotate90";
160 PImage nimg;
161
162 register Byte *src;
163 int bs, sdw, ddh, w, y;
164
165 if ( !img || !kind_of(( Handle) img, CImage))
166 croak("%s: not an image passed", method);
167
168 if (( img-> type & imBPP) < 8) {
169 Handle convt, type8;
170 convt = img-> self-> dup((Handle) img);
171 CImage(convt)-> set_type( convt, imbpp8);
172 type8 = ( Handle) IPA__Geometry_rotate90((PImage) convt, clockwise);
173 Object_destroy( convt);
174
175 CImage(type8)-> set_conversion( type8, ictNone);
176 CImage(type8)-> set_type( type8, img-> type);
177 CImage(type8)-> set_conversion( type8, img-> conversion);
178 return (PImage) type8;
179 }
180
181 nimg = createImage( img-> h, img-> w, img-> type);
182 memcpy( nimg-> palette, img-> palette, ( nimg-> palSize = img-> palSize) * 3);
183
184 w = img-> w;
185 bs = (img-> type & imBPP) / 8;
186 src = img-> data;
187 sdw = img-> lineSize - w * bs;
188 ddh = nimg-> lineSize;
189
190 if ( clockwise) {
191 if ( bs == 1) {
192 Byte * dst0 = nimg-> data + nimg-> w - ddh - 1;
193 for ( y = 0; y < img-> h; y++) {
194 register int x = w;
195 register Byte * dst = dst0--;
196 while (x--)
197 *(dst += ddh) = *src++;
198 src += sdw;
199 }
200 } else {
201 Byte * dst0 = nimg-> data + ( nimg-> w - 1) * bs;
202 ddh -= bs;
203 for ( y = 0; y < img-> h; y++) {
204 register int x = w;
205 register Byte * dst = dst0;
206 while (x--) {
207 register int b = bs;
208 while ( b--)
209 *dst++ = *src++;
210 dst += ddh;
211
212 }
213 src += sdw;
214 dst0 -= bs;
215 }
216 }
217 } else {
218 if ( bs == 1) {
219 Byte * dst0 = nimg-> data + nimg-> h * nimg-> lineSize;
220 for ( y = 0; y < img-> h; y++) {
221 register int x = w;
222 register Byte * dst = dst0++;
223 while (x--)
224 *(dst -= ddh) = *src++;
225 src += sdw;
226 }
227 } else {
228 Byte * dst0 = nimg-> data + ( nimg-> h - 1) * nimg-> lineSize;
229 ddh += bs;
230 for ( y = 0; y < img-> h; y++) {
231 register int x = w;
232 register Byte * dst = dst0;
233 while (x--) {
234 register int b = bs;
235 while ( b--)
236 *dst++ = *src++;
237 dst -= ddh;
238 }
239 src += sdw;
240 dst0 += bs;
241 }
242 }
243 }
244
245 return nimg;
246 }
247
IPA__Geometry_rotate180(PImage img)248 PImage IPA__Geometry_rotate180(PImage img)
249 {
250 const char *method="IPA::Geometry::rotate180";
251 PImage nimg;
252
253 register Byte *src, *dst;
254 int bs, dw, w, y;
255
256 if ( !img || !kind_of(( Handle) img, CImage))
257 croak("%s: not an image passed", method);
258
259 if (( img-> type & imBPP) < 8) {
260 Handle convt, type8;
261 convt = img-> self-> dup((Handle) img);
262 CImage(convt)-> set_type( convt, imbpp8);
263 type8 = ( Handle) IPA__Geometry_rotate180((PImage) convt);
264 Object_destroy( convt);
265
266 CImage(type8)-> set_conversion( type8, ictNone);
267 CImage(type8)-> set_type( type8, img-> type);
268 CImage(type8)-> set_conversion( type8, img-> conversion);
269 return (PImage) type8;
270 }
271
272 nimg = createImage( img-> w, img-> h, img-> type);
273 memcpy( nimg-> palette, img-> palette, ( nimg-> palSize = img-> palSize) * 3);
274
275 w = img-> w;
276 bs = (img-> type & imBPP) / 8;
277 dw = img-> lineSize - w * bs;
278 src = img-> data;
279 dst = nimg-> data + nimg-> h * nimg-> lineSize - dw - bs;
280
281 if ( bs == 1) {
282 for ( y = 0; y < img-> h; y++) {
283 register int x = w;
284 while (x--)
285 *dst-- = *src++;
286 src += dw;
287 dst -= dw;
288 }
289 } else {
290 int bs2 = bs + bs;
291 for ( y = 0; y < img-> h; y++) {
292 register int x = w;
293 while (x--) {
294 register int b = bs;
295 while ( b--)
296 *dst++ = *src++;
297 dst -= bs2;
298 }
299 src += dw;
300 dst -= dw;
301 }
302 }
303
304 return nimg;
305 }
306