"Fossies" - the Fresh Open Source Software Archive

Member "cfitsio-4.0.0/zuncompress.c" (20 May 2021, 16425 Bytes) of package /linux/misc/cfitsio-4.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "zuncompress.c" see the Fossies "Dox" file reference documentation.

    1 /* gzcompress.h -- definitions for the .Z decompression routine used in CFITSIO */
    2 
    3 #include <stdlib.h>
    4 #include <stdio.h>
    5 #include <string.h>
    6 #include <ctype.h>
    7 
    8 #define get_char() get_byte()
    9 
   10 /* gzip.h -- common declarations for all gzip modules  */
   11 
   12 #define OF(args)  args
   13 typedef void *voidp;
   14 
   15 #define memzero(s, n)     memset ((voidp)(s), 0, (n))
   16 
   17 typedef unsigned char  uch;
   18 typedef unsigned short ush;
   19 typedef unsigned long  ulg;
   20 
   21 /* private version of MIN function */
   22 #define MINZIP(a,b) ((a) <= (b) ? (a) : (b))
   23 
   24 /* Return codes from gzip */
   25 #define OK      0
   26 #define ERROR   1
   27 #define COMPRESSED  1
   28 #define DEFLATED    8
   29 #define INBUFSIZ  0x8000    /* input buffer size */
   30 #define INBUF_EXTRA  64     /* required by unlzw() */
   31 #define OUTBUFSIZ  16384    /* output buffer size */
   32 #define OUTBUF_EXTRA 2048   /* required by unlzw() */
   33 #define DIST_BUFSIZE 0x8000 /* buffer for distances, see trees.c */
   34 #define WSIZE 0x8000        /* window size--must be a power of two, and */
   35 #define DECLARE(type, array, size)  type array[size]
   36 #define tab_suffix window
   37 #define tab_prefix prev    /* hash link (see deflate.c) */
   38 #define head (prev+WSIZE)  /* hash head (see deflate.c) */
   39 #define LZW_MAGIC      "\037\235" /* Magic header for lzw files, 1F 9D */
   40 #define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf(0))
   41 
   42 /* Diagnostic functions */
   43 #  define Assert(cond,msg)
   44 #  define Trace(x)
   45 #  define Tracev(x)
   46 #  define Tracevv(x)
   47 #  define Tracec(c,x)
   48 #  define Tracecv(c,x)
   49 
   50 /* lzw.h -- define the lzw functions. */
   51 
   52 #ifndef BITS
   53 #  define BITS 16
   54 #endif
   55 #define INIT_BITS 9              /* Initial number of bits per code */
   56 #define BIT_MASK    0x1f /* Mask for 'number of compression bits' */
   57 #define BLOCK_MODE  0x80
   58 #define LZW_RESERVED 0x60 /* reserved bits */
   59 #define CLEAR  256       /* flush the dictionary */
   60 #define FIRST  (CLEAR+1) /* first free entry */
   61 
   62 /* prototypes */
   63 
   64 #define local static
   65 void ffpmsg(const char *err_message);
   66 
   67 local int  fill_inbuf    OF((int eof_ok));
   68 local void write_buf     OF((voidp buf, unsigned cnt));
   69 local void error         OF((char *m));
   70 local int unlzw  OF((FILE *in, FILE *out));
   71 
   72 typedef int file_t;     /* Do not use stdio */
   73 
   74 int (*work) OF((FILE *infile, FILE *outfile)) = unlzw; /* function to call */
   75 
   76 local void error         OF((char *m));
   77 
   78         /* global buffers */
   79 
   80 static DECLARE(uch, inbuf,  INBUFSIZ +INBUF_EXTRA);
   81 static DECLARE(uch, outbuf, OUTBUFSIZ+OUTBUF_EXTRA);
   82 static DECLARE(ush, d_buf,  DIST_BUFSIZE);
   83 static DECLARE(uch, window, 2L*WSIZE);
   84 
   85 #ifndef MAXSEG_64K
   86     static DECLARE(ush, tab_prefix, 1L<<BITS);
   87 #else
   88     static DECLARE(ush, tab_prefix0, 1L<<(BITS-1));
   89     static DECLARE(ush, tab_prefix1, 1L<<(BITS-1));
   90 #endif
   91 
   92         /* local variables */
   93 
   94 /* 11/25/98: added 'static' to local variable definitions, to avoid */
   95 /* conflict with external source files */
   96 
   97 static int maxbits = BITS;   /* max bits per code for LZW */
   98 static int method = DEFLATED;/* compression method */
   99 static int exit_code = OK;   /* program exit code */
  100 static int last_member;      /* set for .zip and .Z files */
  101 static long bytes_in;             /* number of input bytes */
  102 static long bytes_out;            /* number of output bytes */
  103 static char ifname[128];          /* input file name */
  104 static FILE *ifd;               /* input file descriptor */
  105 static FILE *ofd;               /* output file descriptor */
  106 static void **memptr;          /* memory location for uncompressed file */
  107 static size_t *memsize;        /* size (bytes) of memory allocated for file */
  108 void *(*realloc_fn)(void *p, size_t newsize);  /* reallocation function */
  109 static unsigned insize;     /* valid bytes in inbuf */
  110 static unsigned inptr;      /* index of next byte to be processed in inbuf */
  111 
  112 /* prototype for the following functions */
  113 int zuncompress2mem(char *filename, 
  114              FILE *diskfile, 
  115              char **buffptr, 
  116              size_t *buffsize, 
  117              void *(*mem_realloc)(void *p, size_t newsize),
  118              size_t *filesize,
  119              int *status);
  120 
  121 /*--------------------------------------------------------------------------*/
  122 int zuncompress2mem(char *filename,  /* name of input file                 */
  123              FILE *indiskfile,     /* I - file pointer                        */
  124              char **buffptr,   /* IO - memory pointer                     */
  125              size_t *buffsize,   /* IO - size of buffer, in bytes           */
  126              void *(*mem_realloc)(void *p, size_t newsize), /* function     */
  127              size_t *filesize,   /* O - size of file, in bytes              */
  128              int *status)        /* IO - error status                       */
  129 
  130 /*
  131   Uncompress the file into memory.  Fill whatever amount of memory has
  132   already been allocated, then realloc more memory, using the supplied
  133   input function, if necessary.
  134 */
  135 {
  136     char magic[2]; /* magic header */
  137 
  138     if (*status > 0)
  139         return(*status);
  140 
  141     /*  save input parameters into global variables */
  142     ifname[0] = '\0';
  143     strncat(ifname, filename, 127);
  144     ifd = indiskfile;
  145     memptr = (void **) buffptr;
  146     memsize = buffsize;
  147     realloc_fn = mem_realloc;
  148 
  149     /* clear input and output buffers */
  150 
  151     insize = inptr = 0;
  152     bytes_in = bytes_out = 0L;
  153 
  154     magic[0] = (char)get_byte();
  155     magic[1] = (char)get_byte();
  156 
  157     if (memcmp(magic, LZW_MAGIC, 2) != 0) {
  158       error("ERROR: input .Z file is in unrecognized compression format.\n");
  159       return(-1);
  160     }
  161 
  162     work = unlzw;
  163     method = COMPRESSED;
  164     last_member = 1;
  165 
  166     /* do the uncompression */
  167     if ((*work)(ifd, ofd) != OK) {
  168         method = -1; /* force cleanup */
  169         *status = 414;    /* report some sort of decompression error */
  170     }
  171 
  172     if (filesize)  *filesize = bytes_out;
  173 
  174     return(*status);
  175 }
  176 /*=========================================================================*/
  177 /*=========================================================================*/
  178 /* this marks the begining of the original file 'unlzw.c'                  */
  179 /*=========================================================================*/
  180 /*=========================================================================*/
  181 
  182 /* unlzw.c -- decompress files in LZW format.
  183  * The code in this file is directly derived from the public domain 'compress'
  184  * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
  185  * Ken Turkowski, Dave Mack and Peter Jannesen.
  186  */
  187 
  188 typedef unsigned char   char_type;
  189 typedef          long   code_int;
  190 typedef unsigned long   count_int;
  191 typedef unsigned short  count_short;
  192 typedef unsigned long   cmp_code_int;
  193 
  194 #define MAXCODE(n)  (1L << (n))
  195     
  196 #ifndef REGISTERS
  197 #   define  REGISTERS   2
  198 #endif
  199 #define REG1    
  200 #define REG2    
  201 #define REG3    
  202 #define REG4    
  203 #define REG5    
  204 #define REG6    
  205 #define REG7    
  206 #define REG8    
  207 #define REG9    
  208 #define REG10
  209 #define REG11   
  210 #define REG12   
  211 #define REG13
  212 #define REG14
  213 #define REG15
  214 #define REG16
  215 #if REGISTERS >= 1
  216 #   undef   REG1
  217 #   define  REG1    register
  218 #endif
  219 #if REGISTERS >= 2
  220 #   undef   REG2
  221 #   define  REG2    register
  222 #endif
  223 #if REGISTERS >= 3
  224 #   undef   REG3
  225 #   define  REG3    register
  226 #endif
  227 #if REGISTERS >= 4
  228 #   undef   REG4
  229 #   define  REG4    register
  230 #endif
  231 #if REGISTERS >= 5
  232 #   undef   REG5
  233 #   define  REG5    register
  234 #endif
  235 #if REGISTERS >= 6
  236 #   undef   REG6
  237 #   define  REG6    register
  238 #endif
  239 #if REGISTERS >= 7
  240 #   undef   REG7
  241 #   define  REG7    register
  242 #endif
  243 #if REGISTERS >= 8
  244 #   undef   REG8
  245 #   define  REG8    register
  246 #endif
  247 #if REGISTERS >= 9
  248 #   undef   REG9
  249 #   define  REG9    register
  250 #endif
  251 #if REGISTERS >= 10
  252 #   undef   REG10
  253 #   define  REG10   register
  254 #endif
  255 #if REGISTERS >= 11
  256 #   undef   REG11
  257 #   define  REG11   register
  258 #endif
  259 #if REGISTERS >= 12
  260 #   undef   REG12
  261 #   define  REG12   register
  262 #endif
  263 #if REGISTERS >= 13
  264 #   undef   REG13
  265 #   define  REG13   register
  266 #endif
  267 #if REGISTERS >= 14
  268 #   undef   REG14
  269 #   define  REG14   register
  270 #endif
  271 #if REGISTERS >= 15
  272 #   undef   REG15
  273 #   define  REG15   register
  274 #endif
  275 #if REGISTERS >= 16
  276 #   undef   REG16
  277 #   define  REG16   register
  278 #endif
  279     
  280 #ifndef BYTEORDER
  281 #   define  BYTEORDER   0000
  282 #endif
  283     
  284 #ifndef NOALLIGN
  285 #   define  NOALLIGN    0
  286 #endif
  287 
  288 
  289 union   bytes {
  290     long  word;
  291     struct {
  292 #if BYTEORDER == 4321
  293     char_type   b1;
  294     char_type   b2;
  295     char_type   b3;
  296     char_type   b4;
  297 #else
  298 #if BYTEORDER == 1234
  299     char_type   b4;
  300     char_type   b3;
  301     char_type   b2;
  302     char_type   b1;
  303 #else
  304 #   undef   BYTEORDER
  305     int  dummy;
  306 #endif
  307 #endif
  308     } bytes;
  309 };
  310 
  311 #if BYTEORDER == 4321 && NOALLIGN == 1
  312 #  define input(b,o,c,n,m){ \
  313      (c) = (*(long *)(&(b)[(o)>>3])>>((o)&0x7))&(m); \
  314      (o) += (n); \
  315    }
  316 #else
  317 #  define input(b,o,c,n,m){ \
  318      REG1 char_type *p = &(b)[(o)>>3]; \
  319      (c) = ((((long)(p[0]))|((long)(p[1])<<8)| \
  320      ((long)(p[2])<<16))>>((o)&0x7))&(m); \
  321      (o) += (n); \
  322    }
  323 #endif
  324 
  325 #ifndef MAXSEG_64K
  326    /* DECLARE(ush, tab_prefix, (1<<BITS)); -- prefix code */
  327 #  define tab_prefixof(i) tab_prefix[i]
  328 #  define clear_tab_prefixof()  memzero(tab_prefix, 256);
  329 #else
  330    /* DECLARE(ush, tab_prefix0, (1<<(BITS-1)); -- prefix for even codes */
  331    /* DECLARE(ush, tab_prefix1, (1<<(BITS-1)); -- prefix for odd  codes */
  332    ush *tab_prefix[2];
  333 #  define tab_prefixof(i) tab_prefix[(i)&1][(i)>>1]
  334 #  define clear_tab_prefixof()  \
  335       memzero(tab_prefix0, 128), \
  336       memzero(tab_prefix1, 128);
  337 #endif
  338 #define de_stack        ((char_type *)(&d_buf[DIST_BUFSIZE-1]))
  339 #define tab_suffixof(i) tab_suffix[i]
  340 
  341 int block_mode = BLOCK_MODE; /* block compress mode -C compatible with 2.0 */
  342 
  343 /* ============================================================================
  344  * Decompress in to out.  This routine adapts to the codes in the
  345  * file building the "string" table on-the-fly; requiring no table to
  346  * be stored in the compressed file.
  347  * IN assertions: the buffer inbuf contains already the beginning of
  348  *   the compressed data, from offsets iptr to insize-1 included.
  349  *   The magic header has already been checked and skipped.
  350  *   bytes_in and bytes_out have been initialized.
  351  */
  352 local int unlzw(FILE *in, FILE *out) 
  353     /* input and output file descriptors */
  354 {
  355     REG2   char_type  *stackp;
  356     REG3   code_int   code;
  357     REG4   int        finchar;
  358     REG5   code_int   oldcode;
  359     REG6   code_int   incode;
  360     REG7   long       inbits;
  361     REG8   long       posbits;
  362     REG9   int        outpos;
  363 /*  REG10  int        insize; (global) */
  364     REG11  unsigned   bitmask;
  365     REG12  code_int   free_ent;
  366     REG13  code_int   maxcode;
  367     REG14  code_int   maxmaxcode;
  368     REG15  int        n_bits;
  369     REG16  int        rsize;
  370     
  371     ofd = out;
  372 
  373 #ifdef MAXSEG_64K
  374     tab_prefix[0] = tab_prefix0;
  375     tab_prefix[1] = tab_prefix1;
  376 #endif
  377     maxbits = get_byte();
  378     block_mode = maxbits & BLOCK_MODE;
  379     if ((maxbits & LZW_RESERVED) != 0) {
  380     error( "warning, unknown flags in unlzw decompression");
  381     }
  382     maxbits &= BIT_MASK;
  383     maxmaxcode = MAXCODE(maxbits);
  384     
  385     if (maxbits > BITS) {
  386     error("compressed with too many bits; cannot handle file");
  387     exit_code = ERROR;
  388     return ERROR;
  389     }
  390     rsize = insize;
  391     maxcode = MAXCODE(n_bits = INIT_BITS)-1;
  392     bitmask = (1<<n_bits)-1;
  393     oldcode = -1;
  394     finchar = 0;
  395     outpos = 0;
  396     posbits = inptr<<3;
  397 
  398     free_ent = ((block_mode) ? FIRST : 256);
  399     
  400     clear_tab_prefixof(); /* Initialize the first 256 entries in the table. */
  401     
  402     for (code = 255 ; code >= 0 ; --code) {
  403     tab_suffixof(code) = (char_type)code;
  404     }
  405     do {
  406     REG1 int i;
  407     int  e;
  408     int  o;
  409     
  410     resetbuf:
  411     e = insize-(o = (posbits>>3));
  412     
  413     for (i = 0 ; i < e ; ++i) {
  414         inbuf[i] = inbuf[i+o];
  415     }
  416     insize = e;
  417     posbits = 0;
  418     
  419     if (insize < INBUF_EXTRA) {
  420 /*  modified to use fread instead of read - WDP 10/22/97  */
  421 /*      if ((rsize = read(in, (char*)inbuf+insize, INBUFSIZ)) == EOF) { */
  422 
  423         if ((rsize = fread((char*)inbuf+insize, 1, INBUFSIZ, in)) == EOF) {
  424         error("unexpected end of file");
  425             exit_code = ERROR;
  426                 return ERROR;
  427         }
  428         insize += rsize;
  429         bytes_in += (ulg)rsize;
  430     }
  431     inbits = ((rsize != 0) ? ((long)insize - insize%n_bits)<<3 : 
  432           ((long)insize<<3)-(n_bits-1));
  433     
  434     while (inbits > posbits) {
  435         if (free_ent > maxcode) {
  436         posbits = ((posbits-1) +
  437                ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3)));
  438         ++n_bits;
  439         if (n_bits == maxbits) {
  440             maxcode = maxmaxcode;
  441         } else {
  442             maxcode = MAXCODE(n_bits)-1;
  443         }
  444         bitmask = (1<<n_bits)-1;
  445         goto resetbuf;
  446         }
  447         input(inbuf,posbits,code,n_bits,bitmask);
  448         Tracev((stderr, "%d ", code));
  449 
  450         if (oldcode == -1) {
  451         if (code >= 256) {
  452                     error("corrupt input.");
  453                 exit_code = ERROR;
  454                     return ERROR;
  455                 }
  456 
  457         outbuf[outpos++] = (char_type)(finchar = (int)(oldcode=code));
  458         continue;
  459         }
  460         if (code == CLEAR && block_mode) {
  461         clear_tab_prefixof();
  462         free_ent = FIRST - 1;
  463         posbits = ((posbits-1) +
  464                ((n_bits<<3)-(posbits-1+(n_bits<<3))%(n_bits<<3)));
  465         maxcode = MAXCODE(n_bits = INIT_BITS)-1;
  466         bitmask = (1<<n_bits)-1;
  467         goto resetbuf;
  468         }
  469         incode = code;
  470         stackp = de_stack;
  471         
  472         if (code >= free_ent) { /* Special case for KwKwK string. */
  473         if (code > free_ent) {
  474             if (outpos > 0) {
  475             write_buf((char*)outbuf, outpos);
  476             bytes_out += (ulg)outpos;
  477             }
  478             error("corrupt input.");
  479                 exit_code = ERROR;
  480                     return ERROR;
  481 
  482         }
  483         *--stackp = (char_type)finchar;
  484         code = oldcode;
  485         }
  486 
  487         while ((cmp_code_int)code >= (cmp_code_int)256) {
  488         /* Generate output characters in reverse order */
  489         *--stackp = tab_suffixof(code);
  490         code = tab_prefixof(code);
  491         }
  492         *--stackp = (char_type)(finchar = tab_suffixof(code));
  493         
  494         /* And put them out in forward order */
  495         {
  496     /*  REG1 int    i;   already defined above (WDP) */
  497         
  498         if (outpos+(i = (de_stack-stackp)) >= OUTBUFSIZ) {
  499             do {
  500             if (i > OUTBUFSIZ-outpos) i = OUTBUFSIZ-outpos;
  501 
  502             if (i > 0) {
  503                 memcpy(outbuf+outpos, stackp, i);
  504                 outpos += i;
  505             }
  506             if (outpos >= OUTBUFSIZ) {
  507                 write_buf((char*)outbuf, outpos);
  508                 bytes_out += (ulg)outpos;
  509                 outpos = 0;
  510             }
  511             stackp+= i;
  512             } while ((i = (de_stack-stackp)) > 0);
  513         } else {
  514             memcpy(outbuf+outpos, stackp, i);
  515             outpos += i;
  516         }
  517         }
  518 
  519         if ((code = free_ent) < maxmaxcode) { /* Generate the new entry. */
  520 
  521         tab_prefixof(code) = (unsigned short)oldcode;
  522         tab_suffixof(code) = (char_type)finchar;
  523         free_ent = code+1;
  524         } 
  525         oldcode = incode;   /* Remember previous code.  */
  526     }
  527     } while (rsize != 0);
  528     
  529     if (outpos > 0) {
  530     write_buf((char*)outbuf, outpos);
  531     bytes_out += (ulg)outpos;
  532     }
  533     return OK;
  534 }
  535 /* ========================================================================*/
  536 /* this marks the start of the code from 'util.c'  */
  537 
  538 local int fill_inbuf(int eof_ok)
  539          /* set if EOF acceptable as a result */
  540 {
  541     int len;
  542 
  543       /* Read as much as possible from file */
  544       insize = 0;
  545       do {
  546         len = fread((char*)inbuf+insize, 1, INBUFSIZ-insize, ifd);
  547         if (len == 0 || len == EOF) break;
  548     insize += len;
  549       } while (insize < INBUFSIZ);
  550 
  551     if (insize == 0) {
  552     if (eof_ok) return EOF;
  553     error("unexpected end of file");
  554         exit_code = ERROR;
  555         return ERROR;
  556     }
  557 
  558     bytes_in += (ulg)insize;
  559     inptr = 1;
  560     return inbuf[0];
  561 }
  562 /* =========================================================================== */
  563 local void write_buf(voidp buf, unsigned cnt)
  564 /*              copy buffer into memory; allocate more memory if required*/
  565 {
  566     if (!realloc_fn)
  567     {
  568       /* append buffer to file */
  569       /* added 'unsigned' to get rid of compiler warning (WDP 1/1/99) */
  570       if ((unsigned long) fwrite(buf, 1, cnt, ofd) != cnt)
  571       {
  572           error
  573           ("failed to write buffer to uncompressed output file (write_buf)");
  574           exit_code = ERROR;
  575           return;
  576       }
  577     }
  578     else
  579     {
  580       /* get more memory if current buffer is too small */
  581       if (bytes_out + cnt > *memsize)
  582       {
  583         *memptr = realloc_fn(*memptr, bytes_out + cnt);
  584         *memsize = bytes_out + cnt;  /* new memory buffer size */
  585 
  586         if (!(*memptr))
  587         {
  588             error("malloc failed while uncompressing (write_buf)");
  589             exit_code = ERROR;
  590             return;
  591         }  
  592       }
  593       /* copy  into memory buffer */
  594       memcpy((char *) *memptr + bytes_out, (char *) buf, cnt);
  595     }
  596 }
  597 /* ======================================================================== */
  598 local void error(char *m)
  599 /*                Error handler */
  600 {
  601     ffpmsg(ifname);
  602     ffpmsg(m);
  603 }