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