home *** CD-ROM | disk | FTP | other *** search
- #include<stdio.h>
- #include<fcntl.h>
- #include<sys/types.h>
- #include<sys\stat.h>
- #include"fxf.h"
-
- /* These are kinda historical; see main() near top. */
- #define INDENT 64
- #define NCOLUMNS 80
- #define NPGLINES 66
-
- struct
- {
- unsigned bits;
- unsigned mask;
- }
- whites[]=
- {
- {0x00ac, 0x00ff},
- {0x0038, 0x003f},
- {0x000e, 0x000f},
- {0x0001, 0x000f},
- {0x000d, 0x000f},
- {0x0003, 0x000f},
- {0x0007, 0x000f},
- {0x000f, 0x000f},
- {0x0019, 0x001f},
- {0x0005, 0x001f},
- {0x001c, 0x001f},
- {0x0002, 0x001f},
- {0x0004, 0x003f},
- {0x0030, 0x003f},
- {0x000b, 0x003f},
- {0x002b, 0x003f},
- {0x0015, 0x003f},
- {0x0035, 0x003f},
- {0x0072, 0x007f},
- {0x0018, 0x007f},
- {0x0008, 0x007f},
- {0x0074, 0x007f},
- {0x0060, 0x007f},
- {0x0010, 0x007f},
- {0x000a, 0x007f},
- {0x006a, 0x007f},
- {0x0064, 0x007f},
- {0x0012, 0x007f},
- {0x000c, 0x007f},
- {0x0040, 0x00ff},
- {0x00c0, 0x00ff},
- {0x0058, 0x00ff},
- {0x00d8, 0x00ff},
- {0x0048, 0x00ff},
- {0x00c8, 0x00ff},
- {0x0028, 0x00ff},
- {0x00a8, 0x00ff},
- {0x0068, 0x00ff},
- {0x00e8, 0x00ff},
- {0x0014, 0x00ff},
- {0x0094, 0x00ff},
- {0x0054, 0x00ff},
- {0x00d4, 0x00ff},
- {0x0034, 0x00ff},
- {0x00b4, 0x00ff},
- {0x0020, 0x00ff},
- {0x00a0, 0x00ff},
- {0x0050, 0x00ff},
- {0x00d0, 0x00ff},
- {0x004a, 0x00ff},
- {0x00ca, 0x00ff},
- {0x002a, 0x00ff},
- {0x00aa, 0x00ff},
- {0x0024, 0x00ff},
- {0x00a4, 0x00ff},
- {0x001a, 0x00ff},
- {0x009a, 0x00ff},
- {0x005a, 0x00ff},
- {0x00da, 0x00ff},
- {0x0052, 0x00ff},
- {0x00d2, 0x00ff},
- {0x004c, 0x00ff},
- {0x00cc, 0x00ff},
- {0x002c, 0x00ff},
- {0x001b, 0x001f},
- {0x0009, 0x001f},
- {0x003a, 0x003f},
- {0x0076, 0x007f},
- {0x006c, 0x00ff},
- {0x00ec, 0x00ff},
- {0x0026, 0x00ff},
- {0x00a6, 0x00ff},
- {0x0016, 0x00ff},
- {0x00e6, 0x00ff},
- {0x0066, 0x01ff},
- {0x0166, 0x01ff},
- {0x0096, 0x01ff},
- {0x0196, 0x01ff},
- {0x0056, 0x01ff},
- {0x0156, 0x01ff},
- {0x00d6, 0x01ff},
- {0x01d6, 0x01ff},
- {0x0036, 0x01ff},
- {0x0136, 0x01ff},
- {0x00b6, 0x01ff},
- {0x01b6, 0x01ff},
- {0x0032, 0x01ff},
- {0x0132, 0x01ff},
- {0x00b2, 0x01ff},
- {0x0006, 0x003f},
- {0x01b2, 0x01ff}
- },
- blacks[]=
- {
- {0x03b0, 0x03ff},
- {0x0002, 0x0007},
- {0x0003, 0x0003},
- {0x0001, 0x0003},
- {0x0006, 0x0007},
- {0x000c, 0x000f},
- {0x0004, 0x000f},
- {0x0018, 0x001f},
- {0x0028, 0x003f},
- {0x0008, 0x003f},
- {0x0010, 0x007f},
- {0x0050, 0x007f},
- {0x0070, 0x007f},
- {0x0020, 0x00ff},
- {0x00e0, 0x00ff},
- {0x0030, 0x01ff},
- {0x03a0, 0x03ff},
- {0x0060, 0x03ff},
- {0x0040, 0x03ff},
- {0x0730, 0x07ff},
- {0x00b0, 0x07ff},
- {0x01b0, 0x07ff},
- {0x0760, 0x07ff},
- {0x00a0, 0x07ff},
- {0x0740, 0x07ff},
- {0x00c0, 0x07ff},
- {0x0530, 0x0fff},
- {0x0d30, 0x0fff},
- {0x0330, 0x0fff},
- {0x0b30, 0x0fff},
- {0x0160, 0x0fff},
- {0x0960, 0x0fff},
- {0x0560, 0x0fff},
- {0x0d60, 0x0fff},
- {0x04b0, 0x0fff},
- {0x0cb0, 0x0fff},
- {0x02b0, 0x0fff},
- {0x0ab0, 0x0fff},
- {0x06b0, 0x0fff},
- {0x0eb0, 0x0fff},
- {0x0360, 0x0fff},
- {0x0b60, 0x0fff},
- {0x05b0, 0x0fff},
- {0x0db0, 0x0fff},
- {0x02a0, 0x0fff},
- {0x0aa0, 0x0fff},
- {0x06a0, 0x0fff},
- {0x0ea0, 0x0fff},
- {0x0260, 0x0fff},
- {0x0a60, 0x0fff},
- {0x04a0, 0x0fff},
- {0x0ca0, 0x0fff},
- {0x0240, 0x0fff},
- {0x0ec0, 0x0fff},
- {0x01c0, 0x0fff},
- {0x0e40, 0x0fff},
- {0x0140, 0x0fff},
- {0x01a0, 0x0fff},
- {0x09a0, 0x0fff},
- {0x0d40, 0x0fff},
- {0x0340, 0x0fff},
- {0x05a0, 0x0fff},
- {0x0660, 0x0fff},
- {0x0e60, 0x0fff},
- {0x03c0, 0x03ff},
- {0x0130, 0x0fff},
- {0x0930, 0x0fff},
- {0x0da0, 0x0fff},
- {0x0cc0, 0x0fff},
- {0x02c0, 0x0fff},
- {0x0ac0, 0x0fff},
- {0x06c0, 0x1fff},
- {0x16c0, 0x1fff},
- {0x0a40, 0x1fff},
- {0x1a40, 0x1fff},
- {0x0640, 0x1fff},
- {0x1640, 0x1fff},
- {0x09c0, 0x1fff},
- {0x19c0, 0x1fff},
- {0x05c0, 0x1fff},
- {0x15c0, 0x1fff},
- {0x0dc0, 0x1fff},
- {0x1dc0, 0x1fff},
- {0x0940, 0x1fff},
- {0x1940, 0x1fff},
- {0x0540, 0x1fff},
- {0x1540, 0x1fff},
- {0x0b40, 0x1fff},
- {0x1b40, 0x1fff},
- {0x04c0, 0x1fff},
- {0x14c0, 0x1fff}
- };
-
- #define SFXBUFSIZ 4096
-
- unsigned char sfxbuf[SFXBUFSIZ];
-
- int sfxfd, sfxbufi;
-
- putbyte(pbb)
- unsigned char pbb;
- {
- sfxbuf[sfxbufi++]=pbb;
- if(sfxbufi>=SFXBUFSIZ)
- {
- if(write(sfxfd, sfxbuf, SFXBUFSIZ)!=SFXBUFSIZ)\
- {
- printf("Write error.\n");
- exit(1);
- }
- sfxbufi=0;
- }
- }
-
- flush()
- {
- if(write(sfxfd, sfxbuf, sfxbufi)!=sfxbufi)
- {
- printf("Write error on explicit flush.\n");
- exit(2);
- }
- sfxbufi=0; /* Left this out earlier. Gott in Himmel! */
- }
-
- unsigned char wkngbyte, wbmask;
-
- putsym(bitsw, maskw)
- unsigned bitsw, maskw;
- {
- unsigned srcmask;
- for(srcmask=1;srcmask&maskw;srcmask<<=1)
- {
- if(bitsw&srcmask)
- wkngbyte|=wbmask;
- if(!(wbmask<<=1))
- {
- if(wkngbyte==0x10)
- putbyte(0x10); /* Shield DLE */
- putbyte(wkngbyte);
- wkngbyte=0;
- wbmask=0x01;
- }
- }
- }
-
- flushsym()
- {
- if(wbmask!=0x01)
- {
- if(wkngbyte==0x10)
- putbyte(0x10); /* Shield DLE */
- putbyte(wkngbyte);
- }
- }
-
- initsym()
- {
- wkngbyte=0;
- wbmask=0x01;
- }
-
- putwhite(n)
- int n;
- {
- int m;
- if((n<0)||(n>1728))
- {
- printf("\nProbable code error; bad white run length %d.\n", n);
- exit(71);
- }
- if(m=(n&~63))
- {
- m>>=6;
- m+=63;
- putsym(whites[m].bits, whites[m].mask);
- }
- m=n&63;
- putsym(whites[m].bits, whites[m].mask);
- }
-
- putblack(n)
- int n;
- {
- int m;
- if((n<0)||(n>1728))
- {
- printf("\nProbable code error, bad black run length %d.\n", n);
- exit(72);
- }
- if(m=(n&~63))
- {
- m>>=6;
- m+=63;
- putsym(blacks[m].bits, blacks[m].mask);
- }
- m=n&63;
- putsym(blacks[m].bits, blacks[m].mask);
- }
-
- unsigned char font[FXF_NCHARS][FXF_NROWS][FXF_NBYTES];
-
- loadfont(fname)
- {
- int fxffd;
- unsigned fnbytes;
- if((fxffd=open(fname, O_RDONLY|O_BINARY))==-1)
- {
- printf("Error opening font file %s.\n", fname);
- exit(30);
- }
- fnbytes=FXF_NCHARS*FXF_NROWS*FXF_NBYTES;
- if(read(fxffd, font, fnbytes)!=fnbytes)
- {
- printf("Error reading in font file %s.\n", fname);
- exit(31);
- }
- close(fxffd);
- }
-
- /* If you look at the arg types, you'll notice "line" means text, not scan */
- /* Now remember, you might or might not get the \n in line */
-
- convertline(line, indent)
- unsigned char *line;
- int indent;
- {
- int row, byte, white, value, pixcnt, charpixcnt;
- unsigned char *cptr;
- for(row=0;row<FXF_NROWS;row++)
- {
- pixcnt=0;
- white=indent;
- for(cptr=line;(*cptr)!=0xff;cptr++)
- {
- charpixcnt=0;
- if((*cptr)<0xfe);
- {
- for(byte=0;byte<FXF_NBYTES;byte++)
- {
- if(value=font[*cptr][row][byte])
- {
- if(byte&1)
- {
- putwhite(white);
- pixcnt+=white;
- white=0;
- putblack(value);
- pixcnt+=value;
- charpixcnt+=value;
- }
- else
- {
- white+=value;
- charpixcnt+=value;
- }
- }
- else if(byte)
- break;
- }
- }
- white+=FXF_LEADING+FXF_WIDTH-charpixcnt;
- }
- putwhite(1728-pixcnt);
- flushsym();
- putbyte(0x00);
- putbyte(0x80);
- initsym();
- }
- }
-
- struct header_s
- {
- unsigned char mfgr;
- unsigned char version;
- unsigned char encoding;
- unsigned char bppix;
- unsigned short xmin;
- unsigned short ymin;
- unsigned short xmax;
- unsigned short ymax;
- unsigned short hdpi;
- unsigned short vdpi;
- unsigned char cmap[48];
- unsigned char reserved;
- unsigned char nplanes;
- unsigned short bypl;
- unsigned short paltinf;
- unsigned short hscrnsz;
- unsigned short vscrnsz;
- unsigned char filler[54];
- };
-
- struct header_s header;
-
- #define PCXBBUFSIZ 4096
-
- unsigned char pcxbbuf[PCXBBUFSIZ];
-
- int pcxfd, pcxbi, pcxbn;
-
- int getpcxb()
- {
- if(pcxbi>=pcxbn)
- if((pcxbn=read(pcxfd, pcxbbuf, PCXBBUFSIZ))<=0)
- {
- printf("\nPremature end of PCX file. Aborting.\n");
- exit(101);
- }
- else
- pcxbi=0;
- return(pcxbbuf[pcxbi++]);
- }
-
- int ncolumns, npglines, toppad, pageline, pagenum;
- unsigned char pcxline[256];
-
- int convertpcx(char *imagename, int indent) /* "imagename" is historical */
- {
- char *inp;
- int height, width;
- int accum, whitep, pcxindent, bpl, pli, npix, cnt;
- unsigned char b, b1, mask, *bptr, just;
- inp=imagename;
- if(imagename[1]==' ')
- if(imagename[0]=='-')
- {
- inp+=2;
- just='-';
- }
- else if(imagename[0]=='+')
- {
- inp+=2;
- just='+';
- }
- else;
- else
- just='0';
- printf("\nPCX file %s; scan lines remaining: ", imagename);
- if((pcxfd=open(inp, O_RDONLY|O_BINARY))<0)
- {
- printf("Error\nUnable to open PCX file %s. Aborting.\n", inp);
- exit(102);
- }
- pcxbi=pcxbn=0;
- if(read(pcxfd, &header, sizeof(header))!=sizeof(header))
- {
- printf("Error\nError reading PCX header from file %s. Aborting.\n", inp);
- exit(103);
- }
- if(header.nplanes!=1)
- {
- printf("Error\n");
- printf("The PCX image %s has multiple planes.\n", inp);
- printf("Only one is relevant, so only one is permitted.\n");
- printf("When you fix it, make sure it isn't grayscale either.\n");
- printf("Aborting.\n");
- exit(104);
- }
- if(header.bppix!=1)
- {
- printf("Error\nThe PCX image %s is grayscale.\n", inp);
- printf("We don't do grayscale. Aborting.\n");
- exit(105);
- }
- height=header.ymax+1-header.ymin;
- width=header.xmax+1-header.xmin;
- if(height>(npglines*FXF_NROWS))
- {
- printf("Error\nThe PCX image %s is too tall. Aborting.\n", inp);
- exit(106);
- }
- if(width>(ncolumns*(FXF_WIDTH+FXF_LEADING)))
- {
- printf("Error\nThe PCX image %s is too wide. Aborting.\n", inp);
- exit(107);
- }
- if(((npglines+1-pageline)*FXF_NROWS)<height) /* Need page break */
- {
- for(cnt=0;cnt<toppad;cnt++)
- convertline("\377", 0);
- pageline=1;
- flushsym();
- flush(); /* More neat trick */
- putbyte(0x10); /* i.e. we can rewind this here */
- putbyte(0x03); /* Not sure we need to here, actually... */
- putbyte(0x00);
- putbyte(0x80);
- initsym();
- pagenum++;
- for(cnt=0;cnt<toppad;cnt++)
- convertline("\377", 0);
- }
- pageline+=height/FXF_NROWS;
- if(height%FXF_NROWS)
- pageline++;
- if(just=='-')
- pcxindent=indent; /* line up for pretty mode */
- else if(just=='+')
- pcxindent=1728-width; /* I can't imagine what people */
- else /* will do with +, but I'd be */
- pcxindent=(1728-width)/2; /* a twit to save the 2 lines. */
- bpl=header.bypl; /* Can't think how to indent. */
- /* Don't think we need to flushsym() */
- pli=0;
- printf("%-5d", height);
- while(1)
- {
- b=getpcxb();
- if((b&0xc0)==0xc0) /* God, I'm getting sick of compression! */
- {
- b1=getpcxb();
- b&=0x3f;
- while(b--)
- pcxline[pli++]=b1;
- }
- else
- pcxline[pli++]=b;
- if(pli<bpl)
- continue;
- /* EOL */
- accum=pcxindent;
- whitep=1;
- mask=0x80;
- npix=pli=0;
- bptr=pcxline;
- for(cnt=width;--cnt;) /* Really seems wrong but cnt-- gave */
- { /* a black stripe on the right side */
- if(mask==0x01)
- {
- bptr++;
- mask=0x80;
- }
- else
- mask>>=1;
- if(whitep)
- if((*bptr)&mask) /* 1, therefore white (PCX)*/
- accum++;
- else
- {
- putwhite(accum);
- npix+=accum;
- accum=1; /* Was 0 for a while. Duh! */
- whitep=0;
- }
- else
- if((*bptr)&mask)
- {
- putblack(accum);
- npix+=accum;
- accum=1;
- whitep=1;
- }
- else
- accum++;
- }
- if(!whitep)
- {
- putblack(accum);
- npix+=accum;
- }
- putwhite(1728-npix);
- flushsym();
- putbyte(0x00);
- putbyte(0x80);
- initsym();
- printf("\b\b\b\b\b%-5d", height);
- if((--height)<=0) /* Had an amusing fencepost error here; */
- break; /* we've already done the loop! */
- }
- printf("\n");
- flush();
- close(pcxfd);
- }
-
- /* NOTE: We flush before DLE-ETX at page breaks, and assume a
- * big enough buffer that all initial page overhead fits.
- * This way, if we later realize that the last page is empty,
- * we just discard the buffer (sfxbufi=0). Handy, eh what?
- */
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- FILE *ascfd;
- unsigned char line[256], ffn[256];
- int column, c;
- int indent, i;
- if(argc<3)
- {
- printf("USAGE: asctosfx <ascii file> <sfx file> [/p]\n");
- printf("/p is pretty, i.e. H & V margins.\n");
- printf("Control-L (FormFeed) is recognized.\n");
- printf("Tabs (Control-I) are modulo 8.\n");
- printf("Control-P <pathname> <newline> inserts PCX. Must occur on a line by itself.\n");
- printf("PCX default is centered.\n");
- printf("<pathname> beginning with -<SP> is flush left, +<SP> is flush right.\n");
- printf("OUTPUT IS HIGH RESOLUTION!!! (Fine / 192 lpi)\n");
- exit(2);
- }
- if((ascfd=fopen(argv[1], "r"))==NULL)
- {
- printf("Error opening text input file %s.\n", argv[1]);
- exit(4);
- }
- if(getenv("PCCPFROM")==NULL)
- {
- printf("\nYour PCCPFROM environment variable is not set, which will result in\n");
- printf("a transmission that we believe may be unlawful under USA FCC regulations.\n");
- printf("\nThis variable is only actually used at send time. See MANUAL.\n\n");
- printf("If you are not in the USA, we apologize for this disgusting display\n");
- printf("of national Chauvinism.\n\n");
- }
- if(getenv("PCCPPATH")==NULL)
- strcpy(ffn, FXF_FILENAME);
- else
- sprintf(ffn, "%s\\%s", getenv("PCCPPATH"), FXF_FILENAME);
- sfxbufi=0;
- loadfont(ffn);
- if((sfxfd=open(argv[2], O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, S_IWRITE))==-1)
- {
- printf("Error opening output file %s.\n", argv[2]);
- exit(3);
- }
- if(argc>3)
- {
- toppad=3;
- indent=INDENT+80;
- ncolumns=NCOLUMNS-8;
- npglines=NPGLINES-6;
- }
- else
- {
- toppad=0;
- indent=INDENT;
- ncolumns=NCOLUMNS;
- npglines=NPGLINES;
- }
- sfxbufi=0;
- pagenum=1;
- putbyte(0x00);
- putbyte(0x80);
- initsym();
- for(i=0;i<toppad;i++)
- convertline("\377", 0);
- printf("\nBeginning to convert %s to %s", argv[1], argv[2]);
- if(argc>3)
- printf(" with pretty margins.\n");
- else
- printf(" in raw mode.\n");
- pageline=1;
- column=0;
- while(1)
- {
- c=getc(ascfd);
- if((c==EOF)||(c==0x0c))
- {
- if(line[0]!=0xff)
- {
- /* pageline++ 'cause we use as flag at end. */
- printf("\rLine %2d of Page %d", pageline++, pagenum);
- line[column]=0xff;
- convertline(line, indent);
- line[0]=0xff;
- column=0;
- }
- for(i=0;i<toppad;i++)
- convertline("\377", 0);
- if(c==EOF)
- break;
- pageline=1;
- flushsym();
- flush(); /* Above-mentioned neat trick */
- putbyte(0x10); /* i.e. we can rewind this here */
- putbyte(0x03);
- putbyte(0x00);
- putbyte(0x80);
- initsym();
- pagenum++;
- for(i=0;i<toppad;i++)
- convertline("\377", 0);
- }
- else
- {
- if(c==('P'&31))
- {
- /* If this ain't at beginning of line,
- * you lose the line, 'cause that's
- * what's easy to code!
- */
- fgets(line, 255, ascfd);
- line[strlen(line)-1]='\0';
- convertpcx(line, indent);
- line[0]=0xff;
- column=0; /* What a pity! */
- if(pageline>=npglines)
- {
- for(i=0;i<toppad;i++)
- convertline("\377", 0);
- pageline=1;
- putbyte(0x10);
- putbyte(0x03);
- putbyte(0x00);
- putbyte(0x80);
- for(i=0;i<toppad;i++)
- convertline("\377", 0);
- printf("\rLine %2d of page %d",
- 1, ++pagenum);
- }
- }
- else if(c=='\t')
- do
- line[column++]=0xfe;
- while((column&0x0007)&&(column<ncolumns));
- else if(c==' ')
- line[column++]=0xfe;
- else if(c!='\n')
- if((c>=FXF_FIRSTCHAR)&&(c<(FXF_FIRSTCHAR+FXF_NCHARS)))
- line[column++]=c-FXF_FIRSTCHAR;
- else
- printf("\nBad character Hex %02x skipped.\n", c);
- /* DEBUG ONLY *
- if(column>ncolumns)
- {
- printf("\nColumn bad value: %d\n", column);
- exit(99);
- }
- * END DEBUG ONLY */
- if((c=='\n')||(column>=ncolumns))
- {
- line[column]=0xff;
- printf("\rLine %2d of Page %d", pageline++, pagenum);
- convertline(line, indent);
- line[0]=0xff;
- column=0;
- if(pageline>=npglines)
- {
- for(i=0;i<toppad;i++)
- convertline("\377", 0);
- pageline=1;
- flushsym();
- flush(); /* More neat trick */
- putbyte(0x10);
- putbyte(0x03);
- putbyte(0x00);
- putbyte(0x80);
- initsym();
- pagenum++;
- for(i=0;i<toppad;i++)
- convertline("\377", 0);
- }
- }
- }
- }
- flushsym();
- if(pageline==1)
- sfxbufi=0; /* Discard empty page overhead from buffer. */
- putbyte(0x10);
- putbyte(0x04);
- fclose(ascfd);
- flush();
- close(sfxfd);
- }
-