// ------------------------------------------------------ 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 );
}
Example #2
0
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;
}
Example #4
0
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);
}
Example #5
0
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 );
}
Example #6
0
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));
		}
	}
}