• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

contrib/zlib/contrib/infback9/infback9.c

00001 /* infback9.c -- inflate deflate64 data using a call-back interface
00002  * Copyright (C) 1995-2008 Mark Adler
00003  * For conditions of distribution and use, see copyright notice in zlib.h
00004  */
00005 
00006 #include "zutil.h"
00007 #include "infback9.h"
00008 #include "inftree9.h"
00009 #include "inflate9.h"
00010 
00011 #define WSIZE 65536UL
00012 
00013 /*
00014    strm provides memory allocation functions in zalloc and zfree, or
00015    Z_NULL to use the library memory allocation functions.
00016 
00017    window is a user-supplied window and output buffer that is 64K bytes.
00018  */
00019 int ZEXPORT inflateBack9Init_(strm, window, version, stream_size)
00020 z_stream FAR *strm;
00021 unsigned char FAR *window;
00022 const char *version;
00023 int stream_size;
00024 {
00025     struct inflate_state FAR *state;
00026 
00027     if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
00028         stream_size != (int)(sizeof(z_stream)))
00029         return Z_VERSION_ERROR;
00030     if (strm == Z_NULL || window == Z_NULL)
00031         return Z_STREAM_ERROR;
00032     strm->msg = Z_NULL;                 /* in case we return an error */
00033     if (strm->zalloc == (alloc_func)0) {
00034         strm->zalloc = zcalloc;
00035         strm->opaque = (voidpf)0;
00036     }
00037     if (strm->zfree == (free_func)0) strm->zfree = zcfree;
00038     state = (struct inflate_state FAR *)ZALLOC(strm, 1,
00039                                                sizeof(struct inflate_state));
00040     if (state == Z_NULL) return Z_MEM_ERROR;
00041     Tracev((stderr, "inflate: allocated\n"));
00042     strm->state = (voidpf)state;
00043     state->window = window;
00044     return Z_OK;
00045 }
00046 
00047 /*
00048    Build and output length and distance decoding tables for fixed code
00049    decoding.
00050  */
00051 #ifdef MAKEFIXED
00052 #include <stdio.h>
00053 
00054 void makefixed9(void)
00055 {
00056     unsigned sym, bits, low, size;
00057     code *next, *lenfix, *distfix;
00058     struct inflate_state state;
00059     code fixed[544];
00060 
00061     /* literal/length table */
00062     sym = 0;
00063     while (sym < 144) state.lens[sym++] = 8;
00064     while (sym < 256) state.lens[sym++] = 9;
00065     while (sym < 280) state.lens[sym++] = 7;
00066     while (sym < 288) state.lens[sym++] = 8;
00067     next = fixed;
00068     lenfix = next;
00069     bits = 9;
00070     inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work);
00071 
00072     /* distance table */
00073     sym = 0;
00074     while (sym < 32) state.lens[sym++] = 5;
00075     distfix = next;
00076     bits = 5;
00077     inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work);
00078 
00079     /* write tables */
00080     puts("    /* inffix9.h -- table for decoding deflate64 fixed codes");
00081     puts("     * Generated automatically by makefixed9().");
00082     puts("     */");
00083     puts("");
00084     puts("    /* WARNING: this file should *not* be used by applications.");
00085     puts("       It is part of the implementation of this library and is");
00086     puts("       subject to change. Applications should only use zlib.h.");
00087     puts("     */");
00088     puts("");
00089     size = 1U << 9;
00090     printf("    static const code lenfix[%u] = {", size);
00091     low = 0;
00092     for (;;) {
00093         if ((low % 6) == 0) printf("\n        ");
00094         printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits,
00095                lenfix[low].val);
00096         if (++low == size) break;
00097         putchar(',');
00098     }
00099     puts("\n    };");
00100     size = 1U << 5;
00101     printf("\n    static const code distfix[%u] = {", size);
00102     low = 0;
00103     for (;;) {
00104         if ((low % 5) == 0) printf("\n        ");
00105         printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits,
00106                distfix[low].val);
00107         if (++low == size) break;
00108         putchar(',');
00109     }
00110     puts("\n    };");
00111 }
00112 #endif /* MAKEFIXED */
00113 
00114 /* Macros for inflateBack(): */
00115 
00116 /* Clear the input bit accumulator */
00117 #define INITBITS() \
00118     do { \
00119         hold = 0; \
00120         bits = 0; \
00121     } while (0)
00122 
00123 /* Assure that some input is available.  If input is requested, but denied,
00124    then return a Z_BUF_ERROR from inflateBack(). */
00125 #define PULL() \
00126     do { \
00127         if (have == 0) { \
00128             have = in(in_desc, &next); \
00129             if (have == 0) { \
00130                 next = Z_NULL; \
00131                 ret = Z_BUF_ERROR; \
00132                 goto inf_leave; \
00133             } \
00134         } \
00135     } while (0)
00136 
00137 /* Get a byte of input into the bit accumulator, or return from inflateBack()
00138    with an error if there is no input available. */
00139 #define PULLBYTE() \
00140     do { \
00141         PULL(); \
00142         have--; \
00143         hold += (unsigned long)(*next++) << bits; \
00144         bits += 8; \
00145     } while (0)
00146 
00147 /* Assure that there are at least n bits in the bit accumulator.  If there is
00148    not enough available input to do that, then return from inflateBack() with
00149    an error. */
00150 #define NEEDBITS(n) \
00151     do { \
00152         while (bits < (unsigned)(n)) \
00153             PULLBYTE(); \
00154     } while (0)
00155 
00156 /* Return the low n bits of the bit accumulator (n <= 16) */
00157 #define BITS(n) \
00158     ((unsigned)hold & ((1U << (n)) - 1))
00159 
00160 /* Remove n bits from the bit accumulator */
00161 #define DROPBITS(n) \
00162     do { \
00163         hold >>= (n); \
00164         bits -= (unsigned)(n); \
00165     } while (0)
00166 
00167 /* Remove zero to seven bits as needed to go to a byte boundary */
00168 #define BYTEBITS() \
00169     do { \
00170         hold >>= bits & 7; \
00171         bits -= bits & 7; \
00172     } while (0)
00173 
00174 /* Assure that some output space is available, by writing out the window
00175    if it's full.  If the write fails, return from inflateBack() with a
00176    Z_BUF_ERROR. */
00177 #define ROOM() \
00178     do { \
00179         if (left == 0) { \
00180             put = window; \
00181             left = WSIZE; \
00182             wrap = 1; \
00183             if (out(out_desc, put, (unsigned)left)) { \
00184                 ret = Z_BUF_ERROR; \
00185                 goto inf_leave; \
00186             } \
00187         } \
00188     } while (0)
00189 
00190 /*
00191    strm provides the memory allocation functions and window buffer on input,
00192    and provides information on the unused input on return.  For Z_DATA_ERROR
00193    returns, strm will also provide an error message.
00194 
00195    in() and out() are the call-back input and output functions.  When
00196    inflateBack() needs more input, it calls in().  When inflateBack() has
00197    filled the window with output, or when it completes with data in the
00198    window, it calls out() to write out the data.  The application must not
00199    change the provided input until in() is called again or inflateBack()
00200    returns.  The application must not change the window/output buffer until
00201    inflateBack() returns.
00202 
00203    in() and out() are called with a descriptor parameter provided in the
00204    inflateBack() call.  This parameter can be a structure that provides the
00205    information required to do the read or write, as well as accumulated
00206    information on the input and output such as totals and check values.
00207 
00208    in() should return zero on failure.  out() should return non-zero on
00209    failure.  If either in() or out() fails, than inflateBack() returns a
00210    Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
00211    was in() or out() that caused in the error.  Otherwise,  inflateBack()
00212    returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
00213    error, or Z_MEM_ERROR if it could not allocate memory for the state.
00214    inflateBack() can also return Z_STREAM_ERROR if the input parameters
00215    are not correct, i.e. strm is Z_NULL or the state was not initialized.
00216  */
00217 int ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc)
00218 z_stream FAR *strm;
00219 in_func in;
00220 void FAR *in_desc;
00221 out_func out;
00222 void FAR *out_desc;
00223 {
00224     struct inflate_state FAR *state;
00225     unsigned char FAR *next;    /* next input */
00226     unsigned char FAR *put;     /* next output */
00227     unsigned have;              /* available input */
00228     unsigned long left;         /* available output */
00229     inflate_mode mode;          /* current inflate mode */
00230     int lastblock;              /* true if processing last block */
00231     int wrap;                   /* true if the window has wrapped */
00232     unsigned long write;        /* window write index */
00233     unsigned char FAR *window;  /* allocated sliding window, if needed */
00234     unsigned long hold;         /* bit buffer */
00235     unsigned bits;              /* bits in bit buffer */
00236     unsigned extra;             /* extra bits needed */
00237     unsigned long length;       /* literal or length of data to copy */
00238     unsigned long offset;       /* distance back to copy string from */
00239     unsigned long copy;         /* number of stored or match bytes to copy */
00240     unsigned char FAR *from;    /* where to copy match bytes from */
00241     code const FAR *lencode;    /* starting table for length/literal codes */
00242     code const FAR *distcode;   /* starting table for distance codes */
00243     unsigned lenbits;           /* index bits for lencode */
00244     unsigned distbits;          /* index bits for distcode */
00245     code here;                  /* current decoding table entry */
00246     code last;                  /* parent table entry */
00247     unsigned len;               /* length to copy for repeats, bits to drop */
00248     int ret;                    /* return code */
00249     static const unsigned short order[19] = /* permutation of code lengths */
00250         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
00251 #include "inffix9.h"
00252 
00253     /* Check that the strm exists and that the state was initialized */
00254     if (strm == Z_NULL || strm->state == Z_NULL)
00255         return Z_STREAM_ERROR;
00256     state = (struct inflate_state FAR *)strm->state;
00257 
00258     /* Reset the state */
00259     strm->msg = Z_NULL;
00260     mode = TYPE;
00261     lastblock = 0;
00262     write = 0;
00263     wrap = 0;
00264     window = state->window;
00265     next = strm->next_in;
00266     have = next != Z_NULL ? strm->avail_in : 0;
00267     hold = 0;
00268     bits = 0;
00269     put = window;
00270     left = WSIZE;
00271     lencode = Z_NULL;
00272     distcode = Z_NULL;
00273 
00274     /* Inflate until end of block marked as last */
00275     for (;;)
00276         switch (mode) {
00277         case TYPE:
00278             /* determine and dispatch block type */
00279             if (lastblock) {
00280                 BYTEBITS();
00281                 mode = DONE;
00282                 break;
00283             }
00284             NEEDBITS(3);
00285             lastblock = BITS(1);
00286             DROPBITS(1);
00287             switch (BITS(2)) {
00288             case 0:                             /* stored block */
00289                 Tracev((stderr, "inflate:     stored block%s\n",
00290                         lastblock ? " (last)" : ""));
00291                 mode = STORED;
00292                 break;
00293             case 1:                             /* fixed block */
00294                 lencode = lenfix;
00295                 lenbits = 9;
00296                 distcode = distfix;
00297                 distbits = 5;
00298                 Tracev((stderr, "inflate:     fixed codes block%s\n",
00299                         lastblock ? " (last)" : ""));
00300                 mode = LEN;                     /* decode codes */
00301                 break;
00302             case 2:                             /* dynamic block */
00303                 Tracev((stderr, "inflate:     dynamic codes block%s\n",
00304                         lastblock ? " (last)" : ""));
00305                 mode = TABLE;
00306                 break;
00307             case 3:
00308                 strm->msg = (char *)"invalid block type";
00309                 mode = BAD;
00310             }
00311             DROPBITS(2);
00312             break;
00313 
00314         case STORED:
00315             /* get and verify stored block length */
00316             BYTEBITS();                         /* go to byte boundary */
00317             NEEDBITS(32);
00318             if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
00319                 strm->msg = (char *)"invalid stored block lengths";
00320                 mode = BAD;
00321                 break;
00322             }
00323             length = (unsigned)hold & 0xffff;
00324             Tracev((stderr, "inflate:       stored length %lu\n",
00325                     length));
00326             INITBITS();
00327 
00328             /* copy stored block from input to output */
00329             while (length != 0) {
00330                 copy = length;
00331                 PULL();
00332                 ROOM();
00333                 if (copy > have) copy = have;
00334                 if (copy > left) copy = left;
00335                 zmemcpy(put, next, copy);
00336                 have -= copy;
00337                 next += copy;
00338                 left -= copy;
00339                 put += copy;
00340                 length -= copy;
00341             }
00342             Tracev((stderr, "inflate:       stored end\n"));
00343             mode = TYPE;
00344             break;
00345 
00346         case TABLE:
00347             /* get dynamic table entries descriptor */
00348             NEEDBITS(14);
00349             state->nlen = BITS(5) + 257;
00350             DROPBITS(5);
00351             state->ndist = BITS(5) + 1;
00352             DROPBITS(5);
00353             state->ncode = BITS(4) + 4;
00354             DROPBITS(4);
00355             if (state->nlen > 286) {
00356                 strm->msg = (char *)"too many length symbols";
00357                 mode = BAD;
00358                 break;
00359             }
00360             Tracev((stderr, "inflate:       table sizes ok\n"));
00361 
00362             /* get code length code lengths (not a typo) */
00363             state->have = 0;
00364             while (state->have < state->ncode) {
00365                 NEEDBITS(3);
00366                 state->lens[order[state->have++]] = (unsigned short)BITS(3);
00367                 DROPBITS(3);
00368             }
00369             while (state->have < 19)
00370                 state->lens[order[state->have++]] = 0;
00371             state->next = state->codes;
00372             lencode = (code const FAR *)(state->next);
00373             lenbits = 7;
00374             ret = inflate_table9(CODES, state->lens, 19, &(state->next),
00375                                 &(lenbits), state->work);
00376             if (ret) {
00377                 strm->msg = (char *)"invalid code lengths set";
00378                 mode = BAD;
00379                 break;
00380             }
00381             Tracev((stderr, "inflate:       code lengths ok\n"));
00382 
00383             /* get length and distance code code lengths */
00384             state->have = 0;
00385             while (state->have < state->nlen + state->ndist) {
00386                 for (;;) {
00387                     here = lencode[BITS(lenbits)];
00388                     if ((unsigned)(here.bits) <= bits) break;
00389                     PULLBYTE();
00390                 }
00391                 if (here.val < 16) {
00392                     NEEDBITS(here.bits);
00393                     DROPBITS(here.bits);
00394                     state->lens[state->have++] = here.val;
00395                 }
00396                 else {
00397                     if (here.val == 16) {
00398                         NEEDBITS(here.bits + 2);
00399                         DROPBITS(here.bits);
00400                         if (state->have == 0) {
00401                             strm->msg = (char *)"invalid bit length repeat";
00402                             mode = BAD;
00403                             break;
00404                         }
00405                         len = (unsigned)(state->lens[state->have - 1]);
00406                         copy = 3 + BITS(2);
00407                         DROPBITS(2);
00408                     }
00409                     else if (here.val == 17) {
00410                         NEEDBITS(here.bits + 3);
00411                         DROPBITS(here.bits);
00412                         len = 0;
00413                         copy = 3 + BITS(3);
00414                         DROPBITS(3);
00415                     }
00416                     else {
00417                         NEEDBITS(here.bits + 7);
00418                         DROPBITS(here.bits);
00419                         len = 0;
00420                         copy = 11 + BITS(7);
00421                         DROPBITS(7);
00422                     }
00423                     if (state->have + copy > state->nlen + state->ndist) {
00424                         strm->msg = (char *)"invalid bit length repeat";
00425                         mode = BAD;
00426                         break;
00427                     }
00428                     while (copy--)
00429                         state->lens[state->have++] = (unsigned short)len;
00430                 }
00431             }
00432 
00433             /* handle error breaks in while */
00434             if (mode == BAD) break;
00435 
00436             /* check for end-of-block code (better have one) */
00437             if (state->lens[256] == 0) {
00438                 strm->msg = (char *)"invalid code -- missing end-of-block";
00439                 mode = BAD;
00440                 break;
00441             }
00442 
00443             /* build code tables -- note: do not change the lenbits or distbits
00444                values here (9 and 6) without reading the comments in inftree9.h
00445                concerning the ENOUGH constants, which depend on those values */
00446             state->next = state->codes;
00447             lencode = (code const FAR *)(state->next);
00448             lenbits = 9;
00449             ret = inflate_table9(LENS, state->lens, state->nlen,
00450                             &(state->next), &(lenbits), state->work);
00451             if (ret) {
00452                 strm->msg = (char *)"invalid literal/lengths set";
00453                 mode = BAD;
00454                 break;
00455             }
00456             distcode = (code const FAR *)(state->next);
00457             distbits = 6;
00458             ret = inflate_table9(DISTS, state->lens + state->nlen,
00459                             state->ndist, &(state->next), &(distbits),
00460                             state->work);
00461             if (ret) {
00462                 strm->msg = (char *)"invalid distances set";
00463                 mode = BAD;
00464                 break;
00465             }
00466             Tracev((stderr, "inflate:       codes ok\n"));
00467             mode = LEN;
00468 
00469         case LEN:
00470             /* get a literal, length, or end-of-block code */
00471             for (;;) {
00472                 here = lencode[BITS(lenbits)];
00473                 if ((unsigned)(here.bits) <= bits) break;
00474                 PULLBYTE();
00475             }
00476             if (here.op && (here.op & 0xf0) == 0) {
00477                 last = here;
00478                 for (;;) {
00479                     here = lencode[last.val +
00480                             (BITS(last.bits + last.op) >> last.bits)];
00481                     if ((unsigned)(last.bits + here.bits) <= bits) break;
00482                     PULLBYTE();
00483                 }
00484                 DROPBITS(last.bits);
00485             }
00486             DROPBITS(here.bits);
00487             length = (unsigned)here.val;
00488 
00489             /* process literal */
00490             if (here.op == 0) {
00491                 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
00492                         "inflate:         literal '%c'\n" :
00493                         "inflate:         literal 0x%02x\n", here.val));
00494                 ROOM();
00495                 *put++ = (unsigned char)(length);
00496                 left--;
00497                 mode = LEN;
00498                 break;
00499             }
00500 
00501             /* process end of block */
00502             if (here.op & 32) {
00503                 Tracevv((stderr, "inflate:         end of block\n"));
00504                 mode = TYPE;
00505                 break;
00506             }
00507 
00508             /* invalid code */
00509             if (here.op & 64) {
00510                 strm->msg = (char *)"invalid literal/length code";
00511                 mode = BAD;
00512                 break;
00513             }
00514 
00515             /* length code -- get extra bits, if any */
00516             extra = (unsigned)(here.op) & 31;
00517             if (extra != 0) {
00518                 NEEDBITS(extra);
00519                 length += BITS(extra);
00520                 DROPBITS(extra);
00521             }
00522             Tracevv((stderr, "inflate:         length %lu\n", length));
00523 
00524             /* get distance code */
00525             for (;;) {
00526                 here = distcode[BITS(distbits)];
00527                 if ((unsigned)(here.bits) <= bits) break;
00528                 PULLBYTE();
00529             }
00530             if ((here.op & 0xf0) == 0) {
00531                 last = here;
00532                 for (;;) {
00533                     here = distcode[last.val +
00534                             (BITS(last.bits + last.op) >> last.bits)];
00535                     if ((unsigned)(last.bits + here.bits) <= bits) break;
00536                     PULLBYTE();
00537                 }
00538                 DROPBITS(last.bits);
00539             }
00540             DROPBITS(here.bits);
00541             if (here.op & 64) {
00542                 strm->msg = (char *)"invalid distance code";
00543                 mode = BAD;
00544                 break;
00545             }
00546             offset = (unsigned)here.val;
00547 
00548             /* get distance extra bits, if any */
00549             extra = (unsigned)(here.op) & 15;
00550             if (extra != 0) {
00551                 NEEDBITS(extra);
00552                 offset += BITS(extra);
00553                 DROPBITS(extra);
00554             }
00555             if (offset > WSIZE - (wrap ? 0: left)) {
00556                 strm->msg = (char *)"invalid distance too far back";
00557                 mode = BAD;
00558                 break;
00559             }
00560             Tracevv((stderr, "inflate:         distance %lu\n", offset));
00561 
00562             /* copy match from window to output */
00563             do {
00564                 ROOM();
00565                 copy = WSIZE - offset;
00566                 if (copy < left) {
00567                     from = put + copy;
00568                     copy = left - copy;
00569                 }
00570                 else {
00571                     from = put - offset;
00572                     copy = left;
00573                 }
00574                 if (copy > length) copy = length;
00575                 length -= copy;
00576                 left -= copy;
00577                 do {
00578                     *put++ = *from++;
00579                 } while (--copy);
00580             } while (length != 0);
00581             break;
00582 
00583         case DONE:
00584             /* inflate stream terminated properly -- write leftover output */
00585             ret = Z_STREAM_END;
00586             if (left < WSIZE) {
00587                 if (out(out_desc, window, (unsigned)(WSIZE - left)))
00588                     ret = Z_BUF_ERROR;
00589             }
00590             goto inf_leave;
00591 
00592         case BAD:
00593             ret = Z_DATA_ERROR;
00594             goto inf_leave;
00595 
00596         default:                /* can't happen, but makes compilers happy */
00597             ret = Z_STREAM_ERROR;
00598             goto inf_leave;
00599         }
00600 
00601     /* Return unused input */
00602   inf_leave:
00603     strm->next_in = next;
00604     strm->avail_in = have;
00605     return ret;
00606 }
00607 
00608 int ZEXPORT inflateBack9End(strm)
00609 z_stream FAR *strm;
00610 {
00611     if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
00612         return Z_STREAM_ERROR;
00613     ZFREE(strm, strm->state);
00614     strm->state = Z_NULL;
00615     Tracev((stderr, "inflate: end\n"));
00616     return Z_OK;
00617 }

Generated on Wed Oct 20 2010 11:12:17 for APBS by  doxygen 1.7.2