void edtaa3(double* _img, uint16_t _width, uint16_t _height, double* _out) { uint32_t size = _width*_height; short* xdist = (short*)malloc(size*sizeof(short) ); short* ydist = (short*)malloc(size*sizeof(short) ); double* gx = (double*)malloc(size*sizeof(double) ); double* gy = (double*)malloc(size*sizeof(double) ); computegradient(_img, _width, _height, gx, gy); edtaa3(_img, gx, gy, _width, _height, xdist, ydist, _out); for (uint32_t ii = 0; ii < size; ++ii) { if (_out[ii] < 0.0) { _out[ii] = 0.0; } } free(xdist); free(ydist); free(gx); free(gy); }
// ------------------------------------------------------ make_distance_map --- void distance_map( 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) ); 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 float vmin = +INFINITY; for( i=0; i<width*height; ++i) { outside[i] -= inside[i]; if( outside[i] < vmin ) { vmin = outside[i]; } } vmin = abs(vmin); for( i=0; i<width*height; ++i) { float 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 ); }
static void makeDistanceMap(const uint8_t* _img, uint8_t* _outImg, uint32_t _width, uint32_t _height) { #if USE_EDTAA3 int16_t* xdist = (int16_t*)malloc(_width * _height * sizeof(int16_t) ); int16_t* ydist = (int16_t*)malloc(_width * _height * sizeof(int16_t) ); double* gx = (double*)calloc(_width * _height, sizeof(double) ); double* gy = (double*)calloc(_width * _height, sizeof(double) ); double* data = (double*)calloc(_width * _height, sizeof(double) ); double* outside = (double*)calloc(_width * _height, sizeof(double) ); double* inside = (double*)calloc(_width * _height, sizeof(double) ); uint32_t ii; // Convert img into double (data) double img_min = 255, img_max = -255; for (ii = 0; ii < _width * _height; ++ii) { double v = _img[ii]; data[ii] = v; if (v > img_max) { img_max = v; } if (v < img_min) { img_min = v; } } // Rescale image levels between 0 and 1 for (ii = 0; ii < _width * _height; ++ii) { data[ii] = (_img[ii] - img_min) / (img_max - img_min); } // Compute outside = edtaa3(bitmap); % Transform background (0's) computegradient(data, _width, _height, gx, gy); edtaa3(data, gx, gy, _width, _height, xdist, ydist, outside); for (ii = 0; ii < _width * _height; ++ii) { if (outside[ii] < 0) { outside[ii] = 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 (ii = 0; ii < _width * _height; ++ii) { data[ii] = 1.0 - data[ii]; } computegradient(data, _width, _height, gx, gy); edtaa3(data, gx, gy, _width, _height, xdist, ydist, inside); for (ii = 0; ii < _width * _height; ++ii) { if (inside[ii] < 0) { inside[ii] = 0.0; } } // distmap = outside - inside; % Bipolar distance field uint8_t* out = _outImg; for (ii = 0; ii < _width * _height; ++ii) { outside[ii] -= inside[ii]; outside[ii] = 128 + outside[ii] * 16; if (outside[ii] < 0) { outside[ii] = 0; } if (outside[ii] > 255) { outside[ii] = 255; } out[ii] = 255 - (uint8_t) outside[ii]; } free(xdist); free(ydist); free(gx); free(gy); free(data); free(outside); free(inside); #else sdfBuild(_outImg, _width, 8.0f, _img, _width, _height, _width); #endif // USE_EDTAA3 }
// ------------------------------------------------------ make_distance_map --- unsigned char * make_distance_map( unsigned char *img, 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 * data = (double *) calloc( width * height, sizeof(double) ); double * outside = (double *) calloc( width * height, sizeof(double) ); double * inside = (double *) calloc( width * height, sizeof(double) ); int i; // Convert img into double (data) double img_min = 255, img_max = -255; 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; } // Rescale image levels between 0 and 1 for( i=0; i<width*height; ++i) { data[i] = (img[i]-img_min)/img_max; } // Compute outside = edtaa3(bitmap); % Transform background (0's) computegradient( data, height, width, gx, gy); edtaa3(data, gx, gy, height, width, xdist, ydist, outside); for( i=0; i<width*height; ++i) if( outside[i] < 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, height, width, gx, gy); edtaa3(data, gx, gy, height, width, xdist, ydist, inside); for( i=0; i<width*height; ++i) if( inside[i] < 0 ) inside[i] = 0.0; // distmap = outside - inside; % Bipolar distance field unsigned char *out = (unsigned char *) malloc( width * height * sizeof(unsigned char) ); for( i=0; i<width*height; ++i) { outside[i] -= inside[i]; outside[i] = 128+outside[i]*16; if( outside[i] < 0 ) outside[i] = 0; if( outside[i] > 255 ) outside[i] = 255; out[i] = 255 - (unsigned char) outside[i]; //out[i] = (unsigned char) outside[i]; } free( xdist ); free( ydist ); free( gx ); free( gy ); free( data ); free( outside ); free( inside ); return out; }
void Distmap::generate(Texture const &other) { if (other.getWidth() != _width || other.getHeight() != _height) throw std::runtime_error( "Distmap cannot be generated from a different size texture."); 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 *data = (double *)calloc(_width * _height, sizeof(double)); double *outside = (double *)calloc(_width * _height, sizeof(double)); double *inside = (double *)calloc(_width * _height, sizeof(double)); size_t i; if (!xdist || !ydist || !gx || !gy || !data || !outside || !inside) throw std::runtime_error("Cannot generated distmap, size is too big."); // Convert img into double (data) unsigned char *img = other.getData(); double img_min = 255; double img_max = -255; 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; } // Rescale image levels between 0 and 1 for (i = 0; i < _width * _height; ++i) { data[i] = (img[i]-img_min)/img_max; } // Compute outside = edtaa3(bitmap); % Transform background (0's) computegradient(data, _width, _height, gx, gy); edtaa3(data, gx, gy, _height, _width, xdist, ydist, outside); for (i = 0; i < _width * _height; ++i) if (outside[i] < 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, _height, _width, 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]; outside[i] = 128+outside[i]*16; if (outside[i] < 0) outside[i] = 0; if (outside[i] > 255) outside[i] = 255; _data[i] = 255 - (unsigned char) outside[i]; _data[i + 1] = 255 - (unsigned char) outside[i]; _data[i + 2] = 255 - (unsigned char) outside[i]; _data[i + 3] = 255 - (unsigned char) outside[i]; } free(xdist); free(ydist); free(gx); free(gy); free(data); free(outside); free(inside); }
void _compute_sdf( 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) ); unsigned int i; double vmin, vmax, v; // Compute outside = edtaa3(bitmap); % Transform background (0's) computegradient( data, height, width, 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, height, width, 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 vmin = outside[0]; vmax = outside[0]; for( i=0; i<width*height; ++i) { outside[i] -= inside[i]; if( outside[i] < vmin ) { vmin = outside[i]; } else if( outside[i] > vmax ){ vmax = outside[i]; } } vmax = -vmin; for( i=0; i<width*height; ++i) { v = outside[i]; if ( v < vmin) outside[i] = vmin; else if( v > vmax) outside[i] = vmax; //data[i] = (outside[i]+vmin)/(2*vmin); data[i] = (outside[i]-vmin) / (vmax-vmin); } free( xdist ); free( ydist ); free( gx ); free( gy ); free( outside ); free( inside ); }
void ewol::resource::DistanceFieldFont::generateDistanceField(const egami::ImageMono& _input, egami::Image& _output) { std11::unique_lock<std11::recursive_mutex> lock(m_mutex); int32_t size = _input.getSize().x() * _input.getSize().y(); std::vector<short> xdist(size); std::vector<short> ydist(size); std::vector<double> gx(size); std::vector<double> gy(size); std::vector<double> data(size); std::vector<double> outside(size); std::vector<double> inside(size); // Convert img into double (data) double img_min = 255, img_max = -255; for (int32_t yyy = 0; yyy < _input.getSize().y(); ++yyy) { for (int32_t xxx = 0; xxx < _input.getSize().x(); ++xxx) { int32_t iii = yyy * _input.getSize().x() + xxx; double v = _input.get(ivec2(xxx, yyy)); data[iii] = v; if (v > img_max) { img_max = v; } if (v < img_min) { img_min = v; } } } // Rescale image levels between 0 and 1 for (int32_t yyy = 0; yyy < _input.getSize().y(); ++yyy) { for (int32_t xxx = 0; xxx < _input.getSize().x(); ++xxx) { int32_t iii = yyy * _input.getSize().x() + xxx; data[iii] = (_input.get(ivec2(xxx, yyy))-img_min)/img_max; } } // Compute outside = edtaa3(bitmap); % Transform background (0's) computegradient(&data[0], _input.getSize().x(), _input.getSize().y(), &gx[0], &gy[0]); edtaa3(&data[0], &gx[0], &gy[0], _input.getSize().x(), _input.getSize().y(), &xdist[0], &ydist[0], &outside[0]); for(size_t iii = 0; iii < outside.size(); ++iii) { if( outside[iii] < 0 ) { outside[iii] = 0.0; } } // Compute inside = edtaa3(1-bitmap); % Transform foreground (1's) for(size_t iii = 0; iii < gx.size(); ++iii) { gx[iii] = 0; } for(size_t iii = 0; iii < gy.size(); ++iii) { gy[iii] = 0; } for(size_t iii = 0; iii < data.size(); ++iii) { data[iii] = 1 - data[iii]; } computegradient( &data[0], _input.getSize().x(), _input.getSize().y(), &gx[0], &gy[0]); edtaa3(&data[0], &gx[0], &gy[0], _input.getSize().x(), _input.getSize().y(), &xdist[0], &ydist[0], &inside[0]); for(size_t iii = 0; iii < inside.size(); ++iii) { if( inside[iii] < 0 ) { inside[iii] = 0.0; } } _output.resize(_input.getSize(), etk::Color<>(0)); _output.clear(etk::Color<>(0)); for (int32_t xxx = 0; xxx < _output.getSize().x(); ++xxx) { for (int32_t yyy = 0; yyy < _output.getSize().y(); ++yyy) { int32_t iii = yyy * _output.getSize().x() + xxx; outside[iii] -= inside[iii]; outside[iii] = 128+outside[iii]*16; if( outside[iii] < 0 ) { outside[iii] = 0; } if( outside[iii] > 255 ) { outside[iii] = 255; } uint8_t val = 255 - (unsigned char) outside[iii]; // TODO : Remove multiple size of the map ... _output.set(ivec2(xxx, yyy), etk::Color<>((int32_t)val,(int32_t)val,(int32_t)val,255)); } } }