1 
2  /* ==================================================================
3     FILE: "/home/joze/pub/zimg/zimg/img.c"
4     LAST MODIFIED: "Wed, 02 Jul 2003 21:13:10 CEST (joze)"
5     (C) 1999 - 2003 by Johannes Zellner
6     johannes@zellner.org
7     $Id: img.c,v 1.8 2003/07/02 19:19:56 joze Exp $
8     ---
9     Copyright (c) 1999 - 2003, Johannes Zellner <johannes@zellner.org>
10     All rights reserved.
11 
12     Redistribution and use in source and binary forms, with or without
13     modification, are permitted provided that the following conditions
14     are met:
15 
16       * Redistributions of source code must retain the above copyright
17         notice, this list of conditions and the following disclaimer.
18       * Redistributions in binary form must reproduce the above copyright
19         notice, this list of conditions and the following disclaimer in the
20         documentation and/or other materials provided with the distribution.
21       * Neither the name of Johannes Zellner nor the names of contributors
22         to this software may be used to endorse or promote products derived
23         from this software without specific prior written permission.
24 
25     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26     ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28     A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
29     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32     PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33     LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34     NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36     ================================================================== */
37 
38 #include "zimg_priv.h"
39 
40 
41 /* ========================
42  * 2D - differentiate image
43  * ========================
44  */
45 void
differentiate(FLOAT * data,unsigned int x,unsigned int y)46 differentiate(FLOAT* data, unsigned int x, unsigned int y)
47 {
48     int     i, j;
49     int     x_ = x - 1;
50     int     y_ = y - 1;
51     int     len = x * y;
52     FLOAT   center;
53     FLOAT  *tmp;
54 
55     tmp =  (FLOAT *) malloc (sizeof (FLOAT) * len);
56 
57     for(i = 0; i < len; i++)
58 	*(tmp + i) = 0.0;
59 
60     for (i = 1; i < x_; i++) {
61 	for (j = 1; j < y_; j++) {
62 
63 	    center = *(data +  (i * y) + j); /* current 'center' pixel */
64 
65 
66 	    /* --------------------------------
67 	     * set tmp to the difference to all
68 	     * neighbouring pixels
69 	     * --------------------------------
70 	     */
71 	    *(tmp +  (i * y) + j)
72 		/* x= 0, y=+1 */
73 		= fabs (center - *(data +  (i * y) + j + 1))
74 		/* x= 0, y=-1 */
75 		+ fabs (center - *(data +  (i * y) + j - 1))
76 
77 		/* x=+1, y= 0 */
78 		+ fabs (center - *(data +  ((i + 1) * y) + j))
79 		/* x=-1, y= 0 */
80 		+ fabs (center - *(data +  ((i - 1) * y) + j))
81 
82 		/* x=+1, y=+1 */
83 		+ fabs (center - *(data +  ((i + 1) * y) + j + 1))
84 		/* x=+1, y=-1 */
85 		+ fabs (center - *(data +  ((i + 1) * y) + j - 1))
86 
87 		/* x=-1, y=+1 */
88 		+ fabs (center - *(data +  ((i - 1) * y) + j + 1))
89 		/* x=-1, y=-1 */
90 		+ fabs (center - *(data +  ((i - 1) * y) + j - 1));
91 
92 	}
93     }
94 
95 
96     /* -----------------------
97      * edges and corners need
98      * some special treatment.
99      * first the edges:
100      * -----------------------
101      */
102     for (i = 0; i < x; i++) {
103 	for (j = 0; j < y; j++) {
104 
105 	    if (i == 0)
106 		*(tmp +  (i * y) + j) = *(tmp +  ((i + 1) * y) + j);
107 	    if (i == x)
108 		*(tmp +  (i * y) + j) = *(tmp +  ((i - 1) * y) + j);
109 
110 	    if (j == 0)
111 		*(tmp +  (i * y) + j) = *(tmp +  (i * y) + j + 1);
112 	    if (j == y)
113 		*(tmp +  (i * y) + j) = *(tmp +  (i * y) + j - 1);
114 
115 	}
116     }
117 
118 
119     /* -------
120      * corners
121      * -------
122      */
123     *(tmp) = *(tmp + 1);
124     *(tmp + y - 1) = *(tmp + y - 2);
125     *(tmp +  ((x_) * y)) = *(tmp +  (x_) * y_);
126     *(tmp +  ((x_) * y) + y_) = *(tmp +  ((x_) * y) + y - 2);
127 
128 
129     /* copy tmp back to data */
130     memcpy(data, tmp, sizeof(FLOAT) * len);
131 
132     free (tmp);
133     return;
134 }
135 
136 /* f(x) curvature for one point
137    on a uniform grid */
138 FLOAT
curvature1d(FLOAT center,FLOAT p1,FLOAT p2)139 curvature1d(FLOAT center, FLOAT p1, FLOAT p2)
140 {
141     FLOAT angle1 = atan(p1 - center);
142     FLOAT angle2 = atan(p2 - center);
143 
144     return angle1 + angle2;
145 }
146 
147 /* f(x, y) curvature for one point
148    on a uniform grid */
149 FLOAT
curvature2d(FLOAT center,FLOAT left,FLOAT right,FLOAT top,FLOAT bottom)150 curvature2d(FLOAT center, FLOAT left, FLOAT right, FLOAT top, FLOAT bottom)
151 {
152     return curvature1d(center, left, right) + curvature1d(center, top, bottom);
153 }
154 
155 FLOAT*
curvature(FLOAT * data,unsigned int width,unsigned int height)156 curvature(FLOAT* data, unsigned int width, unsigned int height)
157 {
158     unsigned int len = width * height;
159     unsigned int width_1 = width - 1;
160     unsigned int height_1 = height - 1;
161     unsigned int width_2 = width - 2;
162     unsigned int height_2 = height - 2;
163     unsigned int width_3 = width - 3;
164     unsigned int height_3 = height - 3;
165 
166     unsigned int y, x;
167 
168     FLOAT* result = malloc(sizeof(FLOAT) * len);
169     FLOAT* ptr = result;
170     assert(result);
171 
172     for (y = 0; y < height; y++) {
173 	for (x = 0; x < width; x++, ptr++) {
174 
175 	    unsigned int cen_x;
176 	    unsigned int cen_y;
177 	    unsigned int left;
178 	    unsigned int right;
179 	    unsigned int top;
180 	    unsigned int bottom;
181 
182 	    if (0 == x) {
183 		left   = 0;
184 		cen_x  = 1;
185 		right  = 2;
186 	    } else if (width_1 == x) {
187 		left   = width_3;
188 		cen_x  = width_2;
189 		right  = width_1;
190 	    } else {
191 		left   = x - 1;
192 		cen_x  = x;
193 		right  = x + 1;
194 	    }
195 
196 	    if (0 == y) {
197 		top    = 0;
198 		cen_y  = 1;
199 		bottom = 2;
200 	    } else if (height_1 == y) {
201 		top    = height_3;
202 		cen_y  = height_2;
203 		bottom = height_1;
204 	    } else {
205 		top    = y - 1;
206 		cen_y  = y;
207 		bottom = y + 1;
208 	    }
209 
210 	    *ptr = curvature2d
211 		(ACCESS2D(cen_x, cen_y, data, width),
212 		 ACCESS2D(left, cen_y, data, width),
213 		 ACCESS2D(right, cen_y, data, width),
214 		 ACCESS2D(cen_x, top, data, width),
215 		 ACCESS2D(cen_x, bottom, data, width));
216 	}
217     }
218 
219     /* copy tmp back to data */
220     memcpy(data, result, sizeof(FLOAT) * len);
221     free(result);
222 
223     return data;
224 }
225 
226 
227 void
torange(FLOAT * data,int len,FLOAT low,FLOAT high)228 torange(FLOAT* data, int len, FLOAT low, FLOAT high)
229 {
230     int i;
231 
232     for (i = 0; i < len; i++) {
233 	if (*(data + i) > high)
234 	    *(data + i) = high;
235 	if (*(data + i) < low)
236 	    *(data + i) = low;
237     }
238 
239     return;
240 }
241 
242