inffast.c
上传用户:jnfxsk
上传日期:2022-06-16
资源大小:3675k
文件大小:7k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /* inffast.c -- fast decoding
  2.  * Copyright (C) 1995-2003 Mark Adler
  3.  * For conditions of distribution and use, see copyright notice in zlib.h
  4.  */
  5. #include "zutil.h"
  6. #include "inftrees.h"
  7. #include "inflate.h"
  8. #include "inffast.h"
  9. #define PUP(a) *(a)++
  10. /*
  11. Decode literal, length, and distance codes and write out the resulting
  12. literal and match bytes until either not enough input or output is
  13. available, an end-of-block is encountered, or a data error is encountered.
  14. When large enough input and output buffers are supplied to inflate(), for
  15. example, a 16K input buffer and a 64K output buffer, more than 95% of the
  16. inflate execution time is spent in this routine.
  17. Entry assumptions:
  18. state->mode == LEN
  19. strm->avail_in >= 6
  20. strm->avail_out >= 258
  21. start >= strm->avail_out
  22. state->bits < 8
  23. On return, state->mode is one of:
  24. LEN -- ran out of enough output space or enough available input
  25. TYPE -- reached end of block code, inflate() to interpret next block
  26. BAD -- error in block data
  27. Notes:
  28. - The maximum input bits used by a length/distance pair is 15 bits for the
  29. length code, 5 bits for the length extra, 15 bits for the distance code,
  30. and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
  31. Therefore if strm->avail_in >= 6, then there is enough input to avoid
  32. checking for available input while decoding.
  33. - The maximum bytes that a single length/distance pair can output is 258
  34. bytes, which is the maximum length that can be coded.  inflate_fast()
  35. requires strm->avail_out >= 258 for each loop to avoid checking for
  36. output space.
  37.  */
  38. void inflate_fast(z_streamp strm, DWORD start)
  39. {
  40.   struct inflate_state *state = (struct inflate_state*)strm->state;
  41.   BYTE *in = strm->next_in;
  42.   BYTE *last = in + (strm->avail_in - 5);
  43.   BYTE *dest = strm->next_out;
  44.   BYTE *beg = dest - (start - strm->avail_out);
  45.   BYTE *end = dest + (strm->avail_out - 257);
  46.   BYTE *window = window = state->window;
  47.   BYTE *from;
  48.   DWORD wsize = state->wsize;
  49.   DWORD whave = state->whave;
  50.   DWORD write = state->write;
  51.   DWORD hold = state->hold;
  52.   DWORD bits = state->bits;
  53.   DWORD lmask = (1U << state->lenbits) - 1;
  54.   DWORD dmask = (1U << state->distbits) - 1;
  55.   DWORD op;
  56.   DWORD len;
  57.   DWORD dist;
  58.   code const *lcode = state->lencode;
  59.   code const *dcode = state->distcode;
  60.   code this;
  61.   /* decode literals and length/distances until end-of-block or not enough
  62.   input data or output space */
  63.   do
  64.   {
  65.     if (bits < 15)
  66.     {
  67.       hold += (DWORD)(PUP(in)) << bits;
  68.       bits += 8;
  69.       hold += (DWORD)(PUP(in)) << bits;
  70.       bits += 8;
  71.     }
  72.     this = lcode[hold & lmask];
  73.  dolen:
  74.     op = (DWORD)(this.bits);
  75.     hold >>= op;
  76.     bits -= op;
  77.     op = (DWORD)(this.op);
  78.     if (!op)
  79.     {
  80.       PUP(dest) = (BYTE)(this.val);
  81.     }
  82.     else if (op &16)
  83.     {
  84.       len = (DWORD)(this.val);
  85.       op &= 15; /* number of extra bits */
  86.       if (op)
  87.       {
  88.         if (bits < op)
  89.         {
  90.           hold += (DWORD)(PUP(in)) << bits;
  91.           bits += 8;
  92.         }
  93.         len += (DWORD)hold &((1U << op) - 1);
  94.         hold >>= op;
  95.         bits -= op;
  96.       }
  97.       if (bits < 15)
  98.       {
  99.         hold += (DWORD)(PUP(in)) << bits;
  100.         bits += 8;
  101.         hold += (DWORD)(PUP(in)) << bits;
  102.         bits += 8;
  103.       }
  104.       this = dcode[hold &dmask];
  105.       dodist: op = (DWORD)(this.bits);
  106.       hold >>= op;
  107.       bits -= op;
  108.       op = (DWORD)(this.op);
  109.       if (op & 16)
  110.       {
  111.         /* distance base */
  112.         dist = (DWORD)(this.val);
  113.         op &= 15; /* number of extra bits */
  114.         if (bits < op)
  115.         {
  116.           hold += (DWORD)(PUP(in)) << bits;
  117.           bits += 8;
  118.           if (bits < op)
  119.           {
  120.             hold += (DWORD)(PUP(in)) << bits;
  121.             bits += 8;
  122.           }
  123.         }
  124.         dist += (DWORD)hold &((1U << op) - 1);
  125.         hold >>= op;
  126.         bits -= op;
  127.         op = (DWORD)(dest - beg);
  128.         if (dist > op)
  129.         {
  130.           op = dist - op;
  131.           if (op > whave)
  132.           {
  133.             state->mode = BAD;
  134.             break;
  135.           }
  136.           from = window;
  137.           if (!write) /* very common case */
  138.           {
  139.             from += wsize - op;
  140.             if (op < len) /* some from window */
  141.             {
  142.               len -= op;
  143.               do
  144.               {
  145.                 PUP(dest) = PUP(from);
  146.               }
  147.               while (--op);
  148.               from = dest - dist; /* rest from output */
  149.             }
  150.           }
  151.           else if (write < op) /* wrap around window */
  152.           {
  153.             from += wsize + write - op;
  154.             op -= write;
  155.             
  156.             if (op < len)   /* some from end of window */
  157.             {
  158.               len -= op;
  159.               
  160.               do
  161.               {
  162.                 PUP(dest) = PUP(from);
  163.               }
  164.               while (--op);
  165.               
  166.               from = window;
  167.               
  168.               if (write < len)  /* some from start of window */
  169.               {
  170.                 op = write;
  171.                 len -= op;
  172.                 
  173.                 do
  174.                 {
  175.                   PUP(dest) = PUP(from);
  176.                 }
  177.                 while (--op);
  178.                 
  179.                 from = dest - dist; /* rest from output */
  180.               }
  181.             }
  182.           }
  183.           else
  184.           {
  185.             from += write - op;
  186.             
  187.             if (op < len)
  188.             {
  189.               len -= op;
  190.               
  191.               do
  192.               {
  193.                 PUP(dest) = PUP(from);
  194.               }
  195.               while (--op);
  196.               
  197.               from = dest - dist; /* rest from output */
  198.             }
  199.           }
  200.           
  201.   memcpy(dest, from, len);
  202.   dest += len;
  203.   from += len;
  204.           len = 0;          
  205.         }
  206.         else
  207.         {
  208.           from = dest - dist; /* copy direct from output */
  209.   
  210. #ifdef __GNUC__
  211. //          asm("movl $dest, %edi");
  212. //          asm("movl $from, %esi");
  213. //          asm("movl $len, %ecx");
  214. //          asm("movl %edi, %eax");
  215. //          asm("addl %ecx, %eax");
  216. //          asm("movl %eax, $dest");
  217. //          asm("repne movsb");
  218.           memcpy(dest, from, len);
  219.           dest += len;
  220. #else
  221.           _asm mov edi, dword ptr dest
  222.           _asm mov esi, dword ptr from
  223.           _asm mov ecx, dword ptr len
  224.           _asm mov eax, edi
  225.           _asm add eax, ecx
  226.           _asm mov dword ptr dest, eax
  227.           _asm repne movsb     
  228. #endif
  229.         }
  230.       }
  231.       else if (!(op & 64))
  232.       {
  233.         this = dcode[this.val + (hold &((1 << op) - 1))];
  234.         goto dodist;
  235.       }
  236.       else
  237.       {
  238.         state->mode = BAD;
  239.         break;
  240.       }
  241.     }
  242.     else if (!(op & 64))
  243.     {
  244.       this = lcode[this.val + (hold &((1 << op) - 1))];
  245.       goto dolen;
  246.     }
  247.     else if (op & 32)
  248.     {
  249.       state->mode = TYPE;
  250.       break;
  251.     }
  252.     else
  253.     {
  254.       state->mode = BAD;
  255.       break;
  256.     }
  257.   }
  258.   while (in < last && dest < end);
  259.   /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
  260.   len = bits >> 3;
  261.   in -= len;
  262.   bits -= len << 3;
  263.   hold &= (1U << bits) - 1;
  264.   /* update state and return */
  265.   strm->next_in = in;
  266.   strm->next_out = dest;
  267.   strm->avail_in = (DWORD)(in < last ? 5+(last - in): 5-(in - last));
  268.   strm->avail_out = (DWORD)(dest < end ? 257+(end - dest): 257-(dest - end));
  269.   state->hold = hold;
  270.   state->bits = bits;
  271. }