mirror of
				https://github.com/KartKrewDev/RingRacers.git
				synced 2025-10-30 08:01:28 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			140 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (c) 2000-2005 Marc Alexander Lehmann <schmorp@schmorp.de>
 | 
						|
 * 
 | 
						|
 * Redistribution and use in source and binary forms, with or without modifica-
 | 
						|
 * tion, are permitted provided that the following conditions are met:
 | 
						|
 * 
 | 
						|
 *   1.  Redistributions of source code must retain the above copyright notice,
 | 
						|
 *       this list of conditions and the following disclaimer.
 | 
						|
 * 
 | 
						|
 *   2.  Redistributions in binary form must reproduce the above copyright
 | 
						|
 *       notice, this list of conditions and the following disclaimer in the
 | 
						|
 *       documentation and/or other materials provided with the distribution.
 | 
						|
 * 
 | 
						|
 *   3.  The name of the author may not be used to endorse or promote products
 | 
						|
 *       derived from this software without specific prior written permission.
 | 
						|
 * 
 | 
						|
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 | 
						|
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
 | 
						|
 * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
 | 
						|
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
 | 
						|
 * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
						|
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 | 
						|
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 | 
						|
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
 | 
						|
 * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 | 
						|
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
						|
 *
 | 
						|
 * Alternatively, the contents of this file may be used under the terms of
 | 
						|
 * the GNU General Public License version 2 (the "GPL"), in which case the
 | 
						|
 * provisions of the GPL are applicable instead of the above. If you wish to
 | 
						|
 * allow the use of your version of this file only under the terms of the
 | 
						|
 * GPL and not to allow others to use your version of this file under the
 | 
						|
 * BSD license, indicate your decision by deleting the provisions above and
 | 
						|
 * replace them with the notice and other provisions required by the GPL. If
 | 
						|
 * you do not delete the provisions above, a recipient may use your version
 | 
						|
 * of this file under either the BSD or the GPL.
 | 
						|
 */
 | 
						|
 | 
						|
#include "lzfP.h"
 | 
						|
 | 
						|
#if AVOID_ERRNO
 | 
						|
# define SET_ERRNO(n)
 | 
						|
#else
 | 
						|
# include <errno.h>
 | 
						|
# define SET_ERRNO(n) errno = (n)
 | 
						|
#endif
 | 
						|
 | 
						|
unsigned int 
 | 
						|
lzf_decompress (const void *const in_data,  unsigned int in_len,
 | 
						|
                void             *out_data, unsigned int out_len)
 | 
						|
{
 | 
						|
  u8 const *ip = (const u8 *)in_data;
 | 
						|
  u8       *op = (u8 *)out_data;
 | 
						|
  u8 const *const in_end  = ip + in_len;
 | 
						|
  u8       *const out_end = op + out_len;
 | 
						|
 | 
						|
  do
 | 
						|
    {
 | 
						|
      unsigned int ctrl = *ip++;
 | 
						|
 | 
						|
      if (ctrl < (1 << 5)) /* literal run */
 | 
						|
        {
 | 
						|
          ctrl++;
 | 
						|
 | 
						|
          if (op + ctrl > out_end)
 | 
						|
            {
 | 
						|
              SET_ERRNO (E2BIG);
 | 
						|
              return 0;
 | 
						|
            }
 | 
						|
 | 
						|
#if CHECK_INPUT
 | 
						|
          if (ip + ctrl > in_end)
 | 
						|
            {
 | 
						|
              SET_ERRNO (EINVAL);
 | 
						|
              return 0;
 | 
						|
            }
 | 
						|
#endif
 | 
						|
 | 
						|
#if USE_MEMCPY
 | 
						|
          memcpy (op, ip, ctrl);
 | 
						|
          op += ctrl;
 | 
						|
          ip += ctrl;
 | 
						|
#else
 | 
						|
          do
 | 
						|
            *op++ = *ip++;
 | 
						|
          while (--ctrl);
 | 
						|
#endif
 | 
						|
        }
 | 
						|
      else /* back reference */
 | 
						|
        {
 | 
						|
          unsigned int len = ctrl >> 5;
 | 
						|
 | 
						|
          u8 *ref = op - ((ctrl & 0x1f) << 8) - 1;
 | 
						|
 | 
						|
#if CHECK_INPUT
 | 
						|
          if (ip >= in_end)
 | 
						|
            {
 | 
						|
              SET_ERRNO (EINVAL);
 | 
						|
              return 0;
 | 
						|
            }
 | 
						|
#endif
 | 
						|
          if (len == 7)
 | 
						|
            {
 | 
						|
              len += *ip++;
 | 
						|
#if CHECK_INPUT
 | 
						|
              if (ip >= in_end)
 | 
						|
                {
 | 
						|
                  SET_ERRNO (EINVAL);
 | 
						|
                  return 0;
 | 
						|
                }
 | 
						|
#endif
 | 
						|
            }
 | 
						|
 | 
						|
          ref -= *ip++;
 | 
						|
 | 
						|
          if (op + len + 2 > out_end)
 | 
						|
            {
 | 
						|
              SET_ERRNO (E2BIG);
 | 
						|
              return 0;
 | 
						|
            }
 | 
						|
 | 
						|
          if (ref < (u8 *)out_data)
 | 
						|
            {
 | 
						|
              SET_ERRNO (EINVAL);
 | 
						|
              return 0;
 | 
						|
            }
 | 
						|
 | 
						|
          *op++ = *ref++;
 | 
						|
          *op++ = *ref++;
 | 
						|
 | 
						|
          do
 | 
						|
            *op++ = *ref++;
 | 
						|
          while (--len);
 | 
						|
        }
 | 
						|
    }
 | 
						|
  while (ip < in_end);
 | 
						|
 | 
						|
  return op - (u8 *)out_data;
 | 
						|
}
 | 
						|
 |