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

📄 compress.c

📁 和Unix的compress/uncompress兼容的压缩/解压算法16位程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*@H************************ < COMPRESS utility> ****************************
*   $@(#) compress.c,v 4.3d 90/01/18 03:00:00 don Release ^                 *
*                                                                           *
*   compress : compress.c                                                   *
*              Main and Operating System Independent support functions      *
*                                                                           *
*   port by  : Donald J. Gloistein                                          *
*                                                                           *
*   Source, Documentation, Object Code:                                     *
*   released to Public Domain. This code is ported from compress v4.0       *
*   release joe.                                                            *
*---------------------------  Module Description  --------------------------*
*   The compress program is compatible with the compression/decompression   *
*   used on the Unix systems compress programs.  This is version 4 and      *
*   supports up to 16 bits compression. The porting retained the Unix       *
*   meanings of all options, added a couple for MsDos and modified the      *
*   file name conventions to make more sense.                               *
*                                                                           *
*--------------------------- Implementation Notes --------------------------*
*                                                                           *
*   compiled with : compress.h compress.fns                                 *
*   linked with   : compapi.obj  compusi.obj                                *
*   problems:                                                               *
*              See notes in compress.h for defines needed.                  *
*              It should work now with Xenix                                *
*                                                                           *
*              Check the signal() handler functions in your compiler        *
*              documentation. This code assumes ANSI SYS V compatible       *
*              header and return values. Change as appropriate for your     *
*              compiler and operating system.                               *
*                                                                           *
*              This source compiles properly with Microsoft C compiler      *
*              version 5.1.                                                 *
*                                                                           *
*   CAUTION:   because the program is in modules, make sure you recompile   *
*              all modules if you change the header or a define in the      *
*              compress.c file                                              *
*                                                                           *
* Algorithm from "A Technique for High Performance Data Compression",       *
* Terry A. Welch, IEEE Computer Vol 17, No 6 (June 1984), pp 8-19.          *
*                                                                           *
* Assumptions:                                                              *
*  When filenames are given, replaces with the compressed version           *
*  (.Z suffix) only if the file decreases in size.                          *
* Algorithm:                                                                *
*  Modified Lempel-Ziv method (LZW).  Basically finds common                *
* substrings and replaces them with a variable size code.  This is          *
* deterministic, and can be done on the fly.  Thus, the decompression       *
* procedure needs no input table, but tracks the way the table was built.   *
*                                                                           *
*                                                                           *
*---------------------------      Author(s)        -------------------------*
*     Initials ---- Name ---------------------------------                  *
*      DjG          Donald J. Gloistein                                     *
*                   Plus many others, see rev.hst file for full list        *
*      Dal          Dale A. Schumacher (Sozobon C port)                     *
*      LvR          Lyle V. Rains, many thanks for improved implementation  *
*************************************************************************@H*/

/*@R************************< Revision History >*****************************
*                                                                           *
*   version -- date -- init ---Notes----------------------                  *
*    4.01    08-29-88  DjG    first cut  for 16 bit MsDos version           *
*            09-04-88  DjG    fixed unlink on zcat if interupted.           *
*                             added msdos filename logic and functions      *
*    4.10    10-27-88  DjG  revised API with coding changes by LvR.         *
*    4.10a   10-30-88  DjG  cleaned up code and fixed bug in freeing ptr.   *
*    4.10b   11-01-88  DjG  cleaned up the logic for inpath/outpath         *
*                           Changed the logic to finding the file name      *
*                           Fixed the allocation bug in the api             *
*                           Added some more portability macros              *
*    4.10c   11-04-88  DjG  Changed maxcode from global to static in api.   *
*                           Supplied some library functions for those who   *
*                           don't have them, changed dos usi to use the     *
*                           strrpbrk(). Checked casts in api again. Compiles*
*                           without warnings at pick level 3.               *
*    4.10d   11-25-88  DjG  revised some memory allocation, put more in the *
*                           header file. Corrected some typos.              *
*                           Changed prog_name() to force lower case         *
*                           Corrected bug, no longer unlinks existing file  *
*                           if not enough memory to compress or decompress  *
*            12-06-88  DjG  VERY minor changes for casts and header defines *
*            12-08-88  DjG  Adjusted path separator check in main function  *
*                           Amiga uses split seg because of compiler        *
*            12-09-88  DjG  Debugging done, all defaults now Unix compress  *
*                           defaults, including unlinking input file and    *
*                           acting as a filter. Must use -h option to get   *
*                           help screen.                                    *
*    4.10e   12-11-88  DjG  Fixed more casts, prototypes and header file.   *
*    4.10f   12-12-88  DjG  Fixed unlinking open files on error. This fails *
*                           on shared or os/2 platforms.                    *
*            12-15-88  DjG  Fixed SIGTYPE for function passed to signal     *
*                           Fixed problems with Xenix 2.2.1                 *
*    4.2     12-19-88  DjG  Replaced adaptive reset as an option.           *
*    4.3     12-26-88  DjG  Fixed long file name bug, fixed bug with        *
*                           compressdir. -B option added, same as -b option *
*            05-06-89  Dal  Ported to Sozobon/Alcyon C for Atari ST.  Also, *
*                           created get_one() for console prompting.        *
*            05-08-89  Dal  Ported to Minix-ST                              *
*    4.3a    05-29-89  DjG  Combined source code changes and now compiles   *
*                           on Minix.                                       *
*    4.3b    08-20-89  DjG  Changed the version() to simplify it. Changed   *
*                           the order of testing for linked files           *
*            10-02-89  DjG  Changed the double negative #ifndef NDEBUG      *
*			    to a more logical coding.                       *
*    4.3c    12-25-89  DjG  Fixed pointer bug in error message code         *
*            01-06-90  LvR  Fixed signed expansion on 68000 cpu's           *
*    4.3d    01-18-90  LvR  Fixed problem with token[] overrunning on some  *
*                           files with large amounts of repeating characters*
*************************************************************************@R*/

#include <stdio.h>

#define MAIN        /* header has defining instances of globals */
#include "compress.h" /* contains the rest of the include file declarations */

#define ARGVAL() (*++(*argv) || (--argc && *++argv))
char suffix[] = SUFFIX ;          /* only used in this file */

void main( argc, argv )
register int argc; char **argv;
{
    char **filelist, **fileptr,*temp;
    char response;
    struct stat statbuf;

#ifndef NOSIGNAL
    if ( (bgnd_flag = signal ( SIGINT, SIG_IGN )) != SIG_IGN ) {
        /* ANSI/SYS V compatible */
        /* the following test checks for error on setting signals */
        /* check your documentation on the value to test          */
        /* if your signal.h doesn't support the return, it is     */
        /* essentially a no-op test                               */
        if (bgnd_flag == SIG_ERR){   
            exit_stat = SIGNAL_ERROR;
            check_error();
        }
        if( (signal(SIGINT,onintr) == SIG_ERR)
        || (signal(SIGSEGV,oops) == SIG_ERR)) {/* check your compiler docs. */
            exit_stat = SIGNAL_ERROR;
            check_error();
        }
    }
#endif

    /* set up array for files to be converted */
#ifdef ALLOC
    filelist = fileptr = (char **)(alloc(argc * sizeof(char *)));
#else
    filelist = fileptr = (char **)(malloc(argc * sizeof(char *)));
#endif
    *filelist = NULL;

    /* gets name, compares and sets defaults */
    prog_name = get_program_name(argv[0]);

    /* now parse command line and get file list */
    for (argc--, argv++; argc > 0; argc--, argv++) {
        if (**argv == '-') {        /* A flag argument */
            while (*++(*argv)) {    /* Process all flags in this arg */
                switch (**argv) {
#ifdef DEBUG
                    case 'D':
                        debug = TRUE;
                        keep_error = TRUE;
                        break;
                    case 'V':
                        verbose = TRUE;
                        version();
                        break;
#else
                    case 'V':
                        version();
                        break;
#endif /*DEBUG */
                    case 'v':
                        quiet = FALSE;
                        break;
                    case 'd':
                        do_decomp = TRUE;
                        break;
                    case 'f':
                        force = overwrite = TRUE;
                        break;
                    case 'n':
                        nomagic = TRUE;
                        break;
                    case 'C':
                        block_compress = FALSE;
                        break;
                    case 'b': case 'B':
                        if (!ARGVAL()) {
                            fprintf(stderr, "Missing maxbits\n");
                            Usage(1);
                            exit(ERROR);
                        }
                        maxbits = atoi(*argv);
                        goto nextarg;
                    case 'I':
                        if (!ARGVAL()) {
                            fprintf(stderr, "Missing in_path name\n");
                            Usage(1);
                            exit(ERROR);
                        }
                        strcpy(inpath,*argv);
                        temp = &inpath[strlen(inpath)-1];
#ifdef MSDOS
                        if (*temp != '\\' && *temp != '/')
#else
                        if (*temp != separator[0])
#endif
                            strcat(inpath,separator);
                        goto nextarg;
                    case 'O':
                        if (!ARGVAL()){
                            fprintf(stderr, "Missing out_path name\n");
                            Usage(1);
                            exit(ERROR);
                        }
                        strcpy(outpath,*argv);
                        temp = &outpath[strlen(outpath)-1];
#ifdef MSDOS
                        if (*temp != '\\' && *temp != '/')
#else
                        if (*temp != separator[0])
#endif
                            strcat(outpath,separator);
                        goto nextarg;
                    case 'c':
                        keep = zcat_flg = TRUE;
                        break;
                    case 'K':
                        keep_error = TRUE;
                        break;
                    case 'k':
                        keep = !keep;
                        break;
                    case '?':case 'h':case 'H':
                        Usage(0);
                        exit(NORMAL);
                        break;
                    case 'q':
                        quiet = TRUE;
                        break;
                    default:
                        fprintf(stderr, "%s : Unknown flag: '%c'\n",prog_name, **argv);
                        Usage(1);
                        exit(ERROR);
                } /* end switch */
            } /* end while processing this argument */
        }  /* end if option parameter */
        else {                                  /* must be input file name */
            *fileptr++ = *argv;                 /* Build input file list */
            *fileptr = NULL;
        } /* end else */
nextarg: 	continue;                          /* process nextarg */
    } /* end command line processing */

    /* adjust for possible errors or conflicts */
    if(maxbits < MINBITS || maxbits > MAXBITS){
        fprintf(stderr,"\n%s: illegal bit value, range = %d to %d\n",prog_name,MINBITS,MAXBITS);
        exit(NORMAL);
    }
    if (zcat_flg && *outpath)         /* can't have an out path and zcat */
        *outpath = '\0';

    /* to make the error messages make sense */
    strcpy(ifname,"stdin");
    strcpy(ofname,"stdout");

    if (*filelist) {         /* Check if there are files specified */
                             /* *fileptr must continue to specify  */
                             /* command line in/out file name      */
        is_list = TRUE;
        for (fileptr = filelist; *fileptr; fileptr++) {
            exit_stat = 0;
            endchar[0] = '\0';
            if (do_decomp) {                /* DECOMPRESSION          */
                if (*inpath){               /* adjust for inpath name */
                    strcpy(ifname,inpath);  /* and copy into ifname   */
                    strcat(ifname,name_index(*fileptr));
                }
                else
                    strcpy(ifname,*fileptr);
                if(!is_z_name(ifname))         /* Check for .Z suffix    */
                    if(!(make_z_name(ifname))) /* No .Z: tack one on     */
                        continue;
                                               /* Open input file        */
                if ((freopen(ifname, READ_FILE_TYPE, stdin)) == NULL) {
                    perror(ifname);
                    continue;
                }
                else
                    setvbuf(stdin,zbuf,_IOFBF,ZBUFSIZE);
                if (!nomagic) {             /* Check the magic number */
                    if ((getchar() != (magic_header[0] & 0xFF))
                      || (getchar() != (magic_header[1] & 0xFF))) {
                        fprintf(stderr, "%s: not in compressed format\n",
                            ifname);
                        continue;
                    }
                    maxbits = getchar();    /* set -b from file */
                    block_compress = maxbits & BLOCK_MASK;
                    maxbits &= BIT_MASK;
                    if(maxbits > MAXBITS) {
                        fprintf(stderr,
                        "%s: compressed with %d bits, can only handle %d bits\n",
                        ifname, maxbits, MAXBITS);
                        continue;
                    }
                }  /* end if nomagic */
                                             /* Generate output filename */
                if (*outpath){               /* adjust for outpath name */
                    strcpy(ofname,outpath);  /* and copy into ofname   */
                    strcat(ofname,name_index(ifname));
                }
                else
                    strcpy(ofname,ifname); /* DjG may screw up the placement */
                                           /* of the outfile */

⌨️ 快捷键说明

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