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

📄 main.c

📁 source code for arithmatic coding
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************File: 		main.cAuthors: 	John Carpinelli   (johnfc@ecr.mu.oz.au)	 	Wayne Salamonsen  (wbs@mundil.cs.mu.oz.au)		Lang Stuiver      (langs@cs.mu.oz.au)Purpose:	Arithmetic coding data compression driver moduleCopyright 1995 John Carpinelli and Wayne Salamonsen, All Rights Reserved.Copyright 1996 Lang Stuiver.  All rights reserved.These programs are supplied free of charge for research purposes only,and may not sold or incorporated into any commercial product.  There isABSOLUTELY NO WARRANTY of any sort, nor any undertaking that they arefit for ANY PURPOSE WHATSOEVER.  Use them at your own risk.  If you dohappen to find a bug, or have modifications to suggest, please reportthe same to Alistair Moffat, alistair@cs.mu.oz.au.  The copyrightnotice above and this statement of conditions must remain an integralpart of each and every copy made of these files.******************************************************************************Main.c is the main program.  It processes the command line, reads andwrites the initial headers of the compressed files, sets any parametersand runs the appropriate model.It also keeps track of memory usage, to keep it within any specified limitsand report on its usage.******************************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#ifdef SYSV#  include <sys/times.h>#  include <limits.h>#  include <unistd.h>#endif#include "bitio.h"#include "arith.h"#include "stats.h"#include "main.h"/* local function prototypes */static void print_results(int operation, int method);static void usage(char *str1);static void encode_only(char *str1, int selected, char **argv);static int determine_model(char *argv);static int decode_magic(unsigned char *str1);static void describe_setup(int method);#ifdef RCSIDstatic char   rcsid[] = "$Id: main.c,v 1.1 1996/08/07 01:34:11 langs Exp $";#endif/*  * The model list is of type ModelType.  Each model has associated with * it a name, its magic number, an encode and decode function, whether * it dynamically uses memory, and if so, whether it will purge it. * There is also a results function which can be specified to describe * statistics specific to that model after it has run.  It is passed a * variable indicating whether it was run to ENCODE, or to DECODE.  The * magic numbers all start with character 255 (\377) to ensure the * compressed file will not be mistaken for a text file. */typedef struct {   char *name;			/* Name, as selected with -t option	*/   char *magic;			/* Magic number				*/   void (*encode)(void);	/* Encode function			*/   void (*decode)(void);	/* Decode function			*/   int needs_mem;		/* Does it need the -m memory option,	*/				/* and use memory dynamically ?		*/   int purge_mem;		/* If so, does it purge as well?	*/   void (*results)(int);	/* Model specific results function	*/   char *desc;			/* Description of model			*/  } ModelType;ModelType model[] =  {/*	  name		magic		encoder	     decoder, needs_mem, purge *	       results,  description */	{ "char",	"\377" "23c",	encode_char,	decode_char,	0, 0,		NULL,		"Character based model"	},	{ "uint",	"\377" "23n",	encode_uints,	decode_uints,	0, 0,		NULL,		"Binary uint based model (with fake-escape coding)"	},	{ "word",	"\377" "23w",	encode_word,	decode_word,	1, 1,		print_results_word,		"Word based model"	},     	{ "bits",	"\377" "23b",	encode_bits,	decode_bits,	1, 0,		print_results_bits,		"Bit based model"	},	{ NULL,	  	NULL,	NULL,		NULL, 	0, 0, NULL, NULL }  };/* global variables */       int verbose = 0;		/* flag set if stats are to be printed *//* Used by the memory counting section */static int mbytes = DEFAULT_MEM;/* stores no. megabytes allowable for mem */static int total_memory = 0;	/* total memory used by all models */static int peak_memory = 0;	/* Peak usage of total_memory before purge */static int purge_counter=0;	/* counts number of memory purges *//*  * parse command line arguments. Decide whether to decode or encode * and optional memory size. Also replaces stdin with input file */int main(int argc, char *argv[]){	    int i;				/* loop counter */    unsigned char	tempstore[MAGICNO_LENGTH];	/* stores magic no */    char version_str[VERSION_LEN+1];	/* Stores version str read in */    int	selected = -1;			/* whether decoding or encoding */    int method;				/* The coding method used */    int mem_specified = 0;		/* Is '-m' on the command line */    int default_method;    int filename_supplied = 0;    char *modelstr = argv[0];	/* Points to name of string				 * to indicate default compression				 * type.  Normally program name				 *	(word, bits, char)				 */        for (i = 1; i < argc; )     {	if (argv[i][0] == '-') 	{	    switch(argv[i][1]) 	    {	      case 'e':		/* do encode */		selected = ENCODE;		i++;		break;	      case 'd':		/* do decode */		selected = DECODE;		i++;		break;	      case 'm':		/* set memory size */		encode_only("Memory size", selected, argv);		mem_specified = 1;		i++;		if (i>=argc) usage(argv[0]);		mbytes = atoi(argv[i++]);		break;	      case 'v':		/* set verbose flag to print stats */		verbose = 1;		i++;		break;	      case 'f':		/* set number of F bits */		encode_only("Frequency bits", selected, argv);		i++;		if (i>=argc) usage(argv[0]);#ifdef VARY_NBITS		F_bits = atoi(argv[i++]);#else		if (F_bits != atoi(argv[i++]))			{ fprintf(stderr,"Invalid F_bits (-f option): "					 "F_bits fixed at %i\n", F_bits);			  exit(1);			}#endif		break;	      case 'c':		i++;		if (i>=argc) usage(argv[0]);		bits_context = atoi(argv[i++]);		break;	      case 'b':		encode_only("Code bits", selected, argv);		i++;		if (i>=argc) usage(argv[0]);#ifdef VARY_NBITS		B_bits = atoi(argv[i++]);#else		if (B_bits != atoi(argv[i++]))			{ fprintf(stderr, "Invalid B_bits (-b option): "					  "B_bits fixed at %i\n", B_bits);			  exit(1);			}#endif		break;	      case 't':		/* Type of compression, 'progname' */		i++;		if (i>argc) usage(argv[0]);		modelstr=argv[i];		i++;		break;	      default:		/* incorrect args */		usage(argv[0]);	    }	}	else 	{ 	  if (filename_supplied)	   {		fprintf(stderr,"Only one filename can be specified\n");		exit(1);   	   }	  if (freopen(argv[i++], "rb", stdin) == (FILE *)NULL) 	   {	    fprintf(stderr, "%s: cannot read file %s\n",		    argv[0], argv[--i]);	    exit(1);	   }	   filename_supplied = 1;	}    }        /* check if memory limit is within allowable range */     if (mbytes < MIN_MBYTES || mbytes > MAX_MBYTES)    {	fprintf(stderr, "memory limit must be between %d and %d\n", 		MIN_MBYTES, MAX_MBYTES);	exit(1);    }    /* check if B_bits is within allowable range */    if (B_bits < 3 || B_bits > MAX_B_BITS)    {	fprintf(stderr, "number of B_bits must be between %d and %d\n",		3, MAX_B_BITS);	exit(1);    }    /* check if F_bits is within allowable range */    if (F_bits < 1 || F_bits > MAX_F_BITS)    {	fprintf(stderr, "number of f bits must be between %d and %d\n",		1, MAX_F_BITS);	exit(1);    }    if (bits_context < MIN_CONTEXT_BITS || bits_context > MAX_CONTEXT_BITS)    {	fprintf(stderr, "Bits of context must be between %d and %d\n",		MIN_CONTEXT_BITS, MAX_CONTEXT_BITS);	exit(1);    }    if (selected == -1)	usage(argv[0]);    if (selected == ENCODE)					/* do ENCODE */    {	if (B_bits < F_bits + 2)	{ fprintf(stderr, "Code bits must be at least freq bits + 2.\n");	  fprintf(stderr, "(Code bits = %i, freq bits = %i)\n",			B_bits, F_bits);	  exit(1);	}	method = determine_model(modelstr);	/* Encoding method to use */	if (method == -1) method = determine_model(DEFAULT_MODEL);	if (method == -1) method = 0;	/* write magic number to output file */	BITIO_FWRITE(model[method].magic, 1, MAGICNO_LENGTH);	/* Write the version string (excluding terminating \0) */	BITIO_FWRITE(VERSION, 1, VERSION_LEN);	/* store F_bits and B_bits being used in output */	OUTPUT_BYTE(F_bits);	OUTPUT_BYTE(B_bits);	if (model[method].needs_mem)	{	  /* store memory limit being used in output */	  OUTPUT_BYTE(mbytes);	}	if (!model[method].needs_mem && mem_specified)	{	   fprintf(stderr,"This compression method doesn't"		" use the -m option\n");	   usage(argv[0]);	}	if (verbose) describe_setup(method);	model[method].encode();  			/* call ENCODER */    }    else							/* do DECODE */    {	BITIO_FREAD(tempstore, 1, MAGICNO_LENGTH);	method = decode_magic(tempstore);	BITIO_FREAD(version_str, 1, VERSION_LEN);	version_str[VERSION_LEN] = '\0';	if (strcmp(VERSION,version_str) != 0)		{ 		  fprintf(stderr,"Wrong version!\n");		  fprintf(stderr,"This is version %s\n",VERSION);		  fprintf(stderr,"Compression was with version %s\n",				  version_str);		  exit(1);		}        	default_method = determine_model(modelstr);	if (default_method == -1) default_method = method;	/* If decompressing with a different model than user might expect	 * tell them  Eg: running "char -e foo | bits -d" will work,	 * but only because they are both the same program, containing all	 * the models in them, and model "char" is selected instead of "bits"	 * to decompress	 */	if (method != default_method)		fprintf(stderr,"Using method: %s\n",model[method].desc);	/* get number of F_bits and B_bits to be used */#ifdef VARY_NBITS	F_bits = INPUT_BYTE();	B_bits = INPUT_BYTE();#else	{ int f1, b1;		f1 = INPUT_BYTE();		b1 = INPUT_BYTE();	if (F_bits != f1 || B_bits != b1)	 {	  fprintf(stderr, "Differing value for frequency / code bits:\n"	    "This program was compiled with fixed  F_bits=%i, B_bits=%i\n"

⌨️ 快捷键说明

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