⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gfuntype.c

📁 完美的在线教育系统
💻 C
📖 第 1 页 / 共 3 页
字号:
 /* --- try both 8-bits/count and 4-bits/count for best compression --- */
 int	maxbitcount[2] = {254,14}; /* don't count too much in one byte */
 int	repeatcmds[2]  = {255,15}; /* opcode for repeat/duplicate count */
 int	minbytes = 0;		/* #bytes needed for smallest format */
 for ( iformat=2; iformat<=3; iformat++ ) { /* 2=8-bit packing, 3=4-bit */
  int	gfbitcount = 0,		/* count of consecutive gfbitval's */
	gfbitval = 0,		/* begin with count of leading 0's */
	pixcount = 0;		/* #packed bytes (#black/white flips) */
  unsigned char *gfcount = gfpixcount[iformat-2]; /*counts for this format*/
  if ( gformat!=0 && gformat!=iformat ) /* this format not allowed */
    continue;			/* so just skip it */
  for ( iscan=0; iscan<height; iscan++ ) /* for each integer in bitvec[] */
   {
   int	bitval = 0;		/* current actual pixel value */
   int	nrepeats=0, nextreps=0;	/* #duplicate lines below current,next line*/
   /* --- check for repeated/duplicate scan lines --- */
   if ( isrepeat		/* we're storing scan line repeat counts */
   &&   iscan < height-1 ) {	/* current scan line isn't the last line */
    /* --- count repeats --- */
    int jscan = iscan;		/* compare current scan with lines below it*/
    while ( ++jscan < height ) { /* until last scan line */
     if (nrepeats == jscan-iscan-1) /*no intervening non-identical lines*/
      if ( bitcmp(bitvec[iscan],bitvec[jscan],width) == 0 ) /* identical */
       nrepeats++;		/* so bump repeat count */
     if ( jscan > iscan+1 )	/* we're below next line */
      if (nextreps == jscan-iscan-2) /*no intervening non-identical lines*/
       if ( bitcmp(bitvec[iscan+1],bitvec[jscan],width) == 0 )/*identical*/
	nextreps++; }		/* so bump next lline repeat count */
    /* --- set repeat command and count --- */
    if ( nrepeats > 0 ) {	/* found repeated lines below current */
     int maxrepeats = maxbitcount[iformat-2]; /*max count/repeats per byte*/
     if ( nrepeats > maxrepeats ) nrepeats=maxrepeats; /* don't exceed max */
     {setbyfmt(iformat,gfcount,pixcount,repeatcmds[iformat-2]);} /*set cmd*/
     {setbyfmt(iformat,gfcount,pixcount+1,nrepeats);} /* set #repeats */
     pixcount += 2; }		/* don't bump pixcount within macros */
    } /* --- end-of-if(isrepeat) --- */
   /* --- set bit counts for current scan line --- */
   for ( ibit=0; ibit<width; ibit++ )	/* for all bits in this scanline */
    {
    bitval = getlongbit(bitvec[iscan],ibit); /* check actual pixel value */
    if ( bitval != gfbitval ) {	/* black-to-white edge (or vice versa) */
      {setbyfmt(iformat,gfcount,pixcount,gfbitcount);} /*set byte or nibble*/
      pixcount++;		/* don't bump pixcount within macro */
      gfbitcount = 0;		/* reset consecutive bit count */
      gfbitval = 1-gfbitval; }	/* flip bit to be counted */
    else			/* check count if continuing with same val */
     if ( gfbitcount >= maxbitcount[iformat-2] ) { /* max count per byte */
      {setbyfmt(iformat,gfcount,pixcount,gfbitcount);} /*set byte or nibble*/
      clearbyfmt(iformat,gfcount,pixcount+1); /*followed by dummy 0 count*/
      pixcount += 2;		/* don't bump pixcount within macros */
      gfbitcount = 0; }		/* reset consecutive bit count */
    if ( bitval == gfbitval )	/* same bit val as preceding, or first new */
      gfbitcount++;		/* so just count another pixel */
    } /* --- end-of-for(ibit) --- */
   /* --- adjust for repeated scan lines --- */
   iscan += nrepeats;		/* skip repeated/duplicate scan lines */
   if ( nrepeats>0 || nextreps>0 ) /* emit count to align on full scan */
    if ( iscan < height-1 )	/* have another scan line below this one */
     if ( gfbitcount > 0 ) {	/* should always have some final count */
      {setbyfmt(iformat,gfcount,pixcount,gfbitcount);} /*set byte or nibble*/
      pixcount++;		/* don't bump pixcount within macro */
      gfbitcount = 0;		/* reset consecutive bit count */
      if ( bitval == getlongbit(bitvec[iscan+1],0) ) { /* same bit value */
       clearbyfmt(iformat,gfcount,pixcount); /*so we need a dummy 0 count*/
       pixcount++; }		/* don't bump pixcount within macros */
      else			/* bitval flips at start of next line */
       gfbitval = 1-gfbitval;	/* so flip bit to be counted */
      } /* --- end-of-if(nrepeats...gfbitcount>0) --- */
   } /* --- end-of-for(iscan) --- */
   /* --- store final count --- */
   if ( gfbitcount > 0 ) {	/* have a final count */
     {setbyfmt(iformat,gfcount,pixcount,gfbitcount);} /*set byte or nibble*/
     pixcount++; }		/* don't bump pixcount within macro */
   else				/* ended exactly after maxbitcount? */
    if ( getbyfmt(iformat,gfcount,pixcount-1) == 0 )/*have dummy 0 trailer?*/
     pixcount--;		/* remove unneeded dummy trailer */
   /* --- save count to choose smallest --- */
   npixcounts[iformat-2] = pixcount; /* save count */
   } /* --- end-of-for(iformat) --- */
 /* --- check for optimal/smallest format --- */
 nbytes2=npixcounts[0];  nbytes3=(1+npixcounts[1])/2; /* #bytes for count */
 iformat = (nbytes2<nbytes3? 2:3); /* choose smallest format */
 minbytes = (iformat==2?nbytes2:nbytes3); /* #bytes for smallest format */
 if ( gformat == 0 )		/* bitmap representation also permitted */
  if ( nbytes1 <= minbytes )	/* and it's the optimal/smallest format */
   iformat = 1;			/* so flip format */
 /* --- move results to returned image --- */
 if ( iformat != 1 ) {		/* using a .gf format */
  if ( (image->pixmap = (unsigned char *)malloc(minbytes)) /* alloc pixmap */
  == NULL ) goto end_of_job;	/* quit if failed to allocate pixmap */
  memcpy(image->pixmap,gfpixcount[iformat-2],minbytes); /*copy local counts*/
  image->format = iformat;	/* signal byte counts or nibble counts */
  image->pixsz = npixcounts[iformat-2]; /*#counts in pixmap for gformat=2,3*/
  } /* --- end-of-if(iformat!=1) --- */
 } /* --- end-of-if(gformat==2) --- */
