
      digit = (int)(dblval - 10.0*dbldigit + 0.01); /* least signif digit */
      if ( digit<0 || digit>9 ) digit=10; /* index check */
      digits[ndigits++] = digittbl[digit]; /* store ascii digit */
      dblval = dbldigit; }		/* ready for next digit */
if ( ndigits < 1 ) digits[ndigits++] = '0'; /* store a single '0' for 0.0 */
/* -------------------------------------------------------------------------
Format whole part from digits[] array
------------------------------------------------------------------------- */
if ( isneg ) *finptr++ = '(';		/* leading paren for negative value*/
for ( digit=ndigits-1; digit>=0; digit-- ) /* start with most significant */
    { *finptr++ = digits[digit];	/* store digit */
      if ( digit>0 && digit%3==0 )	/* need a comma */
	*finptr++ = ','; }		/* put in separating comma */
/* -------------------------------------------------------------------------
Format fractional part using ifrac
------------------------------------------------------------------------- */
if ( npts > 0 )
    { *finptr++ = '.';			/* start with decimal point */
      sprintf(finptr,"%0*d",npts,ifrac); /* convert to string */
      finptr += npts; }			/* bump ptr past fractional digits */
/* -------------------------------------------------------------------------
End-of-Job
------------------------------------------------------------------------- */
if ( isneg ) *finptr++ = ')';		/*trailing paren for negative value*/
*finptr = '\000';			/* null-terminate converted double */
return ( finval );			/* converted double back to caller */
} /* --- end-of-function dtoa() --- */


/* ==========================================================================
 * Function:	aalowpass ( rp, bytemap, grayscale )
 * Purpose:	calculates a lowpass anti-aliased bytemap
 *		for rp->bitmap, with each byte 0...grayscale-1
 * --------------------------------------------------------------------------
 * Arguments:	rp (I)		raster *  to raster whose bitmap
 *				is to be anti-aliased
 *		bytemap (O)	intbyte * to bytemap, calculated
 *				by applying lowpass filter to rp->bitmap,
 *				and returned (as you'd expect) in 1-to-1
 *				addressing correspondence with rp->bitmap
 *		grayscale (I)	int containing number of grayscales
 *				to be calculated, 0...grayscale-1
 *				(should typically be given as 256)
 * --------------------------------------------------------------------------
 * Returns:	( int )		1=success, 0=any error
 * --------------------------------------------------------------------------
 * Notes:     o	If the center point of the box being averaged is black,
 *		then the entire "average" is forced black (grayscale-1)
 *		regardless of the surrounding points.  This is my attempt
 *		to avoid a "washed-out" appearance of thin (one-pixel-wide)
 *		lines, which would otherwise turn from black to a gray shade.
 *	     o	Also, while the weights for neighbor points are fixed,
 *		you may adjust the center point weight on the compile line.
 *		A higher weight sharpens the resulting anti-aliased image;
 *		lower weights blur it out more (but keep the "center" black
 *		as per the preceding note).
 * ======================================================================= */
/* --- entry point --- */
int	aalowpass (raster *rp, intbyte *bytemap, int grayscale)
{
/* -------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
int	status = 1;			/* 1=success, 0=failure to caller */
pixbyte	*bitmap= (rp==NULL?NULL:rp->pixmap); /*local rp->pixmap ptr*/
int	irow=0, icol=0;			/* rp->height, rp->width indexes */
int	weights[9] = { 1,3,1, 3,0,3, 1,3,1 }; /* matrix of weights */
int	adjindex[9]= { 0,1,2, 7,-1,3, 6,5,4 }; /*clockwise from upper-left*/
int	totwts = 0;			/* sum of all weights in matrix */
int	isforceavg = 1,			/*force avg black if center black?*/
	isminmaxwts = 1,		/*use wts or #pts for min/max test */
	blackscale = 0; /*(grayscale+1)/4;*/ /*force black if wgted avg>bs */
/* -------------------------------------------------------------------------
Initialization
-------------------------------------------------------------------------- */
/* --- calculate total weights --- */
weights[4]= centerwt;			/* weight for center point */
weights[1]= weights[3]= weights[5]= weights[7]= adjacentwt; /*adjacent pts*/
totwts = centerwt + 4*(1+adjacentwt);	/* tot is center plus neighbors */
/* -------------------------------------------------------------------------
Calculate bytemap as 9-point weighted average over bitmap
-------------------------------------------------------------------------- */
for ( irow=0; irow<rp->height; irow++ )
 for ( icol=0; icol<rp->width; icol++ )
  {
  int	ipixel = icol + irow*(rp->width); /* center pixel index */
  int	jrow=0, jcol=0,			/* box around ipixel */
	bitval = 0,			/* value of bit/pixel at jrow,jcol */
	iscenter = 0,			/* set true if center pixel black */
	nadjacent=0, wadjacent=0,	/* #adjacent black pixels, their wts*/
	ngaps = 0,			/* #gaps in 8 pixels around center */
	iwt=(-1), sumwts=0;		/* weights index, sum in-bound wts */
  char	adjmatrix[8];			/* adjacency "matrix" */
  memset(adjmatrix,0,8);		/* zero out adjacency matrix */
  bytemap[ipixel] = 0;			/* init pixel white */
  /*--- for ipixel at irow,icol, get weighted average of adjacent pixels ---*/
  for ( jrow=irow-1; jrow<=irow+1; jrow++ )  /* jrow = irow-1...irow+1 */
   for ( jcol=icol-1; jcol<=icol+1; jcol++ ) /* jcol = icol-1...icol+1 */
    {
    int	jpixel = jcol + jrow*(rp->width); /* averaging index */
    iwt++;				/*always bump weight index*/
    if ( jrow<0 || jrow>=rp->height	/* if row out pf bounds */
    ||   jcol<0 || jcol>=rp->width )	/* or col out of bounds */
	continue;			/* ignore this point */
    bitval = (int)getlongbit(bitmap,jpixel); /* value of bit at jrow,jcol */
    if ( bitval )			/* this is a black pixel */
      {	if ( jrow==irow && jcol==icol )	/* and this is center point */
	  iscenter = 1;			/* set flag for center point black */
	else				/* adjacent point black */
	  { nadjacent++;		/* bump adjacent black count */
	    adjmatrix[adjindex[iwt]] = 1; } /*set "bit" in adjacency matrix*/
	wadjacent += weights[iwt]; }	/* sum weights for black pixels */
    sumwts += weights[iwt];		/* and sum weights for all pixels */
    } /* --- end-of-for(jrow,jcol) --- */
  /* --- count gaps --- */
  ngaps = (adjmatrix[7]!=adjmatrix[0]?1:0); /* init count */
  for ( iwt=0; iwt<7; iwt++ )		/* clockwise around adjacency */
    if ( adjmatrix[iwt]!= adjmatrix[iwt+1] ) ngaps++; /* black/white flip */
  ngaps /= 2;				/*each gap has 2 black/white flips*/
  /* --- anti-alias pixel, but leave it black if it was already black --- */
  if ( isforceavg && iscenter )		/* force avg if center point black */
      bytemap[ipixel] = grayscale-1;	/* so force grayscale-1=black */
  else