mirror of
https://github.com/libretro/beetle-psx-libretro.git
synced 2024-11-27 02:40:31 +00:00
Rip out all compression code
This commit is contained in:
parent
d69f53690d
commit
c5c37867fa
7
Makefile
7
Makefile
@ -112,12 +112,7 @@ SOURCES_C := $(MEDNAFEN_DIR)/trio/trio.c \
|
||||
$(LIBRETRO_SOURCES_C) \
|
||||
$(MEDNAFEN_DIR)/trio/trionan.c \
|
||||
$(MEDNAFEN_DIR)/trio/triostr.c \
|
||||
$(MEDNAFEN_DIR)/string/world_strtod.c \
|
||||
$(MEDNAFEN_DIR)/compress/blz.c \
|
||||
$(MEDNAFEN_DIR)/compress/unzip.c \
|
||||
$(MEDNAFEN_DIR)/compress/minilzo.c \
|
||||
$(MEDNAFEN_DIR)/compress/quicklz.c \
|
||||
$(MEDNAFEN_DIR)/compress/ioapi.c
|
||||
$(MEDNAFEN_DIR)/string/world_strtod.c
|
||||
|
||||
SOURCES := $(LIBRETRO_SOURCES) $(PSX_SOURCES) $(MEDNAFEN_SOURCES)
|
||||
OBJECTS := $(SOURCES:.cpp=.o) $(SOURCES_C:.c=.o)
|
||||
|
@ -1 +0,0 @@
|
||||
mednafen_SOURCES += compress/minilzo.c compress/quicklz.c compress/blz.cpp compress/ioapi.c compress/unzip.c
|
@ -1,124 +0,0 @@
|
||||
|
||||
============================================================================
|
||||
miniLZO -- mini subset of the LZO real-time data compression library
|
||||
============================================================================
|
||||
|
||||
Author : Markus Franz Xaver Johannes Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
http://www.oberhumer.com/opensource/lzo/
|
||||
Version : 2.06
|
||||
Date : 12 Aug 2011
|
||||
|
||||
I've created miniLZO for projects where it is inconvenient to
|
||||
include (or require) the full LZO source code just because you
|
||||
want to add a little bit of data compression to your application.
|
||||
|
||||
miniLZO implements the LZO1X-1 compressor and both the standard and
|
||||
safe LZO1X decompressor. Apart from fast compression it also useful
|
||||
for situations where you want to use pre-compressed data files (which
|
||||
must have been compressed with LZO1X-999).
|
||||
|
||||
miniLZO consists of one C source file and three header files:
|
||||
minilzo.c
|
||||
minilzo.h, lzoconf.h, lzodefs.h
|
||||
|
||||
To use miniLZO just copy these files into your source directory, add
|
||||
minilzo.c to your Makefile and #include minilzo.h from your program.
|
||||
Note: you also must distribute this file ('README.LZO') with your project.
|
||||
|
||||
minilzo.o compiles to about 6 KiB (using gcc or Visual C on an i386), and
|
||||
the sources are about 30 KiB when packed with zip - so there's no more
|
||||
excuse that your application doesn't support data compression :-)
|
||||
|
||||
For more information, documentation, example programs and other support
|
||||
files (like Makefiles and build scripts) please download the full LZO
|
||||
package from
|
||||
http://www.oberhumer.com/opensource/lzo/
|
||||
|
||||
Have fun,
|
||||
Markus
|
||||
|
||||
|
||||
P.S. minilzo.c is generated automatically from the LZO sources and
|
||||
therefore functionality is completely identical
|
||||
|
||||
|
||||
Appendix A: building miniLZO
|
||||
----------------------------
|
||||
miniLZO is written such a way that it should compile and run
|
||||
out-of-the-box on most machines.
|
||||
|
||||
If you are running on a very unusual architecture and lzo_init() fails then
|
||||
you should first recompile with '-DLZO_DEBUG' to see what causes the failure.
|
||||
The most probable case is something like 'sizeof(void *) != sizeof(size_t)'.
|
||||
After identifying the problem you can compile by adding some defines
|
||||
like '-DSIZEOF_VOID_P=8' to your Makefile.
|
||||
|
||||
The best solution is (of course) using Autoconf - if your project uses
|
||||
Autoconf anyway just add '-DMINILZO_HAVE_CONFIG_H' to your compiler
|
||||
flags when compiling minilzo.c. See the LZO distribution for an example
|
||||
how to set up configure.ac.
|
||||
|
||||
|
||||
Appendix B: list of public functions available in miniLZO
|
||||
---------------------------------------------------------
|
||||
Library initialization
|
||||
lzo_init()
|
||||
|
||||
Compression
|
||||
lzo1x_1_compress()
|
||||
|
||||
Decompression
|
||||
lzo1x_decompress()
|
||||
lzo1x_decompress_safe()
|
||||
|
||||
Checksum functions
|
||||
lzo_adler32()
|
||||
|
||||
Version functions
|
||||
lzo_version()
|
||||
lzo_version_string()
|
||||
lzo_version_date()
|
||||
|
||||
Portable (but slow) string functions
|
||||
lzo_memcmp()
|
||||
lzo_memcpy()
|
||||
lzo_memmove()
|
||||
lzo_memset()
|
||||
|
||||
|
||||
Appendix C: suggested macros for 'configure.ac' when using Autoconf
|
||||
-------------------------------------------------------------------
|
||||
Checks for typedefs and structures
|
||||
AC_CHECK_TYPE(ptrdiff_t,long)
|
||||
AC_TYPE_SIZE_T
|
||||
AC_CHECK_SIZEOF(short)
|
||||
AC_CHECK_SIZEOF(int)
|
||||
AC_CHECK_SIZEOF(long)
|
||||
AC_CHECK_SIZEOF(long long)
|
||||
AC_CHECK_SIZEOF(__int64)
|
||||
AC_CHECK_SIZEOF(void *)
|
||||
AC_CHECK_SIZEOF(size_t)
|
||||
AC_CHECK_SIZEOF(ptrdiff_t)
|
||||
|
||||
Checks for compiler characteristics
|
||||
AC_C_CONST
|
||||
|
||||
Checks for library functions
|
||||
AC_CHECK_FUNCS(memcmp memcpy memmove memset)
|
||||
|
||||
|
||||
Appendix D: Copyright
|
||||
---------------------
|
||||
LZO and miniLZO are Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
|
||||
Markus Franz Xaver Oberhumer <markus@oberhumer.com>.
|
||||
|
||||
LZO and miniLZO are distributed under the terms of the GNU General
|
||||
Public License (GPL). See the file COPYING.
|
||||
|
||||
Special licenses for commercial and other applications which
|
||||
are not willing to accept the GNU General Public License
|
||||
are available by contacting the author.
|
||||
|
||||
|
@ -1,982 +0,0 @@
|
||||
/* Configuration macros. If undefined, it is automatically configured, otherwise its
|
||||
value (0 or 1) determines the setting. */
|
||||
|
||||
/* Enable/disable use of negative/positive sign for faster high bit testing */
|
||||
/*#define BLZ_USE_SIGN 1 */
|
||||
|
||||
/* Enable/disable fast version that makes unaligned memory accesses. Fast version
|
||||
uses all the following flags. Portable version only uses BLZ_USE_SIGN flag. */
|
||||
/*#define BLZ_FAST 1 */
|
||||
|
||||
/* Enable/disable use count leading zeros operation */
|
||||
/*#define BLZ_FAST_CLZ 1 */
|
||||
|
||||
/* Big/little endian override. Only needs to be set if assertion in blz_pack() fails.
|
||||
Can happen on processors which support both byte orders and are using the less-common
|
||||
one, like little-endian PowerPC or big-endian ARM. */
|
||||
/*#define BLZ_BIG_ENDIAN 1 */
|
||||
|
||||
/* Restricted pointer keyword. Auto configured for GCC and Microsoft, others might
|
||||
use plain restrict. */
|
||||
/*#define BLZ_RESTRICT restrict */
|
||||
|
||||
/* blz 0.9.1. http://www.slack.net/~ant/ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "blz.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* Copyright (C) 2007 Shay Green. This module is free software; you can
|
||||
redistribute it and/or modify it under the terms of the GNU General Public
|
||||
License, version 2 or later, as published by the Free Software Foundation.
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details. You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
|
||||
|
||||
/* Comments with percentages are how often the condition is true */
|
||||
|
||||
/* Data format: [32-bit length] [block 1] [block 2] ... [32-bit data 0] [16-bit data 0]
|
||||
|
||||
block: [32 bits] [symbol 0] [symbol 1] ... [symbol 30]
|
||||
|
||||
Bits tell whether a symbol is a literal byte (1) or match (0), starting at bit 0.
|
||||
Highest bit set is an end marker, so a block can have at most 31 symbols.
|
||||
Matches are encoded in three ways.
|
||||
|
||||
Short match [3-bit length | 13-bit offset]
|
||||
Mid match [5-bit length] [16-bit offset]
|
||||
Long match [8-bit data 0] [32-bit length] [32-bit offset] */
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
#if INT_MAX < 0x7FFFFFFF || UINT_MAX < 0xFFFFFFFF
|
||||
#error "int must be at least 32 bits"
|
||||
#endif
|
||||
|
||||
/* Automatically optimize for known processors. Thanks http://predef.sourceforge.net/ */
|
||||
|
||||
#define BLZ_PPC (defined (__POWERPC__) || defined (__ppc__) || defined (_M_PPC) || defined (_POWER))
|
||||
|
||||
#if BLZ_PPC || defined (__m68k__)
|
||||
#ifndef BLZ_BIG_ENDIAN
|
||||
#define BLZ_BIG_ENDIAN 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BLZ_PPC || defined (__m68k__) || defined (__i386__) || defined (__x86_64__) || \
|
||||
defined (_M_IX86) || defined (_M_X64)
|
||||
#ifndef BLZ_FAST
|
||||
#define BLZ_FAST 1
|
||||
#endif
|
||||
#ifndef BLZ_FAST_CLZ
|
||||
#define BLZ_FAST_CLZ 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BLZ_RESTRICT
|
||||
#if __GNUC__ >= 3 || _MSC_VER
|
||||
#define BLZ_RESTRICT __restrict
|
||||
#else
|
||||
#define BLZ_RESTRICT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if INT_MAX != 0x7FFFFFFF || !BLZ_USE_SIGN
|
||||
typedef unsigned bits_t;
|
||||
#define TOP_BIT( n ) ((n) & 0x80000000u)
|
||||
#define ALL_BITS( n ) ((n) & 0xFFFFFFFFu)
|
||||
#else
|
||||
typedef int bits_t;
|
||||
#define TOP_BIT( n ) ((n) < 0)
|
||||
#define ALL_BITS( n ) (n)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**** Fast version ****/
|
||||
|
||||
#if BLZ_FAST
|
||||
|
||||
char const blz_version [] = "fast";
|
||||
|
||||
#if defined (HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
#elif defined (HAVE_INTTYPES_H)
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#if USHRT_MAX != 0xFFFF || UINT_MAX != 0xFFFFFFFF
|
||||
#error "Short must be 16 bits and int must be 32 bits"
|
||||
#endif
|
||||
/* macros instead of typedefs in case std headers have these typedefs */
|
||||
#define uint16_t unsigned short
|
||||
#define uint32_t unsigned int
|
||||
#define int32_t signed int
|
||||
#endif
|
||||
|
||||
#ifndef GET16
|
||||
#define GET16( addr ) (*(uint16_t const*) (addr))
|
||||
#define GET32( addr ) (*(uint32_t const*) (addr))
|
||||
#define GET32S( addr ) (*( int32_t const*) (addr))
|
||||
#define SET16( addr, in ) (void) (*(uint16_t*) (addr) = (uint16_t) (in))
|
||||
#define SET32( addr, in ) (void) (*(uint32_t*) (addr) = (uint32_t) (in))
|
||||
#endif
|
||||
|
||||
#if BLZ_BIG_ENDIAN
|
||||
#define BIG_LITTLE( big, little ) (big)
|
||||
#else
|
||||
#define BIG_LITTLE( big, little ) (little)
|
||||
#endif
|
||||
|
||||
#if BLZ_FAST_CLZ
|
||||
/* CLZ: count leading zeros, CTZ: count trailing zeros */
|
||||
#if __GNUC__ >= 4
|
||||
#define CLZ __builtin_clz
|
||||
#define CTZ __builtin_ctz
|
||||
#elif BLZ_PPC && (__GNUC__ >= 3 || __MWERKS__)
|
||||
#if __GNUC__
|
||||
#include <ppc_intrinsics.h>
|
||||
#endif
|
||||
#define CLZ __cntlzw
|
||||
#define CTZ( n ) (32 - __cntlzw( ((n) - 1) & ~(n) ))
|
||||
#endif
|
||||
|
||||
#ifdef CLZ
|
||||
#define COUNT_MATCH( n ) (BIG_LITTLE( CLZ( n ), CTZ( n ) ) >> 3)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define CALC_HASH( n ) BIG_LITTLE( (n >> 20) ^ (n >> 8 & 0xFFF), ((n >> 12) ^ n) & 0xFFF )
|
||||
|
||||
#if BLZ_BIG_ENDIAN && BLZ_PPC
|
||||
/* optimizes out two instructions (unless compiler is really smart) */
|
||||
typedef int dict_entry_t;
|
||||
#define DICT_SHIFT( x, y ) \
|
||||
(((x) / ((1u << (y)) / sizeof (byte*))) & (0xFFF * sizeof (byte*)))
|
||||
#define DICT_ENTRY( d, n ) (DICT_SHIFT( n, 20 ) ^ DICT_SHIFT( n, 8 ))
|
||||
#define USE_ENTRY( d, o ) *(byte const**) ((byte*) d + o)
|
||||
#else
|
||||
typedef byte const** dict_entry_t;
|
||||
#define DICT_ENTRY( d, n ) &d [CALC_HASH( n )]
|
||||
#define USE_ENTRY( d, o ) *o
|
||||
#endif
|
||||
|
||||
/* Pack */
|
||||
|
||||
#define PRE_GOTO() \
|
||||
data = GET32( in )
|
||||
|
||||
#define GOTO_NEXT \
|
||||
if ( !TOP_BIT( bits ) ) /* 97% */ \
|
||||
goto match;\
|
||||
goto flush;
|
||||
|
||||
enum { in_max_offset = 11 }; /* 8+ byte match just before end will read this far ahead */
|
||||
|
||||
static int blz_pack_( byte const* const in_min, int const size,
|
||||
void* const out_min, blz_pack_t* const dict )
|
||||
{
|
||||
/* On 32-bit x86, only dict, in_max, out_max, and bits_out don't fit in registers */
|
||||
byte const* BLZ_RESTRICT in = in_min;
|
||||
byte const* const in_max = in + size - in_max_offset;
|
||||
|
||||
byte* out = (byte*) out_min;
|
||||
byte* const out_max = out + size;
|
||||
byte* out_bits;
|
||||
|
||||
bits_t bits = 2;
|
||||
unsigned data;
|
||||
|
||||
in += 4;
|
||||
SET32( out, size );
|
||||
out_bits = (out += 8);
|
||||
|
||||
literal_sub_4: /* Literal byte */
|
||||
{
|
||||
int const t = in [-4];
|
||||
in -= 3;
|
||||
PRE_GOTO();
|
||||
*out++ = t;
|
||||
if ( TOP_BIT( ++bits ) ) /* 3% */
|
||||
goto flush;
|
||||
}
|
||||
|
||||
match: /* Check for match and update dict */
|
||||
{
|
||||
/* calc dict entry and check for end of input */
|
||||
dict_entry_t const dict_offset = DICT_ENTRY( dict->dict, data );
|
||||
byte const* const BLZ_RESTRICT match = USE_ENTRY( dict->dict, dict_offset );
|
||||
bits <<= 1;
|
||||
if ( in >= in_max ) /* 1% */
|
||||
goto final_bytes;
|
||||
|
||||
/* read first 4 bytes of match and check match distance */
|
||||
{
|
||||
unsigned const match_first = GET32( match - 4 );
|
||||
if ( match > in ) /* 1% */
|
||||
goto literal;
|
||||
|
||||
/* compare first four bytes and update dict */
|
||||
USE_ENTRY( dict->dict, dict_offset ) = (in += 4);
|
||||
if ( (data ^= match_first) != 0 ) /* 74% */
|
||||
{
|
||||
int off = in - match;
|
||||
if ( BIG_LITTLE( data >> 8, data & 0x00FFFFFF ) ) /* 57% */
|
||||
goto literal_sub_4;
|
||||
if ( off >= (1 << 13) ) /* 19% */
|
||||
goto literal_sub_4;
|
||||
|
||||
/* 3 byte match */
|
||||
--in;
|
||||
PRE_GOTO();
|
||||
SET16( out, BIG_LITTLE( (1 << 13) | off, (off << 3) + 1 ) );
|
||||
out += 2;
|
||||
GOTO_NEXT
|
||||
}
|
||||
}
|
||||
|
||||
if ( (data = GET32( in ) ^ GET32( match )) != 0 ) /* 78% */
|
||||
{
|
||||
/* 4-7 byte match */
|
||||
int off = in - match;
|
||||
int len;
|
||||
#ifdef COUNT_MATCH
|
||||
len = COUNT_MATCH( data );
|
||||
in += len;
|
||||
len += 2;
|
||||
#else
|
||||
len = 2;
|
||||
if ( !(data & BIG_LITTLE( 0xFF000000, 0x000000FF )) ) /* 48% 5-7 byte match */
|
||||
{
|
||||
++in;
|
||||
len = 3;
|
||||
if ( !(data & BIG_LITTLE( 0x00FF0000, 0x0000FFFF )) ) /* 47% 6-7 byte match */
|
||||
{
|
||||
++in;
|
||||
len = 4;
|
||||
if ( !BIG_LITTLE( data >> 8, data & 0x00FF0000 ) ) /* 37% 7 byte match */
|
||||
{
|
||||
++in;
|
||||
len = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
PRE_GOTO(); /* TODO: could avoid this in 4-byte case since it's already read */
|
||||
|
||||
/* Encode offset and length */
|
||||
if ( off < (1 << 13) ) /* 82% */
|
||||
{
|
||||
/* LLLOOOOO OOOOOOOO */
|
||||
SET16( out, BIG_LITTLE( (len << 13) | off, (off << 3) + len ) );
|
||||
out += 2;
|
||||
GOTO_NEXT
|
||||
}
|
||||
|
||||
/* unsigned cast and <= helps PowerPC */
|
||||
if ( (unsigned) off <= (1 << 16) - 1 ) /* 91% */
|
||||
{
|
||||
/* 000LLLLL OOOOOOOO OOOOOOOO */
|
||||
*out = BIG_LITTLE( len, len << 3 );
|
||||
SET16( out + 1, off );
|
||||
out += 3;
|
||||
GOTO_NEXT
|
||||
}
|
||||
|
||||
in -= 2;
|
||||
in -= len;
|
||||
goto literal;
|
||||
}
|
||||
{
|
||||
/* 8+ byte match */
|
||||
byte const* const start = in + 2;
|
||||
int off = match - in;
|
||||
in += 4;
|
||||
{
|
||||
/* compare 4 bytes at a time */
|
||||
int temp;
|
||||
do
|
||||
{
|
||||
data = GET32( in );
|
||||
temp = GET32( in + off );
|
||||
if ( in >= in_max ) /* 1% */
|
||||
goto hit_end;
|
||||
in += 4;
|
||||
}
|
||||
while ( !(data ^= temp) ); /* 73% */
|
||||
|
||||
/* determine which of the 4 bytes matched */
|
||||
#ifdef COUNT_MATCH
|
||||
in += COUNT_MATCH( data );
|
||||
#else
|
||||
if ( !(data & BIG_LITTLE( 0xFF000000, 0x000000FF )) ) /* 64% */
|
||||
{
|
||||
++in;
|
||||
if ( !(data & BIG_LITTLE( 0x00FF0000, 0x0000FFFF )) ) /* 58% */
|
||||
{
|
||||
++in;
|
||||
if ( !BIG_LITTLE( data >> 8, data & 0x00FF0000 ) ) /* 45% */
|
||||
++in;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
hit_end:
|
||||
|
||||
/* Encode offset and length */
|
||||
{
|
||||
int len = in - start;
|
||||
in -= 4;
|
||||
off = -off;
|
||||
PRE_GOTO();
|
||||
|
||||
if ( len < (1 << 5) ) /* 90% */
|
||||
{
|
||||
/* unsigned cast and <= helps PowerPC */
|
||||
if ( (unsigned) off <= (1 << 16) - 1 ) /* 98% */
|
||||
{
|
||||
/* 000LLLLL OOOOOOOO OOOOOOOO */
|
||||
*out = BIG_LITTLE( len, len << 3 );
|
||||
SET16( out + 1, off );
|
||||
out += 3;
|
||||
GOTO_NEXT
|
||||
}
|
||||
|
||||
if ( len <= 9 - 2 ) /* 52% */
|
||||
{
|
||||
/* TODO: lame */
|
||||
in -= 2;
|
||||
in -= len;
|
||||
goto literal;
|
||||
}
|
||||
}
|
||||
|
||||
/* 00000000 OOOOOOOO OOOOOOOO OOOOOOOO OOOOOOOO LLLLLLLL LLLLLLLL LLLLLLLL LLLLLLLL */
|
||||
*out = 0;
|
||||
SET32( out + 1, off );
|
||||
SET32( out + 5, len );
|
||||
out += 9;
|
||||
GOTO_NEXT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* These two are at bottom of loop to make branches here positive and branches back
|
||||
negative, which helps CPUs that lack dynamic branch prediction */
|
||||
|
||||
literal: /* Literal byte */
|
||||
{
|
||||
int const t = *in++;
|
||||
PRE_GOTO();
|
||||
*out++ = t;
|
||||
if ( !TOP_BIT( ++bits ) ) /* 97% */
|
||||
goto match;
|
||||
}
|
||||
|
||||
flush: /* Flush bits */
|
||||
out += 4;
|
||||
SET32( out_bits - 4, (bits << 1) + 1 );
|
||||
out_bits = out;
|
||||
bits = 1;
|
||||
if ( out < out_max ) /* 99% */
|
||||
goto match;
|
||||
return -1; /* no compression */
|
||||
|
||||
final_bytes:
|
||||
/* Right-justify and flush final bits */
|
||||
#ifdef CLZ
|
||||
SET32( out_bits - 4, (bits + 1) << (CLZ( bits ) + 1) );
|
||||
#else
|
||||
++bits;
|
||||
if ( !(bits & 0xFFFF0000u) )
|
||||
bits <<= 16;
|
||||
|
||||
if ( !TOP_BIT( bits ) )
|
||||
while ( !TOP_BIT( bits <<= 1 ) ) { }
|
||||
bits <<= 1;
|
||||
|
||||
SET32( out_bits - 4, bits );
|
||||
#endif
|
||||
|
||||
/* Remaining bytes should be in narrow range */
|
||||
assert( in_max + in_max_offset - in >= in_max_offset - 6 );
|
||||
assert( in_max + in_max_offset - in <= in_max_offset + 1 );
|
||||
|
||||
{
|
||||
/* Copy final bytes */
|
||||
unsigned t0 = GET32( in_max + (in_max_offset - 12) );
|
||||
unsigned t1 = GET32( in_max + (in_max_offset - 8) );
|
||||
unsigned t2 = GET32( in_max + (in_max_offset - 4) );
|
||||
SET32( out, 0 ); /* End marker */
|
||||
SET32( out + 4, t0 );
|
||||
SET32( out + 8, t1 );
|
||||
SET32( out + 12, t2 );
|
||||
out += 16;
|
||||
}
|
||||
|
||||
return out - (byte*) out_min;
|
||||
}
|
||||
|
||||
int blz_pack( void const* in_min, int size, void* out, blz_pack_t* dict )
|
||||
{
|
||||
byte const* in = (byte const*) in_min;
|
||||
assert( (unsigned) size <= 0x7FFFFFFF );
|
||||
if ( size >= 31 && dict ) /* 31 repeated bytes compress to 34 bytes */
|
||||
{
|
||||
/* clear dict */
|
||||
byte const** dout = dict->dict;
|
||||
int count;
|
||||
in += 4;
|
||||
for ( count = 0x1000; count--; )
|
||||
*dout++ = in;
|
||||
in -= 4;
|
||||
|
||||
{
|
||||
int out_size = blz_pack_( in, size, out, dict );
|
||||
if ( (unsigned) out_size < (unsigned) size + 4 )
|
||||
return out_size;
|
||||
}
|
||||
}
|
||||
SET32( out, -size );
|
||||
memcpy( (byte*) out + 4, in, size );
|
||||
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
/* If these assertions fail, enable the appropriate byte order macro at the
|
||||
top of this file */
|
||||
static byte const data [5] = { 0x12, 0x34, 0x56, 0x78, 0x9A };
|
||||
assert( GET32( data ) == BIG_LITTLE( 0x12345678, 0x78563412 ) );
|
||||
assert( GET32( data + 1 ) == BIG_LITTLE( 0x3456789A, 0x9A785634 ) );
|
||||
|
||||
{
|
||||
volatile bits_t i = 0x40000000;
|
||||
assert( !TOP_BIT( i ) && TOP_BIT( i << 1 ) && !TOP_BIT( i << 2 ) && !ALL_BITS( i << 2 ) );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return size + 4;
|
||||
}
|
||||
|
||||
/* Unpack */
|
||||
|
||||
int blz_size( void const* in )
|
||||
{
|
||||
int n = GET32S( in );
|
||||
if ( n < 0 )
|
||||
n = -n;
|
||||
return n;
|
||||
}
|
||||
|
||||
int blz_unpack( void const* in_min, void* out_min )
|
||||
{
|
||||
int out_size = GET32S( in_min );
|
||||
byte const* BLZ_RESTRICT in = (byte const*) in_min + 4;
|
||||
byte* out = (byte*) out_min;
|
||||
|
||||
if ( out_size > 0 )
|
||||
{
|
||||
byte* const out_end = out + out_size;
|
||||
|
||||
/* Everything fits in registers, even on 32-bit x86 */
|
||||
unsigned data;
|
||||
bits_t bits;
|
||||
|
||||
refill: /* Refill bits */
|
||||
bits = GET32( in );
|
||||
in += 4;
|
||||
data = GET16( in );
|
||||
if ( TOP_BIT( bits ) ) /* 48% */
|
||||
goto literal;
|
||||
if ( !bits ) /* 1% */
|
||||
goto final_bytes;
|
||||
|
||||
match: { /* Matching symbol */
|
||||
int off;
|
||||
bits <<= 1;
|
||||
off = BIG_LITTLE( data & 0x1FFF, data >> 3 );
|
||||
if ( !BIG_LITTLE( data >>= 13, data &= 0x07 ) ) /* 14% */
|
||||
goto long_match;
|
||||
copy_bytes:
|
||||
/*assert( data > 0 && (size_t) off <= (size_t) (out - (byte*) out_min) );*/
|
||||
|
||||
/* Copy bytes */
|
||||
off = -off;
|
||||
{
|
||||
byte* const end = out + 2 + data;
|
||||
SET32( out, GET32( out + off ) );
|
||||
if ( data > 2 ) /* 30% */
|
||||
{
|
||||
out += 4;
|
||||
do
|
||||
{
|
||||
SET32( out, GET32( out + off ) );
|
||||
out += 4;
|
||||
}
|
||||
while ( out < end ); /* 55% */
|
||||
}
|
||||
out = end;
|
||||
}
|
||||
in += 2;
|
||||
|
||||
data = GET16( in );
|
||||
if ( !TOP_BIT( bits ) ) /* 60% */
|
||||
goto match;
|
||||
literal:
|
||||
if ( ALL_BITS( bits <<= 1 ) == 0 ) /* 7% */
|
||||
goto refill;
|
||||
|
||||
/* Literal byte */
|
||||
*out++ = BIG_LITTLE( data >> 8, data );
|
||||
++in;
|
||||
|
||||
data = GET16( in );
|
||||
if ( TOP_BIT( bits ) ) /* 60% */
|
||||
goto literal;
|
||||
|
||||
/* Start decoding match */
|
||||
bits <<= 1;
|
||||
off = BIG_LITTLE( data & 0x1FFF, data >> 3 );
|
||||
if ( BIG_LITTLE( data >>= 13, data &= 0x07 ) != 0 ) /* 86% */
|
||||
goto copy_bytes;
|
||||
|
||||
/* Longer match encodings */
|
||||
long_match:
|
||||
data = BIG_LITTLE( off >> 8, off & 0x1F );
|
||||
++in;
|
||||
off = GET16( in );
|
||||
if ( data ) /* 92% */
|
||||
goto copy_bytes;
|
||||
|
||||
off = GET32( in );
|
||||
data = GET32( in + 4 );
|
||||
in += 6;
|
||||
goto copy_bytes;
|
||||
}
|
||||
|
||||
final_bytes: /* Copy final bytes */
|
||||
{
|
||||
unsigned t0 = GET32( in );
|
||||
unsigned t1 = GET32( in + 4 );
|
||||
unsigned t2 = GET32( in + 8 );
|
||||
SET32( out_end - 12, t0 );
|
||||
SET32( out_end - 8, t1 );
|
||||
SET32( out_end - 4, t2 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( out, in, (out_size = -out_size) );
|
||||
}
|
||||
return out_size;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/**** Slow version ****/
|
||||
|
||||
char const blz_version [] = "slow";
|
||||
|
||||
/* Makes heavy use of pre-increment since that is more efficient on popular RISC processors */
|
||||
|
||||
/* Pack */
|
||||
|
||||
#define PRE_GOTO( off ) \
|
||||
{\
|
||||
data = (in [off + 2] << 16) | (in [off + 1] << 8);\
|
||||
data |= *(in += off);\
|
||||
}
|
||||
|
||||
#define GOTO_NEXT \
|
||||
if ( !TOP_BIT( bits ) ) /* 97% */ \
|
||||
goto match;\
|
||||
goto flush;
|
||||
|
||||
enum { in_max_offset = 9 }; /* 8+ byte match just before end will read this far ahead */
|
||||
|
||||
static int blz_pack_( byte const* const in_min, int size,
|
||||
void* const out_min, blz_pack_t* const dict )
|
||||
{
|
||||
byte const* BLZ_RESTRICT in = in_min;
|
||||
byte const* const in_max = in + size - in_max_offset;
|
||||
|
||||
byte* out = (byte*) out_min;
|
||||
byte* const out_max = out + size;
|
||||
byte* out_bits;
|
||||
|
||||
unsigned data;
|
||||
bits_t bits = 2;
|
||||
|
||||
out [0] = size;
|
||||
out [1] = size >> 8;
|
||||
out [2] = size >> 16;
|
||||
out [3] = size >> 24;
|
||||
out [4] = in [0];
|
||||
out [5] = in [1];
|
||||
in += 2;
|
||||
out_bits = (out += 9);
|
||||
|
||||
literal: /* Literal byte */
|
||||
{
|
||||
int const t = *in;
|
||||
PRE_GOTO( 1 );
|
||||
*++out = t;
|
||||
if ( TOP_BIT( ++bits ) ) /* 3% */
|
||||
goto flush;
|
||||
}
|
||||
|
||||
match: /* Check for match and update dict */
|
||||
{
|
||||
/* get then update dict entry and handle end of input */
|
||||
int off = (data >> 12) ^ (data & 0xFFF);
|
||||
byte const* const BLZ_RESTRICT match = dict->dict [off];
|
||||
bits <<= 1;
|
||||
dict->dict [off] = in;
|
||||
if ( in >= in_max ) /* 1% */
|
||||
goto final_bytes;
|
||||
|
||||
/* compare first 3 bytes and pre-read 4th bytes */
|
||||
data ^= match [0];
|
||||
data ^= match [1] << 8;
|
||||
{
|
||||
unsigned const in3 = in [3];
|
||||
unsigned const match3 = match [3];
|
||||
if ( data != ((unsigned) match [2] << 16) ) /* 42% first 3 bytes don't match */
|
||||
goto literal;
|
||||
|
||||
off = in - match;
|
||||
if ( in3 != match3 ) /* 53% 3 byte match */
|
||||
{
|
||||
if ( off >= (1 << 13) ) /* 19% too far */
|
||||
goto literal;
|
||||
|
||||
/* LLLhhhhh llllllll */
|
||||
PRE_GOTO( 3 );
|
||||
*(out += 2) = off;
|
||||
out [-1] = (off >> 8) | (1 << 5);
|
||||
GOTO_NEXT
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/* 4-7 byte match */
|
||||
int len = 2 << 5;
|
||||
if ( *(in += 4) == match [4] ) /* 59% */
|
||||
{
|
||||
len = 3 << 5;
|
||||
if ( *++in == match [5] ) /* 66% */
|
||||
{
|
||||
len = 4 << 5;
|
||||
if ( *++in == match [6] ) /* 71% */
|
||||
{
|
||||
len = 5 << 5;
|
||||
if ( *++in == match [7] ) /* 75% */
|
||||
goto long_match;
|
||||
}
|
||||
}
|
||||
}
|
||||
PRE_GOTO( 0 );
|
||||
|
||||
/* Encode offset and length */
|
||||
if ( off < (1 << 13) ) /* 82% */
|
||||
{
|
||||
/* LLLhhhhh llllllll */
|
||||
*(out += 2) = off;
|
||||
out [-1] = (off >> 8) | len;
|
||||
GOTO_NEXT
|
||||
}
|
||||
|
||||
len >>= 5;
|
||||
if ( off < (1 << 16) ) /* 91% */
|
||||
{
|
||||
/* 000LLLLL llllllll hhhhhhhh */
|
||||
out [1] = len;
|
||||
out [2] = off;
|
||||
*(out += 3) = off >> 8;
|
||||
GOTO_NEXT
|
||||
}
|
||||
in -= 2;
|
||||
in -= len;
|
||||
goto literal;
|
||||
}
|
||||
|
||||
long_match:
|
||||
{
|
||||
/* 8+ byte match */
|
||||
byte const* const start = in - 4;
|
||||
off = -off;
|
||||
++in;
|
||||
{
|
||||
int x, y;
|
||||
do
|
||||
{
|
||||
x = *in;
|
||||
y = in [off];
|
||||
if ( in >= in_max )
|
||||
break;
|
||||
++in;
|
||||
}
|
||||
while ( x == y ); /* 92% */
|
||||
}
|
||||
|
||||
/* Encode offset and length */
|
||||
{
|
||||
int len = in - start;
|
||||
PRE_GOTO( -1 );
|
||||
off = -off;
|
||||
|
||||
if ( len < (1 << 5) ) /* 90% */
|
||||
{
|
||||
out [1] = len;
|
||||
if ( off < (1 << 16) ) /* 98% */
|
||||
{
|
||||
/* 000LLLLL llllllll hhhhhhhh */
|
||||
out [2] = off;
|
||||
*(out += 3) = off >> 8;
|
||||
GOTO_NEXT
|
||||
}
|
||||
|
||||
if ( len <= 9 - 2 ) /* 52% */
|
||||
{
|
||||
/* TODO: lame */
|
||||
in -= 2;
|
||||
in -= len;
|
||||
goto literal;
|
||||
}
|
||||
}
|
||||
|
||||
/* 8-bit 0, 32-bit offset, 32-bit length */
|
||||
out [1] = 0;
|
||||
out [2] = off;
|
||||
out [3] = off >> 8;
|
||||
out [4] = off >> 16;
|
||||
out [5] = off >> 24;
|
||||
out [6] = len;
|
||||
out [7] = len >> 8;
|
||||
out [8] = len >> 16;
|
||||
*(out += 9) = len >> 24;
|
||||
GOTO_NEXT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This is at bottom of loop to make branches here positive and branches back
|
||||
negative, which helps CPUs that lack dynamic branch prediction */
|
||||
|
||||
flush: /* Flush bits */
|
||||
out += 4;
|
||||
out_bits [-3] = (bits << 1) + 1;
|
||||
out_bits [-2] = bits >> 7;
|
||||
out_bits [-1] = bits >> 15;
|
||||
out_bits [ 0] = bits >> 23;
|
||||
out_bits = out;
|
||||
bits = 1;
|
||||
if ( out < out_max ) /* 99% */
|
||||
goto match;
|
||||
return -1; /* no compression */
|
||||
|
||||
final_bytes:
|
||||
/* Right-justify and flush final bits */
|
||||
{
|
||||
++bits;
|
||||
if ( (bits & 0xFFFF0000) == 0 )
|
||||
bits <<= 16;
|
||||
|
||||
if ( !TOP_BIT( bits ) )
|
||||
while ( !TOP_BIT( bits <<= 1 ) ) { }
|
||||
bits <<= 1;
|
||||
|
||||
out_bits [-3] = bits;
|
||||
out_bits [-2] = bits >> 8;
|
||||
out_bits [-1] = bits >> 16;
|
||||
out_bits [ 0] = bits >> 24;
|
||||
}
|
||||
|
||||
{
|
||||
byte const* const end = in_max + in_max_offset;
|
||||
|
||||
/* Remaining bytes should be in narrow range */
|
||||
assert( end - in >= in_max_offset - 6 );
|
||||
assert( end - in <= in_max_offset + 1 );
|
||||
|
||||
/* End marker */
|
||||
out [1] = 0;
|
||||
out [2] = 0;
|
||||
out [3] = 0;
|
||||
*(out += 4) = 0;
|
||||
|
||||
/* Copy final bytes */
|
||||
do
|
||||
{
|
||||
*++out = *in++;
|
||||
}
|
||||
while ( in < end );
|
||||
}
|
||||
|
||||
return out + 1 - (byte*) out_min;
|
||||
}
|
||||
|
||||
int blz_pack( void const* in_min, int size, void* out, blz_pack_t* dict )
|
||||
{
|
||||
byte const* in = (byte const*) in_min;
|
||||
assert( (unsigned) size <= 0x7FFFFFFF );
|
||||
if ( size >= 21 && dict ) /* 21 repeated bytes compress to 24 bytes */
|
||||
{
|
||||
/* clear dict */
|
||||
byte const** dout = dict->dict;
|
||||
int count;
|
||||
in += 1; /* avoid match at beginning since out is one less in unpack */
|
||||
for ( count = 0x1000; count--; )
|
||||
*dout++ = in;
|
||||
in -= 1;
|
||||
|
||||
{
|
||||
int out_size = blz_pack_( in, size, out, dict );
|
||||
if ( (unsigned) out_size < (unsigned) size + 4 )
|
||||
return out_size;
|
||||
}
|
||||
}
|
||||
((byte*) out) [0] = size;
|
||||
((byte*) out) [1] = size >> 8;
|
||||
((byte*) out) [2] = size >> 16;
|
||||
((byte*) out) [3] = 0x80 | (size >> 24);
|
||||
memcpy( (byte*) out + 4, in, size );
|
||||
|
||||
#ifndef NDEBUG
|
||||
{
|
||||
volatile bits_t i = 0x40000000;
|
||||
assert( !TOP_BIT( i ) && TOP_BIT( i << 1 ) && !TOP_BIT( i << 2 ) && !ALL_BITS( i << 2 ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
return size + 4;
|
||||
}
|
||||
|
||||
/* Unpack */
|
||||
|
||||
int blz_size( void const* in_ )
|
||||
{
|
||||
byte const* in = (byte const*) in_;
|
||||
return in [0] | (in [1] << 8) | (in [2] << 16) | (in [3] << 24 & 0x7F);
|
||||
}
|
||||
|
||||
int blz_unpack( void const* in_min, void* out_min )
|
||||
{
|
||||
byte const* BLZ_RESTRICT in = (byte const*) in_min;
|
||||
byte* out = (byte*) out_min;
|
||||
bits_t out_size = in [0] | (in [1] << 8) | (in [2] << 16) | (in [3] << 24);
|
||||
in += 4;
|
||||
|
||||
if ( !TOP_BIT( out_size ) )
|
||||
{
|
||||
byte* const out_max = out + out_size - 2;
|
||||
unsigned data; /* usually holds next input byte, read ahead of time */
|
||||
bits_t bits;
|
||||
|
||||
*out = in [0];
|
||||
*++out = in [1];
|
||||
in += 2;
|
||||
|
||||
refill: { /* Refill bits */
|
||||
bits_t first = (in [3] << 24);
|
||||
bits = in [0] | first | (in [1] << 8) | (in [2] << 16);
|
||||
data = *(in += 4);
|
||||
if ( TOP_BIT( first ) ) /* 48% */
|
||||
goto literal;
|
||||
if ( !bits ) /* 1% */
|
||||
goto final_bytes;
|
||||
}
|
||||
|
||||
match: { /* Matching symbol */
|
||||
int len, off;
|
||||
bits <<= 1;
|
||||
off = *++in;
|
||||
len = data >> 5;
|
||||
data &= 0x1F;
|
||||
if ( !len ) /* 17% */
|
||||
goto long_match;
|
||||
|
||||
copy_bytes: /* Copy len+2 bytes from out-off to out */
|
||||
off |= data << 8;
|
||||
{
|
||||
byte const* match = out - off;
|
||||
/*assert( len > 0 && (size_t) (match - (byte*) out_min) < (size_t) out_size );*/
|
||||
|
||||
/* match may = out + 1, so can't read ahead at all */
|
||||
out [1] = match [1];
|
||||
*(out += 2) = match [2];
|
||||
data = *(match += 3);
|
||||
if ( --len ) /* 50% */
|
||||
{
|
||||
do
|
||||
{
|
||||
*++out = data;
|
||||
data = *++match;
|
||||
}
|
||||
while ( --len ); /* 80% */
|
||||
}
|
||||
*++out = data;
|
||||
}
|
||||
|
||||
data = *++in;
|
||||
if ( !TOP_BIT( bits ) ) /* 58% */
|
||||
goto match;
|
||||
literal:
|
||||
if ( ALL_BITS( bits <<= 1 ) == 0 ) /* 7% */
|
||||
goto refill;
|
||||
|
||||
/* Literal byte */
|
||||
*++out = data;
|
||||
data = *++in;
|
||||
if ( TOP_BIT( bits ) ) /* 60% */
|
||||
goto literal;
|
||||
|
||||
/* Start decoding match */
|
||||
bits <<= 1;
|
||||
off = *++in;
|
||||
len = data >> 5;
|
||||
data &= 0x1F;
|
||||
if ( len ) /* 82% */
|
||||
goto copy_bytes;
|
||||
|
||||
long_match: /* Longer match encodings */
|
||||
len = data;
|
||||
data = *++in;
|
||||
if ( len ) /* 93% */
|
||||
goto copy_bytes;
|
||||
|
||||
off |= in [1] << 16;
|
||||
off |= in [2] << 24;
|
||||
len = in [3];
|
||||
len |= in [4] << 8;
|
||||
len |= in [5] << 16;
|
||||
len |= *(in += 6) << 24;
|
||||
goto copy_bytes;
|
||||
}
|
||||
|
||||
final_bytes: /* Copy final bytes */
|
||||
do
|
||||
{
|
||||
*++out = data;
|
||||
data = *++in;
|
||||
}
|
||||
while ( out < out_max );
|
||||
*++out = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy( out, in, out_size ^= 0x80000000u );
|
||||
}
|
||||
return out_size;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,40 +0,0 @@
|
||||
/* Fast data compressor for keeping data compressed in memory. Data format subject
|
||||
to change, so not suitable for long-term storage or transfer between computers. */
|
||||
|
||||
/* blz 0.9.1 */
|
||||
#ifndef BLZ_H
|
||||
#define BLZ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* All functions are thread-safe */
|
||||
|
||||
/* Temporary buffer type that you must allocate. Does NOT need to be cleared
|
||||
before calling blz_pack(), and can be freed immediately afterwards. */
|
||||
typedef struct blz_pack_t { unsigned char const* dict [0x1000]; } blz_pack_t;
|
||||
|
||||
/* Compresses data_size bytes from data_in to packed_out and returns packed size,
|
||||
at most data_size + blz_worst_case. Requires data_size + blz_pack_extra bytes
|
||||
allocated to packed_out. Requires that data_size be 0 to 0x7FFFFFFF (2 GB).
|
||||
If temp is NULL, stores data uncompressed. */
|
||||
enum { blz_pack_extra = 320 };
|
||||
enum { blz_worst_case = 4 };
|
||||
int blz_pack( void const* data_in, int data_size, void* packed_out, blz_pack_t* temp );
|
||||
|
||||
/* Decompresses from packed_in to data_out and returns original data size.
|
||||
Does NOT do any consistency checking, so corrupt data can crash program. */
|
||||
int blz_unpack( void const* packed_in, void* data_out );
|
||||
|
||||
/* Size of original data before compression */
|
||||
int blz_size( void const* packed_in );
|
||||
|
||||
/* String describing version of blz. Currently either "fast" or "slow". */
|
||||
extern char const blz_version [];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,180 +0,0 @@
|
||||
/* ioapi.c -- IO base function header for compress/uncompress .zip
|
||||
files using zlib + zip or unzip API
|
||||
|
||||
Version 1.01e, February 12th, 2005
|
||||
|
||||
Copyright (C) 1998-2005 Gilles Vollant
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zlib.h"
|
||||
#ifndef OF
|
||||
#define OF(a) a
|
||||
#endif
|
||||
#include "ioapi.h"
|
||||
|
||||
|
||||
|
||||
/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
|
||||
|
||||
#ifndef SEEK_CUR
|
||||
#define SEEK_CUR 1
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_END
|
||||
#define SEEK_END 2
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0
|
||||
#endif
|
||||
|
||||
voidpf ZCALLBACK fopen_file_func OF((
|
||||
voidpf opaque,
|
||||
const char* filename,
|
||||
int mode));
|
||||
|
||||
uLong ZCALLBACK fread_file_func OF((
|
||||
voidpf opaque,
|
||||
voidpf stream,
|
||||
void* buf,
|
||||
uLong size));
|
||||
|
||||
uLong ZCALLBACK fwrite_file_func OF((
|
||||
voidpf opaque,
|
||||
voidpf stream,
|
||||
const void* buf,
|
||||
uLong size));
|
||||
|
||||
long ZCALLBACK ftell_file_func OF((
|
||||
voidpf opaque,
|
||||
voidpf stream));
|
||||
|
||||
long ZCALLBACK fseek_file_func OF((
|
||||
voidpf opaque,
|
||||
voidpf stream,
|
||||
uLong offset,
|
||||
int origin));
|
||||
|
||||
int ZCALLBACK fclose_file_func OF((
|
||||
voidpf opaque,
|
||||
voidpf stream));
|
||||
|
||||
int ZCALLBACK ferror_file_func OF((
|
||||
voidpf opaque,
|
||||
voidpf stream));
|
||||
|
||||
|
||||
voidpf ZCALLBACK fopen_file_func (opaque, filename, mode)
|
||||
voidpf opaque;
|
||||
const char* filename;
|
||||
int mode;
|
||||
{
|
||||
FILE* file = NULL;
|
||||
const char* mode_fopen = NULL;
|
||||
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
|
||||
mode_fopen = "rb";
|
||||
else
|
||||
if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
|
||||
mode_fopen = "r+b";
|
||||
else
|
||||
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
|
||||
mode_fopen = "wb";
|
||||
|
||||
if ((filename!=NULL) && (mode_fopen != NULL))
|
||||
file = fopen(filename, mode_fopen);
|
||||
return file;
|
||||
}
|
||||
|
||||
|
||||
uLong ZCALLBACK fread_file_func (opaque, stream, buf, size)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
void* buf;
|
||||
uLong size;
|
||||
{
|
||||
uLong ret;
|
||||
ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
const void* buf;
|
||||
uLong size;
|
||||
{
|
||||
uLong ret;
|
||||
ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
long ZCALLBACK ftell_file_func (opaque, stream)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
{
|
||||
long ret;
|
||||
ret = ftell((FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
long ZCALLBACK fseek_file_func (opaque, stream, offset, origin)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
uLong offset;
|
||||
int origin;
|
||||
{
|
||||
int fseek_origin=0;
|
||||
long ret;
|
||||
switch (origin)
|
||||
{
|
||||
case ZLIB_FILEFUNC_SEEK_CUR :
|
||||
fseek_origin = SEEK_CUR;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_END :
|
||||
fseek_origin = SEEK_END;
|
||||
break;
|
||||
case ZLIB_FILEFUNC_SEEK_SET :
|
||||
fseek_origin = SEEK_SET;
|
||||
break;
|
||||
default: return -1;
|
||||
}
|
||||
ret = 0;
|
||||
fseek((FILE *)stream, offset, fseek_origin);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ZCALLBACK fclose_file_func (opaque, stream)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
{
|
||||
int ret;
|
||||
ret = fclose((FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ZCALLBACK ferror_file_func (opaque, stream)
|
||||
voidpf opaque;
|
||||
voidpf stream;
|
||||
{
|
||||
int ret;
|
||||
ret = ferror((FILE *)stream);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fill_fopen_filefunc (pzlib_filefunc_def)
|
||||
zlib_filefunc_def* pzlib_filefunc_def;
|
||||
{
|
||||
pzlib_filefunc_def->zopen_file = fopen_file_func;
|
||||
pzlib_filefunc_def->zread_file = fread_file_func;
|
||||
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
|
||||
pzlib_filefunc_def->ztell_file = ftell_file_func;
|
||||
pzlib_filefunc_def->zseek_file = fseek_file_func;
|
||||
pzlib_filefunc_def->zclose_file = fclose_file_func;
|
||||
pzlib_filefunc_def->zerror_file = ferror_file_func;
|
||||
pzlib_filefunc_def->opaque = NULL;
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/* ioapi.h -- IO base function header for compress/uncompress .zip
|
||||
files using zlib + zip or unzip API
|
||||
|
||||
Version 1.01e, February 12th, 2005
|
||||
|
||||
Copyright (C) 1998-2005 Gilles Vollant
|
||||
*/
|
||||
|
||||
#ifndef _ZLIBIOAPI_H
|
||||
#define _ZLIBIOAPI_H
|
||||
|
||||
|
||||
#define ZLIB_FILEFUNC_SEEK_CUR (1)
|
||||
#define ZLIB_FILEFUNC_SEEK_END (2)
|
||||
#define ZLIB_FILEFUNC_SEEK_SET (0)
|
||||
|
||||
#define ZLIB_FILEFUNC_MODE_READ (1)
|
||||
#define ZLIB_FILEFUNC_MODE_WRITE (2)
|
||||
#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
|
||||
|
||||
#define ZLIB_FILEFUNC_MODE_EXISTING (4)
|
||||
#define ZLIB_FILEFUNC_MODE_CREATE (8)
|
||||
|
||||
|
||||
#ifndef ZCALLBACK
|
||||
|
||||
#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
|
||||
#define ZCALLBACK CALLBACK
|
||||
#else
|
||||
#define ZCALLBACK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
|
||||
typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
|
||||
typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
|
||||
typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
|
||||
typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
|
||||
typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
|
||||
|
||||
typedef struct zlib_filefunc_def_s
|
||||
{
|
||||
open_file_func zopen_file;
|
||||
read_file_func zread_file;
|
||||
write_file_func zwrite_file;
|
||||
tell_file_func ztell_file;
|
||||
seek_file_func zseek_file;
|
||||
close_file_func zclose_file;
|
||||
testerror_file_func zerror_file;
|
||||
voidpf opaque;
|
||||
} zlib_filefunc_def;
|
||||
|
||||
|
||||
|
||||
void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
|
||||
|
||||
#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size))
|
||||
#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size))
|
||||
#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream))
|
||||
#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode))
|
||||
#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream))
|
||||
#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream))
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,446 +0,0 @@
|
||||
/* lzoconf.h -- configuration of the LZO data compression library
|
||||
|
||||
This file is part of the LZO real-time data compression library.
|
||||
|
||||
Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
The LZO library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
The LZO library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the LZO library; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
http://www.oberhumer.com/opensource/lzo/
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __LZOCONF_H_INCLUDED
|
||||
#define __LZOCONF_H_INCLUDED 1
|
||||
|
||||
#define LZO_VERSION 0x2060
|
||||
#define LZO_VERSION_STRING "2.06"
|
||||
#define LZO_VERSION_DATE "Aug 12 2011"
|
||||
|
||||
/* internal Autoconf configuration file - only used when building LZO */
|
||||
#if defined(LZO_HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// LZO requires a conforming <limits.h>
|
||||
************************************************************************/
|
||||
|
||||
#if !defined(CHAR_BIT) || (CHAR_BIT != 8)
|
||||
# error "invalid CHAR_BIT"
|
||||
#endif
|
||||
#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
|
||||
# error "check your compiler installation"
|
||||
#endif
|
||||
#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1)
|
||||
# error "your limits.h macros are broken"
|
||||
#endif
|
||||
|
||||
/* get OS and architecture defines */
|
||||
#ifndef __LZODEFS_H_INCLUDED
|
||||
#include "lzodefs.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// some core defines
|
||||
************************************************************************/
|
||||
|
||||
#if !defined(LZO_UINT32_C)
|
||||
# if (UINT_MAX < LZO_0xffffffffL)
|
||||
# define LZO_UINT32_C(c) c ## UL
|
||||
# else
|
||||
# define LZO_UINT32_C(c) ((c) + 0U)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* memory checkers */
|
||||
#if !defined(__LZO_CHECKER)
|
||||
# if defined(__BOUNDS_CHECKING_ON)
|
||||
# define __LZO_CHECKER 1
|
||||
# elif defined(__CHECKER__)
|
||||
# define __LZO_CHECKER 1
|
||||
# elif defined(__INSURE__)
|
||||
# define __LZO_CHECKER 1
|
||||
# elif defined(__PURIFY__)
|
||||
# define __LZO_CHECKER 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// integral and pointer types
|
||||
************************************************************************/
|
||||
|
||||
/* lzo_uint should match size_t */
|
||||
#if !defined(LZO_UINT_MAX)
|
||||
# if defined(LZO_ABI_LLP64) /* WIN64 */
|
||||
# if defined(LZO_OS_WIN64)
|
||||
typedef unsigned __int64 lzo_uint;
|
||||
typedef __int64 lzo_int;
|
||||
# else
|
||||
typedef unsigned long long lzo_uint;
|
||||
typedef long long lzo_int;
|
||||
# endif
|
||||
# define LZO_UINT_MAX 0xffffffffffffffffull
|
||||
# define LZO_INT_MAX 9223372036854775807LL
|
||||
# define LZO_INT_MIN (-1LL - LZO_INT_MAX)
|
||||
# elif defined(LZO_ABI_IP32L64) /* MIPS R5900 */
|
||||
typedef unsigned int lzo_uint;
|
||||
typedef int lzo_int;
|
||||
# define LZO_UINT_MAX UINT_MAX
|
||||
# define LZO_INT_MAX INT_MAX
|
||||
# define LZO_INT_MIN INT_MIN
|
||||
# elif (ULONG_MAX >= LZO_0xffffffffL)
|
||||
typedef unsigned long lzo_uint;
|
||||
typedef long lzo_int;
|
||||
# define LZO_UINT_MAX ULONG_MAX
|
||||
# define LZO_INT_MAX LONG_MAX
|
||||
# define LZO_INT_MIN LONG_MIN
|
||||
# else
|
||||
# error "lzo_uint"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Integral types with 32 bits or more. */
|
||||
#if !defined(LZO_UINT32_MAX)
|
||||
# if (UINT_MAX >= LZO_0xffffffffL)
|
||||
typedef unsigned int lzo_uint32;
|
||||
typedef int lzo_int32;
|
||||
# define LZO_UINT32_MAX UINT_MAX
|
||||
# define LZO_INT32_MAX INT_MAX
|
||||
# define LZO_INT32_MIN INT_MIN
|
||||
# elif (ULONG_MAX >= LZO_0xffffffffL)
|
||||
typedef unsigned long lzo_uint32;
|
||||
typedef long lzo_int32;
|
||||
# define LZO_UINT32_MAX ULONG_MAX
|
||||
# define LZO_INT32_MAX LONG_MAX
|
||||
# define LZO_INT32_MIN LONG_MIN
|
||||
# else
|
||||
# error "lzo_uint32"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Integral types with exactly 64 bits. */
|
||||
#if !defined(LZO_UINT64_MAX)
|
||||
# if (LZO_UINT_MAX >= LZO_0xffffffffL)
|
||||
# if ((((LZO_UINT_MAX) >> 31) >> 31) == 3)
|
||||
# define lzo_uint64 lzo_uint
|
||||
# define lzo_int64 lzo_int
|
||||
# define LZO_UINT64_MAX LZO_UINT_MAX
|
||||
# define LZO_INT64_MAX LZO_INT_MAX
|
||||
# define LZO_INT64_MIN LZO_INT_MIN
|
||||
# endif
|
||||
# elif (ULONG_MAX >= LZO_0xffffffffL)
|
||||
# if ((((ULONG_MAX) >> 31) >> 31) == 3)
|
||||
typedef unsigned long lzo_uint64;
|
||||
typedef long lzo_int64;
|
||||
# define LZO_UINT64_MAX ULONG_MAX
|
||||
# define LZO_INT64_MAX LONG_MAX
|
||||
# define LZO_INT64_MIN LONG_MIN
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The larger type of lzo_uint and lzo_uint32. */
|
||||
#if (LZO_UINT_MAX >= LZO_UINT32_MAX)
|
||||
# define lzo_xint lzo_uint
|
||||
#else
|
||||
# define lzo_xint lzo_uint32
|
||||
#endif
|
||||
|
||||
/* Memory model that allows to access memory at offsets of lzo_uint. */
|
||||
#if !defined(__LZO_MMODEL)
|
||||
# if (LZO_UINT_MAX <= UINT_MAX)
|
||||
# define __LZO_MMODEL /*empty*/
|
||||
# elif defined(LZO_HAVE_MM_HUGE_PTR)
|
||||
# define __LZO_MMODEL_HUGE 1
|
||||
# define __LZO_MMODEL __huge
|
||||
# else
|
||||
# define __LZO_MMODEL /*empty*/
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* no typedef here because of const-pointer issues */
|
||||
#define lzo_bytep unsigned char __LZO_MMODEL *
|
||||
#define lzo_charp char __LZO_MMODEL *
|
||||
#define lzo_voidp void __LZO_MMODEL *
|
||||
#define lzo_shortp short __LZO_MMODEL *
|
||||
#define lzo_ushortp unsigned short __LZO_MMODEL *
|
||||
#define lzo_uint32p lzo_uint32 __LZO_MMODEL *
|
||||
#define lzo_int32p lzo_int32 __LZO_MMODEL *
|
||||
#if defined(LZO_UINT64_MAX)
|
||||
#define lzo_uint64p lzo_uint64 __LZO_MMODEL *
|
||||
#define lzo_int64p lzo_int64 __LZO_MMODEL *
|
||||
#endif
|
||||
#define lzo_uintp lzo_uint __LZO_MMODEL *
|
||||
#define lzo_intp lzo_int __LZO_MMODEL *
|
||||
#define lzo_xintp lzo_xint __LZO_MMODEL *
|
||||
#define lzo_voidpp lzo_voidp __LZO_MMODEL *
|
||||
#define lzo_bytepp lzo_bytep __LZO_MMODEL *
|
||||
/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */
|
||||
#define lzo_byte unsigned char __LZO_MMODEL
|
||||
|
||||
typedef int lzo_bool;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// function types
|
||||
************************************************************************/
|
||||
|
||||
/* name mangling */
|
||||
#if !defined(__LZO_EXTERN_C)
|
||||
# ifdef __cplusplus
|
||||
# define __LZO_EXTERN_C extern "C"
|
||||
# else
|
||||
# define __LZO_EXTERN_C extern
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* calling convention */
|
||||
#if !defined(__LZO_CDECL)
|
||||
# define __LZO_CDECL __lzo_cdecl
|
||||
#endif
|
||||
|
||||
/* DLL export information */
|
||||
#if !defined(__LZO_EXPORT1)
|
||||
# define __LZO_EXPORT1 /*empty*/
|
||||
#endif
|
||||
#if !defined(__LZO_EXPORT2)
|
||||
# define __LZO_EXPORT2 /*empty*/
|
||||
#endif
|
||||
|
||||
/* __cdecl calling convention for public C and assembly functions */
|
||||
#if !defined(LZO_PUBLIC)
|
||||
# define LZO_PUBLIC(_rettype) __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL
|
||||
#endif
|
||||
#if !defined(LZO_EXTERN)
|
||||
# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype)
|
||||
#endif
|
||||
#if !defined(LZO_PRIVATE)
|
||||
# define LZO_PRIVATE(_rettype) static _rettype __LZO_CDECL
|
||||
#endif
|
||||
|
||||
/* function types */
|
||||
typedef int
|
||||
(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem );
|
||||
|
||||
typedef int
|
||||
(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem );
|
||||
|
||||
typedef int
|
||||
(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem );
|
||||
|
||||
typedef int
|
||||
(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem,
|
||||
const lzo_bytep dict, lzo_uint dict_len );
|
||||
|
||||
typedef int
|
||||
(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem,
|
||||
const lzo_bytep dict, lzo_uint dict_len );
|
||||
|
||||
|
||||
/* Callback interface. Currently only the progress indicator ("nprogress")
|
||||
* is used, but this may change in a future release. */
|
||||
|
||||
struct lzo_callback_t;
|
||||
typedef struct lzo_callback_t lzo_callback_t;
|
||||
#define lzo_callback_p lzo_callback_t __LZO_MMODEL *
|
||||
|
||||
/* malloc & free function types */
|
||||
typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t)
|
||||
(lzo_callback_p self, lzo_uint items, lzo_uint size);
|
||||
typedef void (__LZO_CDECL *lzo_free_func_t)
|
||||
(lzo_callback_p self, lzo_voidp ptr);
|
||||
|
||||
/* a progress indicator callback function */
|
||||
typedef void (__LZO_CDECL *lzo_progress_func_t)
|
||||
(lzo_callback_p, lzo_uint, lzo_uint, int);
|
||||
|
||||
struct lzo_callback_t
|
||||
{
|
||||
/* custom allocators (set to 0 to disable) */
|
||||
lzo_alloc_func_t nalloc; /* [not used right now] */
|
||||
lzo_free_func_t nfree; /* [not used right now] */
|
||||
|
||||
/* a progress indicator callback function (set to 0 to disable) */
|
||||
lzo_progress_func_t nprogress;
|
||||
|
||||
/* NOTE: the first parameter "self" of the nalloc/nfree/nprogress
|
||||
* callbacks points back to this struct, so you are free to store
|
||||
* some extra info in the following variables. */
|
||||
lzo_voidp user1;
|
||||
lzo_xint user2;
|
||||
lzo_xint user3;
|
||||
};
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// error codes and prototypes
|
||||
************************************************************************/
|
||||
|
||||
/* Error codes for the compression/decompression functions. Negative
|
||||
* values are errors, positive values will be used for special but
|
||||
* normal events.
|
||||
*/
|
||||
#define LZO_E_OK 0
|
||||
#define LZO_E_ERROR (-1)
|
||||
#define LZO_E_OUT_OF_MEMORY (-2) /* [lzo_alloc_func_t failure] */
|
||||
#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */
|
||||
#define LZO_E_INPUT_OVERRUN (-4)
|
||||
#define LZO_E_OUTPUT_OVERRUN (-5)
|
||||
#define LZO_E_LOOKBEHIND_OVERRUN (-6)
|
||||
#define LZO_E_EOF_NOT_FOUND (-7)
|
||||
#define LZO_E_INPUT_NOT_CONSUMED (-8)
|
||||
#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */
|
||||
#define LZO_E_INVALID_ARGUMENT (-10)
|
||||
|
||||
|
||||
#ifndef lzo_sizeof_dict_t
|
||||
# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep))
|
||||
#endif
|
||||
|
||||
/* lzo_init() should be the first function you call.
|
||||
* Check the return code !
|
||||
*
|
||||
* lzo_init() is a macro to allow checking that the library and the
|
||||
* compiler's view of various types are consistent.
|
||||
*/
|
||||
#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\
|
||||
(int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\
|
||||
(int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\
|
||||
(int)sizeof(lzo_callback_t))
|
||||
LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int);
|
||||
|
||||
/* version functions (useful for shared libraries) */
|
||||
LZO_EXTERN(unsigned) lzo_version(void);
|
||||
LZO_EXTERN(const char *) lzo_version_string(void);
|
||||
LZO_EXTERN(const char *) lzo_version_date(void);
|
||||
LZO_EXTERN(const lzo_charp) _lzo_version_string(void);
|
||||
LZO_EXTERN(const lzo_charp) _lzo_version_date(void);
|
||||
|
||||
/* string functions */
|
||||
LZO_EXTERN(int)
|
||||
lzo_memcmp(const lzo_voidp a, const lzo_voidp b, lzo_uint len);
|
||||
LZO_EXTERN(lzo_voidp)
|
||||
lzo_memcpy(lzo_voidp dst, const lzo_voidp src, lzo_uint len);
|
||||
LZO_EXTERN(lzo_voidp)
|
||||
lzo_memmove(lzo_voidp dst, const lzo_voidp src, lzo_uint len);
|
||||
LZO_EXTERN(lzo_voidp)
|
||||
lzo_memset(lzo_voidp buf, int c, lzo_uint len);
|
||||
|
||||
/* checksum functions */
|
||||
LZO_EXTERN(lzo_uint32)
|
||||
lzo_adler32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
|
||||
LZO_EXTERN(lzo_uint32)
|
||||
lzo_crc32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
|
||||
LZO_EXTERN(const lzo_uint32p)
|
||||
lzo_get_crc32_table(void);
|
||||
|
||||
/* misc. */
|
||||
LZO_EXTERN(int) _lzo_config_check(void);
|
||||
typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u;
|
||||
typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u;
|
||||
typedef union { void *vp; lzo_bytep bp; lzo_uint u; lzo_uint32 u32; unsigned long l; } lzo_align_t;
|
||||
|
||||
/* align a char pointer on a boundary that is a multiple of 'size' */
|
||||
LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size);
|
||||
#define LZO_PTR_ALIGN_UP(p,size) \
|
||||
((p) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(p),(lzo_uint)(size)))
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
// deprecated macros - only for backward compatibility with LZO v1.xx
|
||||
************************************************************************/
|
||||
|
||||
#if defined(LZO_CFG_COMPAT)
|
||||
|
||||
#define __LZOCONF_H 1
|
||||
|
||||
#if defined(LZO_ARCH_I086)
|
||||
# define __LZO_i386 1
|
||||
#elif defined(LZO_ARCH_I386)
|
||||
# define __LZO_i386 1
|
||||
#endif
|
||||
|
||||
#if defined(LZO_OS_DOS16)
|
||||
# define __LZO_DOS 1
|
||||
# define __LZO_DOS16 1
|
||||
#elif defined(LZO_OS_DOS32)
|
||||
# define __LZO_DOS 1
|
||||
#elif defined(LZO_OS_WIN16)
|
||||
# define __LZO_WIN 1
|
||||
# define __LZO_WIN16 1
|
||||
#elif defined(LZO_OS_WIN32)
|
||||
# define __LZO_WIN 1
|
||||
#endif
|
||||
|
||||
#define __LZO_CMODEL /*empty*/
|
||||
#define __LZO_DMODEL /*empty*/
|
||||
#define __LZO_ENTRY __LZO_CDECL
|
||||
#define LZO_EXTERN_CDECL LZO_EXTERN
|
||||
#define LZO_ALIGN LZO_PTR_ALIGN_UP
|
||||
|
||||
#define lzo_compress_asm_t lzo_compress_t
|
||||
#define lzo_decompress_asm_t lzo_decompress_t
|
||||
|
||||
#endif /* LZO_CFG_COMPAT */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/* vim:set ts=4 et: */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,109 +0,0 @@
|
||||
/* minilzo.h -- mini subset of the LZO real-time data compression library
|
||||
|
||||
This file is part of the LZO real-time data compression library.
|
||||
|
||||
Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
The LZO library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
The LZO library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with the LZO library; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
http://www.oberhumer.com/opensource/lzo/
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* the full LZO package can be found at
|
||||
* http://www.oberhumer.com/opensource/lzo/
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __MINILZO_H
|
||||
#define __MINILZO_H 1
|
||||
|
||||
#define MINILZO_VERSION 0x2060
|
||||
|
||||
#ifdef __LZOCONF_H
|
||||
# error "you cannot use both LZO and miniLZO"
|
||||
#endif
|
||||
|
||||
#undef LZO_HAVE_CONFIG_H
|
||||
#include "lzoconf.h"
|
||||
|
||||
#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION)
|
||||
# error "version mismatch in header files"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
//
|
||||
************************************************************************/
|
||||
|
||||
/* Memory required for the wrkmem parameter.
|
||||
* When the required size is 0, you can also pass a NULL pointer.
|
||||
*/
|
||||
|
||||
#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS
|
||||
#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t))
|
||||
#define LZO1X_MEM_DECOMPRESS (0)
|
||||
|
||||
|
||||
/* compression */
|
||||
LZO_EXTERN(int)
|
||||
lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem );
|
||||
|
||||
/* decompression */
|
||||
LZO_EXTERN(int)
|
||||
lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem /* NOT USED */ );
|
||||
|
||||
/* safe decompression with overrun testing */
|
||||
LZO_EXTERN(int)
|
||||
lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len,
|
||||
lzo_bytep dst, lzo_uintp dst_len,
|
||||
lzo_voidp wrkmem /* NOT USED */ );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* already included */
|
||||
|
@ -1,888 +0,0 @@
|
||||
// QuickLZ data compression library
|
||||
// Copyright (C) 2006-2008 Lasse Mikkel Reinhold
|
||||
// lar@quicklz.com
|
||||
//
|
||||
// QuickLZ can be used for free under the GPL-1 or GPL-2 license (where anything
|
||||
// released into public must be open source) or under a commercial license if such
|
||||
// has been acquired (see http://www.quicklz.com/order.html). The commercial license
|
||||
// does not cover derived or ported versions created by third parties under GPL.
|
||||
|
||||
#include "quicklz.h"
|
||||
|
||||
int qlz_get_setting(int setting)
|
||||
{
|
||||
switch (setting)
|
||||
{
|
||||
case 0: return COMPRESSION_LEVEL;
|
||||
case 1: return SCRATCH_COMPRESS;
|
||||
case 2: return SCRATCH_DECOMPRESS;
|
||||
case 3: return STREAMING_MODE_VALUE;
|
||||
#ifdef test_rle
|
||||
case 4: return 1;
|
||||
#else
|
||||
case 4: return 0;
|
||||
#endif
|
||||
#ifdef speedup_incompressible
|
||||
case 5: return 1;
|
||||
#else
|
||||
case 5: return 0;
|
||||
#endif
|
||||
#ifdef memory_safe
|
||||
case 6: return 1;
|
||||
#else
|
||||
case 6: return 0;
|
||||
#endif
|
||||
case 7: return QLZ_VERSION_MAJOR;
|
||||
case 8: return QLZ_VERSION_MINOR;
|
||||
case 9: return QLZ_VERSION_REVISION;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
__inline unsigned int hash_func(unsigned int i)
|
||||
{
|
||||
return ((i >> 12) ^ i) & 0x0fff;
|
||||
}
|
||||
|
||||
__inline unsigned int fast_read(void const *src, unsigned int bytes)
|
||||
{
|
||||
#ifndef X86X64
|
||||
unsigned char *p = (unsigned char*)src;
|
||||
switch (bytes)
|
||||
{
|
||||
case 4:
|
||||
return(*p | *(p + 1) << 8 | *(p + 2) << 16 | *(p + 3) << 24);
|
||||
case 3:
|
||||
return(*p | *(p + 1) << 8 | *(p + 2) << 16);
|
||||
case 2:
|
||||
return(*p | *(p + 1) << 8);
|
||||
case 1:
|
||||
return(*p);
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
if (bytes >= 1 && bytes <= 4)
|
||||
return *((unsigned int*)src);
|
||||
else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
__inline void fast_write(unsigned int f, void *dst, unsigned int bytes)
|
||||
{
|
||||
#ifndef X86X64
|
||||
unsigned char *p = (unsigned char*)dst;
|
||||
|
||||
switch (bytes)
|
||||
{
|
||||
case 4:
|
||||
*p = (unsigned char)f;
|
||||
*(p + 1) = (unsigned char)(f >> 8);
|
||||
*(p + 2) = (unsigned char)(f >> 16);
|
||||
*(p + 3) = (unsigned char)(f >> 24);
|
||||
return;
|
||||
case 3:
|
||||
*p = (unsigned char)f;
|
||||
*(p + 1) = (unsigned char)(f >> 8);
|
||||
*(p + 2) = (unsigned char)(f >> 16);
|
||||
return;
|
||||
case 2:
|
||||
*p = (unsigned char)f;
|
||||
*(p + 1) = (unsigned char)(f >> 8);
|
||||
return;
|
||||
case 1:
|
||||
*p = (unsigned char)f;
|
||||
return;
|
||||
}
|
||||
#else
|
||||
switch (bytes)
|
||||
{
|
||||
case 4:
|
||||
*((unsigned int*)dst) = f;
|
||||
return;
|
||||
case 3:
|
||||
*((unsigned int*)dst) = f;
|
||||
return;
|
||||
case 2:
|
||||
#if COMPRESSION_LEVEL == 0
|
||||
// 2 byte writes are common in level 0
|
||||
*((unsigned short int*)dst) = (unsigned short int)f;
|
||||
#else
|
||||
*((unsigned int*)dst) = f;
|
||||
#endif
|
||||
return;
|
||||
case 1:
|
||||
*((unsigned char*)dst) = (unsigned char)f;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
__inline void memcpy_up(unsigned char *dst, const unsigned char *src, unsigned int n)
|
||||
{
|
||||
// cannot be replaced by overlap handling of memmove() due to LZSS algorithm
|
||||
#ifndef X86X64
|
||||
|
||||
if(n > 8 && src + n < dst)
|
||||
memcpy(dst, src, n);
|
||||
else
|
||||
{
|
||||
unsigned char *end = dst + n;
|
||||
while(dst < end)
|
||||
{
|
||||
*dst = *src;
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (n < 5)
|
||||
*((unsigned int*)dst) = *((unsigned int*)src);
|
||||
else
|
||||
{
|
||||
unsigned char *end = dst + n;
|
||||
while(dst < end)
|
||||
{
|
||||
*((unsigned int*)dst) = *((unsigned int*)src);
|
||||
dst = dst + 4;
|
||||
src = src + 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
__inline unsigned int fast_read_safe(void const *src, unsigned int bytes, const unsigned char *invalid)
|
||||
{
|
||||
#ifdef memory_safe
|
||||
if ((const unsigned char *)src + 4 > (const unsigned char *)invalid)
|
||||
return 0xffffffff;
|
||||
#endif
|
||||
invalid = invalid;
|
||||
return fast_read(src, bytes);
|
||||
}
|
||||
|
||||
unsigned int qlz_compress_core(const void *source, unsigned char *destination, unsigned int size, const unsigned char *hashtable[][AND + 1], const unsigned char *first_valid, unsigned char *hash_counter)
|
||||
{
|
||||
const unsigned char *source_c = (const unsigned char*)source;
|
||||
unsigned char *destination_c = (unsigned char*)destination;
|
||||
const unsigned char *last_byte = source_c + size - 1;
|
||||
const unsigned char *src = source_c;
|
||||
unsigned char *cword_ptr = destination_c;
|
||||
unsigned char *dst = destination_c + 4;
|
||||
unsigned int cword_val = 1U << 31;
|
||||
const unsigned char *guarantee_uncompressed = last_byte - 8;
|
||||
|
||||
#ifdef speedup_incompressible
|
||||
unsigned char *prev_dst = dst;
|
||||
const unsigned char *prev_src = src;
|
||||
#endif
|
||||
|
||||
hash_counter = hash_counter;
|
||||
first_valid = first_valid;
|
||||
|
||||
// save first 4 bytes uncompressed
|
||||
while(src < source_c + 4 && src < guarantee_uncompressed)
|
||||
{
|
||||
cword_val = (cword_val >> 1);
|
||||
*dst = *src;
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
|
||||
while(src < guarantee_uncompressed)
|
||||
{
|
||||
unsigned int fetch;
|
||||
if ((cword_val & 1) == 1)
|
||||
{
|
||||
// check if destinationc pointer could exceed destination buffer
|
||||
if (dst > destination_c + size)
|
||||
return 0;
|
||||
|
||||
// store control word
|
||||
fast_write((cword_val >> 1) | (1U << 31), cword_ptr, 4);
|
||||
cword_ptr = dst;
|
||||
dst += 4;
|
||||
cword_val = 1U << 31;
|
||||
|
||||
#ifdef speedup_incompressible
|
||||
// check if source chunk is compressible
|
||||
if (dst - prev_dst > src - prev_src && src > source_c + 1000)
|
||||
{
|
||||
int q;
|
||||
for(q = 0; q < 30 && src + 31 < guarantee_uncompressed && dst + 35 < destination_c + size; q++)
|
||||
{
|
||||
|
||||
#if(COMPRESSION_LEVEL == 0)
|
||||
int w;
|
||||
for(w = 0; w < 31; w++)
|
||||
{
|
||||
fetch = fast_read(src + w, 4);
|
||||
*(unsigned int*)&hashtable[hash_func(fetch)][0] = fast_read(src + w, 4);
|
||||
hashtable[hash_func(fetch)][1] = src + w;
|
||||
}
|
||||
#endif
|
||||
fast_write((1U << 31), dst - 4, 4);
|
||||
memcpy(dst, src, 31);
|
||||
|
||||
dst += 4*8 - 1 + 4;
|
||||
src += 4*8 - 1;
|
||||
prev_src = src;
|
||||
prev_dst = dst;
|
||||
cword_ptr = dst - 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef test_rle
|
||||
// check for rle sequence
|
||||
if (fast_read(src, 4) == fast_read(src + 1, 4))
|
||||
{
|
||||
const unsigned char *orig_src;
|
||||
fetch = fast_read(src, 4);
|
||||
orig_src = src;
|
||||
do src = src + 4; while (src <= guarantee_uncompressed - 4 && fetch == fast_read(src, 4));
|
||||
if((src - orig_src) <= 2047)
|
||||
{
|
||||
fast_write(((fetch & 0xff) << 16) | (unsigned int)((src - orig_src) << 4) | 15, dst, 4);
|
||||
dst = dst + 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
fast_write(((fetch & 0xff) << 16) | 15, dst, 4);
|
||||
fast_write((unsigned int)(src - orig_src), dst + 3, 4);
|
||||
dst = dst + 7;
|
||||
}
|
||||
cword_val = (cword_val >> 1) | (1 << 31);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
const unsigned char *o;
|
||||
unsigned int hash, matchlen;
|
||||
|
||||
#if(COMPRESSION_LEVEL < 2)
|
||||
unsigned int cached;
|
||||
|
||||
fetch = fast_read(src, 4);
|
||||
hash = hash_func(fetch);
|
||||
|
||||
cached = fetch ^ *(unsigned int*)&hashtable[hash][0];
|
||||
*(unsigned int*)&hashtable[hash][0] = fetch;
|
||||
|
||||
o = hashtable[hash][1];
|
||||
hashtable[hash][1] = src;
|
||||
|
||||
#else
|
||||
unsigned char c;
|
||||
unsigned int k, m;
|
||||
const unsigned char *offset2 = 0;
|
||||
|
||||
fetch = fast_read(src, 4);
|
||||
hash = hash_func(fetch);
|
||||
|
||||
matchlen = 0;
|
||||
c = hash_counter[hash];
|
||||
for(k = 0; k < AND + 1; k++)
|
||||
{
|
||||
o = hashtable[hash][(c - k) & AND];
|
||||
if(o > first_valid && o < src - 3 && *(src + matchlen) == *(o + matchlen) && (fast_read(o, 3) & 0xffffff) == (fetch & 0xffffff) && src - o < 131071)
|
||||
{
|
||||
size_t remaining;
|
||||
remaining = guarantee_uncompressed - src;
|
||||
m = 3;
|
||||
if (fast_read(o, 4) == fetch)
|
||||
{
|
||||
while(*(o + m) == *(src + m) && m < remaining)
|
||||
m++;
|
||||
}
|
||||
if (m > matchlen)
|
||||
{
|
||||
matchlen = m;
|
||||
offset2 = o;
|
||||
}
|
||||
}
|
||||
}
|
||||
o = offset2;
|
||||
c = (hash_counter[hash] + 1) & AND;
|
||||
hash_counter[hash] = c;
|
||||
hashtable[hash][c] = src;
|
||||
#endif
|
||||
|
||||
#if(COMPRESSION_LEVEL == 0)
|
||||
if (o != 0 && (cached & 0xffffff) == 0 && src - o > 3)
|
||||
#elif(COMPRESSION_LEVEL == 1)
|
||||
if ((cached & 0xffffff) == 0 && o > first_valid && o < src - 3 && ((fast_read(o, 3) ^ fast_read(src, 3)) & 0xffffff) == 0 && src - o < 131071)
|
||||
#elif(COMPRESSION_LEVEL > 1)
|
||||
if(matchlen == 3)
|
||||
#endif
|
||||
{
|
||||
unsigned int offset;
|
||||
offset = (unsigned int)(src - o);
|
||||
|
||||
#if(COMPRESSION_LEVEL < 2)
|
||||
if (cached & 0xffffffff)
|
||||
#endif
|
||||
{
|
||||
#if (COMPRESSION_LEVEL > 2)
|
||||
unsigned int u;
|
||||
for(u = 1; u < 3; u++)
|
||||
{
|
||||
hash = hash_func(fast_read(src + u, 4));
|
||||
c = (hash_counter[hash] + 1) & AND;
|
||||
hash_counter[hash] = c;
|
||||
hashtable[hash][c] = src + u;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (COMPRESSION_LEVEL == 0)
|
||||
cword_val = (cword_val >> 1) | (1U << 31);
|
||||
fast_write(3 | (hash << 4), dst, 2);
|
||||
src += 3;
|
||||
dst += 2;
|
||||
#else
|
||||
|
||||
if(offset <= 63)
|
||||
{
|
||||
// encode lz match
|
||||
*dst = (unsigned char)(offset << 2);
|
||||
cword_val = (cword_val >> 1) | (1U << 31);
|
||||
src += 3;
|
||||
dst++;
|
||||
}
|
||||
else if (offset <= 16383)
|
||||
{
|
||||
// encode lz match
|
||||
unsigned int f = (offset << 2) | 1;
|
||||
fast_write(f, dst, 2);
|
||||
cword_val = (cword_val >> 1) | (1U << 31);
|
||||
src += 3;
|
||||
dst += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// encode literal
|
||||
*dst = *src;
|
||||
src++;
|
||||
dst++;
|
||||
cword_val = (cword_val >> 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if(COMPRESSION_LEVEL > 1)
|
||||
}
|
||||
else if(matchlen > 3)
|
||||
{
|
||||
#elif(COMPRESSION_LEVEL < 2)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// encode lz match
|
||||
unsigned int offset;
|
||||
|
||||
#if(COMPRESSION_LEVEL < 2)
|
||||
const unsigned char *old_src = src;
|
||||
offset = (unsigned int)(src - o);
|
||||
cword_val = (cword_val >> 1) | (1U << 31);
|
||||
|
||||
src += 3;
|
||||
while(*(o + (src - old_src)) == *src && src < guarantee_uncompressed)
|
||||
src++;
|
||||
matchlen = (unsigned int)(src - old_src);
|
||||
#else
|
||||
unsigned int u;
|
||||
offset = (unsigned int)(src - o);
|
||||
cword_val = (cword_val >> 1) | (1U << 31);
|
||||
|
||||
#if (COMPRESSION_LEVEL > 2)
|
||||
for(u = 1; u < matchlen; u++)
|
||||
#else
|
||||
for(u = 1; u < matchlen && u < 5; u++)
|
||||
#endif
|
||||
{
|
||||
hash = hash_func(fast_read(src + u, 4));
|
||||
c = (hash_counter[hash] + 1) & AND;
|
||||
hash_counter[hash] = c;
|
||||
hashtable[hash][c] = src + u;
|
||||
}
|
||||
src += matchlen;
|
||||
#endif
|
||||
|
||||
#if (COMPRESSION_LEVEL == 0)
|
||||
if (matchlen < 15)
|
||||
{
|
||||
fast_write(matchlen | (hash << 4), dst, 2);
|
||||
dst += 2;
|
||||
}
|
||||
else if (matchlen < 255)
|
||||
{
|
||||
fast_write(hash << 4, dst, 2);
|
||||
*(dst + 2) = (unsigned char)matchlen;
|
||||
dst += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
fast_write(hash << 4, dst, 2);
|
||||
*(dst + 2) = 0;
|
||||
fast_write(matchlen, dst + 3, 4);
|
||||
dst += 7;
|
||||
}
|
||||
#else
|
||||
if (matchlen <= 18 && offset <= 1023)
|
||||
{
|
||||
unsigned int f = ((matchlen - 3) << 2) | (offset << 6) | 2;
|
||||
fast_write(f, dst, 2);
|
||||
dst += 2;
|
||||
}
|
||||
|
||||
else if(matchlen <= 34 && offset <= 65535)
|
||||
{
|
||||
unsigned int f = ((matchlen - 3) << 3) | (offset << 8) | 3;
|
||||
fast_write(f, dst, 3);
|
||||
dst += 3;
|
||||
}
|
||||
else if (matchlen >= 3)
|
||||
{
|
||||
if (matchlen <= 2050)
|
||||
{
|
||||
unsigned int f = ((matchlen - 3) << 4) | (offset << 15) | 7;
|
||||
fast_write(f, dst, 4);
|
||||
dst += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
fast_write(7, dst, 4);
|
||||
fast_write(matchlen, dst + 4, 4);
|
||||
fast_write(offset, dst + 8, 4);
|
||||
dst += 12;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// encode literal
|
||||
*dst = *src;
|
||||
src++;
|
||||
dst++;
|
||||
cword_val = (cword_val >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save last source bytes as literals
|
||||
while (src <= last_byte)
|
||||
{
|
||||
if ((cword_val & 1) == 1)
|
||||
{
|
||||
fast_write((cword_val >> 1) | (1U << 31), cword_ptr, 4);
|
||||
cword_ptr = dst;
|
||||
dst += 4;
|
||||
cword_val = 1U << 31;
|
||||
}
|
||||
|
||||
if (src < last_byte - 2 && src > source_c + 3)
|
||||
{
|
||||
hashtable[hash_func(fast_read(src, 4))][1] = src;
|
||||
*(unsigned int*)&hashtable[hash_func(fast_read(src, 4))][0] = fast_read(src, 4);
|
||||
}
|
||||
*dst = *src;
|
||||
src++;
|
||||
dst++;
|
||||
|
||||
cword_val = (cword_val >> 1);
|
||||
}
|
||||
|
||||
while((cword_val & 1) != 1)
|
||||
cword_val = (cword_val >> 1);
|
||||
|
||||
fast_write((cword_val >> 1) | (1U << 31), cword_ptr, 4);
|
||||
|
||||
// min. size must be 9 bytes so that the qlz_size functions can take 9 bytes as argument
|
||||
if (dst - destination_c < 9)
|
||||
return 9;
|
||||
else
|
||||
return (unsigned int)(dst - destination_c);
|
||||
}
|
||||
|
||||
size_t qlz_decompress_core(const unsigned char *source, void *destination, size_t size, size_t source_size, unsigned char *first_valid, const unsigned char *hashtable[])
|
||||
{
|
||||
const unsigned char *source_c = (const unsigned char*)source;
|
||||
unsigned char *destination_c = (unsigned char*)destination;
|
||||
const unsigned char *src = source_c;
|
||||
unsigned char *dst = destination_c;
|
||||
const unsigned char* last_byte_successor = destination_c + size;
|
||||
unsigned int cword_val = 1;
|
||||
const unsigned int bitlut[16] = {4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
|
||||
const unsigned char *guaranteed_uncompressed = last_byte_successor - 4;
|
||||
unsigned char *last_hashed = destination_c + 3;
|
||||
|
||||
first_valid = first_valid;
|
||||
last_hashed = last_hashed;
|
||||
hashtable = hashtable;
|
||||
|
||||
// prevent spurious memory read on a source with size < 4
|
||||
if (dst >= guaranteed_uncompressed)
|
||||
{
|
||||
src += 4;
|
||||
while(dst < last_byte_successor)
|
||||
{
|
||||
*dst = *src;
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
|
||||
return (unsigned int)(dst - destination_c);
|
||||
}
|
||||
|
||||
|
||||
for(;;)
|
||||
{
|
||||
unsigned int fetch;
|
||||
|
||||
if (cword_val == 1)
|
||||
{
|
||||
// fetch control word
|
||||
cword_val = fast_read_safe(src, 4, source_c + source_size) | (1U << 31);
|
||||
src += 4;
|
||||
}
|
||||
|
||||
fetch = fast_read_safe(src, 4, source_c + source_size);
|
||||
|
||||
// check if we must decode lz match
|
||||
if ((cword_val & 1) == 1)
|
||||
{
|
||||
unsigned int matchlen;
|
||||
|
||||
#if(COMPRESSION_LEVEL == 0)
|
||||
unsigned int hash;
|
||||
const unsigned char *offset2;
|
||||
|
||||
cword_val = cword_val >> 1;
|
||||
|
||||
if((fetch & 0xf) != 15)
|
||||
{
|
||||
hash = (fetch >> 4) & 0xfff;
|
||||
offset2 = hashtable[hash];
|
||||
|
||||
if((fetch & 0xf) != 0)
|
||||
{
|
||||
matchlen = (fetch & 0xf);
|
||||
src += 2;
|
||||
}
|
||||
else if((fetch & 0x00ff0000) != 0)
|
||||
{
|
||||
matchlen = *(src + 2);
|
||||
src += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
matchlen = fast_read(src + 3, 4);
|
||||
src += 7;
|
||||
}
|
||||
memcpy_up(dst, offset2, matchlen);
|
||||
while(last_hashed < dst)
|
||||
{
|
||||
last_hashed++;
|
||||
hashtable[hash_func(fast_read(last_hashed, 4))] = last_hashed;
|
||||
}
|
||||
dst += matchlen;
|
||||
last_hashed = dst - 1;
|
||||
}
|
||||
|
||||
#else
|
||||
unsigned int offset;
|
||||
cword_val = cword_val >> 1;
|
||||
|
||||
if ((fetch & 3) == 0)
|
||||
{
|
||||
offset = (fetch & 0xff) >> 2;
|
||||
#ifdef memory_safe
|
||||
if (3 > (unsigned int)(guaranteed_uncompressed - dst) || offset > (unsigned int)(dst - first_valid))
|
||||
return 0;
|
||||
#endif
|
||||
memcpy_up(dst, dst - offset, 3);
|
||||
dst += 3;
|
||||
src++;
|
||||
}
|
||||
else if ((fetch & 2) == 0)
|
||||
{
|
||||
offset = (fetch & 0xffff) >> 2;
|
||||
#ifdef memory_safe
|
||||
if (3 > (unsigned int)(guaranteed_uncompressed - dst) || offset > (unsigned int)(dst - first_valid))
|
||||
return 0;
|
||||
#endif
|
||||
memcpy_up(dst, dst - offset, 3);
|
||||
dst += 3;
|
||||
src += 2;
|
||||
}
|
||||
else if ((fetch & 1) == 0)
|
||||
{
|
||||
offset = (fetch & 0xffff) >> 6;
|
||||
matchlen = ((fetch >> 2) & 15) + 3;
|
||||
#ifdef memory_safe
|
||||
if (matchlen > (unsigned int)(guaranteed_uncompressed - dst) || offset > (unsigned int)(dst - first_valid))
|
||||
return 0;
|
||||
#endif
|
||||
memcpy_up(dst, dst - offset, matchlen);
|
||||
src += 2;
|
||||
dst += matchlen;
|
||||
}
|
||||
else if ((fetch & 4) == 0)
|
||||
{
|
||||
offset = (fetch & 0xffffff) >> 8;
|
||||
matchlen = ((fetch >> 3) & 31) + 3;
|
||||
#ifdef memory_safe
|
||||
if (matchlen > (unsigned int)(guaranteed_uncompressed - dst) || offset > (unsigned int)(dst - first_valid))
|
||||
return 0;
|
||||
#endif
|
||||
memcpy_up(dst, dst - offset, matchlen);
|
||||
src += 3;
|
||||
dst += matchlen;
|
||||
}
|
||||
else if ((fetch & 8) == 0)
|
||||
{
|
||||
offset = (fetch >> 15);
|
||||
if (offset != 0)
|
||||
{
|
||||
matchlen = ((fetch >> 4) & 2047) + 3;
|
||||
src += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
matchlen = fast_read_safe(src + 4, 4, source_c + source_size);
|
||||
offset = fast_read_safe(src + 8, 4, source_c + source_size);
|
||||
src += 12;
|
||||
}
|
||||
#ifdef memory_safe
|
||||
if (matchlen > (unsigned int)(guaranteed_uncompressed - dst) || offset > (unsigned int)(dst - first_valid))
|
||||
return 0;
|
||||
#endif
|
||||
memcpy_up(dst, dst - offset, matchlen);
|
||||
dst += matchlen;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
// decode rle sequence
|
||||
unsigned char rle_char;
|
||||
rle_char = (unsigned char)(fetch >> 16);
|
||||
matchlen = ((fetch >> 4) & 0xfff);
|
||||
|
||||
if(matchlen != 0)
|
||||
src += 3;
|
||||
else
|
||||
{
|
||||
matchlen = fast_read_safe(src + 3, 4, source_c + source_size);
|
||||
src += 7;
|
||||
}
|
||||
|
||||
#ifdef memory_safe
|
||||
if(matchlen > (unsigned int)(guaranteed_uncompressed - dst))
|
||||
return 0;
|
||||
#endif
|
||||
memset(dst, rle_char, matchlen);
|
||||
|
||||
#if(COMPRESSION_LEVEL == 0)
|
||||
while(last_hashed < dst - 1)
|
||||
{
|
||||
last_hashed++;
|
||||
hashtable[hash_func(fast_read(last_hashed, 4))] = last_hashed;
|
||||
}
|
||||
last_hashed = dst - 1 + matchlen;
|
||||
#endif
|
||||
dst += matchlen;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// decode literal
|
||||
#ifdef memory_safe
|
||||
if (4 > destination_c + size - dst || src > source_c + source_size + 4)
|
||||
return 0;
|
||||
#endif
|
||||
memcpy_up(dst, src, 4);
|
||||
|
||||
dst += bitlut[cword_val & 0xf];
|
||||
src += bitlut[cword_val & 0xf];
|
||||
cword_val = cword_val >> (bitlut[cword_val & 0xf]);
|
||||
|
||||
#if(COMPRESSION_LEVEL == 0)
|
||||
while(last_hashed < dst - 3)
|
||||
{
|
||||
last_hashed++;
|
||||
hashtable[hash_func(fast_read(last_hashed, 4))] = last_hashed;
|
||||
}
|
||||
#endif
|
||||
if (dst >= guaranteed_uncompressed)
|
||||
{
|
||||
// decode last literals and exit
|
||||
while(dst < last_byte_successor)
|
||||
{
|
||||
if (cword_val == 1)
|
||||
{
|
||||
src += 4;
|
||||
cword_val = 1U << 31;
|
||||
}
|
||||
if (1 > destination_c + size - dst)
|
||||
return 0;
|
||||
|
||||
*dst = *src;
|
||||
dst++;
|
||||
src++;
|
||||
cword_val = cword_val >> 1;
|
||||
}
|
||||
|
||||
#if(COMPRESSION_LEVEL == 0)
|
||||
while(last_hashed < last_byte_successor - 4)
|
||||
{
|
||||
last_hashed++;
|
||||
hashtable[hash_func(fast_read(last_hashed, 4))] = last_hashed;
|
||||
}
|
||||
#endif
|
||||
if((src - 1) - source_c > 8) // 8 bytes comp. size excessive len is ok
|
||||
return 0;
|
||||
else if(dst - destination_c - size == 0)
|
||||
return size;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t qlz_size_decompressed(const char *source)
|
||||
{
|
||||
unsigned int n, r;
|
||||
n = (((*source) & 2) == 2) ? 4 : 1;
|
||||
r = fast_read(source + 1 + n, n);
|
||||
r = r & (0xffffffff >> ((4 - n)*8));
|
||||
return r;
|
||||
}
|
||||
|
||||
size_t qlz_size_compressed(const char *source)
|
||||
{
|
||||
unsigned int n, r;
|
||||
n = (((*source) & 2) == 2) ? 4 : 1;
|
||||
r = fast_read(source + 1, n);
|
||||
r = r & (0xffffffff >> ((4 - n)*8));
|
||||
return r;
|
||||
}
|
||||
|
||||
size_t qlz_compress(const void *source, char *destination, size_t size, char *scratch)
|
||||
{
|
||||
// 1-8 bytes for aligning (not 0-7!); 8 bytes for buffersize (padds on 32 bit cpu); HASH_SIZE hash table; STREAMING_MODE_ROUNDED bytes streambuffer; optional HASH_ENTRIES byte hash counter
|
||||
unsigned char *buffer_aligned = (unsigned char *)scratch + 8 - (((size_t)scratch) % 8);
|
||||
const unsigned char *(*hashtable)[AND + 1] = (const unsigned char *(*)[AND + 1])(buffer_aligned + 8);
|
||||
size_t *buffersize = (size_t *)buffer_aligned;
|
||||
unsigned char *streambuffer = buffer_aligned + 8 + HASH_SIZE;
|
||||
unsigned int r;
|
||||
unsigned int compressed, base;
|
||||
unsigned char *hash_counter = streambuffer + STREAMING_MODE_ROUNDED;
|
||||
|
||||
if(size == 0 || size > 0xffffffff)
|
||||
return 0;
|
||||
|
||||
#if (COMPRESSION_LEVEL == 0 && STREAMING_MODE_ROUNDED == 0)
|
||||
memset((void *)hashtable, 0, HASH_SIZE);
|
||||
#endif
|
||||
|
||||
if(size < 216)
|
||||
base = 3;
|
||||
else
|
||||
base = 9;
|
||||
|
||||
// if not STREAMING_MODE, then STREAMING_MODE_ROUNDED == 0 and first case (streaming buffer full) is executed unconditionally, functioning as block comp.
|
||||
if (*buffersize + size - 1 >= STREAMING_MODE_ROUNDED)
|
||||
{
|
||||
#if (COMPRESSION_LEVEL == 0 && STREAMING_MODE_ROUNDED != 0)
|
||||
memset((void *)hashtable, 0, HASH_SIZE);
|
||||
#endif
|
||||
|
||||
r = base + qlz_compress_core(source, (unsigned char*)destination + base, (unsigned int)size, hashtable, (const unsigned char*)source, hash_counter);
|
||||
#if (COMPRESSION_LEVEL == 0 && STREAMING_MODE_ROUNDED != 0)
|
||||
memset((void *)hashtable, 0, HASH_SIZE);
|
||||
#endif
|
||||
|
||||
if(r == base)
|
||||
{
|
||||
memcpy(destination + base, source, size);
|
||||
r = (unsigned int)size + base;
|
||||
compressed = 0;
|
||||
}
|
||||
else
|
||||
compressed = 1;
|
||||
*buffersize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(streambuffer + *buffersize, source, size);
|
||||
r = base + qlz_compress_core(streambuffer + *buffersize, (unsigned char*)destination + base, (unsigned int)size, hashtable, streambuffer, hash_counter);
|
||||
|
||||
if(r == base)
|
||||
{
|
||||
memcpy(destination + base, streambuffer + *buffersize, size);
|
||||
r = (unsigned int)size + base;
|
||||
compressed = 0;
|
||||
|
||||
memset((void*)hashtable, 0, HASH_SIZE);
|
||||
}
|
||||
else
|
||||
compressed = 1;
|
||||
*buffersize += size;
|
||||
}
|
||||
|
||||
if(base == 3)
|
||||
{
|
||||
*destination = (unsigned char)(0 | compressed);
|
||||
*(destination + 1) = (unsigned char)r;
|
||||
*(destination + 2) = (unsigned char)size;
|
||||
}
|
||||
else
|
||||
{
|
||||
*destination = (unsigned char)(2 | compressed);
|
||||
fast_write(r, destination + 1, 4);
|
||||
fast_write((unsigned int)size, destination + 5, 4);
|
||||
}
|
||||
|
||||
#if (COMPRESSION_LEVEL == 0)
|
||||
*destination = (*destination) | 4;
|
||||
#endif
|
||||
|
||||
return (size_t)r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
size_t qlz_decompress(const char *source, void *destination, char *scratch)
|
||||
{
|
||||
// 1-8 bytes for aligning (not 0-7!); 8 bytes for buffersize (padds on 32bit cpu); STREAMING_MODE_ROUNDED streambuffer; HASH_SIZE hash table
|
||||
unsigned char *buffer_aligned = (unsigned char *)scratch + 8 - (((size_t)scratch) % 8);
|
||||
size_t *buffersize = (size_t *)buffer_aligned;
|
||||
unsigned int headerlen = 2*((((*source) & 2) == 2) ? 4 : 1) + 1; // get header len
|
||||
|
||||
unsigned char *streambuffer = buffer_aligned + 8;
|
||||
const unsigned char **hashtable = (const unsigned char **)(streambuffer + STREAMING_MODE_ROUNDED);
|
||||
|
||||
size_t dsiz = qlz_size_decompressed((char *)source);
|
||||
size_t csiz = qlz_size_compressed((char *)source);
|
||||
if (*buffersize + qlz_size_decompressed((char *)source) - 1 >= STREAMING_MODE_ROUNDED)
|
||||
{
|
||||
if((*source & 1) == 1)
|
||||
qlz_decompress_core((const unsigned char *)source + headerlen, destination, dsiz, csiz, (unsigned char*)destination, hashtable);
|
||||
else
|
||||
memcpy(destination, source + headerlen, dsiz);
|
||||
*buffersize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((*source & 1) == 1)
|
||||
qlz_decompress_core((const unsigned char *)source + headerlen, streambuffer + *buffersize, dsiz, csiz, streambuffer, hashtable);
|
||||
else
|
||||
memcpy(streambuffer + *buffersize, source + headerlen, dsiz);
|
||||
memcpy(destination, streambuffer + *buffersize, dsiz);
|
||||
*buffersize += dsiz;
|
||||
}
|
||||
return dsiz;
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
#ifndef QLZ_HEADER
|
||||
#define QLZ_HEADER
|
||||
|
||||
// Version 1.31 final
|
||||
#define QLZ_VERSION_MAJOR 1
|
||||
#define QLZ_VERSION_MINOR 3
|
||||
#define QLZ_VERSION_REVISION 1
|
||||
|
||||
// Set following flags according to the manual
|
||||
#define COMPRESSION_LEVEL 0
|
||||
//#define STREAMING_MODE 2000000
|
||||
#define test_rle
|
||||
#define speedup_incompressible
|
||||
//#define memory_safe
|
||||
|
||||
// Public functions of QuickLZ
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
size_t qlz_decompress(const char *source, void *destination, char *scratch);
|
||||
size_t qlz_compress(const void *source, char *destination, size_t size, char *scratch);
|
||||
size_t qlz_size_decompressed(const char *source);
|
||||
size_t qlz_size_compressed(const char *source);
|
||||
int qlz_get_setting(int setting);
|
||||
|
||||
#if (defined(__X86__) || defined(__i386__) || defined(i386) || defined(_M_IX86) || defined(__386__) || defined(__x86_64__) || defined(_M_X64))
|
||||
#define X86X64
|
||||
#endif
|
||||
|
||||
// Compute SCRATCH_COMPRESS, SCRATCH_DECOMPRESS and constants used internally
|
||||
#if COMPRESSION_LEVEL == 0 && defined(memory_safe)
|
||||
#error memory_safe flag cannot be used with COMPRESSION_LEVEL 0
|
||||
#endif
|
||||
|
||||
#define HASH_ENTRIES 4096
|
||||
|
||||
#if (COMPRESSION_LEVEL == 0 || COMPRESSION_LEVEL == 1 || COMPRESSION_LEVEL == 2)
|
||||
#define AND 1
|
||||
#elif (COMPRESSION_LEVEL == 3)
|
||||
#define AND 0x7
|
||||
#else
|
||||
#error COMPRESSION_LEVEL must be 0, 1, 2 or 3
|
||||
#endif
|
||||
|
||||
#define HASH_SIZE (AND + 1)*HASH_ENTRIES*sizeof(unsigned char *)
|
||||
|
||||
#ifdef STREAMING_MODE
|
||||
#define STREAMING_MODE_VALUE STREAMING_MODE
|
||||
#else
|
||||
#define STREAMING_MODE_VALUE 0
|
||||
#endif
|
||||
|
||||
#define STREAMING_MODE_ROUNDED ((STREAMING_MODE_VALUE >> 3) << 3)
|
||||
|
||||
#if (COMPRESSION_LEVEL > 1)
|
||||
#define SCRATCH_COMPRESS HASH_SIZE + STREAMING_MODE_VALUE + 16 + HASH_ENTRIES
|
||||
#else
|
||||
#define SCRATCH_COMPRESS HASH_SIZE + STREAMING_MODE_VALUE + 16
|
||||
#endif
|
||||
|
||||
#if (COMPRESSION_LEVEL == 0)
|
||||
#define SCRATCH_DECOMPRESS HASH_ENTRIES*sizeof(unsigned char *) + 16 + STREAMING_MODE_VALUE
|
||||
#else
|
||||
#define SCRATCH_DECOMPRESS 16 + STREAMING_MODE_VALUE
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,357 +0,0 @@
|
||||
/* unzip.h -- IO for uncompress .zip files using zlib
|
||||
Version 1.01e, February 12th, 2005
|
||||
|
||||
Copyright (C) 1998-2005 Gilles Vollant
|
||||
|
||||
This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
|
||||
WinZip, InfoZip tools and compatible.
|
||||
|
||||
Multi volume ZipFile (span) are not supported.
|
||||
Encryption compatible with pkzip 2.04g only supported
|
||||
Old compressions used by old PKZip 1.x are not supported
|
||||
|
||||
|
||||
I WAIT FEEDBACK at mail info@winimage.com
|
||||
Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
|
||||
|
||||
Condition of use and distribution are the same than zlib :
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/* for more info about .ZIP format, see
|
||||
http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip
|
||||
http://www.info-zip.org/pub/infozip/doc/
|
||||
PkWare has also a specification at :
|
||||
ftp://ftp.pkware.com/probdesc.zip
|
||||
*/
|
||||
|
||||
#ifndef _unz_H
|
||||
#define _unz_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _ZLIB_H
|
||||
#include "zlib.h"
|
||||
#ifndef OF
|
||||
#define OF(a) a
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _ZLIBIOAPI_H
|
||||
#include "ioapi.h"
|
||||
#endif
|
||||
|
||||
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
|
||||
/* like the STRICT of WIN32, we define a pointer that cannot be converted
|
||||
from (void*) without cast */
|
||||
typedef struct TagunzFile__ { int unused; } unzFile__;
|
||||
typedef unzFile__ *unzFile;
|
||||
#else
|
||||
typedef voidp unzFile;
|
||||
#endif
|
||||
|
||||
|
||||
#define UNZ_OK (0)
|
||||
#define UNZ_END_OF_LIST_OF_FILE (-100)
|
||||
#define UNZ_ERRNO (Z_ERRNO)
|
||||
#define UNZ_EOF (0)
|
||||
#define UNZ_PARAMERROR (-102)
|
||||
#define UNZ_BADZIPFILE (-103)
|
||||
#define UNZ_INTERNALERROR (-104)
|
||||
#define UNZ_CRCERROR (-105)
|
||||
|
||||
/* tm_unz contain date/time info */
|
||||
typedef struct tm_unz_s
|
||||
{
|
||||
uInt tm_sec; /* seconds after the minute - [0,59] */
|
||||
uInt tm_min; /* minutes after the hour - [0,59] */
|
||||
uInt tm_hour; /* hours since midnight - [0,23] */
|
||||
uInt tm_mday; /* day of the month - [1,31] */
|
||||
uInt tm_mon; /* months since January - [0,11] */
|
||||
uInt tm_year; /* years - [1980..2044] */
|
||||
} tm_unz;
|
||||
|
||||
/* unz_global_info structure contain global data about the ZIPfile
|
||||
These data comes from the end of central dir */
|
||||
typedef struct unz_global_info_s
|
||||
{
|
||||
uLong number_entry; /* total number of entries in
|
||||
the central dir on this disk */
|
||||
uLong size_comment; /* size of the global comment of the zipfile */
|
||||
} unz_global_info;
|
||||
|
||||
|
||||
/* unz_file_info contain information about a file in the zipfile */
|
||||
typedef struct unz_file_info_s
|
||||
{
|
||||
uLong version; /* version made by 2 bytes */
|
||||
uLong version_needed; /* version needed to extract 2 bytes */
|
||||
uLong flag; /* general purpose bit flag 2 bytes */
|
||||
uLong compression_method; /* compression method 2 bytes */
|
||||
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
|
||||
uLong crc; /* crc-32 4 bytes */
|
||||
uLong compressed_size; /* compressed size 4 bytes */
|
||||
uLong uncompressed_size; /* uncompressed size 4 bytes */
|
||||
uLong size_filename; /* filename length 2 bytes */
|
||||
uLong size_file_extra; /* extra field length 2 bytes */
|
||||
uLong size_file_comment; /* file comment length 2 bytes */
|
||||
|
||||
uLong disk_num_start; /* disk number start 2 bytes */
|
||||
uLong internal_fa; /* internal file attributes 2 bytes */
|
||||
uLong external_fa; /* external file attributes 4 bytes */
|
||||
|
||||
tm_unz tmu_date;
|
||||
} unz_file_info;
|
||||
|
||||
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
|
||||
const char* fileName2,
|
||||
int iCaseSensitivity));
|
||||
/*
|
||||
Compare two filename (fileName1,fileName2).
|
||||
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
|
||||
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
|
||||
or strcasecmp)
|
||||
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
|
||||
(like 1 on Unix, 2 on Windows)
|
||||
*/
|
||||
|
||||
|
||||
extern unzFile ZEXPORT unzOpen OF((const char *path));
|
||||
/*
|
||||
Open a Zip file. path contain the full pathname (by example,
|
||||
on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
|
||||
"zlib/zlib113.zip".
|
||||
If the zipfile cannot be opened (file don't exist or in not valid), the
|
||||
return value is NULL.
|
||||
Else, the return value is a unzFile Handle, usable with other function
|
||||
of this unzip package.
|
||||
*/
|
||||
|
||||
extern unzFile ZEXPORT unzOpen2 OF((const char *path,
|
||||
zlib_filefunc_def* pzlib_filefunc_def));
|
||||
/*
|
||||
Open a Zip file, like unzOpen, but provide a set of file low level API
|
||||
for read/write the zip file (see ioapi.h)
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzClose OF((unzFile file));
|
||||
/*
|
||||
Close a ZipFile opened with unzipOpen.
|
||||
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
|
||||
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
|
||||
return UNZ_OK if there is no problem. */
|
||||
|
||||
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
|
||||
unz_global_info *pglobal_info));
|
||||
/*
|
||||
Write info about the ZipFile in the *pglobal_info structure.
|
||||
No preparation of the structure is needed
|
||||
return UNZ_OK if there is no problem. */
|
||||
|
||||
|
||||
extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
|
||||
char *szComment,
|
||||
uLong uSizeBuf));
|
||||
/*
|
||||
Get the global comment string of the ZipFile, in the szComment buffer.
|
||||
uSizeBuf is the size of the szComment buffer.
|
||||
return the number of byte copied or an error code <0
|
||||
*/
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* Unzip package allow you browse the directory of the zipfile */
|
||||
|
||||
extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
|
||||
/*
|
||||
Set the current file of the zipfile to the first file.
|
||||
return UNZ_OK if there is no problem
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzGoToNextFile OF((unzFile file));
|
||||
/*
|
||||
Set the current file of the zipfile to the next file.
|
||||
return UNZ_OK if there is no problem
|
||||
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzLocateFile OF((unzFile file,
|
||||
const char *szFileName,
|
||||
int iCaseSensitivity));
|
||||
/*
|
||||
Try locate the file szFileName in the zipfile.
|
||||
For the iCaseSensitivity signification, see unzStringFileNameCompare
|
||||
|
||||
return value :
|
||||
UNZ_OK if the file is found. It becomes the current file.
|
||||
UNZ_END_OF_LIST_OF_FILE if the file is not found
|
||||
*/
|
||||
|
||||
|
||||
/* ****************************************** */
|
||||
/* Ryan supplied functions */
|
||||
/* unz_file_info contain information about a file in the zipfile */
|
||||
typedef struct unz_file_pos_s
|
||||
{
|
||||
uLong pos_in_zip_directory; /* offset in zip file directory */
|
||||
uLong num_of_file; /* # of file */
|
||||
} unz_file_pos;
|
||||
|
||||
extern int ZEXPORT unzGetFilePos(
|
||||
unzFile file,
|
||||
unz_file_pos* file_pos);
|
||||
|
||||
extern int ZEXPORT unzGoToFilePos(
|
||||
unzFile file,
|
||||
unz_file_pos* file_pos);
|
||||
|
||||
/* ****************************************** */
|
||||
|
||||
extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
|
||||
unz_file_info *pfile_info,
|
||||
char *szFileName,
|
||||
uLong fileNameBufferSize,
|
||||
void *extraField,
|
||||
uLong extraFieldBufferSize,
|
||||
char *szComment,
|
||||
uLong commentBufferSize));
|
||||
/*
|
||||
Get Info about the current file
|
||||
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
|
||||
the current file
|
||||
if szFileName!=NULL, the filemane string will be copied in szFileName
|
||||
(fileNameBufferSize is the size of the buffer)
|
||||
if extraField!=NULL, the extra field information will be copied in extraField
|
||||
(extraFieldBufferSize is the size of the buffer).
|
||||
This is the Central-header version of the extra field
|
||||
if szComment!=NULL, the comment string of the file will be copied in szComment
|
||||
(commentBufferSize is the size of the buffer)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
/* for reading the content of the current zipfile, you can open it, read data
|
||||
from it, and close it (you can close it before reading all the file)
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
|
||||
/*
|
||||
Open for reading data the current file in the zipfile.
|
||||
If there is no error, the return value is UNZ_OK.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
|
||||
const char* password));
|
||||
/*
|
||||
Open for reading data the current file in the zipfile.
|
||||
password is a crypting password
|
||||
If there is no error, the return value is UNZ_OK.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
|
||||
int* method,
|
||||
int* level,
|
||||
int raw));
|
||||
/*
|
||||
Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
|
||||
if raw==1
|
||||
*method will receive method of compression, *level will receive level of
|
||||
compression
|
||||
note : you can set level parameter as NULL (if you did not want known level,
|
||||
but you CANNOT set method parameter as NULL
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
|
||||
int* method,
|
||||
int* level,
|
||||
int raw,
|
||||
const char* password));
|
||||
/*
|
||||
Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
|
||||
if raw==1
|
||||
*method will receive method of compression, *level will receive level of
|
||||
compression
|
||||
note : you can set level parameter as NULL (if you did not want known level,
|
||||
but you CANNOT set method parameter as NULL
|
||||
*/
|
||||
|
||||
|
||||
extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
|
||||
/*
|
||||
Close the file in zip opened with unzOpenCurrentFile
|
||||
Return UNZ_CRCERROR if all the file was read but the CRC is not good
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
|
||||
voidp buf,
|
||||
unsigned len));
|
||||
/*
|
||||
Read bytes from the current file (opened by unzOpenCurrentFile)
|
||||
buf contain buffer where data must be copied
|
||||
len the size of buf.
|
||||
|
||||
return the number of byte copied if somes bytes are copied
|
||||
return 0 if the end of file was reached
|
||||
return <0 with error code if there is an error
|
||||
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
|
||||
*/
|
||||
|
||||
extern z_off_t ZEXPORT unztell OF((unzFile file));
|
||||
/*
|
||||
Give the current position in uncompressed data
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzeof OF((unzFile file));
|
||||
/*
|
||||
return 1 if the end of file was reached, 0 elsewhere
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
|
||||
voidp buf,
|
||||
unsigned len));
|
||||
/*
|
||||
Read extra field from the current file (opened by unzOpenCurrentFile)
|
||||
This is the local-header version of the extra field (sometimes, there is
|
||||
more info in the local-header version than in the central-header)
|
||||
|
||||
if buf==NULL, it return the size of the local extra field
|
||||
|
||||
if buf!=NULL, len is the size of the buffer, the extra header is copied in
|
||||
buf.
|
||||
the return value is the number of bytes copied in buf, or (if <0)
|
||||
the error code
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
/* Get the current file offset */
|
||||
extern uLong ZEXPORT unzGetOffset (unzFile file);
|
||||
|
||||
/* Set the current file offset */
|
||||
extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _unz_H */
|
@ -24,17 +24,6 @@
|
||||
#include <errno.h>
|
||||
#include <trio/trio.h>
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <zlib.h>
|
||||
#include "compress/unzip.h"
|
||||
|
||||
#include "file.h"
|
||||
#include "general.h"
|
||||
|
||||
@ -47,32 +36,8 @@ static const int64 MaxROMImageSize = (int64)1 << 26; // 2 ^ 26 = 64MiB
|
||||
enum
|
||||
{
|
||||
MDFN_FILETYPE_PLAIN = 0,
|
||||
MDFN_FILETYPE_GZIP = 1,
|
||||
MDFN_FILETYPE_ZIP = 2,
|
||||
};
|
||||
|
||||
static const char *unzErrorString(int error_code)
|
||||
{
|
||||
if(error_code == UNZ_OK)
|
||||
return("ZIP OK");
|
||||
else if(error_code == UNZ_END_OF_LIST_OF_FILE)
|
||||
return("ZIP End of file list");
|
||||
else if(error_code == UNZ_EOF)
|
||||
return("ZIP EOF");
|
||||
else if(error_code == UNZ_PARAMERROR)
|
||||
return("ZIP Parameter error");
|
||||
else if(error_code == UNZ_BADZIPFILE)
|
||||
return("ZIP file bad");
|
||||
else if(error_code == UNZ_INTERNALERROR)
|
||||
return("ZIP Internal error");
|
||||
else if(error_code == UNZ_CRCERROR)
|
||||
return("ZIP CRC error");
|
||||
else if(error_code == UNZ_ERRNO)
|
||||
return(strerror(errno));
|
||||
else
|
||||
return("ZIP Unknown");
|
||||
}
|
||||
|
||||
bool MDFNFILE::ApplyIPS(FILE *ips)
|
||||
{
|
||||
uint8 header[5];
|
||||
@ -97,26 +62,6 @@ bool MDFNFILE::ApplyIPS(FILE *ips)
|
||||
return(0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
// If the file is mmap()'d, move it to malloc()'d RAM
|
||||
if(is_mmap)
|
||||
{
|
||||
void *tmp_ptr = MDFN_malloc(f_size, _("file read buffer"));
|
||||
if(!tmp_ptr)
|
||||
{
|
||||
//Close();
|
||||
//fclose(ipsfile);
|
||||
return(0);
|
||||
}
|
||||
memcpy(tmp_ptr, f_data, f_size);
|
||||
|
||||
munmap(f_data, f_size);
|
||||
|
||||
is_mmap = FALSE;
|
||||
f_data = (uint8 *)tmp_ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
while(::fread(header, 1, 3, ips) == 3)
|
||||
{
|
||||
uint32 offset = (header[0] << 16) | (header[1] << 8) | header[2];
|
||||
@ -234,13 +179,8 @@ bool MDFNFILE::MakeMemWrapAndClose(void *tz, int type)
|
||||
{
|
||||
bool ret = FALSE;
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
is_mmap = FALSE;
|
||||
#endif
|
||||
location = 0;
|
||||
|
||||
if(type == MDFN_FILETYPE_PLAIN)
|
||||
{
|
||||
::fseek((FILE *)tz, 0, SEEK_END);
|
||||
f_size = ::ftell((FILE *)tz);
|
||||
::fseek((FILE *)tz, 0, SEEK_SET);
|
||||
@ -251,21 +191,6 @@ bool MDFNFILE::MakeMemWrapAndClose(void *tz, int type)
|
||||
goto doret;
|
||||
}
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
if((void *)-1 != (f_data = (uint8 *)mmap(NULL, size, PROT_READ, MAP_SHARED, fileno((FILE *)tz), 0)))
|
||||
{
|
||||
//puts("mmap'ed");
|
||||
is_mmap = TRUE;
|
||||
#ifdef HAVE_MADVISE
|
||||
if(0 == madvise(f_data, size, MADV_SEQUENTIAL | MADV_WILLNEED))
|
||||
{
|
||||
//puts("madvised");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
if(!(f_data = (uint8*)MDFN_malloc(size, _("file read buffer"))))
|
||||
{
|
||||
goto doret;
|
||||
@ -278,100 +203,11 @@ bool MDFNFILE::MakeMemWrapAndClose(void *tz, int type)
|
||||
free(f_data);
|
||||
goto doret;
|
||||
}
|
||||
#ifdef HAVE_MMAP
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if(type == MDFN_FILETYPE_GZIP)
|
||||
{
|
||||
uint32_t cur_size = 0;
|
||||
uint32_t cur_alloced = 65536;
|
||||
int howmany;
|
||||
|
||||
if(!(f_data = (uint8*)MDFN_malloc(cur_alloced, _("file read buffer"))))
|
||||
{
|
||||
goto doret;
|
||||
}
|
||||
|
||||
while((howmany = gzread((gzFile)tz, f_data + cur_size, cur_alloced - cur_size)) > 0)
|
||||
{
|
||||
cur_size += howmany;
|
||||
cur_alloced <<= 1;
|
||||
|
||||
if(cur_size > MaxROMImageSize)
|
||||
{
|
||||
MDFN_PrintError(_("ROM image is too large; maximum size allowed is %llu bytes."), (unsigned long long)MaxROMImageSize);
|
||||
goto doret;
|
||||
}
|
||||
|
||||
if(!(f_data = (uint8 *)MDFN_realloc(f_data, cur_alloced, _("file read buffer"))))
|
||||
{
|
||||
goto doret;
|
||||
}
|
||||
}
|
||||
|
||||
if(!(f_data = (uint8 *)MDFN_realloc(f_data, cur_size, _("file read buffer"))))
|
||||
{
|
||||
goto doret;
|
||||
}
|
||||
|
||||
f_size = cur_size;
|
||||
|
||||
{
|
||||
int gzerrnum = 0;
|
||||
const char *gzerrstring;
|
||||
if((gzerrstring = gzerror((gzFile)tz, &gzerrnum)) && gzerrnum != Z_OK && gzerrnum != Z_STREAM_END)
|
||||
{
|
||||
if(gzerrnum != Z_ERRNO)
|
||||
{
|
||||
MDFN_PrintError(_("Error reading file: zlib error: %s"), gzerrstring);
|
||||
}
|
||||
else
|
||||
{
|
||||
ErrnoHolder ene(errno);
|
||||
MDFN_PrintError(_("Error reading file: %s"), ene.StrError());
|
||||
}
|
||||
goto doret;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(type == MDFN_FILETYPE_ZIP)
|
||||
{
|
||||
unz_file_info ufo;
|
||||
unzGetCurrentFileInfo((unzFile)tz, &ufo, 0, 0, 0, 0, 0, 0);
|
||||
|
||||
f_size = ufo.uncompressed_size;
|
||||
|
||||
if(size > MaxROMImageSize)
|
||||
{
|
||||
MDFN_PrintError(_("ROM image is too large; maximum size allowed is %llu bytes."), (unsigned long long)MaxROMImageSize);
|
||||
goto doret;
|
||||
}
|
||||
|
||||
if(!(f_data=(uint8 *)MDFN_malloc(ufo.uncompressed_size, _("file read buffer"))))
|
||||
{
|
||||
goto doret;
|
||||
}
|
||||
|
||||
unzReadCurrentFile((unzFile)tz, f_data, ufo.uncompressed_size);
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
doret:
|
||||
if(type == MDFN_FILETYPE_PLAIN)
|
||||
{
|
||||
fclose((FILE *)tz);
|
||||
}
|
||||
else if(type == MDFN_FILETYPE_GZIP)
|
||||
{
|
||||
gzclose((gzFile)tz);
|
||||
}
|
||||
else if(type == MDFN_FILETYPE_ZIP)
|
||||
{
|
||||
unzCloseCurrentFile((unzFile)tz);
|
||||
unzClose((unzFile)tz);
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
@ -383,10 +219,6 @@ MDFNFILE::MDFNFILE() : size(f_size), data((const uint8* const &)f_data), ext((co
|
||||
f_ext = NULL;
|
||||
|
||||
location = 0;
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
is_mmap = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
MDFNFILE::MDFNFILE(const char *path, const FileExtensionSpecStruct *known_ext, const char *purpose) : size(f_size), data((const uint8* const &)f_data), ext((const char * const &)f_ext)
|
||||
@ -406,96 +238,11 @@ MDFNFILE::~MDFNFILE()
|
||||
|
||||
bool MDFNFILE::Open(const char *path, const FileExtensionSpecStruct *known_ext, const char *purpose, const bool suppress_notfound_pe)
|
||||
{
|
||||
unzFile tz;
|
||||
|
||||
local_errno = 0;
|
||||
error_code = MDFNFILE_EC_OTHER; // Set to 0 at the end if the function succeeds.
|
||||
|
||||
//f_data = (uint8 *)0xDEADBEEF;
|
||||
|
||||
// Try opening it as a zip file first
|
||||
if((tz = unzOpen(path)))
|
||||
{
|
||||
char tempu[1024];
|
||||
int errcode;
|
||||
|
||||
if((errcode = unzGoToFirstFile(tz)) != UNZ_OK)
|
||||
{
|
||||
MDFN_PrintError(_("Could not seek to first file in ZIP archive: %s"), unzErrorString(errcode));
|
||||
unzClose(tz);
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if(known_ext)
|
||||
{
|
||||
bool FileFound = FALSE;
|
||||
while(!FileFound)
|
||||
{
|
||||
size_t tempu_strlen;
|
||||
const FileExtensionSpecStruct *ext_search = known_ext;
|
||||
|
||||
if((errcode = unzGetCurrentFileInfo(tz, 0, tempu, 1024, 0, 0, 0, 0)) != UNZ_OK)
|
||||
{
|
||||
MDFN_PrintError(_("Could not get file information in ZIP archive: %s"), unzErrorString(errcode));
|
||||
unzClose(tz);
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
tempu[1023] = 0;
|
||||
tempu_strlen = strlen(tempu);
|
||||
|
||||
while(ext_search->extension && !FileFound)
|
||||
{
|
||||
size_t ttmeow = strlen(ext_search->extension);
|
||||
if(tempu_strlen >= ttmeow)
|
||||
{
|
||||
if(!strcasecmp(tempu + tempu_strlen - ttmeow, ext_search->extension))
|
||||
FileFound = TRUE;
|
||||
}
|
||||
ext_search++;
|
||||
}
|
||||
|
||||
if(FileFound)
|
||||
break;
|
||||
|
||||
if((errcode = unzGoToNextFile(tz)) != UNZ_OK)
|
||||
{
|
||||
if(errcode != UNZ_END_OF_LIST_OF_FILE)
|
||||
{
|
||||
MDFN_PrintError(_("Error seeking to next file in ZIP archive: %s"), unzErrorString(errcode));
|
||||
unzClose(tz);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if((errcode = unzGoToFirstFile(tz)) != UNZ_OK)
|
||||
{
|
||||
MDFN_PrintError(_("Could not seek to first file in ZIP archive: %s"), unzErrorString(errcode));
|
||||
unzClose(tz);
|
||||
return(NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
} // end to while(!FileFound)
|
||||
} // end to if(ext)
|
||||
|
||||
if((errcode = unzOpenCurrentFile(tz)) != UNZ_OK)
|
||||
{
|
||||
MDFN_PrintError(_("Could not open file in ZIP archive: %s"), unzErrorString(errcode));
|
||||
unzClose(tz);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if(!MakeMemWrapAndClose(tz, MDFN_FILETYPE_ZIP))
|
||||
return(0);
|
||||
|
||||
char *ld = strrchr(tempu, '.');
|
||||
|
||||
f_ext = strdup(ld ? ld + 1 : "");
|
||||
}
|
||||
else // If it's not a zip file, handle it as...another type of file!
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
@ -516,14 +263,6 @@ bool MDFNFILE::Open(const char *path, const FileExtensionSpecStruct *known_ext,
|
||||
return(0);
|
||||
}
|
||||
|
||||
uint32 gzmagic;
|
||||
|
||||
gzmagic = ::fgetc(fp);
|
||||
gzmagic |= ::fgetc(fp) << 8;
|
||||
gzmagic |= ::fgetc(fp) << 16;
|
||||
|
||||
if(gzmagic != 0x088b1f) /* Not gzip... */
|
||||
{
|
||||
::fseek(fp, 0, SEEK_SET);
|
||||
|
||||
if(!MakeMemWrapAndClose(fp, MDFN_FILETYPE_PLAIN))
|
||||
@ -531,53 +270,6 @@ bool MDFNFILE::Open(const char *path, const FileExtensionSpecStruct *known_ext,
|
||||
|
||||
const char *ld = strrchr(path, '.');
|
||||
f_ext = strdup(ld ? ld + 1 : "");
|
||||
}
|
||||
else /* Probably gzip */
|
||||
{
|
||||
gzFile gzp;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
// Clear errno so we can see if the error occurred within zlib or the C lib
|
||||
errno = 0;
|
||||
if(!(gzp = gzopen(path, "rb")))
|
||||
{
|
||||
if(errno != 0)
|
||||
{
|
||||
ErrnoHolder ene(errno);
|
||||
local_errno = ene.Errno();
|
||||
|
||||
if(ene.Errno() == ENOENT)
|
||||
{
|
||||
local_errno = ene.Errno();
|
||||
error_code = MDFNFILE_EC_NOTFOUND;
|
||||
}
|
||||
|
||||
if(ene.Errno() != ENOENT || !suppress_notfound_pe)
|
||||
MDFN_PrintError(_("Error opening \"%s\": %s"), path, ene.StrError());
|
||||
}
|
||||
else
|
||||
MDFN_PrintError(_("Error opening \"%s\": %s"), path, _("zlib error"));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(!MakeMemWrapAndClose(gzp, MDFN_FILETYPE_GZIP))
|
||||
return(0);
|
||||
|
||||
char *tmp_path = strdup(path);
|
||||
char *ld = strrchr(tmp_path, '.');
|
||||
|
||||
if(ld && ld > tmp_path)
|
||||
{
|
||||
char *last_ld = ld;
|
||||
*ld = 0;
|
||||
ld = strrchr(tmp_path, '.');
|
||||
if(!ld) { *last_ld = '.'; ld = last_ld; }
|
||||
}
|
||||
f_ext = strdup(ld ? ld + 1 : "");
|
||||
free(tmp_path);
|
||||
} // End gzip handling
|
||||
} // End normal and gzip file handling else to zip
|
||||
|
||||
// FIXME: Handle extension fixing for cases where loaded filename is like "moo.moo/lalala"
|
||||
@ -597,11 +289,6 @@ bool MDFNFILE::Close(void)
|
||||
|
||||
if(f_data)
|
||||
{
|
||||
#if HAVE_MMAP
|
||||
if(is_mmap)
|
||||
munmap(f_data, size);
|
||||
else
|
||||
#endif
|
||||
free(f_data);
|
||||
f_data = NULL;
|
||||
}
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "FileWrapper.h"
|
||||
#include "cdrom/cdromif.h"
|
||||
#include "mempatcher.h"
|
||||
#include "compress/minilzo.h"
|
||||
#include "md5.h"
|
||||
#include "clamp.h"
|
||||
|
||||
@ -835,8 +834,6 @@ int MDFNI_Initialize(const char *basedir, const std::vector<MDFNSetting> &Driver
|
||||
// FIXME static
|
||||
static std::vector<MDFNSetting> dynamic_settings;
|
||||
|
||||
lzo_init();
|
||||
|
||||
MDFNI_SetBaseDirectory(basedir);
|
||||
|
||||
// Generate dynamic settings
|
||||
|
Loading…
Reference in New Issue
Block a user