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

📄 compress.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
		bits -= 8;	}	/* high order bits. */	code |= (*bp & rmask[bits]) << r_off;	offset += n_bits;	return code;}#ifdef DEBUGprintcodes(){	/*	* Just print out codes from input file.  For debugging.	*/	code_int code;	int col = 0, bits;	bits = n_bits = INIT_BITS;	maxcode = MAXCODE(n_bits);	free_ent = ((block_compress) ? FIRST : 256 );	while ( ( code = getcode() ) >= 0 ) {	if ( (code == CLEAR) && block_compress ) {			free_ent = FIRST - 1;			clear_flg = 1;	}	else if ( free_ent < maxmaxcode )		free_ent++;	if ( bits != n_bits ) {		fprintf(stderr, "\nChange to %d bits\n", n_bits );		bits = n_bits;		col = 0;	}	fprintf(stderr, "%5d%c", code, (col+=6) >= 74 ? (col = 0, '\n') : ' ' );	}	putc( '\n', stderr );	exit( 0 );}code_int sorttab[1<<BITS];	/* sorted pointers into htab */#define STACK_SIZE	15000dump_tab()	/* dump string table */{	int i, first, c, ent;	int stack_top = STACK_SIZE;	if(do_decomp == 0) {	/* compressing */	int flag = 1;	for(i=0; i<hsize; i++) {	/* build sort pointers */		if((long)htabof(i) >= 0) {			sorttab[codetabof(i)] = i;		}	}	first = block_compress ? FIRST : 256;	for(i = first; i < free_ent; i++) {		fprintf(stderr, "%5d: \"", i);		de_stack[--stack_top] = '\n';		de_stack[--stack_top] = '"';		stack_top = in_stack((htabof(sorttab[i])>>maxbits)&0xff,	stack_top);		for(ent=htabof(sorttab[i]) & ((1<<maxbits)-1);			ent > 256;			ent=htabof(sorttab[ent]) & ((1<<maxbits)-1)) {			stack_top = in_stack(htabof(sorttab[ent]) >> maxbits,						stack_top);		}		stack_top = in_stack(ent, stack_top);		fwrite( &de_stack[stack_top], 1, STACK_SIZE-stack_top, stderr);			stack_top = STACK_SIZE;	}	} else if(!debug) {	/* decompressing */	for ( i = 0; i < free_ent; i++ ) {		ent = i;		c = tab_suffixof(ent);		if ( isascii(c) && isprint(c) )		fprintf( stderr, "%5d: %5d/'%c'  \"",				ent, tab_prefixof(ent), c );		else		fprintf( stderr, "%5d: %5d/\\%03o \"",				ent, tab_prefixof(ent), c );		de_stack[--stack_top] = '\n';		de_stack[--stack_top] = '"';		for ( ; ent != NULL;			ent = (ent >= FIRST ? tab_prefixof(ent) : NULL) ) {		stack_top = in_stack(tab_suffixof(ent), stack_top);		}		fwrite( &de_stack[stack_top], 1, STACK_SIZE - stack_top, stderr );		stack_top = STACK_SIZE;	}	}}intin_stack(int c, int stack_top){	if ( (isascii(c) && isprint(c) && c != '\\') || c == ' ' ) {		de_stack[--stack_top] = c;	} else {		switch( c ) {		case '\n': de_stack[--stack_top] = 'n'; break;		case '\t': de_stack[--stack_top] = 't'; break;		case '\b': de_stack[--stack_top] = 'b'; break;		case '\f': de_stack[--stack_top] = 'f'; break;		case '\r': de_stack[--stack_top] = 'r'; break;		case '\\': de_stack[--stack_top] = '\\'; break;		default:	 	de_stack[--stack_top] = '0' + c % 8;	 	de_stack[--stack_top] = '0' + (c / 8) % 8;	 	de_stack[--stack_top] = '0' + c / 64;	 	break;		}		de_stack[--stack_top] = '\\';	}	return stack_top;}#endif /* DEBUG */writeerr(){	perror(ofname);	unlink(ofname);	exit(1);}copystat(ifname, ofname)char *ifname, *ofname;{	int mode;	time_t timep[2];	struct stat statbuf;	fclose(stdout);	if (stat(ifname, &statbuf)) {		/* Get stat on input file */		perror(ifname);		return;	}	if (!S_ISREG(statbuf.st_mode)) {		if (quiet)			fprintf(stderr, "%s: ", ifname);		fprintf(stderr, " -- not a regular file: unchanged");		exit_stat = 1;	} else if (exit_stat == 2 && !force) {		/* No compression: remove file.Z */		if (!quiet)			fprintf(stderr, " -- file unchanged");	} else {			/* Successful Compression */		exit_stat = 0;		mode = statbuf.st_mode & 0777;		if (chmod(ofname, mode))		/* Copy modes */			perror(ofname);		/* Copy ownership */		chown(ofname, statbuf.st_uid, statbuf.st_gid);		timep[0] = statbuf.st_atime;		timep[1] = statbuf.st_mtime;		/* Update last accessed and modified times */		utime(ofname, timep);//		if (unlink(ifname))	/* Remove input file *///			perror(ifname);		return;			/* success */	}	/* Unsuccessful return -- one of the tests failed */	if (unlink(ofname))		perror(ofname);}/* * This routine returns 1 if we are running in the foreground and stderr * is a tty. */foreground(){	if(bgnd_flag)			/* background? */		return 0;	else				/* foreground */		return isatty(2);	/* and stderr is a tty */}voidonintr(int x){	unlink(ofname);	exit(1);}voidoops(int x)		/* wild pointer -- assume bad input */{	if (do_decomp == 1)		fprintf(stderr, "uncompress: corrupt input\n");	unlink(ofname);	exit(1);}cl_block ()		/* table clear for block compress */{	long rat;	checkpoint = in_count + CHECK_GAP;#ifdef DEBUG	if ( debug ) {		fprintf ( stderr, "count: %ld, ratio: ", in_count );		prratio ( stderr, in_count, bytes_out );		fprintf ( stderr, "\n");	}#endif /* DEBUG */	if (in_count > 0x007fffff) {	/* shift will overflow */		rat = bytes_out >> 8;		if (rat == 0)		/* Don't divide by zero */			rat = 0x7fffffff;		else			rat = in_count / rat;	} else		rat = (in_count << 8) / bytes_out;	/* 8 fractional bits */	if (rat > ratio)		ratio = rat;	else {		ratio = 0;#ifdef DEBUG		if (verbose)			dump_tab();	/* dump string table */#endif		cl_hash((count_int)hsize);		free_ent = FIRST;		clear_flg = 1;		output((code_int)CLEAR);#ifdef DEBUG		if (debug)			fprintf(stderr, "clear\n");#endif /* DEBUG */	}}cl_hash(hsize)		/* reset code table */count_int hsize;{	count_int *htab_p = htab+hsize;	long i;	long m1 = -1;	i = hsize - 16; 	do {				/* might use Sys V memset(3) here */		*(htab_p-16) = m1;		*(htab_p-15) = m1;		*(htab_p-14) = m1;		*(htab_p-13) = m1;		*(htab_p-12) = m1;		*(htab_p-11) = m1;		*(htab_p-10) = m1;		*(htab_p-9) = m1;		*(htab_p-8) = m1;		*(htab_p-7) = m1;		*(htab_p-6) = m1;		*(htab_p-5) = m1;		*(htab_p-4) = m1;		*(htab_p-3) = m1;		*(htab_p-2) = m1;		*(htab_p-1) = m1;		htab_p -= 16;	} while ((i -= 16) >= 0);	for ( i += 16; i > 0; i-- )		*--htab_p = m1;}prratio(stream, num, den)FILE *stream;long num, den;{	int q;				/* Doesn't need to be long */	if(num > 214748L)		/* 2147483647/10000 */		q = num / (den / 10000L);	else		q = 10000L * num / den;	/* Long calculations, though */	if (q < 0) {		putc('-', stream);		q = -q;	}	fprintf(stream, "%d.%02d%%", q / 100, q % 100);}version(){	fprintf(stderr, "%s\n", rcs_ident);	fprintf(stderr, "Options: ");#ifdef DEBUG	fprintf(stderr, "DEBUG, ");#endif#ifdef BSD4_2	fprintf(stderr, "BSD4_2, ");#endif	fprintf(stderr, "BITS = %d\n", BITS);}/* * The revision-history novel: * * $Header: compress.c,v 4.0 85/07/30 12:50:00 joe Release $ * $Log:	compress.c,v $ * Revision 4.0  85/07/30  12:50:00  joe * Removed ferror() calls in output routine on every output except first. * Prepared for release to the world. * * Revision 3.6  85/07/04  01:22:21  joe * Remove much wasted storage by overlaying hash table with the tables * used by decompress: tab_suffix[1<<BITS], stack[8000].  Updated USERMEM * computations.  Fixed dump_tab() DEBUG routine. * * Revision 3.5  85/06/30  20:47:21  jaw * Change hash function to use exclusive-or.  Rip out hash cache.  These * speedups render the megamemory version defunct, for now.  Make decoder * stack global.  Parts of the RCS trunks 2.7, 2.6, and 2.1 no longer apply. * * Revision 3.4  85/06/27  12:00:00  ken * Get rid of all floating-point calculations by doing all compression ratio * calculations in fixed point. * * Revision 3.3  85/06/24  21:53:24  joe * Incorporate portability suggestion for M_XENIX.  Got rid of text on #else * and #endif lines.  Cleaned up #ifdefs for vax and interdata. * * Revision 3.2  85/06/06  21:53:24  jaw * Incorporate portability suggestions for Z8000, IBM PC/XT from mailing list. * Default to "quiet" output (no compression statistics). * * Revision 3.1  85/05/12  18:56:13  jaw * Integrate decompress() stack speedups (from early pointer mods by McKie). * Repair multi-file USERMEM gaffe.  Unify 'force' flags to mimic semantics * of SVR2 'pack'.  Streamline block-compress table clear logic.  Increase * output byte count by magic number size. * * Revision 3.0	84/11/27  11:50:00  petsd!joe * Set HSIZE depending on BITS.  Set BITS depending on USERMEM.  Unrolled * loops in clear routines.  Added "-C" flag for 2.0 compatibility.  Used * unsigned compares on Perkin-Elmer.  Fixed foreground check. * * Revision 2.7	84/11/16  19:35:39  ames!jaw * Cache common hash codes based on input statistics; this improves * performance for low-density raster images.  Pass on #ifdef bundle * from Turkowski. * * Revision 2.6	84/11/05  19:18:21  ames!jaw * Vary size of hash tables to reduce time for small files. * Tune PDP-11 hash function. * * Revision 2.5	84/10/30  20:15:14  ames!jaw * Junk chaining; replace with the simpler (and, on the VAX, faster) * double hashing, discussed within.  Make block compression standard. * * Revision 2.4	84/10/16  11:11:11  ames!jaw * Introduce adaptive reset for block compression, to boost the rate * another several percent.  (See mailing list notes.) * * Revision 2.3	84/09/22  22:00:00  petsd!joe * Implemented "-B" block compress.  Implemented REVERSE sorting of tab_next. * Bug fix for last bits.  Changed fwrite to putchar loop everywhere. * * Revision 2.2	84/09/18  14:12:21  ames!jaw * Fold in news changes, small machine typedef from thomas, * #ifdef interdata from joe. * * Revision 2.1	84/09/10  12:34:56  ames!jaw * Configured fast table lookup for 32-bit machines. * This cuts user time in half for b <= FBITS, and is useful for news batching * from VAX to PDP sites.  Also sped up decompress() [fwrite->putc] and * added signal catcher [plus beef in writeerr()] to delete effluvia. * * Revision 2.0	84/08/28  22:00:00  petsd!joe * Add check for foreground before prompting user.  Insert maxbits into * compressed file.  Force file being uncompressed to end with ".Z". * Added "-c" flag and "zcat".  Prepared for release. * * Revision 1.10  84/08/24  18:28:00  turtlevax!ken * Will only compress regular files (no directories), added a magic number * header (plus an undocumented -n flag to handle old files without headers), * added -f flag to force overwriting of possibly existing destination file, * otherwise the user is prompted for a response.  Will tack on a .Z to a * filename if it doesn't have one when decompressing.  Will only replace * file if it was compressed. * * Revision 1.9  84/08/16  17:28:00  turtlevax!ken * Removed scanargs(), getopt(), added .Z extension and unlimited number of * filenames to compress.  Flags may be clustered (-Ddvb12) or separated * (-D -d -v -b 12), or combination thereof.  Modes and other status is * copied with copystat().  -O bug for 4.2 seems to have disappeared with * 1.8. * * Revision 1.8  84/08/09  23:15:00  joe * Made it compatible with vax version, installed jim's fixes/enhancements * * Revision 1.6  84/08/01  22:08:00  joe * Sped up algorithm significantly by sorting the compress chain. * * Revision 1.5  84/07/13  13:11:00  srd * Added C version of vax asm routines.  Changed structure to arrays to * save much memory.  Do unsigned compares where possible (faster on * Perkin-Elmer) * * Revision 1.4  84/07/05  03:11:11  thomas * Clean up the code a little and lint it.  (Lint complains about all * the regs used in the asm, but I'm not going to "fix" this.) * * Revision 1.3  84/07/05  02:06:54  thomas * Minor fixes. * * Revision 1.2  84/07/05  00:27:27  thomas * Add variable bit length output. */

⌨️ 快捷键说明

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