forked from rougier/freetype-gl
-
Notifications
You must be signed in to change notification settings - Fork 1
/
distance-field.c
105 lines (89 loc) · 3.04 KB
/
distance-field.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/* Freetype GL - A C OpenGL Freetype engine
*
* Distributed under the OSI-approved BSD 2-Clause License. See accompanying
* file `LICENSE` for more details.
*/
#include <math.h>
#include <float.h>
#include <stdlib.h>
#include <string.h>
#include "edtaa3func.h"
double *
make_distance_mapd( double *data, unsigned int width, unsigned int height )
{
short * xdist = (short *) malloc( width * height * sizeof(short) );
short * ydist = (short *) malloc( width * height * sizeof(short) );
double * gx = (double *) calloc( width * height, sizeof(double) );
double * gy = (double *) calloc( width * height, sizeof(double) );
double * outside = (double *) calloc( width * height, sizeof(double) );
double * inside = (double *) calloc( width * height, sizeof(double) );
double vmin = DBL_MAX;
unsigned int i;
// Compute outside = edtaa3(bitmap); % Transform background (0's)
computegradient( data, width, height, gx, gy);
edtaa3(data, gx, gy, width, height, xdist, ydist, outside);
for( i=0; i<width*height; ++i)
if( outside[i] < 0.0 )
outside[i] = 0.0;
// Compute inside = edtaa3(1-bitmap); % Transform foreground (1's)
memset( gx, 0, sizeof(double)*width*height );
memset( gy, 0, sizeof(double)*width*height );
for( i=0; i<width*height; ++i)
data[i] = 1 - data[i];
computegradient( data, width, height, gx, gy );
edtaa3( data, gx, gy, width, height, xdist, ydist, inside );
for( i=0; i<width*height; ++i )
if( inside[i] < 0 )
inside[i] = 0.0;
// distmap = outside - inside; % Bipolar distance field
for( i=0; i<width*height; ++i)
{
outside[i] -= inside[i];
if( outside[i] < vmin )
vmin = outside[i];
}
vmin = fabs(vmin);
for( i=0; i<width*height; ++i)
{
double v = outside[i];
if ( v < -vmin) outside[i] = -vmin;
else if( v > +vmin) outside[i] = +vmin;
data[i] = (outside[i]+vmin)/(2*vmin);
}
free( xdist );
free( ydist );
free( gx );
free( gy );
free( outside );
free( inside );
return data;
}
unsigned char *
make_distance_mapb( unsigned char *img,
unsigned int width, unsigned int height )
{
double * data = (double *) calloc( width * height, sizeof(double) );
unsigned char *out = (unsigned char *) malloc( width * height * sizeof(unsigned char) );
unsigned int i;
// find minimimum and maximum values
double img_min = DBL_MAX;
double img_max = DBL_MIN;
for( i=0; i<width*height; ++i)
{
double v = img[i];
data[i] = v;
if (v > img_max)
img_max = v;
if (v < img_min)
img_min = v;
}
// Map values from 0 - 255 to 0.0 - 1.0
for( i=0; i<width*height; ++i)
data[i] = (img[i]-img_min)/img_max;
data = make_distance_mapd(data, width, height);
// map values from 0.0 - 1.0 to 0 - 255
for( i=0; i<width*height; ++i)
out[i] = (unsigned char)(255*(1-data[i]));
free( data );
return out;
}