|
DataMuseum.dkPresents historical artifacts from the history of: Jet Computer Jet80 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Jet Computer Jet80 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - download
Length: 6912 (0x1b00) Types: TextFile Names: »SQ.C«
└─⟦1275f6521⟧ Bits:30005823 BD Software C Compiler v1.50a └─ ⟦this⟧ »SQ.C«
/* This program compresses a file without loosing information. * The usq.com program is required to unsqueeze the file * before it can be used. * * Typical compression rates are: * .COM 6% (Don't bother) * .ASM 33% (using full ASCII set) * .DIC 46% (using only uppercase and a few others) * Squeezing a really big file takes a few minutes. * * Useage: * SQ item ... * where ... represents more (optional) items and * "item" is either: * drive: to change the output drive * file input file * drive:file input file * - toggle debugging display mode * * If no such items are given on the command line you will be * prompted for commands (one at a time). An empty command * terminates the program. * * SQ uses the dio package, so input and output can be redirected * by special items on the command line such as: * <file reads console input from file * >file sends console output to file * +file sends console output to console and file * Also console output of another program using dio can be piped * to the input of this one or vice-versa. Example: * A>fls parameters øsq * where fls might be a program that expands patterns like *.com * to a list of ambiguous file names for sq to squeeze. * * The squeezed file name is formed by changing the second * letter of the file type to Q. If there is no file type, * the squeezed file type is QQQ. If the name exists it is * overwritten! * * Examples: * A>SQ GRUMP makes GRUMP.QQQ on A: * A>SQ D:CRAP.XYZ makes CRAP.XQZ on A: * A>SQ B: D:CRAP.COM makes CRAP.CQM on B: * B>SQ X.A C: Y.B makes X.AQ on B: and Y.BQ on C: * * The transformations compress strings of identical bytes and * then encode each resulting byte value and EOF as bit strings * having lengths in inverse proportion to their frequency of * occurrance in the intermediate input stream. The latter uses * the Huffman algorithm. Decoding information is included in * the squeezed file, so squeezing short files or files with * uniformly distributed byte values will actually increase size. */ /* CHANGE HISTORY: * 1.3 Close files properly in case of error exit. * 1.4 Break up long introductory lines. * 1.4 Send introduction only to console. * 1.4 Send errors only to console. * 1.5 Fix BUG that caused a rare few squeezed files * to be incorrect and fail the USQ crc check. * The problem was that some 17 bit codes were * generated but are not supported by other code. * THIS IS A MAJOR CHANGE affecting TR2.C and SQ.H and * requires recompilation of all files which are part * of SQ. Two basic changes were made: tree depth is now * used as a tie breaker when weights are equal. This * makes the tree shallower. Although that may always be * sufficient, an error trap was added to cause rescaling * of the counts if any code > 16 bits long is generated. * 1.5 Add debugging displays option '-'. */ \f #define VERSION "1.5 08/29/81" #include <bdscio.h> #include <dio.h> #include "sqcom.h" #include "sq.h" #define STDOUT 4 /* console only (error) stream */ main(argc, argv) int argc; char *argvÆÅ; æ int i,c; int getchar(); /* Directed io version */ char inpargÆ16Å; /* parameter from input */ dioinit(&argc, argv); /* obey directed to args */ debug = FALSE; fprintf(STDOUT,"File squeezer version %s byØnØtRichard GreenlawØnØt251 Colony Ct.ØnØtGahanna, Ohio 43230Øn", VERSION); fprintf(STDOUT,"Accepts redirection and pipes.ØnOmit other parameters for help and promptØn"); /* Initialize output drive to default drive */ outdrvÆ0Å = 'Ø0'; /* But prepare for a specific drive */ outdrvÆ1Å = ':'; outdrvÆ2Å = 'Ø0'; /* string terminator */ /* Process the parameters in order */ for(i = 1; i < argc; ++i) obey(argvÆiÅ); if(argc < 2) æ fprintf(STDOUT, "Parameters are from command line or one-at-a-time from standardØninput and are output drives and input file names. Empty to quit.Øn"); do æ fprintf(STDOUT, "Øn*"); for(i = 0; i < 16; ++i) æ if((c = getchar()) == EOF) c = 'Øn'; /* fake empty (exit) command */ if((inpargÆiÅ = c) == 'Øn') æ inpargÆiÅ = 'Ø0'; break; å å if(inpargÆ0Å != 'Ø0') obey(inparg); å while(inpargÆ0Å != 'Ø0'); å dioflush(); /* clean up any directed io */ å \f obey(p) char *p; æ char *q; char outfileÆ16Å; /* output file spec. */ if(*p == '-') æ /* toggle debug option */ debug = !debug; return; å if(*(p + 1) == ':') æ /* Got a drive */ if(isalpha(*p)) æ if(*(p+2) == 'Ø0') æ /* Change output drive */ printf("ØnOutput drive =%s",p); outdrvÆ0Å = *p; return; å å else æ fprintf(STDOUT, "ØnERROR - Ignoring %s", p); return; å å /* Check for ambiguous (wild-card) name */ for(q = p; *q != 'Ø0'; ++q) if(*q == '*' øø *q == '?') æ fprintf(STDOUT, "ØnAmbiguous name %s ignored", p); return; å /* First build output file name */ outfileÆ0Å = 'Ø0'; /* empty */ strcat(outfile, outdrv); /* drive */ strcat(outfile, (*(p + 1) == ':') ? p + 2 : p); /* input name */ /* Find and change output file type */ for(q = outfile; *q != 'Ø0'; ++q) if(*q == '.') if(*(q + 1) == 'Ø0') *q = 'Ø0'; /* kill trailing dot */ else switch(*(q+2)) æ case 'q': case 'Q': fprintf(STDOUT, "Øn%s ignored ( already squeezed?)", p); return; case 'Ø0': *(q+3) = 'Ø0'; /* fall thru */ default: *(q + 2) = 'Q'; goto named; å /* No file type */ strcat(outfile, ".QQQ"); named: squeeze(p, outfile); å \f squeeze(infile, outfile) char *infile, *outfile; æ int i, c; struct _buf inbuff, outbuff; /* file buffers */ printf("Øn%s -> %s: ", infile, outfile); if(fopen(infile, &inbuff) == ERROR) æ fprintf(STDOUT, "Can't open %s for input pass 1Øn", infile); return; å if(fcreat(outfile, &outbuff) == ERROR) æ fprintf(STDOUT, "Can't create %sØn", outfile); fclose(&inbuff); return; å /* First pass - get properties of file */ crc = 0; /* initialize checksum */ printf("analyzing, "); /*init_ncr();*/ init_huff(&inbuff); fclose(&inbuff); /* Write output file header with decoding info */ wrt_head(&outbuff, infile); /* Second pass - encode the file */ printf("squeezing, "); if(fopen(infile, &inbuff) == ERROR) æ fprintf(STDOUT, "Can't open %s for input pass 2Øn", infile); goto closeout; å /*init_ncr(); *//* For second pass */ /* Translate the input file into the output file */ while((c = gethuff(&inbuff)) != EOF) if(putc(c, &outbuff) == ERROR) æ fprintf(STDOUT, "ERROR - write failure in %sØn", outfile); goto closeall; å printf(" done."); closeall: fclose(&inbuff); closeout: fflush(&outbuff); fclose(&outbuff); å «eof»