naev 0.12.5
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
39
41#include <float.h>
42#include <math.h>
43#include <stdlib.h>
44#include <string.h>
46
47#include "edtaa3func.h"
48
60double *make_distance_mapd( double *data, unsigned int width,
61 unsigned int height, double *vmax )
62{
63 unsigned int wh = width * height;
64 short *xdist = (short *)malloc( wh * sizeof( short ) );
65 short *ydist = (short *)malloc( wh * sizeof( short ) );
66 double *gx = (double *)calloc( wh, sizeof( double ) );
67 double *gy = (double *)calloc( wh, sizeof( double ) );
68 double *outside = (double *)calloc( wh, sizeof( double ) );
69 double *inside = (double *)calloc( wh, sizeof( double ) );
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 ( unsigned int i = 0; i < wh; 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 ( unsigned int i = 0; i < wh; 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 ( unsigned int i = 0; i < wh; i++ )
86 if ( inside[i] < 0. )
87 inside[i] = 0.;
88
89 // distmap = outside - inside; % Bipolar distance field
90 *vmax = 0.;
91 for ( unsigned int i = 0; i < wh; i++ ) {
92 outside[i] -= inside[i];
93 if ( *vmax < fabs( outside[i] ) )
94 *vmax = fabs( outside[i] );
95 }
96
97 for ( unsigned int i = 0; i < wh; i++ ) {
98 double v = outside[i];
99 if ( v < -*vmax )
100 outside[i] = -*vmax;
101 else if ( v > +*vmax )
102 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 *make_distance_mapbf( unsigned char *img, unsigned int width,
128 unsigned int height, double *vmax )
129{
130 unsigned int wh = width * height;
131 double *data = (double *)calloc( wh, sizeof( double ) );
132 float *out = (float *)malloc( wh * sizeof( float ) );
133
134 // find minimum and maximum values
135 double img_min = DBL_MAX;
136 double img_max = DBL_MIN;
137
138 for ( unsigned int i = 0; i < wh; i++ ) {
139 double v = img[i];
140 if ( v > img_max )
141 img_max = v;
142 if ( v < img_min )
143 img_min = v;
144 }
145
146 // Map values from 0 - 255 to 0.0 - 1.0
147 for ( unsigned int i = 0; i < wh; i++ )
148 data[i] = ( img[i] - img_min ) / img_max;
149
150 data = make_distance_mapd( data, width, height, vmax );
151
152 // lower to float
153 for ( unsigned int i = 0; i < wh; i++ )
154 out[i] = (float)( 1 - data[i] );
155
156 free( data );
157
158 return out;
159}
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,...