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

📄 efaxlib.c.orig

📁 用于使用moden进行传真的源代码
💻 ORIG
📖 第 1 页 / 共 5 页
字号:
/* 	      efaxlib.c - utility routines for efax		     Copyright 1995 Ed Casas*/#include <ctype.h>#include <stdio.h>#include <string.h>#include "efaxmsg.h"#include "efaxlib.h"#ifndef SEEK_SET#define SEEK_SET 0#endif#define DEFXRES 204.145		/* fax x and y resolution in dpi */#define DEFYRES 195.58#define DEFWIDTH  1728		/* 215x297 mm image at fax resolution */#define DEFHEIGHT 2287extern t4tab wtab [ ( 64 + 27 + 13 ) + 1 ] ; /* T.4 coding tables */extern t4tab btab [ ( 64 + 27 + 13 ) + 1 ] ;short short256 = 256 ;		/* for endian-ness detection *//* Make sure printf strings have only %d escapes and n or fewer   of them.  Returns 0 if OK, 1 on error. */int ckfmt ( char *p, int n ){  for ( ; *p ; p++ ) {    if ( p[0] == '%' ) {      if ( p[1] == 'd' ) n-- ;      else if ( p[1] == '%' ) p++ ;      else n=-1 ;    }  }    return n < 0 ;}/* Initialize state of variable-length code word encoder. */void newENCODER ( ENCODER *e ){  e->x = 0 ;  e->shift = -8 ;}/* Store a code word `code' of length `bits' (<=24) in buffer pointed to by   `buf'.  Bits that don't fit in complete bytes are saved between calls.   To flush the remaining bits call the function with code=0 and bits=0.   Returns pointer to next free element in output buffer.  Calling function   must ensure at least bits/8 bytes are available in buffer.  */uchar *putcode ( ENCODER *e, short code, short bits, uchar *buf ){  e->x = ( e->x << bits ) | code ;  e->shift += bits ? bits : -e->shift ;  while ( e->shift >= 0 ) {    *buf++ = e->x >> e->shift ;    e->shift -= 8 ;  }  return buf ;}/* Convert run lengths to 1-D T.4-codes.  First run is white.  Silently   truncates run lengths that are too long. After using this function EOLs   may need to be added and/or the putcode() buffer flushed.  Returns   pointer to next free element in output buffer. */uchar *runtocode ( ENCODER *e, short *runs, int nr, uchar *codes ){  uchar col = 0, *maxcodes = codes + MAXCODES ;  t4tab *ctab = wtab, *p ;  short rlen ;  long x ;  short shift ;#define PUTCODE(p) { x = ( x << p->bits ) | p->code ;  shift += p->bits ; \	while ( shift >= 0 ) { *codes++ = x >> shift ; shift -= 8 ; } }  x = e->x ; shift = e->shift ;  while ( nr-- > 0 ) {    rlen = *runs++ ;    if ( rlen > 63 ) {				/* make-up code */      if ( rlen > MAXRUNLEN ) rlen = MAXRUNLEN ;      p = ctab + 63 + ( rlen >> 6 ) ;      if ( codes < maxcodes ) PUTCODE(p) ;    }    p = ctab + ( rlen & 0x3f ) ;		/* terminating code */    if ( codes < maxcodes ) PUTCODE(p) ;    ctab = ( col ^= 1 ) ? btab : wtab ;  }      e->x = x ; e->shift = shift ;  return codes ;}/* Pad/truncate run-length coded scan line 'runs' of 'nr' runs by 'pad'   pixels (truncate if negative).  Returns the new number of runs. */int xpad ( short *runs, int nr, int pad ){  if ( pad < 0 ) {		          /* truncate */    while ( pad < 0 ) pad += ( nr <= 0 ? -pad : runs [ --nr ] ) ;    runs [ nr++ ] = pad ;  } else {				  /* pad with white */    if ( nr & 1 ) runs [ nr - 1 ] += pad ;    else runs [ nr++ ] = pad ;  }  return nr ;}/* Shift a run-length coded scan line right by s pixels (left if negative).   If necessary, zero-length runs are created to avoid copying.  Returns   the pixel width change (+/-). */int xshift ( short *runs, int nr, int s ){  int i=0, n=0 ;  if ( s < 0 ) {    for ( i = 0 ; s < 0 && i < nr ; i++ ) {       s += runs [ i ] ;      n -= runs [ i ] ;      runs [ i ] = 0 ;     }    i-- ;  }  if ( i < nr ) {    runs [ i ] += s ;    n += s ;  }  return n ;}/* Scale nr run lengths in buffer pointed to by p to scale image   horizontally.  The scaling factor is xs/256. Returns new line width in   pixels. */int xscale ( short *p, int nr, int xs ){  int inlen=0, outlen=0 ;  for ( ; nr-- > 0 ; p++ ) {    inlen += *p ;    *p = ( ( inlen * xs + 128 ) >> 8 ) - outlen ;    outlen += *p ;  }  return outlen ;}/* Invert a run-length buffer by prepending or removing a   zero-length initial run. */int xinvert ( short *p, int nr ){  int i ;  if ( ! *p ) {    for ( i=0 ; i<nr-1 ; i++ ) { /* remove */      p[i] = p[i+1] ;    }    nr-- ;  } else {    for ( i=nr ; i>0 ; i-- ) {	/* insert */      p[i] = p[i-1] ;    }    p[0] = 0 ;    nr++ ;  }  return nr ;}/* Zero-terminated lists of run lengths for each byte. */uchar byteruns [ 1408 + 1 ] =    "8071061106205120511105210530413041210411110411204220421104310440"   "3140313103121103122031112031111103112103113032303221032111032120"   "3320331103410350215021410213110213202121202121110212210212302111"   "3021112102111111021111202112202112110211310211402240223102221102"   "2220221120221111022121022130233023210231110231202420241102510260"   "1160115101141101142011312011311101132101133011213011212101121111"   "0112112011222011221101123101124011114011113101111211011112201111"   "1120111111110111112101111130111230111221011121110111212011132011"   "1311011141011150125012410123110123201221201221110122210122301211"   "3012112101211111012111201212201212110121310121401340133101321101"   "3220131120131111013121013130143014210141110141201520151101610170"   "1701610151101520141201411101421014301313013121013111101311201322"   "0132110133101340121401213101212110121220121112012111110121121012"   "1130122301222101221110122120123201231101241012501115011141011131"   "1011132011121201112111011122101112301111130111112101111111101111"   "1120111122011112110111131011114011240112310112211011222011211201"   "1211110112121011213011330113210113111011312011420114110115101160"   "2602510241102420231202311102321023302213022121022111102211202222"   "0222110223102240211402113102112110211220211112021111110211121021"   "1130212302122102121110212120213202131102141021503503410331103320"   "3212032111032210323031130311210311111031112031220312110313103140"   "4404310421104220411204111104121041305305210511105120620611071080" ;/* Convert byte-aligned bit-mapped n-byte scan line into array of run   lengths.  Run length array must have *more* than 8*n elements.  First   run is white.  Returns number of runs coded.  */int bittorun ( uchar *bits, int n, short *runs ){  static uchar init=0, *rltab [ 256 ] ;  register uchar *p, c, lastc = 0x00 ;  short *runs0 = runs ;  if ( ! init ) {		/* initialize pointer and run tables */    int i = 0 ;    for ( rltab[ 0 ] = p = byteruns ; *p ; p++ )      if ( ! ( *p -= '0' ) && i < 255 ) 	rltab [ ++i ] = p+1 ;    init = 1 ;  }  *runs = 0 ;  for ( ; n > 0 ; n-- ) {    p = rltab [ c = *bits++ ] ;    if ( ( lastc & 0x01 ) ? ! ( c & 0x80 ) : ( c & 0x80 ) )      *(++runs) = *p++ ;		  /* new run */    else 			        *runs += *p++ ;			  /* continue run */    while ( *p )       *(++runs) = *p++ ;    lastc = c ;  }  return runs - runs0 + 1  ;}/* Bitwise-OR two run-length coded scan lines.  The run length   vectors a and b are OR-ed into c.  If c is null, the result is   placed in a.  The new image width is stored in pels if it is   not null.  Returns the number of runs in the result.  */int runor ( short *a, int na, short *b, int nb, short *c, int *pels ){  register short la, lb ;  int ia, ib, ic, np=0 ;  short tmp [ MAXRUNS ] ;  if ( ! c ) c = tmp ;  la = a [ ia = 0 ] ;  lb = b [ ib = 0 ] ;  c [ ic = 0 ] = 0 ;  while ( 1 ) {    if ( la <= lb ) {			  /* select shorter sub-run */      if ( ( ( ia | ib ) ^ ic ) & 1 )	  /* OR of subruns same colour as c? */	c [ ++ic ] = la ;		  /* no, new output run */      else 	c [ ic ] += la ;		  /* yes, add it */      lb -= la ;			  /* align subruns */      if ( ++ia >= na ) break ;		  /* done */      la = a [ ia ] ;			  /* get new subrun */    } else {				  /* same for line b ... */      if ( ( ( ia | ib ) ^ ic ) & 1 ) 	c [ ++ic ] = lb ;      else 	c [ ic ] += lb ;      la -= lb ;      if ( ++ib >= nb ) break ;      lb = b [ ib ] ;    }  }  if ( ia < na )    while ( 1 ) {      if ( ( ia ^ ic ) & 1 )	  	c [ ++ic ] = la ;		        else 	c [ ic ] += la ;		        if ( ++ia >= na ) break ;		        la = a [ ia ] ;			      }   else    while ( 1 ) {      if ( ( ib ^ ic ) & 1 ) 	c [ ++ic ] = lb ;      else 	c [ ic ] += lb ;      if ( ++ib >= nb ) break ;      lb = b [ ib ] ;    }  if ( c == tmp ) for ( ia=0 ; ia <= ic ; ia++ ) np += a[ia] = c[ia] ;  if ( pels ) *pels = np ;  return ic + 1 ;}  /* Get a number from a PBM file header while skipping whitespace   and comments. Returns the number or 0 on EOF. Reads one more   byte than used by the number. */int pbmdim ( IFILE *f ){  int c, n=0 ;    /* scan for first digit and skip comments */  while ( ! isdigit ( c = fgetc ( f->f ) ) && c >= 0 )     if ( c == '#' )      while ( ( c = fgetc ( f->f ) ) != '\n' && c >= 0 ) ;  /* get the number */  if ( c >= 0 && isdigit( c ) ) {    n = c - '0' ;    while ( isdigit ( c = fgetc ( f->f ) ) && c >= 0 )       n = n * 10 + c - '0' ;  }  return n ;}/* Append nb bits from in[from] to bit-mapped scan line buffer   where `from' is a bit (not byte) index.  Bits in bytes are   ordered from MS to LS bit. Initialize before each scan line by   calling with nb=0 and in pointing to output buffer.  Flush   after each scan line by calling with nb=0 and in=NULL. */#define putbits( c, b ) { x = ( x << (b) ) | (c) ; shift += (b) ; \          if ( shift >= 0 ) { *out++ = x >> shift ; shift -= 8 ; } }void copybits ( uchar *in, int from, short nb ){  uchar *f ;  short bits ;  static uchar *out ;  static short x, shift ;  static unsigned char right [ 9 ] = {     0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff } ;    if ( ! nb ) {				/* reset for new scan line */    if ( in ) out = in ;		       else putbits ( 0, -shift ) ;	/* or flush bit buffer */    x = 0 ;    shift = -8 ;  } else {    f = in + ( from >> 3 ) ;    bits = 8 - ( from & 7 ) ;    if ( nb >= bits ) {      putbits ( *f++ & right [ bits ], bits ) ;      nb -= bits ;    } else {      putbits ( ( *f >> ( bits - nb ) ) & right [ bits ], nb ) ;      nb = 0 ;    }     while ( nb >= 8 ) { putbits ( *f++, 8 ) ; nb -= 8 ; }    if ( nb > 0 ) putbits ( *f >> ( 8 - nb ), nb );  }}   /* Generate scan line 'line' of string 'txt' using font `font'   and store the runs in 'runs'.  The font is scaled so it   appears to have cells of width w and height h.  lmargin pixels   of white space are added at the left margin. Sets 'pels' to   line width if not null.  Returns number of runs coded. */int texttorun ( uchar *txt, faxfont *font, short line, 	       int w, int h, int lmargin,	       short *runs, int *ppels ){  uchar *in, out [ MAXLINELEN * MAXFONTW / 8 + 1 ] ;  int i, nc = 0, cw, nr, pels ;  line = ( line * font->h + h/2 ) / h ;  cw = font->w ;  if ( line >= font->h ) line = font->h - 1 ;  in = font->buf + 256/8 * cw * line ;  copybits ( out, 0, 0 ) ;  for ( i=0 ; txt[i] && i < MAXLINELEN ; i++ ) {    copybits ( in, font->offset [ txt[i] ], cw ) ;    nc++ ;    while ( ( txt[i] == HT ) && ( nc & 7 ) ) { /* tab */      copybits ( in, font->offset [ ' ' ], cw ) ;      nc++ ;    }  }  copybits ( 0, 0, 0 ) ;  nr = bittorun ( out, ( nc*cw + 7 )/8, runs ) ;    if ( font->w == w )    pels = nc*cw ;  else        pels = xscale ( runs, nr, ( w * 256 ) / font->w ) ;    pels += xshift ( runs, nr, lmargin ) ;    if ( ppels ) *ppels = pels ;  return nr ;}		/* Image File Input Functions *//* Names of file formats */char *iformatname [ NIFORMATS ] = IFORMATS ;char *oformatname [ NOFORMATS ] = OFORMATS ;char *pformatname [ NPFORMATS ] = PFORMATS ;/* Log the names of files still to be sent using the "msg()"   format string s. */void logifnames ( IFILE *f, char *s ){  PAGE *p ;  char *fn ;  if ( f && f->page )    for ( p = f->page ; p <= f->lastpage ; p++ ) {      fn = p->fname ;      if ( fn ) msg ( s, fn ) ;    }}/* Read run lengths for one scan line from T.4-coded IFILE f into buffer   runs.  If pointer pels is not null it is used to save pixel count.   Returns number of runs stored, EOF on RTC, or -2 on EOF or other   error. */int readruns ( IFILE *f, short *runs, int *pels ){  int err=0, c=EOF, n ;  register int x ;  dtab *tab, *t ;  short shift ;  short *p, *maxp, *q, len=0, npad=0 ;  DECODER *d ;  uchar reverse=f->page->revbits ;  maxp = ( p = runs ) + MAXRUNS ;  d = &f->d ;  x = d->x ; shift = d->shift ; tab = d->tab ; /* restore decoder state */  do {    do {      while ( shift < 0 ) { 

⌨️ 快捷键说明

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