/* --------------------------------------------------------------------------
copy each integer in bitvec[] to raster pixmap, bit by bit
-------------------------------------------------------------------------- */
if ( iformat == 1 )		/* bit-by-bit representation of image */
 {
 int	ipixel = 0;		/* pixmap index */
 /* --- first allocate image raster pixmap for character --- */
 if ( (image->pixmap = (unsigned char *)malloc(pixmapsz(image)))
 == NULL ) goto end_of_job;	/* quit if failed to allocate pixmap */
 image->format = iformat;	/* reset format */
 /* --- now store bit image in allocated raster --- */
 for ( iscan=0; iscan<height; iscan++ )	/* for each integer in bitvec[] */
  for ( ibit=0; ibit<width; ibit++ )	/* for all bits in this scanline */
    {
    if ( getlongbit(bitvec[iscan],ibit) != 0 ) /* check current scan pixel */
      { setlongbit(image->pixmap,ipixel); }
    else				/*turn off corresponding raster bit*/
      { unsetlongbit(image->pixmap,ipixel); }
    ipixel++;				/* bump image raster pixel */
    } /* --- end-of-for(iscan,ibit) --- */
 } /* --- end-of-if(gformat==1) --- */
/* --------------------------------------------------------------------------
done
-------------------------------------------------------------------------- */
isokay = 1;				/* reset flag for success */
 end_of_job:
  return ( isokay );			/* back with 1=success, 0=failure */
} /* --- end-of-function rasterizechar() --- */


/* ==========================================================================
 * Function:	parsecorner ( line, row, col )
 * Purpose:	Parses a "pixel corner" line (upper left or lower left)
 *		and returns the (col,row) information on it as integers.
 * --------------------------------------------------------------------------
 * Arguments:	line (I)	char *  to input line containing
 *				".<--This pixel's..." to be parsed
 *		row (O)		int *  returning the (,row)
 *		col (O)		int *  returning the (col,)
 * Returns:	( int )		1 if successful, or 0 for any error
 * --------------------------------------------------------------------------
 * Notes:     o
 * ======================================================================= */
