naev 0.10.4
distance_field.c
Go to the documentation of this file.
1/* Freetype GL - A C OpenGL Freetype engine
2 *
3Copyright 2011-2016 Nicolas P. Rougier
4Copyright 2013-2016 Marcel Metz
5All rights reserved.
6
7Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions are met:
9
10 1. Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
21FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28The views and conclusions contained in the software and documentation are
29those of the authors and should not be interpreted as representing official
30policies, either expressed or implied, of the freetype-gl project.
31 */
32
33
42#include <math.h>
43#include <float.h>
44#include <stdlib.h>
45#include <string.h>
48#include "edtaa3func.h"
49
60double *
61make_distance_mapd( double *data, unsigned int width, unsigned int height, double *vmax )
62{
63 short * xdist = (short *) malloc( width * height * sizeof(short) );
64 short * ydist = (short *) malloc( width * height * sizeof(short) );
65 double * gx = (double *) calloc( width * height, sizeof(double) );
66 double * gy = (double *) calloc( width * height, sizeof(double) );
67 double * outside = (double *) calloc( width * height, sizeof(double) );
68 double * inside = (double *) calloc( width * height, sizeof(double) );
69 unsigned int i;
70
71 // Compute outside = edtaa3(bitmap); % Transform background (0's)
72 computegradient( data, width, height, gx, gy);
73 edtaa3(data, gx, gy, width, height, xdist, ydist, outside);
74 for( i=0; i<width*height; ++i)
75 if( outside[i] < 0.0 )
76 outside[i] = 0.0;
77
78 // Compute inside = edtaa3(1-bitmap); % Transform foreground (1's)
79 memset( gx, 0, sizeof(double)*width*height );
80 memset( gy, 0, sizeof(double)*width*height );
81 for( i=0; i<width*height; ++i)
82 data[i] = 1 - data[i];
83 computegradient( data, width, height, gx, gy );
84 edtaa3( data, gx, gy, width, height, xdist, ydist, inside );
85 for( i=0; i<width*height; ++i )
86 if( inside[i] < 0 )
87 inside[i] = 0.0;
88
89 // distmap = outside - inside; % Bipolar distance field
90 *vmax = 0.;
91 for( i=0; i<width*height; ++i)
92 {
93 outside[i] -= inside[i];
94 if( *vmax < fabs( outside[i] ) )
95 *vmax = fabs( outside[i] );
96 }
97
98 for( i=0; i<width*height; ++i)
99 {
100 double v = outside[i];
101 if ( v < -*vmax) outside[i] = -*vmax;
102 else if( v > +*vmax) outside[i] = +*vmax;
103 data[i] = (outside[i]+*vmax)/(2. * *vmax);
104 }
105
106 free( xdist );
107 free( ydist );
108 free( gx );
109 free( gy );
110 free( outside );
111 free( inside );
112 return data;
113}
114
127float*
128make_distance_mapbf( unsigned char *img,
129 unsigned int width, unsigned int height, double *vmax )
130{
131 double * data = (double *) calloc( width * height, sizeof(double) );
132 float *out = (float *) malloc( width * height * sizeof(float) );
133 unsigned int i;
134
135 // find minimum and maximum values
136 double img_min = DBL_MAX;
137 double img_max = DBL_MIN;
138
139 for( i=0; i<width*height; ++i)
140 {
141 double v = img[i];
142 data[i] = v;
143 if (v > img_max)
144 img_max = v;
145 if (v < img_min)
146 img_min = v;
147 }
148
149 // Map values from 0 - 255 to 0.0 - 1.0
150 for( i=0; i<width*height; ++i)
151 data[i] = (img[i]-img_min)/img_max;
152
153 data = make_distance_mapd(data, width, height, vmax);
154
155 // lower to float
156 for( i=0; i<width*height; ++i)
157 out[i] = (float)(1-data[i]);
158
159 free( data );
160
161 return out;
162}
float * make_distance_mapbf(unsigned char *img, unsigned int width, unsigned int height, double *vmax)
Perform a Euclidean Distance Transform on the input and normalize to [0,1], with a value of 0....
double * make_distance_mapd(double *data, unsigned int width, unsigned int height, double *vmax)
Like the original: perform a Euclidean Distance Transform on the input and normalize to [0,...