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

📄 arcpack.c

📁 汇编源代码大全
💻 C
字号:
/* * $Header: arcpack.c,v 1.9 88/06/02 16:27:36 hyc Locked $ *//*  ARC - Archive utility - ARCPACK    Version 3.49, created on 04/21/87 at 11:26:51(C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED    By:	 Thom Henderson    Description:	 This file contains the routines used to compress a file	 when placing it in an archive.    Language:	 Computer Innovations Optimizing C86*/#include <stdio.h>#include "arc.h"#if	MTS#include <ctype.h>#endifvoid	setcode(), sqinit_cm(), sqputc_cm(), init_cm(), putc_cm();void	filecopy(), abort(), putc_tst();int	getch(), addcrc();/* stuff for non-repeat packing */#define DLE 0x90		/* repeat sequence marker */static unsigned char state;	/* current packing state *//* non-repeat packing states */#define NOHIST  0		/* don't consider previous input */#define SENTCHAR 1		/* lastchar set, no lookahead yet */#define SENDNEWC 2		/* run over, send new char next */#define SENDCNT 3		/* newchar set, send count next *//* packing results */static long     stdlen;		/* length for standard packing */static short    crcval;		/* CRC check value */voidpack(f, t, hdr)			/* pack file into an archive */	FILE           *f, *t;	/* source, destination */	struct heads   *hdr;	/* pointer to header data */{	int             c;	/* one character of stream */	long            ncrlen;	/* length after packing */	long		huflen;	/* length after squeezing */	long            lzwlen;	/* length after crunching */	long		pred_sq(), file_sq();	/* stuff for squeezing */	long            pred_cm(), sqpred_cm();	/* dynamic crunching cleanup */	long            tloc, ftell();	/* start of output */	int		getch();	int             getc_ncr();	void            putc_pak();	/* first pass - see which method is best */	tloc = ftell(t);	/* note start of output */	if (!nocomp) {		/* if storage kludge not active */		if (note) {			printf(" analyzing, ");			fflush(stdout);		}		state = NOHIST;	/* initialize ncr packing */		stdlen = ncrlen = 0;	/* reset size counters */		crcval = 0;	/* initialize CRC check value */		setcode();	/* initialize encryption */		init_sq();	/* initialize for squeeze scan */		if (dosquash) {			sqinit_cm();			while ((c = getch(f)) != EOF) {	/* for each byte of file */				ncrlen++;	/* one more packed byte */				scan_sq(c);	/* see what squeezing can do */				sqputc_cm(c, t);	/* see what squashing							 * can do */			}			lzwlen = sqpred_cm(t);		} else {			init_cm(t);	/* initialize for crunching */				while ((c = getc_ncr(f)) != EOF) {	/* for each byte of file */				ncrlen++;	/* one more packed byte */				scan_sq(c);	/* see what squeezing can do */				putc_cm(c, t);	/* see what crunching can do */			}			lzwlen = pred_cm(t);	/* finish up after crunching */		}		huflen = pred_sq();	/* finish up after squeezing */	} else {		/* else kludge the method */		stdlen = 0;	/* make standard look best */		ncrlen = huflen = lzwlen = 1;	}	/* standard set-ups common to all methods */	fseek(f, 0L, 0);	/* rewind input */	hdr->crc = crcval;	/* note CRC check value */	hdr->length = stdlen;	/* set actual file length */	state = NOHIST;		/* reinitialize ncr packing */	setcode();		/* reinitialize encryption */	/* choose and use the shortest method */	if (kludge && note)		printf("\n\tS:%ld  P:%ld  S:%ld  C:%ld,\t ",			stdlen, ncrlen, huflen, lzwlen);	if (stdlen <= ncrlen && stdlen <= huflen && stdlen <= lzwlen) {		if (note) {			printf("storing, ");	/* store without compression */			fflush(stdout);		}		hdrver = 2;	/* note packing method */		fseek(t, tloc, 0);	/* reset output for new method */		stdlen = crcval = 0;	/* recalc these for kludge */		while ((c = getch(f)) != EOF)	/* store it straight */			putc_pak(c, t);		hdr->crc = crcval;		hdr->length = hdr->size = stdlen;	} else if (ncrlen < lzwlen && ncrlen < huflen) {		if (note) {			printf("packing, ");	/* pack with repeat			fflush(stdout);		 * suppression */		}		hdrver = 3;	/* note packing method */		hdr->size = ncrlen;	/* set data length */		fseek(t, tloc, 0);	/* reset output for new method */		while ((c = getc_ncr(f)) != EOF)			putc_pak(c, t);	} else if (huflen < lzwlen) {		if (note) {			printf("squeezing, ");			fflush(stdout);		}		hdrver = 4;	/* note packing method */		fseek(t, tloc, 0);	/* reset output for new method */		hdr->size = file_sq(f, t);	/* note final size */	} else {		if (note)			printf(dosquash ? "squashed, " : "crunched, ");		hdrver = dosquash ? 9 : 8;		hdr->size = lzwlen;	/* size should not change */	}	/* standard cleanups common to all methods */	if (note)		printf("done. (%ld%%)\n",100L - (100L*hdr->size)/hdr->length);}/* * Non-repeat compression - text is passed through normally, except that a * run of more than two is encoded as: *  * <char> <DLE> <count> *  * Special case: a count of zero indicates that the DLE is really a DLE, not a * repeat marker. */intgetc_ncr(f)			/* get bytes with collapsed runs */	FILE           *f;	/* file to get from */{	static int      lastc;	/* value returned on last call */	static int      repcnt;	/* repetition counter */	static int      c;	/* latest value seen */	switch (state) {	/* depends on our state */	case NOHIST:		/* no relevant history */		state = SENTCHAR;		return lastc = getch(f);	/* remember the value next						 * time */	case SENTCHAR:		/* char was sent. look ahead */		switch (lastc) {/* action depends on char */		case DLE:	/* if we sent a real DLE */			state = NOHIST;	/* then start over again */			return 0;	/* but note that the DLE was real */		case EOF:	/* EOF is always a special case */			return EOF;		default:	/* else test for a repeat */			for (repcnt = 1; (c = getch(f)) == lastc && repcnt < 255; repcnt++);			/* find end of run */			switch (repcnt) {	/* action depends on run size */			case 1:/* not a repeat */				return lastc = c;	/* but remember value							 * next time */			case 2:/* a repeat, but too short */				state = SENDNEWC;	/* send the second one							 * next time */				return lastc;			default:	/* a run - compress it */				state = SENDCNT;	/* send repeat count							 * next time */				return DLE;	/* send repeat marker this						 * time */			}		}	case SENDNEWC:		/* send second char of short run */		state = SENTCHAR;		return lastc = c;	case SENDCNT:		/* sent DLE, now send count */		state = SENDNEWC;		return repcnt;	default:		abort("Bug - bad ncr state\n");	}}intgetch(f)			/* special get char for packing */	FILE           *f;	/* file to get from */{	int		c;	/* a char from the file */#if	!DOS	static int      cr = 0;	/* add \r before \n ? */	if (cr) {		c = '\n';#if	MTS		c = toascii(c);#endif		crcval = addcrc(crcval, c);		stdlen++;		cr = 0;		return (c);	}#endif	if ((c = fgetc(f)) != EOF) {	/* if not the end of file */#if	!DOS		if (!image && (c == '\n')) {			c = '\r';			cr = 1;		}#endif#if	MTS		if (!image)			c = toascii(c);#endif		crcval = addcrc(crcval, c);	/* then update CRC check						 * value */		stdlen++;	/* and bump length counter */	}	return c;}voidputc_pak(c, f)			/* put a packed byte into archive */	char            c;	/* byte to put */	FILE           *f;	/* archive to put it in */{	unsigned char		code();	putc_tst(code(c), f);	/* put encoded byte, with checks */}

⌨️ 快捷键说明

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