1 /*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
27 /*
28 * rotatetest1.c
29 *
30 * rotatetest1 filein angle(in degrees) fileout
31 */
32
33 #include "allheaders.h"
34
35 #define NTIMES 180
36 #define NITERS 3
37
main(int argc,char ** argv)38 int main(int argc,
39 char **argv)
40 {
41 l_int32 i, w, h, d, rotflag;
42 PIX *pixs, *pixt, *pixd;
43 l_float32 angle, deg2rad, pops, ang;
44 char *filein, *fileout;
45 static char mainName[] = "rotatetest1";
46
47 if (argc != 4)
48 return ERROR_INT(" Syntax: rotatetest1 filein angle fileout",
49 mainName, 1);
50 filein = argv[1];
51 angle = atof(argv[2]);
52 fileout = argv[3];
53
54 setLeptDebugOK(1);
55 lept_mkdir("lept/rotate");
56
57 deg2rad = 3.1415926535 / 180.;
58 if ((pixs = pixRead(filein)) == NULL)
59 return ERROR_INT("pix not made", mainName, 1);
60 if (pixGetDepth(pixs) == 1) {
61 pixt = pixScaleToGray3(pixs);
62 pixDestroy(&pixs);
63 pixs = pixAddBorderGeneral(pixt, 1, 0, 1, 0, 255);
64 pixDestroy(&pixt);
65 }
66
67 pixGetDimensions(pixs, &w, &h, &d);
68 fprintf(stderr, "w = %d, h = %d\n", w, h);
69
70 #if 0
71 /* repertory of rotation operations to choose from */
72 pixd = pixRotateAM(pixs, deg2rad * angle, L_BRING_IN_WHITE);
73 pixd = pixRotateAMColor(pixs, deg2rad * angle, 0xffffff00);
74 pixd = pixRotateAMColorFast(pixs, deg2rad * angle, 255);
75 pixd = pixRotateAMCorner(pixs, deg2rad * angle, L_BRING_IN_WHITE);
76 pixd = pixRotateShear(pixs, w /2, h / 2, deg2rad * angle,
77 L_BRING_IN_WHITE);
78 pixd = pixRotate3Shear(pixs, w /2, h / 2, deg2rad * angle,
79 L_BRING_IN_WHITE);
80 pixRotateShearIP(pixs, w / 2, h / 2, deg2rad * angle); pixd = pixs;
81 #endif
82
83 #if 0
84 /* timing of shear rotation */
85 for (i = 0; i < NITERS; i++) {
86 pixd = pixRotateShear(pixs, (i * w) / NITERS,
87 (i * h) / NITERS, deg2rad * angle,
88 L_BRING_IN_WHITE);
89 pixDisplay(pixd, 100 + 20 * i, 100 + 20 * i);
90 pixDestroy(&pixd);
91 }
92 #endif
93
94 #if 0
95 /* timing of in-place shear rotation */
96 for (i = 0; i < NITERS; i++) {
97 pixRotateShearIP(pixs, w/2, h/2, deg2rad * angle, L_BRING_IN_WHITE);
98 /* pixRotateShearCenterIP(pixs, deg2rad * angle, L_BRING_IN_WHITE); */
99 pixDisplay(pixs, 100 + 20 * i, 100 + 20 * i);
100 }
101 pixd = pixs;
102 if (pixGetDepth(pixd) == 1)
103 pixWrite(fileout, pixd, IFF_PNG);
104 else
105 pixWrite(fileout, pixd, IFF_JFIF_JPEG);
106 pixDestroy(&pixs);
107 #endif
108
109 #if 0
110 /* timing of various rotation operations (choose) */
111 startTimer();
112 w = pixGetWidth(pixs);
113 h = pixGetHeight(pixs);
114 for (i = 0; i < NTIMES; i++) {
115 pixd = pixRotateShearCenter(pixs, deg2rad * angle, L_BRING_IN_WHITE);
116 pixDestroy(&pixd);
117 }
118 pops = (l_float32)(w * h * NTIMES / 1000000.) / stopTimer();
119 fprintf(stderr, "vers. 1, mpops: %f\n", pops);
120 startTimer();
121 w = pixGetWidth(pixs);
122 h = pixGetHeight(pixs);
123 for (i = 0; i < NTIMES; i++) {
124 pixRotateShearIP(pixs, w/2, h/2, deg2rad * angle, L_BRING_IN_WHITE);
125 }
126 pops = (l_float32)(w * h * NTIMES / 1000000.) / stopTimer();
127 fprintf(stderr, "shear, mpops: %f\n", pops);
128 pixWrite(fileout, pixs, IFF_PNG);
129 for (i = 0; i < NTIMES; i++) {
130 pixRotateShearIP(pixs, w/2, h/2, -deg2rad * angle, L_BRING_IN_WHITE);
131 }
132 pixWrite("/usr/tmp/junkout", pixs, IFF_PNG);
133 #endif
134
135 #if 0
136 /* area-mapping rotation operations */
137 pixd = pixRotateAM(pixs, deg2rad * angle, L_BRING_IN_WHITE);
138 /* pixd = pixRotateAMColorFast(pixs, deg2rad * angle, 255); */
139 if (pixGetDepth(pixd) == 1)
140 pixWrite(fileout, pixd, IFF_PNG);
141 else
142 pixWrite(fileout, pixd, IFF_JFIF_JPEG);
143 #endif
144
145 #if 0
146 /* compare the standard area-map color rotation with
147 * the fast area-map color rotation, on a pixel basis */
148 {
149 PIX *pix1, *pix2;
150 NUMA *nar, *nag, *nab, *naseq;
151 GPLOT *gplot;
152
153 startTimer();
154 pix1 = pixRotateAMColor(pixs, 0.12, 0xffffff00);
155 fprintf(stderr, " standard color rotate: %7.2f sec\n", stopTimer());
156 pixWrite("/tmp/lept/rotate/color1.jpg", pix1, IFF_JFIF_JPEG);
157 startTimer();
158 pix2 = pixRotateAMColorFast(pixs, 0.12, 0xffffff00);
159 fprintf(stderr, " fast color rotate: %7.2f sec\n", stopTimer());
160 pixWrite("/tmp/lept/rotate/color2.jpg", pix2, IFF_JFIF_JPEG);
161 pixd = pixAbsDifference(pix1, pix2);
162 pixGetColorHistogram(pixd, 1, &nar, &nag, &nab);
163 naseq = numaMakeSequence(0., 1., 256);
164 gplot = gplotCreate("/tmp/lept/rotate/absdiff", GPLOT_PNG,
165 "Number vs diff", "diff", "number");
166 gplotAddPlot(gplot, naseq, nar, GPLOT_POINTS, "red");
167 gplotAddPlot(gplot, naseq, nag, GPLOT_POINTS, "green");
168 gplotAddPlot(gplot, naseq, nab, GPLOT_POINTS, "blue");
169 gplotMakeOutput(gplot);
170 l_fileDisplay("/tmp/lept/rotate/absdiff.png", 100, 100, 1.0);
171 pixDestroy(&pix1);
172 pixDestroy(&pix2);
173 pixDestroy(&pixd);
174 numaDestroy(&nar);
175 numaDestroy(&nag);
176 numaDestroy(&nab);
177 numaDestroy(&naseq);
178 gplotDestroy(&gplot);
179 }
180 #endif
181
182 /* Do a succession of 180 7-degree rotations in a cw
183 * direction, and unwind the result with another set in
184 * a ccw direction. Although there is a considerable amount
185 * of distortion after successive rotations, after all
186 * 360 rotations, the resulting image is restored to
187 * its original pristine condition! */
188 #if 1
189 rotflag = L_ROTATE_AREA_MAP;
190 /* rotflag = L_ROTATE_SHEAR; */
191 /* rotflag = L_ROTATE_SAMPLING; */
192 ang = 7.0 * deg2rad;
193 pixGetDimensions(pixs, &w, &h, NULL);
194 pixd = pixRotate(pixs, ang, rotflag, L_BRING_IN_WHITE, w, h);
195 pixWrite("/tmp/lept/rotate/rot7.png", pixd, IFF_PNG);
196 for (i = 1; i < 180; i++) {
197 pixs = pixd;
198 pixd = pixRotate(pixs, ang, rotflag, L_BRING_IN_WHITE, w, h);
199 if ((i % 30) == 0) pixDisplay(pixd, 600, 0);
200 pixDestroy(&pixs);
201 }
202
203 pixWrite("/tmp/lept/rotate/spin.png", pixd, IFF_PNG);
204 pixDisplay(pixd, 0, 0);
205
206 for (i = 0; i < 180; i++) {
207 pixs = pixd;
208 pixd = pixRotate(pixs, -ang, rotflag, L_BRING_IN_WHITE, w, h);
209 if (i && (i % 30) == 0) pixDisplay(pixd, 600, 500);
210 pixDestroy(&pixs);
211 }
212
213 pixWrite("/tmp/lept/rotate/unspin.png", pixd, IFF_PNG);
214 pixDisplay(pixd, 0, 500);
215 pixDestroy(&pixd);
216 #endif
217
218 return 0;
219 }
220
221