Diff for /embedaddon/rsync/zlib/inffast.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/17 15:09:30 version 1.1.1.2, 2013/10/14 07:51:14
Line 1 Line 1
 /* inffast.c -- fast decoding  /* inffast.c -- fast decoding
 * Copyright (C) 1995-2004 Mark Adler * Copyright (C) 1995-2008, 2010, 2013 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h   * For conditions of distribution and use, see copyright notice in zlib.h
  */   */
   
Line 64 Line 64
       requires strm->avail_out >= 258 for each loop to avoid checking for        requires strm->avail_out >= 258 for each loop to avoid checking for
       output space.        output space.
  */   */
void inflate_fast(strm, start)void ZLIB_INTERNAL inflate_fast(strm, start)
 z_streamp strm;  z_streamp strm;
 unsigned start;         /* inflate()'s starting value for strm->avail_out */  unsigned start;         /* inflate()'s starting value for strm->avail_out */
 {  {
     struct inflate_state FAR *state;      struct inflate_state FAR *state;
    unsigned char FAR *in;      /* local strm->next_in */    z_const unsigned char FAR *in;      /* local strm->next_in */
    unsigned char FAR *last;    /* while in < last, enough input available */    z_const unsigned char FAR *last;    /* have enough input while in < last */
     unsigned char FAR *out;     /* local strm->next_out */      unsigned char FAR *out;     /* local strm->next_out */
     unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */      unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
     unsigned char FAR *end;     /* while out < end, enough space available */      unsigned char FAR *end;     /* while out < end, enough space available */
Line 79  unsigned start;         /* inflate()'s starting value  Line 79  unsigned start;         /* inflate()'s starting value 
 #endif  #endif
     unsigned wsize;             /* window size or zero if not using window */      unsigned wsize;             /* window size or zero if not using window */
     unsigned whave;             /* valid bytes in the window */      unsigned whave;             /* valid bytes in the window */
    unsigned write;             /* window write index */    unsigned wnext;             /* window write index */
     unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */      unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
     unsigned long hold;         /* local strm->hold */      unsigned long hold;         /* local strm->hold */
     unsigned bits;              /* local strm->bits */      unsigned bits;              /* local strm->bits */
Line 87  unsigned start;         /* inflate()'s starting value  Line 87  unsigned start;         /* inflate()'s starting value 
     code const FAR *dcode;      /* local strm->distcode */      code const FAR *dcode;      /* local strm->distcode */
     unsigned lmask;             /* mask for first level of length codes */      unsigned lmask;             /* mask for first level of length codes */
     unsigned dmask;             /* mask for first level of distance codes */      unsigned dmask;             /* mask for first level of distance codes */
    code this;                  /* retrieved table entry */    code here;                  /* retrieved table entry */
     unsigned op;                /* code bits, operation, extra bits, or */      unsigned op;                /* code bits, operation, extra bits, or */
                                 /*  window position, window bytes to copy */                                  /*  window position, window bytes to copy */
     unsigned len;               /* match length, unused bytes */      unsigned len;               /* match length, unused bytes */
Line 106  unsigned start;         /* inflate()'s starting value  Line 106  unsigned start;         /* inflate()'s starting value 
 #endif  #endif
     wsize = state->wsize;      wsize = state->wsize;
     whave = state->whave;      whave = state->whave;
    write = state->write;    wnext = state->wnext;
     window = state->window;      window = state->window;
     hold = state->hold;      hold = state->hold;
     bits = state->bits;      bits = state->bits;
Line 124  unsigned start;         /* inflate()'s starting value  Line 124  unsigned start;         /* inflate()'s starting value 
             hold += (unsigned long)(PUP(in)) << bits;              hold += (unsigned long)(PUP(in)) << bits;
             bits += 8;              bits += 8;
         }          }
        this = lcode[hold & lmask];        here = lcode[hold & lmask];
       dolen:        dolen:
        op = (unsigned)(this.bits);        op = (unsigned)(here.bits);
         hold >>= op;          hold >>= op;
         bits -= op;          bits -= op;
        op = (unsigned)(this.op);        op = (unsigned)(here.op);
         if (op == 0) {                          /* literal */          if (op == 0) {                          /* literal */
            Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?            Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
                     "inflate:         literal '%c'\n" :                      "inflate:         literal '%c'\n" :
                    "inflate:         literal 0x%02x\n", this.val));                    "inflate:         literal 0x%02x\n", here.val));
            PUP(out) = (unsigned char)(this.val);            PUP(out) = (unsigned char)(here.val);
         }          }
         else if (op & 16) {                     /* length base */          else if (op & 16) {                     /* length base */
            len = (unsigned)(this.val);            len = (unsigned)(here.val);
             op &= 15;                           /* number of extra bits */              op &= 15;                           /* number of extra bits */
             if (op) {              if (op) {
                 if (bits < op) {                  if (bits < op) {
Line 155  unsigned start;         /* inflate()'s starting value  Line 155  unsigned start;         /* inflate()'s starting value 
                 hold += (unsigned long)(PUP(in)) << bits;                  hold += (unsigned long)(PUP(in)) << bits;
                 bits += 8;                  bits += 8;
             }              }
            this = dcode[hold & dmask];            here = dcode[hold & dmask];
           dodist:            dodist:
            op = (unsigned)(this.bits);            op = (unsigned)(here.bits);
             hold >>= op;              hold >>= op;
             bits -= op;              bits -= op;
            op = (unsigned)(this.op);            op = (unsigned)(here.op);
             if (op & 16) {                      /* distance base */              if (op & 16) {                      /* distance base */
                dist = (unsigned)(this.val);                dist = (unsigned)(here.val);
                 op &= 15;                       /* number of extra bits */                  op &= 15;                       /* number of extra bits */
                 if (bits < op) {                  if (bits < op) {
                     hold += (unsigned long)(PUP(in)) << bits;                      hold += (unsigned long)(PUP(in)) << bits;
Line 187  unsigned start;         /* inflate()'s starting value  Line 187  unsigned start;         /* inflate()'s starting value 
                 if (dist > op) {                /* see if copy from window */                  if (dist > op) {                /* see if copy from window */
                     op = dist - op;             /* distance back in window */                      op = dist - op;             /* distance back in window */
                     if (op > whave) {                      if (op > whave) {
                        strm->msg = (char *)"invalid distance too far back";                        if (state->sane) {
                        state->mode = BAD;                            strm->msg =
                        break;                                (char *)"invalid distance too far back";
                             state->mode = BAD;
                             break;
                         }
 #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
                         if (len <= op - whave) {
                             do {
                                 PUP(out) = 0;
                             } while (--len);
                             continue;
                         }
                         len -= op - whave;
                         do {
                             PUP(out) = 0;
                         } while (--op > whave);
                         if (op == 0) {
                             from = out - dist;
                             do {
                                 PUP(out) = PUP(from);
                             } while (--len);
                             continue;
                         }
 #endif
                     }                      }
                     from = window - OFF;                      from = window - OFF;
                    if (write == 0) {           /* very common case */                    if (wnext == 0) {           /* very common case */
                         from += wsize - op;                          from += wsize - op;
                         if (op < len) {         /* some from window */                          if (op < len) {         /* some from window */
                             len -= op;                              len -= op;
Line 202  unsigned start;         /* inflate()'s starting value  Line 224  unsigned start;         /* inflate()'s starting value 
                             from = out - dist;  /* rest from output */                              from = out - dist;  /* rest from output */
                         }                          }
                     }                      }
                    else if (write < op) {      /* wrap around window */                    else if (wnext < op) {      /* wrap around window */
                        from += wsize + write - op;                        from += wsize + wnext - op;
                        op -= write;                        op -= wnext;
                         if (op < len) {         /* some from end of window */                          if (op < len) {         /* some from end of window */
                             len -= op;                              len -= op;
                             do {                              do {
                                 PUP(out) = PUP(from);                                  PUP(out) = PUP(from);
                             } while (--op);                              } while (--op);
                             from = window - OFF;                              from = window - OFF;
                            if (write < len) {  /* some from start of window */                            if (wnext < len) {  /* some from start of window */
                                op = write;                                op = wnext;
                                 len -= op;                                  len -= op;
                                 do {                                  do {
                                     PUP(out) = PUP(from);                                      PUP(out) = PUP(from);
Line 222  unsigned start;         /* inflate()'s starting value  Line 244  unsigned start;         /* inflate()'s starting value 
                         }                          }
                     }                      }
                     else {                      /* contiguous in window */                      else {                      /* contiguous in window */
                        from += write - op;                        from += wnext - op;
                         if (op < len) {         /* some from window */                          if (op < len) {         /* some from window */
                             len -= op;                              len -= op;
                             do {                              do {
Line 259  unsigned start;         /* inflate()'s starting value  Line 281  unsigned start;         /* inflate()'s starting value 
                 }                  }
             }              }
             else if ((op & 64) == 0) {          /* 2nd level distance code */              else if ((op & 64) == 0) {          /* 2nd level distance code */
                this = dcode[this.val + (hold & ((1U << op) - 1))];                here = dcode[here.val + (hold & ((1U << op) - 1))];
                 goto dodist;                  goto dodist;
             }              }
             else {              else {
Line 269  unsigned start;         /* inflate()'s starting value  Line 291  unsigned start;         /* inflate()'s starting value 
             }              }
         }          }
         else if ((op & 64) == 0) {              /* 2nd level length code */          else if ((op & 64) == 0) {              /* 2nd level length code */
            this = lcode[this.val + (hold & ((1U << op) - 1))];            here = lcode[here.val + (hold & ((1U << op) - 1))];
             goto dolen;              goto dolen;
         }          }
         else if (op & 32) {                     /* end-of-block */          else if (op & 32) {                     /* end-of-block */
Line 305  unsigned start;         /* inflate()'s starting value  Line 327  unsigned start;         /* inflate()'s starting value 
    inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):     inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
    - Using bit fields for code structure     - Using bit fields for code structure
    - Different op definition to avoid & for extra bits (do & for table bits)     - Different op definition to avoid & for extra bits (do & for table bits)
   - Three separate decoding do-loops for direct, window, and write == 0   - Three separate decoding do-loops for direct, window, and wnext == 0
    - Special case for distance > 1 copies to do overlapped load and store copy     - Special case for distance > 1 copies to do overlapped load and store copy
    - Explicit branch predictions (based on measured branch probabilities)     - Explicit branch predictions (based on measured branch probabilities)
    - Deferring match copy and interspersed it with decoding subsequent codes     - Deferring match copy and interspersed it with decoding subsequent codes

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>