/* --- entry point --- */
int	parsecorner ( char *line, int *row, int *col )
{
/* --------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
int	isokay = 0;		/* success/fail flag, init for failure */
char	field[99], *delim;	/*(col,row) field and ptr to various delims*/
/* --------------------------------------------------------------------------
extract (col,row) field from line, and interpret col and row as integers
-------------------------------------------------------------------------- */
/* --- first, check beginning of line --- */
if ( line == (char *)NULL ) goto end_of_job; /* no line supplied by caller */
/* --- check for blank line --- */
if ( strstr(line,BLANKCHAR_STUB) != NULL ) /* got entirely blank character */
  return ( -999 );			/* so return special -999 signal */
/* --- check for corner --- */
if ( memcmp(line,CORNER_STUB,strlen(CORNER_STUB)) != 0 ) /*not valid corner*/
  goto end_of_job;			/* so quit */
/* --- extract  col,row  field from line --- */
if ( (delim=strchr(line,'(')) == NULL ) goto end_of_job; /*find open paren*/
strncpy(field,delim+1,10);		/* extract next 10 chars */
field[10] = '\000';			/* and null-terminate field */
if ( (delim=strchr(field,')')) == NULL ) goto end_of_job; /*find close paren*/
*delim = '\000';			/* terminate field at close paren */
/* --- interpret col,row as integers --- */
if ( (delim=strchr(field,',')) == NULL ) goto end_of_job; /* find comma */
*delim = '\000';			/* break field into col and row */
if ( col != (int *)NULL )		/* caller gave us ptr for col */
  *col = atoi(field);			/* so return it to him */
if ( row != (int *)NULL )		/* caller gave us ptr for row */
  *row = atoi(delim+1);			/* so return it to him */
/* --------------------------------------------------------------------------
done
-------------------------------------------------------------------------- */
isokay = 1;				/* reset flag for success */
 end_of_job:
  return ( isokay );			/* back with success/fail flag */
} /* --- end-of-function parsecorner() --- */


/* ==========================================================================
 * Function:	readaline ( fp )
 * Purpose:	Reads a line from fp, strips terminating newline,
 *		and returns ptr to internal buffer
 * --------------------------------------------------------------------------
 * Arguments:	fp (I)		FILE *  to input file to be read.
 *				If null, returns line previously read.
 * Returns:	( char * )	internal buffer containing line read,
 *				or NULL for eof or error.
 * --------------------------------------------------------------------------
 * Notes:     o	fp is left on the line following the returned line
 * ======================================================================= */
/* --- entry point --- */
char	*readaline ( FILE *fp )
{
/* --------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
static	char buffer[2048];	/* static buffer returned to caller */
char	*fgets(), *bufptr=buffer; /* read line from fp */
char	*strchr(), *delim;	/* remove terminating newline */
/* --------------------------------------------------------------------------
Read line and strip trailing newline
-------------------------------------------------------------------------- */
if ( fp != NULL )			/*if null, return previous line read*/
  if ( (bufptr=fgets(buffer,2047,fp))	/* read next line from fp */
  != NULL )				/* and check that we succeeded */
    {
    if ( (delim=strchr(bufptr,'\n'))	/* look for terminating newline */
    != NULL )				/* and check that we found it */
      *delim = '\000';			/* truncate line at newline */
    } /* --- end-of-if(fgets()!=NULL) --- */
return ( bufptr );			/*back to caller with buffer or null*/
} /* --- end-of-function readaline() --- */


/* ==========================================================================
 * Function:	bitcmp ( bs1, bs2, n )
 * Purpose:	compares the first n bits of two strings
 * --------------------------------------------------------------------------
 * Arguments:	bs1 (I)		unsigned char * to first bit string
 *		bs2 (I)		unsigned char * to second bit string
 *		n (I)		int containing #bits to compare
 * Returns:	( int )		0 if first n bits are identical
 *				-1 if first unmatching bit of bs1 is 0
 *				+1 if first unmatching bit of bs2 id 0
 * --------------------------------------------------------------------------
 * Notes:     o
 * ======================================================================= */
/* --- entry point --- */
int	bitcmp ( unsigned char *bs1, unsigned char *bs2, int n )
{
/* --------------------------------------------------------------------------
Allocations and Declarations
-------------------------------------------------------------------------- */
int	icmp = 0;		/* returned to caller */
int	nbytes = n/8,		/* #full bytes we can compare with memcmp()*/
	nbits  = n%8,  ibit=0;	/* #trailing bits in last byte, index */
/* --------------------------------------------------------------------------
compare leading bytes, then trailing bits
-------------------------------------------------------------------------- */
if ( nbytes > 0 ) icmp = memcmp(bs1,bs2,nbytes); /* compare leading bytes */
if ( icmp == 0 )		/* leading bytes identical */
 if ( nbits > 0 )		/* and we have trailing bits */
  for ( ibit=0; ibit<nbits; ibit++ ) /* check each bit */
   { icmp = (int)get1bit(bs1[nbytes],ibit) - (int)get1bit(bs2[nbytes],ibit);
     if ( icmp != 0 ) break; }	/* done at first unmatched bit */
return ( icmp );		/* back to caller with -1,0,+1 */
} /* --- end-of-function bitcmp() --- */
/* --- end-of-file gfuntype.c --- */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -