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