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