mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-11 11:19:09 +00:00
touch: add new commands
This commit is contained in:
Executable
+270
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This file contains the definitions required to use AES in C. See aesopt.h
|
||||
for optimisation details.
|
||||
*/
|
||||
|
||||
#ifndef _AES_H
|
||||
#define _AES_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* This include is used to find 8 & 32 bit unsigned integer types */
|
||||
#include "brg_types.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define AES_128 /* if a fast 128 bit key scheduler is needed */
|
||||
#define AES_192 /* if a fast 192 bit key scheduler is needed */
|
||||
#define AES_256 /* if a fast 256 bit key scheduler is needed */
|
||||
#define AES_VAR /* if variable key size scheduler is needed */
|
||||
#define AES_MODES /* if support is needed for modes */
|
||||
|
||||
/* The following must also be set in assembler files if being used */
|
||||
|
||||
#define AES_ENCRYPT /* if support for encryption is needed */
|
||||
#define AES_DECRYPT /* if support for decryption is needed */
|
||||
|
||||
#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */
|
||||
#define N_COLS 4 /* the number of columns in the state */
|
||||
|
||||
/* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */
|
||||
/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */
|
||||
/* or 44, 52 or 60 32-bit words. */
|
||||
|
||||
#if defined( AES_VAR ) || defined( AES_256 )
|
||||
#define KS_LENGTH 60
|
||||
#elif defined( AES_192 )
|
||||
#define KS_LENGTH 52
|
||||
#else
|
||||
#define KS_LENGTH 44
|
||||
#endif
|
||||
|
||||
#define AES_RETURN INT_RETURN
|
||||
|
||||
/* the character array 'inf' in the following structures is used */
|
||||
/* to hold AES context information. This AES code uses cx->inf.b[0] */
|
||||
/* to hold the number of rounds multiplied by 16. The other three */
|
||||
/* elements can be used by code that implements additional modes */
|
||||
|
||||
typedef union
|
||||
{ uint32_t l;
|
||||
uint8_t b[4];
|
||||
} aes_inf;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning( disable : 4324 )
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(_WIN64)
|
||||
#define ALIGNED_(x) __declspec(align(x))
|
||||
#elif defined(__GNUC__) && defined(__x86_64__)
|
||||
#define ALIGNED_(x) __attribute__ ((aligned(x)))
|
||||
#else
|
||||
#define ALIGNED_(x)
|
||||
#endif
|
||||
|
||||
typedef struct ALIGNED_(16)
|
||||
{ uint32_t ks[KS_LENGTH];
|
||||
aes_inf inf;
|
||||
} aes_encrypt_ctx;
|
||||
|
||||
typedef struct ALIGNED_(16)
|
||||
{ uint32_t ks[KS_LENGTH];
|
||||
aes_inf inf;
|
||||
} aes_decrypt_ctx;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning( default : 4324 )
|
||||
#endif
|
||||
|
||||
/* This routine must be called before first use if non-static */
|
||||
/* tables are being used */
|
||||
|
||||
AES_RETURN aes_init(void);
|
||||
|
||||
/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */
|
||||
/* those in the range 128 <= key_len <= 256 are given in bits */
|
||||
|
||||
#if defined( AES_ENCRYPT )
|
||||
|
||||
#if defined( AES_128 ) || defined( AES_VAR)
|
||||
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined( AES_192 ) || defined( AES_VAR)
|
||||
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined( AES_256 ) || defined( AES_VAR)
|
||||
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined( AES_VAR )
|
||||
AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_DECRYPT )
|
||||
|
||||
#if defined( AES_128 ) || defined( AES_VAR)
|
||||
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined( AES_192 ) || defined( AES_VAR)
|
||||
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined( AES_256 ) || defined( AES_VAR)
|
||||
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
#if defined( AES_VAR )
|
||||
AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]);
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]);
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_MODES )
|
||||
|
||||
/* Multiple calls to the following subroutines for multiple block */
|
||||
/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */
|
||||
/* long messages incrementally provided that the context AND the iv */
|
||||
/* are preserved between all such calls. For the ECB and CBC modes */
|
||||
/* each individual call within a series of incremental calls must */
|
||||
/* process only full blocks (i.e. len must be a multiple of 16) but */
|
||||
/* the CFB, OFB and CTR mode calls can handle multiple incremental */
|
||||
/* calls of any length. Each mode is reset when a new AES key is */
|
||||
/* set but ECB needs no reset and CBC can be reset without setting */
|
||||
/* a new key by setting a new IV value. To reset CFB, OFB and CTR */
|
||||
/* without setting the key, aes_mode_reset() must be called and the */
|
||||
/* IV must be set. NOTE: All these calls update the IV on exit so */
|
||||
/* this has to be reset if a new operation with the same IV as the */
|
||||
/* previous one is required (or decryption follows encryption with */
|
||||
/* the same IV array). */
|
||||
|
||||
AES_RETURN aes_test_alignment_detection(unsigned int n);
|
||||
|
||||
AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, const aes_decrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, const aes_decrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||
|
||||
#define aes_ofb_encrypt aes_ofb_crypt
|
||||
#define aes_ofb_decrypt aes_ofb_crypt
|
||||
|
||||
AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
|
||||
|
||||
typedef void cbuf_inc(unsigned char *cbuf);
|
||||
|
||||
#define aes_ctr_encrypt aes_ctr_crypt
|
||||
#define aes_ctr_decrypt aes_ctr_crypt
|
||||
|
||||
AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
|
||||
int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]);
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
# define ADD_AESNI_MODE_CALLS
|
||||
#endif
|
||||
|
||||
#if 0 && defined( ADD_AESNI_MODE_CALLS )
|
||||
# define USE_AES_CONTEXT
|
||||
#endif
|
||||
|
||||
#ifdef ADD_AESNI_MODE_CALLS
|
||||
# ifdef USE_AES_CONTEXT
|
||||
|
||||
AES_RETURN aes_CBC_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
unsigned char ivec[16],
|
||||
unsigned long length,
|
||||
const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_CBC_decrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
unsigned char ivec[16],
|
||||
unsigned long length,
|
||||
const aes_decrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN AES_CTR_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
const unsigned char ivec[8],
|
||||
const unsigned char nonce[4],
|
||||
unsigned long length,
|
||||
const aes_encrypt_ctx cx[1]);
|
||||
|
||||
# else
|
||||
|
||||
void aes_CBC_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
unsigned char ivec[16],
|
||||
unsigned long length,
|
||||
unsigned char *key,
|
||||
int number_of_rounds);
|
||||
|
||||
void aes_CBC_decrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
unsigned char ivec[16],
|
||||
unsigned long length,
|
||||
unsigned char *key,
|
||||
int number_of_rounds);
|
||||
|
||||
void AES_CTR_encrypt(const unsigned char *in,
|
||||
unsigned char *out,
|
||||
const unsigned char ivec[8],
|
||||
const unsigned char nonce[4],
|
||||
unsigned long length,
|
||||
const unsigned char *key,
|
||||
int number_of_rounds);
|
||||
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Executable
+301
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#include "aesopt.h"
|
||||
#include "aestab.h"
|
||||
|
||||
#if defined( USE_INTEL_AES_IF_PRESENT )
|
||||
# include "aes_ni.h"
|
||||
#else
|
||||
/* map names here to provide the external API ('name' -> 'aes_name') */
|
||||
# define aes_xi(x) aes_ ## x
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
|
||||
#define so(y,x,c) word_out(y, c, s(x,c))
|
||||
|
||||
#if defined(ARRAYS)
|
||||
#define locals(y,x) x[4],y[4]
|
||||
#else
|
||||
#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
|
||||
#endif
|
||||
|
||||
#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
|
||||
s(y,2) = s(x,2); s(y,3) = s(x,3);
|
||||
#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
|
||||
#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
|
||||
#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
|
||||
|
||||
#if ( FUNCS_IN_C & ENCRYPTION_IN_C )
|
||||
|
||||
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||
Pentium optimiation with small code but this is poor for decryption
|
||||
so we need to control this with the following VC++ pragmas
|
||||
*/
|
||||
|
||||
#if defined( _MSC_VER ) && !defined( _WIN64 )
|
||||
#pragma optimize( "s", on )
|
||||
#endif
|
||||
|
||||
/* Given the column (c) of the output state variable, the following
|
||||
macros give the input state variables which are needed in its
|
||||
computation for each row (r) of the state. All the alternative
|
||||
macros give the same end values but expand into different ways
|
||||
of calculating these values. In particular the complex macro
|
||||
used for dynamically variable block sizes is designed to expand
|
||||
to a compile time constant whenever possible but will expand to
|
||||
conditional clauses on some branches (I am grateful to Frank
|
||||
Yellin for this construction)
|
||||
*/
|
||||
|
||||
#define fwd_var(x,r,c)\
|
||||
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
|
||||
: r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
|
||||
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
|
||||
: ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
|
||||
|
||||
#if defined(FT4_SET)
|
||||
#undef dec_fmvars
|
||||
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
|
||||
#elif defined(FT1_SET)
|
||||
#undef dec_fmvars
|
||||
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
|
||||
#else
|
||||
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))
|
||||
#endif
|
||||
|
||||
#if defined(FL4_SET)
|
||||
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
|
||||
#elif defined(FL1_SET)
|
||||
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
|
||||
#else
|
||||
#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
|
||||
{ uint32_t locals(b0, b1);
|
||||
const uint32_t *kp;
|
||||
#if defined( dec_fmvars )
|
||||
dec_fmvars; /* declare variables for fwd_mcol() if needed */
|
||||
#endif
|
||||
|
||||
if(cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
kp = cx->ks;
|
||||
state_in(b0, in, kp);
|
||||
|
||||
#if (ENC_UNROLL == FULL)
|
||||
|
||||
switch(cx->inf.b[0])
|
||||
{
|
||||
case 14 * 16:
|
||||
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||
kp += 2 * N_COLS;
|
||||
case 12 * 16:
|
||||
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||
kp += 2 * N_COLS;
|
||||
case 10 * 16:
|
||||
round(fwd_rnd, b1, b0, kp + 1 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 2 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 3 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 4 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 5 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 6 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 7 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 8 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 9 * N_COLS);
|
||||
round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if (ENC_UNROLL == PARTIAL)
|
||||
{ uint32_t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
|
||||
{
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b0, b1, kp);
|
||||
}
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
#else
|
||||
{ uint32_t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
|
||||
{
|
||||
kp += N_COLS;
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
l_copy(b0, b1);
|
||||
}
|
||||
#endif
|
||||
kp += N_COLS;
|
||||
round(fwd_lrnd, b0, b1, kp);
|
||||
}
|
||||
#endif
|
||||
|
||||
state_out(out, b0);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if ( FUNCS_IN_C & DECRYPTION_IN_C)
|
||||
|
||||
/* Visual C++ .Net v7.1 provides the fastest encryption code when using
|
||||
Pentium optimiation with small code but this is poor for decryption
|
||||
so we need to control this with the following VC++ pragmas
|
||||
*/
|
||||
|
||||
#if defined( _MSC_VER ) && !defined( _WIN64 )
|
||||
#pragma optimize( "t", on )
|
||||
#endif
|
||||
|
||||
/* Given the column (c) of the output state variable, the following
|
||||
macros give the input state variables which are needed in its
|
||||
computation for each row (r) of the state. All the alternative
|
||||
macros give the same end values but expand into different ways
|
||||
of calculating these values. In particular the complex macro
|
||||
used for dynamically variable block sizes is designed to expand
|
||||
to a compile time constant whenever possible but will expand to
|
||||
conditional clauses on some branches (I am grateful to Frank
|
||||
Yellin for this construction)
|
||||
*/
|
||||
|
||||
#define inv_var(x,r,c)\
|
||||
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
|
||||
: r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
|
||||
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
|
||||
: ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
|
||||
|
||||
#if defined(IT4_SET)
|
||||
#undef dec_imvars
|
||||
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
|
||||
#elif defined(IT1_SET)
|
||||
#undef dec_imvars
|
||||
#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
|
||||
#else
|
||||
#define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))
|
||||
#endif
|
||||
|
||||
#if defined(IL4_SET)
|
||||
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
|
||||
#elif defined(IL1_SET)
|
||||
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
|
||||
#else
|
||||
#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
|
||||
#endif
|
||||
|
||||
/* This code can work with the decryption key schedule in the */
|
||||
/* order that is used for encrytpion (where the 1st decryption */
|
||||
/* round key is at the high end ot the schedule) or with a key */
|
||||
/* schedule that has been reversed to put the 1st decryption */
|
||||
/* round key at the low end of the schedule in memory (when */
|
||||
/* AES_REV_DKS is defined) */
|
||||
|
||||
#ifdef AES_REV_DKS
|
||||
#define key_ofs 0
|
||||
#define rnd_key(n) (kp + n * N_COLS)
|
||||
#else
|
||||
#define key_ofs 1
|
||||
#define rnd_key(n) (kp - n * N_COLS)
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_xi(decrypt)(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
|
||||
{ uint32_t locals(b0, b1);
|
||||
#if defined( dec_imvars )
|
||||
dec_imvars; /* declare variables for inv_mcol() if needed */
|
||||
#endif
|
||||
const uint32_t *kp;
|
||||
|
||||
if(cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
|
||||
state_in(b0, in, kp);
|
||||
|
||||
#if (DEC_UNROLL == FULL)
|
||||
|
||||
kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
|
||||
switch(cx->inf.b[0])
|
||||
{
|
||||
case 14 * 16:
|
||||
round(inv_rnd, b1, b0, rnd_key(-13));
|
||||
round(inv_rnd, b0, b1, rnd_key(-12));
|
||||
case 12 * 16:
|
||||
round(inv_rnd, b1, b0, rnd_key(-11));
|
||||
round(inv_rnd, b0, b1, rnd_key(-10));
|
||||
case 10 * 16:
|
||||
round(inv_rnd, b1, b0, rnd_key(-9));
|
||||
round(inv_rnd, b0, b1, rnd_key(-8));
|
||||
round(inv_rnd, b1, b0, rnd_key(-7));
|
||||
round(inv_rnd, b0, b1, rnd_key(-6));
|
||||
round(inv_rnd, b1, b0, rnd_key(-5));
|
||||
round(inv_rnd, b0, b1, rnd_key(-4));
|
||||
round(inv_rnd, b1, b0, rnd_key(-3));
|
||||
round(inv_rnd, b0, b1, rnd_key(-2));
|
||||
round(inv_rnd, b1, b0, rnd_key(-1));
|
||||
round(inv_lrnd, b0, b1, rnd_key( 0));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if (DEC_UNROLL == PARTIAL)
|
||||
{ uint32_t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
|
||||
{
|
||||
kp = rnd_key(1);
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
kp = rnd_key(1);
|
||||
round(inv_rnd, b0, b1, kp);
|
||||
}
|
||||
kp = rnd_key(1);
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
#else
|
||||
{ uint32_t rnd;
|
||||
for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
|
||||
{
|
||||
kp = rnd_key(1);
|
||||
round(inv_rnd, b1, b0, kp);
|
||||
l_copy(b0, b1);
|
||||
}
|
||||
#endif
|
||||
kp = rnd_key(1);
|
||||
round(inv_lrnd, b0, b1, kp);
|
||||
}
|
||||
#endif
|
||||
|
||||
state_out(out, b0);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
Executable
+554
@@ -0,0 +1,554 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#include "aesopt.h"
|
||||
#include "aestab.h"
|
||||
|
||||
#if defined( USE_INTEL_AES_IF_PRESENT )
|
||||
# include "aes_ni.h"
|
||||
#else
|
||||
/* map names here to provide the external API ('name' -> 'aes_name') */
|
||||
# define aes_xi(x) aes_ ## x
|
||||
#endif
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
# include "aes_via_ace.h"
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* Initialise the key schedule from the user supplied key. The key
|
||||
length can be specified in bytes, with legal values of 16, 24
|
||||
and 32, or in bits, with legal values of 128, 192 and 256. These
|
||||
values correspond with Nk values of 4, 6 and 8 respectively.
|
||||
|
||||
The following macros implement a single cycle in the key
|
||||
schedule generation process. The number of cycles needed
|
||||
for each cx->n_col and nk value is:
|
||||
|
||||
nk = 4 5 6 7 8
|
||||
------------------------------
|
||||
cx->n_col = 4 10 9 8 7 7
|
||||
cx->n_col = 5 14 11 10 9 9
|
||||
cx->n_col = 6 19 15 12 11 11
|
||||
cx->n_col = 7 21 19 16 13 14
|
||||
cx->n_col = 8 29 23 19 17 14
|
||||
*/
|
||||
|
||||
#if defined( REDUCE_CODE_SIZE )
|
||||
# define ls_box ls_sub
|
||||
uint32_t ls_sub(const uint32_t t, const uint32_t n);
|
||||
# define inv_mcol im_sub
|
||||
uint32_t im_sub(const uint32_t x);
|
||||
# ifdef ENC_KS_UNROLL
|
||||
# undef ENC_KS_UNROLL
|
||||
# endif
|
||||
# ifdef DEC_KS_UNROLL
|
||||
# undef DEC_KS_UNROLL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if (FUNCS_IN_C & ENC_KEYING_IN_C)
|
||||
|
||||
#if defined(AES_128) || defined( AES_VAR )
|
||||
|
||||
#define ke4(k,i) \
|
||||
{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
|
||||
k[4*(i)+5] = ss[1] ^= ss[0]; \
|
||||
k[4*(i)+6] = ss[2] ^= ss[1]; \
|
||||
k[4*(i)+7] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_xi(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{ uint32_t ss[4];
|
||||
|
||||
cx->ks[0] = ss[0] = word_in(key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(key, 1);
|
||||
cx->ks[2] = ss[2] = word_in(key, 2);
|
||||
cx->ks[3] = ss[3] = word_in(key, 3);
|
||||
|
||||
#ifdef ENC_KS_UNROLL
|
||||
ke4(cx->ks, 0); ke4(cx->ks, 1);
|
||||
ke4(cx->ks, 2); ke4(cx->ks, 3);
|
||||
ke4(cx->ks, 4); ke4(cx->ks, 5);
|
||||
ke4(cx->ks, 6); ke4(cx->ks, 7);
|
||||
ke4(cx->ks, 8);
|
||||
#else
|
||||
{ uint32_t i;
|
||||
for(i = 0; i < 9; ++i)
|
||||
ke4(cx->ks, i);
|
||||
}
|
||||
#endif
|
||||
ke4(cx->ks, 9);
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 10 * 16;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_192) || defined( AES_VAR )
|
||||
|
||||
#define kef6(k,i) \
|
||||
{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
|
||||
k[6*(i)+ 7] = ss[1] ^= ss[0]; \
|
||||
k[6*(i)+ 8] = ss[2] ^= ss[1]; \
|
||||
k[6*(i)+ 9] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#define ke6(k,i) \
|
||||
{ kef6(k,i); \
|
||||
k[6*(i)+10] = ss[4] ^= ss[3]; \
|
||||
k[6*(i)+11] = ss[5] ^= ss[4]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_xi(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{ uint32_t ss[6];
|
||||
|
||||
cx->ks[0] = ss[0] = word_in(key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(key, 1);
|
||||
cx->ks[2] = ss[2] = word_in(key, 2);
|
||||
cx->ks[3] = ss[3] = word_in(key, 3);
|
||||
cx->ks[4] = ss[4] = word_in(key, 4);
|
||||
cx->ks[5] = ss[5] = word_in(key, 5);
|
||||
|
||||
#ifdef ENC_KS_UNROLL
|
||||
ke6(cx->ks, 0); ke6(cx->ks, 1);
|
||||
ke6(cx->ks, 2); ke6(cx->ks, 3);
|
||||
ke6(cx->ks, 4); ke6(cx->ks, 5);
|
||||
ke6(cx->ks, 6);
|
||||
#else
|
||||
{ uint32_t i;
|
||||
for(i = 0; i < 7; ++i)
|
||||
ke6(cx->ks, i);
|
||||
}
|
||||
#endif
|
||||
kef6(cx->ks, 7);
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 12 * 16;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_256) || defined( AES_VAR )
|
||||
|
||||
#define kef8(k,i) \
|
||||
{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
|
||||
k[8*(i)+ 9] = ss[1] ^= ss[0]; \
|
||||
k[8*(i)+10] = ss[2] ^= ss[1]; \
|
||||
k[8*(i)+11] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#define ke8(k,i) \
|
||||
{ kef8(k,i); \
|
||||
k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
|
||||
k[8*(i)+13] = ss[5] ^= ss[4]; \
|
||||
k[8*(i)+14] = ss[6] ^= ss[5]; \
|
||||
k[8*(i)+15] = ss[7] ^= ss[6]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1])
|
||||
{ uint32_t ss[8];
|
||||
|
||||
cx->ks[0] = ss[0] = word_in(key, 0);
|
||||
cx->ks[1] = ss[1] = word_in(key, 1);
|
||||
cx->ks[2] = ss[2] = word_in(key, 2);
|
||||
cx->ks[3] = ss[3] = word_in(key, 3);
|
||||
cx->ks[4] = ss[4] = word_in(key, 4);
|
||||
cx->ks[5] = ss[5] = word_in(key, 5);
|
||||
cx->ks[6] = ss[6] = word_in(key, 6);
|
||||
cx->ks[7] = ss[7] = word_in(key, 7);
|
||||
|
||||
#ifdef ENC_KS_UNROLL
|
||||
ke8(cx->ks, 0); ke8(cx->ks, 1);
|
||||
ke8(cx->ks, 2); ke8(cx->ks, 3);
|
||||
ke8(cx->ks, 4); ke8(cx->ks, 5);
|
||||
#else
|
||||
{ uint32_t i;
|
||||
for(i = 0; i < 6; ++i)
|
||||
ke8(cx->ks, i);
|
||||
}
|
||||
#endif
|
||||
kef8(cx->ks, 6);
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 14 * 16;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if (FUNCS_IN_C & DEC_KEYING_IN_C)
|
||||
|
||||
/* this is used to store the decryption round keys */
|
||||
/* in forward or reverse order */
|
||||
|
||||
#ifdef AES_REV_DKS
|
||||
#define v(n,i) ((n) - (i) + 2 * ((i) & 3))
|
||||
#else
|
||||
#define v(n,i) (i)
|
||||
#endif
|
||||
|
||||
#if DEC_ROUND == NO_TABLES
|
||||
#define ff(x) (x)
|
||||
#else
|
||||
#define ff(x) inv_mcol(x)
|
||||
#if defined( dec_imvars )
|
||||
#define d_vars dec_imvars
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(AES_128) || defined( AES_VAR )
|
||||
|
||||
#define k4e(k,i) \
|
||||
{ k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
|
||||
k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
|
||||
k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
|
||||
k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#if 1
|
||||
|
||||
#define kdf4(k,i) \
|
||||
{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
|
||||
ss[1] = ss[1] ^ ss[3]; \
|
||||
ss[2] = ss[2] ^ ss[3]; \
|
||||
ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
|
||||
ss[i % 4] ^= ss[4]; \
|
||||
ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \
|
||||
ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
|
||||
ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
|
||||
ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
|
||||
}
|
||||
|
||||
#define kd4(k,i) \
|
||||
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
|
||||
ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
|
||||
k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
|
||||
k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
|
||||
k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
|
||||
k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
|
||||
}
|
||||
|
||||
#define kdl4(k,i) \
|
||||
{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
|
||||
k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
|
||||
k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
|
||||
k[v(40,(4*(i))+6)] = ss[0]; \
|
||||
k[v(40,(4*(i))+7)] = ss[1]; \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define kdf4(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \
|
||||
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \
|
||||
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \
|
||||
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \
|
||||
}
|
||||
|
||||
#define kd4(k,i) \
|
||||
{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
|
||||
ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \
|
||||
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \
|
||||
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \
|
||||
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \
|
||||
}
|
||||
|
||||
#define kdl4(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \
|
||||
ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \
|
||||
ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \
|
||||
ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
AES_RETURN aes_xi(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{ uint32_t ss[5];
|
||||
#if defined( d_vars )
|
||||
d_vars;
|
||||
#endif
|
||||
|
||||
cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
|
||||
cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
|
||||
cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
|
||||
cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
|
||||
|
||||
#ifdef DEC_KS_UNROLL
|
||||
kdf4(cx->ks, 0); kd4(cx->ks, 1);
|
||||
kd4(cx->ks, 2); kd4(cx->ks, 3);
|
||||
kd4(cx->ks, 4); kd4(cx->ks, 5);
|
||||
kd4(cx->ks, 6); kd4(cx->ks, 7);
|
||||
kd4(cx->ks, 8); kdl4(cx->ks, 9);
|
||||
#else
|
||||
{ uint32_t i;
|
||||
for(i = 0; i < 10; ++i)
|
||||
k4e(cx->ks, i);
|
||||
#if !(DEC_ROUND == NO_TABLES)
|
||||
for(i = N_COLS; i < 10 * N_COLS; ++i)
|
||||
cx->ks[i] = inv_mcol(cx->ks[i]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 10 * 16;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_192) || defined( AES_VAR )
|
||||
|
||||
#define k6ef(k,i) \
|
||||
{ k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
|
||||
k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
|
||||
k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
|
||||
k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#define k6e(k,i) \
|
||||
{ k6ef(k,i); \
|
||||
k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
|
||||
k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
|
||||
}
|
||||
|
||||
#define kdf6(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
|
||||
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
|
||||
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
|
||||
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
|
||||
ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
|
||||
ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
|
||||
}
|
||||
|
||||
#define kd6(k,i) \
|
||||
{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
|
||||
ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
|
||||
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
|
||||
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
|
||||
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
|
||||
ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
|
||||
ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
|
||||
}
|
||||
|
||||
#define kdl6(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
|
||||
ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
|
||||
ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
|
||||
ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{ uint32_t ss[7];
|
||||
#if defined( d_vars )
|
||||
d_vars;
|
||||
#endif
|
||||
|
||||
cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
|
||||
cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
|
||||
cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
|
||||
cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
|
||||
|
||||
#ifdef DEC_KS_UNROLL
|
||||
cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
|
||||
cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
|
||||
kdf6(cx->ks, 0); kd6(cx->ks, 1);
|
||||
kd6(cx->ks, 2); kd6(cx->ks, 3);
|
||||
kd6(cx->ks, 4); kd6(cx->ks, 5);
|
||||
kd6(cx->ks, 6); kdl6(cx->ks, 7);
|
||||
#else
|
||||
cx->ks[v(48,(4))] = ss[4] = word_in(key, 4);
|
||||
cx->ks[v(48,(5))] = ss[5] = word_in(key, 5);
|
||||
{ uint32_t i;
|
||||
|
||||
for(i = 0; i < 7; ++i)
|
||||
k6e(cx->ks, i);
|
||||
k6ef(cx->ks, 7);
|
||||
#if !(DEC_ROUND == NO_TABLES)
|
||||
for(i = N_COLS; i < 12 * N_COLS; ++i)
|
||||
cx->ks[i] = inv_mcol(cx->ks[i]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 12 * 16;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(AES_256) || defined( AES_VAR )
|
||||
|
||||
#define k8ef(k,i) \
|
||||
{ k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
|
||||
k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
|
||||
k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
|
||||
k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
|
||||
}
|
||||
|
||||
#define k8e(k,i) \
|
||||
{ k8ef(k,i); \
|
||||
k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
|
||||
k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
|
||||
k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
|
||||
k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
|
||||
}
|
||||
|
||||
#define kdf8(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
|
||||
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
|
||||
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
|
||||
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
|
||||
ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
|
||||
ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
|
||||
ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
|
||||
ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
|
||||
}
|
||||
|
||||
#define kd8(k,i) \
|
||||
{ ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
|
||||
ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
|
||||
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
|
||||
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
|
||||
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
|
||||
ss[8] = ls_box(ss[3],0); \
|
||||
ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
|
||||
ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
|
||||
ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
|
||||
ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
|
||||
}
|
||||
|
||||
#define kdl8(k,i) \
|
||||
{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
|
||||
ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
|
||||
ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
|
||||
ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
|
||||
}
|
||||
|
||||
AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1])
|
||||
{ uint32_t ss[9];
|
||||
#if defined( d_vars )
|
||||
d_vars;
|
||||
#endif
|
||||
|
||||
cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
|
||||
cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
|
||||
cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
|
||||
cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
|
||||
|
||||
#ifdef DEC_KS_UNROLL
|
||||
cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
|
||||
cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
|
||||
cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
|
||||
cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
|
||||
kdf8(cx->ks, 0); kd8(cx->ks, 1);
|
||||
kd8(cx->ks, 2); kd8(cx->ks, 3);
|
||||
kd8(cx->ks, 4); kd8(cx->ks, 5);
|
||||
kdl8(cx->ks, 6);
|
||||
#else
|
||||
cx->ks[v(56,(4))] = ss[4] = word_in(key, 4);
|
||||
cx->ks[v(56,(5))] = ss[5] = word_in(key, 5);
|
||||
cx->ks[v(56,(6))] = ss[6] = word_in(key, 6);
|
||||
cx->ks[v(56,(7))] = ss[7] = word_in(key, 7);
|
||||
{ uint32_t i;
|
||||
|
||||
for(i = 0; i < 6; ++i)
|
||||
k8e(cx->ks, i);
|
||||
k8ef(cx->ks, 6);
|
||||
#if !(DEC_ROUND == NO_TABLES)
|
||||
for(i = N_COLS; i < 14 * N_COLS; ++i)
|
||||
cx->ks[i] = inv_mcol(cx->ks[i]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
cx->inf.l = 0;
|
||||
cx->inf.b[0] = 14 * 16;
|
||||
|
||||
#ifdef USE_VIA_ACE_IF_PRESENT
|
||||
if(VIA_ACE_AVAILABLE)
|
||||
cx->inf.b[1] = 0xff;
|
||||
#endif
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( AES_VAR )
|
||||
|
||||
AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
|
||||
{
|
||||
switch(key_len)
|
||||
{
|
||||
case 16: case 128: return aes_encrypt_key128(key, cx);
|
||||
case 24: case 192: return aes_encrypt_key192(key, cx);
|
||||
case 32: case 256: return aes_encrypt_key256(key, cx);
|
||||
default: return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
|
||||
{
|
||||
switch(key_len)
|
||||
{
|
||||
case 16: case 128: return aes_decrypt_key128(key, cx);
|
||||
case 24: case 192: return aes_decrypt_key192(key, cx);
|
||||
case 32: case 256: return aes_decrypt_key256(key, cx);
|
||||
default: return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
Executable
+776
@@ -0,0 +1,776 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This file contains the compilation options for AES (Rijndael) and code
|
||||
that is common across encryption, key scheduling and table generation.
|
||||
|
||||
OPERATION
|
||||
|
||||
These source code files implement the AES algorithm Rijndael designed by
|
||||
Joan Daemen and Vincent Rijmen. This version is designed for the standard
|
||||
block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24
|
||||
and 32 bytes).
|
||||
|
||||
This version is designed for flexibility and speed using operations on
|
||||
32-bit words rather than operations on bytes. It can be compiled with
|
||||
either big or little endian internal byte order but is faster when the
|
||||
native byte order for the processor is used.
|
||||
|
||||
THE CIPHER INTERFACE
|
||||
|
||||
The cipher interface is implemented as an array of bytes in which lower
|
||||
AES bit sequence indexes map to higher numeric significance within bytes.
|
||||
|
||||
uint8_t (an unsigned 8-bit type)
|
||||
uint32_t (an unsigned 32-bit type)
|
||||
struct aes_encrypt_ctx (structure for the cipher encryption context)
|
||||
struct aes_decrypt_ctx (structure for the cipher decryption context)
|
||||
AES_RETURN the function return type
|
||||
|
||||
C subroutine calls:
|
||||
|
||||
AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
|
||||
AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const aes_encrypt_ctx cx[1]);
|
||||
|
||||
AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
|
||||
AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const aes_decrypt_ctx cx[1]);
|
||||
|
||||
IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that
|
||||
you call aes_init() before AES is used so that the tables are initialised.
|
||||
|
||||
C++ aes class subroutines:
|
||||
|
||||
Class AESencrypt for encryption
|
||||
|
||||
Construtors:
|
||||
AESencrypt(void)
|
||||
AESencrypt(const unsigned char *key) - 128 bit key
|
||||
Members:
|
||||
AES_RETURN key128(const unsigned char *key)
|
||||
AES_RETURN key192(const unsigned char *key)
|
||||
AES_RETURN key256(const unsigned char *key)
|
||||
AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const
|
||||
|
||||
Class AESdecrypt for encryption
|
||||
Construtors:
|
||||
AESdecrypt(void)
|
||||
AESdecrypt(const unsigned char *key) - 128 bit key
|
||||
Members:
|
||||
AES_RETURN key128(const unsigned char *key)
|
||||
AES_RETURN key192(const unsigned char *key)
|
||||
AES_RETURN key256(const unsigned char *key)
|
||||
AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const
|
||||
*/
|
||||
|
||||
#if !defined( _AESOPT_H )
|
||||
#define _AESOPT_H
|
||||
|
||||
#if defined( __cplusplus )
|
||||
#include "aescpp.h"
|
||||
#else
|
||||
#include "aes.h"
|
||||
#endif
|
||||
|
||||
/* PLATFORM SPECIFIC INCLUDES */
|
||||
|
||||
#include "brg_endian.h"
|
||||
|
||||
/* CONFIGURATION - THE USE OF DEFINES
|
||||
|
||||
Later in this section there are a number of defines that control the
|
||||
operation of the code. In each section, the purpose of each define is
|
||||
explained so that the relevant form can be included or excluded by
|
||||
setting either 1's or 0's respectively on the branches of the related
|
||||
#if clauses. The following local defines should not be changed.
|
||||
*/
|
||||
|
||||
#define ENCRYPTION_IN_C 1
|
||||
#define DECRYPTION_IN_C 2
|
||||
#define ENC_KEYING_IN_C 4
|
||||
#define DEC_KEYING_IN_C 8
|
||||
|
||||
#define NO_TABLES 0
|
||||
#define ONE_TABLE 1
|
||||
#define FOUR_TABLES 4
|
||||
#define NONE 0
|
||||
#define PARTIAL 1
|
||||
#define FULL 2
|
||||
|
||||
/* --- START OF USER CONFIGURED OPTIONS --- */
|
||||
|
||||
/* 1. BYTE ORDER WITHIN 32 BIT WORDS
|
||||
|
||||
The fundamental data processing units in Rijndael are 8-bit bytes. The
|
||||
input, output and key input are all enumerated arrays of bytes in which
|
||||
bytes are numbered starting at zero and increasing to one less than the
|
||||
number of bytes in the array in question. This enumeration is only used
|
||||
for naming bytes and does not imply any adjacency or order relationship
|
||||
from one byte to another. When these inputs and outputs are considered
|
||||
as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
|
||||
byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
|
||||
In this implementation bits are numbered from 0 to 7 starting at the
|
||||
numerically least significant end of each byte (bit n represents 2^n).
|
||||
|
||||
However, Rijndael can be implemented more efficiently using 32-bit
|
||||
words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
|
||||
into word[n]. While in principle these bytes can be assembled into words
|
||||
in any positions, this implementation only supports the two formats in
|
||||
which bytes in adjacent positions within words also have adjacent byte
|
||||
numbers. This order is called big-endian if the lowest numbered bytes
|
||||
in words have the highest numeric significance and little-endian if the
|
||||
opposite applies.
|
||||
|
||||
This code can work in either order irrespective of the order used by the
|
||||
machine on which it runs. Normally the internal byte order will be set
|
||||
to the order of the processor on which the code is to be run but this
|
||||
define can be used to reverse this in special situations
|
||||
|
||||
WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set.
|
||||
This define will hence be redefined later (in section 4) if necessary
|
||||
*/
|
||||
|
||||
#if 1
|
||||
# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
|
||||
#elif 0
|
||||
# define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#elif 0
|
||||
# define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#else
|
||||
# error The algorithm byte order is not defined
|
||||
#endif
|
||||
|
||||
/* 2. Intel AES AND VIA ACE SUPPORT */
|
||||
|
||||
#if defined( __GNUC__ ) && defined( __i386__ ) \
|
||||
|| defined( _WIN32 ) && defined( _M_IX86 ) && !(defined( _WIN64 ) \
|
||||
|| defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
|
||||
# define VIA_ACE_POSSIBLE
|
||||
#endif
|
||||
|
||||
#if (defined( _WIN64 ) && defined( _MSC_VER )) \
|
||||
|| (defined( __GNUC__ ) && defined( __x86_64__ )) && !(defined( __APPLE__ ))\
|
||||
&& !(defined( INTEL_AES_POSSIBLE ))
|
||||
# define INTEL_AES_POSSIBLE
|
||||
#endif
|
||||
|
||||
/* Define this option if support for the Intel AESNI is required
|
||||
If USE_INTEL_AES_IF_PRESENT is defined then AESNI will be used
|
||||
if it is detected (both present and enabled).
|
||||
|
||||
AESNI uses a decryption key schedule with the first decryption
|
||||
round key at the high end of the key scedule with the following
|
||||
round keys at lower positions in memory. So AES_REV_DKS must NOT
|
||||
be defined when AESNI will be used. ALthough it is unlikely that
|
||||
assembler code will be used with an AESNI build, if it is then
|
||||
AES_REV_DKS must NOT be defined when the assembler files are
|
||||
built
|
||||
*/
|
||||
|
||||
#if 0 && defined( INTEL_AES_POSSIBLE ) && !defined( USE_INTEL_AES_IF_PRESENT )
|
||||
# define USE_INTEL_AES_IF_PRESENT
|
||||
#endif
|
||||
|
||||
/* Define this option if support for the VIA ACE is required. This uses
|
||||
inline assembler instructions and is only implemented for the Microsoft,
|
||||
Intel and GCC compilers. If VIA ACE is known to be present, then defining
|
||||
ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption
|
||||
code. If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if
|
||||
it is detected (both present and enabled) but the normal AES code will
|
||||
also be present.
|
||||
|
||||
When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte
|
||||
aligned; other input/output buffers do not need to be 16 byte aligned
|
||||
but there are very large performance gains if this can be arranged.
|
||||
VIA ACE also requires the decryption key schedule to be in reverse
|
||||
order (which later checks below ensure).
|
||||
|
||||
AES_REV_DKS must be set for assembler code used with a VIA ACE build
|
||||
*/
|
||||
|
||||
#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT )
|
||||
# define USE_VIA_ACE_IF_PRESENT
|
||||
#endif
|
||||
|
||||
#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT )
|
||||
# define ASSUME_VIA_ACE_PRESENT
|
||||
# endif
|
||||
|
||||
/* 3. ASSEMBLER SUPPORT
|
||||
|
||||
This define (which can be on the command line) enables the use of the
|
||||
assembler code routines for encryption, decryption and key scheduling
|
||||
as follows:
|
||||
|
||||
ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for
|
||||
encryption and decryption and but with key scheduling in C
|
||||
ASM_X86_V2 uses assembler (aes_x86_v2.asm) with compressed tables for
|
||||
encryption, decryption and key scheduling
|
||||
ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for
|
||||
encryption and decryption and but with key scheduling in C
|
||||
ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for
|
||||
encryption and decryption and but with key scheduling in C
|
||||
|
||||
Change one 'if 0' below to 'if 1' to select the version or define
|
||||
as a compilation option.
|
||||
*/
|
||||
|
||||
#if 0 && !defined( ASM_X86_V1C )
|
||||
# define ASM_X86_V1C
|
||||
#elif 0 && !defined( ASM_X86_V2 )
|
||||
# define ASM_X86_V2
|
||||
#elif 0 && !defined( ASM_X86_V2C )
|
||||
# define ASM_X86_V2C
|
||||
#elif 0 && !defined( ASM_AMD64_C )
|
||||
# define ASM_AMD64_C
|
||||
#endif
|
||||
|
||||
#if defined( __i386 ) || defined( _M_IX86 )
|
||||
# define A32_
|
||||
#elif defined( __x86_64__ ) || defined( _M_X64 )
|
||||
# define A64_
|
||||
#endif
|
||||
|
||||
#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \
|
||||
&& !defined( A32_ ) || defined( ASM_AMD64_C ) && !defined( A64_ )
|
||||
# error Assembler code is only available for x86 and AMD64 systems
|
||||
#endif
|
||||
|
||||
/* 4. FAST INPUT/OUTPUT OPERATIONS.
|
||||
|
||||
On some machines it is possible to improve speed by transferring the
|
||||
bytes in the input and output arrays to and from the internal 32-bit
|
||||
variables by addressing these arrays as if they are arrays of 32-bit
|
||||
words. On some machines this will always be possible but there may
|
||||
be a large performance penalty if the byte arrays are not aligned on
|
||||
the normal word boundaries. On other machines this technique will
|
||||
lead to memory access errors when such 32-bit word accesses are not
|
||||
properly aligned. The option SAFE_IO avoids such problems but will
|
||||
often be slower on those machines that support misaligned access
|
||||
(especially so if care is taken to align the input and output byte
|
||||
arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
|
||||
assumed that access to byte arrays as if they are arrays of 32-bit
|
||||
words will not cause problems when such accesses are misaligned.
|
||||
*/
|
||||
#if 1 && !defined( _MSC_VER )
|
||||
# define SAFE_IO
|
||||
#endif
|
||||
|
||||
/* 5. LOOP UNROLLING
|
||||
|
||||
The code for encryption and decrytpion cycles through a number of rounds
|
||||
that can be implemented either in a loop or by expanding the code into a
|
||||
long sequence of instructions, the latter producing a larger program but
|
||||
one that will often be much faster. The latter is called loop unrolling.
|
||||
There are also potential speed advantages in expanding two iterations in
|
||||
a loop with half the number of iterations, which is called partial loop
|
||||
unrolling. The following options allow partial or full loop unrolling
|
||||
to be set independently for encryption and decryption
|
||||
*/
|
||||
#if 1
|
||||
# define ENC_UNROLL FULL
|
||||
#elif 0
|
||||
# define ENC_UNROLL PARTIAL
|
||||
#else
|
||||
# define ENC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
# define DEC_UNROLL FULL
|
||||
#elif 0
|
||||
# define DEC_UNROLL PARTIAL
|
||||
#else
|
||||
# define DEC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
# define ENC_KS_UNROLL
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
# define DEC_KS_UNROLL
|
||||
#endif
|
||||
|
||||
/* 6. FAST FINITE FIELD OPERATIONS
|
||||
|
||||
If this section is included, tables are used to provide faster finite
|
||||
field arithmetic (this has no effect if STATIC_TABLES is defined).
|
||||
*/
|
||||
#if 1
|
||||
# define FF_TABLES
|
||||
#endif
|
||||
|
||||
/* 7. INTERNAL STATE VARIABLE FORMAT
|
||||
|
||||
The internal state of Rijndael is stored in a number of local 32-bit
|
||||
word varaibles which can be defined either as an array or as individual
|
||||
names variables. Include this section if you want to store these local
|
||||
varaibles in arrays. Otherwise individual local variables will be used.
|
||||
*/
|
||||
#if 1
|
||||
# define ARRAYS
|
||||
#endif
|
||||
|
||||
/* 8. FIXED OR DYNAMIC TABLES
|
||||
|
||||
When this section is included the tables used by the code are compiled
|
||||
statically into the binary file. Otherwise the subroutine aes_init()
|
||||
must be called to compute them before the code is first used.
|
||||
*/
|
||||
#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
|
||||
# define STATIC_TABLES
|
||||
#endif
|
||||
|
||||
/* 9. MASKING OR CASTING FROM LONGER VALUES TO BYTES
|
||||
|
||||
In some systems it is better to mask longer values to extract bytes
|
||||
rather than using a cast. This option allows this choice.
|
||||
*/
|
||||
#if 0
|
||||
# define to_byte(x) ((uint8_t)(x))
|
||||
#else
|
||||
# define to_byte(x) ((x) & 0xff)
|
||||
#endif
|
||||
|
||||
/* 10. TABLE ALIGNMENT
|
||||
|
||||
On some sytsems speed will be improved by aligning the AES large lookup
|
||||
tables on particular boundaries. This define should be set to a power of
|
||||
two giving the desired alignment. It can be left undefined if alignment
|
||||
is not needed. This option is specific to the Microsft VC++ compiler -
|
||||
it seems to sometimes cause trouble for the VC++ version 6 compiler.
|
||||
*/
|
||||
|
||||
#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
|
||||
# define TABLE_ALIGN 32
|
||||
#endif
|
||||
|
||||
/* 11. REDUCE CODE AND TABLE SIZE
|
||||
|
||||
This replaces some expanded macros with function calls if AES_ASM_V2 or
|
||||
AES_ASM_V2C are defined
|
||||
*/
|
||||
|
||||
#if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))
|
||||
# define REDUCE_CODE_SIZE
|
||||
#endif
|
||||
|
||||
/* 12. TABLE OPTIONS
|
||||
|
||||
This cipher proceeds by repeating in a number of cycles known as 'rounds'
|
||||
which are implemented by a round function which can optionally be speeded
|
||||
up using tables. The basic tables are each 256 32-bit words, with either
|
||||
one or four tables being required for each round function depending on
|
||||
how much speed is required. The encryption and decryption round functions
|
||||
are different and the last encryption and decrytpion round functions are
|
||||
different again making four different round functions in all.
|
||||
|
||||
This means that:
|
||||
1. Normal encryption and decryption rounds can each use either 0, 1
|
||||
or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
|
||||
2. The last encryption and decryption rounds can also use either 0, 1
|
||||
or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
|
||||
|
||||
Include or exclude the appropriate definitions below to set the number
|
||||
of tables used by this implementation.
|
||||
*/
|
||||
|
||||
#if 1 /* set tables for the normal encryption round */
|
||||
# define ENC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
# define ENC_ROUND ONE_TABLE
|
||||
#else
|
||||
# define ENC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
#if 1 /* set tables for the last encryption round */
|
||||
# define LAST_ENC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
# define LAST_ENC_ROUND ONE_TABLE
|
||||
#else
|
||||
# define LAST_ENC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
#if 1 /* set tables for the normal decryption round */
|
||||
# define DEC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
# define DEC_ROUND ONE_TABLE
|
||||
#else
|
||||
# define DEC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
#if 1 /* set tables for the last decryption round */
|
||||
# define LAST_DEC_ROUND FOUR_TABLES
|
||||
#elif 0
|
||||
# define LAST_DEC_ROUND ONE_TABLE
|
||||
#else
|
||||
# define LAST_DEC_ROUND NO_TABLES
|
||||
#endif
|
||||
|
||||
/* The decryption key schedule can be speeded up with tables in the same
|
||||
way that the round functions can. Include or exclude the following
|
||||
defines to set this requirement.
|
||||
*/
|
||||
#if 1
|
||||
# define KEY_SCHED FOUR_TABLES
|
||||
#elif 0
|
||||
# define KEY_SCHED ONE_TABLE
|
||||
#else
|
||||
# define KEY_SCHED NO_TABLES
|
||||
#endif
|
||||
|
||||
/* ---- END OF USER CONFIGURED OPTIONS ---- */
|
||||
|
||||
/* VIA ACE support is only available for VC++ and GCC */
|
||||
|
||||
#if !defined( _MSC_VER ) && !defined( __GNUC__ )
|
||||
# if defined( ASSUME_VIA_ACE_PRESENT )
|
||||
# undef ASSUME_VIA_ACE_PRESENT
|
||||
# endif
|
||||
# if defined( USE_VIA_ACE_IF_PRESENT )
|
||||
# undef USE_VIA_ACE_IF_PRESENT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT )
|
||||
# define USE_VIA_ACE_IF_PRESENT
|
||||
#endif
|
||||
|
||||
/* define to reverse decryption key schedule */
|
||||
#if 1 || defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS )
|
||||
# define AES_REV_DKS
|
||||
#endif
|
||||
|
||||
/* Intel AESNI uses a decryption key schedule in the encryption order */
|
||||
#if defined( USE_INTEL_AES_IF_PRESENT ) && defined ( AES_REV_DKS )
|
||||
# undef AES_REV_DKS
|
||||
#endif
|
||||
|
||||
/* Assembler support requires the use of platform byte order */
|
||||
|
||||
#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \
|
||||
&& (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER)
|
||||
# undef ALGORITHM_BYTE_ORDER
|
||||
# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
|
||||
#endif
|
||||
|
||||
/* In this implementation the columns of the state array are each held in
|
||||
32-bit words. The state array can be held in various ways: in an array
|
||||
of words, in a number of individual word variables or in a number of
|
||||
processor registers. The following define maps a variable name x and
|
||||
a column number c to the way the state array variable is to be held.
|
||||
The first define below maps the state into an array x[c] whereas the
|
||||
second form maps the state into a number of individual variables x0,
|
||||
x1, etc. Another form could map individual state colums to machine
|
||||
register names.
|
||||
*/
|
||||
|
||||
#if defined( ARRAYS )
|
||||
# define s(x,c) x[c]
|
||||
#else
|
||||
# define s(x,c) x##c
|
||||
#endif
|
||||
|
||||
/* This implementation provides subroutines for encryption, decryption
|
||||
and for setting the three key lengths (separately) for encryption
|
||||
and decryption. Since not all functions are needed, masks are set
|
||||
up here to determine which will be implemented in C
|
||||
*/
|
||||
|
||||
#if !defined( AES_ENCRYPT )
|
||||
# define EFUNCS_IN_C 0
|
||||
#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
|
||||
|| defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
|
||||
# define EFUNCS_IN_C ENC_KEYING_IN_C
|
||||
#elif !defined( ASM_X86_V2 )
|
||||
# define EFUNCS_IN_C ( ENCRYPTION_IN_C | ENC_KEYING_IN_C )
|
||||
#else
|
||||
# define EFUNCS_IN_C 0
|
||||
#endif
|
||||
|
||||
#if !defined( AES_DECRYPT )
|
||||
# define DFUNCS_IN_C 0
|
||||
#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
|
||||
|| defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
|
||||
# define DFUNCS_IN_C DEC_KEYING_IN_C
|
||||
#elif !defined( ASM_X86_V2 )
|
||||
# define DFUNCS_IN_C ( DECRYPTION_IN_C | DEC_KEYING_IN_C )
|
||||
#else
|
||||
# define DFUNCS_IN_C 0
|
||||
#endif
|
||||
|
||||
#define FUNCS_IN_C ( EFUNCS_IN_C | DFUNCS_IN_C )
|
||||
|
||||
/* END OF CONFIGURATION OPTIONS */
|
||||
|
||||
#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2))
|
||||
|
||||
/* Disable or report errors on some combinations of options */
|
||||
|
||||
#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
|
||||
# undef LAST_ENC_ROUND
|
||||
# define LAST_ENC_ROUND NO_TABLES
|
||||
#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
|
||||
# undef LAST_ENC_ROUND
|
||||
# define LAST_ENC_ROUND ONE_TABLE
|
||||
#endif
|
||||
|
||||
#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
|
||||
# undef ENC_UNROLL
|
||||
# define ENC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
|
||||
# undef LAST_DEC_ROUND
|
||||
# define LAST_DEC_ROUND NO_TABLES
|
||||
#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
|
||||
# undef LAST_DEC_ROUND
|
||||
# define LAST_DEC_ROUND ONE_TABLE
|
||||
#endif
|
||||
|
||||
#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
|
||||
# undef DEC_UNROLL
|
||||
# define DEC_UNROLL NONE
|
||||
#endif
|
||||
|
||||
#if defined( bswap32 )
|
||||
# define aes_sw32 bswap32
|
||||
#elif defined( bswap_32 )
|
||||
# define aes_sw32 bswap_32
|
||||
#else
|
||||
# define brot(x,n) (((uint32_t)(x) << n) | ((uint32_t)(x) >> (32 - n)))
|
||||
# define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00))
|
||||
#endif
|
||||
|
||||
/* upr(x,n): rotates bytes within words by n positions, moving bytes to
|
||||
higher index positions with wrap around into low positions
|
||||
ups(x,n): moves bytes by n positions to higher index positions in
|
||||
words but without wrap around
|
||||
bval(x,n): extracts a byte from a word
|
||||
|
||||
WARNING: The definitions given here are intended only for use with
|
||||
unsigned variables and with shift counts that are compile
|
||||
time constants
|
||||
*/
|
||||
|
||||
#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN )
|
||||
# define upr(x,n) (((uint32_t)(x) << (8 * (n))) | ((uint32_t)(x) >> (32 - 8 * (n))))
|
||||
# define ups(x,n) ((uint32_t) (x) << (8 * (n)))
|
||||
# define bval(x,n) to_byte((x) >> (8 * (n)))
|
||||
# define bytes2word(b0, b1, b2, b3) \
|
||||
(((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0))
|
||||
#endif
|
||||
|
||||
#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN )
|
||||
# define upr(x,n) (((uint32_t)(x) >> (8 * (n))) | ((uint32_t)(x) << (32 - 8 * (n))))
|
||||
# define ups(x,n) ((uint32_t) (x) >> (8 * (n)))
|
||||
# define bval(x,n) to_byte((x) >> (24 - 8 * (n)))
|
||||
# define bytes2word(b0, b1, b2, b3) \
|
||||
(((uint32_t)(b0) << 24) | ((uint32_t)(b1) << 16) | ((uint32_t)(b2) << 8) | (b3))
|
||||
#endif
|
||||
|
||||
#if defined( SAFE_IO )
|
||||
# define word_in(x,c) bytes2word(((const uint8_t*)(x)+4*c)[0], ((const uint8_t*)(x)+4*c)[1], \
|
||||
((const uint8_t*)(x)+4*c)[2], ((const uint8_t*)(x)+4*c)[3])
|
||||
# define word_out(x,c,v) { ((uint8_t*)(x)+4*c)[0] = bval(v,0); ((uint8_t*)(x)+4*c)[1] = bval(v,1); \
|
||||
((uint8_t*)(x)+4*c)[2] = bval(v,2); ((uint8_t*)(x)+4*c)[3] = bval(v,3); }
|
||||
#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER )
|
||||
# define word_in(x,c) (*((uint32_t*)(x)+(c)))
|
||||
# define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = (v))
|
||||
#else
|
||||
# define word_in(x,c) aes_sw32(*((uint32_t*)(x)+(c)))
|
||||
# define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = aes_sw32(v))
|
||||
#endif
|
||||
|
||||
/* the finite field modular polynomial and elements */
|
||||
|
||||
#define WPOLY 0x011b
|
||||
#define BPOLY 0x1b
|
||||
|
||||
/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
|
||||
|
||||
#define gf_c1 0x80808080
|
||||
#define gf_c2 0x7f7f7f7f
|
||||
#define gf_mulx(x) ((((x) & gf_c2) << 1) ^ ((((x) & gf_c1) >> 7) * BPOLY))
|
||||
|
||||
/* The following defines provide alternative definitions of gf_mulx that might
|
||||
give improved performance if a fast 32-bit multiply is not available. Note
|
||||
that a temporary variable u needs to be defined where gf_mulx is used.
|
||||
|
||||
#define gf_mulx(x) (u = (x) & gf_c1, u |= (u >> 1), ((x) & gf_c2) << 1) ^ ((u >> 3) | (u >> 6))
|
||||
#define gf_c4 (0x01010101 * BPOLY)
|
||||
#define gf_mulx(x) (u = (x) & gf_c1, ((x) & gf_c2) << 1) ^ ((u - (u >> 7)) & gf_c4)
|
||||
*/
|
||||
|
||||
/* Work out which tables are needed for the different options */
|
||||
|
||||
#if defined( ASM_X86_V1C )
|
||||
# if defined( ENC_ROUND )
|
||||
# undef ENC_ROUND
|
||||
# endif
|
||||
# define ENC_ROUND FOUR_TABLES
|
||||
# if defined( LAST_ENC_ROUND )
|
||||
# undef LAST_ENC_ROUND
|
||||
# endif
|
||||
# define LAST_ENC_ROUND FOUR_TABLES
|
||||
# if defined( DEC_ROUND )
|
||||
# undef DEC_ROUND
|
||||
# endif
|
||||
# define DEC_ROUND FOUR_TABLES
|
||||
# if defined( LAST_DEC_ROUND )
|
||||
# undef LAST_DEC_ROUND
|
||||
# endif
|
||||
# define LAST_DEC_ROUND FOUR_TABLES
|
||||
# if defined( KEY_SCHED )
|
||||
# undef KEY_SCHED
|
||||
# define KEY_SCHED FOUR_TABLES
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C )
|
||||
# if ENC_ROUND == ONE_TABLE
|
||||
# define FT1_SET
|
||||
# elif ENC_ROUND == FOUR_TABLES
|
||||
# define FT4_SET
|
||||
# else
|
||||
# define SBX_SET
|
||||
# endif
|
||||
# if LAST_ENC_ROUND == ONE_TABLE
|
||||
# define FL1_SET
|
||||
# elif LAST_ENC_ROUND == FOUR_TABLES
|
||||
# define FL4_SET
|
||||
# elif !defined( SBX_SET )
|
||||
# define SBX_SET
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C )
|
||||
# if DEC_ROUND == ONE_TABLE
|
||||
# define IT1_SET
|
||||
# elif DEC_ROUND == FOUR_TABLES
|
||||
# define IT4_SET
|
||||
# else
|
||||
# define ISB_SET
|
||||
# endif
|
||||
# if LAST_DEC_ROUND == ONE_TABLE
|
||||
# define IL1_SET
|
||||
# elif LAST_DEC_ROUND == FOUR_TABLES
|
||||
# define IL4_SET
|
||||
# elif !defined(ISB_SET)
|
||||
# define ISB_SET
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )))
|
||||
# if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C))
|
||||
# if KEY_SCHED == ONE_TABLE
|
||||
# if !defined( FL1_SET ) && !defined( FL4_SET )
|
||||
# define LS1_SET
|
||||
# endif
|
||||
# elif KEY_SCHED == FOUR_TABLES
|
||||
# if !defined( FL4_SET )
|
||||
# define LS4_SET
|
||||
# endif
|
||||
# elif !defined( SBX_SET )
|
||||
# define SBX_SET
|
||||
# endif
|
||||
# endif
|
||||
# if (FUNCS_IN_C & DEC_KEYING_IN_C)
|
||||
# if KEY_SCHED == ONE_TABLE
|
||||
# define IM1_SET
|
||||
# elif KEY_SCHED == FOUR_TABLES
|
||||
# define IM4_SET
|
||||
# elif !defined( SBX_SET )
|
||||
# define SBX_SET
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* generic definitions of Rijndael macros that use tables */
|
||||
|
||||
#define no_table(x,box,vf,rf,c) bytes2word( \
|
||||
box[bval(vf(x,0,c),rf(0,c))], \
|
||||
box[bval(vf(x,1,c),rf(1,c))], \
|
||||
box[bval(vf(x,2,c),rf(2,c))], \
|
||||
box[bval(vf(x,3,c),rf(3,c))])
|
||||
|
||||
#define one_table(x,op,tab,vf,rf,c) \
|
||||
( tab[bval(vf(x,0,c),rf(0,c))] \
|
||||
^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
|
||||
^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
|
||||
^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
|
||||
|
||||
#define four_tables(x,tab,vf,rf,c) \
|
||||
( tab[0][bval(vf(x,0,c),rf(0,c))] \
|
||||
^ tab[1][bval(vf(x,1,c),rf(1,c))] \
|
||||
^ tab[2][bval(vf(x,2,c),rf(2,c))] \
|
||||
^ tab[3][bval(vf(x,3,c),rf(3,c))])
|
||||
|
||||
#define vf1(x,r,c) (x)
|
||||
#define rf1(r,c) (r)
|
||||
#define rf2(r,c) ((8+r-c)&3)
|
||||
|
||||
/* perform forward and inverse column mix operation on four bytes in long word x in */
|
||||
/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */
|
||||
|
||||
#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )))
|
||||
|
||||
#if defined( FM4_SET ) /* not currently used */
|
||||
# define fwd_mcol(x) four_tables(x,t_use(f,m),vf1,rf1,0)
|
||||
#elif defined( FM1_SET ) /* not currently used */
|
||||
# define fwd_mcol(x) one_table(x,upr,t_use(f,m),vf1,rf1,0)
|
||||
#else
|
||||
# define dec_fmvars uint32_t g2
|
||||
# define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1))
|
||||
#endif
|
||||
|
||||
#if defined( IM4_SET )
|
||||
# define inv_mcol(x) four_tables(x,t_use(i,m),vf1,rf1,0)
|
||||
#elif defined( IM1_SET )
|
||||
# define inv_mcol(x) one_table(x,upr,t_use(i,m),vf1,rf1,0)
|
||||
#else
|
||||
# define dec_imvars uint32_t g2, g4, g9
|
||||
# define inv_mcol(x) (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \
|
||||
(x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1))
|
||||
#endif
|
||||
|
||||
#if defined( FL4_SET )
|
||||
# define ls_box(x,c) four_tables(x,t_use(f,l),vf1,rf2,c)
|
||||
#elif defined( LS4_SET )
|
||||
# define ls_box(x,c) four_tables(x,t_use(l,s),vf1,rf2,c)
|
||||
#elif defined( FL1_SET )
|
||||
# define ls_box(x,c) one_table(x,upr,t_use(f,l),vf1,rf2,c)
|
||||
#elif defined( LS1_SET )
|
||||
# define ls_box(x,c) one_table(x,upr,t_use(l,s),vf1,rf2,c)
|
||||
#else
|
||||
# define ls_box(x,c) no_table(x,t_use(s,box),vf1,rf2,c)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET )
|
||||
# define ISB_SET
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Executable
+418
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#define DO_TABLES
|
||||
|
||||
#include "aes.h"
|
||||
#include "aesopt.h"
|
||||
|
||||
#if defined(STATIC_TABLES)
|
||||
|
||||
#define sb_data(w) {\
|
||||
w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
|
||||
w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
|
||||
w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
|
||||
w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
|
||||
w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
|
||||
w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
|
||||
w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
|
||||
w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
|
||||
w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
|
||||
w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
|
||||
w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
|
||||
w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
|
||||
w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
|
||||
w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
|
||||
w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
|
||||
w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
|
||||
w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
|
||||
w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
|
||||
w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
|
||||
w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
|
||||
w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
|
||||
w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
|
||||
w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
|
||||
w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
|
||||
w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
|
||||
w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
|
||||
w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
|
||||
w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
|
||||
w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
|
||||
w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
|
||||
w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
|
||||
w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
|
||||
|
||||
#define isb_data(w) {\
|
||||
w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
|
||||
w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
|
||||
w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
|
||||
w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
|
||||
w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
|
||||
w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
|
||||
w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
|
||||
w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
|
||||
w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
|
||||
w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
|
||||
w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
|
||||
w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
|
||||
w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
|
||||
w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
|
||||
w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
|
||||
w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
|
||||
w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
|
||||
w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
|
||||
w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
|
||||
w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
|
||||
w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
|
||||
w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
|
||||
w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
|
||||
w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
|
||||
w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
|
||||
w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
|
||||
w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
|
||||
w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
|
||||
w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
|
||||
w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
|
||||
w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
|
||||
w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) }
|
||||
|
||||
#define mm_data(w) {\
|
||||
w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
|
||||
w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
|
||||
w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
|
||||
w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
|
||||
w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
|
||||
w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
|
||||
w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
|
||||
w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
|
||||
w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
|
||||
w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
|
||||
w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
|
||||
w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
|
||||
w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
|
||||
w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
|
||||
w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
|
||||
w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
|
||||
w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
|
||||
w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
|
||||
w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
|
||||
w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
|
||||
w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
|
||||
w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
|
||||
w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
|
||||
w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
|
||||
w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
|
||||
w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
|
||||
w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
|
||||
w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
|
||||
w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
|
||||
w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
|
||||
w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
|
||||
w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) }
|
||||
|
||||
#define rc_data(w) {\
|
||||
w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\
|
||||
w(0x1b), w(0x36) }
|
||||
|
||||
#define h0(x) (x)
|
||||
|
||||
#define w0(p) bytes2word(p, 0, 0, 0)
|
||||
#define w1(p) bytes2word(0, p, 0, 0)
|
||||
#define w2(p) bytes2word(0, 0, p, 0)
|
||||
#define w3(p) bytes2word(0, 0, 0, p)
|
||||
|
||||
#define u0(p) bytes2word(f2(p), p, p, f3(p))
|
||||
#define u1(p) bytes2word(f3(p), f2(p), p, p)
|
||||
#define u2(p) bytes2word(p, f3(p), f2(p), p)
|
||||
#define u3(p) bytes2word(p, p, f3(p), f2(p))
|
||||
|
||||
#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p))
|
||||
#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p))
|
||||
#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p))
|
||||
#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p))
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(STATIC_TABLES) || !defined(FF_TABLES)
|
||||
|
||||
#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
|
||||
#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
|
||||
#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
|
||||
^ (((x>>5) & 4) * WPOLY))
|
||||
#define f3(x) (f2(x) ^ x)
|
||||
#define f9(x) (f8(x) ^ x)
|
||||
#define fb(x) (f8(x) ^ f2(x) ^ x)
|
||||
#define fd(x) (f8(x) ^ f4(x) ^ x)
|
||||
#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
|
||||
|
||||
#else
|
||||
|
||||
#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
|
||||
#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
|
||||
#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
|
||||
#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
|
||||
#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
|
||||
#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
|
||||
|
||||
#endif
|
||||
|
||||
#include "aestab.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if defined(STATIC_TABLES)
|
||||
|
||||
/* implemented in case of wrong call for fixed tables */
|
||||
|
||||
AES_RETURN aes_init(void)
|
||||
{
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#else /* Generate the tables for the dynamic table option */
|
||||
|
||||
#if defined(FF_TABLES)
|
||||
|
||||
#define gf_inv(x) ((x) ? pow[ 255 - log[x]] : 0)
|
||||
|
||||
#else
|
||||
|
||||
/* It will generally be sensible to use tables to compute finite
|
||||
field multiplies and inverses but where memory is scarse this
|
||||
code might sometimes be better. But it only has effect during
|
||||
initialisation so its pretty unimportant in overall terms.
|
||||
*/
|
||||
|
||||
/* return 2 ^ (n - 1) where n is the bit number of the highest bit
|
||||
set in x with x in the range 1 < x < 0x00000200. This form is
|
||||
used so that locals within fi can be bytes rather than words
|
||||
*/
|
||||
|
||||
static uint8_t hibit(const uint32_t x)
|
||||
{ uint8_t r = (uint8_t)((x >> 1) | (x >> 2));
|
||||
|
||||
r |= (r >> 2);
|
||||
r |= (r >> 4);
|
||||
return (r + 1) >> 1;
|
||||
}
|
||||
|
||||
/* return the inverse of the finite field element x */
|
||||
|
||||
static uint8_t gf_inv(const uint8_t x)
|
||||
{ uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
|
||||
|
||||
if(x < 2)
|
||||
return x;
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
if(n1)
|
||||
while(n2 >= n1) /* divide polynomial p2 by p1 */
|
||||
{
|
||||
n2 /= n1; /* shift smaller polynomial left */
|
||||
p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */
|
||||
v2 ^= v1 * n2; /* shift accumulated value and */
|
||||
n2 = hibit(p2); /* add into result */
|
||||
}
|
||||
else
|
||||
return v1;
|
||||
|
||||
if(n2) /* repeat with values swapped */
|
||||
while(n1 >= n2)
|
||||
{
|
||||
n1 /= n2;
|
||||
p1 ^= p2 * n1;
|
||||
v1 ^= v2 * n1;
|
||||
n1 = hibit(p1);
|
||||
}
|
||||
else
|
||||
return v2;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* The forward and inverse affine transformations used in the S-box */
|
||||
uint8_t fwd_affine(const uint8_t x)
|
||||
{ uint32_t w = x;
|
||||
w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
|
||||
return 0x63 ^ ((w ^ (w >> 8)) & 0xff);
|
||||
}
|
||||
|
||||
uint8_t inv_affine(const uint8_t x)
|
||||
{ uint32_t w = x;
|
||||
w = (w << 1) ^ (w << 3) ^ (w << 6);
|
||||
return 0x05 ^ ((w ^ (w >> 8)) & 0xff);
|
||||
}
|
||||
|
||||
static int init = 0;
|
||||
|
||||
AES_RETURN aes_init(void)
|
||||
{ uint32_t i, w;
|
||||
|
||||
#if defined(FF_TABLES)
|
||||
|
||||
uint8_t pow[512], log[256];
|
||||
|
||||
if(init)
|
||||
return EXIT_SUCCESS;
|
||||
/* log and power tables for GF(2^8) finite field with
|
||||
WPOLY as modular polynomial - the simplest primitive
|
||||
root is 0x03, used here to generate the tables
|
||||
*/
|
||||
|
||||
i = 0; w = 1;
|
||||
do
|
||||
{
|
||||
pow[i] = (uint8_t)w;
|
||||
pow[i + 255] = (uint8_t)w;
|
||||
log[w] = (uint8_t)i++;
|
||||
w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0);
|
||||
}
|
||||
while (w != 1);
|
||||
|
||||
#else
|
||||
if(init)
|
||||
return EXIT_SUCCESS;
|
||||
#endif
|
||||
|
||||
for(i = 0, w = 1; i < RC_LENGTH; ++i)
|
||||
{
|
||||
t_set(r,c)[i] = bytes2word(w, 0, 0, 0);
|
||||
w = f2(w);
|
||||
}
|
||||
|
||||
for(i = 0; i < 256; ++i)
|
||||
{ uint8_t b;
|
||||
|
||||
b = fwd_affine(gf_inv((uint8_t)i));
|
||||
w = bytes2word(f2(b), b, b, f3(b));
|
||||
|
||||
#if defined( SBX_SET )
|
||||
t_set(s,box)[i] = b;
|
||||
#endif
|
||||
|
||||
#if defined( FT1_SET ) /* tables for a normal encryption round */
|
||||
t_set(f,n)[i] = w;
|
||||
#endif
|
||||
#if defined( FT4_SET )
|
||||
t_set(f,n)[0][i] = w;
|
||||
t_set(f,n)[1][i] = upr(w,1);
|
||||
t_set(f,n)[2][i] = upr(w,2);
|
||||
t_set(f,n)[3][i] = upr(w,3);
|
||||
#endif
|
||||
w = bytes2word(b, 0, 0, 0);
|
||||
|
||||
#if defined( FL1_SET ) /* tables for last encryption round (may also */
|
||||
t_set(f,l)[i] = w; /* be used in the key schedule) */
|
||||
#endif
|
||||
#if defined( FL4_SET )
|
||||
t_set(f,l)[0][i] = w;
|
||||
t_set(f,l)[1][i] = upr(w,1);
|
||||
t_set(f,l)[2][i] = upr(w,2);
|
||||
t_set(f,l)[3][i] = upr(w,3);
|
||||
#endif
|
||||
|
||||
#if defined( LS1_SET ) /* table for key schedule if t_set(f,l) above is*/
|
||||
t_set(l,s)[i] = w; /* not of the required form */
|
||||
#endif
|
||||
#if defined( LS4_SET )
|
||||
t_set(l,s)[0][i] = w;
|
||||
t_set(l,s)[1][i] = upr(w,1);
|
||||
t_set(l,s)[2][i] = upr(w,2);
|
||||
t_set(l,s)[3][i] = upr(w,3);
|
||||
#endif
|
||||
|
||||
b = gf_inv(inv_affine((uint8_t)i));
|
||||
w = bytes2word(fe(b), f9(b), fd(b), fb(b));
|
||||
|
||||
#if defined( IM1_SET ) /* tables for the inverse mix column operation */
|
||||
t_set(i,m)[b] = w;
|
||||
#endif
|
||||
#if defined( IM4_SET )
|
||||
t_set(i,m)[0][b] = w;
|
||||
t_set(i,m)[1][b] = upr(w,1);
|
||||
t_set(i,m)[2][b] = upr(w,2);
|
||||
t_set(i,m)[3][b] = upr(w,3);
|
||||
#endif
|
||||
|
||||
#if defined( ISB_SET )
|
||||
t_set(i,box)[i] = b;
|
||||
#endif
|
||||
#if defined( IT1_SET ) /* tables for a normal decryption round */
|
||||
t_set(i,n)[i] = w;
|
||||
#endif
|
||||
#if defined( IT4_SET )
|
||||
t_set(i,n)[0][i] = w;
|
||||
t_set(i,n)[1][i] = upr(w,1);
|
||||
t_set(i,n)[2][i] = upr(w,2);
|
||||
t_set(i,n)[3][i] = upr(w,3);
|
||||
#endif
|
||||
w = bytes2word(b, 0, 0, 0);
|
||||
#if defined( IL1_SET ) /* tables for last decryption round */
|
||||
t_set(i,l)[i] = w;
|
||||
#endif
|
||||
#if defined( IL4_SET )
|
||||
t_set(i,l)[0][i] = w;
|
||||
t_set(i,l)[1][i] = upr(w,1);
|
||||
t_set(i,l)[2][i] = upr(w,2);
|
||||
t_set(i,l)[3][i] = upr(w,3);
|
||||
#endif
|
||||
}
|
||||
init = 1;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
Automatic code initialisation (suggested by by Henrik S. Gaßmann)
|
||||
based on code provided by Joe Lowe and placed in the public domain at:
|
||||
http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#pragma section(".CRT$XCU", read)
|
||||
|
||||
__declspec(allocate(".CRT$XCU")) void (__cdecl *aes_startup)(void) = aes_init;
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
static void aes_startup(void) __attribute__((constructor));
|
||||
|
||||
static void aes_startup(void)
|
||||
{
|
||||
aes_init();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#pragma message( "dynamic tables must be initialised manually on your system" )
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
Executable
+173
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This file contains the code for declaring the tables needed to implement
|
||||
AES. The file aesopt.h is assumed to be included before this header file.
|
||||
If there are no global variables, the definitions here can be used to put
|
||||
the AES tables in a structure so that a pointer can then be added to the
|
||||
AES context to pass them to the AES routines that need them. If this
|
||||
facility is used, the calling program has to ensure that this pointer is
|
||||
managed appropriately. In particular, the value of the t_dec(in,it) item
|
||||
in the table structure must be set to zero in order to ensure that the
|
||||
tables are initialised. In practice the three code sequences in aeskey.c
|
||||
that control the calls to aes_init() and the aes_init() routine itself will
|
||||
have to be changed for a specific implementation. If global variables are
|
||||
available it will generally be preferable to use them with the precomputed
|
||||
STATIC_TABLES option that uses static global tables.
|
||||
|
||||
The following defines can be used to control the way the tables
|
||||
are defined, initialised and used in embedded environments that
|
||||
require special features for these purposes
|
||||
|
||||
the 't_dec' construction is used to declare fixed table arrays
|
||||
the 't_set' construction is used to set fixed table values
|
||||
the 't_use' construction is used to access fixed table values
|
||||
|
||||
256 byte tables:
|
||||
|
||||
t_xxx(s,box) => forward S box
|
||||
t_xxx(i,box) => inverse S box
|
||||
|
||||
256 32-bit word OR 4 x 256 32-bit word tables:
|
||||
|
||||
t_xxx(f,n) => forward normal round
|
||||
t_xxx(f,l) => forward last round
|
||||
t_xxx(i,n) => inverse normal round
|
||||
t_xxx(i,l) => inverse last round
|
||||
t_xxx(l,s) => key schedule table
|
||||
t_xxx(i,m) => key schedule table
|
||||
|
||||
Other variables and tables:
|
||||
|
||||
t_xxx(r,c) => the rcon table
|
||||
*/
|
||||
|
||||
#if !defined( _AESTAB_H )
|
||||
#define _AESTAB_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define t_dec(m,n) t_##m##n
|
||||
#define t_set(m,n) t_##m##n
|
||||
#define t_use(m,n) t_##m##n
|
||||
|
||||
#if defined(STATIC_TABLES)
|
||||
# if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ ))
|
||||
/* make tables far data to avoid using too much DGROUP space (PG) */
|
||||
# define CONST const far
|
||||
# else
|
||||
# define CONST const
|
||||
# endif
|
||||
#else
|
||||
# define CONST
|
||||
#endif
|
||||
|
||||
#if defined(DO_TABLES)
|
||||
# define EXTERN
|
||||
#else
|
||||
# define EXTERN extern
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && defined(TABLE_ALIGN)
|
||||
#define ALIGN __declspec(align(TABLE_ALIGN))
|
||||
#else
|
||||
#define ALIGN
|
||||
#endif
|
||||
|
||||
#if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
|
||||
# define XP_DIR __cdecl
|
||||
#else
|
||||
# define XP_DIR
|
||||
#endif
|
||||
|
||||
#if defined(DO_TABLES) && defined(STATIC_TABLES)
|
||||
#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] = b(e)
|
||||
#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) }
|
||||
EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
|
||||
#else
|
||||
#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256]
|
||||
#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256]
|
||||
EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH];
|
||||
#endif
|
||||
|
||||
#if defined( SBX_SET )
|
||||
d_1(uint8_t, t_dec(s,box), sb_data, h0);
|
||||
#endif
|
||||
#if defined( ISB_SET )
|
||||
d_1(uint8_t, t_dec(i,box), isb_data, h0);
|
||||
#endif
|
||||
|
||||
#if defined( FT1_SET )
|
||||
d_1(uint32_t, t_dec(f,n), sb_data, u0);
|
||||
#endif
|
||||
#if defined( FT4_SET )
|
||||
d_4(uint32_t, t_dec(f,n), sb_data, u0, u1, u2, u3);
|
||||
#endif
|
||||
|
||||
#if defined( FL1_SET )
|
||||
d_1(uint32_t, t_dec(f,l), sb_data, w0);
|
||||
#endif
|
||||
#if defined( FL4_SET )
|
||||
d_4(uint32_t, t_dec(f,l), sb_data, w0, w1, w2, w3);
|
||||
#endif
|
||||
|
||||
#if defined( IT1_SET )
|
||||
d_1(uint32_t, t_dec(i,n), isb_data, v0);
|
||||
#endif
|
||||
#if defined( IT4_SET )
|
||||
d_4(uint32_t, t_dec(i,n), isb_data, v0, v1, v2, v3);
|
||||
#endif
|
||||
|
||||
#if defined( IL1_SET )
|
||||
d_1(uint32_t, t_dec(i,l), isb_data, w0);
|
||||
#endif
|
||||
#if defined( IL4_SET )
|
||||
d_4(uint32_t, t_dec(i,l), isb_data, w0, w1, w2, w3);
|
||||
#endif
|
||||
|
||||
#if defined( LS1_SET )
|
||||
#if defined( FL1_SET )
|
||||
#undef LS1_SET
|
||||
#else
|
||||
d_1(uint32_t, t_dec(l,s), sb_data, w0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined( LS4_SET )
|
||||
#if defined( FL4_SET )
|
||||
#undef LS4_SET
|
||||
#else
|
||||
d_4(uint32_t, t_dec(l,s), sb_data, w0, w1, w2, w3);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined( IM1_SET )
|
||||
d_1(uint32_t, t_dec(i,m), mm_data, v0);
|
||||
#endif
|
||||
#if defined( IM4_SET )
|
||||
d_4(uint32_t, t_dec(i,m), mm_data, v0, v1, v2, v3);
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#ifndef _BRG_ENDIAN_H
|
||||
#define _BRG_ENDIAN_H
|
||||
|
||||
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
|
||||
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
|
||||
|
||||
/* Include files where endian defines and byteswap functions may reside */
|
||||
#if defined( __sun )
|
||||
# include <sys/isa_defs.h>
|
||||
#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
|
||||
# include <sys/endian.h>
|
||||
#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
|
||||
defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) || \
|
||||
defined(__pnacl__)
|
||||
# include <machine/endian.h>
|
||||
#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
|
||||
# if !defined( __MINGW32__ ) && !defined( _AIX )
|
||||
# include <endian.h>
|
||||
# if !defined( __BEOS__ )
|
||||
# include <byteswap.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Now attempt to set the define for platform byte order using any */
|
||||
/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */
|
||||
/* seem to encompass most endian symbol definitions */
|
||||
|
||||
#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )
|
||||
# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( BIG_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( LITTLE_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )
|
||||
# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( _BIG_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( _LITTLE_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )
|
||||
# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( __BIG_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( __LITTLE_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )
|
||||
# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( __BIG_ENDIAN__ )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( __LITTLE_ENDIAN__ )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
/* if the platform byte order could not be determined, then try to */
|
||||
/* set this define using common machine defines */
|
||||
#if !defined(PLATFORM_BYTE_ORDER)
|
||||
|
||||
#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \
|
||||
defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
|
||||
defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
|
||||
defined( vax ) || defined( vms ) || defined( VMS ) || \
|
||||
defined( __VMS ) || defined( _M_X64 )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
|
||||
#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \
|
||||
defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \
|
||||
defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \
|
||||
defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
|
||||
defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
|
||||
defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \
|
||||
defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
|
||||
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#else
|
||||
# error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
The unsigned integer types defined here are of the form uint_<nn>t where
|
||||
<nn> is the length of the type; for example, the unsigned 32-bit type is
|
||||
'uint32_t'. These are NOT the same as the 'C99 integer types' that are
|
||||
defined in the inttypes.h and stdint.h headers since attempts to use these
|
||||
types have shown that support for them is still highly variable. However,
|
||||
since the latter are of the form uint<nn>_t, a regular expression search
|
||||
and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t')
|
||||
can be used to convert the types used here to the C99 standard types.
|
||||
*/
|
||||
|
||||
#ifndef _BRG_TYPES_H
|
||||
#define _BRG_TYPES_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
|
||||
# include <stddef.h>
|
||||
# define ptrint_t intptr_t
|
||||
#elif defined( __ECOS__ )
|
||||
# define intptr_t unsigned int
|
||||
# define ptrint_t intptr_t
|
||||
#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 )
|
||||
# define ptrint_t intptr_t
|
||||
#else
|
||||
# define ptrint_t int
|
||||
#endif
|
||||
|
||||
#ifndef BRG_UI32
|
||||
# define BRG_UI32
|
||||
# if UINT_MAX == 4294967295u
|
||||
# define li_32(h) 0x##h##u
|
||||
# elif ULONG_MAX == 4294967295u
|
||||
# define li_32(h) 0x##h##ul
|
||||
# elif defined( _CRAY )
|
||||
# error This code needs 32-bit data types, which Cray machines do not provide
|
||||
# else
|
||||
# error Please define uint32_t as a 32-bit unsigned integer type in brg_types.h
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef BRG_UI64
|
||||
# if defined( __BORLANDC__ ) && !defined( __MSDOS__ )
|
||||
# define BRG_UI64
|
||||
# define li_64(h) 0x##h##ui64
|
||||
# elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */
|
||||
# define BRG_UI64
|
||||
# define li_64(h) 0x##h##ui64
|
||||
# elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful
|
||||
# define BRG_UI64
|
||||
# define li_64(h) 0x##h##ull
|
||||
# elif defined( __MVS__ )
|
||||
# define BRG_UI64
|
||||
# define li_64(h) 0x##h##ull
|
||||
# elif defined( UINT_MAX ) && UINT_MAX > 4294967295u
|
||||
# if UINT_MAX == 18446744073709551615u
|
||||
# define BRG_UI64
|
||||
# define li_64(h) 0x##h##u
|
||||
# endif
|
||||
# elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u
|
||||
# if ULONG_MAX == 18446744073709551615ul
|
||||
# define BRG_UI64
|
||||
# define li_64(h) 0x##h##ul
|
||||
# endif
|
||||
# elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u
|
||||
# if ULLONG_MAX == 18446744073709551615ull
|
||||
# define BRG_UI64
|
||||
# define li_64(h) 0x##h##ull
|
||||
# endif
|
||||
# elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u
|
||||
# if ULONG_LONG_MAX == 18446744073709551615ull
|
||||
# define BRG_UI64
|
||||
# define li_64(h) 0x##h##ull
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined( BRG_UI64 )
|
||||
# if defined( NEED_UINT_64T )
|
||||
# error Please define uint64_t as an unsigned 64 bit type in brg_types.h
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef RETURN_VALUES
|
||||
# define RETURN_VALUES
|
||||
# if defined( DLL_EXPORT )
|
||||
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
|
||||
# define VOID_RETURN __declspec( dllexport ) void __stdcall
|
||||
# define INT_RETURN __declspec( dllexport ) int __stdcall
|
||||
# elif defined( __GNUC__ )
|
||||
# define VOID_RETURN __declspec( __dllexport__ ) void
|
||||
# define INT_RETURN __declspec( __dllexport__ ) int
|
||||
# else
|
||||
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
|
||||
# endif
|
||||
# elif defined( DLL_IMPORT )
|
||||
# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
|
||||
# define VOID_RETURN __declspec( dllimport ) void __stdcall
|
||||
# define INT_RETURN __declspec( dllimport ) int __stdcall
|
||||
# elif defined( __GNUC__ )
|
||||
# define VOID_RETURN __declspec( __dllimport__ ) void
|
||||
# define INT_RETURN __declspec( __dllimport__ ) int
|
||||
# else
|
||||
# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
|
||||
# endif
|
||||
# elif defined( __WATCOMC__ )
|
||||
# define VOID_RETURN void __cdecl
|
||||
# define INT_RETURN int __cdecl
|
||||
# else
|
||||
# define VOID_RETURN void
|
||||
# define INT_RETURN int
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* These defines are used to detect and set the memory alignment of pointers.
|
||||
Note that offsets are in bytes.
|
||||
|
||||
ALIGN_OFFSET(x,n) return the positive or zero offset of
|
||||
the memory addressed by the pointer 'x'
|
||||
from an address that is aligned on an
|
||||
'n' byte boundary ('n' is a power of 2)
|
||||
|
||||
ALIGN_FLOOR(x,n) return a pointer that points to memory
|
||||
that is aligned on an 'n' byte boundary
|
||||
and is not higher than the memory address
|
||||
pointed to by 'x' ('n' is a power of 2)
|
||||
|
||||
ALIGN_CEIL(x,n) return a pointer that points to memory
|
||||
that is aligned on an 'n' byte boundary
|
||||
and is not lower than the memory address
|
||||
pointed to by 'x' ('n' is a power of 2)
|
||||
*/
|
||||
|
||||
#define ALIGN_OFFSET(x,n) (((ptrint_t)(x)) & ((n) - 1))
|
||||
#define ALIGN_FLOOR(x,n) ((uint8_t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1)))
|
||||
#define ALIGN_CEIL(x,n) ((uint8_t*)(x) + (-((ptrint_t)(x)) & ((n) - 1)))
|
||||
|
||||
/* These defines are used to declare buffers in a way that allows
|
||||
faster operations on longer variables to be used. In all these
|
||||
defines 'size' must be a power of 2 and >= 8. NOTE that the
|
||||
buffer size is in bytes but the type length is in bits
|
||||
|
||||
UNIT_TYPEDEF(x,size) declares a variable 'x' of length
|
||||
'size' bits
|
||||
|
||||
BUFR_TYPEDEF(x,size,bsize) declares a buffer 'x' of length 'bsize'
|
||||
bytes defined as an array of variables
|
||||
each of 'size' bits (bsize must be a
|
||||
multiple of size / 8)
|
||||
|
||||
UNIT_CAST(x,size) casts a variable to a type of
|
||||
length 'size' bits
|
||||
|
||||
UPTR_CAST(x,size) casts a pointer to a pointer to a
|
||||
varaiable of length 'size' bits
|
||||
*/
|
||||
|
||||
#define UI_TYPE(size) uint##size##_t
|
||||
#define UNIT_TYPEDEF(x,size) typedef UI_TYPE(size) x
|
||||
#define BUFR_TYPEDEF(x,size,bsize) typedef UI_TYPE(size) x[bsize / (size >> 3)]
|
||||
#define UNIT_CAST(x,size) ((UI_TYPE(size) )(x))
|
||||
#define UPTR_CAST(x,size) ((UI_TYPE(size)*)(x))
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Executable
+209
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This is an implementation of HMAC, the FIPS standard keyed hash function
|
||||
*/
|
||||
|
||||
#include "hmac.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* initialise the HMAC context to zero */
|
||||
int hmac_sha_begin(enum hmac_hash hash, hmac_ctx cx[1])
|
||||
{
|
||||
memset(cx, 0, sizeof(hmac_ctx));
|
||||
switch(hash)
|
||||
{
|
||||
#ifdef SHA_1
|
||||
case HMAC_SHA1:
|
||||
cx->f_begin = (hf_begin *)sha1_begin;
|
||||
cx->f_hash = (hf_hash *)sha1_hash;
|
||||
cx->f_end = (hf_end *)sha1_end;
|
||||
cx->input_len = SHA1_BLOCK_SIZE;
|
||||
cx->output_len = SHA1_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SHA_224
|
||||
case HMAC_SHA224:
|
||||
cx->f_begin = (hf_begin *)sha224_begin;
|
||||
cx->f_hash = (hf_hash *)sha224_hash;
|
||||
cx->f_end = (hf_end *)sha224_end;
|
||||
cx->input_len = SHA224_BLOCK_SIZE;
|
||||
cx->output_len = SHA224_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SHA_256
|
||||
case HMAC_SHA256:
|
||||
cx->f_begin = (hf_begin *)sha256_begin;
|
||||
cx->f_hash = (hf_hash *)sha256_hash;
|
||||
cx->f_end = (hf_end *)sha256_end;
|
||||
cx->input_len = SHA256_BLOCK_SIZE;
|
||||
cx->output_len = SHA256_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SHA_384
|
||||
case HMAC_SHA384:
|
||||
cx->f_begin = (hf_begin *)sha384_begin;
|
||||
cx->f_hash = (hf_hash *)sha384_hash;
|
||||
cx->f_end = (hf_end *)sha384_end;
|
||||
cx->input_len = SHA384_BLOCK_SIZE;
|
||||
cx->output_len = SHA384_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef SHA_512
|
||||
case HMAC_SHA512:
|
||||
cx->f_begin = (hf_begin *)sha512_begin;
|
||||
cx->f_hash = (hf_hash *)sha512_hash;
|
||||
cx->f_end = (hf_end *)sha512_end;
|
||||
cx->input_len = SHA512_BLOCK_SIZE;
|
||||
cx->output_len = SHA512_DIGEST_SIZE;
|
||||
break;
|
||||
case HMAC_SHA512_256:
|
||||
cx->f_begin = (hf_begin *)sha512_256_begin;
|
||||
cx->f_hash = (hf_hash *)sha512_256_hash;
|
||||
cx->f_end = (hf_end *)sha512_256_end;
|
||||
cx->input_len = SHA512_256_BLOCK_SIZE;
|
||||
cx->output_len = SHA512_256_DIGEST_SIZE;
|
||||
break;
|
||||
case HMAC_SHA512_224:
|
||||
cx->f_begin = (hf_begin *)sha512_224_begin;
|
||||
cx->f_hash = (hf_hash *)sha512_224_hash;
|
||||
cx->f_end = (hf_end *)sha512_224_end;
|
||||
cx->input_len = SHA512_224_BLOCK_SIZE;
|
||||
cx->output_len = SHA512_224_DIGEST_SIZE;
|
||||
break;
|
||||
case HMAC_SHA512_192:
|
||||
cx->f_begin = (hf_begin *)sha512_192_begin;
|
||||
cx->f_hash = (hf_hash *)sha512_192_hash;
|
||||
cx->f_end = (hf_end *)sha512_192_end;
|
||||
cx->input_len = SHA512_192_BLOCK_SIZE;
|
||||
cx->output_len = SHA512_192_DIGEST_SIZE;
|
||||
break;
|
||||
case HMAC_SHA512_128:
|
||||
cx->f_begin = (hf_begin *)sha512_128_begin;
|
||||
cx->f_hash = (hf_hash *)sha512_128_hash;
|
||||
cx->f_end = (hf_begin *)sha512_128_end;
|
||||
cx->input_len = SHA512_128_BLOCK_SIZE;
|
||||
cx->output_len = SHA512_128_DIGEST_SIZE;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
return (int)cx->output_len;
|
||||
}
|
||||
|
||||
/* input the HMAC key (can be called multiple times) */
|
||||
int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1])
|
||||
{
|
||||
if(cx->klen == HMAC_IN_DATA) /* error if further key input */
|
||||
return EXIT_FAILURE; /* is attempted in data mode */
|
||||
|
||||
if(cx->klen + key_len > cx->input_len) /* if the key has to be hashed */
|
||||
{
|
||||
if(cx->klen <= cx->input_len) /* if the hash has not yet been */
|
||||
{ /* started, initialise it and */
|
||||
cx->f_begin(cx->sha_ctx); /* hash stored key characters */
|
||||
cx->f_hash(cx->key, cx->klen, cx->sha_ctx);
|
||||
}
|
||||
|
||||
cx->f_hash(key, key_len, cx->sha_ctx); /* hash long key data into hash */
|
||||
}
|
||||
else /* otherwise store key data */
|
||||
memcpy(cx->key + cx->klen, key, key_len);
|
||||
|
||||
cx->klen += key_len; /* update the key length count */
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* input the HMAC data (can be called multiple times) - */
|
||||
/* note that this call terminates the key input phase */
|
||||
void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1])
|
||||
{ unsigned int i;
|
||||
|
||||
if(cx->klen != HMAC_IN_DATA) /* if not yet in data phase */
|
||||
{
|
||||
if(cx->klen > cx->input_len) /* if key is being hashed */
|
||||
{ /* complete the hash and */
|
||||
cx->f_end(cx->key, cx->sha_ctx); /* store the result as the */
|
||||
cx->klen = cx->output_len; /* key and set new length */
|
||||
}
|
||||
|
||||
/* pad the key if necessary */
|
||||
memset(cx->key + cx->klen, 0, cx->input_len - cx->klen);
|
||||
|
||||
/* xor ipad into key value */
|
||||
for(i = 0; i < (cx->input_len >> 2); ++i)
|
||||
((uint32_t*)cx->key)[i] ^= 0x36363636;
|
||||
|
||||
/* and start hash operation */
|
||||
cx->f_begin(cx->sha_ctx);
|
||||
cx->f_hash(cx->key, cx->input_len, cx->sha_ctx);
|
||||
|
||||
/* mark as now in data mode */
|
||||
cx->klen = HMAC_IN_DATA;
|
||||
}
|
||||
|
||||
/* hash the data (if any) */
|
||||
if(data_len)
|
||||
cx->f_hash(data, data_len, cx->sha_ctx);
|
||||
}
|
||||
|
||||
/* compute and output the MAC value */
|
||||
void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1])
|
||||
{ unsigned char dig[HMAC_MAX_OUTPUT_SIZE];
|
||||
unsigned int i;
|
||||
|
||||
/* if no data has been entered perform a null data phase */
|
||||
if(cx->klen != HMAC_IN_DATA)
|
||||
hmac_sha_data((const unsigned char*)0, 0, cx);
|
||||
|
||||
cx->f_end(dig, cx->sha_ctx); /* complete the inner hash */
|
||||
|
||||
/* set outer key value using opad and removing ipad */
|
||||
for(i = 0; i < (cx->input_len >> 2); ++i)
|
||||
((uint32_t*)cx->key)[i] ^= 0x36363636 ^ 0x5c5c5c5c;
|
||||
|
||||
/* perform the outer hash operation */
|
||||
cx->f_begin(cx->sha_ctx);
|
||||
cx->f_hash(cx->key, cx->input_len, cx->sha_ctx);
|
||||
cx->f_hash(dig, cx->output_len, cx->sha_ctx);
|
||||
cx->f_end(dig, cx->sha_ctx);
|
||||
|
||||
/* output the hash value */
|
||||
for(i = 0; i < mac_len; ++i)
|
||||
mac[i] = dig[i];
|
||||
}
|
||||
|
||||
/* 'do it all in one go' subroutine */
|
||||
void hmac_sha(enum hmac_hash hash, const unsigned char key[], unsigned long key_len,
|
||||
const unsigned char data[], unsigned long data_len,
|
||||
unsigned char mac[], unsigned long mac_len)
|
||||
{ hmac_ctx cx[1];
|
||||
|
||||
hmac_sha_begin(hash, cx);
|
||||
hmac_sha_key(key, key_len, cx);
|
||||
hmac_sha_data(data, data_len, cx);
|
||||
hmac_sha_end(mac, mac_len, cx);
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
Executable
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This is an implementation of HMAC, the FIPS standard keyed hash function
|
||||
*/
|
||||
|
||||
#ifndef _HMAC2_H
|
||||
#define _HMAC2_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
#if defined(SHA_224) || defined(SHA_256) || defined(SHA_384) || defined(SHA_512)
|
||||
#define HMAC_MAX_OUTPUT_SIZE SHA2_MAX_DIGEST_SIZE
|
||||
#define HMAC_MAX_BLOCK_SIZE SHA2_MAX_BLOCK_SIZE
|
||||
#else
|
||||
#define HMAC_MAX_OUTPUT_SIZE SHA1_DIGEST_SIZE
|
||||
#define HMAC_MAX_BLOCK_SIZE SHA1_BLOCK_SIZE
|
||||
#endif
|
||||
|
||||
#define HMAC_IN_DATA 0xffffffff
|
||||
|
||||
enum hmac_hash
|
||||
{
|
||||
#ifdef SHA_1
|
||||
HMAC_SHA1,
|
||||
#endif
|
||||
#ifdef SHA_224
|
||||
HMAC_SHA224,
|
||||
#endif
|
||||
#ifdef SHA_256
|
||||
HMAC_SHA256,
|
||||
#endif
|
||||
#ifdef SHA_384
|
||||
HMAC_SHA384,
|
||||
#endif
|
||||
#ifdef SHA_512
|
||||
HMAC_SHA512,
|
||||
HMAC_SHA512_256,
|
||||
HMAC_SHA512_224,
|
||||
HMAC_SHA512_192,
|
||||
HMAC_SHA512_128
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef VOID_RETURN hf_begin(void*);
|
||||
typedef VOID_RETURN hf_hash(const void*, unsigned long len, void*);
|
||||
typedef VOID_RETURN hf_end(void*, void*);
|
||||
|
||||
typedef struct
|
||||
{ hf_begin *f_begin;
|
||||
hf_hash *f_hash;
|
||||
hf_end *f_end;
|
||||
unsigned char key[HMAC_MAX_BLOCK_SIZE];
|
||||
union
|
||||
{
|
||||
#ifdef SHA_1
|
||||
sha1_ctx u_sha1;
|
||||
#endif
|
||||
#ifdef SHA_224
|
||||
sha224_ctx u_sha224;
|
||||
#endif
|
||||
#ifdef SHA_256
|
||||
sha256_ctx u_sha256;
|
||||
#endif
|
||||
#ifdef SHA_384
|
||||
sha384_ctx u_sha384;
|
||||
#endif
|
||||
#ifdef SHA_512
|
||||
sha512_ctx u_sha512;
|
||||
#endif
|
||||
} sha_ctx[1];
|
||||
unsigned long input_len;
|
||||
unsigned long output_len;
|
||||
unsigned long klen;
|
||||
} hmac_ctx;
|
||||
|
||||
/* returns the length of hash digest for the hash used */
|
||||
/* mac_len must not be greater than this */
|
||||
int hmac_sha_begin(enum hmac_hash hash, hmac_ctx cx[1]);
|
||||
|
||||
int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1]);
|
||||
|
||||
void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1]);
|
||||
|
||||
void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1]);
|
||||
|
||||
void hmac_sha(enum hmac_hash hash, const unsigned char key[], unsigned long key_len,
|
||||
const unsigned char data[], unsigned long data_len,
|
||||
unsigned char mac[], unsigned long mac_len);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Executable
+182
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This is an implementation of RFC2898, which specifies key derivation from
|
||||
a password and a salt value.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "hmac.h"
|
||||
#include "pwd2key.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void derive_key(const unsigned char pwd[], /* the PASSWORD */
|
||||
unsigned int pwd_len, /* and its length */
|
||||
const unsigned char salt[], /* the SALT and its */
|
||||
unsigned int salt_len, /* length */
|
||||
unsigned int iter, /* the number of iterations */
|
||||
unsigned char key[], /* space for the output key */
|
||||
unsigned int key_len)/* and its required length */
|
||||
{
|
||||
unsigned int i, j, k, n_blk, h_size;
|
||||
unsigned char uu[HMAC_MAX_OUTPUT_SIZE], ux[HMAC_MAX_OUTPUT_SIZE];
|
||||
hmac_ctx c1[1], c2[1], c3[1];
|
||||
|
||||
/* set HMAC context (c1) for password */
|
||||
h_size = hmac_sha_begin(HMAC_SHA1, c1);
|
||||
hmac_sha_key(pwd, pwd_len, c1);
|
||||
|
||||
/* set HMAC context (c2) for password and salt */
|
||||
memcpy(c2, c1, sizeof(hmac_ctx));
|
||||
hmac_sha_data(salt, salt_len, c2);
|
||||
|
||||
/* find the number of SHA blocks in the key */
|
||||
n_blk = 1 + (key_len - 1) / h_size;
|
||||
|
||||
for(i = 0; i < n_blk; ++i) /* for each block in key */
|
||||
{
|
||||
/* ux[] holds the running xor value */
|
||||
memset(ux, 0, h_size);
|
||||
|
||||
/* set HMAC context (c3) for password and salt */
|
||||
memcpy(c3, c2, sizeof(hmac_ctx));
|
||||
|
||||
/* enter additional data for 1st block into uu */
|
||||
uu[0] = (unsigned char)((i + 1) >> 24);
|
||||
uu[1] = (unsigned char)((i + 1) >> 16);
|
||||
uu[2] = (unsigned char)((i + 1) >> 8);
|
||||
uu[3] = (unsigned char)(i + 1);
|
||||
|
||||
/* this is the key mixing iteration */
|
||||
for(j = 0, k = 4; j < iter; ++j)
|
||||
{
|
||||
/* add previous round data to HMAC */
|
||||
hmac_sha_data(uu, k, c3);
|
||||
|
||||
/* obtain HMAC for uu[] */
|
||||
hmac_sha_end(uu, h_size, c3);
|
||||
|
||||
/* xor into the running xor block */
|
||||
for(k = 0; k < h_size; ++k)
|
||||
ux[k] ^= uu[k];
|
||||
|
||||
/* set HMAC context (c3) for password */
|
||||
memcpy(c3, c1, sizeof(hmac_ctx));
|
||||
}
|
||||
|
||||
/* compile key blocks into the key output */
|
||||
j = 0; k = i * h_size;
|
||||
while(j < h_size && k < key_len)
|
||||
key[k++] = ux[j++];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct
|
||||
{ unsigned int pwd_len;
|
||||
unsigned int salt_len;
|
||||
unsigned int it_count;
|
||||
unsigned char *pwd;
|
||||
unsigned char salt[32];
|
||||
unsigned char key[32];
|
||||
} tests[] =
|
||||
{
|
||||
{ 8, 4, 5, (unsigned char*)"password",
|
||||
{
|
||||
0x12, 0x34, 0x56, 0x78
|
||||
},
|
||||
{
|
||||
0x5c, 0x75, 0xce, 0xf0, 0x1a, 0x96, 0x0d, 0xf7,
|
||||
0x4c, 0xb6, 0xb4, 0x9b, 0x9e, 0x38, 0xe6, 0xb5
|
||||
}
|
||||
},
|
||||
{ 8, 8, 5, (unsigned char*)"password",
|
||||
{
|
||||
0x12, 0x34, 0x56, 0x78, 0x78, 0x56, 0x34, 0x12
|
||||
},
|
||||
{
|
||||
0xd1, 0xda, 0xa7, 0x86, 0x15, 0xf2, 0x87, 0xe6,
|
||||
0xa1, 0xc8, 0xb1, 0x20, 0xd7, 0x06, 0x2a, 0x49
|
||||
}
|
||||
},
|
||||
{ 8, 21, 1, (unsigned char*)"password",
|
||||
{
|
||||
"ATHENA.MIT.EDUraeburn"
|
||||
},
|
||||
{
|
||||
0xcd, 0xed, 0xb5, 0x28, 0x1b, 0xb2, 0xf8, 0x01,
|
||||
0x56, 0x5a, 0x11, 0x22, 0xb2, 0x56, 0x35, 0x15
|
||||
}
|
||||
},
|
||||
{ 8, 21, 2, (unsigned char*)"password",
|
||||
{
|
||||
"ATHENA.MIT.EDUraeburn"
|
||||
},
|
||||
{
|
||||
0x01, 0xdb, 0xee, 0x7f, 0x4a, 0x9e, 0x24, 0x3e,
|
||||
0x98, 0x8b, 0x62, 0xc7, 0x3c, 0xda, 0x93, 0x5d
|
||||
}
|
||||
},
|
||||
{ 8, 21, 1200, (unsigned char*)"password",
|
||||
{
|
||||
"ATHENA.MIT.EDUraeburn"
|
||||
},
|
||||
{
|
||||
0x5c, 0x08, 0xeb, 0x61, 0xfd, 0xf7, 0x1e, 0x4e,
|
||||
0x4e, 0xc3, 0xcf, 0x6b, 0xa1, 0xf5, 0x51, 0x2b
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{ unsigned int i, j, key_len = 256;
|
||||
unsigned char key[256];
|
||||
|
||||
printf("\nTest of RFC2898 Password Based Key Derivation");
|
||||
for(i = 0; i < 5; ++i)
|
||||
{
|
||||
derive_key(tests[i].pwd, tests[i].pwd_len, tests[i].salt,
|
||||
tests[i].salt_len, tests[i].it_count, key, key_len);
|
||||
|
||||
printf("\ntest %i: ", i + 1);
|
||||
printf("key %s", memcmp(tests[i].key, key, 16) ? "is bad" : "is good");
|
||||
for(j = 0; j < key_len && j < 64; j += 4)
|
||||
{
|
||||
if(j % 16 == 0)
|
||||
printf("\n");
|
||||
printf("0x%02x%02x%02x%02x ", key[j], key[j + 1], key[j + 2], key[j + 3]);
|
||||
}
|
||||
printf(j < key_len ? " ... \n" : "\n");
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
|
||||
This is an implementation of RFC2898, which specifies key derivation from
|
||||
a password and a salt value.
|
||||
*/
|
||||
|
||||
#ifndef PWD2KEY_H
|
||||
#define PWD2KEY_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void derive_key(
|
||||
const unsigned char pwd[], /* the PASSWORD, and */
|
||||
unsigned int pwd_len, /* its length */
|
||||
const unsigned char salt[], /* the SALT and its */
|
||||
unsigned int salt_len, /* length */
|
||||
unsigned int iter, /* the number of iterations */
|
||||
unsigned char key[], /* space for the output key */
|
||||
unsigned int key_len); /* and its required length */
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Executable
+283
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#include <string.h> /* for memcpy() etc. */
|
||||
|
||||
#include "sha1.h"
|
||||
#include "brg_endian.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
|
||||
#pragma intrinsic(memcpy)
|
||||
#pragma intrinsic(memset)
|
||||
#endif
|
||||
|
||||
#if 0 && defined(_MSC_VER)
|
||||
#define rotl32 _lrotl
|
||||
#define rotr32 _lrotr
|
||||
#else
|
||||
#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n)))
|
||||
#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n)))
|
||||
#endif
|
||||
|
||||
#if !defined(bswap_32)
|
||||
#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
|
||||
#endif
|
||||
|
||||
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
|
||||
#define SWAP_BYTES
|
||||
#else
|
||||
#undef SWAP_BYTES
|
||||
#endif
|
||||
|
||||
#if defined(SWAP_BYTES)
|
||||
#define bsw_32(p,n) \
|
||||
{ int _i = (n); while(_i--) ((uint32_t*)p)[_i] = bswap_32(((uint32_t*)p)[_i]); }
|
||||
#else
|
||||
#define bsw_32(p,n)
|
||||
#endif
|
||||
|
||||
#define SHA1_MASK (SHA1_BLOCK_SIZE - 1)
|
||||
|
||||
#if 0
|
||||
|
||||
#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
|
||||
#define parity(x,y,z) ((x) ^ (y) ^ (z))
|
||||
#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
|
||||
#else /* Discovered by Rich Schroeppel and Colin Plumb */
|
||||
|
||||
#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||
#define parity(x,y,z) ((x) ^ (y) ^ (z))
|
||||
#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y))))
|
||||
|
||||
#endif
|
||||
|
||||
/* Compile 64 bytes of hash data into SHA1 context. Note */
|
||||
/* that this routine assumes that the byte order in the */
|
||||
/* ctx->wbuf[] at this point is in such an order that low */
|
||||
/* address bytes in the ORIGINAL byte stream will go in */
|
||||
/* this buffer to the high end of 32-bit words on BOTH big */
|
||||
/* and little endian systems */
|
||||
|
||||
#ifdef ARRAY
|
||||
#define q(v,n) v[n]
|
||||
#else
|
||||
#define q(v,n) v##n
|
||||
#endif
|
||||
|
||||
#ifdef SHA_1
|
||||
|
||||
#define one_cycle(v,a,b,c,d,e,f,k,h) \
|
||||
q(v,e) += rotr32(q(v,a),27) + \
|
||||
f(q(v,b),q(v,c),q(v,d)) + k + h; \
|
||||
q(v,b) = rotr32(q(v,b), 2)
|
||||
|
||||
#define five_cycle(v,f,k,i) \
|
||||
one_cycle(v, 0,1,2,3,4, f,k,hf(i )); \
|
||||
one_cycle(v, 4,0,1,2,3, f,k,hf(i+1)); \
|
||||
one_cycle(v, 3,4,0,1,2, f,k,hf(i+2)); \
|
||||
one_cycle(v, 2,3,4,0,1, f,k,hf(i+3)); \
|
||||
one_cycle(v, 1,2,3,4,0, f,k,hf(i+4))
|
||||
|
||||
VOID_RETURN sha1_compile(sha1_ctx ctx[1])
|
||||
{ uint32_t *w = ctx->wbuf;
|
||||
|
||||
#ifdef ARRAY
|
||||
uint32_t v[5];
|
||||
memcpy(v, ctx->hash, sizeof(ctx->hash));
|
||||
#else
|
||||
uint32_t v0, v1, v2, v3, v4;
|
||||
v0 = ctx->hash[0]; v1 = ctx->hash[1];
|
||||
v2 = ctx->hash[2]; v3 = ctx->hash[3];
|
||||
v4 = ctx->hash[4];
|
||||
#endif
|
||||
|
||||
#define hf(i) w[i]
|
||||
|
||||
five_cycle(v, ch, 0x5a827999, 0);
|
||||
five_cycle(v, ch, 0x5a827999, 5);
|
||||
five_cycle(v, ch, 0x5a827999, 10);
|
||||
one_cycle(v,0,1,2,3,4, ch, 0x5a827999, hf(15)); \
|
||||
|
||||
#undef hf
|
||||
#define hf(i) (w[(i) & 15] = rotl32( \
|
||||
w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \
|
||||
^ w[((i) + 2) & 15] ^ w[(i) & 15], 1))
|
||||
|
||||
one_cycle(v,4,0,1,2,3, ch, 0x5a827999, hf(16));
|
||||
one_cycle(v,3,4,0,1,2, ch, 0x5a827999, hf(17));
|
||||
one_cycle(v,2,3,4,0,1, ch, 0x5a827999, hf(18));
|
||||
one_cycle(v,1,2,3,4,0, ch, 0x5a827999, hf(19));
|
||||
|
||||
five_cycle(v, parity, 0x6ed9eba1, 20);
|
||||
five_cycle(v, parity, 0x6ed9eba1, 25);
|
||||
five_cycle(v, parity, 0x6ed9eba1, 30);
|
||||
five_cycle(v, parity, 0x6ed9eba1, 35);
|
||||
|
||||
five_cycle(v, maj, 0x8f1bbcdc, 40);
|
||||
five_cycle(v, maj, 0x8f1bbcdc, 45);
|
||||
five_cycle(v, maj, 0x8f1bbcdc, 50);
|
||||
five_cycle(v, maj, 0x8f1bbcdc, 55);
|
||||
|
||||
five_cycle(v, parity, 0xca62c1d6, 60);
|
||||
five_cycle(v, parity, 0xca62c1d6, 65);
|
||||
five_cycle(v, parity, 0xca62c1d6, 70);
|
||||
five_cycle(v, parity, 0xca62c1d6, 75);
|
||||
|
||||
#ifdef ARRAY
|
||||
ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
|
||||
ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
|
||||
ctx->hash[4] += v[4];
|
||||
#else
|
||||
ctx->hash[0] += v0; ctx->hash[1] += v1;
|
||||
ctx->hash[2] += v2; ctx->hash[3] += v3;
|
||||
ctx->hash[4] += v4;
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID_RETURN sha1_begin(sha1_ctx ctx[1])
|
||||
{
|
||||
memset(ctx, 0, sizeof(sha1_ctx));
|
||||
ctx->hash[0] = 0x67452301;
|
||||
ctx->hash[1] = 0xefcdab89;
|
||||
ctx->hash[2] = 0x98badcfe;
|
||||
ctx->hash[3] = 0x10325476;
|
||||
ctx->hash[4] = 0xc3d2e1f0;
|
||||
}
|
||||
|
||||
/* SHA1 hash data in an array of bytes into hash buffer and */
|
||||
/* call the hash_compile function as required. For both the */
|
||||
/* bit and byte orientated versions, the block length 'len' */
|
||||
/* must not be greater than 2^32 - 1 bits (2^29 - 1 bytes) */
|
||||
|
||||
VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1])
|
||||
{ uint32_t pos = (uint32_t)((ctx->count[0] >> 3) & SHA1_MASK);
|
||||
const unsigned char *sp = data;
|
||||
unsigned char *w = (unsigned char*)ctx->wbuf;
|
||||
#if SHA1_BITS == 1
|
||||
uint32_t ofs = (ctx->count[0] & 7);
|
||||
#else
|
||||
len <<= 3;
|
||||
#endif
|
||||
if((ctx->count[0] += len) < len)
|
||||
++(ctx->count[1]);
|
||||
#if SHA1_BITS == 1
|
||||
if(ofs) /* if not on a byte boundary */
|
||||
{
|
||||
if(ofs + len < 8) /* if no added bytes are needed */
|
||||
{
|
||||
w[pos] |= (*sp >> ofs);
|
||||
}
|
||||
else /* otherwise and add bytes */
|
||||
{ unsigned char part = w[pos];
|
||||
|
||||
while((int)(ofs + (len -= 8)) >= 0)
|
||||
{
|
||||
w[pos++] = part | (*sp >> ofs);
|
||||
part = *sp++ << (8 - ofs);
|
||||
if(pos == SHA1_BLOCK_SIZE)
|
||||
{
|
||||
bsw_32(w, SHA1_BLOCK_SIZE >> 2);
|
||||
sha1_compile(ctx); pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
w[pos] = part;
|
||||
}
|
||||
}
|
||||
else /* data is byte aligned */
|
||||
#endif
|
||||
{ uint32_t space = SHA1_BLOCK_SIZE - pos;
|
||||
|
||||
while(len >= (space << 3))
|
||||
{
|
||||
memcpy(w + pos, sp, space);
|
||||
bsw_32(w, SHA1_BLOCK_SIZE >> 2);
|
||||
sha1_compile(ctx);
|
||||
sp += space; len -= (space << 3);
|
||||
space = SHA1_BLOCK_SIZE; pos = 0;
|
||||
}
|
||||
memcpy(w + pos, sp, (len + 7 * SHA1_BITS) >> 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* SHA1 final padding and digest calculation */
|
||||
|
||||
VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1])
|
||||
{ uint32_t i = (uint32_t)((ctx->count[0] >> 3) & SHA1_MASK), m1;
|
||||
|
||||
/* put bytes in the buffer in an order in which references to */
|
||||
/* 32-bit words will put bytes with lower addresses into the */
|
||||
/* top of 32 bit words on BOTH big and little endian machines */
|
||||
bsw_32(ctx->wbuf, (i + 3 + SHA1_BITS) >> 2);
|
||||
|
||||
/* we now need to mask valid bytes and add the padding which is */
|
||||
/* a single 1 bit and as many zero bits as necessary. Note that */
|
||||
/* we can always add the first padding byte here because the */
|
||||
/* buffer always has at least one empty slot */
|
||||
m1 = (unsigned char)0x80 >> (ctx->count[0] & 7);
|
||||
ctx->wbuf[i >> 2] &= ((0xffffff00 | (~m1 + 1)) << 8 * (~i & 3));
|
||||
ctx->wbuf[i >> 2] |= (m1 << 8 * (~i & 3));
|
||||
|
||||
/* we need 9 or more empty positions, one for the padding byte */
|
||||
/* (above) and eight for the length count. If there is not */
|
||||
/* enough space, pad and empty the buffer */
|
||||
if(i > SHA1_BLOCK_SIZE - 9)
|
||||
{
|
||||
if(i < 60) ctx->wbuf[15] = 0;
|
||||
sha1_compile(ctx);
|
||||
i = 0;
|
||||
}
|
||||
else /* compute a word index for the empty buffer positions */
|
||||
i = (i >> 2) + 1;
|
||||
|
||||
while(i < 14) /* and zero pad all but last two positions */
|
||||
ctx->wbuf[i++] = 0;
|
||||
|
||||
/* the following 32-bit length fields are assembled in the */
|
||||
/* wrong byte order on little endian machines but this is */
|
||||
/* corrected later since they are only ever used as 32-bit */
|
||||
/* word values. */
|
||||
ctx->wbuf[14] = ctx->count[1];
|
||||
ctx->wbuf[15] = ctx->count[0];
|
||||
sha1_compile(ctx);
|
||||
|
||||
/* extract the hash value as bytes in case the hash buffer is */
|
||||
/* misaligned for 32-bit words */
|
||||
for(i = 0; i < SHA1_DIGEST_SIZE; ++i)
|
||||
hval[i] = ((ctx->hash[i >> 2] >> (8 * (~i & 3))) & 0xff);
|
||||
}
|
||||
|
||||
VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len)
|
||||
{ sha1_ctx cx[1];
|
||||
|
||||
sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#ifndef _SHA1_H
|
||||
#define _SHA1_H
|
||||
|
||||
#define SHA_1
|
||||
|
||||
/* define for bit or byte oriented SHA */
|
||||
#if 1
|
||||
# define SHA1_BITS 0 /* byte oriented */
|
||||
#else
|
||||
# define SHA1_BITS 1 /* bit oriented */
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "brg_types.h"
|
||||
|
||||
#define SHA1_BLOCK_SIZE 64
|
||||
#define SHA1_DIGEST_SIZE 20
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* type to hold the SHA256 context */
|
||||
|
||||
typedef struct
|
||||
{ uint32_t count[2];
|
||||
uint32_t hash[SHA1_DIGEST_SIZE >> 2];
|
||||
uint32_t wbuf[SHA1_BLOCK_SIZE >> 2];
|
||||
} sha1_ctx;
|
||||
|
||||
/* Note that these prototypes are the same for both bit and */
|
||||
/* byte oriented implementations. However the length fields */
|
||||
/* are in bytes or bits as appropriate for the version used */
|
||||
/* and bit sequences are input as arrays of bytes in which */
|
||||
/* bit sequences run from the most to the least significant */
|
||||
/* end of each byte. The value 'len' in sha1_hash for the */
|
||||
/* byte oriented version of SHA1 is limited to 2^29 bytes, */
|
||||
/* but multiple calls will handle longer data blocks. */
|
||||
|
||||
VOID_RETURN sha1_compile(sha1_ctx ctx[1]);
|
||||
|
||||
VOID_RETURN sha1_begin(sha1_ctx ctx[1]);
|
||||
VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]);
|
||||
VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1]);
|
||||
VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
This program, "bzip2", the associated library "libbzip2", and all
|
||||
documentation, are copyright (C) 1996-2010 Julian R Seward. All
|
||||
rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. 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.
|
||||
|
||||
3. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
4. The name of the author may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Julian Seward, jseward@bzip.org
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
+1094
File diff suppressed because it is too large
Load Diff
Executable
+1572
File diff suppressed because it is too large
Load Diff
Executable
+282
@@ -0,0 +1,282 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Public header file for the library. ---*/
|
||||
/*--- bzlib.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#ifndef _BZLIB_H
|
||||
#define _BZLIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BZ_RUN 0
|
||||
#define BZ_FLUSH 1
|
||||
#define BZ_FINISH 2
|
||||
|
||||
#define BZ_OK 0
|
||||
#define BZ_RUN_OK 1
|
||||
#define BZ_FLUSH_OK 2
|
||||
#define BZ_FINISH_OK 3
|
||||
#define BZ_STREAM_END 4
|
||||
#define BZ_SEQUENCE_ERROR (-1)
|
||||
#define BZ_PARAM_ERROR (-2)
|
||||
#define BZ_MEM_ERROR (-3)
|
||||
#define BZ_DATA_ERROR (-4)
|
||||
#define BZ_DATA_ERROR_MAGIC (-5)
|
||||
#define BZ_IO_ERROR (-6)
|
||||
#define BZ_UNEXPECTED_EOF (-7)
|
||||
#define BZ_OUTBUFF_FULL (-8)
|
||||
#define BZ_CONFIG_ERROR (-9)
|
||||
|
||||
typedef
|
||||
struct {
|
||||
char *next_in;
|
||||
unsigned int avail_in;
|
||||
unsigned int total_in_lo32;
|
||||
unsigned int total_in_hi32;
|
||||
|
||||
char *next_out;
|
||||
unsigned int avail_out;
|
||||
unsigned int total_out_lo32;
|
||||
unsigned int total_out_hi32;
|
||||
|
||||
void *state;
|
||||
|
||||
void *(*bzalloc)(void *,int,int);
|
||||
void (*bzfree)(void *,void *);
|
||||
void *opaque;
|
||||
}
|
||||
bz_stream;
|
||||
|
||||
|
||||
#ifndef BZ_IMPORT
|
||||
#define BZ_EXPORT
|
||||
#endif
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
/* Need a definitition for FILE */
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# ifdef small
|
||||
/* windows.h define small to char */
|
||||
# undef small
|
||||
# endif
|
||||
# ifdef BZ_EXPORT
|
||||
# define BZ_API(func) WINAPI func
|
||||
# define BZ_EXTERN extern
|
||||
# else
|
||||
/* import windows dll dynamically */
|
||||
# define BZ_API(func) (WINAPI * func)
|
||||
# define BZ_EXTERN
|
||||
# endif
|
||||
#else
|
||||
# define BZ_API(func) func
|
||||
# define BZ_EXTERN extern
|
||||
#endif
|
||||
|
||||
|
||||
/*-- Core (low-level) library functions --*/
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
|
||||
bz_stream* strm,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompress) (
|
||||
bz_stream* strm,
|
||||
int action
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
|
||||
bz_stream *strm,
|
||||
int verbosity,
|
||||
int small
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
|
||||
bz_stream* strm
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
|
||||
bz_stream *strm
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*-- High(er) level library functions --*/
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
#define BZ_MAX_UNUSED 5000
|
||||
|
||||
typedef void BZFILE;
|
||||
|
||||
BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
|
||||
int* bzerror,
|
||||
FILE* f,
|
||||
int verbosity,
|
||||
int small,
|
||||
void* unused,
|
||||
int nUnused
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
|
||||
int* bzerror,
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void** unused,
|
||||
int* nUnused
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzRead) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
|
||||
int* bzerror,
|
||||
FILE* f,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWrite) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in,
|
||||
unsigned int* nbytes_out
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
|
||||
int* bzerror,
|
||||
BZFILE* b,
|
||||
int abandon,
|
||||
unsigned int* nbytes_in_lo32,
|
||||
unsigned int* nbytes_in_hi32,
|
||||
unsigned int* nbytes_out_lo32,
|
||||
unsigned int* nbytes_out_hi32
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
/*-- Utility functions --*/
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
|
||||
char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
unsigned int sourceLen,
|
||||
int blockSize100k,
|
||||
int verbosity,
|
||||
int workFactor
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
|
||||
char* dest,
|
||||
unsigned int* destLen,
|
||||
char* source,
|
||||
unsigned int sourceLen,
|
||||
int small,
|
||||
int verbosity
|
||||
);
|
||||
|
||||
|
||||
/*--
|
||||
Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
|
||||
to support better zlib compatibility.
|
||||
This code is not _officially_ part of libbzip2 (yet);
|
||||
I haven't tested it, documented it, or considered the
|
||||
threading-safeness of it.
|
||||
If this code breaks, please contact both Yoshioka and me.
|
||||
--*/
|
||||
|
||||
BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
|
||||
void
|
||||
);
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
|
||||
const char *path,
|
||||
const char *mode
|
||||
);
|
||||
|
||||
BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
|
||||
int fd,
|
||||
const char *mode
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzread) (
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzwrite) (
|
||||
BZFILE* b,
|
||||
void* buf,
|
||||
int len
|
||||
);
|
||||
|
||||
BZ_EXTERN int BZ_API(BZ2_bzflush) (
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN void BZ_API(BZ2_bzclose) (
|
||||
BZFILE* b
|
||||
);
|
||||
|
||||
BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
|
||||
BZFILE *b,
|
||||
int *errnum
|
||||
);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end bzlib.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
+509
@@ -0,0 +1,509 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Private header file for the library. ---*/
|
||||
/*--- bzlib_private.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#ifndef _BZLIB_PRIVATE_H
|
||||
#define _BZLIB_PRIVATE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "bzlib.h"
|
||||
|
||||
|
||||
|
||||
/*-- General stuff. --*/
|
||||
|
||||
#define BZ_VERSION "1.0.6, 6-Sept-2010"
|
||||
|
||||
typedef char Char;
|
||||
typedef unsigned char Bool;
|
||||
typedef unsigned char UChar;
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
|
||||
#define True ((Bool)1)
|
||||
#define False ((Bool)0)
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define __inline__ /* */
|
||||
#endif
|
||||
|
||||
#ifndef BZ_NO_STDIO
|
||||
|
||||
extern void BZ2_bz__AssertH__fail ( int errcode );
|
||||
#define AssertH(cond,errcode) \
|
||||
{ if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
|
||||
|
||||
#if BZ_DEBUG
|
||||
#define AssertD(cond,msg) \
|
||||
{ if (!(cond)) { \
|
||||
fprintf ( stderr, \
|
||||
"\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
|
||||
exit(1); \
|
||||
}}
|
||||
#else
|
||||
#define AssertD(cond,msg) /* */
|
||||
#endif
|
||||
|
||||
#define VPrintf0(zf) \
|
||||
fprintf(stderr,zf)
|
||||
#define VPrintf1(zf,za1) \
|
||||
fprintf(stderr,zf,za1)
|
||||
#define VPrintf2(zf,za1,za2) \
|
||||
fprintf(stderr,zf,za1,za2)
|
||||
#define VPrintf3(zf,za1,za2,za3) \
|
||||
fprintf(stderr,zf,za1,za2,za3)
|
||||
#define VPrintf4(zf,za1,za2,za3,za4) \
|
||||
fprintf(stderr,zf,za1,za2,za3,za4)
|
||||
#define VPrintf5(zf,za1,za2,za3,za4,za5) \
|
||||
fprintf(stderr,zf,za1,za2,za3,za4,za5)
|
||||
|
||||
#else
|
||||
|
||||
extern void bz_internal_error ( int errcode );
|
||||
#define AssertH(cond,errcode) \
|
||||
{ if (!(cond)) bz_internal_error ( errcode ); }
|
||||
#define AssertD(cond,msg) do { } while (0)
|
||||
#define VPrintf0(zf) do { } while (0)
|
||||
#define VPrintf1(zf,za1) do { } while (0)
|
||||
#define VPrintf2(zf,za1,za2) do { } while (0)
|
||||
#define VPrintf3(zf,za1,za2,za3) do { } while (0)
|
||||
#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0)
|
||||
#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
|
||||
#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
|
||||
|
||||
|
||||
/*-- Header bytes. --*/
|
||||
|
||||
#define BZ_HDR_B 0x42 /* 'B' */
|
||||
#define BZ_HDR_Z 0x5a /* 'Z' */
|
||||
#define BZ_HDR_h 0x68 /* 'h' */
|
||||
#define BZ_HDR_0 0x30 /* '0' */
|
||||
|
||||
/*-- Constants for the back end. --*/
|
||||
|
||||
#define BZ_MAX_ALPHA_SIZE 258
|
||||
#define BZ_MAX_CODE_LEN 23
|
||||
|
||||
#define BZ_RUNA 0
|
||||
#define BZ_RUNB 1
|
||||
|
||||
#define BZ_N_GROUPS 6
|
||||
#define BZ_G_SIZE 50
|
||||
#define BZ_N_ITERS 4
|
||||
|
||||
#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
|
||||
|
||||
|
||||
|
||||
/*-- Stuff for randomising repetitive blocks. --*/
|
||||
|
||||
extern Int32 BZ2_rNums[512];
|
||||
|
||||
#define BZ_RAND_DECLS \
|
||||
Int32 rNToGo; \
|
||||
Int32 rTPos \
|
||||
|
||||
#define BZ_RAND_INIT_MASK \
|
||||
s->rNToGo = 0; \
|
||||
s->rTPos = 0 \
|
||||
|
||||
#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
|
||||
|
||||
#define BZ_RAND_UPD_MASK \
|
||||
if (s->rNToGo == 0) { \
|
||||
s->rNToGo = BZ2_rNums[s->rTPos]; \
|
||||
s->rTPos++; \
|
||||
if (s->rTPos == 512) s->rTPos = 0; \
|
||||
} \
|
||||
s->rNToGo--;
|
||||
|
||||
|
||||
|
||||
/*-- Stuff for doing CRCs. --*/
|
||||
|
||||
extern UInt32 BZ2_crc32Table[256];
|
||||
|
||||
#define BZ_INITIALISE_CRC(crcVar) \
|
||||
{ \
|
||||
crcVar = 0xffffffffL; \
|
||||
}
|
||||
|
||||
#define BZ_FINALISE_CRC(crcVar) \
|
||||
{ \
|
||||
crcVar = ~(crcVar); \
|
||||
}
|
||||
|
||||
#define BZ_UPDATE_CRC(crcVar,cha) \
|
||||
{ \
|
||||
crcVar = (crcVar << 8) ^ \
|
||||
BZ2_crc32Table[(crcVar >> 24) ^ \
|
||||
((UChar)cha)]; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-- States and modes for compression. --*/
|
||||
|
||||
#define BZ_M_IDLE 1
|
||||
#define BZ_M_RUNNING 2
|
||||
#define BZ_M_FLUSHING 3
|
||||
#define BZ_M_FINISHING 4
|
||||
|
||||
#define BZ_S_OUTPUT 1
|
||||
#define BZ_S_INPUT 2
|
||||
|
||||
#define BZ_N_RADIX 2
|
||||
#define BZ_N_QSORT 12
|
||||
#define BZ_N_SHELL 18
|
||||
#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
|
||||
|
||||
|
||||
|
||||
|
||||
/*-- Structure holding all the compression-side stuff. --*/
|
||||
|
||||
typedef
|
||||
struct {
|
||||
/* pointer back to the struct bz_stream */
|
||||
bz_stream* strm;
|
||||
|
||||
/* mode this stream is in, and whether inputting */
|
||||
/* or outputting data */
|
||||
Int32 mode;
|
||||
Int32 state;
|
||||
|
||||
/* remembers avail_in when flush/finish requested */
|
||||
UInt32 avail_in_expect;
|
||||
|
||||
/* for doing the block sorting */
|
||||
UInt32* arr1;
|
||||
UInt32* arr2;
|
||||
UInt32* ftab;
|
||||
Int32 origPtr;
|
||||
|
||||
/* aliases for arr1 and arr2 */
|
||||
UInt32* ptr;
|
||||
UChar* block;
|
||||
UInt16* mtfv;
|
||||
UChar* zbits;
|
||||
|
||||
/* for deciding when to use the fallback sorting algorithm */
|
||||
Int32 workFactor;
|
||||
|
||||
/* run-length-encoding of the input */
|
||||
UInt32 state_in_ch;
|
||||
Int32 state_in_len;
|
||||
BZ_RAND_DECLS;
|
||||
|
||||
/* input and output limits and current posns */
|
||||
Int32 nblock;
|
||||
Int32 nblockMAX;
|
||||
Int32 numZ;
|
||||
Int32 state_out_pos;
|
||||
|
||||
/* map of bytes used in block */
|
||||
Int32 nInUse;
|
||||
Bool inUse[256];
|
||||
UChar unseqToSeq[256];
|
||||
|
||||
/* the buffer for bit stream creation */
|
||||
UInt32 bsBuff;
|
||||
Int32 bsLive;
|
||||
|
||||
/* block and combined CRCs */
|
||||
UInt32 blockCRC;
|
||||
UInt32 combinedCRC;
|
||||
|
||||
/* misc administratium */
|
||||
Int32 verbosity;
|
||||
Int32 blockNo;
|
||||
Int32 blockSize100k;
|
||||
|
||||
/* stuff for coding the MTF values */
|
||||
Int32 nMTF;
|
||||
Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
|
||||
UChar selector [BZ_MAX_SELECTORS];
|
||||
UChar selectorMtf[BZ_MAX_SELECTORS];
|
||||
|
||||
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
/* second dimension: only 3 needed; 4 makes index calculations faster */
|
||||
UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
|
||||
|
||||
}
|
||||
EState;
|
||||
|
||||
|
||||
|
||||
/*-- externs for compression. --*/
|
||||
|
||||
extern void
|
||||
BZ2_blockSort ( EState* );
|
||||
|
||||
extern void
|
||||
BZ2_compressBlock ( EState*, Bool );
|
||||
|
||||
extern void
|
||||
BZ2_bsInitWrite ( EState* );
|
||||
|
||||
extern void
|
||||
BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
|
||||
|
||||
extern void
|
||||
BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
|
||||
|
||||
|
||||
|
||||
/*-- states for decompression. --*/
|
||||
|
||||
#define BZ_X_IDLE 1
|
||||
#define BZ_X_OUTPUT 2
|
||||
|
||||
#define BZ_X_MAGIC_1 10
|
||||
#define BZ_X_MAGIC_2 11
|
||||
#define BZ_X_MAGIC_3 12
|
||||
#define BZ_X_MAGIC_4 13
|
||||
#define BZ_X_BLKHDR_1 14
|
||||
#define BZ_X_BLKHDR_2 15
|
||||
#define BZ_X_BLKHDR_3 16
|
||||
#define BZ_X_BLKHDR_4 17
|
||||
#define BZ_X_BLKHDR_5 18
|
||||
#define BZ_X_BLKHDR_6 19
|
||||
#define BZ_X_BCRC_1 20
|
||||
#define BZ_X_BCRC_2 21
|
||||
#define BZ_X_BCRC_3 22
|
||||
#define BZ_X_BCRC_4 23
|
||||
#define BZ_X_RANDBIT 24
|
||||
#define BZ_X_ORIGPTR_1 25
|
||||
#define BZ_X_ORIGPTR_2 26
|
||||
#define BZ_X_ORIGPTR_3 27
|
||||
#define BZ_X_MAPPING_1 28
|
||||
#define BZ_X_MAPPING_2 29
|
||||
#define BZ_X_SELECTOR_1 30
|
||||
#define BZ_X_SELECTOR_2 31
|
||||
#define BZ_X_SELECTOR_3 32
|
||||
#define BZ_X_CODING_1 33
|
||||
#define BZ_X_CODING_2 34
|
||||
#define BZ_X_CODING_3 35
|
||||
#define BZ_X_MTF_1 36
|
||||
#define BZ_X_MTF_2 37
|
||||
#define BZ_X_MTF_3 38
|
||||
#define BZ_X_MTF_4 39
|
||||
#define BZ_X_MTF_5 40
|
||||
#define BZ_X_MTF_6 41
|
||||
#define BZ_X_ENDHDR_2 42
|
||||
#define BZ_X_ENDHDR_3 43
|
||||
#define BZ_X_ENDHDR_4 44
|
||||
#define BZ_X_ENDHDR_5 45
|
||||
#define BZ_X_ENDHDR_6 46
|
||||
#define BZ_X_CCRC_1 47
|
||||
#define BZ_X_CCRC_2 48
|
||||
#define BZ_X_CCRC_3 49
|
||||
#define BZ_X_CCRC_4 50
|
||||
|
||||
|
||||
|
||||
/*-- Constants for the fast MTF decoder. --*/
|
||||
|
||||
#define MTFA_SIZE 4096
|
||||
#define MTFL_SIZE 16
|
||||
|
||||
|
||||
|
||||
/*-- Structure holding all the decompression-side stuff. --*/
|
||||
|
||||
typedef
|
||||
struct {
|
||||
/* pointer back to the struct bz_stream */
|
||||
bz_stream* strm;
|
||||
|
||||
/* state indicator for this stream */
|
||||
Int32 state;
|
||||
|
||||
/* for doing the final run-length decoding */
|
||||
UChar state_out_ch;
|
||||
Int32 state_out_len;
|
||||
Bool blockRandomised;
|
||||
BZ_RAND_DECLS;
|
||||
|
||||
/* the buffer for bit stream reading */
|
||||
UInt32 bsBuff;
|
||||
Int32 bsLive;
|
||||
|
||||
/* misc administratium */
|
||||
Int32 blockSize100k;
|
||||
Bool smallDecompress;
|
||||
Int32 currBlockNo;
|
||||
Int32 verbosity;
|
||||
|
||||
/* for undoing the Burrows-Wheeler transform */
|
||||
Int32 origPtr;
|
||||
UInt32 tPos;
|
||||
Int32 k0;
|
||||
Int32 unzftab[256];
|
||||
Int32 nblock_used;
|
||||
Int32 cftab[257];
|
||||
Int32 cftabCopy[257];
|
||||
|
||||
/* for undoing the Burrows-Wheeler transform (FAST) */
|
||||
UInt32 *tt;
|
||||
|
||||
/* for undoing the Burrows-Wheeler transform (SMALL) */
|
||||
UInt16 *ll16;
|
||||
UChar *ll4;
|
||||
|
||||
/* stored and calculated CRCs */
|
||||
UInt32 storedBlockCRC;
|
||||
UInt32 storedCombinedCRC;
|
||||
UInt32 calculatedBlockCRC;
|
||||
UInt32 calculatedCombinedCRC;
|
||||
|
||||
/* map of bytes used in block */
|
||||
Int32 nInUse;
|
||||
Bool inUse[256];
|
||||
Bool inUse16[16];
|
||||
UChar seqToUnseq[256];
|
||||
|
||||
/* for decoding the MTF values */
|
||||
UChar mtfa [MTFA_SIZE];
|
||||
Int32 mtfbase[256 / MTFL_SIZE];
|
||||
UChar selector [BZ_MAX_SELECTORS];
|
||||
UChar selectorMtf[BZ_MAX_SELECTORS];
|
||||
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
|
||||
Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 minLens[BZ_N_GROUPS];
|
||||
|
||||
/* save area for scalars in the main decompress code */
|
||||
Int32 save_i;
|
||||
Int32 save_j;
|
||||
Int32 save_t;
|
||||
Int32 save_alphaSize;
|
||||
Int32 save_nGroups;
|
||||
Int32 save_nSelectors;
|
||||
Int32 save_EOB;
|
||||
Int32 save_groupNo;
|
||||
Int32 save_groupPos;
|
||||
Int32 save_nextSym;
|
||||
Int32 save_nblockMAX;
|
||||
Int32 save_nblock;
|
||||
Int32 save_es;
|
||||
Int32 save_N;
|
||||
Int32 save_curr;
|
||||
Int32 save_zt;
|
||||
Int32 save_zn;
|
||||
Int32 save_zvec;
|
||||
Int32 save_zj;
|
||||
Int32 save_gSel;
|
||||
Int32 save_gMinlen;
|
||||
Int32* save_gLimit;
|
||||
Int32* save_gBase;
|
||||
Int32* save_gPerm;
|
||||
|
||||
}
|
||||
DState;
|
||||
|
||||
|
||||
|
||||
/*-- Macros for decompression. --*/
|
||||
|
||||
#define BZ_GET_FAST(cccc) \
|
||||
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
|
||||
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
|
||||
s->tPos = s->tt[s->tPos]; \
|
||||
cccc = (UChar)(s->tPos & 0xff); \
|
||||
s->tPos >>= 8;
|
||||
|
||||
#define BZ_GET_FAST_C(cccc) \
|
||||
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
|
||||
if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
|
||||
c_tPos = c_tt[c_tPos]; \
|
||||
cccc = (UChar)(c_tPos & 0xff); \
|
||||
c_tPos >>= 8;
|
||||
|
||||
#define SET_LL4(i,n) \
|
||||
{ if (((i) & 0x1) == 0) \
|
||||
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
|
||||
s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
|
||||
}
|
||||
|
||||
#define GET_LL4(i) \
|
||||
((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
|
||||
|
||||
#define SET_LL(i,n) \
|
||||
{ s->ll16[i] = (UInt16)(n & 0x0000ffff); \
|
||||
SET_LL4(i, n >> 16); \
|
||||
}
|
||||
|
||||
#define GET_LL(i) \
|
||||
(((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
|
||||
|
||||
#define BZ_GET_SMALL(cccc) \
|
||||
/* c_tPos is unsigned, hence test < 0 is pointless. */ \
|
||||
if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
|
||||
cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
|
||||
s->tPos = GET_LL(s->tPos);
|
||||
|
||||
|
||||
/*-- externs for decompression. --*/
|
||||
|
||||
extern Int32
|
||||
BZ2_indexIntoF ( Int32, Int32* );
|
||||
|
||||
extern Int32
|
||||
BZ2_decompress ( DState* );
|
||||
|
||||
extern void
|
||||
BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
|
||||
Int32, Int32, Int32 );
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
|
||||
|
||||
#ifdef BZ_NO_STDIO
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end bzlib_private.h ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
+672
@@ -0,0 +1,672 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Compression machinery (not incl block sorting) ---*/
|
||||
/*--- compress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
/* CHANGES
|
||||
0.9.0 -- original version.
|
||||
0.9.0a/b -- no changes in this file.
|
||||
0.9.0c -- changed setting of nGroups in sendMTFValues()
|
||||
so as to do a bit better on small files
|
||||
*/
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
/*--- Bit stream I/O ---*/
|
||||
/*---------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_bsInitWrite ( EState* s )
|
||||
{
|
||||
s->bsLive = 0;
|
||||
s->bsBuff = 0;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void bsFinishWrite ( EState* s )
|
||||
{
|
||||
while (s->bsLive > 0) {
|
||||
s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
|
||||
s->numZ++;
|
||||
s->bsBuff <<= 8;
|
||||
s->bsLive -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define bsNEEDW(nz) \
|
||||
{ \
|
||||
while (s->bsLive >= 8) { \
|
||||
s->zbits[s->numZ] \
|
||||
= (UChar)(s->bsBuff >> 24); \
|
||||
s->numZ++; \
|
||||
s->bsBuff <<= 8; \
|
||||
s->bsLive -= 8; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
__inline__
|
||||
void bsW ( EState* s, Int32 n, UInt32 v )
|
||||
{
|
||||
bsNEEDW ( n );
|
||||
s->bsBuff |= (v << (32 - s->bsLive - n));
|
||||
s->bsLive += n;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void bsPutUInt32 ( EState* s, UInt32 u )
|
||||
{
|
||||
bsW ( s, 8, (u >> 24) & 0xffL );
|
||||
bsW ( s, 8, (u >> 16) & 0xffL );
|
||||
bsW ( s, 8, (u >> 8) & 0xffL );
|
||||
bsW ( s, 8, u & 0xffL );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void bsPutUChar ( EState* s, UChar c )
|
||||
{
|
||||
bsW( s, 8, (UInt32)c );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
/*--- The back end proper ---*/
|
||||
/*---------------------------------------------------*/
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void makeMaps_e ( EState* s )
|
||||
{
|
||||
Int32 i;
|
||||
s->nInUse = 0;
|
||||
for (i = 0; i < 256; i++)
|
||||
if (s->inUse[i]) {
|
||||
s->unseqToSeq[i] = s->nInUse;
|
||||
s->nInUse++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void generateMTFValues ( EState* s )
|
||||
{
|
||||
UChar yy[256];
|
||||
Int32 i, j;
|
||||
Int32 zPend;
|
||||
Int32 wr;
|
||||
Int32 EOB;
|
||||
|
||||
/*
|
||||
After sorting (eg, here),
|
||||
s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
|
||||
and
|
||||
((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
|
||||
holds the original block data.
|
||||
|
||||
The first thing to do is generate the MTF values,
|
||||
and put them in
|
||||
((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
|
||||
Because there are strictly fewer or equal MTF values
|
||||
than block values, ptr values in this area are overwritten
|
||||
with MTF values only when they are no longer needed.
|
||||
|
||||
The final compressed bitstream is generated into the
|
||||
area starting at
|
||||
(UChar*) (&((UChar*)s->arr2)[s->nblock])
|
||||
|
||||
These storage aliases are set up in bzCompressInit(),
|
||||
except for the last one, which is arranged in
|
||||
compressBlock().
|
||||
*/
|
||||
UInt32* ptr = s->ptr;
|
||||
UChar* block = s->block;
|
||||
UInt16* mtfv = s->mtfv;
|
||||
|
||||
makeMaps_e ( s );
|
||||
EOB = s->nInUse+1;
|
||||
|
||||
for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
|
||||
|
||||
wr = 0;
|
||||
zPend = 0;
|
||||
for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
|
||||
|
||||
for (i = 0; i < s->nblock; i++) {
|
||||
UChar ll_i;
|
||||
AssertD ( wr <= i, "generateMTFValues(1)" );
|
||||
j = ptr[i]-1; if (j < 0) j += s->nblock;
|
||||
ll_i = s->unseqToSeq[block[j]];
|
||||
AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
|
||||
|
||||
if (yy[0] == ll_i) {
|
||||
zPend++;
|
||||
} else {
|
||||
|
||||
if (zPend > 0) {
|
||||
zPend--;
|
||||
while (True) {
|
||||
if (zPend & 1) {
|
||||
mtfv[wr] = BZ_RUNB; wr++;
|
||||
s->mtfFreq[BZ_RUNB]++;
|
||||
} else {
|
||||
mtfv[wr] = BZ_RUNA; wr++;
|
||||
s->mtfFreq[BZ_RUNA]++;
|
||||
}
|
||||
if (zPend < 2) break;
|
||||
zPend = (zPend - 2) / 2;
|
||||
};
|
||||
zPend = 0;
|
||||
}
|
||||
{
|
||||
register UChar rtmp;
|
||||
register UChar* ryy_j;
|
||||
register UChar rll_i;
|
||||
rtmp = yy[1];
|
||||
yy[1] = yy[0];
|
||||
ryy_j = &(yy[1]);
|
||||
rll_i = ll_i;
|
||||
while ( rll_i != rtmp ) {
|
||||
register UChar rtmp2;
|
||||
ryy_j++;
|
||||
rtmp2 = rtmp;
|
||||
rtmp = *ryy_j;
|
||||
*ryy_j = rtmp2;
|
||||
};
|
||||
yy[0] = rtmp;
|
||||
j = ryy_j - &(yy[0]);
|
||||
mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (zPend > 0) {
|
||||
zPend--;
|
||||
while (True) {
|
||||
if (zPend & 1) {
|
||||
mtfv[wr] = BZ_RUNB; wr++;
|
||||
s->mtfFreq[BZ_RUNB]++;
|
||||
} else {
|
||||
mtfv[wr] = BZ_RUNA; wr++;
|
||||
s->mtfFreq[BZ_RUNA]++;
|
||||
}
|
||||
if (zPend < 2) break;
|
||||
zPend = (zPend - 2) / 2;
|
||||
};
|
||||
zPend = 0;
|
||||
}
|
||||
|
||||
mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
|
||||
|
||||
s->nMTF = wr;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define BZ_LESSER_ICOST 0
|
||||
#define BZ_GREATER_ICOST 15
|
||||
|
||||
static
|
||||
void sendMTFValues ( EState* s )
|
||||
{
|
||||
Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
|
||||
Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
|
||||
Int32 nGroups, nBytes;
|
||||
|
||||
/*--
|
||||
UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
is a global since the decoder also needs it.
|
||||
|
||||
Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
|
||||
are also globals only used in this proc.
|
||||
Made global to keep stack frame size small.
|
||||
--*/
|
||||
|
||||
|
||||
UInt16 cost[BZ_N_GROUPS];
|
||||
Int32 fave[BZ_N_GROUPS];
|
||||
|
||||
UInt16* mtfv = s->mtfv;
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf3( " %d in block, %d after MTF & 1-2 coding, "
|
||||
"%d+2 syms in use\n",
|
||||
s->nblock, s->nMTF, s->nInUse );
|
||||
|
||||
alphaSize = s->nInUse+2;
|
||||
for (t = 0; t < BZ_N_GROUPS; t++)
|
||||
for (v = 0; v < alphaSize; v++)
|
||||
s->len[t][v] = BZ_GREATER_ICOST;
|
||||
|
||||
/*--- Decide how many coding tables to use ---*/
|
||||
AssertH ( s->nMTF > 0, 3001 );
|
||||
if (s->nMTF < 200) nGroups = 2; else
|
||||
if (s->nMTF < 600) nGroups = 3; else
|
||||
if (s->nMTF < 1200) nGroups = 4; else
|
||||
if (s->nMTF < 2400) nGroups = 5; else
|
||||
nGroups = 6;
|
||||
|
||||
/*--- Generate an initial set of coding tables ---*/
|
||||
{
|
||||
Int32 nPart, remF, tFreq, aFreq;
|
||||
|
||||
nPart = nGroups;
|
||||
remF = s->nMTF;
|
||||
gs = 0;
|
||||
while (nPart > 0) {
|
||||
tFreq = remF / nPart;
|
||||
ge = gs-1;
|
||||
aFreq = 0;
|
||||
while (aFreq < tFreq && ge < alphaSize-1) {
|
||||
ge++;
|
||||
aFreq += s->mtfFreq[ge];
|
||||
}
|
||||
|
||||
if (ge > gs
|
||||
&& nPart != nGroups && nPart != 1
|
||||
&& ((nGroups-nPart) % 2 == 1)) {
|
||||
aFreq -= s->mtfFreq[ge];
|
||||
ge--;
|
||||
}
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf5( " initial group %d, [%d .. %d], "
|
||||
"has %d syms (%4.1f%%)\n",
|
||||
nPart, gs, ge, aFreq,
|
||||
(100.0 * (float)aFreq) / (float)(s->nMTF) );
|
||||
|
||||
for (v = 0; v < alphaSize; v++)
|
||||
if (v >= gs && v <= ge)
|
||||
s->len[nPart-1][v] = BZ_LESSER_ICOST; else
|
||||
s->len[nPart-1][v] = BZ_GREATER_ICOST;
|
||||
|
||||
nPart--;
|
||||
gs = ge+1;
|
||||
remF -= aFreq;
|
||||
}
|
||||
}
|
||||
|
||||
/*---
|
||||
Iterate up to BZ_N_ITERS times to improve the tables.
|
||||
---*/
|
||||
for (iter = 0; iter < BZ_N_ITERS; iter++) {
|
||||
|
||||
for (t = 0; t < nGroups; t++) fave[t] = 0;
|
||||
|
||||
for (t = 0; t < nGroups; t++)
|
||||
for (v = 0; v < alphaSize; v++)
|
||||
s->rfreq[t][v] = 0;
|
||||
|
||||
/*---
|
||||
Set up an auxiliary length table which is used to fast-track
|
||||
the common case (nGroups == 6).
|
||||
---*/
|
||||
if (nGroups == 6) {
|
||||
for (v = 0; v < alphaSize; v++) {
|
||||
s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
|
||||
s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
|
||||
s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
|
||||
}
|
||||
}
|
||||
|
||||
nSelectors = 0;
|
||||
totc = 0;
|
||||
gs = 0;
|
||||
while (True) {
|
||||
|
||||
/*--- Set group start & end marks. --*/
|
||||
if (gs >= s->nMTF) break;
|
||||
ge = gs + BZ_G_SIZE - 1;
|
||||
if (ge >= s->nMTF) ge = s->nMTF-1;
|
||||
|
||||
/*--
|
||||
Calculate the cost of this group as coded
|
||||
by each of the coding tables.
|
||||
--*/
|
||||
for (t = 0; t < nGroups; t++) cost[t] = 0;
|
||||
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
/*--- fast track the common case ---*/
|
||||
register UInt32 cost01, cost23, cost45;
|
||||
register UInt16 icv;
|
||||
cost01 = cost23 = cost45 = 0;
|
||||
|
||||
# define BZ_ITER(nn) \
|
||||
icv = mtfv[gs+(nn)]; \
|
||||
cost01 += s->len_pack[icv][0]; \
|
||||
cost23 += s->len_pack[icv][1]; \
|
||||
cost45 += s->len_pack[icv][2]; \
|
||||
|
||||
BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
|
||||
BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
|
||||
BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
|
||||
BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
|
||||
BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
|
||||
BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
|
||||
BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
|
||||
BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
|
||||
BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
|
||||
BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
|
||||
|
||||
# undef BZ_ITER
|
||||
|
||||
cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
|
||||
cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
|
||||
cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
|
||||
|
||||
} else {
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
for (i = gs; i <= ge; i++) {
|
||||
UInt16 icv = mtfv[i];
|
||||
for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
|
||||
}
|
||||
}
|
||||
|
||||
/*--
|
||||
Find the coding table which is best for this group,
|
||||
and record its identity in the selector table.
|
||||
--*/
|
||||
bc = 999999999; bt = -1;
|
||||
for (t = 0; t < nGroups; t++)
|
||||
if (cost[t] < bc) { bc = cost[t]; bt = t; };
|
||||
totc += bc;
|
||||
fave[bt]++;
|
||||
s->selector[nSelectors] = bt;
|
||||
nSelectors++;
|
||||
|
||||
/*--
|
||||
Increment the symbol frequencies for the selected table.
|
||||
--*/
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
/*--- fast track the common case ---*/
|
||||
|
||||
# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
|
||||
|
||||
BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
|
||||
BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
|
||||
BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
|
||||
BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
|
||||
BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
|
||||
BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
|
||||
BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
|
||||
BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
|
||||
BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
|
||||
BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
|
||||
|
||||
# undef BZ_ITUR
|
||||
|
||||
} else {
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
for (i = gs; i <= ge; i++)
|
||||
s->rfreq[bt][ mtfv[i] ]++;
|
||||
}
|
||||
|
||||
gs = ge+1;
|
||||
}
|
||||
if (s->verbosity >= 3) {
|
||||
VPrintf2 ( " pass %d: size is %d, grp uses are ",
|
||||
iter+1, totc/8 );
|
||||
for (t = 0; t < nGroups; t++)
|
||||
VPrintf1 ( "%d ", fave[t] );
|
||||
VPrintf0 ( "\n" );
|
||||
}
|
||||
|
||||
/*--
|
||||
Recompute the tables based on the accumulated frequencies.
|
||||
--*/
|
||||
/* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
|
||||
comment in huffman.c for details. */
|
||||
for (t = 0; t < nGroups; t++)
|
||||
BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
|
||||
alphaSize, 17 /*20*/ );
|
||||
}
|
||||
|
||||
|
||||
AssertH( nGroups < 8, 3002 );
|
||||
AssertH( nSelectors < 32768 &&
|
||||
nSelectors <= (2 + (900000 / BZ_G_SIZE)),
|
||||
3003 );
|
||||
|
||||
|
||||
/*--- Compute MTF values for the selectors. ---*/
|
||||
{
|
||||
UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
|
||||
for (i = 0; i < nGroups; i++) pos[i] = i;
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
ll_i = s->selector[i];
|
||||
j = 0;
|
||||
tmp = pos[j];
|
||||
while ( ll_i != tmp ) {
|
||||
j++;
|
||||
tmp2 = tmp;
|
||||
tmp = pos[j];
|
||||
pos[j] = tmp2;
|
||||
};
|
||||
pos[0] = tmp;
|
||||
s->selectorMtf[i] = j;
|
||||
}
|
||||
};
|
||||
|
||||
/*--- Assign actual codes for the tables. --*/
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
minLen = 32;
|
||||
maxLen = 0;
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
|
||||
if (s->len[t][i] < minLen) minLen = s->len[t][i];
|
||||
}
|
||||
AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
|
||||
AssertH ( !(minLen < 1), 3005 );
|
||||
BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
|
||||
minLen, maxLen, alphaSize );
|
||||
}
|
||||
|
||||
/*--- Transmit the mapping table. ---*/
|
||||
{
|
||||
Bool inUse16[16];
|
||||
for (i = 0; i < 16; i++) {
|
||||
inUse16[i] = False;
|
||||
for (j = 0; j < 16; j++)
|
||||
if (s->inUse[i * 16 + j]) inUse16[i] = True;
|
||||
}
|
||||
|
||||
nBytes = s->numZ;
|
||||
for (i = 0; i < 16; i++)
|
||||
if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
if (inUse16[i])
|
||||
for (j = 0; j < 16; j++) {
|
||||
if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
|
||||
}
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes );
|
||||
}
|
||||
|
||||
/*--- Now the selectors. ---*/
|
||||
nBytes = s->numZ;
|
||||
bsW ( s, 3, nGroups );
|
||||
bsW ( s, 15, nSelectors );
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
|
||||
bsW(s,1,0);
|
||||
}
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf1( "selectors %d, ", s->numZ-nBytes );
|
||||
|
||||
/*--- Now the coding tables. ---*/
|
||||
nBytes = s->numZ;
|
||||
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
Int32 curr = s->len[t][0];
|
||||
bsW ( s, 5, curr );
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
|
||||
while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
|
||||
bsW ( s, 1, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
|
||||
|
||||
/*--- And finally, the block data proper ---*/
|
||||
nBytes = s->numZ;
|
||||
selCtr = 0;
|
||||
gs = 0;
|
||||
while (True) {
|
||||
if (gs >= s->nMTF) break;
|
||||
ge = gs + BZ_G_SIZE - 1;
|
||||
if (ge >= s->nMTF) ge = s->nMTF-1;
|
||||
AssertH ( s->selector[selCtr] < nGroups, 3006 );
|
||||
|
||||
if (nGroups == 6 && 50 == ge-gs+1) {
|
||||
/*--- fast track the common case ---*/
|
||||
UInt16 mtfv_i;
|
||||
UChar* s_len_sel_selCtr
|
||||
= &(s->len[s->selector[selCtr]][0]);
|
||||
Int32* s_code_sel_selCtr
|
||||
= &(s->code[s->selector[selCtr]][0]);
|
||||
|
||||
# define BZ_ITAH(nn) \
|
||||
mtfv_i = mtfv[gs+(nn)]; \
|
||||
bsW ( s, \
|
||||
s_len_sel_selCtr[mtfv_i], \
|
||||
s_code_sel_selCtr[mtfv_i] )
|
||||
|
||||
BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
|
||||
BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
|
||||
BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
|
||||
BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
|
||||
BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
|
||||
BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
|
||||
BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
|
||||
BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
|
||||
BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
|
||||
BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
|
||||
|
||||
# undef BZ_ITAH
|
||||
|
||||
} else {
|
||||
/*--- slow version which correctly handles all situations ---*/
|
||||
for (i = gs; i <= ge; i++) {
|
||||
bsW ( s,
|
||||
s->len [s->selector[selCtr]] [mtfv[i]],
|
||||
s->code [s->selector[selCtr]] [mtfv[i]] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gs = ge+1;
|
||||
selCtr++;
|
||||
}
|
||||
AssertH( selCtr == nSelectors, 3007 );
|
||||
|
||||
if (s->verbosity >= 3)
|
||||
VPrintf1( "codes %d\n", s->numZ-nBytes );
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
extern void BZ2_compressBlock ( EState* s, Bool is_last_block )
|
||||
{
|
||||
if (s->nblock > 0) {
|
||||
|
||||
BZ_FINALISE_CRC ( s->blockCRC );
|
||||
s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
|
||||
s->combinedCRC ^= s->blockCRC;
|
||||
if (s->blockNo > 1) s->numZ = 0;
|
||||
|
||||
if (s->verbosity >= 2)
|
||||
VPrintf4( " block %d: crc = 0x%08x, "
|
||||
"combined CRC = 0x%08x, size = %d\n",
|
||||
s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
|
||||
|
||||
BZ2_blockSort ( s );
|
||||
}
|
||||
|
||||
s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
|
||||
|
||||
/*-- If this is the first block, create the stream header. --*/
|
||||
if (s->blockNo == 1) {
|
||||
BZ2_bsInitWrite ( s );
|
||||
bsPutUChar ( s, BZ_HDR_B );
|
||||
bsPutUChar ( s, BZ_HDR_Z );
|
||||
bsPutUChar ( s, BZ_HDR_h );
|
||||
bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
|
||||
}
|
||||
|
||||
if (s->nblock > 0) {
|
||||
|
||||
bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
|
||||
bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
|
||||
bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
|
||||
|
||||
/*-- Now the block's CRC, so it is in a known place. --*/
|
||||
bsPutUInt32 ( s, s->blockCRC );
|
||||
|
||||
/*--
|
||||
Now a single bit indicating (non-)randomisation.
|
||||
As of version 0.9.5, we use a better sorting algorithm
|
||||
which makes randomisation unnecessary. So always set
|
||||
the randomised bit to 'no'. Of course, the decoder
|
||||
still needs to be able to handle randomised blocks
|
||||
so as to maintain backwards compatibility with
|
||||
older versions of bzip2.
|
||||
--*/
|
||||
bsW(s,1,0);
|
||||
|
||||
bsW ( s, 24, s->origPtr );
|
||||
generateMTFValues ( s );
|
||||
sendMTFValues ( s );
|
||||
}
|
||||
|
||||
|
||||
/*-- If this is the last block, add the stream trailer. --*/
|
||||
if (is_last_block) {
|
||||
|
||||
bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
|
||||
bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
|
||||
bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
|
||||
bsPutUInt32 ( s, s->combinedCRC );
|
||||
if (s->verbosity >= 2)
|
||||
VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
|
||||
bsFinishWrite ( s );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end compress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Table for doing CRCs ---*/
|
||||
/*--- crctable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
/*--
|
||||
I think this is an implementation of the AUTODIN-II,
|
||||
Ethernet & FDDI 32-bit CRC standard. Vaguely derived
|
||||
from code by Rob Warnock, in Section 51 of the
|
||||
comp.compression FAQ.
|
||||
--*/
|
||||
|
||||
UInt32 BZ2_crc32Table[256] = {
|
||||
|
||||
/*-- Ugly, innit? --*/
|
||||
|
||||
0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
|
||||
0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
|
||||
0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
|
||||
0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
|
||||
0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
|
||||
0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
|
||||
0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
|
||||
0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
|
||||
0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
|
||||
0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
|
||||
0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
|
||||
0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
|
||||
0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
|
||||
0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
|
||||
0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
|
||||
0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
|
||||
0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
|
||||
0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
|
||||
0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
|
||||
0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
|
||||
0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
|
||||
0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
|
||||
0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
|
||||
0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
|
||||
0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
|
||||
0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
|
||||
0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
|
||||
0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
|
||||
0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
|
||||
0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
|
||||
0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
|
||||
0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
|
||||
0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
|
||||
0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
|
||||
0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
|
||||
0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
|
||||
0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
|
||||
0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
|
||||
0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
|
||||
0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
|
||||
0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
|
||||
0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
|
||||
0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
|
||||
0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
|
||||
0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
|
||||
0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
|
||||
0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
|
||||
0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
|
||||
0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
|
||||
0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
|
||||
0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
|
||||
0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
|
||||
0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
|
||||
0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
|
||||
0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
|
||||
0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
|
||||
0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
|
||||
0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
|
||||
0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
|
||||
0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
|
||||
0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
|
||||
0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
|
||||
0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
|
||||
0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end crctable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
+646
@@ -0,0 +1,646 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Decompression machinery ---*/
|
||||
/*--- decompress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
static
|
||||
void makeMaps_d ( DState* s )
|
||||
{
|
||||
Int32 i;
|
||||
s->nInUse = 0;
|
||||
for (i = 0; i < 256; i++)
|
||||
if (s->inUse[i]) {
|
||||
s->seqToUnseq[s->nInUse] = i;
|
||||
s->nInUse++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define RETURN(rrr) \
|
||||
{ retVal = rrr; goto save_state_and_return; };
|
||||
|
||||
#define GET_BITS(lll,vvv,nnn) \
|
||||
case lll: s->state = lll; \
|
||||
while (True) { \
|
||||
if (s->bsLive >= nnn) { \
|
||||
UInt32 v; \
|
||||
v = (s->bsBuff >> \
|
||||
(s->bsLive-nnn)) & ((1 << nnn)-1); \
|
||||
s->bsLive -= nnn; \
|
||||
vvv = v; \
|
||||
break; \
|
||||
} \
|
||||
if (s->strm->avail_in == 0) RETURN(BZ_OK); \
|
||||
s->bsBuff \
|
||||
= (s->bsBuff << 8) | \
|
||||
((UInt32) \
|
||||
(*((UChar*)(s->strm->next_in)))); \
|
||||
s->bsLive += 8; \
|
||||
s->strm->next_in++; \
|
||||
s->strm->avail_in--; \
|
||||
s->strm->total_in_lo32++; \
|
||||
if (s->strm->total_in_lo32 == 0) \
|
||||
s->strm->total_in_hi32++; \
|
||||
}
|
||||
|
||||
#define GET_UCHAR(lll,uuu) \
|
||||
GET_BITS(lll,uuu,8)
|
||||
|
||||
#define GET_BIT(lll,uuu) \
|
||||
GET_BITS(lll,uuu,1)
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define GET_MTF_VAL(label1,label2,lval) \
|
||||
{ \
|
||||
if (groupPos == 0) { \
|
||||
groupNo++; \
|
||||
if (groupNo >= nSelectors) \
|
||||
RETURN(BZ_DATA_ERROR); \
|
||||
groupPos = BZ_G_SIZE; \
|
||||
gSel = s->selector[groupNo]; \
|
||||
gMinlen = s->minLens[gSel]; \
|
||||
gLimit = &(s->limit[gSel][0]); \
|
||||
gPerm = &(s->perm[gSel][0]); \
|
||||
gBase = &(s->base[gSel][0]); \
|
||||
} \
|
||||
groupPos--; \
|
||||
zn = gMinlen; \
|
||||
GET_BITS(label1, zvec, zn); \
|
||||
while (1) { \
|
||||
if (zn > 20 /* the longest code */) \
|
||||
RETURN(BZ_DATA_ERROR); \
|
||||
if (zvec <= gLimit[zn]) break; \
|
||||
zn++; \
|
||||
GET_BIT(label2, zj); \
|
||||
zvec = (zvec << 1) | zj; \
|
||||
}; \
|
||||
if (zvec - gBase[zn] < 0 \
|
||||
|| zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
|
||||
RETURN(BZ_DATA_ERROR); \
|
||||
lval = gPerm[zvec - gBase[zn]]; \
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
Int32 BZ2_decompress ( DState* s )
|
||||
{
|
||||
UChar uc;
|
||||
Int32 retVal;
|
||||
Int32 minLen, maxLen;
|
||||
bz_stream* strm = s->strm;
|
||||
|
||||
/* stuff that needs to be saved/restored */
|
||||
Int32 i;
|
||||
Int32 j;
|
||||
Int32 t;
|
||||
Int32 alphaSize;
|
||||
Int32 nGroups;
|
||||
Int32 nSelectors;
|
||||
Int32 EOB;
|
||||
Int32 groupNo;
|
||||
Int32 groupPos;
|
||||
Int32 nextSym;
|
||||
Int32 nblockMAX;
|
||||
Int32 nblock;
|
||||
Int32 es;
|
||||
Int32 N;
|
||||
Int32 curr;
|
||||
Int32 zt;
|
||||
Int32 zn;
|
||||
Int32 zvec;
|
||||
Int32 zj;
|
||||
Int32 gSel;
|
||||
Int32 gMinlen;
|
||||
Int32* gLimit;
|
||||
Int32* gBase;
|
||||
Int32* gPerm;
|
||||
|
||||
if (s->state == BZ_X_MAGIC_1) {
|
||||
/*initialise the save area*/
|
||||
s->save_i = 0;
|
||||
s->save_j = 0;
|
||||
s->save_t = 0;
|
||||
s->save_alphaSize = 0;
|
||||
s->save_nGroups = 0;
|
||||
s->save_nSelectors = 0;
|
||||
s->save_EOB = 0;
|
||||
s->save_groupNo = 0;
|
||||
s->save_groupPos = 0;
|
||||
s->save_nextSym = 0;
|
||||
s->save_nblockMAX = 0;
|
||||
s->save_nblock = 0;
|
||||
s->save_es = 0;
|
||||
s->save_N = 0;
|
||||
s->save_curr = 0;
|
||||
s->save_zt = 0;
|
||||
s->save_zn = 0;
|
||||
s->save_zvec = 0;
|
||||
s->save_zj = 0;
|
||||
s->save_gSel = 0;
|
||||
s->save_gMinlen = 0;
|
||||
s->save_gLimit = NULL;
|
||||
s->save_gBase = NULL;
|
||||
s->save_gPerm = NULL;
|
||||
}
|
||||
|
||||
/*restore from the save area*/
|
||||
i = s->save_i;
|
||||
j = s->save_j;
|
||||
t = s->save_t;
|
||||
alphaSize = s->save_alphaSize;
|
||||
nGroups = s->save_nGroups;
|
||||
nSelectors = s->save_nSelectors;
|
||||
EOB = s->save_EOB;
|
||||
groupNo = s->save_groupNo;
|
||||
groupPos = s->save_groupPos;
|
||||
nextSym = s->save_nextSym;
|
||||
nblockMAX = s->save_nblockMAX;
|
||||
nblock = s->save_nblock;
|
||||
es = s->save_es;
|
||||
N = s->save_N;
|
||||
curr = s->save_curr;
|
||||
zt = s->save_zt;
|
||||
zn = s->save_zn;
|
||||
zvec = s->save_zvec;
|
||||
zj = s->save_zj;
|
||||
gSel = s->save_gSel;
|
||||
gMinlen = s->save_gMinlen;
|
||||
gLimit = s->save_gLimit;
|
||||
gBase = s->save_gBase;
|
||||
gPerm = s->save_gPerm;
|
||||
|
||||
retVal = BZ_OK;
|
||||
|
||||
switch (s->state) {
|
||||
|
||||
GET_UCHAR(BZ_X_MAGIC_1, uc);
|
||||
if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
|
||||
|
||||
GET_UCHAR(BZ_X_MAGIC_2, uc);
|
||||
if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
|
||||
|
||||
GET_UCHAR(BZ_X_MAGIC_3, uc)
|
||||
if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
|
||||
|
||||
GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
|
||||
if (s->blockSize100k < (BZ_HDR_0 + 1) ||
|
||||
s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
|
||||
s->blockSize100k -= BZ_HDR_0;
|
||||
|
||||
if (s->smallDecompress) {
|
||||
s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
|
||||
s->ll4 = BZALLOC(
|
||||
((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
|
||||
);
|
||||
if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
|
||||
} else {
|
||||
s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
|
||||
if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
|
||||
}
|
||||
|
||||
GET_UCHAR(BZ_X_BLKHDR_1, uc);
|
||||
|
||||
if (uc == 0x17) goto endhdr_2;
|
||||
if (uc != 0x31) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_2, uc);
|
||||
if (uc != 0x41) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_3, uc);
|
||||
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_4, uc);
|
||||
if (uc != 0x26) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_5, uc);
|
||||
if (uc != 0x53) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_BLKHDR_6, uc);
|
||||
if (uc != 0x59) RETURN(BZ_DATA_ERROR);
|
||||
|
||||
s->currBlockNo++;
|
||||
if (s->verbosity >= 2)
|
||||
VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
|
||||
|
||||
s->storedBlockCRC = 0;
|
||||
GET_UCHAR(BZ_X_BCRC_1, uc);
|
||||
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_BCRC_2, uc);
|
||||
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_BCRC_3, uc);
|
||||
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_BCRC_4, uc);
|
||||
s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
|
||||
|
||||
GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
|
||||
|
||||
s->origPtr = 0;
|
||||
GET_UCHAR(BZ_X_ORIGPTR_1, uc);
|
||||
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
|
||||
GET_UCHAR(BZ_X_ORIGPTR_2, uc);
|
||||
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
|
||||
GET_UCHAR(BZ_X_ORIGPTR_3, uc);
|
||||
s->origPtr = (s->origPtr << 8) | ((Int32)uc);
|
||||
|
||||
if (s->origPtr < 0)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
if (s->origPtr > 10 + 100000*s->blockSize100k)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
|
||||
/*--- Receive the mapping table ---*/
|
||||
for (i = 0; i < 16; i++) {
|
||||
GET_BIT(BZ_X_MAPPING_1, uc);
|
||||
if (uc == 1)
|
||||
s->inUse16[i] = True; else
|
||||
s->inUse16[i] = False;
|
||||
}
|
||||
|
||||
for (i = 0; i < 256; i++) s->inUse[i] = False;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
if (s->inUse16[i])
|
||||
for (j = 0; j < 16; j++) {
|
||||
GET_BIT(BZ_X_MAPPING_2, uc);
|
||||
if (uc == 1) s->inUse[i * 16 + j] = True;
|
||||
}
|
||||
makeMaps_d ( s );
|
||||
if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
|
||||
alphaSize = s->nInUse+2;
|
||||
|
||||
/*--- Now the selectors ---*/
|
||||
GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
|
||||
if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
|
||||
GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
|
||||
if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
j = 0;
|
||||
while (True) {
|
||||
GET_BIT(BZ_X_SELECTOR_3, uc);
|
||||
if (uc == 0) break;
|
||||
j++;
|
||||
if (j >= nGroups) RETURN(BZ_DATA_ERROR);
|
||||
}
|
||||
s->selectorMtf[i] = j;
|
||||
}
|
||||
|
||||
/*--- Undo the MTF values for the selectors. ---*/
|
||||
{
|
||||
UChar pos[BZ_N_GROUPS], tmp, v;
|
||||
for (v = 0; v < nGroups; v++) pos[v] = v;
|
||||
|
||||
for (i = 0; i < nSelectors; i++) {
|
||||
v = s->selectorMtf[i];
|
||||
tmp = pos[v];
|
||||
while (v > 0) { pos[v] = pos[v-1]; v--; }
|
||||
pos[0] = tmp;
|
||||
s->selector[i] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/*--- Now the coding tables ---*/
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
GET_BITS(BZ_X_CODING_1, curr, 5);
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
while (True) {
|
||||
if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
|
||||
GET_BIT(BZ_X_CODING_2, uc);
|
||||
if (uc == 0) break;
|
||||
GET_BIT(BZ_X_CODING_3, uc);
|
||||
if (uc == 0) curr++; else curr--;
|
||||
}
|
||||
s->len[t][i] = curr;
|
||||
}
|
||||
}
|
||||
|
||||
/*--- Create the Huffman decoding tables ---*/
|
||||
for (t = 0; t < nGroups; t++) {
|
||||
minLen = 32;
|
||||
maxLen = 0;
|
||||
for (i = 0; i < alphaSize; i++) {
|
||||
if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
|
||||
if (s->len[t][i] < minLen) minLen = s->len[t][i];
|
||||
}
|
||||
BZ2_hbCreateDecodeTables (
|
||||
&(s->limit[t][0]),
|
||||
&(s->base[t][0]),
|
||||
&(s->perm[t][0]),
|
||||
&(s->len[t][0]),
|
||||
minLen, maxLen, alphaSize
|
||||
);
|
||||
s->minLens[t] = minLen;
|
||||
}
|
||||
|
||||
/*--- Now the MTF values ---*/
|
||||
|
||||
EOB = s->nInUse+1;
|
||||
nblockMAX = 100000 * s->blockSize100k;
|
||||
groupNo = -1;
|
||||
groupPos = 0;
|
||||
|
||||
for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
|
||||
|
||||
/*-- MTF init --*/
|
||||
{
|
||||
Int32 ii, jj, kk;
|
||||
kk = MTFA_SIZE-1;
|
||||
for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
|
||||
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
|
||||
s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
|
||||
kk--;
|
||||
}
|
||||
s->mtfbase[ii] = kk + 1;
|
||||
}
|
||||
}
|
||||
/*-- end MTF init --*/
|
||||
|
||||
nblock = 0;
|
||||
GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
|
||||
|
||||
while (True) {
|
||||
|
||||
if (nextSym == EOB) break;
|
||||
|
||||
if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
|
||||
|
||||
es = -1;
|
||||
N = 1;
|
||||
do {
|
||||
/* Check that N doesn't get too big, so that es doesn't
|
||||
go negative. The maximum value that can be
|
||||
RUNA/RUNB encoded is equal to the block size (post
|
||||
the initial RLE), viz, 900k, so bounding N at 2
|
||||
million should guard against overflow without
|
||||
rejecting any legitimate inputs. */
|
||||
if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
|
||||
if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
|
||||
if (nextSym == BZ_RUNB) es = es + (1+1) * N;
|
||||
N = N * 2;
|
||||
GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
|
||||
}
|
||||
while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
|
||||
|
||||
es++;
|
||||
uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
|
||||
s->unzftab[uc] += es;
|
||||
|
||||
if (s->smallDecompress)
|
||||
while (es > 0) {
|
||||
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
s->ll16[nblock] = (UInt16)uc;
|
||||
nblock++;
|
||||
es--;
|
||||
}
|
||||
else
|
||||
while (es > 0) {
|
||||
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
s->tt[nblock] = (UInt32)uc;
|
||||
nblock++;
|
||||
es--;
|
||||
};
|
||||
|
||||
continue;
|
||||
|
||||
} else {
|
||||
|
||||
if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
|
||||
|
||||
/*-- uc = MTF ( nextSym-1 ) --*/
|
||||
{
|
||||
Int32 ii, jj, kk, pp, lno, off;
|
||||
UInt32 nn;
|
||||
nn = (UInt32)(nextSym - 1);
|
||||
|
||||
if (nn < MTFL_SIZE) {
|
||||
/* avoid general-case expense */
|
||||
pp = s->mtfbase[0];
|
||||
uc = s->mtfa[pp+nn];
|
||||
while (nn > 3) {
|
||||
Int32 z = pp+nn;
|
||||
s->mtfa[(z) ] = s->mtfa[(z)-1];
|
||||
s->mtfa[(z)-1] = s->mtfa[(z)-2];
|
||||
s->mtfa[(z)-2] = s->mtfa[(z)-3];
|
||||
s->mtfa[(z)-3] = s->mtfa[(z)-4];
|
||||
nn -= 4;
|
||||
}
|
||||
while (nn > 0) {
|
||||
s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
|
||||
};
|
||||
s->mtfa[pp] = uc;
|
||||
} else {
|
||||
/* general case */
|
||||
lno = nn / MTFL_SIZE;
|
||||
off = nn % MTFL_SIZE;
|
||||
pp = s->mtfbase[lno] + off;
|
||||
uc = s->mtfa[pp];
|
||||
while (pp > s->mtfbase[lno]) {
|
||||
s->mtfa[pp] = s->mtfa[pp-1]; pp--;
|
||||
};
|
||||
s->mtfbase[lno]++;
|
||||
while (lno > 0) {
|
||||
s->mtfbase[lno]--;
|
||||
s->mtfa[s->mtfbase[lno]]
|
||||
= s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
|
||||
lno--;
|
||||
}
|
||||
s->mtfbase[0]--;
|
||||
s->mtfa[s->mtfbase[0]] = uc;
|
||||
if (s->mtfbase[0] == 0) {
|
||||
kk = MTFA_SIZE-1;
|
||||
for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
|
||||
for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
|
||||
s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
|
||||
kk--;
|
||||
}
|
||||
s->mtfbase[ii] = kk + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-- end uc = MTF ( nextSym-1 ) --*/
|
||||
|
||||
s->unzftab[s->seqToUnseq[uc]]++;
|
||||
if (s->smallDecompress)
|
||||
s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
|
||||
s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
|
||||
nblock++;
|
||||
|
||||
GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we know what nblock is, we can do a better sanity
|
||||
check on s->origPtr.
|
||||
*/
|
||||
if (s->origPtr < 0 || s->origPtr >= nblock)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
|
||||
/*-- Set up cftab to facilitate generation of T^(-1) --*/
|
||||
/* Check: unzftab entries in range. */
|
||||
for (i = 0; i <= 255; i++) {
|
||||
if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
}
|
||||
/* Actually generate cftab. */
|
||||
s->cftab[0] = 0;
|
||||
for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
|
||||
for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
|
||||
/* Check: cftab entries in range. */
|
||||
for (i = 0; i <= 256; i++) {
|
||||
if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
|
||||
/* s->cftab[i] can legitimately be == nblock */
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
}
|
||||
}
|
||||
/* Check: cftab entries non-descending. */
|
||||
for (i = 1; i <= 256; i++) {
|
||||
if (s->cftab[i-1] > s->cftab[i]) {
|
||||
RETURN(BZ_DATA_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
s->state_out_len = 0;
|
||||
s->state_out_ch = 0;
|
||||
BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
|
||||
s->state = BZ_X_OUTPUT;
|
||||
if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
|
||||
|
||||
if (s->smallDecompress) {
|
||||
|
||||
/*-- Make a copy of cftab, used in generation of T --*/
|
||||
for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
|
||||
|
||||
/*-- compute the T vector --*/
|
||||
for (i = 0; i < nblock; i++) {
|
||||
uc = (UChar)(s->ll16[i]);
|
||||
SET_LL(i, s->cftabCopy[uc]);
|
||||
s->cftabCopy[uc]++;
|
||||
}
|
||||
|
||||
/*-- Compute T^(-1) by pointer reversal on T --*/
|
||||
i = s->origPtr;
|
||||
j = GET_LL(i);
|
||||
do {
|
||||
Int32 tmp = GET_LL(j);
|
||||
SET_LL(j, i);
|
||||
i = j;
|
||||
j = tmp;
|
||||
}
|
||||
while (i != s->origPtr);
|
||||
|
||||
s->tPos = s->origPtr;
|
||||
s->nblock_used = 0;
|
||||
if (s->blockRandomised) {
|
||||
BZ_RAND_INIT_MASK;
|
||||
BZ_GET_SMALL(s->k0); s->nblock_used++;
|
||||
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
|
||||
} else {
|
||||
BZ_GET_SMALL(s->k0); s->nblock_used++;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/*-- compute the T^(-1) vector --*/
|
||||
for (i = 0; i < nblock; i++) {
|
||||
uc = (UChar)(s->tt[i] & 0xff);
|
||||
s->tt[s->cftab[uc]] |= (i << 8);
|
||||
s->cftab[uc]++;
|
||||
}
|
||||
|
||||
s->tPos = s->tt[s->origPtr] >> 8;
|
||||
s->nblock_used = 0;
|
||||
if (s->blockRandomised) {
|
||||
BZ_RAND_INIT_MASK;
|
||||
BZ_GET_FAST(s->k0); s->nblock_used++;
|
||||
BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
|
||||
} else {
|
||||
BZ_GET_FAST(s->k0); s->nblock_used++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RETURN(BZ_OK);
|
||||
|
||||
|
||||
|
||||
endhdr_2:
|
||||
|
||||
GET_UCHAR(BZ_X_ENDHDR_2, uc);
|
||||
if (uc != 0x72) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_ENDHDR_3, uc);
|
||||
if (uc != 0x45) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_ENDHDR_4, uc);
|
||||
if (uc != 0x38) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_ENDHDR_5, uc);
|
||||
if (uc != 0x50) RETURN(BZ_DATA_ERROR);
|
||||
GET_UCHAR(BZ_X_ENDHDR_6, uc);
|
||||
if (uc != 0x90) RETURN(BZ_DATA_ERROR);
|
||||
|
||||
s->storedCombinedCRC = 0;
|
||||
GET_UCHAR(BZ_X_CCRC_1, uc);
|
||||
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_CCRC_2, uc);
|
||||
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_CCRC_3, uc);
|
||||
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
|
||||
GET_UCHAR(BZ_X_CCRC_4, uc);
|
||||
s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
|
||||
|
||||
s->state = BZ_X_IDLE;
|
||||
RETURN(BZ_STREAM_END);
|
||||
|
||||
default: AssertH ( False, 4001 );
|
||||
}
|
||||
|
||||
AssertH ( False, 4002 );
|
||||
|
||||
save_state_and_return:
|
||||
|
||||
s->save_i = i;
|
||||
s->save_j = j;
|
||||
s->save_t = t;
|
||||
s->save_alphaSize = alphaSize;
|
||||
s->save_nGroups = nGroups;
|
||||
s->save_nSelectors = nSelectors;
|
||||
s->save_EOB = EOB;
|
||||
s->save_groupNo = groupNo;
|
||||
s->save_groupPos = groupPos;
|
||||
s->save_nextSym = nextSym;
|
||||
s->save_nblockMAX = nblockMAX;
|
||||
s->save_nblock = nblock;
|
||||
s->save_es = es;
|
||||
s->save_N = N;
|
||||
s->save_curr = curr;
|
||||
s->save_zt = zt;
|
||||
s->save_zn = zn;
|
||||
s->save_zvec = zvec;
|
||||
s->save_zj = zj;
|
||||
s->save_gSel = gSel;
|
||||
s->save_gMinlen = gMinlen;
|
||||
s->save_gLimit = gLimit;
|
||||
s->save_gBase = gBase;
|
||||
s->save_gPerm = gPerm;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end decompress.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Huffman coding low-level stuff ---*/
|
||||
/*--- huffman.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
#define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
|
||||
#define DEPTHOF(zz1) ((zz1) & 0x000000ff)
|
||||
#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
|
||||
|
||||
#define ADDWEIGHTS(zw1,zw2) \
|
||||
(WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
|
||||
(1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
|
||||
|
||||
#define UPHEAP(z) \
|
||||
{ \
|
||||
Int32 zz, tmp; \
|
||||
zz = z; tmp = heap[zz]; \
|
||||
while (weight[tmp] < weight[heap[zz >> 1]]) { \
|
||||
heap[zz] = heap[zz >> 1]; \
|
||||
zz >>= 1; \
|
||||
} \
|
||||
heap[zz] = tmp; \
|
||||
}
|
||||
|
||||
#define DOWNHEAP(z) \
|
||||
{ \
|
||||
Int32 zz, yy, tmp; \
|
||||
zz = z; tmp = heap[zz]; \
|
||||
while (True) { \
|
||||
yy = zz << 1; \
|
||||
if (yy > nHeap) break; \
|
||||
if (yy < nHeap && \
|
||||
weight[heap[yy+1]] < weight[heap[yy]]) \
|
||||
yy++; \
|
||||
if (weight[tmp] < weight[heap[yy]]) break; \
|
||||
heap[zz] = heap[yy]; \
|
||||
zz = yy; \
|
||||
} \
|
||||
heap[zz] = tmp; \
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbMakeCodeLengths ( UChar *len,
|
||||
Int32 *freq,
|
||||
Int32 alphaSize,
|
||||
Int32 maxLen )
|
||||
{
|
||||
/*--
|
||||
Nodes and heap entries run from 1. Entry 0
|
||||
for both the heap and nodes is a sentinel.
|
||||
--*/
|
||||
Int32 nNodes, nHeap, n1, n2, i, j, k;
|
||||
Bool tooLong;
|
||||
|
||||
Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
|
||||
Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
|
||||
Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
|
||||
|
||||
for (i = 0; i < alphaSize; i++)
|
||||
weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
|
||||
|
||||
while (True) {
|
||||
|
||||
nNodes = alphaSize;
|
||||
nHeap = 0;
|
||||
|
||||
heap[0] = 0;
|
||||
weight[0] = 0;
|
||||
parent[0] = -2;
|
||||
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
parent[i] = -1;
|
||||
nHeap++;
|
||||
heap[nHeap] = i;
|
||||
UPHEAP(nHeap);
|
||||
}
|
||||
|
||||
AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
|
||||
|
||||
while (nHeap > 1) {
|
||||
n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
|
||||
n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
|
||||
nNodes++;
|
||||
parent[n1] = parent[n2] = nNodes;
|
||||
weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
|
||||
parent[nNodes] = -1;
|
||||
nHeap++;
|
||||
heap[nHeap] = nNodes;
|
||||
UPHEAP(nHeap);
|
||||
}
|
||||
|
||||
AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
|
||||
|
||||
tooLong = False;
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
j = 0;
|
||||
k = i;
|
||||
while (parent[k] >= 0) { k = parent[k]; j++; }
|
||||
len[i-1] = j;
|
||||
if (j > maxLen) tooLong = True;
|
||||
}
|
||||
|
||||
if (! tooLong) break;
|
||||
|
||||
/* 17 Oct 04: keep-going condition for the following loop used
|
||||
to be 'i < alphaSize', which missed the last element,
|
||||
theoretically leading to the possibility of the compressor
|
||||
looping. However, this count-scaling step is only needed if
|
||||
one of the generated Huffman code words is longer than
|
||||
maxLen, which up to and including version 1.0.2 was 20 bits,
|
||||
which is extremely unlikely. In version 1.0.3 maxLen was
|
||||
changed to 17 bits, which has minimal effect on compression
|
||||
ratio, but does mean this scaling step is used from time to
|
||||
time, enough to verify that it works.
|
||||
|
||||
This means that bzip2-1.0.3 and later will only produce
|
||||
Huffman codes with a maximum length of 17 bits. However, in
|
||||
order to preserve backwards compatibility with bitstreams
|
||||
produced by versions pre-1.0.3, the decompressor must still
|
||||
handle lengths of up to 20. */
|
||||
|
||||
for (i = 1; i <= alphaSize; i++) {
|
||||
j = weight[i] >> 8;
|
||||
j = 1 + (j / 2);
|
||||
weight[i] = j << 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbAssignCodes ( Int32 *code,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
{
|
||||
Int32 n, vec, i;
|
||||
|
||||
vec = 0;
|
||||
for (n = minLen; n <= maxLen; n++) {
|
||||
for (i = 0; i < alphaSize; i++)
|
||||
if (length[i] == n) { code[i] = vec; vec++; };
|
||||
vec <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------*/
|
||||
void BZ2_hbCreateDecodeTables ( Int32 *limit,
|
||||
Int32 *base,
|
||||
Int32 *perm,
|
||||
UChar *length,
|
||||
Int32 minLen,
|
||||
Int32 maxLen,
|
||||
Int32 alphaSize )
|
||||
{
|
||||
Int32 pp, i, j, vec;
|
||||
|
||||
pp = 0;
|
||||
for (i = minLen; i <= maxLen; i++)
|
||||
for (j = 0; j < alphaSize; j++)
|
||||
if (length[j] == i) { perm[pp] = j; pp++; };
|
||||
|
||||
for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
|
||||
for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
|
||||
|
||||
for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
|
||||
|
||||
for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
|
||||
vec = 0;
|
||||
|
||||
for (i = minLen; i <= maxLen; i++) {
|
||||
vec += (base[i+1] - base[i]);
|
||||
limit[i] = vec-1;
|
||||
vec <<= 1;
|
||||
}
|
||||
for (i = minLen + 1; i <= maxLen; i++)
|
||||
base[i] = ((limit[i-1] + 1) << 1) - base[i];
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end huffman.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- Table for randomising repetitive blocks ---*/
|
||||
/*--- randtable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
This file is part of bzip2/libbzip2, a program and library for
|
||||
lossless, block-sorting data compression.
|
||||
|
||||
bzip2/libbzip2 version 1.0.6 of 6 September 2010
|
||||
Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
|
||||
|
||||
Please read the WARNING, DISCLAIMER and PATENTS sections in the
|
||||
README file.
|
||||
|
||||
This program is released under the terms of the license contained
|
||||
in the file LICENSE.
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
|
||||
#include "bzlib_private.h"
|
||||
|
||||
|
||||
/*---------------------------------------------*/
|
||||
Int32 BZ2_rNums[512] = {
|
||||
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
|
||||
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
|
||||
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
|
||||
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
|
||||
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
|
||||
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
|
||||
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
|
||||
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
|
||||
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
|
||||
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
|
||||
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
|
||||
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
|
||||
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
|
||||
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
|
||||
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
|
||||
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
|
||||
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
|
||||
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
|
||||
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
|
||||
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
|
||||
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
|
||||
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
|
||||
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
|
||||
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
|
||||
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
|
||||
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
|
||||
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
|
||||
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
|
||||
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
|
||||
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
|
||||
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
|
||||
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
|
||||
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
|
||||
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
|
||||
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
|
||||
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
|
||||
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
|
||||
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
|
||||
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
|
||||
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
|
||||
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
|
||||
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
|
||||
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
|
||||
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
|
||||
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
|
||||
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
|
||||
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
|
||||
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
|
||||
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
|
||||
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
|
||||
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
|
||||
936, 638
|
||||
};
|
||||
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
/*--- end randtable.c ---*/
|
||||
/*-------------------------------------------------------------*/
|
||||
+321
@@ -0,0 +1,321 @@
|
||||
/**
|
||||
* \file api/lzma.h
|
||||
* \brief The public API of liblzma data compression library
|
||||
*
|
||||
* liblzma is a public domain general-purpose data compression library with
|
||||
* a zlib-like API. The native file format is .xz, but also the old .lzma
|
||||
* format and raw (no headers) streams are supported. Multiple compression
|
||||
* algorithms (filters) are supported. Currently LZMA2 is the primary filter.
|
||||
*
|
||||
* liblzma is part of XZ Utils <http://tukaani.org/xz/>. XZ Utils includes
|
||||
* a gzip-like command line tool named xz and some other tools. XZ Utils
|
||||
* is developed and maintained by Lasse Collin.
|
||||
*
|
||||
* Major parts of liblzma are based on Igor Pavlov's public domain LZMA SDK
|
||||
* <http://7-zip.org/sdk.html>.
|
||||
*
|
||||
* The SHA-256 implementation is based on the public domain code found from
|
||||
* 7-Zip <http://7-zip.org/>, which has a modified version of the public
|
||||
* domain SHA-256 code found from Crypto++ <http://www.cryptopp.com/>.
|
||||
* The SHA-256 code in Crypto++ was written by Kevin Springle and Wei Dai.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author: Lasse Collin
|
||||
*
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
#ifndef LZMA_H
|
||||
#define LZMA_H
|
||||
|
||||
/*****************************
|
||||
* Required standard headers *
|
||||
*****************************/
|
||||
|
||||
/*
|
||||
* liblzma API headers need some standard types and macros. To allow
|
||||
* including lzma.h without requiring the application to include other
|
||||
* headers first, lzma.h includes the required standard headers unless
|
||||
* they already seem to be included already or if LZMA_MANUAL_HEADERS
|
||||
* has been defined.
|
||||
*
|
||||
* Here's what types and macros are needed and from which headers:
|
||||
* - stddef.h: size_t, NULL
|
||||
* - stdint.h: uint8_t, uint32_t, uint64_t, UINT32_C(n), uint64_C(n),
|
||||
* UINT32_MAX, UINT64_MAX
|
||||
*
|
||||
* However, inttypes.h is a little more portable than stdint.h, although
|
||||
* inttypes.h declares some unneeded things compared to plain stdint.h.
|
||||
*
|
||||
* The hacks below aren't perfect, specifically they assume that inttypes.h
|
||||
* exists and that it typedefs at least uint8_t, uint32_t, and uint64_t,
|
||||
* and that, in case of incomplete inttypes.h, unsigned int is 32-bit.
|
||||
* If the application already takes care of setting up all the types and
|
||||
* macros properly (for example by using gnulib's stdint.h or inttypes.h),
|
||||
* we try to detect that the macros are already defined and don't include
|
||||
* inttypes.h here again. However, you may define LZMA_MANUAL_HEADERS to
|
||||
* force this file to never include any system headers.
|
||||
*
|
||||
* Some could argue that liblzma API should provide all the required types,
|
||||
* for example lzma_uint64, LZMA_UINT64_C(n), and LZMA_UINT64_MAX. This was
|
||||
* seen as an unnecessary mess, since most systems already provide all the
|
||||
* necessary types and macros in the standard headers.
|
||||
*
|
||||
* Note that liblzma API still has lzma_bool, because using stdbool.h would
|
||||
* break C89 and C++ programs on many systems. sizeof(bool) in C99 isn't
|
||||
* necessarily the same as sizeof(bool) in C++.
|
||||
*/
|
||||
|
||||
#ifndef LZMA_MANUAL_HEADERS
|
||||
/*
|
||||
* I suppose this works portably also in C++. Note that in C++,
|
||||
* we need to get size_t into the global namespace.
|
||||
*/
|
||||
# include <stddef.h>
|
||||
|
||||
/*
|
||||
* Skip inttypes.h if we already have all the required macros. If we
|
||||
* have the macros, we assume that we have the matching typedefs too.
|
||||
*/
|
||||
# if !defined(UINT32_C) || !defined(UINT64_C) \
|
||||
|| !defined(UINT32_MAX) || !defined(UINT64_MAX)
|
||||
/*
|
||||
* MSVC versions older than 2013 have no C99 support, and
|
||||
* thus they cannot be used to compile liblzma. Using an
|
||||
* existing liblzma.dll with old MSVC can work though(*),
|
||||
* but we need to define the required standard integer
|
||||
* types here in a MSVC-specific way.
|
||||
*
|
||||
* (*) If you do this, the existing liblzma.dll probably uses
|
||||
* a different runtime library than your MSVC-built
|
||||
* application. Mixing runtimes is generally bad, but
|
||||
* in this case it should work as long as you avoid
|
||||
* the few rarely-needed liblzma functions that allocate
|
||||
* memory and expect the caller to free it using free().
|
||||
*/
|
||||
# if defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1800
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
# else
|
||||
/* Use the standard inttypes.h. */
|
||||
# ifdef __cplusplus
|
||||
/*
|
||||
* C99 sections 7.18.2 and 7.18.4 specify
|
||||
* that C++ implementations define the limit
|
||||
* and constant macros only if specifically
|
||||
* requested. Note that if you want the
|
||||
* format macros (PRIu64 etc.) too, you need
|
||||
* to define __STDC_FORMAT_MACROS before
|
||||
* including lzma.h, since re-including
|
||||
* inttypes.h with __STDC_FORMAT_MACROS
|
||||
* defined doesn't necessarily work.
|
||||
*/
|
||||
# ifndef __STDC_LIMIT_MACROS
|
||||
# define __STDC_LIMIT_MACROS 1
|
||||
# endif
|
||||
# ifndef __STDC_CONSTANT_MACROS
|
||||
# define __STDC_CONSTANT_MACROS 1
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# include <inttypes.h>
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Some old systems have only the typedefs in inttypes.h, and
|
||||
* lack all the macros. For those systems, we need a few more
|
||||
* hacks. We assume that unsigned int is 32-bit and unsigned
|
||||
* long is either 32-bit or 64-bit. If these hacks aren't
|
||||
* enough, the application has to setup the types manually
|
||||
* before including lzma.h.
|
||||
*/
|
||||
# ifndef UINT32_C
|
||||
# if defined(_WIN32) && defined(_MSC_VER)
|
||||
# define UINT32_C(n) n ## UI32
|
||||
# else
|
||||
# define UINT32_C(n) n ## U
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef UINT64_C
|
||||
# if defined(_WIN32) && defined(_MSC_VER)
|
||||
# define UINT64_C(n) n ## UI64
|
||||
# else
|
||||
/* Get ULONG_MAX. */
|
||||
# include <limits.h>
|
||||
# if ULONG_MAX == 4294967295UL
|
||||
# define UINT64_C(n) n ## ULL
|
||||
# else
|
||||
# define UINT64_C(n) n ## UL
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef UINT32_MAX
|
||||
# define UINT32_MAX (UINT32_C(4294967295))
|
||||
# endif
|
||||
|
||||
# ifndef UINT64_MAX
|
||||
# define UINT64_MAX (UINT64_C(18446744073709551615))
|
||||
# endif
|
||||
# endif
|
||||
#endif /* ifdef LZMA_MANUAL_HEADERS */
|
||||
|
||||
|
||||
/******************
|
||||
* LZMA_API macro *
|
||||
******************/
|
||||
|
||||
/*
|
||||
* Some systems require that the functions and function pointers are
|
||||
* declared specially in the headers. LZMA_API_IMPORT is for importing
|
||||
* symbols and LZMA_API_CALL is to specify the calling convention.
|
||||
*
|
||||
* By default it is assumed that the application will link dynamically
|
||||
* against liblzma. #define LZMA_API_STATIC in your application if you
|
||||
* want to link against static liblzma. If you don't care about portability
|
||||
* to operating systems like Windows, or at least don't care about linking
|
||||
* against static liblzma on them, don't worry about LZMA_API_STATIC. That
|
||||
* is, most developers will never need to use LZMA_API_STATIC.
|
||||
*
|
||||
* The GCC variants are a special case on Windows (Cygwin and MinGW).
|
||||
* We rely on GCC doing the right thing with its auto-import feature,
|
||||
* and thus don't use __declspec(dllimport). This way developers don't
|
||||
* need to worry about LZMA_API_STATIC. Also the calling convention is
|
||||
* omitted on Cygwin but not on MinGW.
|
||||
*/
|
||||
#ifndef LZMA_API_IMPORT
|
||||
# if !defined(LZMA_API_STATIC) && defined(_WIN32) && !defined(__GNUC__)
|
||||
# define LZMA_API_IMPORT __declspec(dllimport)
|
||||
# else
|
||||
# define LZMA_API_IMPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef LZMA_API_CALL
|
||||
# if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
# define LZMA_API_CALL __cdecl
|
||||
# else
|
||||
# define LZMA_API_CALL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef LZMA_API
|
||||
# define LZMA_API(type) LZMA_API_IMPORT type LZMA_API_CALL
|
||||
#endif
|
||||
|
||||
|
||||
/***********
|
||||
* nothrow *
|
||||
***********/
|
||||
|
||||
/*
|
||||
* None of the functions in liblzma may throw an exception. Even
|
||||
* the functions that use callback functions won't throw exceptions,
|
||||
* because liblzma would break if a callback function threw an exception.
|
||||
*/
|
||||
#ifndef lzma_nothrow
|
||||
# if defined(__cplusplus)
|
||||
# define lzma_nothrow throw()
|
||||
# elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
|
||||
# define lzma_nothrow __attribute__((__nothrow__))
|
||||
# else
|
||||
# define lzma_nothrow
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/********************
|
||||
* GNU C extensions *
|
||||
********************/
|
||||
|
||||
/*
|
||||
* GNU C extensions are used conditionally in the public API. It doesn't
|
||||
* break anything if these are sometimes enabled and sometimes not, only
|
||||
* affects warnings and optimizations.
|
||||
*/
|
||||
#if __GNUC__ >= 3
|
||||
# ifndef lzma_attribute
|
||||
# define lzma_attribute(attr) __attribute__(attr)
|
||||
# endif
|
||||
|
||||
/* warn_unused_result was added in GCC 3.4. */
|
||||
# ifndef lzma_attr_warn_unused_result
|
||||
# if __GNUC__ == 3 && __GNUC_MINOR__ < 4
|
||||
# define lzma_attr_warn_unused_result
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#else
|
||||
# ifndef lzma_attribute
|
||||
# define lzma_attribute(attr)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef lzma_attr_pure
|
||||
# define lzma_attr_pure lzma_attribute((__pure__))
|
||||
#endif
|
||||
|
||||
#ifndef lzma_attr_const
|
||||
# define lzma_attr_const lzma_attribute((__const__))
|
||||
#endif
|
||||
|
||||
#ifndef lzma_attr_warn_unused_result
|
||||
# define lzma_attr_warn_unused_result \
|
||||
lzma_attribute((__warn_unused_result__))
|
||||
#endif
|
||||
|
||||
|
||||
/**************
|
||||
* Subheaders *
|
||||
**************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Subheaders check that this is defined. It is to prevent including
|
||||
* them directly from applications.
|
||||
*/
|
||||
#define LZMA_H_INTERNAL 1
|
||||
|
||||
/* Basic features */
|
||||
#include "lzma/version.h"
|
||||
#include "lzma/base.h"
|
||||
#include "lzma/vli.h"
|
||||
#include "lzma/check.h"
|
||||
|
||||
/* Filters */
|
||||
#include "lzma/filter.h"
|
||||
//#include "lzma/bcj.h"
|
||||
//#include "lzma/delta.h"
|
||||
#include "lzma/lzma12.h"
|
||||
|
||||
/* Container formats */
|
||||
#include "lzma/container.h"
|
||||
|
||||
/* Advanced features */
|
||||
//#include "lzma/stream_flags.h"
|
||||
//#include "lzma/block.h"
|
||||
//#include "lzma/index.h"
|
||||
//#include "lzma/index_hash.h"
|
||||
|
||||
/* Hardware information */
|
||||
//#include "lzma/hardware.h"
|
||||
|
||||
/*
|
||||
* All subheaders included. Undefine LZMA_H_INTERNAL to prevent applications
|
||||
* re-including the subheaders.
|
||||
*/
|
||||
#undef LZMA_H_INTERNAL
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ifndef LZMA_H */
|
||||
+654
@@ -0,0 +1,654 @@
|
||||
/**
|
||||
* \file lzma/base.h
|
||||
* \brief Data types and functions used in many places in liblzma API
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author: Lasse Collin
|
||||
*
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*
|
||||
* See ../lzma.h for information about liblzma as a whole.
|
||||
*/
|
||||
|
||||
#ifndef LZMA_H_INTERNAL
|
||||
# error Never include this file directly. Use <lzma.h> instead.
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \brief Boolean
|
||||
*
|
||||
* This is here because C89 doesn't have stdbool.h. To set a value for
|
||||
* variables having type lzma_bool, you can use
|
||||
* - C99's `true' and `false' from stdbool.h;
|
||||
* - C++'s internal `true' and `false'; or
|
||||
* - integers one (true) and zero (false).
|
||||
*/
|
||||
typedef unsigned char lzma_bool;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Type of reserved enumeration variable in structures
|
||||
*
|
||||
* To avoid breaking library ABI when new features are added, several
|
||||
* structures contain extra variables that may be used in future. Since
|
||||
* sizeof(enum) can be different than sizeof(int), and sizeof(enum) may
|
||||
* even vary depending on the range of enumeration constants, we specify
|
||||
* a separate type to be used for reserved enumeration variables. All
|
||||
* enumeration constants in liblzma API will be non-negative and less
|
||||
* than 128, which should guarantee that the ABI won't break even when
|
||||
* new constants are added to existing enumerations.
|
||||
*/
|
||||
typedef enum {
|
||||
LZMA_RESERVED_ENUM = 0
|
||||
} lzma_reserved_enum;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Return values used by several functions in liblzma
|
||||
*
|
||||
* Check the descriptions of specific functions to find out which return
|
||||
* values they can return. With some functions the return values may have
|
||||
* more specific meanings than described here; those differences are
|
||||
* described per-function basis.
|
||||
*/
|
||||
typedef enum {
|
||||
LZMA_OK = 0,
|
||||
/**<
|
||||
* \brief Operation completed successfully
|
||||
*/
|
||||
|
||||
LZMA_STREAM_END = 1,
|
||||
/**<
|
||||
* \brief End of stream was reached
|
||||
*
|
||||
* In encoder, LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, or
|
||||
* LZMA_FINISH was finished. In decoder, this indicates
|
||||
* that all the data was successfully decoded.
|
||||
*
|
||||
* In all cases, when LZMA_STREAM_END is returned, the last
|
||||
* output bytes should be picked from strm->next_out.
|
||||
*/
|
||||
|
||||
LZMA_NO_CHECK = 2,
|
||||
/**<
|
||||
* \brief Input stream has no integrity check
|
||||
*
|
||||
* This return value can be returned only if the
|
||||
* LZMA_TELL_NO_CHECK flag was used when initializing
|
||||
* the decoder. LZMA_NO_CHECK is just a warning, and
|
||||
* the decoding can be continued normally.
|
||||
*
|
||||
* It is possible to call lzma_get_check() immediately after
|
||||
* lzma_code has returned LZMA_NO_CHECK. The result will
|
||||
* naturally be LZMA_CHECK_NONE, but the possibility to call
|
||||
* lzma_get_check() may be convenient in some applications.
|
||||
*/
|
||||
|
||||
LZMA_UNSUPPORTED_CHECK = 3,
|
||||
/**<
|
||||
* \brief Cannot calculate the integrity check
|
||||
*
|
||||
* The usage of this return value is different in encoders
|
||||
* and decoders.
|
||||
*
|
||||
* Encoders can return this value only from the initialization
|
||||
* function. If initialization fails with this value, the
|
||||
* encoding cannot be done, because there's no way to produce
|
||||
* output with the correct integrity check.
|
||||
*
|
||||
* Decoders can return this value only from lzma_code() and
|
||||
* only if the LZMA_TELL_UNSUPPORTED_CHECK flag was used when
|
||||
* initializing the decoder. The decoding can still be
|
||||
* continued normally even if the check type is unsupported,
|
||||
* but naturally the check will not be validated, and possible
|
||||
* errors may go undetected.
|
||||
*
|
||||
* With decoder, it is possible to call lzma_get_check()
|
||||
* immediately after lzma_code() has returned
|
||||
* LZMA_UNSUPPORTED_CHECK. This way it is possible to find
|
||||
* out what the unsupported Check ID was.
|
||||
*/
|
||||
|
||||
LZMA_GET_CHECK = 4,
|
||||
/**<
|
||||
* \brief Integrity check type is now available
|
||||
*
|
||||
* This value can be returned only by the lzma_code() function
|
||||
* and only if the decoder was initialized with the
|
||||
* LZMA_TELL_ANY_CHECK flag. LZMA_GET_CHECK tells the
|
||||
* application that it may now call lzma_get_check() to find
|
||||
* out the Check ID. This can be used, for example, to
|
||||
* implement a decoder that accepts only files that have
|
||||
* strong enough integrity check.
|
||||
*/
|
||||
|
||||
LZMA_MEM_ERROR = 5,
|
||||
/**<
|
||||
* \brief Cannot allocate memory
|
||||
*
|
||||
* Memory allocation failed, or the size of the allocation
|
||||
* would be greater than SIZE_MAX.
|
||||
*
|
||||
* Due to internal implementation reasons, the coding cannot
|
||||
* be continued even if more memory were made available after
|
||||
* LZMA_MEM_ERROR.
|
||||
*/
|
||||
|
||||
LZMA_MEMLIMIT_ERROR = 6,
|
||||
/**
|
||||
* \brief Memory usage limit was reached
|
||||
*
|
||||
* Decoder would need more memory than allowed by the
|
||||
* specified memory usage limit. To continue decoding,
|
||||
* the memory usage limit has to be increased with
|
||||
* lzma_memlimit_set().
|
||||
*/
|
||||
|
||||
LZMA_FORMAT_ERROR = 7,
|
||||
/**<
|
||||
* \brief File format not recognized
|
||||
*
|
||||
* The decoder did not recognize the input as supported file
|
||||
* format. This error can occur, for example, when trying to
|
||||
* decode .lzma format file with lzma_stream_decoder,
|
||||
* because lzma_stream_decoder accepts only the .xz format.
|
||||
*/
|
||||
|
||||
LZMA_OPTIONS_ERROR = 8,
|
||||
/**<
|
||||
* \brief Invalid or unsupported options
|
||||
*
|
||||
* Invalid or unsupported options, for example
|
||||
* - unsupported filter(s) or filter options; or
|
||||
* - reserved bits set in headers (decoder only).
|
||||
*
|
||||
* Rebuilding liblzma with more features enabled, or
|
||||
* upgrading to a newer version of liblzma may help.
|
||||
*/
|
||||
|
||||
LZMA_DATA_ERROR = 9,
|
||||
/**<
|
||||
* \brief Data is corrupt
|
||||
*
|
||||
* The usage of this return value is different in encoders
|
||||
* and decoders. In both encoder and decoder, the coding
|
||||
* cannot continue after this error.
|
||||
*
|
||||
* Encoders return this if size limits of the target file
|
||||
* format would be exceeded. These limits are huge, thus
|
||||
* getting this error from an encoder is mostly theoretical.
|
||||
* For example, the maximum compressed and uncompressed
|
||||
* size of a .xz Stream is roughly 8 EiB (2^63 bytes).
|
||||
*
|
||||
* Decoders return this error if the input data is corrupt.
|
||||
* This can mean, for example, invalid CRC32 in headers
|
||||
* or invalid check of uncompressed data.
|
||||
*/
|
||||
|
||||
LZMA_BUF_ERROR = 10,
|
||||
/**<
|
||||
* \brief No progress is possible
|
||||
*
|
||||
* This error code is returned when the coder cannot consume
|
||||
* any new input and produce any new output. The most common
|
||||
* reason for this error is that the input stream being
|
||||
* decoded is truncated or corrupt.
|
||||
*
|
||||
* This error is not fatal. Coding can be continued normally
|
||||
* by providing more input and/or more output space, if
|
||||
* possible.
|
||||
*
|
||||
* Typically the first call to lzma_code() that can do no
|
||||
* progress returns LZMA_OK instead of LZMA_BUF_ERROR. Only
|
||||
* the second consecutive call doing no progress will return
|
||||
* LZMA_BUF_ERROR. This is intentional.
|
||||
*
|
||||
* With zlib, Z_BUF_ERROR may be returned even if the
|
||||
* application is doing nothing wrong, so apps will need
|
||||
* to handle Z_BUF_ERROR specially. The above hack
|
||||
* guarantees that liblzma never returns LZMA_BUF_ERROR
|
||||
* to properly written applications unless the input file
|
||||
* is truncated or corrupt. This should simplify the
|
||||
* applications a little.
|
||||
*/
|
||||
|
||||
LZMA_PROG_ERROR = 11,
|
||||
/**<
|
||||
* \brief Programming error
|
||||
*
|
||||
* This indicates that the arguments given to the function are
|
||||
* invalid or the internal state of the decoder is corrupt.
|
||||
* - Function arguments are invalid or the structures
|
||||
* pointed by the argument pointers are invalid
|
||||
* e.g. if strm->next_out has been set to NULL and
|
||||
* strm->avail_out > 0 when calling lzma_code().
|
||||
* - lzma_* functions have been called in wrong order
|
||||
* e.g. lzma_code() was called right after lzma_end().
|
||||
* - If errors occur randomly, the reason might be flaky
|
||||
* hardware.
|
||||
*
|
||||
* If you think that your code is correct, this error code
|
||||
* can be a sign of a bug in liblzma. See the documentation
|
||||
* how to report bugs.
|
||||
*/
|
||||
} lzma_ret;
|
||||
|
||||
|
||||
/**
|
||||
* \brief The `action' argument for lzma_code()
|
||||
*
|
||||
* After the first use of LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, LZMA_FULL_BARRIER,
|
||||
* or LZMA_FINISH, the same `action' must is used until lzma_code() returns
|
||||
* LZMA_STREAM_END. Also, the amount of input (that is, strm->avail_in) must
|
||||
* not be modified by the application until lzma_code() returns
|
||||
* LZMA_STREAM_END. Changing the `action' or modifying the amount of input
|
||||
* will make lzma_code() return LZMA_PROG_ERROR.
|
||||
*/
|
||||
typedef enum {
|
||||
LZMA_RUN = 0,
|
||||
/**<
|
||||
* \brief Continue coding
|
||||
*
|
||||
* Encoder: Encode as much input as possible. Some internal
|
||||
* buffering will probably be done (depends on the filter
|
||||
* chain in use), which causes latency: the input used won't
|
||||
* usually be decodeable from the output of the same
|
||||
* lzma_code() call.
|
||||
*
|
||||
* Decoder: Decode as much input as possible and produce as
|
||||
* much output as possible.
|
||||
*/
|
||||
|
||||
LZMA_SYNC_FLUSH = 1,
|
||||
/**<
|
||||
* \brief Make all the input available at output
|
||||
*
|
||||
* Normally the encoder introduces some latency.
|
||||
* LZMA_SYNC_FLUSH forces all the buffered data to be
|
||||
* available at output without resetting the internal
|
||||
* state of the encoder. This way it is possible to use
|
||||
* compressed stream for example for communication over
|
||||
* network.
|
||||
*
|
||||
* Only some filters support LZMA_SYNC_FLUSH. Trying to use
|
||||
* LZMA_SYNC_FLUSH with filters that don't support it will
|
||||
* make lzma_code() return LZMA_OPTIONS_ERROR. For example,
|
||||
* LZMA1 doesn't support LZMA_SYNC_FLUSH but LZMA2 does.
|
||||
*
|
||||
* Using LZMA_SYNC_FLUSH very often can dramatically reduce
|
||||
* the compression ratio. With some filters (for example,
|
||||
* LZMA2), fine-tuning the compression options may help
|
||||
* mitigate this problem significantly (for example,
|
||||
* match finder with LZMA2).
|
||||
*
|
||||
* Decoders don't support LZMA_SYNC_FLUSH.
|
||||
*/
|
||||
|
||||
LZMA_FULL_FLUSH = 2,
|
||||
/**<
|
||||
* \brief Finish encoding of the current Block
|
||||
*
|
||||
* All the input data going to the current Block must have
|
||||
* been given to the encoder (the last bytes can still be
|
||||
* pending in *next_in). Call lzma_code() with LZMA_FULL_FLUSH
|
||||
* until it returns LZMA_STREAM_END. Then continue normally
|
||||
* with LZMA_RUN or finish the Stream with LZMA_FINISH.
|
||||
*
|
||||
* This action is currently supported only by Stream encoder
|
||||
* and easy encoder (which uses Stream encoder). If there is
|
||||
* no unfinished Block, no empty Block is created.
|
||||
*/
|
||||
|
||||
LZMA_FULL_BARRIER = 4,
|
||||
/**<
|
||||
* \brief Finish encoding of the current Block
|
||||
*
|
||||
* This is like LZMA_FULL_FLUSH except that this doesn't
|
||||
* necessarily wait until all the input has been made
|
||||
* available via the output buffer. That is, lzma_code()
|
||||
* might return LZMA_STREAM_END as soon as all the input
|
||||
* has been consumed (avail_in == 0).
|
||||
*
|
||||
* LZMA_FULL_BARRIER is useful with a threaded encoder if
|
||||
* one wants to split the .xz Stream into Blocks at specific
|
||||
* offsets but doesn't care if the output isn't flushed
|
||||
* immediately. Using LZMA_FULL_BARRIER allows keeping
|
||||
* the threads busy while LZMA_FULL_FLUSH would make
|
||||
* lzma_code() wait until all the threads have finished
|
||||
* until more data could be passed to the encoder.
|
||||
*
|
||||
* With a lzma_stream initialized with the single-threaded
|
||||
* lzma_stream_encoder() or lzma_easy_encoder(),
|
||||
* LZMA_FULL_BARRIER is an alias for LZMA_FULL_FLUSH.
|
||||
*/
|
||||
|
||||
LZMA_FINISH = 3
|
||||
/**<
|
||||
* \brief Finish the coding operation
|
||||
*
|
||||
* All the input data must have been given to the encoder
|
||||
* (the last bytes can still be pending in next_in).
|
||||
* Call lzma_code() with LZMA_FINISH until it returns
|
||||
* LZMA_STREAM_END. Once LZMA_FINISH has been used,
|
||||
* the amount of input must no longer be changed by
|
||||
* the application.
|
||||
*
|
||||
* When decoding, using LZMA_FINISH is optional unless the
|
||||
* LZMA_CONCATENATED flag was used when the decoder was
|
||||
* initialized. When LZMA_CONCATENATED was not used, the only
|
||||
* effect of LZMA_FINISH is that the amount of input must not
|
||||
* be changed just like in the encoder.
|
||||
*/
|
||||
} lzma_action;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Custom functions for memory handling
|
||||
*
|
||||
* A pointer to lzma_allocator may be passed via lzma_stream structure
|
||||
* to liblzma, and some advanced functions take a pointer to lzma_allocator
|
||||
* as a separate function argument. The library will use the functions
|
||||
* specified in lzma_allocator for memory handling instead of the default
|
||||
* malloc() and free(). C++ users should note that the custom memory
|
||||
* handling functions must not throw exceptions.
|
||||
*
|
||||
* Single-threaded mode only: liblzma doesn't make an internal copy of
|
||||
* lzma_allocator. Thus, it is OK to change these function pointers in
|
||||
* the middle of the coding process, but obviously it must be done
|
||||
* carefully to make sure that the replacement `free' can deallocate
|
||||
* memory allocated by the earlier `alloc' function(s).
|
||||
*
|
||||
* Multithreaded mode: liblzma might internally store pointers to the
|
||||
* lzma_allocator given via the lzma_stream structure. The application
|
||||
* must not change the allocator pointer in lzma_stream or the contents
|
||||
* of the pointed lzma_allocator structure until lzma_end() has been used
|
||||
* to free the memory associated with that lzma_stream. The allocation
|
||||
* functions might be called simultaneously from multiple threads, and
|
||||
* thus they must be thread safe.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* \brief Pointer to a custom memory allocation function
|
||||
*
|
||||
* If you don't want a custom allocator, but still want
|
||||
* custom free(), set this to NULL and liblzma will use
|
||||
* the standard malloc().
|
||||
*
|
||||
* \param opaque lzma_allocator.opaque (see below)
|
||||
* \param nmemb Number of elements like in calloc(). liblzma
|
||||
* will always set nmemb to 1, so it is safe to
|
||||
* ignore nmemb in a custom allocator if you like.
|
||||
* The nmemb argument exists only for
|
||||
* compatibility with zlib and libbzip2.
|
||||
* \param size Size of an element in bytes.
|
||||
* liblzma never sets this to zero.
|
||||
*
|
||||
* \return Pointer to the beginning of a memory block of
|
||||
* `size' bytes, or NULL if allocation fails
|
||||
* for some reason. When allocation fails, functions
|
||||
* of liblzma return LZMA_MEM_ERROR.
|
||||
*
|
||||
* The allocator should not waste time zeroing the allocated buffers.
|
||||
* This is not only about speed, but also memory usage, since the
|
||||
* operating system kernel doesn't necessarily allocate the requested
|
||||
* memory in physical memory until it is actually used. With small
|
||||
* input files, liblzma may actually need only a fraction of the
|
||||
* memory that it requested for allocation.
|
||||
*
|
||||
* \note LZMA_MEM_ERROR is also used when the size of the
|
||||
* allocation would be greater than SIZE_MAX. Thus,
|
||||
* don't assume that the custom allocator must have
|
||||
* returned NULL if some function from liblzma
|
||||
* returns LZMA_MEM_ERROR.
|
||||
*/
|
||||
void *(LZMA_API_CALL *alloc)(void *opaque, size_t nmemb, size_t size);
|
||||
|
||||
/**
|
||||
* \brief Pointer to a custom memory freeing function
|
||||
*
|
||||
* If you don't want a custom freeing function, but still
|
||||
* want a custom allocator, set this to NULL and liblzma
|
||||
* will use the standard free().
|
||||
*
|
||||
* \param opaque lzma_allocator.opaque (see below)
|
||||
* \param ptr Pointer returned by lzma_allocator.alloc(),
|
||||
* or when it is set to NULL, a pointer returned
|
||||
* by the standard malloc().
|
||||
*/
|
||||
void (LZMA_API_CALL *free)(void *opaque, void *ptr);
|
||||
|
||||
/**
|
||||
* \brief Pointer passed to .alloc() and .free()
|
||||
*
|
||||
* opaque is passed as the first argument to lzma_allocator.alloc()
|
||||
* and lzma_allocator.free(). This intended to ease implementing
|
||||
* custom memory allocation functions for use with liblzma.
|
||||
*
|
||||
* If you don't need this, you should set this to NULL.
|
||||
*/
|
||||
void *opaque;
|
||||
|
||||
} lzma_allocator;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Internal data structure
|
||||
*
|
||||
* The contents of this structure is not visible outside the library.
|
||||
*/
|
||||
typedef struct lzma_internal_s lzma_internal;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Passing data to and from liblzma
|
||||
*
|
||||
* The lzma_stream structure is used for
|
||||
* - passing pointers to input and output buffers to liblzma;
|
||||
* - defining custom memory hander functions; and
|
||||
* - holding a pointer to coder-specific internal data structures.
|
||||
*
|
||||
* Typical usage:
|
||||
*
|
||||
* - After allocating lzma_stream (on stack or with malloc()), it must be
|
||||
* initialized to LZMA_STREAM_INIT (see LZMA_STREAM_INIT for details).
|
||||
*
|
||||
* - Initialize a coder to the lzma_stream, for example by using
|
||||
* lzma_easy_encoder() or lzma_auto_decoder(). Some notes:
|
||||
* - In contrast to zlib, strm->next_in and strm->next_out are
|
||||
* ignored by all initialization functions, thus it is safe
|
||||
* to not initialize them yet.
|
||||
* - The initialization functions always set strm->total_in and
|
||||
* strm->total_out to zero.
|
||||
* - If the initialization function fails, no memory is left allocated
|
||||
* that would require freeing with lzma_end() even if some memory was
|
||||
* associated with the lzma_stream structure when the initialization
|
||||
* function was called.
|
||||
*
|
||||
* - Use lzma_code() to do the actual work.
|
||||
*
|
||||
* - Once the coding has been finished, the existing lzma_stream can be
|
||||
* reused. It is OK to reuse lzma_stream with different initialization
|
||||
* function without calling lzma_end() first. Old allocations are
|
||||
* automatically freed.
|
||||
*
|
||||
* - Finally, use lzma_end() to free the allocated memory. lzma_end() never
|
||||
* frees the lzma_stream structure itself.
|
||||
*
|
||||
* Application may modify the values of total_in and total_out as it wants.
|
||||
* They are updated by liblzma to match the amount of data read and
|
||||
* written but aren't used for anything else except as a possible return
|
||||
* values from lzma_get_progress().
|
||||
*/
|
||||
typedef struct {
|
||||
const uint8_t *next_in; /**< Pointer to the next input byte. */
|
||||
size_t avail_in; /**< Number of available input bytes in next_in. */
|
||||
uint64_t total_in; /**< Total number of bytes read by liblzma. */
|
||||
|
||||
uint8_t *next_out; /**< Pointer to the next output position. */
|
||||
size_t avail_out; /**< Amount of free space in next_out. */
|
||||
uint64_t total_out; /**< Total number of bytes written by liblzma. */
|
||||
|
||||
/**
|
||||
* \brief Custom memory allocation functions
|
||||
*
|
||||
* In most cases this is NULL which makes liblzma use
|
||||
* the standard malloc() and free().
|
||||
*
|
||||
* \note In 5.0.x this is not a const pointer.
|
||||
*/
|
||||
const lzma_allocator *allocator;
|
||||
|
||||
/** Internal state is not visible to applications. */
|
||||
lzma_internal *internal;
|
||||
|
||||
/*
|
||||
* Reserved space to allow possible future extensions without
|
||||
* breaking the ABI. Excluding the initialization of this structure,
|
||||
* you should not touch these, because the names of these variables
|
||||
* may change.
|
||||
*/
|
||||
void *reserved_ptr1;
|
||||
void *reserved_ptr2;
|
||||
void *reserved_ptr3;
|
||||
void *reserved_ptr4;
|
||||
uint64_t reserved_int1;
|
||||
uint64_t reserved_int2;
|
||||
size_t reserved_int3;
|
||||
size_t reserved_int4;
|
||||
lzma_reserved_enum reserved_enum1;
|
||||
lzma_reserved_enum reserved_enum2;
|
||||
|
||||
} lzma_stream;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialization for lzma_stream
|
||||
*
|
||||
* When you declare an instance of lzma_stream, you can immediately
|
||||
* initialize it so that initialization functions know that no memory
|
||||
* has been allocated yet:
|
||||
*
|
||||
* lzma_stream strm = LZMA_STREAM_INIT;
|
||||
*
|
||||
* If you need to initialize a dynamically allocated lzma_stream, you can use
|
||||
* memset(strm_pointer, 0, sizeof(lzma_stream)). Strictly speaking, this
|
||||
* violates the C standard since NULL may have different internal
|
||||
* representation than zero, but it should be portable enough in practice.
|
||||
* Anyway, for maximum portability, you can use something like this:
|
||||
*
|
||||
* lzma_stream tmp = LZMA_STREAM_INIT;
|
||||
* *strm = tmp;
|
||||
*/
|
||||
#define LZMA_STREAM_INIT \
|
||||
{ NULL, 0, 0, NULL, 0, 0, NULL, NULL, \
|
||||
NULL, NULL, NULL, NULL, 0, 0, 0, 0, \
|
||||
LZMA_RESERVED_ENUM, LZMA_RESERVED_ENUM }
|
||||
|
||||
|
||||
/**
|
||||
* \brief Encode or decode data
|
||||
*
|
||||
* Once the lzma_stream has been successfully initialized (e.g. with
|
||||
* lzma_stream_encoder()), the actual encoding or decoding is done
|
||||
* using this function. The application has to update strm->next_in,
|
||||
* strm->avail_in, strm->next_out, and strm->avail_out to pass input
|
||||
* to and get output from liblzma.
|
||||
*
|
||||
* See the description of the coder-specific initialization function to find
|
||||
* out what `action' values are supported by the coder.
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_code(lzma_stream *strm, lzma_action action)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Free memory allocated for the coder data structures
|
||||
*
|
||||
* \param strm Pointer to lzma_stream that is at least initialized
|
||||
* with LZMA_STREAM_INIT.
|
||||
*
|
||||
* After lzma_end(strm), strm->internal is guaranteed to be NULL. No other
|
||||
* members of the lzma_stream structure are touched.
|
||||
*
|
||||
* \note zlib indicates an error if application end()s unfinished
|
||||
* stream structure. liblzma doesn't do this, and assumes that
|
||||
* application knows what it is doing.
|
||||
*/
|
||||
extern LZMA_API(void) lzma_end(lzma_stream *strm) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get progress information
|
||||
*
|
||||
* In single-threaded mode, applications can get progress information from
|
||||
* strm->total_in and strm->total_out. In multi-threaded mode this is less
|
||||
* useful because a significant amount of both input and output data gets
|
||||
* buffered internally by liblzma. This makes total_in and total_out give
|
||||
* misleading information and also makes the progress indicator updates
|
||||
* non-smooth.
|
||||
*
|
||||
* This function gives realistic progress information also in multi-threaded
|
||||
* mode by taking into account the progress made by each thread. In
|
||||
* single-threaded mode *progress_in and *progress_out are set to
|
||||
* strm->total_in and strm->total_out, respectively.
|
||||
*/
|
||||
extern LZMA_API(void) lzma_get_progress(lzma_stream *strm,
|
||||
uint64_t *progress_in, uint64_t *progress_out) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the memory usage of decoder filter chain
|
||||
*
|
||||
* This function is currently supported only when *strm has been initialized
|
||||
* with a function that takes a memlimit argument. With other functions, you
|
||||
* should use e.g. lzma_raw_encoder_memusage() or lzma_raw_decoder_memusage()
|
||||
* to estimate the memory requirements.
|
||||
*
|
||||
* This function is useful e.g. after LZMA_MEMLIMIT_ERROR to find out how big
|
||||
* the memory usage limit should have been to decode the input. Note that
|
||||
* this may give misleading information if decoding .xz Streams that have
|
||||
* multiple Blocks, because each Block can have different memory requirements.
|
||||
*
|
||||
* \return How much memory is currently allocated for the filter
|
||||
* decoders. If no filter chain is currently allocated,
|
||||
* some non-zero value is still returned, which is less than
|
||||
* or equal to what any filter chain would indicate as its
|
||||
* memory requirement.
|
||||
*
|
||||
* If this function isn't supported by *strm or some other error
|
||||
* occurs, zero is returned.
|
||||
*/
|
||||
extern LZMA_API(uint64_t) lzma_memusage(const lzma_stream *strm)
|
||||
lzma_nothrow lzma_attr_pure;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the current memory usage limit
|
||||
*
|
||||
* This function is supported only when *strm has been initialized with
|
||||
* a function that takes a memlimit argument.
|
||||
*
|
||||
* \return On success, the current memory usage limit is returned
|
||||
* (always non-zero). On error, zero is returned.
|
||||
*/
|
||||
extern LZMA_API(uint64_t) lzma_memlimit_get(const lzma_stream *strm)
|
||||
lzma_nothrow lzma_attr_pure;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Set the memory usage limit
|
||||
*
|
||||
* This function is supported only when *strm has been initialized with
|
||||
* a function that takes a memlimit argument.
|
||||
*
|
||||
* \return - LZMA_OK: New memory usage limit successfully set.
|
||||
* - LZMA_MEMLIMIT_ERROR: The new limit is too small.
|
||||
* The limit was not changed.
|
||||
* - LZMA_PROG_ERROR: Invalid arguments, e.g. *strm doesn't
|
||||
* support memory usage limit or memlimit was zero.
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_memlimit_set(
|
||||
lzma_stream *strm, uint64_t memlimit) lzma_nothrow;
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* \file lzma/check.h
|
||||
* \brief Integrity checks
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author: Lasse Collin
|
||||
*
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*
|
||||
* See ../lzma.h for information about liblzma as a whole.
|
||||
*/
|
||||
|
||||
#ifndef LZMA_H_INTERNAL
|
||||
# error Never include this file directly. Use <lzma.h> instead.
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \brief Type of the integrity check (Check ID)
|
||||
*
|
||||
* The .xz format supports multiple types of checks that are calculated
|
||||
* from the uncompressed data. They vary in both speed and ability to
|
||||
* detect errors.
|
||||
*/
|
||||
typedef enum {
|
||||
LZMA_CHECK_NONE = 0,
|
||||
/**<
|
||||
* No Check is calculated.
|
||||
*
|
||||
* Size of the Check field: 0 bytes
|
||||
*/
|
||||
|
||||
LZMA_CHECK_CRC32 = 1,
|
||||
/**<
|
||||
* CRC32 using the polynomial from the IEEE 802.3 standard
|
||||
*
|
||||
* Size of the Check field: 4 bytes
|
||||
*/
|
||||
|
||||
LZMA_CHECK_CRC64 = 4,
|
||||
/**<
|
||||
* CRC64 using the polynomial from the ECMA-182 standard
|
||||
*
|
||||
* Size of the Check field: 8 bytes
|
||||
*/
|
||||
|
||||
LZMA_CHECK_SHA256 = 10
|
||||
/**<
|
||||
* SHA-256
|
||||
*
|
||||
* Size of the Check field: 32 bytes
|
||||
*/
|
||||
} lzma_check;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Maximum valid Check ID
|
||||
*
|
||||
* The .xz file format specification specifies 16 Check IDs (0-15). Some
|
||||
* of them are only reserved, that is, no actual Check algorithm has been
|
||||
* assigned. When decoding, liblzma still accepts unknown Check IDs for
|
||||
* future compatibility. If a valid but unsupported Check ID is detected,
|
||||
* liblzma can indicate a warning; see the flags LZMA_TELL_NO_CHECK,
|
||||
* LZMA_TELL_UNSUPPORTED_CHECK, and LZMA_TELL_ANY_CHECK in container.h.
|
||||
*/
|
||||
#define LZMA_CHECK_ID_MAX 15
|
||||
|
||||
|
||||
/**
|
||||
* \brief Test if the given Check ID is supported
|
||||
*
|
||||
* Return true if the given Check ID is supported by this liblzma build.
|
||||
* Otherwise false is returned. It is safe to call this with a value that
|
||||
* is not in the range [0, 15]; in that case the return value is always false.
|
||||
*
|
||||
* You can assume that LZMA_CHECK_NONE and LZMA_CHECK_CRC32 are always
|
||||
* supported (even if liblzma is built with limited features).
|
||||
*/
|
||||
extern LZMA_API(lzma_bool) lzma_check_is_supported(lzma_check check)
|
||||
lzma_nothrow lzma_attr_const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the size of the Check field with the given Check ID
|
||||
*
|
||||
* Although not all Check IDs have a check algorithm associated, the size of
|
||||
* every Check is already frozen. This function returns the size (in bytes) of
|
||||
* the Check field with the specified Check ID. The values are:
|
||||
* { 0, 4, 4, 4, 8, 8, 8, 16, 16, 16, 32, 32, 32, 64, 64, 64 }
|
||||
*
|
||||
* If the argument is not in the range [0, 15], UINT32_MAX is returned.
|
||||
*/
|
||||
extern LZMA_API(uint32_t) lzma_check_size(lzma_check check)
|
||||
lzma_nothrow lzma_attr_const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Maximum size of a Check field
|
||||
*/
|
||||
#define LZMA_CHECK_SIZE_MAX 64
|
||||
|
||||
|
||||
/**
|
||||
* \brief Calculate CRC32
|
||||
*
|
||||
* Calculate CRC32 using the polynomial from the IEEE 802.3 standard.
|
||||
*
|
||||
* \param buf Pointer to the input buffer
|
||||
* \param size Size of the input buffer
|
||||
* \param crc Previously returned CRC value. This is used to
|
||||
* calculate the CRC of a big buffer in smaller chunks.
|
||||
* Set to zero when starting a new calculation.
|
||||
*
|
||||
* \return Updated CRC value, which can be passed to this function
|
||||
* again to continue CRC calculation.
|
||||
*/
|
||||
extern LZMA_API(uint32_t) lzma_crc32(
|
||||
const uint8_t *buf, size_t size, uint32_t crc)
|
||||
lzma_nothrow lzma_attr_pure;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Calculate CRC64
|
||||
*
|
||||
* Calculate CRC64 using the polynomial from the ECMA-182 standard.
|
||||
*
|
||||
* This function is used similarly to lzma_crc32(). See its documentation.
|
||||
*/
|
||||
extern LZMA_API(uint64_t) lzma_crc64(
|
||||
const uint8_t *buf, size_t size, uint64_t crc)
|
||||
lzma_nothrow lzma_attr_pure;
|
||||
|
||||
|
||||
/*
|
||||
* SHA-256 functions are currently not exported to public API.
|
||||
* Contact Lasse Collin if you think it should be.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the type of the integrity check
|
||||
*
|
||||
* This function can be called only immediately after lzma_code() has
|
||||
* returned LZMA_NO_CHECK, LZMA_UNSUPPORTED_CHECK, or LZMA_GET_CHECK.
|
||||
* Calling this function in any other situation has undefined behavior.
|
||||
*/
|
||||
extern LZMA_API(lzma_check) lzma_get_check(const lzma_stream *strm)
|
||||
lzma_nothrow;
|
||||
+619
@@ -0,0 +1,619 @@
|
||||
/**
|
||||
* \file lzma/container.h
|
||||
* \brief File formats
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author: Lasse Collin
|
||||
*
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*
|
||||
* See ../lzma.h for information about liblzma as a whole.
|
||||
*/
|
||||
|
||||
#ifndef LZMA_H_INTERNAL
|
||||
# error Never include this file directly. Use <lzma.h> instead.
|
||||
#endif
|
||||
|
||||
|
||||
/************
|
||||
* Encoding *
|
||||
************/
|
||||
|
||||
/**
|
||||
* \brief Default compression preset
|
||||
*
|
||||
* It's not straightforward to recommend a default preset, because in some
|
||||
* cases keeping the resource usage relatively low is more important that
|
||||
* getting the maximum compression ratio.
|
||||
*/
|
||||
#define LZMA_PRESET_DEFAULT UINT32_C(6)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Mask for preset level
|
||||
*
|
||||
* This is useful only if you need to extract the level from the preset
|
||||
* variable. That should be rare.
|
||||
*/
|
||||
#define LZMA_PRESET_LEVEL_MASK UINT32_C(0x1F)
|
||||
|
||||
|
||||
/*
|
||||
* Preset flags
|
||||
*
|
||||
* Currently only one flag is defined.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Extreme compression preset
|
||||
*
|
||||
* This flag modifies the preset to make the encoding significantly slower
|
||||
* while improving the compression ratio only marginally. This is useful
|
||||
* when you don't mind wasting time to get as small result as possible.
|
||||
*
|
||||
* This flag doesn't affect the memory usage requirements of the decoder (at
|
||||
* least not significantly). The memory usage of the encoder may be increased
|
||||
* a little but only at the lowest preset levels (0-3).
|
||||
*/
|
||||
#define LZMA_PRESET_EXTREME (UINT32_C(1) << 31)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Multithreading options
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* \brief Flags
|
||||
*
|
||||
* Set this to zero if no flags are wanted.
|
||||
*
|
||||
* No flags are currently supported.
|
||||
*/
|
||||
uint32_t flags;
|
||||
|
||||
/**
|
||||
* \brief Number of worker threads to use
|
||||
*/
|
||||
uint32_t threads;
|
||||
|
||||
/**
|
||||
* \brief Maximum uncompressed size of a Block
|
||||
*
|
||||
* The encoder will start a new .xz Block every block_size bytes.
|
||||
* Using LZMA_FULL_FLUSH or LZMA_FULL_BARRIER with lzma_code()
|
||||
* the caller may tell liblzma to start a new Block earlier.
|
||||
*
|
||||
* With LZMA2, a recommended block size is 2-4 times the LZMA2
|
||||
* dictionary size. With very small dictionaries, it is recommended
|
||||
* to use at least 1 MiB block size for good compression ratio, even
|
||||
* if this is more than four times the dictionary size. Note that
|
||||
* these are only recommendations for typical use cases; feel free
|
||||
* to use other values. Just keep in mind that using a block size
|
||||
* less than the LZMA2 dictionary size is waste of RAM.
|
||||
*
|
||||
* Set this to 0 to let liblzma choose the block size depending
|
||||
* on the compression options. For LZMA2 it will be 3*dict_size
|
||||
* or 1 MiB, whichever is more.
|
||||
*
|
||||
* For each thread, about 3 * block_size bytes of memory will be
|
||||
* allocated. This may change in later liblzma versions. If so,
|
||||
* the memory usage will probably be reduced, not increased.
|
||||
*/
|
||||
uint64_t block_size;
|
||||
|
||||
/**
|
||||
* \brief Timeout to allow lzma_code() to return early
|
||||
*
|
||||
* Multithreading can make liblzma to consume input and produce
|
||||
* output in a very bursty way: it may first read a lot of input
|
||||
* to fill internal buffers, then no input or output occurs for
|
||||
* a while.
|
||||
*
|
||||
* In single-threaded mode, lzma_code() won't return until it has
|
||||
* either consumed all the input or filled the output buffer. If
|
||||
* this is done in multithreaded mode, it may cause a call
|
||||
* lzma_code() to take even tens of seconds, which isn't acceptable
|
||||
* in all applications.
|
||||
*
|
||||
* To avoid very long blocking times in lzma_code(), a timeout
|
||||
* (in milliseconds) may be set here. If lzma_code() would block
|
||||
* longer than this number of milliseconds, it will return with
|
||||
* LZMA_OK. Reasonable values are 100 ms or more. The xz command
|
||||
* line tool uses 300 ms.
|
||||
*
|
||||
* If long blocking times are fine for you, set timeout to a special
|
||||
* value of 0, which will disable the timeout mechanism and will make
|
||||
* lzma_code() block until all the input is consumed or the output
|
||||
* buffer has been filled.
|
||||
*
|
||||
* \note Even with a timeout, lzma_code() might sometimes take
|
||||
* somewhat long time to return. No timing guarantees
|
||||
* are made.
|
||||
*/
|
||||
uint32_t timeout;
|
||||
|
||||
/**
|
||||
* \brief Compression preset (level and possible flags)
|
||||
*
|
||||
* The preset is set just like with lzma_easy_encoder().
|
||||
* The preset is ignored if filters below is non-NULL.
|
||||
*/
|
||||
uint32_t preset;
|
||||
|
||||
/**
|
||||
* \brief Filter chain (alternative to a preset)
|
||||
*
|
||||
* If this is NULL, the preset above is used. Otherwise the preset
|
||||
* is ignored and the filter chain specified here is used.
|
||||
*/
|
||||
const lzma_filter *filters;
|
||||
|
||||
/**
|
||||
* \brief Integrity check type
|
||||
*
|
||||
* See check.h for available checks. The xz command line tool
|
||||
* defaults to LZMA_CHECK_CRC64, which is a good choice if you
|
||||
* are unsure.
|
||||
*/
|
||||
lzma_check check;
|
||||
|
||||
/*
|
||||
* Reserved space to allow possible future extensions without
|
||||
* breaking the ABI. You should not touch these, because the names
|
||||
* of these variables may change. These are and will never be used
|
||||
* with the currently supported options, so it is safe to leave these
|
||||
* uninitialized.
|
||||
*/
|
||||
lzma_reserved_enum reserved_enum1;
|
||||
lzma_reserved_enum reserved_enum2;
|
||||
lzma_reserved_enum reserved_enum3;
|
||||
uint32_t reserved_int1;
|
||||
uint32_t reserved_int2;
|
||||
uint32_t reserved_int3;
|
||||
uint32_t reserved_int4;
|
||||
uint64_t reserved_int5;
|
||||
uint64_t reserved_int6;
|
||||
uint64_t reserved_int7;
|
||||
uint64_t reserved_int8;
|
||||
void *reserved_ptr1;
|
||||
void *reserved_ptr2;
|
||||
void *reserved_ptr3;
|
||||
void *reserved_ptr4;
|
||||
|
||||
} lzma_mt;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Calculate approximate memory usage of easy encoder
|
||||
*
|
||||
* This function is a wrapper for lzma_raw_encoder_memusage().
|
||||
*
|
||||
* \param preset Compression preset (level and possible flags)
|
||||
*
|
||||
* \return Number of bytes of memory required for the given
|
||||
* preset when encoding. If an error occurs, for example
|
||||
* due to unsupported preset, UINT64_MAX is returned.
|
||||
*/
|
||||
extern LZMA_API(uint64_t) lzma_easy_encoder_memusage(uint32_t preset)
|
||||
lzma_nothrow lzma_attr_pure;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Calculate approximate decoder memory usage of a preset
|
||||
*
|
||||
* This function is a wrapper for lzma_raw_decoder_memusage().
|
||||
*
|
||||
* \param preset Compression preset (level and possible flags)
|
||||
*
|
||||
* \return Number of bytes of memory required to decompress a file
|
||||
* that was compressed using the given preset. If an error
|
||||
* occurs, for example due to unsupported preset, UINT64_MAX
|
||||
* is returned.
|
||||
*/
|
||||
extern LZMA_API(uint64_t) lzma_easy_decoder_memusage(uint32_t preset)
|
||||
lzma_nothrow lzma_attr_pure;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialize .xz Stream encoder using a preset number
|
||||
*
|
||||
* This function is intended for those who just want to use the basic features
|
||||
* if liblzma (that is, most developers out there).
|
||||
*
|
||||
* \param strm Pointer to lzma_stream that is at least initialized
|
||||
* with LZMA_STREAM_INIT.
|
||||
* \param preset Compression preset to use. A preset consist of level
|
||||
* number and zero or more flags. Usually flags aren't
|
||||
* used, so preset is simply a number [0, 9] which match
|
||||
* the options -0 ... -9 of the xz command line tool.
|
||||
* Additional flags can be be set using bitwise-or with
|
||||
* the preset level number, e.g. 6 | LZMA_PRESET_EXTREME.
|
||||
* \param check Integrity check type to use. See check.h for available
|
||||
* checks. The xz command line tool defaults to
|
||||
* LZMA_CHECK_CRC64, which is a good choice if you are
|
||||
* unsure. LZMA_CHECK_CRC32 is good too as long as the
|
||||
* uncompressed file is not many gigabytes.
|
||||
*
|
||||
* \return - LZMA_OK: Initialization succeeded. Use lzma_code() to
|
||||
* encode your data.
|
||||
* - LZMA_MEM_ERROR: Memory allocation failed.
|
||||
* - LZMA_OPTIONS_ERROR: The given compression preset is not
|
||||
* supported by this build of liblzma.
|
||||
* - LZMA_UNSUPPORTED_CHECK: The given check type is not
|
||||
* supported by this liblzma build.
|
||||
* - LZMA_PROG_ERROR: One or more of the parameters have values
|
||||
* that will never be valid. For example, strm == NULL.
|
||||
*
|
||||
* If initialization fails (return value is not LZMA_OK), all the memory
|
||||
* allocated for *strm by liblzma is always freed. Thus, there is no need
|
||||
* to call lzma_end() after failed initialization.
|
||||
*
|
||||
* If initialization succeeds, use lzma_code() to do the actual encoding.
|
||||
* Valid values for `action' (the second argument of lzma_code()) are
|
||||
* LZMA_RUN, LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, and LZMA_FINISH. In future,
|
||||
* there may be compression levels or flags that don't support LZMA_SYNC_FLUSH.
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_easy_encoder(
|
||||
lzma_stream *strm, uint32_t preset, lzma_check check)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Single-call .xz Stream encoding using a preset number
|
||||
*
|
||||
* The maximum required output buffer size can be calculated with
|
||||
* lzma_stream_buffer_bound().
|
||||
*
|
||||
* \param preset Compression preset to use. See the description
|
||||
* in lzma_easy_encoder().
|
||||
* \param check Type of the integrity check to calculate from
|
||||
* uncompressed data.
|
||||
* \param allocator lzma_allocator for custom allocator functions.
|
||||
* Set to NULL to use malloc() and free().
|
||||
* \param in Beginning of the input buffer
|
||||
* \param in_size Size of the input buffer
|
||||
* \param out Beginning of the output buffer
|
||||
* \param out_pos The next byte will be written to out[*out_pos].
|
||||
* *out_pos is updated only if encoding succeeds.
|
||||
* \param out_size Size of the out buffer; the first byte into
|
||||
* which no data is written to is out[out_size].
|
||||
*
|
||||
* \return - LZMA_OK: Encoding was successful.
|
||||
* - LZMA_BUF_ERROR: Not enough output buffer space.
|
||||
* - LZMA_UNSUPPORTED_CHECK
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_DATA_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_easy_buffer_encode(
|
||||
uint32_t preset, lzma_check check,
|
||||
const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialize .xz Stream encoder using a custom filter chain
|
||||
*
|
||||
* \param strm Pointer to properly prepared lzma_stream
|
||||
* \param filters Array of filters. This must be terminated with
|
||||
* filters[n].id = LZMA_VLI_UNKNOWN. See filter.h for
|
||||
* more information.
|
||||
* \param check Type of the integrity check to calculate from
|
||||
* uncompressed data.
|
||||
*
|
||||
* \return - LZMA_OK: Initialization was successful.
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_UNSUPPORTED_CHECK
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_stream_encoder(lzma_stream *strm,
|
||||
const lzma_filter *filters, lzma_check check)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Calculate approximate memory usage of multithreaded .xz encoder
|
||||
*
|
||||
* Since doing the encoding in threaded mode doesn't affect the memory
|
||||
* requirements of single-threaded decompressor, you can use
|
||||
* lzma_easy_decoder_memusage(options->preset) or
|
||||
* lzma_raw_decoder_memusage(options->filters) to calculate
|
||||
* the decompressor memory requirements.
|
||||
*
|
||||
* \param options Compression options
|
||||
*
|
||||
* \return Number of bytes of memory required for encoding with the
|
||||
* given options. If an error occurs, for example due to
|
||||
* unsupported preset or filter chain, UINT64_MAX is returned.
|
||||
*/
|
||||
extern LZMA_API(uint64_t) lzma_stream_encoder_mt_memusage(
|
||||
const lzma_mt *options) lzma_nothrow lzma_attr_pure;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialize multithreaded .xz Stream encoder
|
||||
*
|
||||
* This provides the functionality of lzma_easy_encoder() and
|
||||
* lzma_stream_encoder() as a single function for multithreaded use.
|
||||
*
|
||||
* The supported actions for lzma_code() are LZMA_RUN, LZMA_FULL_FLUSH,
|
||||
* LZMA_FULL_BARRIER, and LZMA_FINISH. Support for LZMA_SYNC_FLUSH might be
|
||||
* added in the future.
|
||||
*
|
||||
* \param strm Pointer to properly prepared lzma_stream
|
||||
* \param options Pointer to multithreaded compression options
|
||||
*
|
||||
* \return - LZMA_OK
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_UNSUPPORTED_CHECK
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_stream_encoder_mt(
|
||||
lzma_stream *strm, const lzma_mt *options)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialize .lzma encoder (legacy file format)
|
||||
*
|
||||
* The .lzma format is sometimes called the LZMA_Alone format, which is the
|
||||
* reason for the name of this function. The .lzma format supports only the
|
||||
* LZMA1 filter. There is no support for integrity checks like CRC32.
|
||||
*
|
||||
* Use this function if and only if you need to create files readable by
|
||||
* legacy LZMA tools such as LZMA Utils 4.32.x. Moving to the .xz format
|
||||
* is strongly recommended.
|
||||
*
|
||||
* The valid action values for lzma_code() are LZMA_RUN and LZMA_FINISH.
|
||||
* No kind of flushing is supported, because the file format doesn't make
|
||||
* it possible.
|
||||
*
|
||||
* \return - LZMA_OK
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_alone_encoder(
|
||||
lzma_stream *strm, const lzma_options_lzma *options)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Calculate output buffer size for single-call Stream encoder
|
||||
*
|
||||
* When trying to compress uncompressible data, the encoded size will be
|
||||
* slightly bigger than the input data. This function calculates how much
|
||||
* output buffer space is required to be sure that lzma_stream_buffer_encode()
|
||||
* doesn't return LZMA_BUF_ERROR.
|
||||
*
|
||||
* The calculated value is not exact, but it is guaranteed to be big enough.
|
||||
* The actual maximum output space required may be slightly smaller (up to
|
||||
* about 100 bytes). This should not be a problem in practice.
|
||||
*
|
||||
* If the calculated maximum size doesn't fit into size_t or would make the
|
||||
* Stream grow past LZMA_VLI_MAX (which should never happen in practice),
|
||||
* zero is returned to indicate the error.
|
||||
*
|
||||
* \note The limit calculated by this function applies only to
|
||||
* single-call encoding. Multi-call encoding may (and probably
|
||||
* will) have larger maximum expansion when encoding
|
||||
* uncompressible data. Currently there is no function to
|
||||
* calculate the maximum expansion of multi-call encoding.
|
||||
*/
|
||||
extern LZMA_API(size_t) lzma_stream_buffer_bound(size_t uncompressed_size)
|
||||
lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Single-call .xz Stream encoder
|
||||
*
|
||||
* \param filters Array of filters. This must be terminated with
|
||||
* filters[n].id = LZMA_VLI_UNKNOWN. See filter.h
|
||||
* for more information.
|
||||
* \param check Type of the integrity check to calculate from
|
||||
* uncompressed data.
|
||||
* \param allocator lzma_allocator for custom allocator functions.
|
||||
* Set to NULL to use malloc() and free().
|
||||
* \param in Beginning of the input buffer
|
||||
* \param in_size Size of the input buffer
|
||||
* \param out Beginning of the output buffer
|
||||
* \param out_pos The next byte will be written to out[*out_pos].
|
||||
* *out_pos is updated only if encoding succeeds.
|
||||
* \param out_size Size of the out buffer; the first byte into
|
||||
* which no data is written to is out[out_size].
|
||||
*
|
||||
* \return - LZMA_OK: Encoding was successful.
|
||||
* - LZMA_BUF_ERROR: Not enough output buffer space.
|
||||
* - LZMA_UNSUPPORTED_CHECK
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_DATA_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_stream_buffer_encode(
|
||||
lzma_filter *filters, lzma_check check,
|
||||
const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/************
|
||||
* Decoding *
|
||||
************/
|
||||
|
||||
/**
|
||||
* This flag makes lzma_code() return LZMA_NO_CHECK if the input stream
|
||||
* being decoded has no integrity check. Note that when used with
|
||||
* lzma_auto_decoder(), all .lzma files will trigger LZMA_NO_CHECK
|
||||
* if LZMA_TELL_NO_CHECK is used.
|
||||
*/
|
||||
#define LZMA_TELL_NO_CHECK UINT32_C(0x01)
|
||||
|
||||
|
||||
/**
|
||||
* This flag makes lzma_code() return LZMA_UNSUPPORTED_CHECK if the input
|
||||
* stream has an integrity check, but the type of the integrity check is not
|
||||
* supported by this liblzma version or build. Such files can still be
|
||||
* decoded, but the integrity check cannot be verified.
|
||||
*/
|
||||
#define LZMA_TELL_UNSUPPORTED_CHECK UINT32_C(0x02)
|
||||
|
||||
|
||||
/**
|
||||
* This flag makes lzma_code() return LZMA_GET_CHECK as soon as the type
|
||||
* of the integrity check is known. The type can then be got with
|
||||
* lzma_get_check().
|
||||
*/
|
||||
#define LZMA_TELL_ANY_CHECK UINT32_C(0x04)
|
||||
|
||||
|
||||
/**
|
||||
* This flag makes lzma_code() not calculate and verify the integrity check
|
||||
* of the compressed data in .xz files. This means that invalid integrity
|
||||
* check values won't be detected and LZMA_DATA_ERROR won't be returned in
|
||||
* such cases.
|
||||
*
|
||||
* This flag only affects the checks of the compressed data itself; the CRC32
|
||||
* values in the .xz headers will still be verified normally.
|
||||
*
|
||||
* Don't use this flag unless you know what you are doing. Possible reasons
|
||||
* to use this flag:
|
||||
*
|
||||
* - Trying to recover data from a corrupt .xz file.
|
||||
*
|
||||
* - Speeding up decompression, which matters mostly with SHA-256
|
||||
* or with files that have compressed extremely well. It's recommended
|
||||
* to not use this flag for this purpose unless the file integrity is
|
||||
* verified externally in some other way.
|
||||
*
|
||||
* Support for this flag was added in liblzma 5.1.4beta.
|
||||
*/
|
||||
#define LZMA_IGNORE_CHECK UINT32_C(0x10)
|
||||
|
||||
|
||||
/**
|
||||
* This flag enables decoding of concatenated files with file formats that
|
||||
* allow concatenating compressed files as is. From the formats currently
|
||||
* supported by liblzma, only the .xz format allows concatenated files.
|
||||
* Concatenated files are not allowed with the legacy .lzma format.
|
||||
*
|
||||
* This flag also affects the usage of the `action' argument for lzma_code().
|
||||
* When LZMA_CONCATENATED is used, lzma_code() won't return LZMA_STREAM_END
|
||||
* unless LZMA_FINISH is used as `action'. Thus, the application has to set
|
||||
* LZMA_FINISH in the same way as it does when encoding.
|
||||
*
|
||||
* If LZMA_CONCATENATED is not used, the decoders still accept LZMA_FINISH
|
||||
* as `action' for lzma_code(), but the usage of LZMA_FINISH isn't required.
|
||||
*/
|
||||
#define LZMA_CONCATENATED UINT32_C(0x08)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialize .xz Stream decoder
|
||||
*
|
||||
* \param strm Pointer to properly prepared lzma_stream
|
||||
* \param memlimit Memory usage limit as bytes. Use UINT64_MAX
|
||||
* to effectively disable the limiter.
|
||||
* \param flags Bitwise-or of zero or more of the decoder flags:
|
||||
* LZMA_TELL_NO_CHECK, LZMA_TELL_UNSUPPORTED_CHECK,
|
||||
* LZMA_TELL_ANY_CHECK, LZMA_CONCATENATED
|
||||
*
|
||||
* \return - LZMA_OK: Initialization was successful.
|
||||
* - LZMA_MEM_ERROR: Cannot allocate memory.
|
||||
* - LZMA_OPTIONS_ERROR: Unsupported flags
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_stream_decoder(
|
||||
lzma_stream *strm, uint64_t memlimit, uint32_t flags)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Decode .xz Streams and .lzma files with autodetection
|
||||
*
|
||||
* This decoder autodetects between the .xz and .lzma file formats, and
|
||||
* calls lzma_stream_decoder() or lzma_alone_decoder() once the type
|
||||
* of the input file has been detected.
|
||||
*
|
||||
* \param strm Pointer to properly prepared lzma_stream
|
||||
* \param memlimit Memory usage limit as bytes. Use UINT64_MAX
|
||||
* to effectively disable the limiter.
|
||||
* \param flags Bitwise-or of flags, or zero for no flags.
|
||||
*
|
||||
* \return - LZMA_OK: Initialization was successful.
|
||||
* - LZMA_MEM_ERROR: Cannot allocate memory.
|
||||
* - LZMA_OPTIONS_ERROR: Unsupported flags
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_auto_decoder(
|
||||
lzma_stream *strm, uint64_t memlimit, uint32_t flags)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialize .lzma decoder (legacy file format)
|
||||
*
|
||||
* Valid `action' arguments to lzma_code() are LZMA_RUN and LZMA_FINISH.
|
||||
* There is no need to use LZMA_FINISH, but allowing it may simplify
|
||||
* certain types of applications.
|
||||
*
|
||||
* \return - LZMA_OK
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_alone_decoder(
|
||||
lzma_stream *strm, uint64_t memlimit)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Single-call .xz Stream decoder
|
||||
*
|
||||
* \param memlimit Pointer to how much memory the decoder is allowed
|
||||
* to allocate. The value pointed by this pointer is
|
||||
* modified if and only if LZMA_MEMLIMIT_ERROR is
|
||||
* returned.
|
||||
* \param flags Bitwise-or of zero or more of the decoder flags:
|
||||
* LZMA_TELL_NO_CHECK, LZMA_TELL_UNSUPPORTED_CHECK,
|
||||
* LZMA_CONCATENATED. Note that LZMA_TELL_ANY_CHECK
|
||||
* is not allowed and will return LZMA_PROG_ERROR.
|
||||
* \param allocator lzma_allocator for custom allocator functions.
|
||||
* Set to NULL to use malloc() and free().
|
||||
* \param in Beginning of the input buffer
|
||||
* \param in_pos The next byte will be read from in[*in_pos].
|
||||
* *in_pos is updated only if decoding succeeds.
|
||||
* \param in_size Size of the input buffer; the first byte that
|
||||
* won't be read is in[in_size].
|
||||
* \param out Beginning of the output buffer
|
||||
* \param out_pos The next byte will be written to out[*out_pos].
|
||||
* *out_pos is updated only if decoding succeeds.
|
||||
* \param out_size Size of the out buffer; the first byte into
|
||||
* which no data is written to is out[out_size].
|
||||
*
|
||||
* \return - LZMA_OK: Decoding was successful.
|
||||
* - LZMA_FORMAT_ERROR
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_DATA_ERROR
|
||||
* - LZMA_NO_CHECK: This can be returned only if using
|
||||
* the LZMA_TELL_NO_CHECK flag.
|
||||
* - LZMA_UNSUPPORTED_CHECK: This can be returned only if using
|
||||
* the LZMA_TELL_UNSUPPORTED_CHECK flag.
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_MEMLIMIT_ERROR: Memory usage limit was reached.
|
||||
* The minimum required memlimit value was stored to *memlimit.
|
||||
* - LZMA_BUF_ERROR: Output buffer was too small.
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_stream_buffer_decode(
|
||||
uint64_t *memlimit, uint32_t flags,
|
||||
const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
+425
@@ -0,0 +1,425 @@
|
||||
/**
|
||||
* \file lzma/filter.h
|
||||
* \brief Common filter related types and functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author: Lasse Collin
|
||||
*
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*
|
||||
* See ../lzma.h for information about liblzma as a whole.
|
||||
*/
|
||||
|
||||
#ifndef LZMA_H_INTERNAL
|
||||
# error Never include this file directly. Use <lzma.h> instead.
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \brief Maximum number of filters in a chain
|
||||
*
|
||||
* A filter chain can have 1-4 filters, of which three are allowed to change
|
||||
* the size of the data. Usually only one or two filters are needed.
|
||||
*/
|
||||
#define LZMA_FILTERS_MAX 4
|
||||
|
||||
|
||||
/**
|
||||
* \brief Filter options
|
||||
*
|
||||
* This structure is used to pass Filter ID and a pointer filter's
|
||||
* options to liblzma. A few functions work with a single lzma_filter
|
||||
* structure, while most functions expect a filter chain.
|
||||
*
|
||||
* A filter chain is indicated with an array of lzma_filter structures.
|
||||
* The array is terminated with .id = LZMA_VLI_UNKNOWN. Thus, the filter
|
||||
* array must have LZMA_FILTERS_MAX + 1 elements (that is, five) to
|
||||
* be able to hold any arbitrary filter chain. This is important when
|
||||
* using lzma_block_header_decode() from block.h, because too small
|
||||
* array would make liblzma write past the end of the filters array.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* \brief Filter ID
|
||||
*
|
||||
* Use constants whose name begin with `LZMA_FILTER_' to specify
|
||||
* different filters. In an array of lzma_filter structures, use
|
||||
* LZMA_VLI_UNKNOWN to indicate end of filters.
|
||||
*
|
||||
* \note This is not an enum, because on some systems enums
|
||||
* cannot be 64-bit.
|
||||
*/
|
||||
lzma_vli id;
|
||||
|
||||
/**
|
||||
* \brief Pointer to filter-specific options structure
|
||||
*
|
||||
* If the filter doesn't need options, set this to NULL. If id is
|
||||
* set to LZMA_VLI_UNKNOWN, options is ignored, and thus
|
||||
* doesn't need be initialized.
|
||||
*/
|
||||
void *options;
|
||||
|
||||
} lzma_filter;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Test if the given Filter ID is supported for encoding
|
||||
*
|
||||
* Return true if the give Filter ID is supported for encoding by this
|
||||
* liblzma build. Otherwise false is returned.
|
||||
*
|
||||
* There is no way to list which filters are available in this particular
|
||||
* liblzma version and build. It would be useless, because the application
|
||||
* couldn't know what kind of options the filter would need.
|
||||
*/
|
||||
extern LZMA_API(lzma_bool) lzma_filter_encoder_is_supported(lzma_vli id)
|
||||
lzma_nothrow lzma_attr_const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Test if the given Filter ID is supported for decoding
|
||||
*
|
||||
* Return true if the give Filter ID is supported for decoding by this
|
||||
* liblzma build. Otherwise false is returned.
|
||||
*/
|
||||
extern LZMA_API(lzma_bool) lzma_filter_decoder_is_supported(lzma_vli id)
|
||||
lzma_nothrow lzma_attr_const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Copy the filters array
|
||||
*
|
||||
* Copy the Filter IDs and filter-specific options from src to dest.
|
||||
* Up to LZMA_FILTERS_MAX filters are copied, plus the terminating
|
||||
* .id == LZMA_VLI_UNKNOWN. Thus, dest should have at least
|
||||
* LZMA_FILTERS_MAX + 1 elements space unless the caller knows that
|
||||
* src is smaller than that.
|
||||
*
|
||||
* Unless the filter-specific options is NULL, the Filter ID has to be
|
||||
* supported by liblzma, because liblzma needs to know the size of every
|
||||
* filter-specific options structure. The filter-specific options are not
|
||||
* validated. If options is NULL, any unsupported Filter IDs are copied
|
||||
* without returning an error.
|
||||
*
|
||||
* Old filter-specific options in dest are not freed, so dest doesn't
|
||||
* need to be initialized by the caller in any way.
|
||||
*
|
||||
* If an error occurs, memory possibly already allocated by this function
|
||||
* is always freed.
|
||||
*
|
||||
* \return - LZMA_OK
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_OPTIONS_ERROR: Unsupported Filter ID and its options
|
||||
* is not NULL.
|
||||
* - LZMA_PROG_ERROR: src or dest is NULL.
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_filters_copy(
|
||||
const lzma_filter *src, lzma_filter *dest,
|
||||
const lzma_allocator *allocator) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Calculate approximate memory requirements for raw encoder
|
||||
*
|
||||
* This function can be used to calculate the memory requirements for
|
||||
* Block and Stream encoders too because Block and Stream encoders don't
|
||||
* need significantly more memory than raw encoder.
|
||||
*
|
||||
* \param filters Array of filters terminated with
|
||||
* .id == LZMA_VLI_UNKNOWN.
|
||||
*
|
||||
* \return Number of bytes of memory required for the given
|
||||
* filter chain when encoding. If an error occurs,
|
||||
* for example due to unsupported filter chain,
|
||||
* UINT64_MAX is returned.
|
||||
*/
|
||||
extern LZMA_API(uint64_t) lzma_raw_encoder_memusage(const lzma_filter *filters)
|
||||
lzma_nothrow lzma_attr_pure;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Calculate approximate memory requirements for raw decoder
|
||||
*
|
||||
* This function can be used to calculate the memory requirements for
|
||||
* Block and Stream decoders too because Block and Stream decoders don't
|
||||
* need significantly more memory than raw decoder.
|
||||
*
|
||||
* \param filters Array of filters terminated with
|
||||
* .id == LZMA_VLI_UNKNOWN.
|
||||
*
|
||||
* \return Number of bytes of memory required for the given
|
||||
* filter chain when decoding. If an error occurs,
|
||||
* for example due to unsupported filter chain,
|
||||
* UINT64_MAX is returned.
|
||||
*/
|
||||
extern LZMA_API(uint64_t) lzma_raw_decoder_memusage(const lzma_filter *filters)
|
||||
lzma_nothrow lzma_attr_pure;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialize raw encoder
|
||||
*
|
||||
* This function may be useful when implementing custom file formats.
|
||||
*
|
||||
* \param strm Pointer to properly prepared lzma_stream
|
||||
* \param filters Array of lzma_filter structures. The end of the
|
||||
* array must be marked with .id = LZMA_VLI_UNKNOWN.
|
||||
*
|
||||
* The `action' with lzma_code() can be LZMA_RUN, LZMA_SYNC_FLUSH (if the
|
||||
* filter chain supports it), or LZMA_FINISH.
|
||||
*
|
||||
* \return - LZMA_OK
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_raw_encoder(
|
||||
lzma_stream *strm, const lzma_filter *filters)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialize raw decoder
|
||||
*
|
||||
* The initialization of raw decoder goes similarly to raw encoder.
|
||||
*
|
||||
* The `action' with lzma_code() can be LZMA_RUN or LZMA_FINISH. Using
|
||||
* LZMA_FINISH is not required, it is supported just for convenience.
|
||||
*
|
||||
* \return - LZMA_OK
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_raw_decoder(
|
||||
lzma_stream *strm, const lzma_filter *filters)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Update the filter chain in the encoder
|
||||
*
|
||||
* This function is for advanced users only. This function has two slightly
|
||||
* different purposes:
|
||||
*
|
||||
* - After LZMA_FULL_FLUSH when using Stream encoder: Set a new filter
|
||||
* chain, which will be used starting from the next Block.
|
||||
*
|
||||
* - After LZMA_SYNC_FLUSH using Raw, Block, or Stream encoder: Change
|
||||
* the filter-specific options in the middle of encoding. The actual
|
||||
* filters in the chain (Filter IDs) cannot be changed. In the future,
|
||||
* it might become possible to change the filter options without
|
||||
* using LZMA_SYNC_FLUSH.
|
||||
*
|
||||
* While rarely useful, this function may be called also when no data has
|
||||
* been compressed yet. In that case, this function will behave as if
|
||||
* LZMA_FULL_FLUSH (Stream encoder) or LZMA_SYNC_FLUSH (Raw or Block
|
||||
* encoder) had been used right before calling this function.
|
||||
*
|
||||
* \return - LZMA_OK
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_MEMLIMIT_ERROR
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_filters_update(
|
||||
lzma_stream *strm, const lzma_filter *filters) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Single-call raw encoder
|
||||
*
|
||||
* \param filters Array of lzma_filter structures. The end of the
|
||||
* array must be marked with .id = LZMA_VLI_UNKNOWN.
|
||||
* \param allocator lzma_allocator for custom allocator functions.
|
||||
* Set to NULL to use malloc() and free().
|
||||
* \param in Beginning of the input buffer
|
||||
* \param in_size Size of the input buffer
|
||||
* \param out Beginning of the output buffer
|
||||
* \param out_pos The next byte will be written to out[*out_pos].
|
||||
* *out_pos is updated only if encoding succeeds.
|
||||
* \param out_size Size of the out buffer; the first byte into
|
||||
* which no data is written to is out[out_size].
|
||||
*
|
||||
* \return - LZMA_OK: Encoding was successful.
|
||||
* - LZMA_BUF_ERROR: Not enough output buffer space.
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_DATA_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*
|
||||
* \note There is no function to calculate how big output buffer
|
||||
* would surely be big enough. (lzma_stream_buffer_bound()
|
||||
* works only for lzma_stream_buffer_encode(); raw encoder
|
||||
* won't necessarily meet that bound.)
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_raw_buffer_encode(
|
||||
const lzma_filter *filters, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t in_size, uint8_t *out,
|
||||
size_t *out_pos, size_t out_size) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Single-call raw decoder
|
||||
*
|
||||
* \param filters Array of lzma_filter structures. The end of the
|
||||
* array must be marked with .id = LZMA_VLI_UNKNOWN.
|
||||
* \param allocator lzma_allocator for custom allocator functions.
|
||||
* Set to NULL to use malloc() and free().
|
||||
* \param in Beginning of the input buffer
|
||||
* \param in_pos The next byte will be read from in[*in_pos].
|
||||
* *in_pos is updated only if decoding succeeds.
|
||||
* \param in_size Size of the input buffer; the first byte that
|
||||
* won't be read is in[in_size].
|
||||
* \param out Beginning of the output buffer
|
||||
* \param out_pos The next byte will be written to out[*out_pos].
|
||||
* *out_pos is updated only if encoding succeeds.
|
||||
* \param out_size Size of the out buffer; the first byte into
|
||||
* which no data is written to is out[out_size].
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_raw_buffer_decode(
|
||||
const lzma_filter *filters, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the size of the Filter Properties field
|
||||
*
|
||||
* This function may be useful when implementing custom file formats
|
||||
* using the raw encoder and decoder.
|
||||
*
|
||||
* \param size Pointer to uint32_t to hold the size of the properties
|
||||
* \param filter Filter ID and options (the size of the properties may
|
||||
* vary depending on the options)
|
||||
*
|
||||
* \return - LZMA_OK
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*
|
||||
* \note This function validates the Filter ID, but does not
|
||||
* necessarily validate the options. Thus, it is possible
|
||||
* that this returns LZMA_OK while the following call to
|
||||
* lzma_properties_encode() returns LZMA_OPTIONS_ERROR.
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_properties_size(
|
||||
uint32_t *size, const lzma_filter *filter) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Encode the Filter Properties field
|
||||
*
|
||||
* \param filter Filter ID and options
|
||||
* \param props Buffer to hold the encoded options. The size of
|
||||
* buffer must have been already determined with
|
||||
* lzma_properties_size().
|
||||
*
|
||||
* \return - LZMA_OK
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*
|
||||
* \note Even this function won't validate more options than actually
|
||||
* necessary. Thus, it is possible that encoding the properties
|
||||
* succeeds but using the same options to initialize the encoder
|
||||
* will fail.
|
||||
*
|
||||
* \note If lzma_properties_size() indicated that the size
|
||||
* of the Filter Properties field is zero, calling
|
||||
* lzma_properties_encode() is not required, but it
|
||||
* won't do any harm either.
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_properties_encode(
|
||||
const lzma_filter *filter, uint8_t *props) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Decode the Filter Properties field
|
||||
*
|
||||
* \param filter filter->id must have been set to the correct
|
||||
* Filter ID. filter->options doesn't need to be
|
||||
* initialized (it's not freed by this function). The
|
||||
* decoded options will be stored to filter->options.
|
||||
* filter->options is set to NULL if there are no
|
||||
* properties or if an error occurs.
|
||||
* \param allocator Custom memory allocator used to allocate the
|
||||
* options. Set to NULL to use the default malloc(),
|
||||
* and in case of an error, also free().
|
||||
* \param props Input buffer containing the properties.
|
||||
* \param props_size Size of the properties. This must be the exact
|
||||
* size; giving too much or too little input will
|
||||
* return LZMA_OPTIONS_ERROR.
|
||||
*
|
||||
* \return - LZMA_OK
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_MEM_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_properties_decode(
|
||||
lzma_filter *filter, const lzma_allocator *allocator,
|
||||
const uint8_t *props, size_t props_size) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Calculate encoded size of a Filter Flags field
|
||||
*
|
||||
* Knowing the size of Filter Flags is useful to know when allocating
|
||||
* memory to hold the encoded Filter Flags.
|
||||
*
|
||||
* \param size Pointer to integer to hold the calculated size
|
||||
* \param filter Filter ID and associated options whose encoded
|
||||
* size is to be calculated
|
||||
*
|
||||
* \return - LZMA_OK: *size set successfully. Note that this doesn't
|
||||
* guarantee that filter->options is valid, thus
|
||||
* lzma_filter_flags_encode() may still fail.
|
||||
* - LZMA_OPTIONS_ERROR: Unknown Filter ID or unsupported options.
|
||||
* - LZMA_PROG_ERROR: Invalid options
|
||||
*
|
||||
* \note If you need to calculate size of List of Filter Flags,
|
||||
* you need to loop over every lzma_filter entry.
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_filter_flags_size(
|
||||
uint32_t *size, const lzma_filter *filter)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Encode Filter Flags into given buffer
|
||||
*
|
||||
* In contrast to some functions, this doesn't allocate the needed buffer.
|
||||
* This is due to how this function is used internally by liblzma.
|
||||
*
|
||||
* \param filter Filter ID and options to be encoded
|
||||
* \param out Beginning of the output buffer
|
||||
* \param out_pos out[*out_pos] is the next write position. This
|
||||
* is updated by the encoder.
|
||||
* \param out_size out[out_size] is the first byte to not write.
|
||||
*
|
||||
* \return - LZMA_OK: Encoding was successful.
|
||||
* - LZMA_OPTIONS_ERROR: Invalid or unsupported options.
|
||||
* - LZMA_PROG_ERROR: Invalid options or not enough output
|
||||
* buffer space (you should have checked it with
|
||||
* lzma_filter_flags_size()).
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_filter_flags_encode(const lzma_filter *filter,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Decode Filter Flags from given buffer
|
||||
*
|
||||
* The decoded result is stored into *filter. The old value of
|
||||
* filter->options is not free()d.
|
||||
*
|
||||
* \return - LZMA_OK
|
||||
* - LZMA_OPTIONS_ERROR
|
||||
* - LZMA_MEM_ERROR
|
||||
* - LZMA_PROG_ERROR
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_filter_flags_decode(
|
||||
lzma_filter *filter, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size)
|
||||
lzma_nothrow lzma_attr_warn_unused_result;
|
||||
+420
@@ -0,0 +1,420 @@
|
||||
/**
|
||||
* \file lzma/lzma12.h
|
||||
* \brief LZMA1 and LZMA2 filters
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author: Lasse Collin
|
||||
*
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*
|
||||
* See ../lzma.h for information about liblzma as a whole.
|
||||
*/
|
||||
|
||||
#ifndef LZMA_H_INTERNAL
|
||||
# error Never include this file directly. Use <lzma.h> instead.
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \brief LZMA1 Filter ID
|
||||
*
|
||||
* LZMA1 is the very same thing as what was called just LZMA in LZMA Utils,
|
||||
* 7-Zip, and LZMA SDK. It's called LZMA1 here to prevent developers from
|
||||
* accidentally using LZMA when they actually want LZMA2.
|
||||
*
|
||||
* LZMA1 shouldn't be used for new applications unless you _really_ know
|
||||
* what you are doing. LZMA2 is almost always a better choice.
|
||||
*/
|
||||
#define LZMA_FILTER_LZMA1 LZMA_VLI_C(0x4000000000000001)
|
||||
|
||||
/**
|
||||
* \brief LZMA2 Filter ID
|
||||
*
|
||||
* Usually you want this instead of LZMA1. Compared to LZMA1, LZMA2 adds
|
||||
* support for LZMA_SYNC_FLUSH, uncompressed chunks (smaller expansion
|
||||
* when trying to compress uncompressible data), possibility to change
|
||||
* lc/lp/pb in the middle of encoding, and some other internal improvements.
|
||||
*/
|
||||
#define LZMA_FILTER_LZMA2 LZMA_VLI_C(0x21)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Match finders
|
||||
*
|
||||
* Match finder has major effect on both speed and compression ratio.
|
||||
* Usually hash chains are faster than binary trees.
|
||||
*
|
||||
* If you will use LZMA_SYNC_FLUSH often, the hash chains may be a better
|
||||
* choice, because binary trees get much higher compression ratio penalty
|
||||
* with LZMA_SYNC_FLUSH.
|
||||
*
|
||||
* The memory usage formulas are only rough estimates, which are closest to
|
||||
* reality when dict_size is a power of two. The formulas are more complex
|
||||
* in reality, and can also change a little between liblzma versions. Use
|
||||
* lzma_raw_encoder_memusage() to get more accurate estimate of memory usage.
|
||||
*/
|
||||
typedef enum {
|
||||
LZMA_MF_HC3 = 0x03,
|
||||
/**<
|
||||
* \brief Hash Chain with 2- and 3-byte hashing
|
||||
*
|
||||
* Minimum nice_len: 3
|
||||
*
|
||||
* Memory usage:
|
||||
* - dict_size <= 16 MiB: dict_size * 7.5
|
||||
* - dict_size > 16 MiB: dict_size * 5.5 + 64 MiB
|
||||
*/
|
||||
|
||||
LZMA_MF_HC4 = 0x04,
|
||||
/**<
|
||||
* \brief Hash Chain with 2-, 3-, and 4-byte hashing
|
||||
*
|
||||
* Minimum nice_len: 4
|
||||
*
|
||||
* Memory usage:
|
||||
* - dict_size <= 32 MiB: dict_size * 7.5
|
||||
* - dict_size > 32 MiB: dict_size * 6.5
|
||||
*/
|
||||
|
||||
LZMA_MF_BT2 = 0x12,
|
||||
/**<
|
||||
* \brief Binary Tree with 2-byte hashing
|
||||
*
|
||||
* Minimum nice_len: 2
|
||||
*
|
||||
* Memory usage: dict_size * 9.5
|
||||
*/
|
||||
|
||||
LZMA_MF_BT3 = 0x13,
|
||||
/**<
|
||||
* \brief Binary Tree with 2- and 3-byte hashing
|
||||
*
|
||||
* Minimum nice_len: 3
|
||||
*
|
||||
* Memory usage:
|
||||
* - dict_size <= 16 MiB: dict_size * 11.5
|
||||
* - dict_size > 16 MiB: dict_size * 9.5 + 64 MiB
|
||||
*/
|
||||
|
||||
LZMA_MF_BT4 = 0x14
|
||||
/**<
|
||||
* \brief Binary Tree with 2-, 3-, and 4-byte hashing
|
||||
*
|
||||
* Minimum nice_len: 4
|
||||
*
|
||||
* Memory usage:
|
||||
* - dict_size <= 32 MiB: dict_size * 11.5
|
||||
* - dict_size > 32 MiB: dict_size * 10.5
|
||||
*/
|
||||
} lzma_match_finder;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Test if given match finder is supported
|
||||
*
|
||||
* Return true if the given match finder is supported by this liblzma build.
|
||||
* Otherwise false is returned. It is safe to call this with a value that
|
||||
* isn't listed in lzma_match_finder enumeration; the return value will be
|
||||
* false.
|
||||
*
|
||||
* There is no way to list which match finders are available in this
|
||||
* particular liblzma version and build. It would be useless, because
|
||||
* a new match finder, which the application developer wasn't aware,
|
||||
* could require giving additional options to the encoder that the older
|
||||
* match finders don't need.
|
||||
*/
|
||||
extern LZMA_API(lzma_bool) lzma_mf_is_supported(lzma_match_finder match_finder)
|
||||
lzma_nothrow lzma_attr_const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Compression modes
|
||||
*
|
||||
* This selects the function used to analyze the data produced by the match
|
||||
* finder.
|
||||
*/
|
||||
typedef enum {
|
||||
LZMA_MODE_FAST = 1,
|
||||
/**<
|
||||
* \brief Fast compression
|
||||
*
|
||||
* Fast mode is usually at its best when combined with
|
||||
* a hash chain match finder.
|
||||
*/
|
||||
|
||||
LZMA_MODE_NORMAL = 2
|
||||
/**<
|
||||
* \brief Normal compression
|
||||
*
|
||||
* This is usually notably slower than fast mode. Use this
|
||||
* together with binary tree match finders to expose the
|
||||
* full potential of the LZMA1 or LZMA2 encoder.
|
||||
*/
|
||||
} lzma_mode;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Test if given compression mode is supported
|
||||
*
|
||||
* Return true if the given compression mode is supported by this liblzma
|
||||
* build. Otherwise false is returned. It is safe to call this with a value
|
||||
* that isn't listed in lzma_mode enumeration; the return value will be false.
|
||||
*
|
||||
* There is no way to list which modes are available in this particular
|
||||
* liblzma version and build. It would be useless, because a new compression
|
||||
* mode, which the application developer wasn't aware, could require giving
|
||||
* additional options to the encoder that the older modes don't need.
|
||||
*/
|
||||
extern LZMA_API(lzma_bool) lzma_mode_is_supported(lzma_mode mode)
|
||||
lzma_nothrow lzma_attr_const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Options specific to the LZMA1 and LZMA2 filters
|
||||
*
|
||||
* Since LZMA1 and LZMA2 share most of the code, it's simplest to share
|
||||
* the options structure too. For encoding, all but the reserved variables
|
||||
* need to be initialized unless specifically mentioned otherwise.
|
||||
* lzma_lzma_preset() can be used to get a good starting point.
|
||||
*
|
||||
* For raw decoding, both LZMA1 and LZMA2 need dict_size, preset_dict, and
|
||||
* preset_dict_size (if preset_dict != NULL). LZMA1 needs also lc, lp, and pb.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* \brief Dictionary size in bytes
|
||||
*
|
||||
* Dictionary size indicates how many bytes of the recently processed
|
||||
* uncompressed data is kept in memory. One method to reduce size of
|
||||
* the uncompressed data is to store distance-length pairs, which
|
||||
* indicate what data to repeat from the dictionary buffer. Thus,
|
||||
* the bigger the dictionary, the better the compression ratio
|
||||
* usually is.
|
||||
*
|
||||
* Maximum size of the dictionary depends on multiple things:
|
||||
* - Memory usage limit
|
||||
* - Available address space (not a problem on 64-bit systems)
|
||||
* - Selected match finder (encoder only)
|
||||
*
|
||||
* Currently the maximum dictionary size for encoding is 1.5 GiB
|
||||
* (i.e. (UINT32_C(1) << 30) + (UINT32_C(1) << 29)) even on 64-bit
|
||||
* systems for certain match finder implementation reasons. In the
|
||||
* future, there may be match finders that support bigger
|
||||
* dictionaries.
|
||||
*
|
||||
* Decoder already supports dictionaries up to 4 GiB - 1 B (i.e.
|
||||
* UINT32_MAX), so increasing the maximum dictionary size of the
|
||||
* encoder won't cause problems for old decoders.
|
||||
*
|
||||
* Because extremely small dictionaries sizes would have unneeded
|
||||
* overhead in the decoder, the minimum dictionary size is 4096 bytes.
|
||||
*
|
||||
* \note When decoding, too big dictionary does no other harm
|
||||
* than wasting memory.
|
||||
*/
|
||||
uint32_t dict_size;
|
||||
# define LZMA_DICT_SIZE_MIN UINT32_C(4096)
|
||||
# define LZMA_DICT_SIZE_DEFAULT (UINT32_C(1) << 23)
|
||||
|
||||
/**
|
||||
* \brief Pointer to an initial dictionary
|
||||
*
|
||||
* It is possible to initialize the LZ77 history window using
|
||||
* a preset dictionary. It is useful when compressing many
|
||||
* similar, relatively small chunks of data independently from
|
||||
* each other. The preset dictionary should contain typical
|
||||
* strings that occur in the files being compressed. The most
|
||||
* probable strings should be near the end of the preset dictionary.
|
||||
*
|
||||
* This feature should be used only in special situations. For
|
||||
* now, it works correctly only with raw encoding and decoding.
|
||||
* Currently none of the container formats supported by
|
||||
* liblzma allow preset dictionary when decoding, thus if
|
||||
* you create a .xz or .lzma file with preset dictionary, it
|
||||
* cannot be decoded with the regular decoder functions. In the
|
||||
* future, the .xz format will likely get support for preset
|
||||
* dictionary though.
|
||||
*/
|
||||
const uint8_t *preset_dict;
|
||||
|
||||
/**
|
||||
* \brief Size of the preset dictionary
|
||||
*
|
||||
* Specifies the size of the preset dictionary. If the size is
|
||||
* bigger than dict_size, only the last dict_size bytes are
|
||||
* processed.
|
||||
*
|
||||
* This variable is read only when preset_dict is not NULL.
|
||||
* If preset_dict is not NULL but preset_dict_size is zero,
|
||||
* no preset dictionary is used (identical to only setting
|
||||
* preset_dict to NULL).
|
||||
*/
|
||||
uint32_t preset_dict_size;
|
||||
|
||||
/**
|
||||
* \brief Number of literal context bits
|
||||
*
|
||||
* How many of the highest bits of the previous uncompressed
|
||||
* eight-bit byte (also known as `literal') are taken into
|
||||
* account when predicting the bits of the next literal.
|
||||
*
|
||||
* E.g. in typical English text, an upper-case letter is
|
||||
* often followed by a lower-case letter, and a lower-case
|
||||
* letter is usually followed by another lower-case letter.
|
||||
* In the US-ASCII character set, the highest three bits are 010
|
||||
* for upper-case letters and 011 for lower-case letters.
|
||||
* When lc is at least 3, the literal coding can take advantage of
|
||||
* this property in the uncompressed data.
|
||||
*
|
||||
* There is a limit that applies to literal context bits and literal
|
||||
* position bits together: lc + lp <= 4. Without this limit the
|
||||
* decoding could become very slow, which could have security related
|
||||
* results in some cases like email servers doing virus scanning.
|
||||
* This limit also simplifies the internal implementation in liblzma.
|
||||
*
|
||||
* There may be LZMA1 streams that have lc + lp > 4 (maximum possible
|
||||
* lc would be 8). It is not possible to decode such streams with
|
||||
* liblzma.
|
||||
*/
|
||||
uint32_t lc;
|
||||
# define LZMA_LCLP_MIN 0
|
||||
# define LZMA_LCLP_MAX 4
|
||||
# define LZMA_LC_DEFAULT 3
|
||||
|
||||
/**
|
||||
* \brief Number of literal position bits
|
||||
*
|
||||
* lp affects what kind of alignment in the uncompressed data is
|
||||
* assumed when encoding literals. A literal is a single 8-bit byte.
|
||||
* See pb below for more information about alignment.
|
||||
*/
|
||||
uint32_t lp;
|
||||
# define LZMA_LP_DEFAULT 0
|
||||
|
||||
/**
|
||||
* \brief Number of position bits
|
||||
*
|
||||
* pb affects what kind of alignment in the uncompressed data is
|
||||
* assumed in general. The default means four-byte alignment
|
||||
* (2^ pb =2^2=4), which is often a good choice when there's
|
||||
* no better guess.
|
||||
*
|
||||
* When the aligment is known, setting pb accordingly may reduce
|
||||
* the file size a little. E.g. with text files having one-byte
|
||||
* alignment (US-ASCII, ISO-8859-*, UTF-8), setting pb=0 can
|
||||
* improve compression slightly. For UTF-16 text, pb=1 is a good
|
||||
* choice. If the alignment is an odd number like 3 bytes, pb=0
|
||||
* might be the best choice.
|
||||
*
|
||||
* Even though the assumed alignment can be adjusted with pb and
|
||||
* lp, LZMA1 and LZMA2 still slightly favor 16-byte alignment.
|
||||
* It might be worth taking into account when designing file formats
|
||||
* that are likely to be often compressed with LZMA1 or LZMA2.
|
||||
*/
|
||||
uint32_t pb;
|
||||
# define LZMA_PB_MIN 0
|
||||
# define LZMA_PB_MAX 4
|
||||
# define LZMA_PB_DEFAULT 2
|
||||
|
||||
/** Compression mode */
|
||||
lzma_mode mode;
|
||||
|
||||
/**
|
||||
* \brief Nice length of a match
|
||||
*
|
||||
* This determines how many bytes the encoder compares from the match
|
||||
* candidates when looking for the best match. Once a match of at
|
||||
* least nice_len bytes long is found, the encoder stops looking for
|
||||
* better candidates and encodes the match. (Naturally, if the found
|
||||
* match is actually longer than nice_len, the actual length is
|
||||
* encoded; it's not truncated to nice_len.)
|
||||
*
|
||||
* Bigger values usually increase the compression ratio and
|
||||
* compression time. For most files, 32 to 128 is a good value,
|
||||
* which gives very good compression ratio at good speed.
|
||||
*
|
||||
* The exact minimum value depends on the match finder. The maximum
|
||||
* is 273, which is the maximum length of a match that LZMA1 and
|
||||
* LZMA2 can encode.
|
||||
*/
|
||||
uint32_t nice_len;
|
||||
|
||||
/** Match finder ID */
|
||||
lzma_match_finder mf;
|
||||
|
||||
/**
|
||||
* \brief Maximum search depth in the match finder
|
||||
*
|
||||
* For every input byte, match finder searches through the hash chain
|
||||
* or binary tree in a loop, each iteration going one step deeper in
|
||||
* the chain or tree. The searching stops if
|
||||
* - a match of at least nice_len bytes long is found;
|
||||
* - all match candidates from the hash chain or binary tree have
|
||||
* been checked; or
|
||||
* - maximum search depth is reached.
|
||||
*
|
||||
* Maximum search depth is needed to prevent the match finder from
|
||||
* wasting too much time in case there are lots of short match
|
||||
* candidates. On the other hand, stopping the search before all
|
||||
* candidates have been checked can reduce compression ratio.
|
||||
*
|
||||
* Setting depth to zero tells liblzma to use an automatic default
|
||||
* value, that depends on the selected match finder and nice_len.
|
||||
* The default is in the range [4, 200] or so (it may vary between
|
||||
* liblzma versions).
|
||||
*
|
||||
* Using a bigger depth value than the default can increase
|
||||
* compression ratio in some cases. There is no strict maximum value,
|
||||
* but high values (thousands or millions) should be used with care:
|
||||
* the encoder could remain fast enough with typical input, but
|
||||
* malicious input could cause the match finder to slow down
|
||||
* dramatically, possibly creating a denial of service attack.
|
||||
*/
|
||||
uint32_t depth;
|
||||
|
||||
/*
|
||||
* Reserved space to allow possible future extensions without
|
||||
* breaking the ABI. You should not touch these, because the names
|
||||
* of these variables may change. These are and will never be used
|
||||
* with the currently supported options, so it is safe to leave these
|
||||
* uninitialized.
|
||||
*/
|
||||
uint32_t reserved_int1;
|
||||
uint32_t reserved_int2;
|
||||
uint32_t reserved_int3;
|
||||
uint32_t reserved_int4;
|
||||
uint32_t reserved_int5;
|
||||
uint32_t reserved_int6;
|
||||
uint32_t reserved_int7;
|
||||
uint32_t reserved_int8;
|
||||
lzma_reserved_enum reserved_enum1;
|
||||
lzma_reserved_enum reserved_enum2;
|
||||
lzma_reserved_enum reserved_enum3;
|
||||
lzma_reserved_enum reserved_enum4;
|
||||
void *reserved_ptr1;
|
||||
void *reserved_ptr2;
|
||||
|
||||
} lzma_options_lzma;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Set a compression preset to lzma_options_lzma structure
|
||||
*
|
||||
* 0 is the fastest and 9 is the slowest. These match the switches -0 .. -9
|
||||
* of the xz command line tool. In addition, it is possible to bitwise-or
|
||||
* flags to the preset. Currently only LZMA_PRESET_EXTREME is supported.
|
||||
* The flags are defined in container.h, because the flags are used also
|
||||
* with lzma_easy_encoder().
|
||||
*
|
||||
* The preset values are subject to changes between liblzma versions.
|
||||
*
|
||||
* This function is available only if LZMA1 or LZMA2 encoder has been enabled
|
||||
* when building liblzma.
|
||||
*
|
||||
* \return On success, false is returned. If the preset is not
|
||||
* supported, true is returned.
|
||||
*/
|
||||
extern LZMA_API(lzma_bool) lzma_lzma_preset(
|
||||
lzma_options_lzma *options, uint32_t preset) lzma_nothrow;
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* \file lzma/version.h
|
||||
* \brief Version number
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author: Lasse Collin
|
||||
*
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*
|
||||
* See ../lzma.h for information about liblzma as a whole.
|
||||
*/
|
||||
|
||||
#ifndef LZMA_H_INTERNAL
|
||||
# error Never include this file directly. Use <lzma.h> instead.
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Version number split into components
|
||||
*/
|
||||
#define LZMA_VERSION_MAJOR 5
|
||||
#define LZMA_VERSION_MINOR 2
|
||||
#define LZMA_VERSION_PATCH 3
|
||||
#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_STABLE
|
||||
|
||||
#ifndef LZMA_VERSION_COMMIT
|
||||
# define LZMA_VERSION_COMMIT ""
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Map symbolic stability levels to integers.
|
||||
*/
|
||||
#define LZMA_VERSION_STABILITY_ALPHA 0
|
||||
#define LZMA_VERSION_STABILITY_BETA 1
|
||||
#define LZMA_VERSION_STABILITY_STABLE 2
|
||||
|
||||
|
||||
/**
|
||||
* \brief Compile-time version number
|
||||
*
|
||||
* The version number is of format xyyyzzzs where
|
||||
* - x = major
|
||||
* - yyy = minor
|
||||
* - zzz = revision
|
||||
* - s indicates stability: 0 = alpha, 1 = beta, 2 = stable
|
||||
*
|
||||
* The same xyyyzzz triplet is never reused with different stability levels.
|
||||
* For example, if 5.1.0alpha has been released, there will never be 5.1.0beta
|
||||
* or 5.1.0 stable.
|
||||
*
|
||||
* \note The version number of liblzma has nothing to with
|
||||
* the version number of Igor Pavlov's LZMA SDK.
|
||||
*/
|
||||
#define LZMA_VERSION (LZMA_VERSION_MAJOR * UINT32_C(10000000) \
|
||||
+ LZMA_VERSION_MINOR * UINT32_C(10000) \
|
||||
+ LZMA_VERSION_PATCH * UINT32_C(10) \
|
||||
+ LZMA_VERSION_STABILITY)
|
||||
|
||||
|
||||
/*
|
||||
* Macros to construct the compile-time version string
|
||||
*/
|
||||
#if LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_ALPHA
|
||||
# define LZMA_VERSION_STABILITY_STRING "alpha"
|
||||
#elif LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_BETA
|
||||
# define LZMA_VERSION_STABILITY_STRING "beta"
|
||||
#elif LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_STABLE
|
||||
# define LZMA_VERSION_STABILITY_STRING ""
|
||||
#else
|
||||
# error Incorrect LZMA_VERSION_STABILITY
|
||||
#endif
|
||||
|
||||
#define LZMA_VERSION_STRING_C_(major, minor, patch, stability, commit) \
|
||||
#major "." #minor "." #patch stability commit
|
||||
|
||||
#define LZMA_VERSION_STRING_C(major, minor, patch, stability, commit) \
|
||||
LZMA_VERSION_STRING_C_(major, minor, patch, stability, commit)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Compile-time version as a string
|
||||
*
|
||||
* This can be for example "4.999.5alpha", "4.999.8beta", or "5.0.0" (stable
|
||||
* versions don't have any "stable" suffix). In future, a snapshot built
|
||||
* from source code repository may include an additional suffix, for example
|
||||
* "4.999.8beta-21-g1d92". The commit ID won't be available in numeric form
|
||||
* in LZMA_VERSION macro.
|
||||
*/
|
||||
#define LZMA_VERSION_STRING LZMA_VERSION_STRING_C( \
|
||||
LZMA_VERSION_MAJOR, LZMA_VERSION_MINOR, \
|
||||
LZMA_VERSION_PATCH, LZMA_VERSION_STABILITY_STRING, \
|
||||
LZMA_VERSION_COMMIT)
|
||||
|
||||
|
||||
/* #ifndef is needed for use with windres (MinGW or Cygwin). */
|
||||
#ifndef LZMA_H_INTERNAL_RC
|
||||
|
||||
/**
|
||||
* \brief Run-time version number as an integer
|
||||
*
|
||||
* Return the value of LZMA_VERSION macro at the compile time of liblzma.
|
||||
* This allows the application to compare if it was built against the same,
|
||||
* older, or newer version of liblzma that is currently running.
|
||||
*/
|
||||
extern LZMA_API(uint32_t) lzma_version_number(void)
|
||||
lzma_nothrow lzma_attr_const;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Run-time version as a string
|
||||
*
|
||||
* This function may be useful if you want to display which version of
|
||||
* liblzma your application is currently using.
|
||||
*/
|
||||
extern LZMA_API(const char *) lzma_version_string(void)
|
||||
lzma_nothrow lzma_attr_const;
|
||||
|
||||
#endif
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* \file lzma/vli.h
|
||||
* \brief Variable-length integer handling
|
||||
*
|
||||
* In the .xz format, most integers are encoded in a variable-length
|
||||
* representation, which is sometimes called little endian base-128 encoding.
|
||||
* This saves space when smaller values are more likely than bigger values.
|
||||
*
|
||||
* The encoding scheme encodes seven bits to every byte, using minimum
|
||||
* number of bytes required to represent the given value. Encodings that use
|
||||
* non-minimum number of bytes are invalid, thus every integer has exactly
|
||||
* one encoded representation. The maximum number of bits in a VLI is 63,
|
||||
* thus the vli argument must be less than or equal to UINT64_MAX / 2. You
|
||||
* should use LZMA_VLI_MAX for clarity.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Author: Lasse Collin
|
||||
*
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*
|
||||
* See ../lzma.h for information about liblzma as a whole.
|
||||
*/
|
||||
|
||||
#ifndef LZMA_H_INTERNAL
|
||||
# error Never include this file directly. Use <lzma.h> instead.
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \brief Maximum supported value of a variable-length integer
|
||||
*/
|
||||
#define LZMA_VLI_MAX (UINT64_MAX / 2)
|
||||
|
||||
/**
|
||||
* \brief VLI value to denote that the value is unknown
|
||||
*/
|
||||
#define LZMA_VLI_UNKNOWN UINT64_MAX
|
||||
|
||||
/**
|
||||
* \brief Maximum supported encoded length of variable length integers
|
||||
*/
|
||||
#define LZMA_VLI_BYTES_MAX 9
|
||||
|
||||
/**
|
||||
* \brief VLI constant suffix
|
||||
*/
|
||||
#define LZMA_VLI_C(n) UINT64_C(n)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Variable-length integer type
|
||||
*
|
||||
* Valid VLI values are in the range [0, LZMA_VLI_MAX]. Unknown value is
|
||||
* indicated with LZMA_VLI_UNKNOWN, which is the maximum value of the
|
||||
* underlaying integer type.
|
||||
*
|
||||
* lzma_vli will be uint64_t for the foreseeable future. If a bigger size
|
||||
* is needed in the future, it is guaranteed that 2 * LZMA_VLI_MAX will
|
||||
* not overflow lzma_vli. This simplifies integer overflow detection.
|
||||
*/
|
||||
typedef uint64_t lzma_vli;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Validate a variable-length integer
|
||||
*
|
||||
* This is useful to test that application has given acceptable values
|
||||
* for example in the uncompressed_size and compressed_size variables.
|
||||
*
|
||||
* \return True if the integer is representable as VLI or if it
|
||||
* indicates unknown value.
|
||||
*/
|
||||
#define lzma_vli_is_valid(vli) \
|
||||
((vli) <= LZMA_VLI_MAX || (vli) == LZMA_VLI_UNKNOWN)
|
||||
|
||||
|
||||
/**
|
||||
* \brief Encode a variable-length integer
|
||||
*
|
||||
* This function has two modes: single-call and multi-call. Single-call mode
|
||||
* encodes the whole integer at once; it is an error if the output buffer is
|
||||
* too small. Multi-call mode saves the position in *vli_pos, and thus it is
|
||||
* possible to continue encoding if the buffer becomes full before the whole
|
||||
* integer has been encoded.
|
||||
*
|
||||
* \param vli Integer to be encoded
|
||||
* \param vli_pos How many VLI-encoded bytes have already been written
|
||||
* out. When starting to encode a new integer in
|
||||
* multi-call mode, *vli_pos must be set to zero.
|
||||
* To use single-call encoding, set vli_pos to NULL.
|
||||
* \param out Beginning of the output buffer
|
||||
* \param out_pos The next byte will be written to out[*out_pos].
|
||||
* \param out_size Size of the out buffer; the first byte into
|
||||
* which no data is written to is out[out_size].
|
||||
*
|
||||
* \return Slightly different return values are used in multi-call and
|
||||
* single-call modes.
|
||||
*
|
||||
* Single-call (vli_pos == NULL):
|
||||
* - LZMA_OK: Integer successfully encoded.
|
||||
* - LZMA_PROG_ERROR: Arguments are not sane. This can be due
|
||||
* to too little output space; single-call mode doesn't use
|
||||
* LZMA_BUF_ERROR, since the application should have checked
|
||||
* the encoded size with lzma_vli_size().
|
||||
*
|
||||
* Multi-call (vli_pos != NULL):
|
||||
* - LZMA_OK: So far all OK, but the integer is not
|
||||
* completely written out yet.
|
||||
* - LZMA_STREAM_END: Integer successfully encoded.
|
||||
* - LZMA_BUF_ERROR: No output space was provided.
|
||||
* - LZMA_PROG_ERROR: Arguments are not sane.
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_vli_encode(lzma_vli vli, size_t *vli_pos,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Decode a variable-length integer
|
||||
*
|
||||
* Like lzma_vli_encode(), this function has single-call and multi-call modes.
|
||||
*
|
||||
* \param vli Pointer to decoded integer. The decoder will
|
||||
* initialize it to zero when *vli_pos == 0, so
|
||||
* application isn't required to initialize *vli.
|
||||
* \param vli_pos How many bytes have already been decoded. When
|
||||
* starting to decode a new integer in multi-call
|
||||
* mode, *vli_pos must be initialized to zero. To
|
||||
* use single-call decoding, set vli_pos to NULL.
|
||||
* \param in Beginning of the input buffer
|
||||
* \param in_pos The next byte will be read from in[*in_pos].
|
||||
* \param in_size Size of the input buffer; the first byte that
|
||||
* won't be read is in[in_size].
|
||||
*
|
||||
* \return Slightly different return values are used in multi-call and
|
||||
* single-call modes.
|
||||
*
|
||||
* Single-call (vli_pos == NULL):
|
||||
* - LZMA_OK: Integer successfully decoded.
|
||||
* - LZMA_DATA_ERROR: Integer is corrupt. This includes hitting
|
||||
* the end of the input buffer before the whole integer was
|
||||
* decoded; providing no input at all will use LZMA_DATA_ERROR.
|
||||
* - LZMA_PROG_ERROR: Arguments are not sane.
|
||||
*
|
||||
* Multi-call (vli_pos != NULL):
|
||||
* - LZMA_OK: So far all OK, but the integer is not
|
||||
* completely decoded yet.
|
||||
* - LZMA_STREAM_END: Integer successfully decoded.
|
||||
* - LZMA_DATA_ERROR: Integer is corrupt.
|
||||
* - LZMA_BUF_ERROR: No input was provided.
|
||||
* - LZMA_PROG_ERROR: Arguments are not sane.
|
||||
*/
|
||||
extern LZMA_API(lzma_ret) lzma_vli_decode(lzma_vli *vli, size_t *vli_pos,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size)
|
||||
lzma_nothrow;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Get the number of bytes required to encode a VLI
|
||||
*
|
||||
* \return Number of bytes on success (1-9). If vli isn't valid,
|
||||
* zero is returned.
|
||||
*/
|
||||
extern LZMA_API(uint32_t) lzma_vli_size(lzma_vli vli)
|
||||
lzma_nothrow lzma_attr_pure;
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file check.c
|
||||
/// \brief Single API to access different integrity checks
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "check.h"
|
||||
|
||||
|
||||
extern LZMA_API(lzma_bool)
|
||||
lzma_check_is_supported(lzma_check type)
|
||||
{
|
||||
if ((unsigned int)(type) > LZMA_CHECK_ID_MAX)
|
||||
return false;
|
||||
|
||||
static const lzma_bool available_checks[LZMA_CHECK_ID_MAX + 1] = {
|
||||
true, // LZMA_CHECK_NONE
|
||||
|
||||
#ifdef HAVE_CHECK_CRC32
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
false, // Reserved
|
||||
false, // Reserved
|
||||
|
||||
#ifdef HAVE_CHECK_CRC64
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
false, // Reserved
|
||||
false, // Reserved
|
||||
false, // Reserved
|
||||
false, // Reserved
|
||||
false, // Reserved
|
||||
|
||||
#ifdef HAVE_CHECK_SHA256
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
false, // Reserved
|
||||
false, // Reserved
|
||||
false, // Reserved
|
||||
false, // Reserved
|
||||
false, // Reserved
|
||||
};
|
||||
|
||||
return available_checks[(unsigned int)(type)];
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(uint32_t)
|
||||
lzma_check_size(lzma_check type)
|
||||
{
|
||||
if ((unsigned int)(type) > LZMA_CHECK_ID_MAX)
|
||||
return UINT32_MAX;
|
||||
|
||||
// See file-format.txt section 2.1.1.2.
|
||||
static const uint8_t check_sizes[LZMA_CHECK_ID_MAX + 1] = {
|
||||
0,
|
||||
4, 4, 4,
|
||||
8, 8, 8,
|
||||
16, 16, 16,
|
||||
32, 32, 32,
|
||||
64, 64, 64
|
||||
};
|
||||
|
||||
return check_sizes[(unsigned int)(type)];
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lzma_check_init(lzma_check_state *check, lzma_check type)
|
||||
{
|
||||
switch (type) {
|
||||
case LZMA_CHECK_NONE:
|
||||
break;
|
||||
|
||||
#ifdef HAVE_CHECK_CRC32
|
||||
case LZMA_CHECK_CRC32:
|
||||
check->state.crc32 = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHECK_CRC64
|
||||
case LZMA_CHECK_CRC64:
|
||||
check->state.crc64 = 0;
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHECK_SHA256
|
||||
case LZMA_CHECK_SHA256:
|
||||
lzma_sha256_init(check);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lzma_check_update(lzma_check_state *check, lzma_check type,
|
||||
const uint8_t *buf, size_t size)
|
||||
{
|
||||
switch (type) {
|
||||
#ifdef HAVE_CHECK_CRC32
|
||||
case LZMA_CHECK_CRC32:
|
||||
check->state.crc32 = lzma_crc32(buf, size, check->state.crc32);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHECK_CRC64
|
||||
case LZMA_CHECK_CRC64:
|
||||
check->state.crc64 = lzma_crc64(buf, size, check->state.crc64);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHECK_SHA256
|
||||
case LZMA_CHECK_SHA256:
|
||||
lzma_sha256_update(buf, size, check);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lzma_check_finish(lzma_check_state *check, lzma_check type)
|
||||
{
|
||||
switch (type) {
|
||||
#ifdef HAVE_CHECK_CRC32
|
||||
case LZMA_CHECK_CRC32:
|
||||
check->buffer.u32[0] = conv32le(check->state.crc32);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHECK_CRC64
|
||||
case LZMA_CHECK_CRC64:
|
||||
check->buffer.u64[0] = conv64le(check->state.crc64);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHECK_SHA256
|
||||
case LZMA_CHECK_SHA256:
|
||||
lzma_sha256_finish(check);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file check.h
|
||||
/// \brief Internal API to different integrity check functions
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_CHECK_H
|
||||
#define LZMA_CHECK_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
// If the function for external SHA-256 is missing, use the internal SHA-256
|
||||
// code. Due to how configure works, these defines can only get defined when
|
||||
// both a usable header and a type have already been found.
|
||||
#if !(defined(HAVE_CC_SHA256_INIT) \
|
||||
|| defined(HAVE_SHA256_INIT) \
|
||||
|| defined(HAVE_SHA256INIT))
|
||||
# define HAVE_INTERNAL_SHA256 1
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INTERNAL_SHA256)
|
||||
// Nothing
|
||||
#elif defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
|
||||
# include <CommonCrypto/CommonDigest.h>
|
||||
#elif defined(HAVE_SHA256_H)
|
||||
# include <sys/types.h>
|
||||
# include <sha256.h>
|
||||
#elif defined(HAVE_SHA2_H)
|
||||
# include <sys/types.h>
|
||||
# include <sha2.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INTERNAL_SHA256)
|
||||
/// State for the internal SHA-256 implementation
|
||||
typedef struct {
|
||||
/// Internal state
|
||||
uint32_t state[8];
|
||||
|
||||
/// Size of the message excluding padding
|
||||
uint64_t size;
|
||||
} lzma_sha256_state;
|
||||
#elif defined(HAVE_CC_SHA256_CTX)
|
||||
typedef CC_SHA256_CTX lzma_sha256_state;
|
||||
#elif defined(HAVE_SHA256_CTX)
|
||||
typedef SHA256_CTX lzma_sha256_state;
|
||||
#elif defined(HAVE_SHA2_CTX)
|
||||
typedef SHA2_CTX lzma_sha256_state;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INTERNAL_SHA256)
|
||||
// Nothing
|
||||
#elif defined(HAVE_CC_SHA256_INIT)
|
||||
# define LZMA_SHA256FUNC(x) CC_SHA256_ ## x
|
||||
#elif defined(HAVE_SHA256_INIT)
|
||||
# define LZMA_SHA256FUNC(x) SHA256_ ## x
|
||||
#elif defined(HAVE_SHA256INIT)
|
||||
# define LZMA_SHA256FUNC(x) SHA256 ## x
|
||||
#endif
|
||||
|
||||
// Index hashing needs the best possible hash function (preferably
|
||||
// a cryptographic hash) for maximum reliability.
|
||||
#if defined(HAVE_CHECK_SHA256)
|
||||
# define LZMA_CHECK_BEST LZMA_CHECK_SHA256
|
||||
#elif defined(HAVE_CHECK_CRC64)
|
||||
# define LZMA_CHECK_BEST LZMA_CHECK_CRC64
|
||||
#else
|
||||
# define LZMA_CHECK_BEST LZMA_CHECK_CRC32
|
||||
#endif
|
||||
|
||||
|
||||
/// \brief Structure to hold internal state of the check being calculated
|
||||
///
|
||||
/// \note This is not in the public API because this structure may
|
||||
/// change in future if new integrity check algorithms are added.
|
||||
typedef struct {
|
||||
/// Buffer to hold the final result and a temporary buffer for SHA256.
|
||||
union {
|
||||
uint8_t u8[64];
|
||||
uint32_t u32[16];
|
||||
uint64_t u64[8];
|
||||
} buffer;
|
||||
|
||||
/// Check-specific data
|
||||
union {
|
||||
uint32_t crc32;
|
||||
uint64_t crc64;
|
||||
lzma_sha256_state sha256;
|
||||
} state;
|
||||
|
||||
} lzma_check_state;
|
||||
|
||||
|
||||
/// lzma_crc32_table[0] is needed by LZ encoder so we need to keep
|
||||
/// the array two-dimensional.
|
||||
#ifdef HAVE_SMALL
|
||||
extern uint32_t lzma_crc32_table[1][256];
|
||||
extern void lzma_crc32_init(void);
|
||||
#else
|
||||
extern const uint32_t lzma_crc32_table[8][256];
|
||||
extern const uint64_t lzma_crc64_table[4][256];
|
||||
#endif
|
||||
|
||||
|
||||
/// \brief Initialize *check depending on type
|
||||
///
|
||||
/// \param check LZMA_OK on success. LZMA_UNSUPPORTED_CHECK if the type
|
||||
/// is not supported by the current version or build of
|
||||
/// liblzma. LZMA_PROG_ERROR if type > LZMA_CHECK_ID_MAX.
|
||||
extern void lzma_check_init(lzma_check_state *check, lzma_check type);
|
||||
|
||||
/// Update the check state
|
||||
extern void lzma_check_update(lzma_check_state *check, lzma_check type,
|
||||
const uint8_t *buf, size_t size);
|
||||
|
||||
/// Finish the check calculation and store the result to check->buffer.u8.
|
||||
extern void lzma_check_finish(lzma_check_state *check, lzma_check type);
|
||||
|
||||
|
||||
#ifndef LZMA_SHA256FUNC
|
||||
|
||||
/// Prepare SHA-256 state for new input.
|
||||
extern void lzma_sha256_init(lzma_check_state *check);
|
||||
|
||||
/// Update the SHA-256 hash state
|
||||
extern void lzma_sha256_update(
|
||||
const uint8_t *buf, size_t size, lzma_check_state *check);
|
||||
|
||||
/// Finish the SHA-256 calculation and store the result to check->buffer.u8.
|
||||
extern void lzma_sha256_finish(lzma_check_state *check);
|
||||
|
||||
|
||||
#else
|
||||
|
||||
static inline void
|
||||
lzma_sha256_init(lzma_check_state *check)
|
||||
{
|
||||
LZMA_SHA256FUNC(Init)(&check->state.sha256);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check)
|
||||
{
|
||||
#if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX
|
||||
// Darwin's CC_SHA256_Update takes uint32_t as the buffer size,
|
||||
// so use a loop to support size_t.
|
||||
while (size > UINT32_MAX) {
|
||||
LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX);
|
||||
buf += UINT32_MAX;
|
||||
size -= UINT32_MAX;
|
||||
}
|
||||
#endif
|
||||
|
||||
LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
lzma_sha256_finish(lzma_check_state *check)
|
||||
{
|
||||
LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,82 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file crc32.c
|
||||
/// \brief CRC32 calculation
|
||||
///
|
||||
/// Calculate the CRC32 using the slice-by-eight algorithm.
|
||||
/// It is explained in this document:
|
||||
/// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf
|
||||
/// The code in this file is not the same as in Intel's paper, but
|
||||
/// the basic principle is identical.
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "check.h"
|
||||
#include "crc_macros.h"
|
||||
|
||||
|
||||
// If you make any changes, do some bench marking! Seemingly unrelated
|
||||
// changes can very easily ruin the performance (and very probably is
|
||||
// very compiler dependent).
|
||||
extern LZMA_API(uint32_t)
|
||||
lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc)
|
||||
{
|
||||
crc = ~crc;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
crc = bswap32(crc);
|
||||
#endif
|
||||
|
||||
if (size > 8) {
|
||||
// Fix the alignment, if needed. The if statement above
|
||||
// ensures that this won't read past the end of buf[].
|
||||
while ((uintptr_t)(buf) & 7) {
|
||||
crc = lzma_crc32_table[0][*buf++ ^ A(crc)] ^ S8(crc);
|
||||
--size;
|
||||
}
|
||||
|
||||
// Calculate the position where to stop.
|
||||
const uint8_t *const limit = buf + (size & ~(size_t)(7));
|
||||
|
||||
// Calculate how many bytes must be calculated separately
|
||||
// before returning the result.
|
||||
size &= (size_t)(7);
|
||||
|
||||
// Calculate the CRC32 using the slice-by-eight algorithm.
|
||||
while (buf < limit) {
|
||||
crc ^= *(const uint32_t *)(buf);
|
||||
buf += 4;
|
||||
|
||||
crc = lzma_crc32_table[7][A(crc)]
|
||||
^ lzma_crc32_table[6][B(crc)]
|
||||
^ lzma_crc32_table[5][C(crc)]
|
||||
^ lzma_crc32_table[4][D(crc)];
|
||||
|
||||
const uint32_t tmp = *(const uint32_t *)(buf);
|
||||
buf += 4;
|
||||
|
||||
// At least with some compilers, it is critical for
|
||||
// performance, that the crc variable is XORed
|
||||
// between the two table-lookup pairs.
|
||||
crc = lzma_crc32_table[3][A(tmp)]
|
||||
^ lzma_crc32_table[2][B(tmp)]
|
||||
^ crc
|
||||
^ lzma_crc32_table[1][C(tmp)]
|
||||
^ lzma_crc32_table[0][D(tmp)];
|
||||
}
|
||||
}
|
||||
|
||||
while (size-- != 0)
|
||||
crc = lzma_crc32_table[0][*buf++ ^ A(crc)] ^ S8(crc);
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
crc = bswap32(crc);
|
||||
#endif
|
||||
|
||||
return ~crc;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file crc32_table.c
|
||||
/// \brief Precalculated CRC32 table with correct endianness
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# include "crc32_table_be.h"
|
||||
#else
|
||||
# include "crc32_table_le.h"
|
||||
#endif
|
||||
@@ -0,0 +1,525 @@
|
||||
/* This file has been automatically generated by crc32_tablegen.c. */
|
||||
|
||||
const uint32_t lzma_crc32_table[8][256] = {
|
||||
{
|
||||
0x00000000, 0x96300777, 0x2C610EEE, 0xBA510999,
|
||||
0x19C46D07, 0x8FF46A70, 0x35A563E9, 0xA395649E,
|
||||
0x3288DB0E, 0xA4B8DC79, 0x1EE9D5E0, 0x88D9D297,
|
||||
0x2B4CB609, 0xBD7CB17E, 0x072DB8E7, 0x911DBF90,
|
||||
0x6410B71D, 0xF220B06A, 0x4871B9F3, 0xDE41BE84,
|
||||
0x7DD4DA1A, 0xEBE4DD6D, 0x51B5D4F4, 0xC785D383,
|
||||
0x56986C13, 0xC0A86B64, 0x7AF962FD, 0xECC9658A,
|
||||
0x4F5C0114, 0xD96C0663, 0x633D0FFA, 0xF50D088D,
|
||||
0xC8206E3B, 0x5E10694C, 0xE44160D5, 0x727167A2,
|
||||
0xD1E4033C, 0x47D4044B, 0xFD850DD2, 0x6BB50AA5,
|
||||
0xFAA8B535, 0x6C98B242, 0xD6C9BBDB, 0x40F9BCAC,
|
||||
0xE36CD832, 0x755CDF45, 0xCF0DD6DC, 0x593DD1AB,
|
||||
0xAC30D926, 0x3A00DE51, 0x8051D7C8, 0x1661D0BF,
|
||||
0xB5F4B421, 0x23C4B356, 0x9995BACF, 0x0FA5BDB8,
|
||||
0x9EB80228, 0x0888055F, 0xB2D90CC6, 0x24E90BB1,
|
||||
0x877C6F2F, 0x114C6858, 0xAB1D61C1, 0x3D2D66B6,
|
||||
0x9041DC76, 0x0671DB01, 0xBC20D298, 0x2A10D5EF,
|
||||
0x8985B171, 0x1FB5B606, 0xA5E4BF9F, 0x33D4B8E8,
|
||||
0xA2C90778, 0x34F9000F, 0x8EA80996, 0x18980EE1,
|
||||
0xBB0D6A7F, 0x2D3D6D08, 0x976C6491, 0x015C63E6,
|
||||
0xF4516B6B, 0x62616C1C, 0xD8306585, 0x4E0062F2,
|
||||
0xED95066C, 0x7BA5011B, 0xC1F40882, 0x57C40FF5,
|
||||
0xC6D9B065, 0x50E9B712, 0xEAB8BE8B, 0x7C88B9FC,
|
||||
0xDF1DDD62, 0x492DDA15, 0xF37CD38C, 0x654CD4FB,
|
||||
0x5861B24D, 0xCE51B53A, 0x7400BCA3, 0xE230BBD4,
|
||||
0x41A5DF4A, 0xD795D83D, 0x6DC4D1A4, 0xFBF4D6D3,
|
||||
0x6AE96943, 0xFCD96E34, 0x468867AD, 0xD0B860DA,
|
||||
0x732D0444, 0xE51D0333, 0x5F4C0AAA, 0xC97C0DDD,
|
||||
0x3C710550, 0xAA410227, 0x10100BBE, 0x86200CC9,
|
||||
0x25B56857, 0xB3856F20, 0x09D466B9, 0x9FE461CE,
|
||||
0x0EF9DE5E, 0x98C9D929, 0x2298D0B0, 0xB4A8D7C7,
|
||||
0x173DB359, 0x810DB42E, 0x3B5CBDB7, 0xAD6CBAC0,
|
||||
0x2083B8ED, 0xB6B3BF9A, 0x0CE2B603, 0x9AD2B174,
|
||||
0x3947D5EA, 0xAF77D29D, 0x1526DB04, 0x8316DC73,
|
||||
0x120B63E3, 0x843B6494, 0x3E6A6D0D, 0xA85A6A7A,
|
||||
0x0BCF0EE4, 0x9DFF0993, 0x27AE000A, 0xB19E077D,
|
||||
0x44930FF0, 0xD2A30887, 0x68F2011E, 0xFEC20669,
|
||||
0x5D5762F7, 0xCB676580, 0x71366C19, 0xE7066B6E,
|
||||
0x761BD4FE, 0xE02BD389, 0x5A7ADA10, 0xCC4ADD67,
|
||||
0x6FDFB9F9, 0xF9EFBE8E, 0x43BEB717, 0xD58EB060,
|
||||
0xE8A3D6D6, 0x7E93D1A1, 0xC4C2D838, 0x52F2DF4F,
|
||||
0xF167BBD1, 0x6757BCA6, 0xDD06B53F, 0x4B36B248,
|
||||
0xDA2B0DD8, 0x4C1B0AAF, 0xF64A0336, 0x607A0441,
|
||||
0xC3EF60DF, 0x55DF67A8, 0xEF8E6E31, 0x79BE6946,
|
||||
0x8CB361CB, 0x1A8366BC, 0xA0D26F25, 0x36E26852,
|
||||
0x95770CCC, 0x03470BBB, 0xB9160222, 0x2F260555,
|
||||
0xBE3BBAC5, 0x280BBDB2, 0x925AB42B, 0x046AB35C,
|
||||
0xA7FFD7C2, 0x31CFD0B5, 0x8B9ED92C, 0x1DAEDE5B,
|
||||
0xB0C2649B, 0x26F263EC, 0x9CA36A75, 0x0A936D02,
|
||||
0xA906099C, 0x3F360EEB, 0x85670772, 0x13570005,
|
||||
0x824ABF95, 0x147AB8E2, 0xAE2BB17B, 0x381BB60C,
|
||||
0x9B8ED292, 0x0DBED5E5, 0xB7EFDC7C, 0x21DFDB0B,
|
||||
0xD4D2D386, 0x42E2D4F1, 0xF8B3DD68, 0x6E83DA1F,
|
||||
0xCD16BE81, 0x5B26B9F6, 0xE177B06F, 0x7747B718,
|
||||
0xE65A0888, 0x706A0FFF, 0xCA3B0666, 0x5C0B0111,
|
||||
0xFF9E658F, 0x69AE62F8, 0xD3FF6B61, 0x45CF6C16,
|
||||
0x78E20AA0, 0xEED20DD7, 0x5483044E, 0xC2B30339,
|
||||
0x612667A7, 0xF71660D0, 0x4D476949, 0xDB776E3E,
|
||||
0x4A6AD1AE, 0xDC5AD6D9, 0x660BDF40, 0xF03BD837,
|
||||
0x53AEBCA9, 0xC59EBBDE, 0x7FCFB247, 0xE9FFB530,
|
||||
0x1CF2BDBD, 0x8AC2BACA, 0x3093B353, 0xA6A3B424,
|
||||
0x0536D0BA, 0x9306D7CD, 0x2957DE54, 0xBF67D923,
|
||||
0x2E7A66B3, 0xB84A61C4, 0x021B685D, 0x942B6F2A,
|
||||
0x37BE0BB4, 0xA18E0CC3, 0x1BDF055A, 0x8DEF022D
|
||||
}, {
|
||||
0x00000000, 0x41311B19, 0x82623632, 0xC3532D2B,
|
||||
0x04C56C64, 0x45F4777D, 0x86A75A56, 0xC796414F,
|
||||
0x088AD9C8, 0x49BBC2D1, 0x8AE8EFFA, 0xCBD9F4E3,
|
||||
0x0C4FB5AC, 0x4D7EAEB5, 0x8E2D839E, 0xCF1C9887,
|
||||
0x5112C24A, 0x1023D953, 0xD370F478, 0x9241EF61,
|
||||
0x55D7AE2E, 0x14E6B537, 0xD7B5981C, 0x96848305,
|
||||
0x59981B82, 0x18A9009B, 0xDBFA2DB0, 0x9ACB36A9,
|
||||
0x5D5D77E6, 0x1C6C6CFF, 0xDF3F41D4, 0x9E0E5ACD,
|
||||
0xA2248495, 0xE3159F8C, 0x2046B2A7, 0x6177A9BE,
|
||||
0xA6E1E8F1, 0xE7D0F3E8, 0x2483DEC3, 0x65B2C5DA,
|
||||
0xAAAE5D5D, 0xEB9F4644, 0x28CC6B6F, 0x69FD7076,
|
||||
0xAE6B3139, 0xEF5A2A20, 0x2C09070B, 0x6D381C12,
|
||||
0xF33646DF, 0xB2075DC6, 0x715470ED, 0x30656BF4,
|
||||
0xF7F32ABB, 0xB6C231A2, 0x75911C89, 0x34A00790,
|
||||
0xFBBC9F17, 0xBA8D840E, 0x79DEA925, 0x38EFB23C,
|
||||
0xFF79F373, 0xBE48E86A, 0x7D1BC541, 0x3C2ADE58,
|
||||
0x054F79F0, 0x447E62E9, 0x872D4FC2, 0xC61C54DB,
|
||||
0x018A1594, 0x40BB0E8D, 0x83E823A6, 0xC2D938BF,
|
||||
0x0DC5A038, 0x4CF4BB21, 0x8FA7960A, 0xCE968D13,
|
||||
0x0900CC5C, 0x4831D745, 0x8B62FA6E, 0xCA53E177,
|
||||
0x545DBBBA, 0x156CA0A3, 0xD63F8D88, 0x970E9691,
|
||||
0x5098D7DE, 0x11A9CCC7, 0xD2FAE1EC, 0x93CBFAF5,
|
||||
0x5CD76272, 0x1DE6796B, 0xDEB55440, 0x9F844F59,
|
||||
0x58120E16, 0x1923150F, 0xDA703824, 0x9B41233D,
|
||||
0xA76BFD65, 0xE65AE67C, 0x2509CB57, 0x6438D04E,
|
||||
0xA3AE9101, 0xE29F8A18, 0x21CCA733, 0x60FDBC2A,
|
||||
0xAFE124AD, 0xEED03FB4, 0x2D83129F, 0x6CB20986,
|
||||
0xAB2448C9, 0xEA1553D0, 0x29467EFB, 0x687765E2,
|
||||
0xF6793F2F, 0xB7482436, 0x741B091D, 0x352A1204,
|
||||
0xF2BC534B, 0xB38D4852, 0x70DE6579, 0x31EF7E60,
|
||||
0xFEF3E6E7, 0xBFC2FDFE, 0x7C91D0D5, 0x3DA0CBCC,
|
||||
0xFA368A83, 0xBB07919A, 0x7854BCB1, 0x3965A7A8,
|
||||
0x4B98833B, 0x0AA99822, 0xC9FAB509, 0x88CBAE10,
|
||||
0x4F5DEF5F, 0x0E6CF446, 0xCD3FD96D, 0x8C0EC274,
|
||||
0x43125AF3, 0x022341EA, 0xC1706CC1, 0x804177D8,
|
||||
0x47D73697, 0x06E62D8E, 0xC5B500A5, 0x84841BBC,
|
||||
0x1A8A4171, 0x5BBB5A68, 0x98E87743, 0xD9D96C5A,
|
||||
0x1E4F2D15, 0x5F7E360C, 0x9C2D1B27, 0xDD1C003E,
|
||||
0x120098B9, 0x533183A0, 0x9062AE8B, 0xD153B592,
|
||||
0x16C5F4DD, 0x57F4EFC4, 0x94A7C2EF, 0xD596D9F6,
|
||||
0xE9BC07AE, 0xA88D1CB7, 0x6BDE319C, 0x2AEF2A85,
|
||||
0xED796BCA, 0xAC4870D3, 0x6F1B5DF8, 0x2E2A46E1,
|
||||
0xE136DE66, 0xA007C57F, 0x6354E854, 0x2265F34D,
|
||||
0xE5F3B202, 0xA4C2A91B, 0x67918430, 0x26A09F29,
|
||||
0xB8AEC5E4, 0xF99FDEFD, 0x3ACCF3D6, 0x7BFDE8CF,
|
||||
0xBC6BA980, 0xFD5AB299, 0x3E099FB2, 0x7F3884AB,
|
||||
0xB0241C2C, 0xF1150735, 0x32462A1E, 0x73773107,
|
||||
0xB4E17048, 0xF5D06B51, 0x3683467A, 0x77B25D63,
|
||||
0x4ED7FACB, 0x0FE6E1D2, 0xCCB5CCF9, 0x8D84D7E0,
|
||||
0x4A1296AF, 0x0B238DB6, 0xC870A09D, 0x8941BB84,
|
||||
0x465D2303, 0x076C381A, 0xC43F1531, 0x850E0E28,
|
||||
0x42984F67, 0x03A9547E, 0xC0FA7955, 0x81CB624C,
|
||||
0x1FC53881, 0x5EF42398, 0x9DA70EB3, 0xDC9615AA,
|
||||
0x1B0054E5, 0x5A314FFC, 0x996262D7, 0xD85379CE,
|
||||
0x174FE149, 0x567EFA50, 0x952DD77B, 0xD41CCC62,
|
||||
0x138A8D2D, 0x52BB9634, 0x91E8BB1F, 0xD0D9A006,
|
||||
0xECF37E5E, 0xADC26547, 0x6E91486C, 0x2FA05375,
|
||||
0xE836123A, 0xA9070923, 0x6A542408, 0x2B653F11,
|
||||
0xE479A796, 0xA548BC8F, 0x661B91A4, 0x272A8ABD,
|
||||
0xE0BCCBF2, 0xA18DD0EB, 0x62DEFDC0, 0x23EFE6D9,
|
||||
0xBDE1BC14, 0xFCD0A70D, 0x3F838A26, 0x7EB2913F,
|
||||
0xB924D070, 0xF815CB69, 0x3B46E642, 0x7A77FD5B,
|
||||
0xB56B65DC, 0xF45A7EC5, 0x370953EE, 0x763848F7,
|
||||
0xB1AE09B8, 0xF09F12A1, 0x33CC3F8A, 0x72FD2493
|
||||
}, {
|
||||
0x00000000, 0x376AC201, 0x6ED48403, 0x59BE4602,
|
||||
0xDCA80907, 0xEBC2CB06, 0xB27C8D04, 0x85164F05,
|
||||
0xB851130E, 0x8F3BD10F, 0xD685970D, 0xE1EF550C,
|
||||
0x64F91A09, 0x5393D808, 0x0A2D9E0A, 0x3D475C0B,
|
||||
0x70A3261C, 0x47C9E41D, 0x1E77A21F, 0x291D601E,
|
||||
0xAC0B2F1B, 0x9B61ED1A, 0xC2DFAB18, 0xF5B56919,
|
||||
0xC8F23512, 0xFF98F713, 0xA626B111, 0x914C7310,
|
||||
0x145A3C15, 0x2330FE14, 0x7A8EB816, 0x4DE47A17,
|
||||
0xE0464D38, 0xD72C8F39, 0x8E92C93B, 0xB9F80B3A,
|
||||
0x3CEE443F, 0x0B84863E, 0x523AC03C, 0x6550023D,
|
||||
0x58175E36, 0x6F7D9C37, 0x36C3DA35, 0x01A91834,
|
||||
0x84BF5731, 0xB3D59530, 0xEA6BD332, 0xDD011133,
|
||||
0x90E56B24, 0xA78FA925, 0xFE31EF27, 0xC95B2D26,
|
||||
0x4C4D6223, 0x7B27A022, 0x2299E620, 0x15F32421,
|
||||
0x28B4782A, 0x1FDEBA2B, 0x4660FC29, 0x710A3E28,
|
||||
0xF41C712D, 0xC376B32C, 0x9AC8F52E, 0xADA2372F,
|
||||
0xC08D9A70, 0xF7E75871, 0xAE591E73, 0x9933DC72,
|
||||
0x1C259377, 0x2B4F5176, 0x72F11774, 0x459BD575,
|
||||
0x78DC897E, 0x4FB64B7F, 0x16080D7D, 0x2162CF7C,
|
||||
0xA4748079, 0x931E4278, 0xCAA0047A, 0xFDCAC67B,
|
||||
0xB02EBC6C, 0x87447E6D, 0xDEFA386F, 0xE990FA6E,
|
||||
0x6C86B56B, 0x5BEC776A, 0x02523168, 0x3538F369,
|
||||
0x087FAF62, 0x3F156D63, 0x66AB2B61, 0x51C1E960,
|
||||
0xD4D7A665, 0xE3BD6464, 0xBA032266, 0x8D69E067,
|
||||
0x20CBD748, 0x17A11549, 0x4E1F534B, 0x7975914A,
|
||||
0xFC63DE4F, 0xCB091C4E, 0x92B75A4C, 0xA5DD984D,
|
||||
0x989AC446, 0xAFF00647, 0xF64E4045, 0xC1248244,
|
||||
0x4432CD41, 0x73580F40, 0x2AE64942, 0x1D8C8B43,
|
||||
0x5068F154, 0x67023355, 0x3EBC7557, 0x09D6B756,
|
||||
0x8CC0F853, 0xBBAA3A52, 0xE2147C50, 0xD57EBE51,
|
||||
0xE839E25A, 0xDF53205B, 0x86ED6659, 0xB187A458,
|
||||
0x3491EB5D, 0x03FB295C, 0x5A456F5E, 0x6D2FAD5F,
|
||||
0x801B35E1, 0xB771F7E0, 0xEECFB1E2, 0xD9A573E3,
|
||||
0x5CB33CE6, 0x6BD9FEE7, 0x3267B8E5, 0x050D7AE4,
|
||||
0x384A26EF, 0x0F20E4EE, 0x569EA2EC, 0x61F460ED,
|
||||
0xE4E22FE8, 0xD388EDE9, 0x8A36ABEB, 0xBD5C69EA,
|
||||
0xF0B813FD, 0xC7D2D1FC, 0x9E6C97FE, 0xA90655FF,
|
||||
0x2C101AFA, 0x1B7AD8FB, 0x42C49EF9, 0x75AE5CF8,
|
||||
0x48E900F3, 0x7F83C2F2, 0x263D84F0, 0x115746F1,
|
||||
0x944109F4, 0xA32BCBF5, 0xFA958DF7, 0xCDFF4FF6,
|
||||
0x605D78D9, 0x5737BAD8, 0x0E89FCDA, 0x39E33EDB,
|
||||
0xBCF571DE, 0x8B9FB3DF, 0xD221F5DD, 0xE54B37DC,
|
||||
0xD80C6BD7, 0xEF66A9D6, 0xB6D8EFD4, 0x81B22DD5,
|
||||
0x04A462D0, 0x33CEA0D1, 0x6A70E6D3, 0x5D1A24D2,
|
||||
0x10FE5EC5, 0x27949CC4, 0x7E2ADAC6, 0x494018C7,
|
||||
0xCC5657C2, 0xFB3C95C3, 0xA282D3C1, 0x95E811C0,
|
||||
0xA8AF4DCB, 0x9FC58FCA, 0xC67BC9C8, 0xF1110BC9,
|
||||
0x740744CC, 0x436D86CD, 0x1AD3C0CF, 0x2DB902CE,
|
||||
0x4096AF91, 0x77FC6D90, 0x2E422B92, 0x1928E993,
|
||||
0x9C3EA696, 0xAB546497, 0xF2EA2295, 0xC580E094,
|
||||
0xF8C7BC9F, 0xCFAD7E9E, 0x9613389C, 0xA179FA9D,
|
||||
0x246FB598, 0x13057799, 0x4ABB319B, 0x7DD1F39A,
|
||||
0x3035898D, 0x075F4B8C, 0x5EE10D8E, 0x698BCF8F,
|
||||
0xEC9D808A, 0xDBF7428B, 0x82490489, 0xB523C688,
|
||||
0x88649A83, 0xBF0E5882, 0xE6B01E80, 0xD1DADC81,
|
||||
0x54CC9384, 0x63A65185, 0x3A181787, 0x0D72D586,
|
||||
0xA0D0E2A9, 0x97BA20A8, 0xCE0466AA, 0xF96EA4AB,
|
||||
0x7C78EBAE, 0x4B1229AF, 0x12AC6FAD, 0x25C6ADAC,
|
||||
0x1881F1A7, 0x2FEB33A6, 0x765575A4, 0x413FB7A5,
|
||||
0xC429F8A0, 0xF3433AA1, 0xAAFD7CA3, 0x9D97BEA2,
|
||||
0xD073C4B5, 0xE71906B4, 0xBEA740B6, 0x89CD82B7,
|
||||
0x0CDBCDB2, 0x3BB10FB3, 0x620F49B1, 0x55658BB0,
|
||||
0x6822D7BB, 0x5F4815BA, 0x06F653B8, 0x319C91B9,
|
||||
0xB48ADEBC, 0x83E01CBD, 0xDA5E5ABF, 0xED3498BE
|
||||
}, {
|
||||
0x00000000, 0x6567BCB8, 0x8BC809AA, 0xEEAFB512,
|
||||
0x5797628F, 0x32F0DE37, 0xDC5F6B25, 0xB938D79D,
|
||||
0xEF28B4C5, 0x8A4F087D, 0x64E0BD6F, 0x018701D7,
|
||||
0xB8BFD64A, 0xDDD86AF2, 0x3377DFE0, 0x56106358,
|
||||
0x9F571950, 0xFA30A5E8, 0x149F10FA, 0x71F8AC42,
|
||||
0xC8C07BDF, 0xADA7C767, 0x43087275, 0x266FCECD,
|
||||
0x707FAD95, 0x1518112D, 0xFBB7A43F, 0x9ED01887,
|
||||
0x27E8CF1A, 0x428F73A2, 0xAC20C6B0, 0xC9477A08,
|
||||
0x3EAF32A0, 0x5BC88E18, 0xB5673B0A, 0xD00087B2,
|
||||
0x6938502F, 0x0C5FEC97, 0xE2F05985, 0x8797E53D,
|
||||
0xD1878665, 0xB4E03ADD, 0x5A4F8FCF, 0x3F283377,
|
||||
0x8610E4EA, 0xE3775852, 0x0DD8ED40, 0x68BF51F8,
|
||||
0xA1F82BF0, 0xC49F9748, 0x2A30225A, 0x4F579EE2,
|
||||
0xF66F497F, 0x9308F5C7, 0x7DA740D5, 0x18C0FC6D,
|
||||
0x4ED09F35, 0x2BB7238D, 0xC518969F, 0xA07F2A27,
|
||||
0x1947FDBA, 0x7C204102, 0x928FF410, 0xF7E848A8,
|
||||
0x3D58149B, 0x583FA823, 0xB6901D31, 0xD3F7A189,
|
||||
0x6ACF7614, 0x0FA8CAAC, 0xE1077FBE, 0x8460C306,
|
||||
0xD270A05E, 0xB7171CE6, 0x59B8A9F4, 0x3CDF154C,
|
||||
0x85E7C2D1, 0xE0807E69, 0x0E2FCB7B, 0x6B4877C3,
|
||||
0xA20F0DCB, 0xC768B173, 0x29C70461, 0x4CA0B8D9,
|
||||
0xF5986F44, 0x90FFD3FC, 0x7E5066EE, 0x1B37DA56,
|
||||
0x4D27B90E, 0x284005B6, 0xC6EFB0A4, 0xA3880C1C,
|
||||
0x1AB0DB81, 0x7FD76739, 0x9178D22B, 0xF41F6E93,
|
||||
0x03F7263B, 0x66909A83, 0x883F2F91, 0xED589329,
|
||||
0x546044B4, 0x3107F80C, 0xDFA84D1E, 0xBACFF1A6,
|
||||
0xECDF92FE, 0x89B82E46, 0x67179B54, 0x027027EC,
|
||||
0xBB48F071, 0xDE2F4CC9, 0x3080F9DB, 0x55E74563,
|
||||
0x9CA03F6B, 0xF9C783D3, 0x176836C1, 0x720F8A79,
|
||||
0xCB375DE4, 0xAE50E15C, 0x40FF544E, 0x2598E8F6,
|
||||
0x73888BAE, 0x16EF3716, 0xF8408204, 0x9D273EBC,
|
||||
0x241FE921, 0x41785599, 0xAFD7E08B, 0xCAB05C33,
|
||||
0x3BB659ED, 0x5ED1E555, 0xB07E5047, 0xD519ECFF,
|
||||
0x6C213B62, 0x094687DA, 0xE7E932C8, 0x828E8E70,
|
||||
0xD49EED28, 0xB1F95190, 0x5F56E482, 0x3A31583A,
|
||||
0x83098FA7, 0xE66E331F, 0x08C1860D, 0x6DA63AB5,
|
||||
0xA4E140BD, 0xC186FC05, 0x2F294917, 0x4A4EF5AF,
|
||||
0xF3762232, 0x96119E8A, 0x78BE2B98, 0x1DD99720,
|
||||
0x4BC9F478, 0x2EAE48C0, 0xC001FDD2, 0xA566416A,
|
||||
0x1C5E96F7, 0x79392A4F, 0x97969F5D, 0xF2F123E5,
|
||||
0x05196B4D, 0x607ED7F5, 0x8ED162E7, 0xEBB6DE5F,
|
||||
0x528E09C2, 0x37E9B57A, 0xD9460068, 0xBC21BCD0,
|
||||
0xEA31DF88, 0x8F566330, 0x61F9D622, 0x049E6A9A,
|
||||
0xBDA6BD07, 0xD8C101BF, 0x366EB4AD, 0x53090815,
|
||||
0x9A4E721D, 0xFF29CEA5, 0x11867BB7, 0x74E1C70F,
|
||||
0xCDD91092, 0xA8BEAC2A, 0x46111938, 0x2376A580,
|
||||
0x7566C6D8, 0x10017A60, 0xFEAECF72, 0x9BC973CA,
|
||||
0x22F1A457, 0x479618EF, 0xA939ADFD, 0xCC5E1145,
|
||||
0x06EE4D76, 0x6389F1CE, 0x8D2644DC, 0xE841F864,
|
||||
0x51792FF9, 0x341E9341, 0xDAB12653, 0xBFD69AEB,
|
||||
0xE9C6F9B3, 0x8CA1450B, 0x620EF019, 0x07694CA1,
|
||||
0xBE519B3C, 0xDB362784, 0x35999296, 0x50FE2E2E,
|
||||
0x99B95426, 0xFCDEE89E, 0x12715D8C, 0x7716E134,
|
||||
0xCE2E36A9, 0xAB498A11, 0x45E63F03, 0x208183BB,
|
||||
0x7691E0E3, 0x13F65C5B, 0xFD59E949, 0x983E55F1,
|
||||
0x2106826C, 0x44613ED4, 0xAACE8BC6, 0xCFA9377E,
|
||||
0x38417FD6, 0x5D26C36E, 0xB389767C, 0xD6EECAC4,
|
||||
0x6FD61D59, 0x0AB1A1E1, 0xE41E14F3, 0x8179A84B,
|
||||
0xD769CB13, 0xB20E77AB, 0x5CA1C2B9, 0x39C67E01,
|
||||
0x80FEA99C, 0xE5991524, 0x0B36A036, 0x6E511C8E,
|
||||
0xA7166686, 0xC271DA3E, 0x2CDE6F2C, 0x49B9D394,
|
||||
0xF0810409, 0x95E6B8B1, 0x7B490DA3, 0x1E2EB11B,
|
||||
0x483ED243, 0x2D596EFB, 0xC3F6DBE9, 0xA6916751,
|
||||
0x1FA9B0CC, 0x7ACE0C74, 0x9461B966, 0xF10605DE
|
||||
}, {
|
||||
0x00000000, 0xB029603D, 0x6053C07A, 0xD07AA047,
|
||||
0xC0A680F5, 0x708FE0C8, 0xA0F5408F, 0x10DC20B2,
|
||||
0xC14B7030, 0x7162100D, 0xA118B04A, 0x1131D077,
|
||||
0x01EDF0C5, 0xB1C490F8, 0x61BE30BF, 0xD1975082,
|
||||
0x8297E060, 0x32BE805D, 0xE2C4201A, 0x52ED4027,
|
||||
0x42316095, 0xF21800A8, 0x2262A0EF, 0x924BC0D2,
|
||||
0x43DC9050, 0xF3F5F06D, 0x238F502A, 0x93A63017,
|
||||
0x837A10A5, 0x33537098, 0xE329D0DF, 0x5300B0E2,
|
||||
0x042FC1C1, 0xB406A1FC, 0x647C01BB, 0xD4556186,
|
||||
0xC4894134, 0x74A02109, 0xA4DA814E, 0x14F3E173,
|
||||
0xC564B1F1, 0x754DD1CC, 0xA537718B, 0x151E11B6,
|
||||
0x05C23104, 0xB5EB5139, 0x6591F17E, 0xD5B89143,
|
||||
0x86B821A1, 0x3691419C, 0xE6EBE1DB, 0x56C281E6,
|
||||
0x461EA154, 0xF637C169, 0x264D612E, 0x96640113,
|
||||
0x47F35191, 0xF7DA31AC, 0x27A091EB, 0x9789F1D6,
|
||||
0x8755D164, 0x377CB159, 0xE706111E, 0x572F7123,
|
||||
0x4958F358, 0xF9719365, 0x290B3322, 0x9922531F,
|
||||
0x89FE73AD, 0x39D71390, 0xE9ADB3D7, 0x5984D3EA,
|
||||
0x88138368, 0x383AE355, 0xE8404312, 0x5869232F,
|
||||
0x48B5039D, 0xF89C63A0, 0x28E6C3E7, 0x98CFA3DA,
|
||||
0xCBCF1338, 0x7BE67305, 0xAB9CD342, 0x1BB5B37F,
|
||||
0x0B6993CD, 0xBB40F3F0, 0x6B3A53B7, 0xDB13338A,
|
||||
0x0A846308, 0xBAAD0335, 0x6AD7A372, 0xDAFEC34F,
|
||||
0xCA22E3FD, 0x7A0B83C0, 0xAA712387, 0x1A5843BA,
|
||||
0x4D773299, 0xFD5E52A4, 0x2D24F2E3, 0x9D0D92DE,
|
||||
0x8DD1B26C, 0x3DF8D251, 0xED827216, 0x5DAB122B,
|
||||
0x8C3C42A9, 0x3C152294, 0xEC6F82D3, 0x5C46E2EE,
|
||||
0x4C9AC25C, 0xFCB3A261, 0x2CC90226, 0x9CE0621B,
|
||||
0xCFE0D2F9, 0x7FC9B2C4, 0xAFB31283, 0x1F9A72BE,
|
||||
0x0F46520C, 0xBF6F3231, 0x6F159276, 0xDF3CF24B,
|
||||
0x0EABA2C9, 0xBE82C2F4, 0x6EF862B3, 0xDED1028E,
|
||||
0xCE0D223C, 0x7E244201, 0xAE5EE246, 0x1E77827B,
|
||||
0x92B0E6B1, 0x2299868C, 0xF2E326CB, 0x42CA46F6,
|
||||
0x52166644, 0xE23F0679, 0x3245A63E, 0x826CC603,
|
||||
0x53FB9681, 0xE3D2F6BC, 0x33A856FB, 0x838136C6,
|
||||
0x935D1674, 0x23747649, 0xF30ED60E, 0x4327B633,
|
||||
0x102706D1, 0xA00E66EC, 0x7074C6AB, 0xC05DA696,
|
||||
0xD0818624, 0x60A8E619, 0xB0D2465E, 0x00FB2663,
|
||||
0xD16C76E1, 0x614516DC, 0xB13FB69B, 0x0116D6A6,
|
||||
0x11CAF614, 0xA1E39629, 0x7199366E, 0xC1B05653,
|
||||
0x969F2770, 0x26B6474D, 0xF6CCE70A, 0x46E58737,
|
||||
0x5639A785, 0xE610C7B8, 0x366A67FF, 0x864307C2,
|
||||
0x57D45740, 0xE7FD377D, 0x3787973A, 0x87AEF707,
|
||||
0x9772D7B5, 0x275BB788, 0xF72117CF, 0x470877F2,
|
||||
0x1408C710, 0xA421A72D, 0x745B076A, 0xC4726757,
|
||||
0xD4AE47E5, 0x648727D8, 0xB4FD879F, 0x04D4E7A2,
|
||||
0xD543B720, 0x656AD71D, 0xB510775A, 0x05391767,
|
||||
0x15E537D5, 0xA5CC57E8, 0x75B6F7AF, 0xC59F9792,
|
||||
0xDBE815E9, 0x6BC175D4, 0xBBBBD593, 0x0B92B5AE,
|
||||
0x1B4E951C, 0xAB67F521, 0x7B1D5566, 0xCB34355B,
|
||||
0x1AA365D9, 0xAA8A05E4, 0x7AF0A5A3, 0xCAD9C59E,
|
||||
0xDA05E52C, 0x6A2C8511, 0xBA562556, 0x0A7F456B,
|
||||
0x597FF589, 0xE95695B4, 0x392C35F3, 0x890555CE,
|
||||
0x99D9757C, 0x29F01541, 0xF98AB506, 0x49A3D53B,
|
||||
0x983485B9, 0x281DE584, 0xF86745C3, 0x484E25FE,
|
||||
0x5892054C, 0xE8BB6571, 0x38C1C536, 0x88E8A50B,
|
||||
0xDFC7D428, 0x6FEEB415, 0xBF941452, 0x0FBD746F,
|
||||
0x1F6154DD, 0xAF4834E0, 0x7F3294A7, 0xCF1BF49A,
|
||||
0x1E8CA418, 0xAEA5C425, 0x7EDF6462, 0xCEF6045F,
|
||||
0xDE2A24ED, 0x6E0344D0, 0xBE79E497, 0x0E5084AA,
|
||||
0x5D503448, 0xED795475, 0x3D03F432, 0x8D2A940F,
|
||||
0x9DF6B4BD, 0x2DDFD480, 0xFDA574C7, 0x4D8C14FA,
|
||||
0x9C1B4478, 0x2C322445, 0xFC488402, 0x4C61E43F,
|
||||
0x5CBDC48D, 0xEC94A4B0, 0x3CEE04F7, 0x8CC764CA
|
||||
}, {
|
||||
0x00000000, 0xA5D35CCB, 0x0BA1C84D, 0xAE729486,
|
||||
0x1642919B, 0xB391CD50, 0x1DE359D6, 0xB830051D,
|
||||
0x6D8253EC, 0xC8510F27, 0x66239BA1, 0xC3F0C76A,
|
||||
0x7BC0C277, 0xDE139EBC, 0x70610A3A, 0xD5B256F1,
|
||||
0x9B02D603, 0x3ED18AC8, 0x90A31E4E, 0x35704285,
|
||||
0x8D404798, 0x28931B53, 0x86E18FD5, 0x2332D31E,
|
||||
0xF68085EF, 0x5353D924, 0xFD214DA2, 0x58F21169,
|
||||
0xE0C21474, 0x451148BF, 0xEB63DC39, 0x4EB080F2,
|
||||
0x3605AC07, 0x93D6F0CC, 0x3DA4644A, 0x98773881,
|
||||
0x20473D9C, 0x85946157, 0x2BE6F5D1, 0x8E35A91A,
|
||||
0x5B87FFEB, 0xFE54A320, 0x502637A6, 0xF5F56B6D,
|
||||
0x4DC56E70, 0xE81632BB, 0x4664A63D, 0xE3B7FAF6,
|
||||
0xAD077A04, 0x08D426CF, 0xA6A6B249, 0x0375EE82,
|
||||
0xBB45EB9F, 0x1E96B754, 0xB0E423D2, 0x15377F19,
|
||||
0xC08529E8, 0x65567523, 0xCB24E1A5, 0x6EF7BD6E,
|
||||
0xD6C7B873, 0x7314E4B8, 0xDD66703E, 0x78B52CF5,
|
||||
0x6C0A580F, 0xC9D904C4, 0x67AB9042, 0xC278CC89,
|
||||
0x7A48C994, 0xDF9B955F, 0x71E901D9, 0xD43A5D12,
|
||||
0x01880BE3, 0xA45B5728, 0x0A29C3AE, 0xAFFA9F65,
|
||||
0x17CA9A78, 0xB219C6B3, 0x1C6B5235, 0xB9B80EFE,
|
||||
0xF7088E0C, 0x52DBD2C7, 0xFCA94641, 0x597A1A8A,
|
||||
0xE14A1F97, 0x4499435C, 0xEAEBD7DA, 0x4F388B11,
|
||||
0x9A8ADDE0, 0x3F59812B, 0x912B15AD, 0x34F84966,
|
||||
0x8CC84C7B, 0x291B10B0, 0x87698436, 0x22BAD8FD,
|
||||
0x5A0FF408, 0xFFDCA8C3, 0x51AE3C45, 0xF47D608E,
|
||||
0x4C4D6593, 0xE99E3958, 0x47ECADDE, 0xE23FF115,
|
||||
0x378DA7E4, 0x925EFB2F, 0x3C2C6FA9, 0x99FF3362,
|
||||
0x21CF367F, 0x841C6AB4, 0x2A6EFE32, 0x8FBDA2F9,
|
||||
0xC10D220B, 0x64DE7EC0, 0xCAACEA46, 0x6F7FB68D,
|
||||
0xD74FB390, 0x729CEF5B, 0xDCEE7BDD, 0x793D2716,
|
||||
0xAC8F71E7, 0x095C2D2C, 0xA72EB9AA, 0x02FDE561,
|
||||
0xBACDE07C, 0x1F1EBCB7, 0xB16C2831, 0x14BF74FA,
|
||||
0xD814B01E, 0x7DC7ECD5, 0xD3B57853, 0x76662498,
|
||||
0xCE562185, 0x6B857D4E, 0xC5F7E9C8, 0x6024B503,
|
||||
0xB596E3F2, 0x1045BF39, 0xBE372BBF, 0x1BE47774,
|
||||
0xA3D47269, 0x06072EA2, 0xA875BA24, 0x0DA6E6EF,
|
||||
0x4316661D, 0xE6C53AD6, 0x48B7AE50, 0xED64F29B,
|
||||
0x5554F786, 0xF087AB4D, 0x5EF53FCB, 0xFB266300,
|
||||
0x2E9435F1, 0x8B47693A, 0x2535FDBC, 0x80E6A177,
|
||||
0x38D6A46A, 0x9D05F8A1, 0x33776C27, 0x96A430EC,
|
||||
0xEE111C19, 0x4BC240D2, 0xE5B0D454, 0x4063889F,
|
||||
0xF8538D82, 0x5D80D149, 0xF3F245CF, 0x56211904,
|
||||
0x83934FF5, 0x2640133E, 0x883287B8, 0x2DE1DB73,
|
||||
0x95D1DE6E, 0x300282A5, 0x9E701623, 0x3BA34AE8,
|
||||
0x7513CA1A, 0xD0C096D1, 0x7EB20257, 0xDB615E9C,
|
||||
0x63515B81, 0xC682074A, 0x68F093CC, 0xCD23CF07,
|
||||
0x189199F6, 0xBD42C53D, 0x133051BB, 0xB6E30D70,
|
||||
0x0ED3086D, 0xAB0054A6, 0x0572C020, 0xA0A19CEB,
|
||||
0xB41EE811, 0x11CDB4DA, 0xBFBF205C, 0x1A6C7C97,
|
||||
0xA25C798A, 0x078F2541, 0xA9FDB1C7, 0x0C2EED0C,
|
||||
0xD99CBBFD, 0x7C4FE736, 0xD23D73B0, 0x77EE2F7B,
|
||||
0xCFDE2A66, 0x6A0D76AD, 0xC47FE22B, 0x61ACBEE0,
|
||||
0x2F1C3E12, 0x8ACF62D9, 0x24BDF65F, 0x816EAA94,
|
||||
0x395EAF89, 0x9C8DF342, 0x32FF67C4, 0x972C3B0F,
|
||||
0x429E6DFE, 0xE74D3135, 0x493FA5B3, 0xECECF978,
|
||||
0x54DCFC65, 0xF10FA0AE, 0x5F7D3428, 0xFAAE68E3,
|
||||
0x821B4416, 0x27C818DD, 0x89BA8C5B, 0x2C69D090,
|
||||
0x9459D58D, 0x318A8946, 0x9FF81DC0, 0x3A2B410B,
|
||||
0xEF9917FA, 0x4A4A4B31, 0xE438DFB7, 0x41EB837C,
|
||||
0xF9DB8661, 0x5C08DAAA, 0xF27A4E2C, 0x57A912E7,
|
||||
0x19199215, 0xBCCACEDE, 0x12B85A58, 0xB76B0693,
|
||||
0x0F5B038E, 0xAA885F45, 0x04FACBC3, 0xA1299708,
|
||||
0x749BC1F9, 0xD1489D32, 0x7F3A09B4, 0xDAE9557F,
|
||||
0x62D95062, 0xC70A0CA9, 0x6978982F, 0xCCABC4E4
|
||||
}, {
|
||||
0x00000000, 0xB40B77A6, 0x29119F97, 0x9D1AE831,
|
||||
0x13244FF4, 0xA72F3852, 0x3A35D063, 0x8E3EA7C5,
|
||||
0x674EEF33, 0xD3459895, 0x4E5F70A4, 0xFA540702,
|
||||
0x746AA0C7, 0xC061D761, 0x5D7B3F50, 0xE97048F6,
|
||||
0xCE9CDE67, 0x7A97A9C1, 0xE78D41F0, 0x53863656,
|
||||
0xDDB89193, 0x69B3E635, 0xF4A90E04, 0x40A279A2,
|
||||
0xA9D23154, 0x1DD946F2, 0x80C3AEC3, 0x34C8D965,
|
||||
0xBAF67EA0, 0x0EFD0906, 0x93E7E137, 0x27EC9691,
|
||||
0x9C39BDCF, 0x2832CA69, 0xB5282258, 0x012355FE,
|
||||
0x8F1DF23B, 0x3B16859D, 0xA60C6DAC, 0x12071A0A,
|
||||
0xFB7752FC, 0x4F7C255A, 0xD266CD6B, 0x666DBACD,
|
||||
0xE8531D08, 0x5C586AAE, 0xC142829F, 0x7549F539,
|
||||
0x52A563A8, 0xE6AE140E, 0x7BB4FC3F, 0xCFBF8B99,
|
||||
0x41812C5C, 0xF58A5BFA, 0x6890B3CB, 0xDC9BC46D,
|
||||
0x35EB8C9B, 0x81E0FB3D, 0x1CFA130C, 0xA8F164AA,
|
||||
0x26CFC36F, 0x92C4B4C9, 0x0FDE5CF8, 0xBBD52B5E,
|
||||
0x79750B44, 0xCD7E7CE2, 0x506494D3, 0xE46FE375,
|
||||
0x6A5144B0, 0xDE5A3316, 0x4340DB27, 0xF74BAC81,
|
||||
0x1E3BE477, 0xAA3093D1, 0x372A7BE0, 0x83210C46,
|
||||
0x0D1FAB83, 0xB914DC25, 0x240E3414, 0x900543B2,
|
||||
0xB7E9D523, 0x03E2A285, 0x9EF84AB4, 0x2AF33D12,
|
||||
0xA4CD9AD7, 0x10C6ED71, 0x8DDC0540, 0x39D772E6,
|
||||
0xD0A73A10, 0x64AC4DB6, 0xF9B6A587, 0x4DBDD221,
|
||||
0xC38375E4, 0x77880242, 0xEA92EA73, 0x5E999DD5,
|
||||
0xE54CB68B, 0x5147C12D, 0xCC5D291C, 0x78565EBA,
|
||||
0xF668F97F, 0x42638ED9, 0xDF7966E8, 0x6B72114E,
|
||||
0x820259B8, 0x36092E1E, 0xAB13C62F, 0x1F18B189,
|
||||
0x9126164C, 0x252D61EA, 0xB83789DB, 0x0C3CFE7D,
|
||||
0x2BD068EC, 0x9FDB1F4A, 0x02C1F77B, 0xB6CA80DD,
|
||||
0x38F42718, 0x8CFF50BE, 0x11E5B88F, 0xA5EECF29,
|
||||
0x4C9E87DF, 0xF895F079, 0x658F1848, 0xD1846FEE,
|
||||
0x5FBAC82B, 0xEBB1BF8D, 0x76AB57BC, 0xC2A0201A,
|
||||
0xF2EA1688, 0x46E1612E, 0xDBFB891F, 0x6FF0FEB9,
|
||||
0xE1CE597C, 0x55C52EDA, 0xC8DFC6EB, 0x7CD4B14D,
|
||||
0x95A4F9BB, 0x21AF8E1D, 0xBCB5662C, 0x08BE118A,
|
||||
0x8680B64F, 0x328BC1E9, 0xAF9129D8, 0x1B9A5E7E,
|
||||
0x3C76C8EF, 0x887DBF49, 0x15675778, 0xA16C20DE,
|
||||
0x2F52871B, 0x9B59F0BD, 0x0643188C, 0xB2486F2A,
|
||||
0x5B3827DC, 0xEF33507A, 0x7229B84B, 0xC622CFED,
|
||||
0x481C6828, 0xFC171F8E, 0x610DF7BF, 0xD5068019,
|
||||
0x6ED3AB47, 0xDAD8DCE1, 0x47C234D0, 0xF3C94376,
|
||||
0x7DF7E4B3, 0xC9FC9315, 0x54E67B24, 0xE0ED0C82,
|
||||
0x099D4474, 0xBD9633D2, 0x208CDBE3, 0x9487AC45,
|
||||
0x1AB90B80, 0xAEB27C26, 0x33A89417, 0x87A3E3B1,
|
||||
0xA04F7520, 0x14440286, 0x895EEAB7, 0x3D559D11,
|
||||
0xB36B3AD4, 0x07604D72, 0x9A7AA543, 0x2E71D2E5,
|
||||
0xC7019A13, 0x730AEDB5, 0xEE100584, 0x5A1B7222,
|
||||
0xD425D5E7, 0x602EA241, 0xFD344A70, 0x493F3DD6,
|
||||
0x8B9F1DCC, 0x3F946A6A, 0xA28E825B, 0x1685F5FD,
|
||||
0x98BB5238, 0x2CB0259E, 0xB1AACDAF, 0x05A1BA09,
|
||||
0xECD1F2FF, 0x58DA8559, 0xC5C06D68, 0x71CB1ACE,
|
||||
0xFFF5BD0B, 0x4BFECAAD, 0xD6E4229C, 0x62EF553A,
|
||||
0x4503C3AB, 0xF108B40D, 0x6C125C3C, 0xD8192B9A,
|
||||
0x56278C5F, 0xE22CFBF9, 0x7F3613C8, 0xCB3D646E,
|
||||
0x224D2C98, 0x96465B3E, 0x0B5CB30F, 0xBF57C4A9,
|
||||
0x3169636C, 0x856214CA, 0x1878FCFB, 0xAC738B5D,
|
||||
0x17A6A003, 0xA3ADD7A5, 0x3EB73F94, 0x8ABC4832,
|
||||
0x0482EFF7, 0xB0899851, 0x2D937060, 0x999807C6,
|
||||
0x70E84F30, 0xC4E33896, 0x59F9D0A7, 0xEDF2A701,
|
||||
0x63CC00C4, 0xD7C77762, 0x4ADD9F53, 0xFED6E8F5,
|
||||
0xD93A7E64, 0x6D3109C2, 0xF02BE1F3, 0x44209655,
|
||||
0xCA1E3190, 0x7E154636, 0xE30FAE07, 0x5704D9A1,
|
||||
0xBE749157, 0x0A7FE6F1, 0x97650EC0, 0x236E7966,
|
||||
0xAD50DEA3, 0x195BA905, 0x84414134, 0x304A3692
|
||||
}, {
|
||||
0x00000000, 0x9E00AACC, 0x7D072542, 0xE3078F8E,
|
||||
0xFA0E4A84, 0x640EE048, 0x87096FC6, 0x1909C50A,
|
||||
0xB51BE5D3, 0x2B1B4F1F, 0xC81CC091, 0x561C6A5D,
|
||||
0x4F15AF57, 0xD115059B, 0x32128A15, 0xAC1220D9,
|
||||
0x2B31BB7C, 0xB53111B0, 0x56369E3E, 0xC83634F2,
|
||||
0xD13FF1F8, 0x4F3F5B34, 0xAC38D4BA, 0x32387E76,
|
||||
0x9E2A5EAF, 0x002AF463, 0xE32D7BED, 0x7D2DD121,
|
||||
0x6424142B, 0xFA24BEE7, 0x19233169, 0x87239BA5,
|
||||
0x566276F9, 0xC862DC35, 0x2B6553BB, 0xB565F977,
|
||||
0xAC6C3C7D, 0x326C96B1, 0xD16B193F, 0x4F6BB3F3,
|
||||
0xE379932A, 0x7D7939E6, 0x9E7EB668, 0x007E1CA4,
|
||||
0x1977D9AE, 0x87777362, 0x6470FCEC, 0xFA705620,
|
||||
0x7D53CD85, 0xE3536749, 0x0054E8C7, 0x9E54420B,
|
||||
0x875D8701, 0x195D2DCD, 0xFA5AA243, 0x645A088F,
|
||||
0xC8482856, 0x5648829A, 0xB54F0D14, 0x2B4FA7D8,
|
||||
0x324662D2, 0xAC46C81E, 0x4F414790, 0xD141ED5C,
|
||||
0xEDC29D29, 0x73C237E5, 0x90C5B86B, 0x0EC512A7,
|
||||
0x17CCD7AD, 0x89CC7D61, 0x6ACBF2EF, 0xF4CB5823,
|
||||
0x58D978FA, 0xC6D9D236, 0x25DE5DB8, 0xBBDEF774,
|
||||
0xA2D7327E, 0x3CD798B2, 0xDFD0173C, 0x41D0BDF0,
|
||||
0xC6F32655, 0x58F38C99, 0xBBF40317, 0x25F4A9DB,
|
||||
0x3CFD6CD1, 0xA2FDC61D, 0x41FA4993, 0xDFFAE35F,
|
||||
0x73E8C386, 0xEDE8694A, 0x0EEFE6C4, 0x90EF4C08,
|
||||
0x89E68902, 0x17E623CE, 0xF4E1AC40, 0x6AE1068C,
|
||||
0xBBA0EBD0, 0x25A0411C, 0xC6A7CE92, 0x58A7645E,
|
||||
0x41AEA154, 0xDFAE0B98, 0x3CA98416, 0xA2A92EDA,
|
||||
0x0EBB0E03, 0x90BBA4CF, 0x73BC2B41, 0xEDBC818D,
|
||||
0xF4B54487, 0x6AB5EE4B, 0x89B261C5, 0x17B2CB09,
|
||||
0x909150AC, 0x0E91FA60, 0xED9675EE, 0x7396DF22,
|
||||
0x6A9F1A28, 0xF49FB0E4, 0x17983F6A, 0x899895A6,
|
||||
0x258AB57F, 0xBB8A1FB3, 0x588D903D, 0xC68D3AF1,
|
||||
0xDF84FFFB, 0x41845537, 0xA283DAB9, 0x3C837075,
|
||||
0xDA853B53, 0x4485919F, 0xA7821E11, 0x3982B4DD,
|
||||
0x208B71D7, 0xBE8BDB1B, 0x5D8C5495, 0xC38CFE59,
|
||||
0x6F9EDE80, 0xF19E744C, 0x1299FBC2, 0x8C99510E,
|
||||
0x95909404, 0x0B903EC8, 0xE897B146, 0x76971B8A,
|
||||
0xF1B4802F, 0x6FB42AE3, 0x8CB3A56D, 0x12B30FA1,
|
||||
0x0BBACAAB, 0x95BA6067, 0x76BDEFE9, 0xE8BD4525,
|
||||
0x44AF65FC, 0xDAAFCF30, 0x39A840BE, 0xA7A8EA72,
|
||||
0xBEA12F78, 0x20A185B4, 0xC3A60A3A, 0x5DA6A0F6,
|
||||
0x8CE74DAA, 0x12E7E766, 0xF1E068E8, 0x6FE0C224,
|
||||
0x76E9072E, 0xE8E9ADE2, 0x0BEE226C, 0x95EE88A0,
|
||||
0x39FCA879, 0xA7FC02B5, 0x44FB8D3B, 0xDAFB27F7,
|
||||
0xC3F2E2FD, 0x5DF24831, 0xBEF5C7BF, 0x20F56D73,
|
||||
0xA7D6F6D6, 0x39D65C1A, 0xDAD1D394, 0x44D17958,
|
||||
0x5DD8BC52, 0xC3D8169E, 0x20DF9910, 0xBEDF33DC,
|
||||
0x12CD1305, 0x8CCDB9C9, 0x6FCA3647, 0xF1CA9C8B,
|
||||
0xE8C35981, 0x76C3F34D, 0x95C47CC3, 0x0BC4D60F,
|
||||
0x3747A67A, 0xA9470CB6, 0x4A408338, 0xD44029F4,
|
||||
0xCD49ECFE, 0x53494632, 0xB04EC9BC, 0x2E4E6370,
|
||||
0x825C43A9, 0x1C5CE965, 0xFF5B66EB, 0x615BCC27,
|
||||
0x7852092D, 0xE652A3E1, 0x05552C6F, 0x9B5586A3,
|
||||
0x1C761D06, 0x8276B7CA, 0x61713844, 0xFF719288,
|
||||
0xE6785782, 0x7878FD4E, 0x9B7F72C0, 0x057FD80C,
|
||||
0xA96DF8D5, 0x376D5219, 0xD46ADD97, 0x4A6A775B,
|
||||
0x5363B251, 0xCD63189D, 0x2E649713, 0xB0643DDF,
|
||||
0x6125D083, 0xFF257A4F, 0x1C22F5C1, 0x82225F0D,
|
||||
0x9B2B9A07, 0x052B30CB, 0xE62CBF45, 0x782C1589,
|
||||
0xD43E3550, 0x4A3E9F9C, 0xA9391012, 0x3739BADE,
|
||||
0x2E307FD4, 0xB030D518, 0x53375A96, 0xCD37F05A,
|
||||
0x4A146BFF, 0xD414C133, 0x37134EBD, 0xA913E471,
|
||||
0xB01A217B, 0x2E1A8BB7, 0xCD1D0439, 0x531DAEF5,
|
||||
0xFF0F8E2C, 0x610F24E0, 0x8208AB6E, 0x1C0801A2,
|
||||
0x0501C4A8, 0x9B016E64, 0x7806E1EA, 0xE6064B26
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,525 @@
|
||||
/* This file has been automatically generated by crc32_tablegen.c. */
|
||||
|
||||
const uint32_t lzma_crc32_table[8][256] = {
|
||||
{
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
|
||||
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
|
||||
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
||||
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
|
||||
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
|
||||
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
||||
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
|
||||
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
|
||||
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
|
||||
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
|
||||
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
||||
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
|
||||
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
|
||||
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
|
||||
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
||||
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
|
||||
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
|
||||
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
||||
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
|
||||
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
|
||||
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
|
||||
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
|
||||
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
||||
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
|
||||
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
|
||||
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
||||
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
|
||||
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
|
||||
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
|
||||
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
||||
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
|
||||
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
||||
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
|
||||
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
|
||||
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
|
||||
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
||||
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
|
||||
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
|
||||
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
|
||||
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
||||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
|
||||
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
|
||||
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
||||
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||
}, {
|
||||
0x00000000, 0x191B3141, 0x32366282, 0x2B2D53C3,
|
||||
0x646CC504, 0x7D77F445, 0x565AA786, 0x4F4196C7,
|
||||
0xC8D98A08, 0xD1C2BB49, 0xFAEFE88A, 0xE3F4D9CB,
|
||||
0xACB54F0C, 0xB5AE7E4D, 0x9E832D8E, 0x87981CCF,
|
||||
0x4AC21251, 0x53D92310, 0x78F470D3, 0x61EF4192,
|
||||
0x2EAED755, 0x37B5E614, 0x1C98B5D7, 0x05838496,
|
||||
0x821B9859, 0x9B00A918, 0xB02DFADB, 0xA936CB9A,
|
||||
0xE6775D5D, 0xFF6C6C1C, 0xD4413FDF, 0xCD5A0E9E,
|
||||
0x958424A2, 0x8C9F15E3, 0xA7B24620, 0xBEA97761,
|
||||
0xF1E8E1A6, 0xE8F3D0E7, 0xC3DE8324, 0xDAC5B265,
|
||||
0x5D5DAEAA, 0x44469FEB, 0x6F6BCC28, 0x7670FD69,
|
||||
0x39316BAE, 0x202A5AEF, 0x0B07092C, 0x121C386D,
|
||||
0xDF4636F3, 0xC65D07B2, 0xED705471, 0xF46B6530,
|
||||
0xBB2AF3F7, 0xA231C2B6, 0x891C9175, 0x9007A034,
|
||||
0x179FBCFB, 0x0E848DBA, 0x25A9DE79, 0x3CB2EF38,
|
||||
0x73F379FF, 0x6AE848BE, 0x41C51B7D, 0x58DE2A3C,
|
||||
0xF0794F05, 0xE9627E44, 0xC24F2D87, 0xDB541CC6,
|
||||
0x94158A01, 0x8D0EBB40, 0xA623E883, 0xBF38D9C2,
|
||||
0x38A0C50D, 0x21BBF44C, 0x0A96A78F, 0x138D96CE,
|
||||
0x5CCC0009, 0x45D73148, 0x6EFA628B, 0x77E153CA,
|
||||
0xBABB5D54, 0xA3A06C15, 0x888D3FD6, 0x91960E97,
|
||||
0xDED79850, 0xC7CCA911, 0xECE1FAD2, 0xF5FACB93,
|
||||
0x7262D75C, 0x6B79E61D, 0x4054B5DE, 0x594F849F,
|
||||
0x160E1258, 0x0F152319, 0x243870DA, 0x3D23419B,
|
||||
0x65FD6BA7, 0x7CE65AE6, 0x57CB0925, 0x4ED03864,
|
||||
0x0191AEA3, 0x188A9FE2, 0x33A7CC21, 0x2ABCFD60,
|
||||
0xAD24E1AF, 0xB43FD0EE, 0x9F12832D, 0x8609B26C,
|
||||
0xC94824AB, 0xD05315EA, 0xFB7E4629, 0xE2657768,
|
||||
0x2F3F79F6, 0x362448B7, 0x1D091B74, 0x04122A35,
|
||||
0x4B53BCF2, 0x52488DB3, 0x7965DE70, 0x607EEF31,
|
||||
0xE7E6F3FE, 0xFEFDC2BF, 0xD5D0917C, 0xCCCBA03D,
|
||||
0x838A36FA, 0x9A9107BB, 0xB1BC5478, 0xA8A76539,
|
||||
0x3B83984B, 0x2298A90A, 0x09B5FAC9, 0x10AECB88,
|
||||
0x5FEF5D4F, 0x46F46C0E, 0x6DD93FCD, 0x74C20E8C,
|
||||
0xF35A1243, 0xEA412302, 0xC16C70C1, 0xD8774180,
|
||||
0x9736D747, 0x8E2DE606, 0xA500B5C5, 0xBC1B8484,
|
||||
0x71418A1A, 0x685ABB5B, 0x4377E898, 0x5A6CD9D9,
|
||||
0x152D4F1E, 0x0C367E5F, 0x271B2D9C, 0x3E001CDD,
|
||||
0xB9980012, 0xA0833153, 0x8BAE6290, 0x92B553D1,
|
||||
0xDDF4C516, 0xC4EFF457, 0xEFC2A794, 0xF6D996D5,
|
||||
0xAE07BCE9, 0xB71C8DA8, 0x9C31DE6B, 0x852AEF2A,
|
||||
0xCA6B79ED, 0xD37048AC, 0xF85D1B6F, 0xE1462A2E,
|
||||
0x66DE36E1, 0x7FC507A0, 0x54E85463, 0x4DF36522,
|
||||
0x02B2F3E5, 0x1BA9C2A4, 0x30849167, 0x299FA026,
|
||||
0xE4C5AEB8, 0xFDDE9FF9, 0xD6F3CC3A, 0xCFE8FD7B,
|
||||
0x80A96BBC, 0x99B25AFD, 0xB29F093E, 0xAB84387F,
|
||||
0x2C1C24B0, 0x350715F1, 0x1E2A4632, 0x07317773,
|
||||
0x4870E1B4, 0x516BD0F5, 0x7A468336, 0x635DB277,
|
||||
0xCBFAD74E, 0xD2E1E60F, 0xF9CCB5CC, 0xE0D7848D,
|
||||
0xAF96124A, 0xB68D230B, 0x9DA070C8, 0x84BB4189,
|
||||
0x03235D46, 0x1A386C07, 0x31153FC4, 0x280E0E85,
|
||||
0x674F9842, 0x7E54A903, 0x5579FAC0, 0x4C62CB81,
|
||||
0x8138C51F, 0x9823F45E, 0xB30EA79D, 0xAA1596DC,
|
||||
0xE554001B, 0xFC4F315A, 0xD7626299, 0xCE7953D8,
|
||||
0x49E14F17, 0x50FA7E56, 0x7BD72D95, 0x62CC1CD4,
|
||||
0x2D8D8A13, 0x3496BB52, 0x1FBBE891, 0x06A0D9D0,
|
||||
0x5E7EF3EC, 0x4765C2AD, 0x6C48916E, 0x7553A02F,
|
||||
0x3A1236E8, 0x230907A9, 0x0824546A, 0x113F652B,
|
||||
0x96A779E4, 0x8FBC48A5, 0xA4911B66, 0xBD8A2A27,
|
||||
0xF2CBBCE0, 0xEBD08DA1, 0xC0FDDE62, 0xD9E6EF23,
|
||||
0x14BCE1BD, 0x0DA7D0FC, 0x268A833F, 0x3F91B27E,
|
||||
0x70D024B9, 0x69CB15F8, 0x42E6463B, 0x5BFD777A,
|
||||
0xDC656BB5, 0xC57E5AF4, 0xEE530937, 0xF7483876,
|
||||
0xB809AEB1, 0xA1129FF0, 0x8A3FCC33, 0x9324FD72
|
||||
}, {
|
||||
0x00000000, 0x01C26A37, 0x0384D46E, 0x0246BE59,
|
||||
0x0709A8DC, 0x06CBC2EB, 0x048D7CB2, 0x054F1685,
|
||||
0x0E1351B8, 0x0FD13B8F, 0x0D9785D6, 0x0C55EFE1,
|
||||
0x091AF964, 0x08D89353, 0x0A9E2D0A, 0x0B5C473D,
|
||||
0x1C26A370, 0x1DE4C947, 0x1FA2771E, 0x1E601D29,
|
||||
0x1B2F0BAC, 0x1AED619B, 0x18ABDFC2, 0x1969B5F5,
|
||||
0x1235F2C8, 0x13F798FF, 0x11B126A6, 0x10734C91,
|
||||
0x153C5A14, 0x14FE3023, 0x16B88E7A, 0x177AE44D,
|
||||
0x384D46E0, 0x398F2CD7, 0x3BC9928E, 0x3A0BF8B9,
|
||||
0x3F44EE3C, 0x3E86840B, 0x3CC03A52, 0x3D025065,
|
||||
0x365E1758, 0x379C7D6F, 0x35DAC336, 0x3418A901,
|
||||
0x3157BF84, 0x3095D5B3, 0x32D36BEA, 0x331101DD,
|
||||
0x246BE590, 0x25A98FA7, 0x27EF31FE, 0x262D5BC9,
|
||||
0x23624D4C, 0x22A0277B, 0x20E69922, 0x2124F315,
|
||||
0x2A78B428, 0x2BBADE1F, 0x29FC6046, 0x283E0A71,
|
||||
0x2D711CF4, 0x2CB376C3, 0x2EF5C89A, 0x2F37A2AD,
|
||||
0x709A8DC0, 0x7158E7F7, 0x731E59AE, 0x72DC3399,
|
||||
0x7793251C, 0x76514F2B, 0x7417F172, 0x75D59B45,
|
||||
0x7E89DC78, 0x7F4BB64F, 0x7D0D0816, 0x7CCF6221,
|
||||
0x798074A4, 0x78421E93, 0x7A04A0CA, 0x7BC6CAFD,
|
||||
0x6CBC2EB0, 0x6D7E4487, 0x6F38FADE, 0x6EFA90E9,
|
||||
0x6BB5866C, 0x6A77EC5B, 0x68315202, 0x69F33835,
|
||||
0x62AF7F08, 0x636D153F, 0x612BAB66, 0x60E9C151,
|
||||
0x65A6D7D4, 0x6464BDE3, 0x662203BA, 0x67E0698D,
|
||||
0x48D7CB20, 0x4915A117, 0x4B531F4E, 0x4A917579,
|
||||
0x4FDE63FC, 0x4E1C09CB, 0x4C5AB792, 0x4D98DDA5,
|
||||
0x46C49A98, 0x4706F0AF, 0x45404EF6, 0x448224C1,
|
||||
0x41CD3244, 0x400F5873, 0x4249E62A, 0x438B8C1D,
|
||||
0x54F16850, 0x55330267, 0x5775BC3E, 0x56B7D609,
|
||||
0x53F8C08C, 0x523AAABB, 0x507C14E2, 0x51BE7ED5,
|
||||
0x5AE239E8, 0x5B2053DF, 0x5966ED86, 0x58A487B1,
|
||||
0x5DEB9134, 0x5C29FB03, 0x5E6F455A, 0x5FAD2F6D,
|
||||
0xE1351B80, 0xE0F771B7, 0xE2B1CFEE, 0xE373A5D9,
|
||||
0xE63CB35C, 0xE7FED96B, 0xE5B86732, 0xE47A0D05,
|
||||
0xEF264A38, 0xEEE4200F, 0xECA29E56, 0xED60F461,
|
||||
0xE82FE2E4, 0xE9ED88D3, 0xEBAB368A, 0xEA695CBD,
|
||||
0xFD13B8F0, 0xFCD1D2C7, 0xFE976C9E, 0xFF5506A9,
|
||||
0xFA1A102C, 0xFBD87A1B, 0xF99EC442, 0xF85CAE75,
|
||||
0xF300E948, 0xF2C2837F, 0xF0843D26, 0xF1465711,
|
||||
0xF4094194, 0xF5CB2BA3, 0xF78D95FA, 0xF64FFFCD,
|
||||
0xD9785D60, 0xD8BA3757, 0xDAFC890E, 0xDB3EE339,
|
||||
0xDE71F5BC, 0xDFB39F8B, 0xDDF521D2, 0xDC374BE5,
|
||||
0xD76B0CD8, 0xD6A966EF, 0xD4EFD8B6, 0xD52DB281,
|
||||
0xD062A404, 0xD1A0CE33, 0xD3E6706A, 0xD2241A5D,
|
||||
0xC55EFE10, 0xC49C9427, 0xC6DA2A7E, 0xC7184049,
|
||||
0xC25756CC, 0xC3953CFB, 0xC1D382A2, 0xC011E895,
|
||||
0xCB4DAFA8, 0xCA8FC59F, 0xC8C97BC6, 0xC90B11F1,
|
||||
0xCC440774, 0xCD866D43, 0xCFC0D31A, 0xCE02B92D,
|
||||
0x91AF9640, 0x906DFC77, 0x922B422E, 0x93E92819,
|
||||
0x96A63E9C, 0x976454AB, 0x9522EAF2, 0x94E080C5,
|
||||
0x9FBCC7F8, 0x9E7EADCF, 0x9C381396, 0x9DFA79A1,
|
||||
0x98B56F24, 0x99770513, 0x9B31BB4A, 0x9AF3D17D,
|
||||
0x8D893530, 0x8C4B5F07, 0x8E0DE15E, 0x8FCF8B69,
|
||||
0x8A809DEC, 0x8B42F7DB, 0x89044982, 0x88C623B5,
|
||||
0x839A6488, 0x82580EBF, 0x801EB0E6, 0x81DCDAD1,
|
||||
0x8493CC54, 0x8551A663, 0x8717183A, 0x86D5720D,
|
||||
0xA9E2D0A0, 0xA820BA97, 0xAA6604CE, 0xABA46EF9,
|
||||
0xAEEB787C, 0xAF29124B, 0xAD6FAC12, 0xACADC625,
|
||||
0xA7F18118, 0xA633EB2F, 0xA4755576, 0xA5B73F41,
|
||||
0xA0F829C4, 0xA13A43F3, 0xA37CFDAA, 0xA2BE979D,
|
||||
0xB5C473D0, 0xB40619E7, 0xB640A7BE, 0xB782CD89,
|
||||
0xB2CDDB0C, 0xB30FB13B, 0xB1490F62, 0xB08B6555,
|
||||
0xBBD72268, 0xBA15485F, 0xB853F606, 0xB9919C31,
|
||||
0xBCDE8AB4, 0xBD1CE083, 0xBF5A5EDA, 0xBE9834ED
|
||||
}, {
|
||||
0x00000000, 0xB8BC6765, 0xAA09C88B, 0x12B5AFEE,
|
||||
0x8F629757, 0x37DEF032, 0x256B5FDC, 0x9DD738B9,
|
||||
0xC5B428EF, 0x7D084F8A, 0x6FBDE064, 0xD7018701,
|
||||
0x4AD6BFB8, 0xF26AD8DD, 0xE0DF7733, 0x58631056,
|
||||
0x5019579F, 0xE8A530FA, 0xFA109F14, 0x42ACF871,
|
||||
0xDF7BC0C8, 0x67C7A7AD, 0x75720843, 0xCDCE6F26,
|
||||
0x95AD7F70, 0x2D111815, 0x3FA4B7FB, 0x8718D09E,
|
||||
0x1ACFE827, 0xA2738F42, 0xB0C620AC, 0x087A47C9,
|
||||
0xA032AF3E, 0x188EC85B, 0x0A3B67B5, 0xB28700D0,
|
||||
0x2F503869, 0x97EC5F0C, 0x8559F0E2, 0x3DE59787,
|
||||
0x658687D1, 0xDD3AE0B4, 0xCF8F4F5A, 0x7733283F,
|
||||
0xEAE41086, 0x525877E3, 0x40EDD80D, 0xF851BF68,
|
||||
0xF02BF8A1, 0x48979FC4, 0x5A22302A, 0xE29E574F,
|
||||
0x7F496FF6, 0xC7F50893, 0xD540A77D, 0x6DFCC018,
|
||||
0x359FD04E, 0x8D23B72B, 0x9F9618C5, 0x272A7FA0,
|
||||
0xBAFD4719, 0x0241207C, 0x10F48F92, 0xA848E8F7,
|
||||
0x9B14583D, 0x23A83F58, 0x311D90B6, 0x89A1F7D3,
|
||||
0x1476CF6A, 0xACCAA80F, 0xBE7F07E1, 0x06C36084,
|
||||
0x5EA070D2, 0xE61C17B7, 0xF4A9B859, 0x4C15DF3C,
|
||||
0xD1C2E785, 0x697E80E0, 0x7BCB2F0E, 0xC377486B,
|
||||
0xCB0D0FA2, 0x73B168C7, 0x6104C729, 0xD9B8A04C,
|
||||
0x446F98F5, 0xFCD3FF90, 0xEE66507E, 0x56DA371B,
|
||||
0x0EB9274D, 0xB6054028, 0xA4B0EFC6, 0x1C0C88A3,
|
||||
0x81DBB01A, 0x3967D77F, 0x2BD27891, 0x936E1FF4,
|
||||
0x3B26F703, 0x839A9066, 0x912F3F88, 0x299358ED,
|
||||
0xB4446054, 0x0CF80731, 0x1E4DA8DF, 0xA6F1CFBA,
|
||||
0xFE92DFEC, 0x462EB889, 0x549B1767, 0xEC277002,
|
||||
0x71F048BB, 0xC94C2FDE, 0xDBF98030, 0x6345E755,
|
||||
0x6B3FA09C, 0xD383C7F9, 0xC1366817, 0x798A0F72,
|
||||
0xE45D37CB, 0x5CE150AE, 0x4E54FF40, 0xF6E89825,
|
||||
0xAE8B8873, 0x1637EF16, 0x048240F8, 0xBC3E279D,
|
||||
0x21E91F24, 0x99557841, 0x8BE0D7AF, 0x335CB0CA,
|
||||
0xED59B63B, 0x55E5D15E, 0x47507EB0, 0xFFEC19D5,
|
||||
0x623B216C, 0xDA874609, 0xC832E9E7, 0x708E8E82,
|
||||
0x28ED9ED4, 0x9051F9B1, 0x82E4565F, 0x3A58313A,
|
||||
0xA78F0983, 0x1F336EE6, 0x0D86C108, 0xB53AA66D,
|
||||
0xBD40E1A4, 0x05FC86C1, 0x1749292F, 0xAFF54E4A,
|
||||
0x322276F3, 0x8A9E1196, 0x982BBE78, 0x2097D91D,
|
||||
0x78F4C94B, 0xC048AE2E, 0xD2FD01C0, 0x6A4166A5,
|
||||
0xF7965E1C, 0x4F2A3979, 0x5D9F9697, 0xE523F1F2,
|
||||
0x4D6B1905, 0xF5D77E60, 0xE762D18E, 0x5FDEB6EB,
|
||||
0xC2098E52, 0x7AB5E937, 0x680046D9, 0xD0BC21BC,
|
||||
0x88DF31EA, 0x3063568F, 0x22D6F961, 0x9A6A9E04,
|
||||
0x07BDA6BD, 0xBF01C1D8, 0xADB46E36, 0x15080953,
|
||||
0x1D724E9A, 0xA5CE29FF, 0xB77B8611, 0x0FC7E174,
|
||||
0x9210D9CD, 0x2AACBEA8, 0x38191146, 0x80A57623,
|
||||
0xD8C66675, 0x607A0110, 0x72CFAEFE, 0xCA73C99B,
|
||||
0x57A4F122, 0xEF189647, 0xFDAD39A9, 0x45115ECC,
|
||||
0x764DEE06, 0xCEF18963, 0xDC44268D, 0x64F841E8,
|
||||
0xF92F7951, 0x41931E34, 0x5326B1DA, 0xEB9AD6BF,
|
||||
0xB3F9C6E9, 0x0B45A18C, 0x19F00E62, 0xA14C6907,
|
||||
0x3C9B51BE, 0x842736DB, 0x96929935, 0x2E2EFE50,
|
||||
0x2654B999, 0x9EE8DEFC, 0x8C5D7112, 0x34E11677,
|
||||
0xA9362ECE, 0x118A49AB, 0x033FE645, 0xBB838120,
|
||||
0xE3E09176, 0x5B5CF613, 0x49E959FD, 0xF1553E98,
|
||||
0x6C820621, 0xD43E6144, 0xC68BCEAA, 0x7E37A9CF,
|
||||
0xD67F4138, 0x6EC3265D, 0x7C7689B3, 0xC4CAEED6,
|
||||
0x591DD66F, 0xE1A1B10A, 0xF3141EE4, 0x4BA87981,
|
||||
0x13CB69D7, 0xAB770EB2, 0xB9C2A15C, 0x017EC639,
|
||||
0x9CA9FE80, 0x241599E5, 0x36A0360B, 0x8E1C516E,
|
||||
0x866616A7, 0x3EDA71C2, 0x2C6FDE2C, 0x94D3B949,
|
||||
0x090481F0, 0xB1B8E695, 0xA30D497B, 0x1BB12E1E,
|
||||
0x43D23E48, 0xFB6E592D, 0xE9DBF6C3, 0x516791A6,
|
||||
0xCCB0A91F, 0x740CCE7A, 0x66B96194, 0xDE0506F1
|
||||
}, {
|
||||
0x00000000, 0x3D6029B0, 0x7AC05360, 0x47A07AD0,
|
||||
0xF580A6C0, 0xC8E08F70, 0x8F40F5A0, 0xB220DC10,
|
||||
0x30704BC1, 0x0D106271, 0x4AB018A1, 0x77D03111,
|
||||
0xC5F0ED01, 0xF890C4B1, 0xBF30BE61, 0x825097D1,
|
||||
0x60E09782, 0x5D80BE32, 0x1A20C4E2, 0x2740ED52,
|
||||
0x95603142, 0xA80018F2, 0xEFA06222, 0xD2C04B92,
|
||||
0x5090DC43, 0x6DF0F5F3, 0x2A508F23, 0x1730A693,
|
||||
0xA5107A83, 0x98705333, 0xDFD029E3, 0xE2B00053,
|
||||
0xC1C12F04, 0xFCA106B4, 0xBB017C64, 0x866155D4,
|
||||
0x344189C4, 0x0921A074, 0x4E81DAA4, 0x73E1F314,
|
||||
0xF1B164C5, 0xCCD14D75, 0x8B7137A5, 0xB6111E15,
|
||||
0x0431C205, 0x3951EBB5, 0x7EF19165, 0x4391B8D5,
|
||||
0xA121B886, 0x9C419136, 0xDBE1EBE6, 0xE681C256,
|
||||
0x54A11E46, 0x69C137F6, 0x2E614D26, 0x13016496,
|
||||
0x9151F347, 0xAC31DAF7, 0xEB91A027, 0xD6F18997,
|
||||
0x64D15587, 0x59B17C37, 0x1E1106E7, 0x23712F57,
|
||||
0x58F35849, 0x659371F9, 0x22330B29, 0x1F532299,
|
||||
0xAD73FE89, 0x9013D739, 0xD7B3ADE9, 0xEAD38459,
|
||||
0x68831388, 0x55E33A38, 0x124340E8, 0x2F236958,
|
||||
0x9D03B548, 0xA0639CF8, 0xE7C3E628, 0xDAA3CF98,
|
||||
0x3813CFCB, 0x0573E67B, 0x42D39CAB, 0x7FB3B51B,
|
||||
0xCD93690B, 0xF0F340BB, 0xB7533A6B, 0x8A3313DB,
|
||||
0x0863840A, 0x3503ADBA, 0x72A3D76A, 0x4FC3FEDA,
|
||||
0xFDE322CA, 0xC0830B7A, 0x872371AA, 0xBA43581A,
|
||||
0x9932774D, 0xA4525EFD, 0xE3F2242D, 0xDE920D9D,
|
||||
0x6CB2D18D, 0x51D2F83D, 0x167282ED, 0x2B12AB5D,
|
||||
0xA9423C8C, 0x9422153C, 0xD3826FEC, 0xEEE2465C,
|
||||
0x5CC29A4C, 0x61A2B3FC, 0x2602C92C, 0x1B62E09C,
|
||||
0xF9D2E0CF, 0xC4B2C97F, 0x8312B3AF, 0xBE729A1F,
|
||||
0x0C52460F, 0x31326FBF, 0x7692156F, 0x4BF23CDF,
|
||||
0xC9A2AB0E, 0xF4C282BE, 0xB362F86E, 0x8E02D1DE,
|
||||
0x3C220DCE, 0x0142247E, 0x46E25EAE, 0x7B82771E,
|
||||
0xB1E6B092, 0x8C869922, 0xCB26E3F2, 0xF646CA42,
|
||||
0x44661652, 0x79063FE2, 0x3EA64532, 0x03C66C82,
|
||||
0x8196FB53, 0xBCF6D2E3, 0xFB56A833, 0xC6368183,
|
||||
0x74165D93, 0x49767423, 0x0ED60EF3, 0x33B62743,
|
||||
0xD1062710, 0xEC660EA0, 0xABC67470, 0x96A65DC0,
|
||||
0x248681D0, 0x19E6A860, 0x5E46D2B0, 0x6326FB00,
|
||||
0xE1766CD1, 0xDC164561, 0x9BB63FB1, 0xA6D61601,
|
||||
0x14F6CA11, 0x2996E3A1, 0x6E369971, 0x5356B0C1,
|
||||
0x70279F96, 0x4D47B626, 0x0AE7CCF6, 0x3787E546,
|
||||
0x85A73956, 0xB8C710E6, 0xFF676A36, 0xC2074386,
|
||||
0x4057D457, 0x7D37FDE7, 0x3A978737, 0x07F7AE87,
|
||||
0xB5D77297, 0x88B75B27, 0xCF1721F7, 0xF2770847,
|
||||
0x10C70814, 0x2DA721A4, 0x6A075B74, 0x576772C4,
|
||||
0xE547AED4, 0xD8278764, 0x9F87FDB4, 0xA2E7D404,
|
||||
0x20B743D5, 0x1DD76A65, 0x5A7710B5, 0x67173905,
|
||||
0xD537E515, 0xE857CCA5, 0xAFF7B675, 0x92979FC5,
|
||||
0xE915E8DB, 0xD475C16B, 0x93D5BBBB, 0xAEB5920B,
|
||||
0x1C954E1B, 0x21F567AB, 0x66551D7B, 0x5B3534CB,
|
||||
0xD965A31A, 0xE4058AAA, 0xA3A5F07A, 0x9EC5D9CA,
|
||||
0x2CE505DA, 0x11852C6A, 0x562556BA, 0x6B457F0A,
|
||||
0x89F57F59, 0xB49556E9, 0xF3352C39, 0xCE550589,
|
||||
0x7C75D999, 0x4115F029, 0x06B58AF9, 0x3BD5A349,
|
||||
0xB9853498, 0x84E51D28, 0xC34567F8, 0xFE254E48,
|
||||
0x4C059258, 0x7165BBE8, 0x36C5C138, 0x0BA5E888,
|
||||
0x28D4C7DF, 0x15B4EE6F, 0x521494BF, 0x6F74BD0F,
|
||||
0xDD54611F, 0xE03448AF, 0xA794327F, 0x9AF41BCF,
|
||||
0x18A48C1E, 0x25C4A5AE, 0x6264DF7E, 0x5F04F6CE,
|
||||
0xED242ADE, 0xD044036E, 0x97E479BE, 0xAA84500E,
|
||||
0x4834505D, 0x755479ED, 0x32F4033D, 0x0F942A8D,
|
||||
0xBDB4F69D, 0x80D4DF2D, 0xC774A5FD, 0xFA148C4D,
|
||||
0x78441B9C, 0x4524322C, 0x028448FC, 0x3FE4614C,
|
||||
0x8DC4BD5C, 0xB0A494EC, 0xF704EE3C, 0xCA64C78C
|
||||
}, {
|
||||
0x00000000, 0xCB5CD3A5, 0x4DC8A10B, 0x869472AE,
|
||||
0x9B914216, 0x50CD91B3, 0xD659E31D, 0x1D0530B8,
|
||||
0xEC53826D, 0x270F51C8, 0xA19B2366, 0x6AC7F0C3,
|
||||
0x77C2C07B, 0xBC9E13DE, 0x3A0A6170, 0xF156B2D5,
|
||||
0x03D6029B, 0xC88AD13E, 0x4E1EA390, 0x85427035,
|
||||
0x9847408D, 0x531B9328, 0xD58FE186, 0x1ED33223,
|
||||
0xEF8580F6, 0x24D95353, 0xA24D21FD, 0x6911F258,
|
||||
0x7414C2E0, 0xBF481145, 0x39DC63EB, 0xF280B04E,
|
||||
0x07AC0536, 0xCCF0D693, 0x4A64A43D, 0x81387798,
|
||||
0x9C3D4720, 0x57619485, 0xD1F5E62B, 0x1AA9358E,
|
||||
0xEBFF875B, 0x20A354FE, 0xA6372650, 0x6D6BF5F5,
|
||||
0x706EC54D, 0xBB3216E8, 0x3DA66446, 0xF6FAB7E3,
|
||||
0x047A07AD, 0xCF26D408, 0x49B2A6A6, 0x82EE7503,
|
||||
0x9FEB45BB, 0x54B7961E, 0xD223E4B0, 0x197F3715,
|
||||
0xE82985C0, 0x23755665, 0xA5E124CB, 0x6EBDF76E,
|
||||
0x73B8C7D6, 0xB8E41473, 0x3E7066DD, 0xF52CB578,
|
||||
0x0F580A6C, 0xC404D9C9, 0x4290AB67, 0x89CC78C2,
|
||||
0x94C9487A, 0x5F959BDF, 0xD901E971, 0x125D3AD4,
|
||||
0xE30B8801, 0x28575BA4, 0xAEC3290A, 0x659FFAAF,
|
||||
0x789ACA17, 0xB3C619B2, 0x35526B1C, 0xFE0EB8B9,
|
||||
0x0C8E08F7, 0xC7D2DB52, 0x4146A9FC, 0x8A1A7A59,
|
||||
0x971F4AE1, 0x5C439944, 0xDAD7EBEA, 0x118B384F,
|
||||
0xE0DD8A9A, 0x2B81593F, 0xAD152B91, 0x6649F834,
|
||||
0x7B4CC88C, 0xB0101B29, 0x36846987, 0xFDD8BA22,
|
||||
0x08F40F5A, 0xC3A8DCFF, 0x453CAE51, 0x8E607DF4,
|
||||
0x93654D4C, 0x58399EE9, 0xDEADEC47, 0x15F13FE2,
|
||||
0xE4A78D37, 0x2FFB5E92, 0xA96F2C3C, 0x6233FF99,
|
||||
0x7F36CF21, 0xB46A1C84, 0x32FE6E2A, 0xF9A2BD8F,
|
||||
0x0B220DC1, 0xC07EDE64, 0x46EAACCA, 0x8DB67F6F,
|
||||
0x90B34FD7, 0x5BEF9C72, 0xDD7BEEDC, 0x16273D79,
|
||||
0xE7718FAC, 0x2C2D5C09, 0xAAB92EA7, 0x61E5FD02,
|
||||
0x7CE0CDBA, 0xB7BC1E1F, 0x31286CB1, 0xFA74BF14,
|
||||
0x1EB014D8, 0xD5ECC77D, 0x5378B5D3, 0x98246676,
|
||||
0x852156CE, 0x4E7D856B, 0xC8E9F7C5, 0x03B52460,
|
||||
0xF2E396B5, 0x39BF4510, 0xBF2B37BE, 0x7477E41B,
|
||||
0x6972D4A3, 0xA22E0706, 0x24BA75A8, 0xEFE6A60D,
|
||||
0x1D661643, 0xD63AC5E6, 0x50AEB748, 0x9BF264ED,
|
||||
0x86F75455, 0x4DAB87F0, 0xCB3FF55E, 0x006326FB,
|
||||
0xF135942E, 0x3A69478B, 0xBCFD3525, 0x77A1E680,
|
||||
0x6AA4D638, 0xA1F8059D, 0x276C7733, 0xEC30A496,
|
||||
0x191C11EE, 0xD240C24B, 0x54D4B0E5, 0x9F886340,
|
||||
0x828D53F8, 0x49D1805D, 0xCF45F2F3, 0x04192156,
|
||||
0xF54F9383, 0x3E134026, 0xB8873288, 0x73DBE12D,
|
||||
0x6EDED195, 0xA5820230, 0x2316709E, 0xE84AA33B,
|
||||
0x1ACA1375, 0xD196C0D0, 0x5702B27E, 0x9C5E61DB,
|
||||
0x815B5163, 0x4A0782C6, 0xCC93F068, 0x07CF23CD,
|
||||
0xF6999118, 0x3DC542BD, 0xBB513013, 0x700DE3B6,
|
||||
0x6D08D30E, 0xA65400AB, 0x20C07205, 0xEB9CA1A0,
|
||||
0x11E81EB4, 0xDAB4CD11, 0x5C20BFBF, 0x977C6C1A,
|
||||
0x8A795CA2, 0x41258F07, 0xC7B1FDA9, 0x0CED2E0C,
|
||||
0xFDBB9CD9, 0x36E74F7C, 0xB0733DD2, 0x7B2FEE77,
|
||||
0x662ADECF, 0xAD760D6A, 0x2BE27FC4, 0xE0BEAC61,
|
||||
0x123E1C2F, 0xD962CF8A, 0x5FF6BD24, 0x94AA6E81,
|
||||
0x89AF5E39, 0x42F38D9C, 0xC467FF32, 0x0F3B2C97,
|
||||
0xFE6D9E42, 0x35314DE7, 0xB3A53F49, 0x78F9ECEC,
|
||||
0x65FCDC54, 0xAEA00FF1, 0x28347D5F, 0xE368AEFA,
|
||||
0x16441B82, 0xDD18C827, 0x5B8CBA89, 0x90D0692C,
|
||||
0x8DD55994, 0x46898A31, 0xC01DF89F, 0x0B412B3A,
|
||||
0xFA1799EF, 0x314B4A4A, 0xB7DF38E4, 0x7C83EB41,
|
||||
0x6186DBF9, 0xAADA085C, 0x2C4E7AF2, 0xE712A957,
|
||||
0x15921919, 0xDECECABC, 0x585AB812, 0x93066BB7,
|
||||
0x8E035B0F, 0x455F88AA, 0xC3CBFA04, 0x089729A1,
|
||||
0xF9C19B74, 0x329D48D1, 0xB4093A7F, 0x7F55E9DA,
|
||||
0x6250D962, 0xA90C0AC7, 0x2F987869, 0xE4C4ABCC
|
||||
}, {
|
||||
0x00000000, 0xA6770BB4, 0x979F1129, 0x31E81A9D,
|
||||
0xF44F2413, 0x52382FA7, 0x63D0353A, 0xC5A73E8E,
|
||||
0x33EF4E67, 0x959845D3, 0xA4705F4E, 0x020754FA,
|
||||
0xC7A06A74, 0x61D761C0, 0x503F7B5D, 0xF64870E9,
|
||||
0x67DE9CCE, 0xC1A9977A, 0xF0418DE7, 0x56368653,
|
||||
0x9391B8DD, 0x35E6B369, 0x040EA9F4, 0xA279A240,
|
||||
0x5431D2A9, 0xF246D91D, 0xC3AEC380, 0x65D9C834,
|
||||
0xA07EF6BA, 0x0609FD0E, 0x37E1E793, 0x9196EC27,
|
||||
0xCFBD399C, 0x69CA3228, 0x582228B5, 0xFE552301,
|
||||
0x3BF21D8F, 0x9D85163B, 0xAC6D0CA6, 0x0A1A0712,
|
||||
0xFC5277FB, 0x5A257C4F, 0x6BCD66D2, 0xCDBA6D66,
|
||||
0x081D53E8, 0xAE6A585C, 0x9F8242C1, 0x39F54975,
|
||||
0xA863A552, 0x0E14AEE6, 0x3FFCB47B, 0x998BBFCF,
|
||||
0x5C2C8141, 0xFA5B8AF5, 0xCBB39068, 0x6DC49BDC,
|
||||
0x9B8CEB35, 0x3DFBE081, 0x0C13FA1C, 0xAA64F1A8,
|
||||
0x6FC3CF26, 0xC9B4C492, 0xF85CDE0F, 0x5E2BD5BB,
|
||||
0x440B7579, 0xE27C7ECD, 0xD3946450, 0x75E36FE4,
|
||||
0xB044516A, 0x16335ADE, 0x27DB4043, 0x81AC4BF7,
|
||||
0x77E43B1E, 0xD19330AA, 0xE07B2A37, 0x460C2183,
|
||||
0x83AB1F0D, 0x25DC14B9, 0x14340E24, 0xB2430590,
|
||||
0x23D5E9B7, 0x85A2E203, 0xB44AF89E, 0x123DF32A,
|
||||
0xD79ACDA4, 0x71EDC610, 0x4005DC8D, 0xE672D739,
|
||||
0x103AA7D0, 0xB64DAC64, 0x87A5B6F9, 0x21D2BD4D,
|
||||
0xE47583C3, 0x42028877, 0x73EA92EA, 0xD59D995E,
|
||||
0x8BB64CE5, 0x2DC14751, 0x1C295DCC, 0xBA5E5678,
|
||||
0x7FF968F6, 0xD98E6342, 0xE86679DF, 0x4E11726B,
|
||||
0xB8590282, 0x1E2E0936, 0x2FC613AB, 0x89B1181F,
|
||||
0x4C162691, 0xEA612D25, 0xDB8937B8, 0x7DFE3C0C,
|
||||
0xEC68D02B, 0x4A1FDB9F, 0x7BF7C102, 0xDD80CAB6,
|
||||
0x1827F438, 0xBE50FF8C, 0x8FB8E511, 0x29CFEEA5,
|
||||
0xDF879E4C, 0x79F095F8, 0x48188F65, 0xEE6F84D1,
|
||||
0x2BC8BA5F, 0x8DBFB1EB, 0xBC57AB76, 0x1A20A0C2,
|
||||
0x8816EAF2, 0x2E61E146, 0x1F89FBDB, 0xB9FEF06F,
|
||||
0x7C59CEE1, 0xDA2EC555, 0xEBC6DFC8, 0x4DB1D47C,
|
||||
0xBBF9A495, 0x1D8EAF21, 0x2C66B5BC, 0x8A11BE08,
|
||||
0x4FB68086, 0xE9C18B32, 0xD82991AF, 0x7E5E9A1B,
|
||||
0xEFC8763C, 0x49BF7D88, 0x78576715, 0xDE206CA1,
|
||||
0x1B87522F, 0xBDF0599B, 0x8C184306, 0x2A6F48B2,
|
||||
0xDC27385B, 0x7A5033EF, 0x4BB82972, 0xEDCF22C6,
|
||||
0x28681C48, 0x8E1F17FC, 0xBFF70D61, 0x198006D5,
|
||||
0x47ABD36E, 0xE1DCD8DA, 0xD034C247, 0x7643C9F3,
|
||||
0xB3E4F77D, 0x1593FCC9, 0x247BE654, 0x820CEDE0,
|
||||
0x74449D09, 0xD23396BD, 0xE3DB8C20, 0x45AC8794,
|
||||
0x800BB91A, 0x267CB2AE, 0x1794A833, 0xB1E3A387,
|
||||
0x20754FA0, 0x86024414, 0xB7EA5E89, 0x119D553D,
|
||||
0xD43A6BB3, 0x724D6007, 0x43A57A9A, 0xE5D2712E,
|
||||
0x139A01C7, 0xB5ED0A73, 0x840510EE, 0x22721B5A,
|
||||
0xE7D525D4, 0x41A22E60, 0x704A34FD, 0xD63D3F49,
|
||||
0xCC1D9F8B, 0x6A6A943F, 0x5B828EA2, 0xFDF58516,
|
||||
0x3852BB98, 0x9E25B02C, 0xAFCDAAB1, 0x09BAA105,
|
||||
0xFFF2D1EC, 0x5985DA58, 0x686DC0C5, 0xCE1ACB71,
|
||||
0x0BBDF5FF, 0xADCAFE4B, 0x9C22E4D6, 0x3A55EF62,
|
||||
0xABC30345, 0x0DB408F1, 0x3C5C126C, 0x9A2B19D8,
|
||||
0x5F8C2756, 0xF9FB2CE2, 0xC813367F, 0x6E643DCB,
|
||||
0x982C4D22, 0x3E5B4696, 0x0FB35C0B, 0xA9C457BF,
|
||||
0x6C636931, 0xCA146285, 0xFBFC7818, 0x5D8B73AC,
|
||||
0x03A0A617, 0xA5D7ADA3, 0x943FB73E, 0x3248BC8A,
|
||||
0xF7EF8204, 0x519889B0, 0x6070932D, 0xC6079899,
|
||||
0x304FE870, 0x9638E3C4, 0xA7D0F959, 0x01A7F2ED,
|
||||
0xC400CC63, 0x6277C7D7, 0x539FDD4A, 0xF5E8D6FE,
|
||||
0x647E3AD9, 0xC209316D, 0xF3E12BF0, 0x55962044,
|
||||
0x90311ECA, 0x3646157E, 0x07AE0FE3, 0xA1D90457,
|
||||
0x579174BE, 0xF1E67F0A, 0xC00E6597, 0x66796E23,
|
||||
0xA3DE50AD, 0x05A95B19, 0x34414184, 0x92364A30
|
||||
}, {
|
||||
0x00000000, 0xCCAA009E, 0x4225077D, 0x8E8F07E3,
|
||||
0x844A0EFA, 0x48E00E64, 0xC66F0987, 0x0AC50919,
|
||||
0xD3E51BB5, 0x1F4F1B2B, 0x91C01CC8, 0x5D6A1C56,
|
||||
0x57AF154F, 0x9B0515D1, 0x158A1232, 0xD92012AC,
|
||||
0x7CBB312B, 0xB01131B5, 0x3E9E3656, 0xF23436C8,
|
||||
0xF8F13FD1, 0x345B3F4F, 0xBAD438AC, 0x767E3832,
|
||||
0xAF5E2A9E, 0x63F42A00, 0xED7B2DE3, 0x21D12D7D,
|
||||
0x2B142464, 0xE7BE24FA, 0x69312319, 0xA59B2387,
|
||||
0xF9766256, 0x35DC62C8, 0xBB53652B, 0x77F965B5,
|
||||
0x7D3C6CAC, 0xB1966C32, 0x3F196BD1, 0xF3B36B4F,
|
||||
0x2A9379E3, 0xE639797D, 0x68B67E9E, 0xA41C7E00,
|
||||
0xAED97719, 0x62737787, 0xECFC7064, 0x205670FA,
|
||||
0x85CD537D, 0x496753E3, 0xC7E85400, 0x0B42549E,
|
||||
0x01875D87, 0xCD2D5D19, 0x43A25AFA, 0x8F085A64,
|
||||
0x562848C8, 0x9A824856, 0x140D4FB5, 0xD8A74F2B,
|
||||
0xD2624632, 0x1EC846AC, 0x9047414F, 0x5CED41D1,
|
||||
0x299DC2ED, 0xE537C273, 0x6BB8C590, 0xA712C50E,
|
||||
0xADD7CC17, 0x617DCC89, 0xEFF2CB6A, 0x2358CBF4,
|
||||
0xFA78D958, 0x36D2D9C6, 0xB85DDE25, 0x74F7DEBB,
|
||||
0x7E32D7A2, 0xB298D73C, 0x3C17D0DF, 0xF0BDD041,
|
||||
0x5526F3C6, 0x998CF358, 0x1703F4BB, 0xDBA9F425,
|
||||
0xD16CFD3C, 0x1DC6FDA2, 0x9349FA41, 0x5FE3FADF,
|
||||
0x86C3E873, 0x4A69E8ED, 0xC4E6EF0E, 0x084CEF90,
|
||||
0x0289E689, 0xCE23E617, 0x40ACE1F4, 0x8C06E16A,
|
||||
0xD0EBA0BB, 0x1C41A025, 0x92CEA7C6, 0x5E64A758,
|
||||
0x54A1AE41, 0x980BAEDF, 0x1684A93C, 0xDA2EA9A2,
|
||||
0x030EBB0E, 0xCFA4BB90, 0x412BBC73, 0x8D81BCED,
|
||||
0x8744B5F4, 0x4BEEB56A, 0xC561B289, 0x09CBB217,
|
||||
0xAC509190, 0x60FA910E, 0xEE7596ED, 0x22DF9673,
|
||||
0x281A9F6A, 0xE4B09FF4, 0x6A3F9817, 0xA6959889,
|
||||
0x7FB58A25, 0xB31F8ABB, 0x3D908D58, 0xF13A8DC6,
|
||||
0xFBFF84DF, 0x37558441, 0xB9DA83A2, 0x7570833C,
|
||||
0x533B85DA, 0x9F918544, 0x111E82A7, 0xDDB48239,
|
||||
0xD7718B20, 0x1BDB8BBE, 0x95548C5D, 0x59FE8CC3,
|
||||
0x80DE9E6F, 0x4C749EF1, 0xC2FB9912, 0x0E51998C,
|
||||
0x04949095, 0xC83E900B, 0x46B197E8, 0x8A1B9776,
|
||||
0x2F80B4F1, 0xE32AB46F, 0x6DA5B38C, 0xA10FB312,
|
||||
0xABCABA0B, 0x6760BA95, 0xE9EFBD76, 0x2545BDE8,
|
||||
0xFC65AF44, 0x30CFAFDA, 0xBE40A839, 0x72EAA8A7,
|
||||
0x782FA1BE, 0xB485A120, 0x3A0AA6C3, 0xF6A0A65D,
|
||||
0xAA4DE78C, 0x66E7E712, 0xE868E0F1, 0x24C2E06F,
|
||||
0x2E07E976, 0xE2ADE9E8, 0x6C22EE0B, 0xA088EE95,
|
||||
0x79A8FC39, 0xB502FCA7, 0x3B8DFB44, 0xF727FBDA,
|
||||
0xFDE2F2C3, 0x3148F25D, 0xBFC7F5BE, 0x736DF520,
|
||||
0xD6F6D6A7, 0x1A5CD639, 0x94D3D1DA, 0x5879D144,
|
||||
0x52BCD85D, 0x9E16D8C3, 0x1099DF20, 0xDC33DFBE,
|
||||
0x0513CD12, 0xC9B9CD8C, 0x4736CA6F, 0x8B9CCAF1,
|
||||
0x8159C3E8, 0x4DF3C376, 0xC37CC495, 0x0FD6C40B,
|
||||
0x7AA64737, 0xB60C47A9, 0x3883404A, 0xF42940D4,
|
||||
0xFEEC49CD, 0x32464953, 0xBCC94EB0, 0x70634E2E,
|
||||
0xA9435C82, 0x65E95C1C, 0xEB665BFF, 0x27CC5B61,
|
||||
0x2D095278, 0xE1A352E6, 0x6F2C5505, 0xA386559B,
|
||||
0x061D761C, 0xCAB77682, 0x44387161, 0x889271FF,
|
||||
0x825778E6, 0x4EFD7878, 0xC0727F9B, 0x0CD87F05,
|
||||
0xD5F86DA9, 0x19526D37, 0x97DD6AD4, 0x5B776A4A,
|
||||
0x51B26353, 0x9D1863CD, 0x1397642E, 0xDF3D64B0,
|
||||
0x83D02561, 0x4F7A25FF, 0xC1F5221C, 0x0D5F2282,
|
||||
0x079A2B9B, 0xCB302B05, 0x45BF2CE6, 0x89152C78,
|
||||
0x50353ED4, 0x9C9F3E4A, 0x121039A9, 0xDEBA3937,
|
||||
0xD47F302E, 0x18D530B0, 0x965A3753, 0x5AF037CD,
|
||||
0xFF6B144A, 0x33C114D4, 0xBD4E1337, 0x71E413A9,
|
||||
0x7B211AB0, 0xB78B1A2E, 0x39041DCD, 0xF5AE1D53,
|
||||
0x2C8E0FFF, 0xE0240F61, 0x6EAB0882, 0xA201081C,
|
||||
0xA8C40105, 0x646E019B, 0xEAE10678, 0x264B06E6
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file crc_macros.h
|
||||
/// \brief Some endian-dependent macros for CRC32 and CRC64
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# define A(x) ((x) >> 24)
|
||||
# define B(x) (((x) >> 16) & 0xFF)
|
||||
# define C(x) (((x) >> 8) & 0xFF)
|
||||
# define D(x) ((x) & 0xFF)
|
||||
|
||||
# define S8(x) ((x) << 8)
|
||||
# define S32(x) ((x) << 32)
|
||||
|
||||
#else
|
||||
# define A(x) ((x) & 0xFF)
|
||||
# define B(x) (((x) >> 8) & 0xFF)
|
||||
# define C(x) (((x) >> 16) & 0xFF)
|
||||
# define D(x) ((x) >> 24)
|
||||
|
||||
# define S8(x) ((x) >> 8)
|
||||
# define S32(x) ((x) >> 32)
|
||||
#endif
|
||||
@@ -0,0 +1,227 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file alone_decoder.c
|
||||
/// \brief Decoder for LZMA_Alone files
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "alone_decoder.h"
|
||||
#include "lzma_decoder.h"
|
||||
#include "lz_decoder.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
lzma_next_coder next;
|
||||
|
||||
enum {
|
||||
SEQ_PROPERTIES,
|
||||
SEQ_DICTIONARY_SIZE,
|
||||
SEQ_UNCOMPRESSED_SIZE,
|
||||
SEQ_CODER_INIT,
|
||||
SEQ_CODE,
|
||||
} sequence;
|
||||
|
||||
/// If true, reject files that are unlikely to be .lzma files.
|
||||
/// If false, more non-.lzma files get accepted and will give
|
||||
/// LZMA_DATA_ERROR either immediately or after a few output bytes.
|
||||
bool picky;
|
||||
|
||||
/// Position in the header fields
|
||||
size_t pos;
|
||||
|
||||
/// Uncompressed size decoded from the header
|
||||
lzma_vli uncompressed_size;
|
||||
|
||||
/// Memory usage limit
|
||||
uint64_t memlimit;
|
||||
|
||||
/// Amount of memory actually needed (only an estimate)
|
||||
uint64_t memusage;
|
||||
|
||||
/// Options decoded from the header needed to initialize
|
||||
/// the LZMA decoder
|
||||
lzma_options_lzma options;
|
||||
} lzma_alone_coder;
|
||||
|
||||
|
||||
static lzma_ret
|
||||
alone_decode(void *coder_ptr,
|
||||
const lzma_allocator *allocator lzma_attribute((__unused__)),
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size,
|
||||
lzma_action action)
|
||||
{
|
||||
lzma_alone_coder *coder = coder_ptr;
|
||||
|
||||
while (*out_pos < out_size
|
||||
&& (coder->sequence == SEQ_CODE || *in_pos < in_size))
|
||||
switch (coder->sequence) {
|
||||
case SEQ_PROPERTIES:
|
||||
if (lzma_lzma_lclppb_decode(&coder->options, in[*in_pos]))
|
||||
return LZMA_FORMAT_ERROR;
|
||||
|
||||
coder->sequence = SEQ_DICTIONARY_SIZE;
|
||||
++*in_pos;
|
||||
break;
|
||||
|
||||
case SEQ_DICTIONARY_SIZE:
|
||||
coder->options.dict_size
|
||||
|= (size_t)(in[*in_pos]) << (coder->pos * 8);
|
||||
++*in_pos;
|
||||
if (++coder->pos < 4)
|
||||
break;
|
||||
|
||||
if (coder->picky && coder->options.dict_size
|
||||
!= UINT32_MAX) {
|
||||
// A hack to ditch tons of false positives:
|
||||
// We allow only dictionary sizes that are
|
||||
// 2^n or 2^n + 2^(n-1). LZMA_Alone created
|
||||
// only files with 2^n, but accepts any
|
||||
// dictionary size.
|
||||
uint32_t d = coder->options.dict_size - 1;
|
||||
d |= d >> 2;
|
||||
d |= d >> 3;
|
||||
d |= d >> 4;
|
||||
d |= d >> 8;
|
||||
d |= d >> 16;
|
||||
++d;
|
||||
|
||||
if (d != coder->options.dict_size)
|
||||
return LZMA_FORMAT_ERROR;
|
||||
}
|
||||
|
||||
coder->uncompressed_size = LZMA_VLI_UNKNOWN;
|
||||
|
||||
// Calculate the memory usage so that it is ready
|
||||
// for SEQ_CODER_INIT.
|
||||
coder->memusage = lzma_lzma_decoder_memusage(&coder->options)
|
||||
+ LZMA_MEMUSAGE_BASE;
|
||||
|
||||
coder->pos = 0;
|
||||
coder->sequence = SEQ_CODER_INIT;
|
||||
|
||||
// Fall through
|
||||
|
||||
case SEQ_CODER_INIT: {
|
||||
if (coder->memusage > coder->memlimit)
|
||||
return LZMA_MEMLIMIT_ERROR;
|
||||
|
||||
lzma_filter_info filters[2] = {
|
||||
{
|
||||
.init = &lzma_lzma_decoder_init,
|
||||
.options = &coder->options,
|
||||
}, {
|
||||
.init = NULL,
|
||||
}
|
||||
};
|
||||
|
||||
const lzma_ret ret = lzma_next_filter_init(&coder->next,
|
||||
allocator, filters);
|
||||
if (ret != LZMA_OK)
|
||||
return ret;
|
||||
|
||||
// Use a hack to set the uncompressed size.
|
||||
lzma_lz_decoder_uncompressed(coder->next.coder,
|
||||
coder->uncompressed_size);
|
||||
|
||||
coder->sequence = SEQ_CODE;
|
||||
break;
|
||||
}
|
||||
|
||||
case SEQ_CODE: {
|
||||
return coder->next.code(coder->next.coder,
|
||||
allocator, in, in_pos, in_size,
|
||||
out, out_pos, out_size, action);
|
||||
}
|
||||
|
||||
default:
|
||||
return LZMA_PROG_ERROR;
|
||||
}
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
alone_decoder_end(void *coder_ptr, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_alone_coder *coder = coder_ptr;
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
alone_decoder_memconfig(void *coder_ptr, uint64_t *memusage,
|
||||
uint64_t *old_memlimit, uint64_t new_memlimit)
|
||||
{
|
||||
lzma_alone_coder *coder = coder_ptr;
|
||||
|
||||
*memusage = coder->memusage;
|
||||
*old_memlimit = coder->memlimit;
|
||||
|
||||
if (new_memlimit != 0) {
|
||||
if (new_memlimit < coder->memusage)
|
||||
return LZMA_MEMLIMIT_ERROR;
|
||||
|
||||
coder->memlimit = new_memlimit;
|
||||
}
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_alone_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
uint64_t memlimit, bool picky)
|
||||
{
|
||||
lzma_next_coder_init(&lzma_alone_decoder_init, next, allocator);
|
||||
|
||||
if (memlimit == 0)
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
lzma_alone_coder *coder = next->coder;
|
||||
|
||||
if (coder == NULL) {
|
||||
coder = lzma_alloc(sizeof(lzma_alone_coder), allocator);
|
||||
if (coder == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
next->coder = coder;
|
||||
next->code = &alone_decode;
|
||||
next->end = &alone_decoder_end;
|
||||
next->memconfig = &alone_decoder_memconfig;
|
||||
coder->next = LZMA_NEXT_CODER_INIT;
|
||||
}
|
||||
|
||||
coder->sequence = SEQ_PROPERTIES;
|
||||
coder->picky = picky;
|
||||
coder->pos = 0;
|
||||
coder->options.dict_size = 0;
|
||||
coder->options.preset_dict = NULL;
|
||||
coder->options.preset_dict_size = 0;
|
||||
coder->uncompressed_size = 0;
|
||||
coder->memlimit = memlimit;
|
||||
coder->memusage = LZMA_MEMUSAGE_BASE;
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_alone_decoder(lzma_stream *strm, uint64_t memlimit)
|
||||
{
|
||||
lzma_next_strm_init(lzma_alone_decoder_init, strm, memlimit, false);
|
||||
|
||||
strm->internal->supported_actions[LZMA_RUN] = true;
|
||||
strm->internal->supported_actions[LZMA_FINISH] = true;
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file alone_decoder.h
|
||||
/// \brief Decoder for LZMA_Alone files
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_ALONE_DECODER_H
|
||||
#define LZMA_ALONE_DECODER_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
extern lzma_ret lzma_alone_decoder_init(
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
uint64_t memlimit, bool picky);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,160 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file alone_decoder.c
|
||||
/// \brief Decoder for LZMA_Alone files
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common.h"
|
||||
#include "lzma_encoder.h"
|
||||
|
||||
|
||||
#define ALONE_HEADER_SIZE (1 + 4)
|
||||
|
||||
|
||||
typedef struct {
|
||||
lzma_next_coder next;
|
||||
|
||||
enum {
|
||||
SEQ_HEADER,
|
||||
SEQ_CODE,
|
||||
} sequence;
|
||||
|
||||
size_t header_pos;
|
||||
uint8_t header[ALONE_HEADER_SIZE];
|
||||
} lzma_alone_coder;
|
||||
|
||||
|
||||
static lzma_ret
|
||||
alone_encode(void *coder_ptr,
|
||||
const lzma_allocator *allocator lzma_attribute((__unused__)),
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size,
|
||||
lzma_action action)
|
||||
{
|
||||
lzma_alone_coder *coder = coder_ptr;
|
||||
|
||||
while (*out_pos < out_size)
|
||||
switch (coder->sequence) {
|
||||
case SEQ_HEADER:
|
||||
lzma_bufcpy(coder->header, &coder->header_pos,
|
||||
ALONE_HEADER_SIZE,
|
||||
out, out_pos, out_size);
|
||||
if (coder->header_pos < ALONE_HEADER_SIZE)
|
||||
return LZMA_OK;
|
||||
|
||||
coder->sequence = SEQ_CODE;
|
||||
break;
|
||||
|
||||
case SEQ_CODE:
|
||||
return coder->next.code(coder->next.coder,
|
||||
allocator, in, in_pos, in_size,
|
||||
out, out_pos, out_size, action);
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return LZMA_PROG_ERROR;
|
||||
}
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
alone_encoder_end(void *coder_ptr, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_alone_coder *coder = coder_ptr;
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
lzma_free(coder, allocator);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// At least for now, this is not used by any internal function.
|
||||
static lzma_ret
|
||||
alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_options_lzma *options)
|
||||
{
|
||||
lzma_next_coder_init(&alone_encoder_init, next, allocator);
|
||||
|
||||
lzma_alone_coder *coder = next->coder;
|
||||
|
||||
if (coder == NULL) {
|
||||
coder = lzma_alloc(sizeof(lzma_alone_coder), allocator);
|
||||
if (coder == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
next->coder = coder;
|
||||
next->code = &alone_encode;
|
||||
next->end = &alone_encoder_end;
|
||||
coder->next = LZMA_NEXT_CODER_INIT;
|
||||
}
|
||||
|
||||
// Basic initializations
|
||||
coder->sequence = SEQ_HEADER;
|
||||
coder->header_pos = 0;
|
||||
|
||||
// Encode the header:
|
||||
// - Properties (1 byte)
|
||||
if (lzma_lzma_lclppb_encode(options, coder->header))
|
||||
return LZMA_OPTIONS_ERROR;
|
||||
|
||||
// - Dictionary size (4 bytes)
|
||||
if (options->dict_size < LZMA_DICT_SIZE_MIN)
|
||||
return LZMA_OPTIONS_ERROR;
|
||||
|
||||
// Round up to the next 2^n or 2^n + 2^(n - 1) depending on which
|
||||
// one is the next unless it is UINT32_MAX. While the header would
|
||||
// allow any 32-bit integer, we do this to keep the decoder of liblzma
|
||||
// accepting the resulting files.
|
||||
uint32_t d = options->dict_size - 1;
|
||||
d |= d >> 2;
|
||||
d |= d >> 3;
|
||||
d |= d >> 4;
|
||||
d |= d >> 8;
|
||||
d |= d >> 16;
|
||||
if (d != UINT32_MAX)
|
||||
++d;
|
||||
|
||||
unaligned_write32le(coder->header + 1, d);
|
||||
|
||||
// Initialize the LZMA encoder.
|
||||
const lzma_filter_info filters[2] = {
|
||||
{
|
||||
.init = &lzma_lzma_encoder_init,
|
||||
.options = (void *)(options),
|
||||
}, {
|
||||
.init = NULL,
|
||||
}
|
||||
};
|
||||
|
||||
return lzma_next_filter_init(&coder->next, allocator, filters);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
extern lzma_ret
|
||||
lzma_alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_options_alone *options)
|
||||
{
|
||||
lzma_next_coder_init(&alone_encoder_init, next, allocator, options);
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_alone_encoder(lzma_stream *strm, const lzma_options_lzma *options)
|
||||
{
|
||||
lzma_next_strm_init(alone_encoder_init, strm, options);
|
||||
|
||||
strm->internal->supported_actions[LZMA_RUN] = true;
|
||||
strm->internal->supported_actions[LZMA_FINISH] = true;
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
+443
@@ -0,0 +1,443 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file common.h
|
||||
/// \brief Common functions needed in many places in liblzma
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/////////////
|
||||
// Version //
|
||||
/////////////
|
||||
|
||||
extern LZMA_API(uint32_t)
|
||||
lzma_version_number(void)
|
||||
{
|
||||
return LZMA_VERSION;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(const char *)
|
||||
lzma_version_string(void)
|
||||
{
|
||||
return LZMA_VERSION_STRING;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////
|
||||
// Memory allocation //
|
||||
///////////////////////
|
||||
|
||||
extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
|
||||
lzma_alloc(size_t size, const lzma_allocator *allocator)
|
||||
{
|
||||
// Some malloc() variants return NULL if called with size == 0.
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
|
||||
void *ptr;
|
||||
|
||||
if (allocator != NULL && allocator->alloc != NULL)
|
||||
ptr = allocator->alloc(allocator->opaque, 1, size);
|
||||
else
|
||||
ptr = malloc(size);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
|
||||
lzma_alloc_zero(size_t size, const lzma_allocator *allocator)
|
||||
{
|
||||
// Some calloc() variants return NULL if called with size == 0.
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
|
||||
void *ptr;
|
||||
|
||||
if (allocator != NULL && allocator->alloc != NULL) {
|
||||
ptr = allocator->alloc(allocator->opaque, 1, size);
|
||||
if (ptr != NULL)
|
||||
memzero(ptr, size);
|
||||
} else {
|
||||
ptr = calloc(1, size);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lzma_free(void *ptr, const lzma_allocator *allocator)
|
||||
{
|
||||
if (allocator != NULL && allocator->free != NULL)
|
||||
allocator->free(allocator->opaque, ptr);
|
||||
else
|
||||
free(ptr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//////////
|
||||
// Misc //
|
||||
//////////
|
||||
|
||||
extern size_t
|
||||
lzma_bufcpy(const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size)
|
||||
{
|
||||
const size_t in_avail = in_size - *in_pos;
|
||||
const size_t out_avail = out_size - *out_pos;
|
||||
const size_t copy_size = my_min(in_avail, out_avail);
|
||||
|
||||
memcpy(out + *out_pos, in + *in_pos, copy_size);
|
||||
|
||||
*in_pos += copy_size;
|
||||
*out_pos += copy_size;
|
||||
|
||||
return copy_size;
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_next_filter_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
lzma_next_coder_init(filters[0].init, next, allocator);
|
||||
next->id = filters[0].id;
|
||||
return filters[0].init == NULL
|
||||
? LZMA_OK : filters[0].init(next, allocator, filters);
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_next_filter_update(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter *reversed_filters)
|
||||
{
|
||||
// Check that the application isn't trying to change the Filter ID.
|
||||
// End of filters is indicated with LZMA_VLI_UNKNOWN in both
|
||||
// reversed_filters[0].id and next->id.
|
||||
if (reversed_filters[0].id != next->id)
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
if (reversed_filters[0].id == LZMA_VLI_UNKNOWN)
|
||||
return LZMA_OK;
|
||||
|
||||
assert(next->update != NULL);
|
||||
return next->update(next->coder, allocator, NULL, reversed_filters);
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator)
|
||||
{
|
||||
if (next->init != (uintptr_t)(NULL)) {
|
||||
// To avoid tiny end functions that simply call
|
||||
// lzma_free(coder, allocator), we allow leaving next->end
|
||||
// NULL and call lzma_free() here.
|
||||
if (next->end != NULL)
|
||||
next->end(next->coder, allocator);
|
||||
else
|
||||
lzma_free(next->coder, allocator);
|
||||
|
||||
// Reset the variables so the we don't accidentally think
|
||||
// that it is an already initialized coder.
|
||||
*next = LZMA_NEXT_CODER_INIT;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
// External to internal API wrapper //
|
||||
//////////////////////////////////////
|
||||
|
||||
extern lzma_ret
|
||||
lzma_strm_init(lzma_stream *strm)
|
||||
{
|
||||
if (strm == NULL)
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
if (strm->internal == NULL) {
|
||||
strm->internal = lzma_alloc(sizeof(lzma_internal),
|
||||
strm->allocator);
|
||||
if (strm->internal == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
strm->internal->next = LZMA_NEXT_CODER_INIT;
|
||||
}
|
||||
|
||||
memzero(strm->internal->supported_actions,
|
||||
sizeof(strm->internal->supported_actions));
|
||||
strm->internal->sequence = ISEQ_RUN;
|
||||
strm->internal->allow_buf_error = false;
|
||||
|
||||
strm->total_in = 0;
|
||||
strm->total_out = 0;
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_code(lzma_stream *strm, lzma_action action)
|
||||
{
|
||||
// Sanity checks
|
||||
if ((strm->next_in == NULL && strm->avail_in != 0)
|
||||
|| (strm->next_out == NULL && strm->avail_out != 0)
|
||||
|| strm->internal == NULL
|
||||
|| strm->internal->next.code == NULL
|
||||
|| (unsigned int)(action) > LZMA_ACTION_MAX
|
||||
|| !strm->internal->supported_actions[action])
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
// Check if unsupported members have been set to non-zero or non-NULL,
|
||||
// which would indicate that some new feature is wanted.
|
||||
if (strm->reserved_ptr1 != NULL
|
||||
|| strm->reserved_ptr2 != NULL
|
||||
|| strm->reserved_ptr3 != NULL
|
||||
|| strm->reserved_ptr4 != NULL
|
||||
|| strm->reserved_int1 != 0
|
||||
|| strm->reserved_int2 != 0
|
||||
|| strm->reserved_int3 != 0
|
||||
|| strm->reserved_int4 != 0
|
||||
|| strm->reserved_enum1 != LZMA_RESERVED_ENUM
|
||||
|| strm->reserved_enum2 != LZMA_RESERVED_ENUM)
|
||||
return LZMA_OPTIONS_ERROR;
|
||||
|
||||
switch (strm->internal->sequence) {
|
||||
case ISEQ_RUN:
|
||||
switch (action) {
|
||||
case LZMA_RUN:
|
||||
break;
|
||||
|
||||
case LZMA_SYNC_FLUSH:
|
||||
strm->internal->sequence = ISEQ_SYNC_FLUSH;
|
||||
break;
|
||||
|
||||
case LZMA_FULL_FLUSH:
|
||||
strm->internal->sequence = ISEQ_FULL_FLUSH;
|
||||
break;
|
||||
|
||||
case LZMA_FINISH:
|
||||
strm->internal->sequence = ISEQ_FINISH;
|
||||
break;
|
||||
|
||||
case LZMA_FULL_BARRIER:
|
||||
strm->internal->sequence = ISEQ_FULL_BARRIER;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ISEQ_SYNC_FLUSH:
|
||||
// The same action must be used until we return
|
||||
// LZMA_STREAM_END, and the amount of input must not change.
|
||||
if (action != LZMA_SYNC_FLUSH
|
||||
|| strm->internal->avail_in != strm->avail_in)
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
break;
|
||||
|
||||
case ISEQ_FULL_FLUSH:
|
||||
if (action != LZMA_FULL_FLUSH
|
||||
|| strm->internal->avail_in != strm->avail_in)
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
break;
|
||||
|
||||
case ISEQ_FINISH:
|
||||
if (action != LZMA_FINISH
|
||||
|| strm->internal->avail_in != strm->avail_in)
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
break;
|
||||
|
||||
case ISEQ_FULL_BARRIER:
|
||||
if (action != LZMA_FULL_BARRIER
|
||||
|| strm->internal->avail_in != strm->avail_in)
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
break;
|
||||
|
||||
case ISEQ_END:
|
||||
return LZMA_STREAM_END;
|
||||
|
||||
case ISEQ_ERROR:
|
||||
default:
|
||||
return LZMA_PROG_ERROR;
|
||||
}
|
||||
|
||||
size_t in_pos = 0;
|
||||
size_t out_pos = 0;
|
||||
lzma_ret ret = strm->internal->next.code(
|
||||
strm->internal->next.coder, strm->allocator,
|
||||
strm->next_in, &in_pos, strm->avail_in,
|
||||
strm->next_out, &out_pos, strm->avail_out, action);
|
||||
|
||||
strm->next_in += in_pos;
|
||||
strm->avail_in -= in_pos;
|
||||
strm->total_in += in_pos;
|
||||
|
||||
strm->next_out += out_pos;
|
||||
strm->avail_out -= out_pos;
|
||||
strm->total_out += out_pos;
|
||||
|
||||
strm->internal->avail_in = strm->avail_in;
|
||||
|
||||
// Cast is needed to silence a warning about LZMA_TIMED_OUT, which
|
||||
// isn't part of lzma_ret enumeration.
|
||||
switch ((unsigned int)(ret)) {
|
||||
case LZMA_OK:
|
||||
// Don't return LZMA_BUF_ERROR when it happens the first time.
|
||||
// This is to avoid returning LZMA_BUF_ERROR when avail_out
|
||||
// was zero but still there was no more data left to written
|
||||
// to next_out.
|
||||
if (out_pos == 0 && in_pos == 0) {
|
||||
if (strm->internal->allow_buf_error)
|
||||
ret = LZMA_BUF_ERROR;
|
||||
else
|
||||
strm->internal->allow_buf_error = true;
|
||||
} else {
|
||||
strm->internal->allow_buf_error = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case LZMA_TIMED_OUT:
|
||||
strm->internal->allow_buf_error = false;
|
||||
ret = LZMA_OK;
|
||||
break;
|
||||
|
||||
case LZMA_STREAM_END:
|
||||
if (strm->internal->sequence == ISEQ_SYNC_FLUSH
|
||||
|| strm->internal->sequence == ISEQ_FULL_FLUSH
|
||||
|| strm->internal->sequence
|
||||
== ISEQ_FULL_BARRIER)
|
||||
strm->internal->sequence = ISEQ_RUN;
|
||||
else
|
||||
strm->internal->sequence = ISEQ_END;
|
||||
|
||||
// Fall through
|
||||
|
||||
case LZMA_NO_CHECK:
|
||||
case LZMA_UNSUPPORTED_CHECK:
|
||||
case LZMA_GET_CHECK:
|
||||
case LZMA_MEMLIMIT_ERROR:
|
||||
// Something else than LZMA_OK, but not a fatal error,
|
||||
// that is, coding may be continued (except if ISEQ_END).
|
||||
strm->internal->allow_buf_error = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
// All the other errors are fatal; coding cannot be continued.
|
||||
assert(ret != LZMA_BUF_ERROR);
|
||||
strm->internal->sequence = ISEQ_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(void)
|
||||
lzma_end(lzma_stream *strm)
|
||||
{
|
||||
if (strm != NULL && strm->internal != NULL) {
|
||||
lzma_next_end(&strm->internal->next, strm->allocator);
|
||||
lzma_free(strm->internal, strm->allocator);
|
||||
strm->internal = NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(void)
|
||||
lzma_get_progress(lzma_stream *strm,
|
||||
uint64_t *progress_in, uint64_t *progress_out)
|
||||
{
|
||||
if (strm->internal->next.get_progress != NULL) {
|
||||
strm->internal->next.get_progress(strm->internal->next.coder,
|
||||
progress_in, progress_out);
|
||||
} else {
|
||||
*progress_in = strm->total_in;
|
||||
*progress_out = strm->total_out;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(lzma_check)
|
||||
lzma_get_check(const lzma_stream *strm)
|
||||
{
|
||||
// Return LZMA_CHECK_NONE if we cannot know the check type.
|
||||
// It's a bug in the application if this happens.
|
||||
if (strm->internal->next.get_check == NULL)
|
||||
return LZMA_CHECK_NONE;
|
||||
|
||||
return strm->internal->next.get_check(strm->internal->next.coder);
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(uint64_t)
|
||||
lzma_memusage(const lzma_stream *strm)
|
||||
{
|
||||
uint64_t memusage;
|
||||
uint64_t old_memlimit;
|
||||
|
||||
if (strm == NULL || strm->internal == NULL
|
||||
|| strm->internal->next.memconfig == NULL
|
||||
|| strm->internal->next.memconfig(
|
||||
strm->internal->next.coder,
|
||||
&memusage, &old_memlimit, 0) != LZMA_OK)
|
||||
return 0;
|
||||
|
||||
return memusage;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(uint64_t)
|
||||
lzma_memlimit_get(const lzma_stream *strm)
|
||||
{
|
||||
uint64_t old_memlimit;
|
||||
uint64_t memusage;
|
||||
|
||||
if (strm == NULL || strm->internal == NULL
|
||||
|| strm->internal->next.memconfig == NULL
|
||||
|| strm->internal->next.memconfig(
|
||||
strm->internal->next.coder,
|
||||
&memusage, &old_memlimit, 0) != LZMA_OK)
|
||||
return 0;
|
||||
|
||||
return old_memlimit;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_memlimit_set(lzma_stream *strm, uint64_t new_memlimit)
|
||||
{
|
||||
// Dummy variables to simplify memconfig functions
|
||||
uint64_t old_memlimit;
|
||||
uint64_t memusage;
|
||||
|
||||
if (strm == NULL || strm->internal == NULL
|
||||
|| strm->internal->next.memconfig == NULL)
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
if (new_memlimit != 0 && new_memlimit < LZMA_MEMUSAGE_BASE)
|
||||
return LZMA_MEMLIMIT_ERROR;
|
||||
|
||||
return strm->internal->next.memconfig(strm->internal->next.coder,
|
||||
&memusage, &old_memlimit, new_memlimit);
|
||||
}
|
||||
+313
@@ -0,0 +1,313 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file common.h
|
||||
/// \brief Definitions common to the whole liblzma library
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_COMMON_H
|
||||
#define LZMA_COMMON_H
|
||||
|
||||
#include "sysdefs.h"
|
||||
#include "tuklib_integer.h"
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# ifdef DLL_EXPORT
|
||||
# define LZMA_API_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define LZMA_API_EXPORT
|
||||
# endif
|
||||
// Don't use ifdef or defined() below.
|
||||
#elif HAVE_VISIBILITY
|
||||
# define LZMA_API_EXPORT __attribute__((__visibility__("default")))
|
||||
#else
|
||||
# define LZMA_API_EXPORT
|
||||
#endif
|
||||
|
||||
#define LZMA_API(type) LZMA_API_EXPORT type LZMA_API_CALL
|
||||
|
||||
#include "lzma.h"
|
||||
|
||||
// These allow helping the compiler in some often-executed branches, whose
|
||||
// result is almost always the same.
|
||||
#ifdef __GNUC__
|
||||
# define likely(expr) __builtin_expect(expr, true)
|
||||
# define unlikely(expr) __builtin_expect(expr, false)
|
||||
#else
|
||||
# define likely(expr) (expr)
|
||||
# define unlikely(expr) (expr)
|
||||
#endif
|
||||
|
||||
|
||||
/// Size of temporary buffers needed in some filters
|
||||
#define LZMA_BUFFER_SIZE 4096
|
||||
|
||||
|
||||
/// Maximum number of worker threads within one multithreaded component.
|
||||
/// The limit exists solely to make it simpler to prevent integer overflows
|
||||
/// when allocating structures etc. This should be big enough for now...
|
||||
/// the code won't scale anywhere close to this number anyway.
|
||||
#define LZMA_THREADS_MAX 16384
|
||||
|
||||
|
||||
/// Starting value for memory usage estimates. Instead of calculating size
|
||||
/// of _every_ structure and taking into account malloc() overhead etc., we
|
||||
/// add a base size to all memory usage estimates. It's not very accurate
|
||||
/// but should be easily good enough.
|
||||
#define LZMA_MEMUSAGE_BASE (UINT64_C(1) << 15)
|
||||
|
||||
/// Start of internal Filter ID space. These IDs must never be used
|
||||
/// in Streams.
|
||||
#define LZMA_FILTER_RESERVED_START (LZMA_VLI_C(1) << 62)
|
||||
|
||||
|
||||
/// Supported flags that can be passed to lzma_stream_decoder()
|
||||
/// or lzma_auto_decoder().
|
||||
#define LZMA_SUPPORTED_FLAGS \
|
||||
( LZMA_TELL_NO_CHECK \
|
||||
| LZMA_TELL_UNSUPPORTED_CHECK \
|
||||
| LZMA_TELL_ANY_CHECK \
|
||||
| LZMA_IGNORE_CHECK \
|
||||
| LZMA_CONCATENATED )
|
||||
|
||||
|
||||
/// Largest valid lzma_action value as unsigned integer.
|
||||
#define LZMA_ACTION_MAX ((unsigned int)(LZMA_FULL_BARRIER))
|
||||
|
||||
|
||||
/// Special return value (lzma_ret) to indicate that a timeout was reached
|
||||
/// and lzma_code() must not return LZMA_BUF_ERROR. This is converted to
|
||||
/// LZMA_OK in lzma_code(). This is not in the lzma_ret enumeration because
|
||||
/// there's no need to have it in the public API.
|
||||
#define LZMA_TIMED_OUT 32
|
||||
|
||||
|
||||
typedef struct lzma_next_coder_s lzma_next_coder;
|
||||
|
||||
typedef struct lzma_filter_info_s lzma_filter_info;
|
||||
|
||||
|
||||
/// Type of a function used to initialize a filter encoder or decoder
|
||||
typedef lzma_ret (*lzma_init_function)(
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
/// Type of a function to do some kind of coding work (filters, Stream,
|
||||
/// Block encoders/decoders etc.). Some special coders use don't use both
|
||||
/// input and output buffers, but for simplicity they still use this same
|
||||
/// function prototype.
|
||||
typedef lzma_ret (*lzma_code_function)(
|
||||
void *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size,
|
||||
lzma_action action);
|
||||
|
||||
/// Type of a function to free the memory allocated for the coder
|
||||
typedef void (*lzma_end_function)(
|
||||
void *coder, const lzma_allocator *allocator);
|
||||
|
||||
|
||||
/// Raw coder validates and converts an array of lzma_filter structures to
|
||||
/// an array of lzma_filter_info structures. This array is used with
|
||||
/// lzma_next_filter_init to initialize the filter chain.
|
||||
struct lzma_filter_info_s {
|
||||
/// Filter ID. This is used only by the encoder
|
||||
/// with lzma_filters_update().
|
||||
lzma_vli id;
|
||||
|
||||
/// Pointer to function used to initialize the filter.
|
||||
/// This is NULL to indicate end of array.
|
||||
lzma_init_function init;
|
||||
|
||||
/// Pointer to filter's options structure
|
||||
void *options;
|
||||
};
|
||||
|
||||
|
||||
/// Hold data and function pointers of the next filter in the chain.
|
||||
struct lzma_next_coder_s {
|
||||
/// Pointer to coder-specific data
|
||||
void *coder;
|
||||
|
||||
/// Filter ID. This is LZMA_VLI_UNKNOWN when this structure doesn't
|
||||
/// point to a filter coder.
|
||||
lzma_vli id;
|
||||
|
||||
/// "Pointer" to init function. This is never called here.
|
||||
/// We need only to detect if we are initializing a coder
|
||||
/// that was allocated earlier. See lzma_next_coder_init and
|
||||
/// lzma_next_strm_init macros in this file.
|
||||
uintptr_t init;
|
||||
|
||||
/// Pointer to function to do the actual coding
|
||||
lzma_code_function code;
|
||||
|
||||
/// Pointer to function to free lzma_next_coder.coder. This can
|
||||
/// be NULL; in that case, lzma_free is called to free
|
||||
/// lzma_next_coder.coder.
|
||||
lzma_end_function end;
|
||||
|
||||
/// Pointer to a function to get progress information. If this is NULL,
|
||||
/// lzma_stream.total_in and .total_out are used instead.
|
||||
void (*get_progress)(void *coder,
|
||||
uint64_t *progress_in, uint64_t *progress_out);
|
||||
|
||||
/// Pointer to function to return the type of the integrity check.
|
||||
/// Most coders won't support this.
|
||||
lzma_check (*get_check)(const void *coder);
|
||||
|
||||
/// Pointer to function to get and/or change the memory usage limit.
|
||||
/// If new_memlimit == 0, the limit is not changed.
|
||||
lzma_ret (*memconfig)(void *coder, uint64_t *memusage,
|
||||
uint64_t *old_memlimit, uint64_t new_memlimit);
|
||||
|
||||
/// Update the filter-specific options or the whole filter chain
|
||||
/// in the encoder.
|
||||
lzma_ret (*update)(void *coder, const lzma_allocator *allocator,
|
||||
const lzma_filter *filters,
|
||||
const lzma_filter *reversed_filters);
|
||||
};
|
||||
|
||||
|
||||
/// Macro to initialize lzma_next_coder structure
|
||||
#define LZMA_NEXT_CODER_INIT \
|
||||
(lzma_next_coder){ \
|
||||
.coder = NULL, \
|
||||
.init = (uintptr_t)(NULL), \
|
||||
.id = LZMA_VLI_UNKNOWN, \
|
||||
.code = NULL, \
|
||||
.end = NULL, \
|
||||
.get_progress = NULL, \
|
||||
.get_check = NULL, \
|
||||
.memconfig = NULL, \
|
||||
.update = NULL, \
|
||||
}
|
||||
|
||||
|
||||
/// Internal data for lzma_strm_init, lzma_code, and lzma_end. A pointer to
|
||||
/// this is stored in lzma_stream.
|
||||
struct lzma_internal_s {
|
||||
/// The actual coder that should do something useful
|
||||
lzma_next_coder next;
|
||||
|
||||
/// Track the state of the coder. This is used to validate arguments
|
||||
/// so that the actual coders can rely on e.g. that LZMA_SYNC_FLUSH
|
||||
/// is used on every call to lzma_code until next.code has returned
|
||||
/// LZMA_STREAM_END.
|
||||
enum {
|
||||
ISEQ_RUN,
|
||||
ISEQ_SYNC_FLUSH,
|
||||
ISEQ_FULL_FLUSH,
|
||||
ISEQ_FINISH,
|
||||
ISEQ_FULL_BARRIER,
|
||||
ISEQ_END,
|
||||
ISEQ_ERROR,
|
||||
} sequence;
|
||||
|
||||
/// A copy of lzma_stream avail_in. This is used to verify that the
|
||||
/// amount of input doesn't change once e.g. LZMA_FINISH has been
|
||||
/// used.
|
||||
size_t avail_in;
|
||||
|
||||
/// Indicates which lzma_action values are allowed by next.code.
|
||||
bool supported_actions[LZMA_ACTION_MAX + 1];
|
||||
|
||||
/// If true, lzma_code will return LZMA_BUF_ERROR if no progress was
|
||||
/// made (no input consumed and no output produced by next.code).
|
||||
bool allow_buf_error;
|
||||
};
|
||||
|
||||
|
||||
/// Allocates memory
|
||||
extern void *lzma_alloc(size_t size, const lzma_allocator *allocator)
|
||||
lzma_attribute((__malloc__)) lzma_attr_alloc_size(1);
|
||||
|
||||
/// Allocates memory and zeroes it (like calloc()). This can be faster
|
||||
/// than lzma_alloc() + memzero() while being backward compatible with
|
||||
/// custom allocators.
|
||||
extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
|
||||
lzma_alloc_zero(size_t size, const lzma_allocator *allocator);
|
||||
|
||||
/// Frees memory
|
||||
extern void lzma_free(void *ptr, const lzma_allocator *allocator);
|
||||
|
||||
|
||||
/// Allocates strm->internal if it is NULL, and initializes *strm and
|
||||
/// strm->internal. This function is only called via lzma_next_strm_init macro.
|
||||
extern lzma_ret lzma_strm_init(lzma_stream *strm);
|
||||
|
||||
/// Initializes the next filter in the chain, if any. This takes care of
|
||||
/// freeing the memory of previously initialized filter if it is different
|
||||
/// than the filter being initialized now. This way the actual filter
|
||||
/// initialization functions don't need to use lzma_next_coder_init macro.
|
||||
extern lzma_ret lzma_next_filter_init(lzma_next_coder *next,
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
/// Update the next filter in the chain, if any. This checks that
|
||||
/// the application is not trying to change the Filter IDs.
|
||||
extern lzma_ret lzma_next_filter_update(
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter *reversed_filters);
|
||||
|
||||
/// Frees the memory allocated for next->coder either using next->end or,
|
||||
/// if next->end is NULL, using lzma_free.
|
||||
extern void lzma_next_end(lzma_next_coder *next,
|
||||
const lzma_allocator *allocator);
|
||||
|
||||
|
||||
/// Copy as much data as possible from in[] to out[] and update *in_pos
|
||||
/// and *out_pos accordingly. Returns the number of bytes copied.
|
||||
extern size_t lzma_bufcpy(const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size);
|
||||
|
||||
|
||||
/// \brief Return if expression doesn't evaluate to LZMA_OK
|
||||
///
|
||||
/// There are several situations where we want to return immediately
|
||||
/// with the value of expr if it isn't LZMA_OK. This macro shortens
|
||||
/// the code a little.
|
||||
#define return_if_error(expr) \
|
||||
do { \
|
||||
const lzma_ret ret_ = (expr); \
|
||||
if (ret_ != LZMA_OK) \
|
||||
return ret_; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/// If next isn't already initialized, free the previous coder. Then mark
|
||||
/// that next is _possibly_ initialized for the coder using this macro.
|
||||
/// "Possibly" means that if e.g. allocation of next->coder fails, the
|
||||
/// structure isn't actually initialized for this coder, but leaving
|
||||
/// next->init to func is still OK.
|
||||
#define lzma_next_coder_init(func, next, allocator) \
|
||||
do { \
|
||||
if ((uintptr_t)(func) != (next)->init) \
|
||||
lzma_next_end(next, allocator); \
|
||||
(next)->init = (uintptr_t)(func); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/// Initializes lzma_strm and calls func() to initialize strm->internal->next.
|
||||
/// (The function being called will use lzma_next_coder_init()). If
|
||||
/// initialization fails, memory that wasn't freed by func() is freed
|
||||
/// along strm->internal.
|
||||
#define lzma_next_strm_init(func, strm, ...) \
|
||||
do { \
|
||||
return_if_error(lzma_strm_init(strm)); \
|
||||
const lzma_ret ret_ = func(&(strm)->internal->next, \
|
||||
(strm)->allocator, __VA_ARGS__); \
|
||||
if (ret_ != LZMA_OK) { \
|
||||
lzma_end(strm); \
|
||||
return ret_; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,238 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file filter_decoder.c
|
||||
/// \brief Filter ID mapping to filter-specific functions
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "filter_encoder.h"
|
||||
#include "lzma_encoder.h"
|
||||
#ifdef HAVE_DECODER_LZMA2
|
||||
#include "lzma2_encoder.h"
|
||||
#endif
|
||||
#if defined(HAVE_DECODER_X86) || \
|
||||
defined(HAVE_DECODER_POWERPC) || \
|
||||
defined(HAVE_DECODER_IA64) || \
|
||||
defined(HAVE_DECODER_ARM) || \
|
||||
defined(HAVE_DECODER_ARMTHUMB) || \
|
||||
defined(HAVE_DECODER_SPARC)
|
||||
#include "simple_encoder.h"
|
||||
#endif
|
||||
#ifdef HAVE_DECODER_DELTA
|
||||
#include "delta_encoder.h"
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// Filter ID
|
||||
lzma_vli id;
|
||||
|
||||
/// Initializes the filter encoder and calls lzma_next_filter_init()
|
||||
/// for filters + 1.
|
||||
lzma_init_function init;
|
||||
|
||||
/// Calculates memory usage of the encoder. If the options are
|
||||
/// invalid, UINT64_MAX is returned.
|
||||
uint64_t (*memusage)(const void *options);
|
||||
|
||||
/// Calculates the recommended Uncompressed Size for .xz Blocks to
|
||||
/// which the input data can be split to make multithreaded
|
||||
/// encoding possible. If this is NULL, it is assumed that
|
||||
/// the encoder is fast enough with single thread.
|
||||
uint64_t (*block_size)(const void *options);
|
||||
|
||||
/// Tells the size of the Filter Properties field. If options are
|
||||
/// invalid, UINT32_MAX is returned. If this is NULL, props_size_fixed
|
||||
/// is used.
|
||||
lzma_ret (*props_size_get)(uint32_t *size, const void *options);
|
||||
uint32_t props_size_fixed;
|
||||
|
||||
/// Encodes Filter Properties.
|
||||
///
|
||||
/// \return - LZMA_OK: Properties encoded successfully.
|
||||
/// - LZMA_OPTIONS_ERROR: Unsupported options
|
||||
/// - LZMA_PROG_ERROR: Invalid options or not enough
|
||||
/// output space
|
||||
lzma_ret (*props_encode)(const void *options, uint8_t *out);
|
||||
|
||||
} lzma_filter_encoder;
|
||||
|
||||
|
||||
static const lzma_filter_encoder encoders[] = {
|
||||
#ifdef HAVE_ENCODER_LZMA1
|
||||
{
|
||||
.id = LZMA_FILTER_LZMA1,
|
||||
.init = &lzma_lzma_encoder_init,
|
||||
.memusage = &lzma_lzma_encoder_memusage,
|
||||
.block_size = NULL, // FIXME
|
||||
.props_size_get = NULL,
|
||||
.props_size_fixed = 5,
|
||||
.props_encode = &lzma_lzma_props_encode,
|
||||
},
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_LZMA2
|
||||
{
|
||||
.id = LZMA_FILTER_LZMA2,
|
||||
.init = &lzma_lzma2_encoder_init,
|
||||
.memusage = &lzma_lzma2_encoder_memusage,
|
||||
.block_size = &lzma_lzma2_block_size, // FIXME
|
||||
.props_size_get = NULL,
|
||||
.props_size_fixed = 1,
|
||||
.props_encode = &lzma_lzma2_props_encode,
|
||||
},
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_X86
|
||||
{
|
||||
.id = LZMA_FILTER_X86,
|
||||
.init = &lzma_simple_x86_encoder_init,
|
||||
.memusage = NULL,
|
||||
.block_size = NULL,
|
||||
.props_size_get = &lzma_simple_props_size,
|
||||
.props_encode = &lzma_simple_props_encode,
|
||||
},
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_POWERPC
|
||||
{
|
||||
.id = LZMA_FILTER_POWERPC,
|
||||
.init = &lzma_simple_powerpc_encoder_init,
|
||||
.memusage = NULL,
|
||||
.block_size = NULL,
|
||||
.props_size_get = &lzma_simple_props_size,
|
||||
.props_encode = &lzma_simple_props_encode,
|
||||
},
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_IA64
|
||||
{
|
||||
.id = LZMA_FILTER_IA64,
|
||||
.init = &lzma_simple_ia64_encoder_init,
|
||||
.memusage = NULL,
|
||||
.block_size = NULL,
|
||||
.props_size_get = &lzma_simple_props_size,
|
||||
.props_encode = &lzma_simple_props_encode,
|
||||
},
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_ARM
|
||||
{
|
||||
.id = LZMA_FILTER_ARM,
|
||||
.init = &lzma_simple_arm_encoder_init,
|
||||
.memusage = NULL,
|
||||
.block_size = NULL,
|
||||
.props_size_get = &lzma_simple_props_size,
|
||||
.props_encode = &lzma_simple_props_encode,
|
||||
},
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_ARMTHUMB
|
||||
{
|
||||
.id = LZMA_FILTER_ARMTHUMB,
|
||||
.init = &lzma_simple_armthumb_encoder_init,
|
||||
.memusage = NULL,
|
||||
.block_size = NULL,
|
||||
.props_size_get = &lzma_simple_props_size,
|
||||
.props_encode = &lzma_simple_props_encode,
|
||||
},
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_SPARC
|
||||
{
|
||||
.id = LZMA_FILTER_SPARC,
|
||||
.init = &lzma_simple_sparc_encoder_init,
|
||||
.memusage = NULL,
|
||||
.block_size = NULL,
|
||||
.props_size_get = &lzma_simple_props_size,
|
||||
.props_encode = &lzma_simple_props_encode,
|
||||
},
|
||||
#endif
|
||||
#ifdef HAVE_ENCODER_DELTA
|
||||
{
|
||||
.id = LZMA_FILTER_DELTA,
|
||||
.init = &lzma_delta_encoder_init,
|
||||
.memusage = &lzma_delta_coder_memusage,
|
||||
.block_size = NULL,
|
||||
.props_size_get = NULL,
|
||||
.props_size_fixed = 1,
|
||||
.props_encode = &lzma_delta_props_encode,
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
static const lzma_filter_encoder *
|
||||
encoder_find(lzma_vli id)
|
||||
{
|
||||
for (size_t i = 0; i < ARRAY_SIZE(encoders); ++i)
|
||||
if (encoders[i].id == id)
|
||||
return encoders + i;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(lzma_bool)
|
||||
lzma_filter_encoder_is_supported(lzma_vli id)
|
||||
{
|
||||
return encoder_find(id) != NULL;
|
||||
}
|
||||
|
||||
|
||||
extern uint64_t
|
||||
lzma_mt_block_size(const lzma_filter *filters)
|
||||
{
|
||||
uint64_t max = 0;
|
||||
|
||||
for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
|
||||
const lzma_filter_encoder *const fe
|
||||
= encoder_find(filters[i].id);
|
||||
if (fe->block_size != NULL) {
|
||||
const uint64_t size
|
||||
= fe->block_size(filters[i].options);
|
||||
if (size == 0)
|
||||
return 0;
|
||||
|
||||
if (size > max)
|
||||
max = size;
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_properties_size(uint32_t *size, const lzma_filter *filter)
|
||||
{
|
||||
const lzma_filter_encoder *const fe = encoder_find(filter->id);
|
||||
if (fe == NULL) {
|
||||
// Unknown filter - if the Filter ID is a proper VLI,
|
||||
// return LZMA_OPTIONS_ERROR instead of LZMA_PROG_ERROR,
|
||||
// because it's possible that we just don't have support
|
||||
// compiled in for the requested filter.
|
||||
return filter->id <= LZMA_VLI_MAX
|
||||
? LZMA_OPTIONS_ERROR : LZMA_PROG_ERROR;
|
||||
}
|
||||
|
||||
if (fe->props_size_get == NULL) {
|
||||
// No props_size_get() function, use props_size_fixed.
|
||||
*size = fe->props_size_fixed;
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
return fe->props_size_get(size, filter->options);
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(lzma_ret)
|
||||
lzma_properties_encode(const lzma_filter *filter, uint8_t *props)
|
||||
{
|
||||
const lzma_filter_encoder *const fe = encoder_find(filter->id);
|
||||
if (fe == NULL)
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
if (fe->props_encode == NULL)
|
||||
return LZMA_OK;
|
||||
|
||||
return fe->props_encode(filter->options, props);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file filter_encoder.c
|
||||
/// \brief Filter ID mapping to filter-specific functions
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_FILTER_ENCODER_H
|
||||
#define LZMA_FILTER_ENCODER_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
// FIXME: Might become a part of the public API.
|
||||
extern uint64_t lzma_mt_block_size(const lzma_filter *filters);
|
||||
|
||||
|
||||
extern lzma_ret lzma_raw_encoder_init(
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter *filters);
|
||||
|
||||
#endif
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file index.h
|
||||
/// \brief Handling of Index
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_INDEX_H
|
||||
#define LZMA_INDEX_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/// Minimum Unpadded Size
|
||||
#define UNPADDED_SIZE_MIN LZMA_VLI_C(5)
|
||||
|
||||
/// Maximum Unpadded Size
|
||||
#define UNPADDED_SIZE_MAX (LZMA_VLI_MAX & ~LZMA_VLI_C(3))
|
||||
|
||||
|
||||
/// Get the size of the Index Padding field. This is needed by Index encoder
|
||||
/// and decoder, but applications should have no use for this.
|
||||
extern uint32_t lzma_index_padding_size(const lzma_index *i);
|
||||
|
||||
|
||||
/// Set for how many Records to allocate memory the next time
|
||||
/// lzma_index_append() needs to allocate space for a new Record.
|
||||
/// This is used only by the Index decoder.
|
||||
extern void lzma_index_prealloc(lzma_index *i, lzma_vli records);
|
||||
|
||||
|
||||
/// Round the variable-length integer to the next multiple of four.
|
||||
static inline lzma_vli
|
||||
vli_ceil4(lzma_vli vli)
|
||||
{
|
||||
assert(vli <= LZMA_VLI_MAX);
|
||||
return (vli + 3) & ~LZMA_VLI_C(3);
|
||||
}
|
||||
|
||||
|
||||
/// Calculate the size of the Index field excluding Index Padding
|
||||
static inline lzma_vli
|
||||
index_size_unpadded(lzma_vli count, lzma_vli index_list_size)
|
||||
{
|
||||
// Index Indicator + Number of Records + List of Records + CRC32
|
||||
return 1 + lzma_vli_size(count) + index_list_size + 4;
|
||||
}
|
||||
|
||||
|
||||
/// Calculate the size of the Index field including Index Padding
|
||||
static inline lzma_vli
|
||||
index_size(lzma_vli count, lzma_vli index_list_size)
|
||||
{
|
||||
return vli_ceil4(index_size_unpadded(count, index_list_size));
|
||||
}
|
||||
|
||||
|
||||
/// Calculate the total size of the Stream
|
||||
static inline lzma_vli
|
||||
index_stream_size(lzma_vli blocks_size,
|
||||
lzma_vli count, lzma_vli index_list_size)
|
||||
{
|
||||
return LZMA_STREAM_HEADER_SIZE + blocks_size
|
||||
+ index_size(count, index_list_size)
|
||||
+ LZMA_STREAM_HEADER_SIZE;
|
||||
}
|
||||
|
||||
#endif
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file memcmplen.h
|
||||
/// \brief Optimized comparison of two buffers
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_MEMCMPLEN_H
|
||||
#define LZMA_MEMCMPLEN_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef HAVE_IMMINTRIN_H
|
||||
# include <immintrin.h>
|
||||
#endif
|
||||
|
||||
|
||||
/// Find out how many equal bytes the two buffers have.
|
||||
///
|
||||
/// \param buf1 First buffer
|
||||
/// \param buf2 Second buffer
|
||||
/// \param len How many bytes have already been compared and will
|
||||
/// be assumed to match
|
||||
/// \param limit How many bytes to compare at most, including the
|
||||
/// already-compared bytes. This must be significantly
|
||||
/// smaller than UINT32_MAX to avoid integer overflows.
|
||||
/// Up to LZMA_MEMCMPLEN_EXTRA bytes may be read past
|
||||
/// the specified limit from both buf1 and buf2.
|
||||
///
|
||||
/// \return Number of equal bytes in the buffers is returned.
|
||||
/// This is always at least len and at most limit.
|
||||
///
|
||||
/// \note LZMA_MEMCMPLEN_EXTRA defines how many extra bytes may be read.
|
||||
/// It's rounded up to 2^n. This extra amount needs to be
|
||||
/// allocated in the buffers being used. It needs to be
|
||||
/// initialized too to keep Valgrind quiet.
|
||||
static inline uint32_t lzma_attribute((__always_inline__))
|
||||
lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2,
|
||||
uint32_t len, uint32_t limit)
|
||||
{
|
||||
assert(len <= limit);
|
||||
assert(limit <= UINT32_MAX / 2);
|
||||
|
||||
#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \
|
||||
&& ((TUKLIB_GNUC_REQ(3, 4) && defined(__x86_64__)) \
|
||||
|| (defined(__INTEL_COMPILER) && defined(__x86_64__)) \
|
||||
|| (defined(__INTEL_COMPILER) && defined(_M_X64)) \
|
||||
|| (defined(_MSC_VER) && defined(_M_X64)))
|
||||
// NOTE: This will use 64-bit unaligned access which
|
||||
// TUKLIB_FAST_UNALIGNED_ACCESS wasn't meant to permit, but
|
||||
// it's convenient here at least as long as it's x86-64 only.
|
||||
//
|
||||
// I keep this x86-64 only for now since that's where I know this
|
||||
// to be a good method. This may be fine on other 64-bit CPUs too.
|
||||
// On big endian one should use xor instead of subtraction and switch
|
||||
// to __builtin_clzll().
|
||||
#define LZMA_MEMCMPLEN_EXTRA 8
|
||||
while (len < limit) {
|
||||
const uint64_t x = *(const uint64_t *)(buf1 + len)
|
||||
- *(const uint64_t *)(buf2 + len);
|
||||
if (x != 0) {
|
||||
# if defined(_M_X64) // MSVC or Intel C compiler on Windows
|
||||
unsigned long tmp;
|
||||
_BitScanForward64(&tmp, x);
|
||||
len += (uint32_t)tmp >> 3;
|
||||
# else // GCC, clang, or Intel C compiler
|
||||
len += (uint32_t)__builtin_ctzll(x) >> 3;
|
||||
# endif
|
||||
return my_min(len, limit);
|
||||
}
|
||||
|
||||
len += 8;
|
||||
}
|
||||
|
||||
return limit;
|
||||
|
||||
#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) \
|
||||
&& defined(HAVE__MM_MOVEMASK_EPI8) \
|
||||
&& ((defined(__GNUC__) && defined(__SSE2_MATH__)) \
|
||||
|| (defined(__INTEL_COMPILER) && defined(__SSE2__)) \
|
||||
|| (defined(_MSC_VER) && defined(_M_IX86_FP) \
|
||||
&& _M_IX86_FP >= 2))
|
||||
// NOTE: Like above, this will use 128-bit unaligned access which
|
||||
// TUKLIB_FAST_UNALIGNED_ACCESS wasn't meant to permit.
|
||||
//
|
||||
// SSE2 version for 32-bit and 64-bit x86. On x86-64 the above
|
||||
// version is sometimes significantly faster and sometimes
|
||||
// slightly slower than this SSE2 version, so this SSE2
|
||||
// version isn't used on x86-64.
|
||||
# define LZMA_MEMCMPLEN_EXTRA 16
|
||||
while (len < limit) {
|
||||
const uint32_t x = 0xFFFF ^ _mm_movemask_epi8(_mm_cmpeq_epi8(
|
||||
_mm_loadu_si128((const __m128i *)(buf1 + len)),
|
||||
_mm_loadu_si128((const __m128i *)(buf2 + len))));
|
||||
|
||||
if (x != 0) {
|
||||
# if defined(__INTEL_COMPILER)
|
||||
len += _bit_scan_forward(x);
|
||||
# elif defined(_MSC_VER)
|
||||
unsigned long tmp;
|
||||
_BitScanForward(&tmp, x);
|
||||
len += tmp;
|
||||
# else
|
||||
len += __builtin_ctz(x);
|
||||
# endif
|
||||
return my_min(len, limit);
|
||||
}
|
||||
|
||||
len += 16;
|
||||
}
|
||||
|
||||
return limit;
|
||||
|
||||
#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) && !defined(WORDS_BIGENDIAN)
|
||||
// Generic 32-bit little endian method
|
||||
# define LZMA_MEMCMPLEN_EXTRA 4
|
||||
while (len < limit) {
|
||||
uint32_t x = *(const uint32_t *)(buf1 + len)
|
||||
- *(const uint32_t *)(buf2 + len);
|
||||
if (x != 0) {
|
||||
if ((x & 0xFFFF) == 0) {
|
||||
len += 2;
|
||||
x >>= 16;
|
||||
}
|
||||
|
||||
if ((x & 0xFF) == 0)
|
||||
++len;
|
||||
|
||||
return my_min(len, limit);
|
||||
}
|
||||
|
||||
len += 4;
|
||||
}
|
||||
|
||||
return limit;
|
||||
|
||||
#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) && defined(WORDS_BIGENDIAN)
|
||||
// Generic 32-bit big endian method
|
||||
# define LZMA_MEMCMPLEN_EXTRA 4
|
||||
while (len < limit) {
|
||||
uint32_t x = *(const uint32_t *)(buf1 + len)
|
||||
^ *(const uint32_t *)(buf2 + len);
|
||||
if (x != 0) {
|
||||
if ((x & 0xFFFF0000) == 0) {
|
||||
len += 2;
|
||||
x <<= 16;
|
||||
}
|
||||
|
||||
if ((x & 0xFF000000) == 0)
|
||||
++len;
|
||||
|
||||
return my_min(len, limit);
|
||||
}
|
||||
|
||||
len += 4;
|
||||
}
|
||||
|
||||
return limit;
|
||||
|
||||
#else
|
||||
// Simple portable version that doesn't use unaligned access.
|
||||
# define LZMA_MEMCMPLEN_EXTRA 0
|
||||
while (len < limit && buf1[len] == buf2[len])
|
||||
++len;
|
||||
|
||||
return len;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file sysdefs.h
|
||||
/// \brief Common includes, definitions, system-specific things etc.
|
||||
///
|
||||
/// This file is used also by the lzma command line tool, that's why this
|
||||
/// file is separate from common.h.
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_SYSDEFS_H
|
||||
#define LZMA_SYSDEFS_H
|
||||
|
||||
//////////////
|
||||
// Includes //
|
||||
//////////////
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
// Get standard-compliant stdio functions under MinGW and MinGW-w64.
|
||||
#ifdef __MINGW32__
|
||||
# define __USE_MINGW_ANSI_STDIO 1
|
||||
#endif
|
||||
|
||||
// size_t and NULL
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
// C99 says that inttypes.h always includes stdint.h, but some systems
|
||||
// don't do that, and require including stdint.h separately.
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
||||
// Some pre-C99 systems have SIZE_MAX in limits.h instead of stdint.h. The
|
||||
// limits are also used to figure out some macros missing from pre-C99 systems.
|
||||
#ifdef HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
||||
// Be more compatible with systems that have non-conforming inttypes.h.
|
||||
// We assume that int is 32-bit and that long is either 32-bit or 64-bit.
|
||||
// Full Autoconf test could be more correct, but this should work well enough.
|
||||
// Note that this duplicates some code from lzma.h, but this is better since
|
||||
// we can work without inttypes.h thanks to Autoconf tests.
|
||||
#ifndef UINT32_C
|
||||
# if UINT_MAX != 4294967295U
|
||||
# error UINT32_C is not defined and unsigned int is not 32-bit.
|
||||
# endif
|
||||
# define UINT32_C(n) n ## U
|
||||
#endif
|
||||
#ifndef UINT32_MAX
|
||||
# define UINT32_MAX UINT32_C(4294967295)
|
||||
#endif
|
||||
#ifndef PRIu32
|
||||
# define PRIu32 "u"
|
||||
#endif
|
||||
#ifndef PRIx32
|
||||
# define PRIx32 "x"
|
||||
#endif
|
||||
#ifndef PRIX32
|
||||
# define PRIX32 "X"
|
||||
#endif
|
||||
|
||||
#if ULONG_MAX == 4294967295UL
|
||||
# ifndef UINT64_C
|
||||
# define UINT64_C(n) n ## ULL
|
||||
# endif
|
||||
# ifndef PRIu64
|
||||
# define PRIu64 "llu"
|
||||
# endif
|
||||
# ifndef PRIx64
|
||||
# define PRIx64 "llx"
|
||||
# endif
|
||||
# ifndef PRIX64
|
||||
# define PRIX64 "llX"
|
||||
# endif
|
||||
#else
|
||||
# ifndef UINT64_C
|
||||
# define UINT64_C(n) n ## UL
|
||||
# endif
|
||||
# ifndef PRIu64
|
||||
# define PRIu64 "lu"
|
||||
# endif
|
||||
# ifndef PRIx64
|
||||
# define PRIx64 "lx"
|
||||
# endif
|
||||
# ifndef PRIX64
|
||||
# define PRIX64 "lX"
|
||||
# endif
|
||||
#endif
|
||||
#ifndef UINT64_MAX
|
||||
# define UINT64_MAX UINT64_C(18446744073709551615)
|
||||
#endif
|
||||
|
||||
// Incorrect(?) SIZE_MAX:
|
||||
// - Interix headers typedef size_t to unsigned long,
|
||||
// but a few lines later define SIZE_MAX to INT32_MAX.
|
||||
// - SCO OpenServer (x86) headers typedef size_t to unsigned int
|
||||
// but define SIZE_MAX to INT32_MAX.
|
||||
#if defined(__INTERIX) || defined(_SCO_DS)
|
||||
# undef SIZE_MAX
|
||||
#endif
|
||||
|
||||
// The code currently assumes that size_t is either 32-bit or 64-bit.
|
||||
#ifndef SIZE_MAX
|
||||
# if SIZEOF_SIZE_T == 4
|
||||
# define SIZE_MAX UINT32_MAX
|
||||
# elif SIZEOF_SIZE_T == 8
|
||||
# define SIZE_MAX UINT64_MAX
|
||||
# else
|
||||
# error size_t is not 32-bit or 64-bit
|
||||
# endif
|
||||
#endif
|
||||
#if SIZE_MAX != UINT32_MAX && SIZE_MAX != UINT64_MAX
|
||||
# error size_t is not 32-bit or 64-bit
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
// Pre-C99 systems lack stdbool.h. All the code in LZMA Utils must be written
|
||||
// so that it works with fake bool type, for example:
|
||||
//
|
||||
// bool foo = (flags & 0x100) != 0;
|
||||
// bool bar = !!(flags & 0x100);
|
||||
//
|
||||
// This works with the real C99 bool but breaks with fake bool:
|
||||
//
|
||||
// bool baz = (flags & 0x100);
|
||||
//
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
# include <stdbool.h>
|
||||
#else
|
||||
# if ! HAVE__BOOL
|
||||
typedef unsigned char _Bool;
|
||||
# endif
|
||||
# define bool _Bool
|
||||
# define false 0
|
||||
# define true 1
|
||||
# define __bool_true_false_are_defined 1
|
||||
#endif
|
||||
|
||||
// string.h should be enough but let's include strings.h and memory.h too if
|
||||
// they exists, since that shouldn't do any harm, but may improve portability.
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MEMORY_H
|
||||
# include <memory.h>
|
||||
#endif
|
||||
|
||||
// As of MSVC 2013, inline and restrict are supported with
|
||||
// non-standard keywords.
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
# ifndef inline
|
||||
# define inline __inline
|
||||
# endif
|
||||
# ifndef restrict
|
||||
# define restrict __restrict
|
||||
# endif
|
||||
#elif __STDC_VERSION__ < 199901L
|
||||
# define restrict // nothing
|
||||
#endif
|
||||
|
||||
////////////
|
||||
// Macros //
|
||||
////////////
|
||||
|
||||
#undef memzero
|
||||
#define memzero(s, n) memset(s, 0, n)
|
||||
|
||||
// NOTE: Avoid using MIN() and MAX(), because even conditionally defining
|
||||
// those macros can cause some portability trouble, since on some systems
|
||||
// the system headers insist defining their own versions.
|
||||
#define my_min(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define my_max(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
|
||||
# define lzma_attr_alloc_size(x) __attribute__((__alloc_size__(x)))
|
||||
#else
|
||||
# define lzma_attr_alloc_size(x)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file tuklib_common.h
|
||||
/// \brief Common definitions for tuklib modules
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef TUKLIB_COMMON_H
|
||||
#define TUKLIB_COMMON_H
|
||||
|
||||
// The config file may be replaced by a package-specific file.
|
||||
// It should include at least stddef.h, inttypes.h, and limits.h.
|
||||
#include "tuklib_config.h"
|
||||
|
||||
// TUKLIB_SYMBOL_PREFIX is prefixed to all symbols exported by
|
||||
// the tuklib modules. If you use a tuklib module in a library,
|
||||
// you should use TUKLIB_SYMBOL_PREFIX to make sure that there
|
||||
// are no symbol conflicts in case someone links your library
|
||||
// into application that also uses the same tuklib module.
|
||||
#ifndef TUKLIB_SYMBOL_PREFIX
|
||||
# define TUKLIB_SYMBOL_PREFIX
|
||||
#endif
|
||||
|
||||
#define TUKLIB_CAT_X(a, b) a ## b
|
||||
#define TUKLIB_CAT(a, b) TUKLIB_CAT_X(a, b)
|
||||
|
||||
#ifndef TUKLIB_SYMBOL
|
||||
# define TUKLIB_SYMBOL(sym) TUKLIB_CAT(TUKLIB_SYMBOL_PREFIX, sym)
|
||||
#endif
|
||||
|
||||
#ifndef TUKLIB_DECLS_BEGIN
|
||||
# ifdef __cplusplus
|
||||
# define TUKLIB_DECLS_BEGIN extern "C" {
|
||||
# else
|
||||
# define TUKLIB_DECLS_BEGIN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef TUKLIB_DECLS_END
|
||||
# ifdef __cplusplus
|
||||
# define TUKLIB_DECLS_END }
|
||||
# else
|
||||
# define TUKLIB_DECLS_END
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && defined(__GNUC_MINOR__)
|
||||
# define TUKLIB_GNUC_REQ(major, minor) \
|
||||
((__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)) \
|
||||
|| __GNUC__ > (major))
|
||||
#else
|
||||
# define TUKLIB_GNUC_REQ(major, minor) 0
|
||||
#endif
|
||||
|
||||
#if TUKLIB_GNUC_REQ(2, 5)
|
||||
# define tuklib_attr_noreturn __attribute__((__noreturn__))
|
||||
#else
|
||||
# define tuklib_attr_noreturn
|
||||
#endif
|
||||
|
||||
#if (defined(_WIN32) && !defined(__CYGWIN__)) \
|
||||
|| defined(__OS2__) || defined(__MSDOS__)
|
||||
# define TUKLIB_DOSLIKE 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "sysdefs.h"
|
||||
#else
|
||||
# include <stddef.h>
|
||||
# include <inttypes.h>
|
||||
# include <limits.h>
|
||||
#endif
|
||||
@@ -0,0 +1,523 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file tuklib_integer.h
|
||||
/// \brief Various integer and bit operations
|
||||
///
|
||||
/// This file provides macros or functions to do some basic integer and bit
|
||||
/// operations.
|
||||
///
|
||||
/// Endianness related integer operations (XX = 16, 32, or 64; Y = b or l):
|
||||
/// - Byte swapping: bswapXX(num)
|
||||
/// - Byte order conversions to/from native: convXXYe(num)
|
||||
/// - Aligned reads: readXXYe(ptr)
|
||||
/// - Aligned writes: writeXXYe(ptr, num)
|
||||
/// - Unaligned reads (16/32-bit only): unaligned_readXXYe(ptr)
|
||||
/// - Unaligned writes (16/32-bit only): unaligned_writeXXYe(ptr, num)
|
||||
///
|
||||
/// Since they can macros, the arguments should have no side effects since
|
||||
/// they may be evaluated more than once.
|
||||
///
|
||||
/// \todo PowerPC and possibly some other architectures support
|
||||
/// byte swapping load and store instructions. This file
|
||||
/// doesn't take advantage of those instructions.
|
||||
///
|
||||
/// Bit scan operations for non-zero 32-bit integers:
|
||||
/// - Bit scan reverse (find highest non-zero bit): bsr32(num)
|
||||
/// - Count leading zeros: clz32(num)
|
||||
/// - Count trailing zeros: ctz32(num)
|
||||
/// - Bit scan forward (simply an alias for ctz32()): bsf32(num)
|
||||
///
|
||||
/// The above bit scan operations return 0-31. If num is zero,
|
||||
/// the result is undefined.
|
||||
//
|
||||
// Authors: Lasse Collin
|
||||
// Joachim Henke
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef TUKLIB_INTEGER_H
|
||||
#define TUKLIB_INTEGER_H
|
||||
|
||||
#include "tuklib_common.h"
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
// Operating system specific features //
|
||||
////////////////////////////////////////
|
||||
|
||||
#if defined(HAVE_BYTESWAP_H)
|
||||
// glibc, uClibc, dietlibc
|
||||
# include <byteswap.h>
|
||||
# ifdef HAVE_BSWAP_16
|
||||
# define bswap16(num) bswap_16(num)
|
||||
# endif
|
||||
# ifdef HAVE_BSWAP_32
|
||||
# define bswap32(num) bswap_32(num)
|
||||
# endif
|
||||
# ifdef HAVE_BSWAP_64
|
||||
# define bswap64(num) bswap_64(num)
|
||||
# endif
|
||||
|
||||
#elif defined(HAVE_SYS_ENDIAN_H)
|
||||
// *BSDs and Darwin
|
||||
# include <sys/endian.h>
|
||||
|
||||
#elif defined(HAVE_SYS_BYTEORDER_H)
|
||||
// Solaris
|
||||
# include <sys/byteorder.h>
|
||||
# ifdef BSWAP_16
|
||||
# define bswap16(num) BSWAP_16(num)
|
||||
# endif
|
||||
# ifdef BSWAP_32
|
||||
# define bswap32(num) BSWAP_32(num)
|
||||
# endif
|
||||
# ifdef BSWAP_64
|
||||
# define bswap64(num) BSWAP_64(num)
|
||||
# endif
|
||||
# ifdef BE_16
|
||||
# define conv16be(num) BE_16(num)
|
||||
# endif
|
||||
# ifdef BE_32
|
||||
# define conv32be(num) BE_32(num)
|
||||
# endif
|
||||
# ifdef BE_64
|
||||
# define conv64be(num) BE_64(num)
|
||||
# endif
|
||||
# ifdef LE_16
|
||||
# define conv16le(num) LE_16(num)
|
||||
# endif
|
||||
# ifdef LE_32
|
||||
# define conv32le(num) LE_32(num)
|
||||
# endif
|
||||
# ifdef LE_64
|
||||
# define conv64le(num) LE_64(num)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////
|
||||
// Byte swapping //
|
||||
///////////////////
|
||||
|
||||
#ifndef bswap16
|
||||
# define bswap16(num) \
|
||||
(((uint16_t)(num) << 8) | ((uint16_t)(num) >> 8))
|
||||
#endif
|
||||
|
||||
#ifndef bswap32
|
||||
# define bswap32(num) \
|
||||
( (((uint32_t)(num) << 24) ) \
|
||||
| (((uint32_t)(num) << 8) & UINT32_C(0x00FF0000)) \
|
||||
| (((uint32_t)(num) >> 8) & UINT32_C(0x0000FF00)) \
|
||||
| (((uint32_t)(num) >> 24) ) )
|
||||
#endif
|
||||
|
||||
#ifndef bswap64
|
||||
# define bswap64(num) \
|
||||
( (((uint64_t)(num) << 56) ) \
|
||||
| (((uint64_t)(num) << 40) & UINT64_C(0x00FF000000000000)) \
|
||||
| (((uint64_t)(num) << 24) & UINT64_C(0x0000FF0000000000)) \
|
||||
| (((uint64_t)(num) << 8) & UINT64_C(0x000000FF00000000)) \
|
||||
| (((uint64_t)(num) >> 8) & UINT64_C(0x00000000FF000000)) \
|
||||
| (((uint64_t)(num) >> 24) & UINT64_C(0x0000000000FF0000)) \
|
||||
| (((uint64_t)(num) >> 40) & UINT64_C(0x000000000000FF00)) \
|
||||
| (((uint64_t)(num) >> 56) ) )
|
||||
#endif
|
||||
|
||||
// Define conversion macros using the basic byte swapping macros.
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
# ifndef conv16be
|
||||
# define conv16be(num) ((uint16_t)(num))
|
||||
# endif
|
||||
# ifndef conv32be
|
||||
# define conv32be(num) ((uint32_t)(num))
|
||||
# endif
|
||||
# ifndef conv64be
|
||||
# define conv64be(num) ((uint64_t)(num))
|
||||
# endif
|
||||
# ifndef conv16le
|
||||
# define conv16le(num) bswap16(num)
|
||||
# endif
|
||||
# ifndef conv32le
|
||||
# define conv32le(num) bswap32(num)
|
||||
# endif
|
||||
# ifndef conv64le
|
||||
# define conv64le(num) bswap64(num)
|
||||
# endif
|
||||
#else
|
||||
# ifndef conv16be
|
||||
# define conv16be(num) bswap16(num)
|
||||
# endif
|
||||
# ifndef conv32be
|
||||
# define conv32be(num) bswap32(num)
|
||||
# endif
|
||||
# ifndef conv64be
|
||||
# define conv64be(num) bswap64(num)
|
||||
# endif
|
||||
# ifndef conv16le
|
||||
# define conv16le(num) ((uint16_t)(num))
|
||||
# endif
|
||||
# ifndef conv32le
|
||||
# define conv32le(num) ((uint32_t)(num))
|
||||
# endif
|
||||
# ifndef conv64le
|
||||
# define conv64le(num) ((uint64_t)(num))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
//////////////////////////////
|
||||
// Aligned reads and writes //
|
||||
//////////////////////////////
|
||||
|
||||
static inline uint16_t
|
||||
read16be(const uint8_t *buf)
|
||||
{
|
||||
uint16_t num = *(const uint16_t *)buf;
|
||||
return conv16be(num);
|
||||
}
|
||||
|
||||
|
||||
static inline uint16_t
|
||||
read16le(const uint8_t *buf)
|
||||
{
|
||||
uint16_t num = *(const uint16_t *)buf;
|
||||
return conv16le(num);
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
read32be(const uint8_t *buf)
|
||||
{
|
||||
uint32_t num = *(const uint32_t *)buf;
|
||||
return conv32be(num);
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
read32le(const uint8_t *buf)
|
||||
{
|
||||
uint32_t num = *(const uint32_t *)buf;
|
||||
return conv32le(num);
|
||||
}
|
||||
|
||||
|
||||
static inline uint64_t
|
||||
read64be(const uint8_t *buf)
|
||||
{
|
||||
uint64_t num = *(const uint64_t *)buf;
|
||||
return conv64be(num);
|
||||
}
|
||||
|
||||
|
||||
static inline uint64_t
|
||||
read64le(const uint8_t *buf)
|
||||
{
|
||||
uint64_t num = *(const uint64_t *)buf;
|
||||
return conv64le(num);
|
||||
}
|
||||
|
||||
|
||||
// NOTE: Possible byte swapping must be done in a macro to allow GCC
|
||||
// to optimize byte swapping of constants when using glibc's or *BSD's
|
||||
// byte swapping macros. The actual write is done in an inline function
|
||||
// to make type checking of the buf pointer possible similarly to readXXYe()
|
||||
// functions.
|
||||
|
||||
#define write16be(buf, num) write16ne((buf), conv16be(num))
|
||||
#define write16le(buf, num) write16ne((buf), conv16le(num))
|
||||
#define write32be(buf, num) write32ne((buf), conv32be(num))
|
||||
#define write32le(buf, num) write32ne((buf), conv32le(num))
|
||||
#define write64be(buf, num) write64ne((buf), conv64be(num))
|
||||
#define write64le(buf, num) write64ne((buf), conv64le(num))
|
||||
|
||||
|
||||
static inline void
|
||||
write16ne(uint8_t *buf, uint16_t num)
|
||||
{
|
||||
*(uint16_t *)buf = num;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
write32ne(uint8_t *buf, uint32_t num)
|
||||
{
|
||||
*(uint32_t *)buf = num;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
write64ne(uint8_t *buf, uint64_t num)
|
||||
{
|
||||
*(uint64_t *)buf = num;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// Unaligned reads and writes //
|
||||
////////////////////////////////
|
||||
|
||||
// NOTE: TUKLIB_FAST_UNALIGNED_ACCESS indicates only support for 16-bit and
|
||||
// 32-bit unaligned integer loads and stores. It's possible that 64-bit
|
||||
// unaligned access doesn't work or is slower than byte-by-byte access.
|
||||
// Since unaligned 64-bit is probably not needed as often as 16-bit or
|
||||
// 32-bit, we simply don't support 64-bit unaligned access for now.
|
||||
#ifdef TUKLIB_FAST_UNALIGNED_ACCESS
|
||||
# define unaligned_read16be read16be
|
||||
# define unaligned_read16le read16le
|
||||
# define unaligned_read32be read32be
|
||||
# define unaligned_read32le read32le
|
||||
# define unaligned_write16be write16be
|
||||
# define unaligned_write16le write16le
|
||||
# define unaligned_write32be write32be
|
||||
# define unaligned_write32le write32le
|
||||
|
||||
#else
|
||||
|
||||
static inline uint16_t
|
||||
unaligned_read16be(const uint8_t *buf)
|
||||
{
|
||||
uint16_t num = ((uint16_t)buf[0] << 8) | (uint16_t)buf[1];
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
static inline uint16_t
|
||||
unaligned_read16le(const uint8_t *buf)
|
||||
{
|
||||
uint16_t num = ((uint16_t)buf[0]) | ((uint16_t)buf[1] << 8);
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
unaligned_read32be(const uint8_t *buf)
|
||||
{
|
||||
uint32_t num = (uint32_t)buf[0] << 24;
|
||||
num |= (uint32_t)buf[1] << 16;
|
||||
num |= (uint32_t)buf[2] << 8;
|
||||
num |= (uint32_t)buf[3];
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
unaligned_read32le(const uint8_t *buf)
|
||||
{
|
||||
uint32_t num = (uint32_t)buf[0];
|
||||
num |= (uint32_t)buf[1] << 8;
|
||||
num |= (uint32_t)buf[2] << 16;
|
||||
num |= (uint32_t)buf[3] << 24;
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
unaligned_write16be(uint8_t *buf, uint16_t num)
|
||||
{
|
||||
buf[0] = (uint8_t)(num >> 8);
|
||||
buf[1] = (uint8_t)num;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
unaligned_write16le(uint8_t *buf, uint16_t num)
|
||||
{
|
||||
buf[0] = (uint8_t)num;
|
||||
buf[1] = (uint8_t)(num >> 8);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
unaligned_write32be(uint8_t *buf, uint32_t num)
|
||||
{
|
||||
buf[0] = (uint8_t)(num >> 24);
|
||||
buf[1] = (uint8_t)(num >> 16);
|
||||
buf[2] = (uint8_t)(num >> 8);
|
||||
buf[3] = (uint8_t)num;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
unaligned_write32le(uint8_t *buf, uint32_t num)
|
||||
{
|
||||
buf[0] = (uint8_t)num;
|
||||
buf[1] = (uint8_t)(num >> 8);
|
||||
buf[2] = (uint8_t)(num >> 16);
|
||||
buf[3] = (uint8_t)(num >> 24);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
bsr32(uint32_t n)
|
||||
{
|
||||
// Check for ICC first, since it tends to define __GNUC__ too.
|
||||
#if defined(__INTEL_COMPILER)
|
||||
return _bit_scan_reverse(n);
|
||||
|
||||
#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX == UINT32_MAX
|
||||
// GCC >= 3.4 has __builtin_clz(), which gives good results on
|
||||
// multiple architectures. On x86, __builtin_clz() ^ 31U becomes
|
||||
// either plain BSR (so the XOR gets optimized away) or LZCNT and
|
||||
// XOR (if -march indicates that SSE4a instructions are supported).
|
||||
return __builtin_clz(n) ^ 31U;
|
||||
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
uint32_t i;
|
||||
__asm__("bsrl %1, %0" : "=r" (i) : "rm" (n));
|
||||
return i;
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
// MSVC isn't supported by tuklib, but since this code exists,
|
||||
// it doesn't hurt to have it here anyway.
|
||||
uint32_t i;
|
||||
_BitScanReverse(&i, n);
|
||||
return i;
|
||||
|
||||
#else
|
||||
uint32_t i = 31;
|
||||
|
||||
if ((n & UINT32_C(0xFFFF0000)) == 0) {
|
||||
n <<= 16;
|
||||
i = 15;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0xFF000000)) == 0) {
|
||||
n <<= 8;
|
||||
i -= 8;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0xF0000000)) == 0) {
|
||||
n <<= 4;
|
||||
i -= 4;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0xC0000000)) == 0) {
|
||||
n <<= 2;
|
||||
i -= 2;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0x80000000)) == 0)
|
||||
--i;
|
||||
|
||||
return i;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
clz32(uint32_t n)
|
||||
{
|
||||
#if defined(__INTEL_COMPILER)
|
||||
return _bit_scan_reverse(n) ^ 31U;
|
||||
|
||||
#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX == UINT32_MAX
|
||||
return __builtin_clz(n);
|
||||
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
uint32_t i;
|
||||
__asm__("bsrl %1, %0\n\t"
|
||||
"xorl $31, %0"
|
||||
: "=r" (i) : "rm" (n));
|
||||
return i;
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
uint32_t i;
|
||||
_BitScanReverse(&i, n);
|
||||
return i ^ 31U;
|
||||
|
||||
#else
|
||||
uint32_t i = 0;
|
||||
|
||||
if ((n & UINT32_C(0xFFFF0000)) == 0) {
|
||||
n <<= 16;
|
||||
i = 16;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0xFF000000)) == 0) {
|
||||
n <<= 8;
|
||||
i += 8;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0xF0000000)) == 0) {
|
||||
n <<= 4;
|
||||
i += 4;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0xC0000000)) == 0) {
|
||||
n <<= 2;
|
||||
i += 2;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0x80000000)) == 0)
|
||||
++i;
|
||||
|
||||
return i;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
ctz32(uint32_t n)
|
||||
{
|
||||
#if defined(__INTEL_COMPILER)
|
||||
return _bit_scan_forward(n);
|
||||
|
||||
#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX >= UINT32_MAX
|
||||
return __builtin_ctz(n);
|
||||
|
||||
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||
uint32_t i;
|
||||
__asm__("bsfl %1, %0" : "=r" (i) : "rm" (n));
|
||||
return i;
|
||||
|
||||
#elif defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
uint32_t i;
|
||||
_BitScanForward(&i, n);
|
||||
return i;
|
||||
|
||||
#else
|
||||
uint32_t i = 0;
|
||||
|
||||
if ((n & UINT32_C(0x0000FFFF)) == 0) {
|
||||
n >>= 16;
|
||||
i = 16;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0x000000FF)) == 0) {
|
||||
n >>= 8;
|
||||
i += 8;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0x0000000F)) == 0) {
|
||||
n >>= 4;
|
||||
i += 4;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0x00000003)) == 0) {
|
||||
n >>= 2;
|
||||
i += 2;
|
||||
}
|
||||
|
||||
if ((n & UINT32_C(0x00000001)) == 0)
|
||||
++i;
|
||||
|
||||
return i;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define bsf32 ctz32
|
||||
|
||||
#endif
|
||||
+497
@@ -0,0 +1,497 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
/* How many MiB of RAM to assume if the real amount cannot be determined. */
|
||||
#define ASSUME_RAM 128
|
||||
|
||||
/* Define to 1 if translation of program messages to the user's native
|
||||
language is requested. */
|
||||
/* #undef ENABLE_NLS */
|
||||
|
||||
/* Define to 1 if bswap_16 is available. */
|
||||
/* #undef HAVE_BSWAP_16 */
|
||||
|
||||
/* Define to 1 if bswap_32 is available. */
|
||||
/* #undef HAVE_BSWAP_32 */
|
||||
|
||||
/* Define to 1 if bswap_64 is available. */
|
||||
/* #undef HAVE_BSWAP_64 */
|
||||
|
||||
/* Define to 1 if you have the <byteswap.h> header file. */
|
||||
/* #undef HAVE_BYTESWAP_H */
|
||||
|
||||
/* Define to 1 if the system has the type `CC_SHA256_CTX'. */
|
||||
/* #undef HAVE_CC_SHA256_CTX */
|
||||
|
||||
/* Define to 1 if you have the `CC_SHA256_Init' function. */
|
||||
/* #undef HAVE_CC_SHA256_INIT */
|
||||
|
||||
/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the
|
||||
CoreFoundation framework. */
|
||||
/* #undef HAVE_CFLOCALECOPYCURRENT */
|
||||
|
||||
/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in
|
||||
the CoreFoundation framework. */
|
||||
/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */
|
||||
|
||||
/* Define to 1 if crc32 integrity check is enabled. */
|
||||
/* #undef HAVE_CHECK_CRC32 */
|
||||
|
||||
/* Define to 1 if crc64 integrity check is enabled. */
|
||||
/* #undef HAVE_CHECK_CRC64 */
|
||||
|
||||
/* Define to 1 if sha256 integrity check is enabled. */
|
||||
/* #undef HAVE_CHECK_SHA256 */
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#define HAVE_CLOCK_GETTIME 1
|
||||
|
||||
/* Define to 1 if you have the <CommonCrypto/CommonDigest.h> header file. */
|
||||
/* #undef HAVE_COMMONCRYPTO_COMMONDIGEST_H */
|
||||
|
||||
/* Define if the GNU dcgettext() function is already present or preinstalled.
|
||||
*/
|
||||
/* #undef HAVE_DCGETTEXT */
|
||||
|
||||
/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_CLOCK_MONOTONIC 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `program_invocation_name', and
|
||||
to 0 if you don't. */
|
||||
#define HAVE_DECL_PROGRAM_INVOCATION_NAME 0
|
||||
|
||||
/* Define to 1 if arm decoder is enabled. */
|
||||
/* #undef HAVE_DECODER_ARM */
|
||||
|
||||
/* Define to 1 if armthumb decoder is enabled. */
|
||||
/* #undef HAVE_DECODER_ARMTHUMB */
|
||||
|
||||
/* Define to 1 if delta decoder is enabled. */
|
||||
/* #undef HAVE_DECODER_DELTA */
|
||||
|
||||
/* Define to 1 if ia64 decoder is enabled. */
|
||||
/* #undef HAVE_DECODER_IA64 */
|
||||
|
||||
/* Define to 1 if lzma1 decoder is enabled. */
|
||||
#define HAVE_DECODER_LZMA1 1
|
||||
|
||||
/* Define to 1 if lzma2 decoder is enabled. */
|
||||
/* #undef HAVE_DECODER_LZMA2 */
|
||||
|
||||
/* Define to 1 if powerpc decoder is enabled. */
|
||||
/* #undef HAVE_DECODER_POWERPC */
|
||||
|
||||
/* Define to 1 if sparc decoder is enabled. */
|
||||
/* #undef HAVE_DECODER_SPARC */
|
||||
|
||||
/* Define to 1 if x86 decoder is enabled. */
|
||||
/* #undef HAVE_DECODER_X86 */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
/* #undef HAVE_DLFCN_H */
|
||||
|
||||
/* Define to 1 if arm encoder is enabled. */
|
||||
/* #undef HAVE_ENCODER_ARM */
|
||||
|
||||
/* Define to 1 if armthumb encoder is enabled. */
|
||||
/* #undef HAVE_ENCODER_ARMTHUMB */
|
||||
|
||||
/* Define to 1 if delta encoder is enabled. */
|
||||
/* #undef HAVE_ENCODER_DELTA */
|
||||
|
||||
/* Define to 1 if ia64 encoder is enabled. */
|
||||
/* #undef HAVE_ENCODER_IA64 */
|
||||
|
||||
/* Define to 1 if lzma1 encoder is enabled. */
|
||||
#define HAVE_ENCODER_LZMA1 1
|
||||
|
||||
/* Define to 1 if lzma2 encoder is enabled. */
|
||||
/* #undef HAVE_ENCODER_LZMA2 */
|
||||
|
||||
/* Define to 1 if powerpc encoder is enabled. */
|
||||
/* #undef HAVE_ENCODER_POWERPC */
|
||||
|
||||
/* Define to 1 if sparc encoder is enabled. */
|
||||
/* #undef HAVE_ENCODER_SPARC */
|
||||
|
||||
/* Define to 1 if x86 encoder is enabled. */
|
||||
/* #undef HAVE_ENCODER_X86 */
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the `futimens' function. */
|
||||
/* #undef HAVE_FUTIMENS */
|
||||
|
||||
/* Define to 1 if you have the `futimes' function. */
|
||||
/* #undef HAVE_FUTIMES */
|
||||
|
||||
/* Define to 1 if you have the `futimesat' function. */
|
||||
/* #undef HAVE_FUTIMESAT */
|
||||
|
||||
/* Define to 1 if you have the <getopt.h> header file. */
|
||||
#define HAVE_GETOPT_H 1
|
||||
|
||||
/* Define to 1 if you have the `getopt_long' function. */
|
||||
#define HAVE_GETOPT_LONG 1
|
||||
|
||||
/* Define if the GNU gettext() function is already present or preinstalled. */
|
||||
/* #undef HAVE_GETTEXT */
|
||||
|
||||
/* Define if you have the iconv() function and it works. */
|
||||
/* #undef HAVE_ICONV */
|
||||
|
||||
/* Define to 1 if you have the <immintrin.h> header file. */
|
||||
#define HAVE_IMMINTRIN_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if mbrtowc and mbstate_t are properly declared. */
|
||||
#define HAVE_MBRTOWC 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 to enable bt2 match finder. */
|
||||
#define HAVE_MF_BT2 1
|
||||
|
||||
/* Define to 1 to enable bt3 match finder. */
|
||||
#define HAVE_MF_BT3 1
|
||||
|
||||
/* Define to 1 to enable bt4 match finder. */
|
||||
#define HAVE_MF_BT4 1
|
||||
|
||||
/* Define to 1 to enable hc3 match finder. */
|
||||
#define HAVE_MF_HC3 1
|
||||
|
||||
/* Define to 1 to enable hc4 match finder. */
|
||||
#define HAVE_MF_HC4 1
|
||||
|
||||
/* Define to 1 if you have the <minix/sha2.h> header file. */
|
||||
/* #undef HAVE_MINIX_SHA2_H */
|
||||
|
||||
/* Define to 1 if getopt.h declares extern int optreset. */
|
||||
/* #undef HAVE_OPTRESET */
|
||||
|
||||
/* Define to 1 if you have the `pipe2' function. */
|
||||
/* #undef HAVE_PIPE2 */
|
||||
|
||||
/* Define to 1 if you have the `posix_fadvise' function. */
|
||||
/* #undef HAVE_POSIX_FADVISE */
|
||||
|
||||
/* Define to 1 if you have the `pthread_condattr_setclock' function. */
|
||||
/* #undef HAVE_PTHREAD_CONDATTR_SETCLOCK */
|
||||
|
||||
/* Have PTHREAD_PRIO_INHERIT. */
|
||||
/* #undef HAVE_PTHREAD_PRIO_INHERIT */
|
||||
|
||||
/* Define to 1 if you have the `SHA256Init' function. */
|
||||
/* #undef HAVE_SHA256INIT */
|
||||
|
||||
/* Define to 1 if the system has the type `SHA256_CTX'. */
|
||||
/* #undef HAVE_SHA256_CTX */
|
||||
|
||||
/* Define to 1 if you have the <sha256.h> header file. */
|
||||
/* #undef HAVE_SHA256_H */
|
||||
|
||||
/* Define to 1 if you have the `SHA256_Init' function. */
|
||||
/* #undef HAVE_SHA256_INIT */
|
||||
|
||||
/* Define to 1 if the system has the type `SHA2_CTX'. */
|
||||
/* #undef HAVE_SHA2_CTX */
|
||||
|
||||
/* Define to 1 if you have the <sha2.h> header file. */
|
||||
/* #undef HAVE_SHA2_H */
|
||||
|
||||
/* Define to 1 if optimizing for size. */
|
||||
/* #undef HAVE_SMALL */
|
||||
|
||||
/* Define to 1 if stdbool.h conforms to C99. */
|
||||
#define HAVE_STDBOOL_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
/* #undef HAVE_STRINGS_H */
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if `st_atimensec' is a member of `struct stat'. */
|
||||
/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */
|
||||
|
||||
/* Define to 1 if `st_atimespec.tv_nsec' is a member of `struct stat'. */
|
||||
/* #undef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC */
|
||||
|
||||
/* Define to 1 if `st_atim.st__tim.tv_nsec' is a member of `struct stat'. */
|
||||
/* #undef HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC */
|
||||
|
||||
/* Define to 1 if `st_atim.tv_nsec' is a member of `struct stat'. */
|
||||
/* #undef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC */
|
||||
|
||||
/* Define to 1 if `st_uatime' is a member of `struct stat'. */
|
||||
/* #undef HAVE_STRUCT_STAT_ST_UATIME */
|
||||
|
||||
/* Define to 1 if you have the <sys/byteorder.h> header file. */
|
||||
/* #undef HAVE_SYS_BYTEORDER_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/endian.h> header file. */
|
||||
/* #undef HAVE_SYS_ENDIAN_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `uintptr_t'. */
|
||||
#define HAVE_UINTPTR_T 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `utime' function. */
|
||||
#define HAVE_UTIME 1
|
||||
|
||||
/* Define to 1 if you have the `utimes' function. */
|
||||
/* #undef HAVE_UTIMES */
|
||||
|
||||
/* Define to 1 or 0, depending whether the compiler supports simple visibility
|
||||
declarations. */
|
||||
#define HAVE_VISIBILITY 1
|
||||
|
||||
/* Define to 1 if you have the `wcwidth' function. */
|
||||
/* #undef HAVE_WCWIDTH */
|
||||
|
||||
/* Define to 1 if the system has the type `_Bool'. */
|
||||
#define HAVE__BOOL 1
|
||||
|
||||
/* Define to 1 if _mm_movemask_epi8 is available. */
|
||||
#define HAVE__MM_MOVEMASK_EPI8 1
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Define to 1 when using POSIX threads (pthreads). */
|
||||
/* #undef MYTHREAD_POSIX */
|
||||
|
||||
#ifdef _WIN64
|
||||
/* Define to 1 when using Windows Vista compatible threads. This uses features
|
||||
that are not available on Windows XP. */
|
||||
# define MYTHREAD_VISTA 1
|
||||
#else
|
||||
/* Define to 1 when using Windows 95 (and thus XP) compatible threads. This
|
||||
avoids use of features that were added in Windows Vista.
|
||||
This is used for 32-bit x86 builds for compatibility reasons since it
|
||||
makes no measurable difference in performance compared to Vista threads. */
|
||||
# define MYTHREAD_WIN95 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 to disable debugging code. */
|
||||
#define NDEBUG 1
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "xz"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "lasse.collin@tukaani.org"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "XZ Utils"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "XZ Utils 5.2.3"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "xz"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL "http://tukaani.org/xz/"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "5.2.3"
|
||||
|
||||
/* Define to necessary symbol if this constant uses a non-standard name on
|
||||
your system. */
|
||||
/* #undef PTHREAD_CREATE_JOINABLE */
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#ifdef _WIN64
|
||||
# define SIZEOF_SIZE_T 8
|
||||
#else
|
||||
# define SIZEOF_SIZE_T 4
|
||||
#endif
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if the number of available CPU cores can be detected with
|
||||
cpuset(2). */
|
||||
/* #undef TUKLIB_CPUCORES_CPUSET */
|
||||
|
||||
/* Define to 1 if the number of available CPU cores can be detected with
|
||||
pstat_getdynamic(). */
|
||||
/* #undef TUKLIB_CPUCORES_PSTAT_GETDYNAMIC */
|
||||
|
||||
/* Define to 1 if the number of available CPU cores can be detected with
|
||||
sysconf(_SC_NPROCESSORS_ONLN) or sysconf(_SC_NPROC_ONLN). */
|
||||
/* #undef TUKLIB_CPUCORES_SYSCONF */
|
||||
|
||||
/* Define to 1 if the number of available CPU cores can be detected with
|
||||
sysctl(). */
|
||||
/* #undef TUKLIB_CPUCORES_SYSCTL */
|
||||
|
||||
/* Define to 1 if the system supports fast unaligned access to 16-bit and
|
||||
32-bit integers. */
|
||||
#define TUKLIB_FAST_UNALIGNED_ACCESS 1
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with
|
||||
_system_configuration.physmem. */
|
||||
/* #undef TUKLIB_PHYSMEM_AIX */
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with
|
||||
getinvent_r(). */
|
||||
/* #undef TUKLIB_PHYSMEM_GETINVENT_R */
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with
|
||||
getsysinfo(). */
|
||||
/* #undef TUKLIB_PHYSMEM_GETSYSINFO */
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with
|
||||
pstat_getstatic(). */
|
||||
/* #undef TUKLIB_PHYSMEM_PSTAT_GETSTATIC */
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with
|
||||
sysconf(_SC_PAGESIZE) and sysconf(_SC_PHYS_PAGES). */
|
||||
/* #undef TUKLIB_PHYSMEM_SYSCONF */
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with sysctl().
|
||||
*/
|
||||
/* #undef TUKLIB_PHYSMEM_SYSCTL */
|
||||
|
||||
/* Define to 1 if the amount of physical memory can be detected with Linux
|
||||
sysinfo(). */
|
||||
/* #undef TUKLIB_PHYSMEM_SYSINFO */
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# define _ALL_SOURCE 1
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# define _TANDEM_SOURCE 1
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# define __EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "5.2.3"
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
/* # undef WORDS_BIGENDIAN */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
/* #undef _POSIX_1_SOURCE */
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
/* #undef _POSIX_SOURCE */
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
/* #undef _UINT32_T */
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
/* #undef _UINT64_T */
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
/* #undef _UINT8_T */
|
||||
|
||||
/* Define to rpl_ if the getopt replacement functions and variables should be
|
||||
used. */
|
||||
/* #undef __GETOPT_PREFIX */
|
||||
|
||||
/* Define to the type of a signed integer type of width exactly 32 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef int32_t */
|
||||
|
||||
/* Define to the type of a signed integer type of width exactly 64 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef int64_t */
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 16 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef uint16_t */
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 32 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef uint32_t */
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 64 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef uint64_t */
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 8 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef uint8_t */
|
||||
|
||||
/* Define to the type of an unsigned integer type wide enough to hold a
|
||||
pointer, if such a type exists, and if the system does not define it. */
|
||||
/* #undef uintptr_t */
|
||||
+306
@@ -0,0 +1,306 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lz_decoder.c
|
||||
/// \brief LZ out window
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// liblzma supports multiple LZ77-based filters. The LZ part is shared
|
||||
// between these filters. The LZ code takes care of dictionary handling
|
||||
// and passing the data between filters in the chain. The filter-specific
|
||||
// part decodes from the input buffer to the dictionary.
|
||||
|
||||
|
||||
#include "lz_decoder.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// Dictionary (history buffer)
|
||||
lzma_dict dict;
|
||||
|
||||
/// The actual LZ-based decoder e.g. LZMA
|
||||
lzma_lz_decoder lz;
|
||||
|
||||
/// Next filter in the chain, if any. Note that LZMA and LZMA2 are
|
||||
/// only allowed as the last filter, but the long-range filter in
|
||||
/// future can be in the middle of the chain.
|
||||
lzma_next_coder next;
|
||||
|
||||
/// True if the next filter in the chain has returned LZMA_STREAM_END.
|
||||
bool next_finished;
|
||||
|
||||
/// True if the LZ decoder (e.g. LZMA) has detected end of payload
|
||||
/// marker. This may become true before next_finished becomes true.
|
||||
bool this_finished;
|
||||
|
||||
/// Temporary buffer needed when the LZ-based filter is not the last
|
||||
/// filter in the chain. The output of the next filter is first
|
||||
/// decoded into buffer[], which is then used as input for the actual
|
||||
/// LZ-based decoder.
|
||||
struct {
|
||||
size_t pos;
|
||||
size_t size;
|
||||
uint8_t buffer[LZMA_BUFFER_SIZE];
|
||||
} temp;
|
||||
} lzma_coder;
|
||||
|
||||
|
||||
static void
|
||||
lz_decoder_reset(lzma_coder *coder)
|
||||
{
|
||||
coder->dict.pos = 0;
|
||||
coder->dict.full = 0;
|
||||
coder->dict.buf[coder->dict.size - 1] = '\0';
|
||||
coder->dict.need_reset = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
decode_buffer(lzma_coder *coder,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size)
|
||||
{
|
||||
while (true) {
|
||||
// Wrap the dictionary if needed.
|
||||
if (coder->dict.pos == coder->dict.size)
|
||||
coder->dict.pos = 0;
|
||||
|
||||
// Store the current dictionary position. It is needed to know
|
||||
// where to start copying to the out[] buffer.
|
||||
const size_t dict_start = coder->dict.pos;
|
||||
|
||||
// Calculate how much we allow coder->lz.code() to decode.
|
||||
// It must not decode past the end of the dictionary
|
||||
// buffer, and we don't want it to decode more than is
|
||||
// actually needed to fill the out[] buffer.
|
||||
coder->dict.limit = coder->dict.pos
|
||||
+ my_min(out_size - *out_pos,
|
||||
coder->dict.size - coder->dict.pos);
|
||||
|
||||
// Call the coder->lz.code() to do the actual decoding.
|
||||
const lzma_ret ret = coder->lz.code(
|
||||
coder->lz.coder, &coder->dict,
|
||||
in, in_pos, in_size);
|
||||
|
||||
// Copy the decoded data from the dictionary to the out[]
|
||||
// buffer.
|
||||
const size_t copy_size = coder->dict.pos - dict_start;
|
||||
assert(copy_size <= out_size - *out_pos);
|
||||
memcpy(out + *out_pos, coder->dict.buf + dict_start,
|
||||
copy_size);
|
||||
*out_pos += copy_size;
|
||||
|
||||
// Reset the dictionary if so requested by coder->lz.code().
|
||||
if (coder->dict.need_reset) {
|
||||
lz_decoder_reset(coder);
|
||||
|
||||
// Since we reset dictionary, we don't check if
|
||||
// dictionary became full.
|
||||
if (ret != LZMA_OK || *out_pos == out_size)
|
||||
return ret;
|
||||
} else {
|
||||
// Return if everything got decoded or an error
|
||||
// occurred, or if there's no more data to decode.
|
||||
//
|
||||
// Note that detecting if there's something to decode
|
||||
// is done by looking if dictionary become full
|
||||
// instead of looking if *in_pos == in_size. This
|
||||
// is because it is possible that all the input was
|
||||
// consumed already but some data is pending to be
|
||||
// written to the dictionary.
|
||||
if (ret != LZMA_OK || *out_pos == out_size
|
||||
|| coder->dict.pos < coder->dict.size)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
lz_decode(void *coder_ptr,
|
||||
const lzma_allocator *allocator lzma_attribute((__unused__)),
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size,
|
||||
lzma_action action)
|
||||
{
|
||||
lzma_coder *coder = coder_ptr;
|
||||
|
||||
if (coder->next.code == NULL)
|
||||
return decode_buffer(coder, in, in_pos, in_size,
|
||||
out, out_pos, out_size);
|
||||
|
||||
// We aren't the last coder in the chain, we need to decode
|
||||
// our input to a temporary buffer.
|
||||
while (*out_pos < out_size) {
|
||||
// Fill the temporary buffer if it is empty.
|
||||
if (!coder->next_finished
|
||||
&& coder->temp.pos == coder->temp.size) {
|
||||
coder->temp.pos = 0;
|
||||
coder->temp.size = 0;
|
||||
|
||||
const lzma_ret ret = coder->next.code(
|
||||
coder->next.coder,
|
||||
allocator, in, in_pos, in_size,
|
||||
coder->temp.buffer, &coder->temp.size,
|
||||
LZMA_BUFFER_SIZE, action);
|
||||
|
||||
if (ret == LZMA_STREAM_END)
|
||||
coder->next_finished = true;
|
||||
else if (ret != LZMA_OK || coder->temp.size == 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (coder->this_finished) {
|
||||
if (coder->temp.size != 0)
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
if (coder->next_finished)
|
||||
return LZMA_STREAM_END;
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
const lzma_ret ret = decode_buffer(coder, coder->temp.buffer,
|
||||
&coder->temp.pos, coder->temp.size,
|
||||
out, out_pos, out_size);
|
||||
|
||||
if (ret == LZMA_STREAM_END)
|
||||
coder->this_finished = true;
|
||||
else if (ret != LZMA_OK)
|
||||
return ret;
|
||||
else if (coder->next_finished && *out_pos < out_size)
|
||||
return LZMA_DATA_ERROR;
|
||||
}
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lz_decoder_end(void *coder_ptr, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_coder *coder = coder_ptr;
|
||||
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
lzma_free(coder->dict.buf, allocator);
|
||||
|
||||
if (coder->lz.end != NULL)
|
||||
coder->lz.end(coder->lz.coder, allocator);
|
||||
else
|
||||
lzma_free(coder->lz.coder, allocator);
|
||||
|
||||
lzma_free(coder, allocator);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters,
|
||||
lzma_ret (*lz_init)(lzma_lz_decoder *lz,
|
||||
const lzma_allocator *allocator, const void *options,
|
||||
lzma_lz_options *lz_options))
|
||||
{
|
||||
// Allocate the base structure if it isn't already allocated.
|
||||
lzma_coder *coder = next->coder;
|
||||
if (coder == NULL) {
|
||||
coder = lzma_alloc(sizeof(lzma_coder), allocator);
|
||||
if (coder == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
next->coder = coder;
|
||||
next->code = &lz_decode;
|
||||
next->end = &lz_decoder_end;
|
||||
|
||||
coder->dict.buf = NULL;
|
||||
coder->dict.size = 0;
|
||||
coder->lz = LZMA_LZ_DECODER_INIT;
|
||||
coder->next = LZMA_NEXT_CODER_INIT;
|
||||
}
|
||||
|
||||
// Allocate and initialize the LZ-based decoder. It will also give
|
||||
// us the dictionary size.
|
||||
lzma_lz_options lz_options;
|
||||
return_if_error(lz_init(&coder->lz, allocator,
|
||||
filters[0].options, &lz_options));
|
||||
|
||||
// If the dictionary size is very small, increase it to 4096 bytes.
|
||||
// This is to prevent constant wrapping of the dictionary, which
|
||||
// would slow things down. The downside is that since we don't check
|
||||
// separately for the real dictionary size, we may happily accept
|
||||
// corrupt files.
|
||||
if (lz_options.dict_size < 4096)
|
||||
lz_options.dict_size = 4096;
|
||||
|
||||
// Make dictionary size a multipe of 16. Some LZ-based decoders like
|
||||
// LZMA use the lowest bits lzma_dict.pos to know the alignment of the
|
||||
// data. Aligned buffer is also good when memcpying from the
|
||||
// dictionary to the output buffer, since applications are
|
||||
// recommended to give aligned buffers to liblzma.
|
||||
//
|
||||
// Avoid integer overflow.
|
||||
if (lz_options.dict_size > SIZE_MAX - 15)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
lz_options.dict_size = (lz_options.dict_size + 15) & ~((size_t)(15));
|
||||
|
||||
// Allocate and initialize the dictionary.
|
||||
if (coder->dict.size != lz_options.dict_size) {
|
||||
lzma_free(coder->dict.buf, allocator);
|
||||
coder->dict.buf
|
||||
= lzma_alloc(lz_options.dict_size, allocator);
|
||||
if (coder->dict.buf == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
coder->dict.size = lz_options.dict_size;
|
||||
}
|
||||
|
||||
lz_decoder_reset(next->coder);
|
||||
|
||||
// Use the preset dictionary if it was given to us.
|
||||
if (lz_options.preset_dict != NULL
|
||||
&& lz_options.preset_dict_size > 0) {
|
||||
// If the preset dictionary is bigger than the actual
|
||||
// dictionary, copy only the tail.
|
||||
const size_t copy_size = my_min(lz_options.preset_dict_size,
|
||||
lz_options.dict_size);
|
||||
const size_t offset = lz_options.preset_dict_size - copy_size;
|
||||
memcpy(coder->dict.buf, lz_options.preset_dict + offset,
|
||||
copy_size);
|
||||
coder->dict.pos = copy_size;
|
||||
coder->dict.full = copy_size;
|
||||
}
|
||||
|
||||
// Miscellaneous initializations
|
||||
coder->next_finished = false;
|
||||
coder->this_finished = false;
|
||||
coder->temp.pos = 0;
|
||||
coder->temp.size = 0;
|
||||
|
||||
// Initialize the next filter in the chain, if any.
|
||||
return lzma_next_filter_init(&coder->next, allocator, filters + 1);
|
||||
}
|
||||
|
||||
|
||||
extern uint64_t
|
||||
lzma_lz_decoder_memusage(size_t dictionary_size)
|
||||
{
|
||||
return sizeof(lzma_coder) + (uint64_t)(dictionary_size);
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lzma_lz_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size)
|
||||
{
|
||||
lzma_coder *coder = coder_ptr;
|
||||
coder->lz.set_uncompressed(coder->lz.coder, uncompressed_size);
|
||||
}
|
||||
+234
@@ -0,0 +1,234 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lz_decoder.h
|
||||
/// \brief LZ out window
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_LZ_DECODER_H
|
||||
#define LZMA_LZ_DECODER_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// Pointer to the dictionary buffer. It can be an allocated buffer
|
||||
/// internal to liblzma, or it can a be a buffer given by the
|
||||
/// application when in single-call mode (not implemented yet).
|
||||
uint8_t *buf;
|
||||
|
||||
/// Write position in dictionary. The next byte will be written to
|
||||
/// buf[pos].
|
||||
size_t pos;
|
||||
|
||||
/// Indicates how full the dictionary is. This is used by
|
||||
/// dict_is_distance_valid() to detect corrupt files that would
|
||||
/// read beyond the beginning of the dictionary.
|
||||
size_t full;
|
||||
|
||||
/// Write limit
|
||||
size_t limit;
|
||||
|
||||
/// Size of the dictionary
|
||||
size_t size;
|
||||
|
||||
/// True when dictionary should be reset before decoding more data.
|
||||
bool need_reset;
|
||||
|
||||
} lzma_dict;
|
||||
|
||||
|
||||
typedef struct {
|
||||
size_t dict_size;
|
||||
const uint8_t *preset_dict;
|
||||
size_t preset_dict_size;
|
||||
} lzma_lz_options;
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// Data specific to the LZ-based decoder
|
||||
void *coder;
|
||||
|
||||
/// Function to decode from in[] to *dict
|
||||
lzma_ret (*code)(void *coder,
|
||||
lzma_dict *restrict dict, const uint8_t *restrict in,
|
||||
size_t *restrict in_pos, size_t in_size);
|
||||
|
||||
void (*reset)(void *coder, const void *options);
|
||||
|
||||
/// Set the uncompressed size
|
||||
void (*set_uncompressed)(void *coder, lzma_vli uncompressed_size);
|
||||
|
||||
/// Free allocated resources
|
||||
void (*end)(void *coder, const lzma_allocator *allocator);
|
||||
|
||||
} lzma_lz_decoder;
|
||||
|
||||
|
||||
#define LZMA_LZ_DECODER_INIT \
|
||||
(lzma_lz_decoder){ \
|
||||
.coder = NULL, \
|
||||
.code = NULL, \
|
||||
.reset = NULL, \
|
||||
.set_uncompressed = NULL, \
|
||||
.end = NULL, \
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret lzma_lz_decoder_init(lzma_next_coder *next,
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters,
|
||||
lzma_ret (*lz_init)(lzma_lz_decoder *lz,
|
||||
const lzma_allocator *allocator, const void *options,
|
||||
lzma_lz_options *lz_options));
|
||||
|
||||
extern uint64_t lzma_lz_decoder_memusage(size_t dictionary_size);
|
||||
|
||||
extern void lzma_lz_decoder_uncompressed(
|
||||
void *coder, lzma_vli uncompressed_size);
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Inline functions //
|
||||
//////////////////////
|
||||
|
||||
/// Get a byte from the history buffer.
|
||||
static inline uint8_t
|
||||
dict_get(const lzma_dict *const dict, const uint32_t distance)
|
||||
{
|
||||
return dict->buf[dict->pos - distance - 1
|
||||
+ (distance < dict->pos ? 0 : dict->size)];
|
||||
}
|
||||
|
||||
|
||||
/// Test if dictionary is empty.
|
||||
static inline bool
|
||||
dict_is_empty(const lzma_dict *const dict)
|
||||
{
|
||||
return dict->full == 0;
|
||||
}
|
||||
|
||||
|
||||
/// Validate the match distance
|
||||
static inline bool
|
||||
dict_is_distance_valid(const lzma_dict *const dict, const size_t distance)
|
||||
{
|
||||
return dict->full > distance;
|
||||
}
|
||||
|
||||
|
||||
/// Repeat *len bytes at distance.
|
||||
static inline bool
|
||||
dict_repeat(lzma_dict *dict, uint32_t distance, uint32_t *len)
|
||||
{
|
||||
// Don't write past the end of the dictionary.
|
||||
const size_t dict_avail = dict->limit - dict->pos;
|
||||
uint32_t left = my_min(dict_avail, *len);
|
||||
*len -= left;
|
||||
|
||||
// Repeat a block of data from the history. Because memcpy() is faster
|
||||
// than copying byte by byte in a loop, the copying process gets split
|
||||
// into three cases.
|
||||
if (distance < left) {
|
||||
// Source and target areas overlap, thus we can't use
|
||||
// memcpy() nor even memmove() safely.
|
||||
do {
|
||||
dict->buf[dict->pos] = dict_get(dict, distance);
|
||||
++dict->pos;
|
||||
} while (--left > 0);
|
||||
|
||||
} else if (distance < dict->pos) {
|
||||
// The easiest and fastest case
|
||||
memcpy(dict->buf + dict->pos,
|
||||
dict->buf + dict->pos - distance - 1,
|
||||
left);
|
||||
dict->pos += left;
|
||||
|
||||
} else {
|
||||
// The bigger the dictionary, the more rare this
|
||||
// case occurs. We need to "wrap" the dict, thus
|
||||
// we might need two memcpy() to copy all the data.
|
||||
assert(dict->full == dict->size);
|
||||
const uint32_t copy_pos
|
||||
= dict->pos - distance - 1 + dict->size;
|
||||
uint32_t copy_size = dict->size - copy_pos;
|
||||
|
||||
if (copy_size < left) {
|
||||
memmove(dict->buf + dict->pos, dict->buf + copy_pos,
|
||||
copy_size);
|
||||
dict->pos += copy_size;
|
||||
copy_size = left - copy_size;
|
||||
memcpy(dict->buf + dict->pos, dict->buf, copy_size);
|
||||
dict->pos += copy_size;
|
||||
} else {
|
||||
memmove(dict->buf + dict->pos, dict->buf + copy_pos,
|
||||
left);
|
||||
dict->pos += left;
|
||||
}
|
||||
}
|
||||
|
||||
// Update how full the dictionary is.
|
||||
if (dict->full < dict->pos)
|
||||
dict->full = dict->pos;
|
||||
|
||||
return unlikely(*len != 0);
|
||||
}
|
||||
|
||||
|
||||
/// Puts one byte into the dictionary. Returns true if the dictionary was
|
||||
/// already full and the byte couldn't be added.
|
||||
static inline bool
|
||||
dict_put(lzma_dict *dict, uint8_t byte)
|
||||
{
|
||||
if (unlikely(dict->pos == dict->limit))
|
||||
return true;
|
||||
|
||||
dict->buf[dict->pos++] = byte;
|
||||
|
||||
if (dict->pos > dict->full)
|
||||
dict->full = dict->pos;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// Copies arbitrary amount of data into the dictionary.
|
||||
static inline void
|
||||
dict_write(lzma_dict *restrict dict, const uint8_t *restrict in,
|
||||
size_t *restrict in_pos, size_t in_size,
|
||||
size_t *restrict left)
|
||||
{
|
||||
// NOTE: If we are being given more data than the size of the
|
||||
// dictionary, it could be possible to optimize the LZ decoder
|
||||
// so that not everything needs to go through the dictionary.
|
||||
// This shouldn't be very common thing in practice though, and
|
||||
// the slowdown of one extra memcpy() isn't bad compared to how
|
||||
// much time it would have taken if the data were compressed.
|
||||
|
||||
if (in_size - *in_pos > *left)
|
||||
in_size = *in_pos + *left;
|
||||
|
||||
*left -= lzma_bufcpy(in, in_pos, in_size,
|
||||
dict->buf, &dict->pos, dict->limit);
|
||||
|
||||
if (dict->pos > dict->full)
|
||||
dict->full = dict->pos;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
dict_reset(lzma_dict *dict)
|
||||
{
|
||||
dict->need_reset = true;
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
+616
@@ -0,0 +1,616 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lz_encoder.c
|
||||
/// \brief LZ in window
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "lz_encoder.h"
|
||||
#include "lz_encoder_hash.h"
|
||||
|
||||
// See lz_encoder_hash.h. This is a bit hackish but avoids making
|
||||
// endianness a conditional in makefiles.
|
||||
#if defined(WORDS_BIGENDIAN) && !defined(HAVE_SMALL)
|
||||
# include "lz_encoder_hash_table.h"
|
||||
#endif
|
||||
|
||||
#include "memcmplen.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// LZ-based encoder e.g. LZMA
|
||||
lzma_lz_encoder lz;
|
||||
|
||||
/// History buffer and match finder
|
||||
lzma_mf mf;
|
||||
|
||||
/// Next coder in the chain
|
||||
lzma_next_coder next;
|
||||
} lzma_coder;
|
||||
|
||||
|
||||
/// \brief Moves the data in the input window to free space for new data
|
||||
///
|
||||
/// mf->buffer is a sliding input window, which keeps mf->keep_size_before
|
||||
/// bytes of input history available all the time. Now and then we need to
|
||||
/// "slide" the buffer to make space for the new data to the end of the
|
||||
/// buffer. At the same time, data older than keep_size_before is dropped.
|
||||
///
|
||||
static void
|
||||
move_window(lzma_mf *mf)
|
||||
{
|
||||
// Align the move to a multiple of 16 bytes. Some LZ-based encoders
|
||||
// like LZMA use the lowest bits of mf->read_pos to know the
|
||||
// alignment of the uncompressed data. We also get better speed
|
||||
// for memmove() with aligned buffers.
|
||||
assert(mf->read_pos > mf->keep_size_before);
|
||||
const uint32_t move_offset
|
||||
= (mf->read_pos - mf->keep_size_before) & ~UINT32_C(15);
|
||||
|
||||
assert(mf->write_pos > move_offset);
|
||||
const size_t move_size = mf->write_pos - move_offset;
|
||||
|
||||
assert(move_offset + move_size <= mf->size);
|
||||
|
||||
memmove(mf->buffer, mf->buffer + move_offset, move_size);
|
||||
|
||||
mf->offset += move_offset;
|
||||
mf->read_pos -= move_offset;
|
||||
mf->read_limit -= move_offset;
|
||||
mf->write_pos -= move_offset;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Tries to fill the input window (mf->buffer)
|
||||
///
|
||||
/// If we are the last encoder in the chain, our input data is in in[].
|
||||
/// Otherwise we call the next filter in the chain to process in[] and
|
||||
/// write its output to mf->buffer.
|
||||
///
|
||||
/// This function must not be called once it has returned LZMA_STREAM_END.
|
||||
///
|
||||
static lzma_ret
|
||||
fill_window(lzma_coder *coder, const lzma_allocator *allocator,
|
||||
const uint8_t *in, size_t *in_pos, size_t in_size,
|
||||
lzma_action action)
|
||||
{
|
||||
assert(coder->mf.read_pos <= coder->mf.write_pos);
|
||||
|
||||
// Move the sliding window if needed.
|
||||
if (coder->mf.read_pos >= coder->mf.size - coder->mf.keep_size_after)
|
||||
move_window(&coder->mf);
|
||||
|
||||
// Maybe this is ugly, but lzma_mf uses uint32_t for most things
|
||||
// (which I find cleanest), but we need size_t here when filling
|
||||
// the history window.
|
||||
size_t write_pos = coder->mf.write_pos;
|
||||
lzma_ret ret;
|
||||
if (coder->next.code == NULL) {
|
||||
// Not using a filter, simply memcpy() as much as possible.
|
||||
lzma_bufcpy(in, in_pos, in_size, coder->mf.buffer,
|
||||
&write_pos, coder->mf.size);
|
||||
|
||||
ret = action != LZMA_RUN && *in_pos == in_size
|
||||
? LZMA_STREAM_END : LZMA_OK;
|
||||
|
||||
} else {
|
||||
ret = coder->next.code(coder->next.coder, allocator,
|
||||
in, in_pos, in_size,
|
||||
coder->mf.buffer, &write_pos,
|
||||
coder->mf.size, action);
|
||||
}
|
||||
|
||||
coder->mf.write_pos = write_pos;
|
||||
|
||||
// Silence Valgrind. lzma_memcmplen() can read extra bytes
|
||||
// and Valgrind will give warnings if those bytes are uninitialized
|
||||
// because Valgrind cannot see that the values of the uninitialized
|
||||
// bytes are eventually ignored.
|
||||
memzero(coder->mf.buffer + write_pos, LZMA_MEMCMPLEN_EXTRA);
|
||||
|
||||
// If end of stream has been reached or flushing completed, we allow
|
||||
// the encoder to process all the input (that is, read_pos is allowed
|
||||
// to reach write_pos). Otherwise we keep keep_size_after bytes
|
||||
// available as prebuffer.
|
||||
if (ret == LZMA_STREAM_END) {
|
||||
assert(*in_pos == in_size);
|
||||
ret = LZMA_OK;
|
||||
coder->mf.action = action;
|
||||
coder->mf.read_limit = coder->mf.write_pos;
|
||||
|
||||
} else if (coder->mf.write_pos > coder->mf.keep_size_after) {
|
||||
// This needs to be done conditionally, because if we got
|
||||
// only little new input, there may be too little input
|
||||
// to do any encoding yet.
|
||||
coder->mf.read_limit = coder->mf.write_pos
|
||||
- coder->mf.keep_size_after;
|
||||
}
|
||||
|
||||
// Restart the match finder after finished LZMA_SYNC_FLUSH.
|
||||
if (coder->mf.pending > 0
|
||||
&& coder->mf.read_pos < coder->mf.read_limit) {
|
||||
// Match finder may update coder->pending and expects it to
|
||||
// start from zero, so use a temporary variable.
|
||||
const uint32_t pending = coder->mf.pending;
|
||||
coder->mf.pending = 0;
|
||||
|
||||
// Rewind read_pos so that the match finder can hash
|
||||
// the pending bytes.
|
||||
assert(coder->mf.read_pos >= pending);
|
||||
coder->mf.read_pos -= pending;
|
||||
|
||||
// Call the skip function directly instead of using
|
||||
// mf_skip(), since we don't want to touch mf->read_ahead.
|
||||
coder->mf.skip(&coder->mf, pending);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
lz_encode(void *coder_ptr, const lzma_allocator *allocator,
|
||||
const uint8_t *restrict in, size_t *restrict in_pos,
|
||||
size_t in_size,
|
||||
uint8_t *restrict out, size_t *restrict out_pos,
|
||||
size_t out_size, lzma_action action)
|
||||
{
|
||||
lzma_coder *coder = coder_ptr;
|
||||
|
||||
while (*out_pos < out_size
|
||||
&& (*in_pos < in_size || action != LZMA_RUN)) {
|
||||
// Read more data to coder->mf.buffer if needed.
|
||||
if (coder->mf.action == LZMA_RUN && coder->mf.read_pos
|
||||
>= coder->mf.read_limit)
|
||||
return_if_error(fill_window(coder, allocator,
|
||||
in, in_pos, in_size, action));
|
||||
|
||||
// Encode
|
||||
const lzma_ret ret = coder->lz.code(coder->lz.coder,
|
||||
&coder->mf, out, out_pos, out_size);
|
||||
if (ret != LZMA_OK) {
|
||||
// Setting this to LZMA_RUN for cases when we are
|
||||
// flushing. It doesn't matter when finishing or if
|
||||
// an error occurred.
|
||||
coder->mf.action = LZMA_RUN;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
lz_encoder_prepare(lzma_mf *mf, const lzma_allocator *allocator,
|
||||
const lzma_lz_options *lz_options)
|
||||
{
|
||||
// For now, the dictionary size is limited to 1.5 GiB. This may grow
|
||||
// in the future if needed, but it needs a little more work than just
|
||||
// changing this check.
|
||||
if (lz_options->dict_size < LZMA_DICT_SIZE_MIN
|
||||
|| lz_options->dict_size
|
||||
> (UINT32_C(1) << 30) + (UINT32_C(1) << 29)
|
||||
|| lz_options->nice_len > lz_options->match_len_max)
|
||||
return true;
|
||||
|
||||
mf->keep_size_before = lz_options->before_size + lz_options->dict_size;
|
||||
|
||||
mf->keep_size_after = lz_options->after_size
|
||||
+ lz_options->match_len_max;
|
||||
|
||||
// To avoid constant memmove()s, allocate some extra space. Since
|
||||
// memmove()s become more expensive when the size of the buffer
|
||||
// increases, we reserve more space when a large dictionary is
|
||||
// used to make the memmove() calls rarer.
|
||||
//
|
||||
// This works with dictionaries up to about 3 GiB. If bigger
|
||||
// dictionary is wanted, some extra work is needed:
|
||||
// - Several variables in lzma_mf have to be changed from uint32_t
|
||||
// to size_t.
|
||||
// - Memory usage calculation needs something too, e.g. use uint64_t
|
||||
// for mf->size.
|
||||
uint32_t reserve = lz_options->dict_size / 2;
|
||||
if (reserve > (UINT32_C(1) << 30))
|
||||
reserve /= 2;
|
||||
|
||||
reserve += (lz_options->before_size + lz_options->match_len_max
|
||||
+ lz_options->after_size) / 2 + (UINT32_C(1) << 19);
|
||||
|
||||
const uint32_t old_size = mf->size;
|
||||
mf->size = mf->keep_size_before + reserve + mf->keep_size_after;
|
||||
|
||||
// Deallocate the old history buffer if it exists but has different
|
||||
// size than what is needed now.
|
||||
if (mf->buffer != NULL && old_size != mf->size) {
|
||||
lzma_free(mf->buffer, allocator);
|
||||
mf->buffer = NULL;
|
||||
}
|
||||
|
||||
// Match finder options
|
||||
mf->match_len_max = lz_options->match_len_max;
|
||||
mf->nice_len = lz_options->nice_len;
|
||||
|
||||
// cyclic_size has to stay smaller than 2 Gi. Note that this doesn't
|
||||
// mean limiting dictionary size to less than 2 GiB. With a match
|
||||
// finder that uses multibyte resolution (hashes start at e.g. every
|
||||
// fourth byte), cyclic_size would stay below 2 Gi even when
|
||||
// dictionary size is greater than 2 GiB.
|
||||
//
|
||||
// It would be possible to allow cyclic_size >= 2 Gi, but then we
|
||||
// would need to be careful to use 64-bit types in various places
|
||||
// (size_t could do since we would need bigger than 32-bit address
|
||||
// space anyway). It would also require either zeroing a multigigabyte
|
||||
// buffer at initialization (waste of time and RAM) or allow
|
||||
// normalization in lz_encoder_mf.c to access uninitialized
|
||||
// memory to keep the code simpler. The current way is simple and
|
||||
// still allows pretty big dictionaries, so I don't expect these
|
||||
// limits to change.
|
||||
mf->cyclic_size = lz_options->dict_size + 1;
|
||||
|
||||
// Validate the match finder ID and setup the function pointers.
|
||||
switch (lz_options->match_finder) {
|
||||
#ifdef HAVE_MF_HC3
|
||||
case LZMA_MF_HC3:
|
||||
mf->find = &lzma_mf_hc3_find;
|
||||
mf->skip = &lzma_mf_hc3_skip;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_MF_HC4
|
||||
case LZMA_MF_HC4:
|
||||
mf->find = &lzma_mf_hc4_find;
|
||||
mf->skip = &lzma_mf_hc4_skip;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_MF_BT2
|
||||
case LZMA_MF_BT2:
|
||||
mf->find = &lzma_mf_bt2_find;
|
||||
mf->skip = &lzma_mf_bt2_skip;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_MF_BT3
|
||||
case LZMA_MF_BT3:
|
||||
mf->find = &lzma_mf_bt3_find;
|
||||
mf->skip = &lzma_mf_bt3_skip;
|
||||
break;
|
||||
#endif
|
||||
#ifdef HAVE_MF_BT4
|
||||
case LZMA_MF_BT4:
|
||||
mf->find = &lzma_mf_bt4_find;
|
||||
mf->skip = &lzma_mf_bt4_skip;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calculate the sizes of mf->hash and mf->son and check that
|
||||
// nice_len is big enough for the selected match finder.
|
||||
const uint32_t hash_bytes = lz_options->match_finder & 0x0F;
|
||||
if (hash_bytes > mf->nice_len)
|
||||
return true;
|
||||
|
||||
const bool is_bt = (lz_options->match_finder & 0x10) != 0;
|
||||
uint32_t hs;
|
||||
|
||||
if (hash_bytes == 2) {
|
||||
hs = 0xFFFF;
|
||||
} else {
|
||||
// Round dictionary size up to the next 2^n - 1 so it can
|
||||
// be used as a hash mask.
|
||||
hs = lz_options->dict_size - 1;
|
||||
hs |= hs >> 1;
|
||||
hs |= hs >> 2;
|
||||
hs |= hs >> 4;
|
||||
hs |= hs >> 8;
|
||||
hs >>= 1;
|
||||
hs |= 0xFFFF;
|
||||
|
||||
if (hs > (UINT32_C(1) << 24)) {
|
||||
if (hash_bytes == 3)
|
||||
hs = (UINT32_C(1) << 24) - 1;
|
||||
else
|
||||
hs >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
mf->hash_mask = hs;
|
||||
|
||||
++hs;
|
||||
if (hash_bytes > 2)
|
||||
hs += HASH_2_SIZE;
|
||||
if (hash_bytes > 3)
|
||||
hs += HASH_3_SIZE;
|
||||
/*
|
||||
No match finder uses this at the moment.
|
||||
if (mf->hash_bytes > 4)
|
||||
hs += HASH_4_SIZE;
|
||||
*/
|
||||
|
||||
const uint32_t old_hash_count = mf->hash_count;
|
||||
const uint32_t old_sons_count = mf->sons_count;
|
||||
mf->hash_count = hs;
|
||||
mf->sons_count = mf->cyclic_size;
|
||||
if (is_bt)
|
||||
mf->sons_count *= 2;
|
||||
|
||||
// Deallocate the old hash array if it exists and has different size
|
||||
// than what is needed now.
|
||||
if (old_hash_count != mf->hash_count
|
||||
|| old_sons_count != mf->sons_count) {
|
||||
lzma_free(mf->hash, allocator);
|
||||
mf->hash = NULL;
|
||||
|
||||
lzma_free(mf->son, allocator);
|
||||
mf->son = NULL;
|
||||
}
|
||||
|
||||
// Maximum number of match finder cycles
|
||||
mf->depth = lz_options->depth;
|
||||
if (mf->depth == 0) {
|
||||
if (is_bt)
|
||||
mf->depth = 16 + mf->nice_len / 2;
|
||||
else
|
||||
mf->depth = 4 + mf->nice_len / 4;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
lz_encoder_init(lzma_mf *mf, const lzma_allocator *allocator,
|
||||
const lzma_lz_options *lz_options)
|
||||
{
|
||||
// Allocate the history buffer.
|
||||
if (mf->buffer == NULL) {
|
||||
// lzma_memcmplen() is used for the dictionary buffer
|
||||
// so we need to allocate a few extra bytes to prevent
|
||||
// it from reading past the end of the buffer.
|
||||
mf->buffer = lzma_alloc(mf->size + LZMA_MEMCMPLEN_EXTRA,
|
||||
allocator);
|
||||
if (mf->buffer == NULL)
|
||||
return true;
|
||||
|
||||
// Keep Valgrind happy with lzma_memcmplen() and initialize
|
||||
// the extra bytes whose value may get read but which will
|
||||
// effectively get ignored.
|
||||
memzero(mf->buffer + mf->size, LZMA_MEMCMPLEN_EXTRA);
|
||||
}
|
||||
|
||||
// Use cyclic_size as initial mf->offset. This allows
|
||||
// avoiding a few branches in the match finders. The downside is
|
||||
// that match finder needs to be normalized more often, which may
|
||||
// hurt performance with huge dictionaries.
|
||||
mf->offset = mf->cyclic_size;
|
||||
mf->read_pos = 0;
|
||||
mf->read_ahead = 0;
|
||||
mf->read_limit = 0;
|
||||
mf->write_pos = 0;
|
||||
mf->pending = 0;
|
||||
|
||||
#if UINT32_MAX >= SIZE_MAX / 4
|
||||
// Check for integer overflow. (Huge dictionaries are not
|
||||
// possible on 32-bit CPU.)
|
||||
if (mf->hash_count > SIZE_MAX / sizeof(uint32_t)
|
||||
|| mf->sons_count > SIZE_MAX / sizeof(uint32_t))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
// Allocate and initialize the hash table. Since EMPTY_HASH_VALUE
|
||||
// is zero, we can use lzma_alloc_zero() or memzero() for mf->hash.
|
||||
//
|
||||
// We don't need to initialize mf->son, but not doing that may
|
||||
// make Valgrind complain in normalization (see normalize() in
|
||||
// lz_encoder_mf.c). Skipping the initialization is *very* good
|
||||
// when big dictionary is used but only small amount of data gets
|
||||
// actually compressed: most of the mf->son won't get actually
|
||||
// allocated by the kernel, so we avoid wasting RAM and improve
|
||||
// initialization speed a lot.
|
||||
if (mf->hash == NULL) {
|
||||
mf->hash = lzma_alloc_zero(mf->hash_count * sizeof(uint32_t),
|
||||
allocator);
|
||||
mf->son = lzma_alloc(mf->sons_count * sizeof(uint32_t),
|
||||
allocator);
|
||||
|
||||
if (mf->hash == NULL || mf->son == NULL) {
|
||||
lzma_free(mf->hash, allocator);
|
||||
mf->hash = NULL;
|
||||
|
||||
lzma_free(mf->son, allocator);
|
||||
mf->son = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
for (uint32_t i = 0; i < mf->hash_count; ++i)
|
||||
mf->hash[i] = EMPTY_HASH_VALUE;
|
||||
*/
|
||||
memzero(mf->hash, mf->hash_count * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
mf->cyclic_pos = 0;
|
||||
|
||||
// Handle preset dictionary.
|
||||
if (lz_options->preset_dict != NULL
|
||||
&& lz_options->preset_dict_size > 0) {
|
||||
// If the preset dictionary is bigger than the actual
|
||||
// dictionary, use only the tail.
|
||||
mf->write_pos = my_min(lz_options->preset_dict_size, mf->size);
|
||||
memcpy(mf->buffer, lz_options->preset_dict
|
||||
+ lz_options->preset_dict_size - mf->write_pos,
|
||||
mf->write_pos);
|
||||
mf->action = LZMA_SYNC_FLUSH;
|
||||
mf->skip(mf, mf->write_pos);
|
||||
}
|
||||
|
||||
mf->action = LZMA_RUN;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
extern uint64_t
|
||||
lzma_lz_encoder_memusage(const lzma_lz_options *lz_options)
|
||||
{
|
||||
// Old buffers must not exist when calling lz_encoder_prepare().
|
||||
lzma_mf mf = {
|
||||
.buffer = NULL,
|
||||
.hash = NULL,
|
||||
.son = NULL,
|
||||
.hash_count = 0,
|
||||
.sons_count = 0,
|
||||
};
|
||||
|
||||
// Setup the size information into mf.
|
||||
if (lz_encoder_prepare(&mf, NULL, lz_options))
|
||||
return UINT64_MAX;
|
||||
|
||||
// Calculate the memory usage.
|
||||
return ((uint64_t)(mf.hash_count) + mf.sons_count) * sizeof(uint32_t)
|
||||
+ mf.size + sizeof(lzma_coder);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
lz_encoder_end(void *coder_ptr, const lzma_allocator *allocator)
|
||||
{
|
||||
lzma_coder *coder = coder_ptr;
|
||||
|
||||
lzma_next_end(&coder->next, allocator);
|
||||
|
||||
lzma_free(coder->mf.son, allocator);
|
||||
lzma_free(coder->mf.hash, allocator);
|
||||
lzma_free(coder->mf.buffer, allocator);
|
||||
|
||||
if (coder->lz.end != NULL)
|
||||
coder->lz.end(coder->lz.coder, allocator);
|
||||
else
|
||||
lzma_free(coder->lz.coder, allocator);
|
||||
|
||||
lzma_free(coder, allocator);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
lz_encoder_update(void *coder_ptr, const lzma_allocator *allocator,
|
||||
const lzma_filter *filters_null lzma_attribute((__unused__)),
|
||||
const lzma_filter *reversed_filters)
|
||||
{
|
||||
lzma_coder *coder = coder_ptr;
|
||||
|
||||
if (coder->lz.options_update == NULL)
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
return_if_error(coder->lz.options_update(
|
||||
coder->lz.coder, reversed_filters));
|
||||
|
||||
return lzma_next_filter_update(
|
||||
&coder->next, allocator, reversed_filters + 1);
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lz_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters,
|
||||
lzma_ret (*lz_init)(lzma_lz_encoder *lz,
|
||||
const lzma_allocator *allocator, const void *options,
|
||||
lzma_lz_options *lz_options))
|
||||
{
|
||||
#ifdef HAVE_SMALL
|
||||
// We need that the CRC32 table has been initialized.
|
||||
lzma_crc32_init();
|
||||
#endif
|
||||
|
||||
// Allocate and initialize the base data structure.
|
||||
lzma_coder *coder = next->coder;
|
||||
if (coder == NULL) {
|
||||
coder = lzma_alloc(sizeof(lzma_coder), allocator);
|
||||
if (coder == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
next->coder = coder;
|
||||
next->code = &lz_encode;
|
||||
next->end = &lz_encoder_end;
|
||||
next->update = &lz_encoder_update;
|
||||
|
||||
coder->lz.coder = NULL;
|
||||
coder->lz.code = NULL;
|
||||
coder->lz.end = NULL;
|
||||
|
||||
// mf.size is initialized to silence Valgrind
|
||||
// when used on optimized binaries (GCC may reorder
|
||||
// code in a way that Valgrind gets unhappy).
|
||||
coder->mf.buffer = NULL;
|
||||
coder->mf.size = 0;
|
||||
coder->mf.hash = NULL;
|
||||
coder->mf.son = NULL;
|
||||
coder->mf.hash_count = 0;
|
||||
coder->mf.sons_count = 0;
|
||||
|
||||
coder->next = LZMA_NEXT_CODER_INIT;
|
||||
}
|
||||
|
||||
// Initialize the LZ-based encoder.
|
||||
lzma_lz_options lz_options;
|
||||
return_if_error(lz_init(&coder->lz, allocator,
|
||||
filters[0].options, &lz_options));
|
||||
|
||||
// Setup the size information into coder->mf and deallocate
|
||||
// old buffers if they have wrong size.
|
||||
if (lz_encoder_prepare(&coder->mf, allocator, &lz_options))
|
||||
return LZMA_OPTIONS_ERROR;
|
||||
|
||||
// Allocate new buffers if needed, and do the rest of
|
||||
// the initialization.
|
||||
if (lz_encoder_init(&coder->mf, allocator, &lz_options))
|
||||
return LZMA_MEM_ERROR;
|
||||
|
||||
// Initialize the next filter in the chain, if any.
|
||||
return lzma_next_filter_init(&coder->next, allocator, filters + 1);
|
||||
}
|
||||
|
||||
|
||||
extern LZMA_API(lzma_bool)
|
||||
lzma_mf_is_supported(lzma_match_finder mf)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
#ifdef HAVE_MF_HC3
|
||||
if (mf == LZMA_MF_HC3)
|
||||
ret = true;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MF_HC4
|
||||
if (mf == LZMA_MF_HC4)
|
||||
ret = true;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MF_BT2
|
||||
if (mf == LZMA_MF_BT2)
|
||||
ret = true;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MF_BT3
|
||||
if (mf == LZMA_MF_BT3)
|
||||
ret = true;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MF_BT4
|
||||
if (mf == LZMA_MF_BT4)
|
||||
ret = true;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
+327
@@ -0,0 +1,327 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lz_encoder.h
|
||||
/// \brief LZ in window and match finder API
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_LZ_ENCODER_H
|
||||
#define LZMA_LZ_ENCODER_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/// A table of these is used by the LZ-based encoder to hold
|
||||
/// the length-distance pairs found by the match finder.
|
||||
typedef struct {
|
||||
uint32_t len;
|
||||
uint32_t dist;
|
||||
} lzma_match;
|
||||
|
||||
|
||||
typedef struct lzma_mf_s lzma_mf;
|
||||
struct lzma_mf_s {
|
||||
///////////////
|
||||
// In Window //
|
||||
///////////////
|
||||
|
||||
/// Pointer to buffer with data to be compressed
|
||||
uint8_t *buffer;
|
||||
|
||||
/// Total size of the allocated buffer (that is, including all
|
||||
/// the extra space)
|
||||
uint32_t size;
|
||||
|
||||
/// Number of bytes that must be kept available in our input history.
|
||||
/// That is, once keep_size_before bytes have been processed,
|
||||
/// buffer[read_pos - keep_size_before] is the oldest byte that
|
||||
/// must be available for reading.
|
||||
uint32_t keep_size_before;
|
||||
|
||||
/// Number of bytes that must be kept in buffer after read_pos.
|
||||
/// That is, read_pos <= write_pos - keep_size_after as long as
|
||||
/// action is LZMA_RUN; when action != LZMA_RUN, read_pos is allowed
|
||||
/// to reach write_pos so that the last bytes get encoded too.
|
||||
uint32_t keep_size_after;
|
||||
|
||||
/// Match finders store locations of matches using 32-bit integers.
|
||||
/// To avoid adjusting several megabytes of integers every time the
|
||||
/// input window is moved with move_window, we only adjust the
|
||||
/// offset of the buffer. Thus, buffer[value_in_hash_table - offset]
|
||||
/// is the byte pointed by value_in_hash_table.
|
||||
uint32_t offset;
|
||||
|
||||
/// buffer[read_pos] is the next byte to run through the match
|
||||
/// finder. This is incremented in the match finder once the byte
|
||||
/// has been processed.
|
||||
uint32_t read_pos;
|
||||
|
||||
/// Number of bytes that have been ran through the match finder, but
|
||||
/// which haven't been encoded by the LZ-based encoder yet.
|
||||
uint32_t read_ahead;
|
||||
|
||||
/// As long as read_pos is less than read_limit, there is enough
|
||||
/// input available in buffer for at least one encoding loop.
|
||||
///
|
||||
/// Because of the stateful API, read_limit may and will get greater
|
||||
/// than read_pos quite often. This is taken into account when
|
||||
/// calculating the value for keep_size_after.
|
||||
uint32_t read_limit;
|
||||
|
||||
/// buffer[write_pos] is the first byte that doesn't contain valid
|
||||
/// uncompressed data; that is, the next input byte will be copied
|
||||
/// to buffer[write_pos].
|
||||
uint32_t write_pos;
|
||||
|
||||
/// Number of bytes not hashed before read_pos. This is needed to
|
||||
/// restart the match finder after LZMA_SYNC_FLUSH.
|
||||
uint32_t pending;
|
||||
|
||||
//////////////////
|
||||
// Match Finder //
|
||||
//////////////////
|
||||
|
||||
/// Find matches. Returns the number of distance-length pairs written
|
||||
/// to the matches array. This is called only via lzma_mf_find().
|
||||
uint32_t (*find)(lzma_mf *mf, lzma_match *matches);
|
||||
|
||||
/// Skips num bytes. This is like find() but doesn't make the
|
||||
/// distance-length pairs available, thus being a little faster.
|
||||
/// This is called only via mf_skip().
|
||||
void (*skip)(lzma_mf *mf, uint32_t num);
|
||||
|
||||
uint32_t *hash;
|
||||
uint32_t *son;
|
||||
uint32_t cyclic_pos;
|
||||
uint32_t cyclic_size; // Must be dictionary size + 1.
|
||||
uint32_t hash_mask;
|
||||
|
||||
/// Maximum number of loops in the match finder
|
||||
uint32_t depth;
|
||||
|
||||
/// Maximum length of a match that the match finder will try to find.
|
||||
uint32_t nice_len;
|
||||
|
||||
/// Maximum length of a match supported by the LZ-based encoder.
|
||||
/// If the longest match found by the match finder is nice_len,
|
||||
/// mf_find() tries to expand it up to match_len_max bytes.
|
||||
uint32_t match_len_max;
|
||||
|
||||
/// When running out of input, binary tree match finders need to know
|
||||
/// if it is due to flushing or finishing. The action is used also
|
||||
/// by the LZ-based encoders themselves.
|
||||
lzma_action action;
|
||||
|
||||
/// Number of elements in hash[]
|
||||
uint32_t hash_count;
|
||||
|
||||
/// Number of elements in son[]
|
||||
uint32_t sons_count;
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// Extra amount of data to keep available before the "actual"
|
||||
/// dictionary.
|
||||
size_t before_size;
|
||||
|
||||
/// Size of the history buffer
|
||||
size_t dict_size;
|
||||
|
||||
/// Extra amount of data to keep available after the "actual"
|
||||
/// dictionary.
|
||||
size_t after_size;
|
||||
|
||||
/// Maximum length of a match that the LZ-based encoder can accept.
|
||||
/// This is used to extend matches of length nice_len to the
|
||||
/// maximum possible length.
|
||||
size_t match_len_max;
|
||||
|
||||
/// Match finder will search matches up to this length.
|
||||
/// This must be less than or equal to match_len_max.
|
||||
size_t nice_len;
|
||||
|
||||
/// Type of the match finder to use
|
||||
lzma_match_finder match_finder;
|
||||
|
||||
/// Maximum search depth
|
||||
uint32_t depth;
|
||||
|
||||
/// TODO: Comment
|
||||
const uint8_t *preset_dict;
|
||||
|
||||
uint32_t preset_dict_size;
|
||||
|
||||
} lzma_lz_options;
|
||||
|
||||
|
||||
// The total usable buffer space at any moment outside the match finder:
|
||||
// before_size + dict_size + after_size + match_len_max
|
||||
//
|
||||
// In reality, there's some extra space allocated to prevent the number of
|
||||
// memmove() calls reasonable. The bigger the dict_size is, the bigger
|
||||
// this extra buffer will be since with bigger dictionaries memmove() would
|
||||
// also take longer.
|
||||
//
|
||||
// A single encoder loop in the LZ-based encoder may call the match finder
|
||||
// (mf_find() or mf_skip()) at most after_size times. In other words,
|
||||
// a single encoder loop may increment lzma_mf.read_pos at most after_size
|
||||
// times. Since matches are looked up to
|
||||
// lzma_mf.buffer[lzma_mf.read_pos + match_len_max - 1], the total
|
||||
// amount of extra buffer needed after dict_size becomes
|
||||
// after_size + match_len_max.
|
||||
//
|
||||
// before_size has two uses. The first one is to keep literals available
|
||||
// in cases when the LZ-based encoder has made some read ahead.
|
||||
// TODO: Maybe this could be changed by making the LZ-based encoders to
|
||||
// store the actual literals as they do with length-distance pairs.
|
||||
//
|
||||
// Algorithms such as LZMA2 first try to compress a chunk, and then check
|
||||
// if the encoded result is smaller than the uncompressed one. If the chunk
|
||||
// was uncompressible, it is better to store it in uncompressed form in
|
||||
// the output stream. To do this, the whole uncompressed chunk has to be
|
||||
// still available in the history buffer. before_size achieves that.
|
||||
|
||||
|
||||
typedef struct {
|
||||
/// Data specific to the LZ-based encoder
|
||||
void *coder;
|
||||
|
||||
/// Function to encode from *dict to out[]
|
||||
lzma_ret (*code)(void *coder,
|
||||
lzma_mf *restrict mf, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size);
|
||||
|
||||
/// Free allocated resources
|
||||
void (*end)(void *coder, const lzma_allocator *allocator);
|
||||
|
||||
/// Update the options in the middle of the encoding.
|
||||
lzma_ret (*options_update)(void *coder, const lzma_filter *filter);
|
||||
|
||||
} lzma_lz_encoder;
|
||||
|
||||
|
||||
// Basic steps:
|
||||
// 1. Input gets copied into the dictionary.
|
||||
// 2. Data in dictionary gets run through the match finder byte by byte.
|
||||
// 3. The literals and matches are encoded using e.g. LZMA.
|
||||
//
|
||||
// The bytes that have been ran through the match finder, but not encoded yet,
|
||||
// are called `read ahead'.
|
||||
|
||||
|
||||
/// Get pointer to the first byte not ran through the match finder
|
||||
static inline const uint8_t *
|
||||
mf_ptr(const lzma_mf *mf)
|
||||
{
|
||||
return mf->buffer + mf->read_pos;
|
||||
}
|
||||
|
||||
|
||||
/// Get the number of bytes that haven't been ran through the match finder yet.
|
||||
static inline uint32_t
|
||||
mf_avail(const lzma_mf *mf)
|
||||
{
|
||||
return mf->write_pos - mf->read_pos;
|
||||
}
|
||||
|
||||
|
||||
/// Get the number of bytes that haven't been encoded yet (some of these
|
||||
/// bytes may have been ran through the match finder though).
|
||||
static inline uint32_t
|
||||
mf_unencoded(const lzma_mf *mf)
|
||||
{
|
||||
return mf->write_pos - mf->read_pos + mf->read_ahead;
|
||||
}
|
||||
|
||||
|
||||
/// Calculate the absolute offset from the beginning of the most recent
|
||||
/// dictionary reset. Only the lowest four bits are important, so there's no
|
||||
/// problem that we don't know the 64-bit size of the data encoded so far.
|
||||
///
|
||||
/// NOTE: When moving the input window, we need to do it so that the lowest
|
||||
/// bits of dict->read_pos are not modified to keep this macro working
|
||||
/// as intended.
|
||||
static inline uint32_t
|
||||
mf_position(const lzma_mf *mf)
|
||||
{
|
||||
return mf->read_pos - mf->read_ahead;
|
||||
}
|
||||
|
||||
|
||||
/// Since everything else begins with mf_, use it also for lzma_mf_find().
|
||||
#define mf_find lzma_mf_find
|
||||
|
||||
|
||||
/// Skip the given number of bytes. This is used when a good match was found.
|
||||
/// For example, if mf_find() finds a match of 200 bytes long, the first byte
|
||||
/// of that match was already consumed by mf_find(), and the rest 199 bytes
|
||||
/// have to be skipped with mf_skip(mf, 199).
|
||||
static inline void
|
||||
mf_skip(lzma_mf *mf, uint32_t amount)
|
||||
{
|
||||
if (amount != 0) {
|
||||
mf->skip(mf, amount);
|
||||
mf->read_ahead += amount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Copies at most *left number of bytes from the history buffer
|
||||
/// to out[]. This is needed by LZMA2 to encode uncompressed chunks.
|
||||
static inline void
|
||||
mf_read(lzma_mf *mf, uint8_t *out, size_t *out_pos, size_t out_size,
|
||||
size_t *left)
|
||||
{
|
||||
const size_t out_avail = out_size - *out_pos;
|
||||
const size_t copy_size = my_min(out_avail, *left);
|
||||
|
||||
assert(mf->read_ahead == 0);
|
||||
assert(mf->read_pos >= *left);
|
||||
|
||||
memcpy(out + *out_pos, mf->buffer + mf->read_pos - *left,
|
||||
copy_size);
|
||||
|
||||
*out_pos += copy_size;
|
||||
*left -= copy_size;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret lzma_lz_encoder_init(
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters,
|
||||
lzma_ret (*lz_init)(lzma_lz_encoder *lz,
|
||||
const lzma_allocator *allocator, const void *options,
|
||||
lzma_lz_options *lz_options));
|
||||
|
||||
|
||||
extern uint64_t lzma_lz_encoder_memusage(const lzma_lz_options *lz_options);
|
||||
|
||||
|
||||
// These are only for LZ encoder's internal use.
|
||||
extern uint32_t lzma_mf_find(
|
||||
lzma_mf *mf, uint32_t *count, lzma_match *matches);
|
||||
|
||||
extern uint32_t lzma_mf_hc3_find(lzma_mf *dict, lzma_match *matches);
|
||||
extern void lzma_mf_hc3_skip(lzma_mf *dict, uint32_t amount);
|
||||
|
||||
extern uint32_t lzma_mf_hc4_find(lzma_mf *dict, lzma_match *matches);
|
||||
extern void lzma_mf_hc4_skip(lzma_mf *dict, uint32_t amount);
|
||||
|
||||
extern uint32_t lzma_mf_bt2_find(lzma_mf *dict, lzma_match *matches);
|
||||
extern void lzma_mf_bt2_skip(lzma_mf *dict, uint32_t amount);
|
||||
|
||||
extern uint32_t lzma_mf_bt3_find(lzma_mf *dict, lzma_match *matches);
|
||||
extern void lzma_mf_bt3_skip(lzma_mf *dict, uint32_t amount);
|
||||
|
||||
extern uint32_t lzma_mf_bt4_find(lzma_mf *dict, lzma_match *matches);
|
||||
extern void lzma_mf_bt4_skip(lzma_mf *dict, uint32_t amount);
|
||||
|
||||
#endif
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lz_encoder_hash.h
|
||||
/// \brief Hash macros for match finders
|
||||
//
|
||||
// Author: Igor Pavlov
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_LZ_ENCODER_HASH_H
|
||||
#define LZMA_LZ_ENCODER_HASH_H
|
||||
|
||||
#if defined(WORDS_BIGENDIAN) && !defined(HAVE_SMALL)
|
||||
// This is to make liblzma produce the same output on big endian
|
||||
// systems that it does on little endian systems. lz_encoder.c
|
||||
// takes care of including the actual table.
|
||||
extern const uint32_t lzma_lz_hash_table[256];
|
||||
# define hash_table lzma_lz_hash_table
|
||||
#else
|
||||
# include "check.h"
|
||||
# define hash_table lzma_crc32_table[0]
|
||||
#endif
|
||||
|
||||
#define HASH_2_SIZE (UINT32_C(1) << 10)
|
||||
#define HASH_3_SIZE (UINT32_C(1) << 16)
|
||||
#define HASH_4_SIZE (UINT32_C(1) << 20)
|
||||
|
||||
#define HASH_2_MASK (HASH_2_SIZE - 1)
|
||||
#define HASH_3_MASK (HASH_3_SIZE - 1)
|
||||
#define HASH_4_MASK (HASH_4_SIZE - 1)
|
||||
|
||||
#define FIX_3_HASH_SIZE (HASH_2_SIZE)
|
||||
#define FIX_4_HASH_SIZE (HASH_2_SIZE + HASH_3_SIZE)
|
||||
#define FIX_5_HASH_SIZE (HASH_2_SIZE + HASH_3_SIZE + HASH_4_SIZE)
|
||||
|
||||
// Endianness doesn't matter in hash_2_calc() (no effect on the output).
|
||||
#ifdef TUKLIB_FAST_UNALIGNED_ACCESS
|
||||
# define hash_2_calc() \
|
||||
const uint32_t hash_value = *(const uint16_t *)(cur)
|
||||
#else
|
||||
# define hash_2_calc() \
|
||||
const uint32_t hash_value \
|
||||
= (uint32_t)(cur[0]) | ((uint32_t)(cur[1]) << 8)
|
||||
#endif
|
||||
|
||||
#define hash_3_calc() \
|
||||
const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \
|
||||
const uint32_t hash_2_value = temp & HASH_2_MASK; \
|
||||
const uint32_t hash_value \
|
||||
= (temp ^ ((uint32_t)(cur[2]) << 8)) & mf->hash_mask
|
||||
|
||||
#define hash_4_calc() \
|
||||
const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \
|
||||
const uint32_t hash_2_value = temp & HASH_2_MASK; \
|
||||
const uint32_t hash_3_value \
|
||||
= (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK; \
|
||||
const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8) \
|
||||
^ (hash_table[cur[3]] << 5)) & mf->hash_mask
|
||||
|
||||
|
||||
// The following are not currently used.
|
||||
|
||||
#define hash_5_calc() \
|
||||
const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \
|
||||
const uint32_t hash_2_value = temp & HASH_2_MASK; \
|
||||
const uint32_t hash_3_value \
|
||||
= (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK; \
|
||||
uint32_t hash_4_value = (temp ^ ((uint32_t)(cur[2]) << 8) ^ \
|
||||
^ hash_table[cur[3]] << 5); \
|
||||
const uint32_t hash_value \
|
||||
= (hash_4_value ^ (hash_table[cur[4]] << 3)) \
|
||||
& mf->hash_mask; \
|
||||
hash_4_value &= HASH_4_MASK
|
||||
|
||||
/*
|
||||
#define hash_zip_calc() \
|
||||
const uint32_t hash_value \
|
||||
= (((uint32_t)(cur[0]) | ((uint32_t)(cur[1]) << 8)) \
|
||||
^ hash_table[cur[2]]) & 0xFFFF
|
||||
*/
|
||||
|
||||
#define hash_zip_calc() \
|
||||
const uint32_t hash_value \
|
||||
= (((uint32_t)(cur[2]) | ((uint32_t)(cur[0]) << 8)) \
|
||||
^ hash_table[cur[1]]) & 0xFFFF
|
||||
|
||||
#define mt_hash_2_calc() \
|
||||
const uint32_t hash_2_value \
|
||||
= (hash_table[cur[0]] ^ cur[1]) & HASH_2_MASK
|
||||
|
||||
#define mt_hash_3_calc() \
|
||||
const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \
|
||||
const uint32_t hash_2_value = temp & HASH_2_MASK; \
|
||||
const uint32_t hash_3_value \
|
||||
= (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK
|
||||
|
||||
#define mt_hash_4_calc() \
|
||||
const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \
|
||||
const uint32_t hash_2_value = temp & HASH_2_MASK; \
|
||||
const uint32_t hash_3_value \
|
||||
= (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK; \
|
||||
const uint32_t hash_4_value = (temp ^ ((uint32_t)(cur[2]) << 8) ^ \
|
||||
(hash_table[cur[3]] << 5)) & HASH_4_MASK
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,68 @@
|
||||
/* This file has been automatically generated by crc32_tablegen.c. */
|
||||
|
||||
const uint32_t lzma_lz_hash_table[256] = {
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
|
||||
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
|
||||
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
||||
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
|
||||
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
|
||||
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
||||
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
|
||||
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
|
||||
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
|
||||
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
|
||||
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
||||
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
|
||||
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
|
||||
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
|
||||
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
||||
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
|
||||
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
|
||||
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
||||
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
|
||||
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
|
||||
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
|
||||
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
|
||||
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
||||
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
|
||||
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
|
||||
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
||||
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
|
||||
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
|
||||
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
|
||||
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
||||
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
|
||||
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
||||
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
|
||||
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
|
||||
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
|
||||
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
||||
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
|
||||
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
|
||||
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
|
||||
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
||||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
|
||||
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
|
||||
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
||||
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||
};
|
||||
+744
@@ -0,0 +1,744 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lz_encoder_mf.c
|
||||
/// \brief Match finders
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "lz_encoder.h"
|
||||
#include "lz_encoder_hash.h"
|
||||
#include "memcmplen.h"
|
||||
|
||||
|
||||
/// \brief Find matches starting from the current byte
|
||||
///
|
||||
/// \return The length of the longest match found
|
||||
extern uint32_t
|
||||
lzma_mf_find(lzma_mf *mf, uint32_t *count_ptr, lzma_match *matches)
|
||||
{
|
||||
// Call the match finder. It returns the number of length-distance
|
||||
// pairs found.
|
||||
// FIXME: Minimum count is zero, what _exactly_ is the maximum?
|
||||
const uint32_t count = mf->find(mf, matches);
|
||||
|
||||
// Length of the longest match; assume that no matches were found
|
||||
// and thus the maximum length is zero.
|
||||
uint32_t len_best = 0;
|
||||
|
||||
if (count > 0) {
|
||||
#ifndef NDEBUG
|
||||
// Validate the matches.
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
assert(matches[i].len <= mf->nice_len);
|
||||
assert(matches[i].dist < mf->read_pos);
|
||||
assert(memcmp(mf_ptr(mf) - 1,
|
||||
mf_ptr(mf) - matches[i].dist - 2,
|
||||
matches[i].len) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// The last used element in the array contains
|
||||
// the longest match.
|
||||
len_best = matches[count - 1].len;
|
||||
|
||||
// If a match of maximum search length was found, try to
|
||||
// extend the match to maximum possible length.
|
||||
if (len_best == mf->nice_len) {
|
||||
// The limit for the match length is either the
|
||||
// maximum match length supported by the LZ-based
|
||||
// encoder or the number of bytes left in the
|
||||
// dictionary, whichever is smaller.
|
||||
uint32_t limit = mf_avail(mf) + 1;
|
||||
if (limit > mf->match_len_max)
|
||||
limit = mf->match_len_max;
|
||||
|
||||
// Pointer to the byte we just ran through
|
||||
// the match finder.
|
||||
const uint8_t *p1 = mf_ptr(mf) - 1;
|
||||
|
||||
// Pointer to the beginning of the match. We need -1
|
||||
// here because the match distances are zero based.
|
||||
const uint8_t *p2 = p1 - matches[count - 1].dist - 1;
|
||||
|
||||
len_best = lzma_memcmplen(p1, p2, len_best, limit);
|
||||
}
|
||||
}
|
||||
|
||||
*count_ptr = count;
|
||||
|
||||
// Finally update the read position to indicate that match finder was
|
||||
// run for this dictionary offset.
|
||||
++mf->read_ahead;
|
||||
|
||||
return len_best;
|
||||
}
|
||||
|
||||
|
||||
/// Hash value to indicate unused element in the hash. Since we start the
|
||||
/// positions from dict_size + 1, zero is always too far to qualify
|
||||
/// as usable match position.
|
||||
#define EMPTY_HASH_VALUE 0
|
||||
|
||||
|
||||
/// Normalization must be done when lzma_mf.offset + lzma_mf.read_pos
|
||||
/// reaches MUST_NORMALIZE_POS.
|
||||
#define MUST_NORMALIZE_POS UINT32_MAX
|
||||
|
||||
|
||||
/// \brief Normalizes hash values
|
||||
///
|
||||
/// The hash arrays store positions of match candidates. The positions are
|
||||
/// relative to an arbitrary offset that is not the same as the absolute
|
||||
/// offset in the input stream. The relative position of the current byte
|
||||
/// is lzma_mf.offset + lzma_mf.read_pos. The distances of the matches are
|
||||
/// the differences of the current read position and the position found from
|
||||
/// the hash.
|
||||
///
|
||||
/// To prevent integer overflows of the offsets stored in the hash arrays,
|
||||
/// we need to "normalize" the stored values now and then. During the
|
||||
/// normalization, we drop values that indicate distance greater than the
|
||||
/// dictionary size, thus making space for new values.
|
||||
static void
|
||||
normalize(lzma_mf *mf)
|
||||
{
|
||||
assert(mf->read_pos + mf->offset == MUST_NORMALIZE_POS);
|
||||
|
||||
// In future we may not want to touch the lowest bits, because there
|
||||
// may be match finders that use larger resolution than one byte.
|
||||
const uint32_t subvalue
|
||||
= (MUST_NORMALIZE_POS - mf->cyclic_size);
|
||||
// & (~(UINT32_C(1) << 10) - 1);
|
||||
|
||||
for (uint32_t i = 0; i < mf->hash_count; ++i) {
|
||||
// If the distance is greater than the dictionary size,
|
||||
// we can simply mark the hash element as empty.
|
||||
if (mf->hash[i] <= subvalue)
|
||||
mf->hash[i] = EMPTY_HASH_VALUE;
|
||||
else
|
||||
mf->hash[i] -= subvalue;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mf->sons_count; ++i) {
|
||||
// Do the same for mf->son.
|
||||
//
|
||||
// NOTE: There may be uninitialized elements in mf->son.
|
||||
// Valgrind may complain that the "if" below depends on
|
||||
// an uninitialized value. In this case it is safe to ignore
|
||||
// the warning. See also the comments in lz_encoder_init()
|
||||
// in lz_encoder.c.
|
||||
if (mf->son[i] <= subvalue)
|
||||
mf->son[i] = EMPTY_HASH_VALUE;
|
||||
else
|
||||
mf->son[i] -= subvalue;
|
||||
}
|
||||
|
||||
// Update offset to match the new locations.
|
||||
mf->offset -= subvalue;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/// Mark the current byte as processed from point of view of the match finder.
|
||||
static void
|
||||
move_pos(lzma_mf *mf)
|
||||
{
|
||||
if (++mf->cyclic_pos == mf->cyclic_size)
|
||||
mf->cyclic_pos = 0;
|
||||
|
||||
++mf->read_pos;
|
||||
assert(mf->read_pos <= mf->write_pos);
|
||||
|
||||
if (unlikely(mf->read_pos + mf->offset == UINT32_MAX))
|
||||
normalize(mf);
|
||||
}
|
||||
|
||||
|
||||
/// When flushing, we cannot run the match finder unless there is nice_len
|
||||
/// bytes available in the dictionary. Instead, we skip running the match
|
||||
/// finder (indicating that no match was found), and count how many bytes we
|
||||
/// have ignored this way.
|
||||
///
|
||||
/// When new data is given after the flushing was completed, the match finder
|
||||
/// is restarted by rewinding mf->read_pos backwards by mf->pending. Then
|
||||
/// the missed bytes are added to the hash using the match finder's skip
|
||||
/// function (with small amount of input, it may start using mf->pending
|
||||
/// again if flushing).
|
||||
///
|
||||
/// Due to this rewinding, we don't touch cyclic_pos or test for
|
||||
/// normalization. It will be done when the match finder's skip function
|
||||
/// catches up after a flush.
|
||||
static void
|
||||
move_pending(lzma_mf *mf)
|
||||
{
|
||||
++mf->read_pos;
|
||||
assert(mf->read_pos <= mf->write_pos);
|
||||
++mf->pending;
|
||||
}
|
||||
|
||||
|
||||
/// Calculate len_limit and determine if there is enough input to run
|
||||
/// the actual match finder code. Sets up "cur" and "pos". This macro
|
||||
/// is used by all find functions and binary tree skip functions. Hash
|
||||
/// chain skip function doesn't need len_limit so a simpler code is used
|
||||
/// in them.
|
||||
#define header(is_bt, len_min, ret_op) \
|
||||
uint32_t len_limit = mf_avail(mf); \
|
||||
if (mf->nice_len <= len_limit) { \
|
||||
len_limit = mf->nice_len; \
|
||||
} else if (len_limit < (len_min) \
|
||||
|| (is_bt && mf->action == LZMA_SYNC_FLUSH)) { \
|
||||
assert(mf->action != LZMA_RUN); \
|
||||
move_pending(mf); \
|
||||
ret_op; \
|
||||
} \
|
||||
const uint8_t *cur = mf_ptr(mf); \
|
||||
const uint32_t pos = mf->read_pos + mf->offset
|
||||
|
||||
|
||||
/// Header for find functions. "return 0" indicates that zero matches
|
||||
/// were found.
|
||||
#define header_find(is_bt, len_min) \
|
||||
header(is_bt, len_min, return 0); \
|
||||
uint32_t matches_count = 0
|
||||
|
||||
|
||||
/// Header for a loop in a skip function. "continue" tells to skip the rest
|
||||
/// of the code in the loop.
|
||||
#define header_skip(is_bt, len_min) \
|
||||
header(is_bt, len_min, continue)
|
||||
|
||||
|
||||
/// Calls hc_find_func() or bt_find_func() and calculates the total number
|
||||
/// of matches found. Updates the dictionary position and returns the number
|
||||
/// of matches found.
|
||||
#define call_find(func, len_best) \
|
||||
do { \
|
||||
matches_count = func(len_limit, pos, cur, cur_match, mf->depth, \
|
||||
mf->son, mf->cyclic_pos, mf->cyclic_size, \
|
||||
matches + matches_count, len_best) \
|
||||
- matches; \
|
||||
move_pos(mf); \
|
||||
return matches_count; \
|
||||
} while (0)
|
||||
|
||||
|
||||
////////////////
|
||||
// Hash Chain //
|
||||
////////////////
|
||||
|
||||
#if defined(HAVE_MF_HC3) || defined(HAVE_MF_HC4)
|
||||
///
|
||||
///
|
||||
/// \param len_limit Don't look for matches longer than len_limit.
|
||||
/// \param pos lzma_mf.read_pos + lzma_mf.offset
|
||||
/// \param cur Pointer to current byte (mf_ptr(mf))
|
||||
/// \param cur_match Start position of the current match candidate
|
||||
/// \param depth Maximum length of the hash chain
|
||||
/// \param son lzma_mf.son (contains the hash chain)
|
||||
/// \param cyclic_pos
|
||||
/// \param cyclic_size
|
||||
/// \param matches Array to hold the matches.
|
||||
/// \param len_best The length of the longest match found so far.
|
||||
static lzma_match *
|
||||
hc_find_func(
|
||||
const uint32_t len_limit,
|
||||
const uint32_t pos,
|
||||
const uint8_t *const cur,
|
||||
uint32_t cur_match,
|
||||
uint32_t depth,
|
||||
uint32_t *const son,
|
||||
const uint32_t cyclic_pos,
|
||||
const uint32_t cyclic_size,
|
||||
lzma_match *matches,
|
||||
uint32_t len_best)
|
||||
{
|
||||
son[cyclic_pos] = cur_match;
|
||||
|
||||
while (true) {
|
||||
const uint32_t delta = pos - cur_match;
|
||||
if (depth-- == 0 || delta >= cyclic_size)
|
||||
return matches;
|
||||
|
||||
const uint8_t *const pb = cur - delta;
|
||||
cur_match = son[cyclic_pos - delta
|
||||
+ (delta > cyclic_pos ? cyclic_size : 0)];
|
||||
|
||||
if (pb[len_best] == cur[len_best] && pb[0] == cur[0]) {
|
||||
uint32_t len = lzma_memcmplen(pb, cur, 1, len_limit);
|
||||
|
||||
if (len_best < len) {
|
||||
len_best = len;
|
||||
matches->len = len;
|
||||
matches->dist = delta - 1;
|
||||
++matches;
|
||||
|
||||
if (len == len_limit)
|
||||
return matches;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define hc_find(len_best) \
|
||||
call_find(hc_find_func, len_best)
|
||||
|
||||
|
||||
#define hc_skip() \
|
||||
do { \
|
||||
mf->son[mf->cyclic_pos] = cur_match; \
|
||||
move_pos(mf); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_MF_HC3
|
||||
extern uint32_t
|
||||
lzma_mf_hc3_find(lzma_mf *mf, lzma_match *matches)
|
||||
{
|
||||
header_find(false, 3);
|
||||
|
||||
hash_3_calc();
|
||||
|
||||
const uint32_t delta2 = pos - mf->hash[hash_2_value];
|
||||
const uint32_t cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value];
|
||||
|
||||
mf->hash[hash_2_value] = pos;
|
||||
mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
|
||||
|
||||
uint32_t len_best = 2;
|
||||
|
||||
if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
|
||||
len_best = lzma_memcmplen(cur - delta2, cur,
|
||||
len_best, len_limit);
|
||||
|
||||
matches[0].len = len_best;
|
||||
matches[0].dist = delta2 - 1;
|
||||
matches_count = 1;
|
||||
|
||||
if (len_best == len_limit) {
|
||||
hc_skip();
|
||||
return 1; // matches_count
|
||||
}
|
||||
}
|
||||
|
||||
hc_find(len_best);
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lzma_mf_hc3_skip(lzma_mf *mf, uint32_t amount)
|
||||
{
|
||||
do {
|
||||
if (mf_avail(mf) < 3) {
|
||||
move_pending(mf);
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint8_t *cur = mf_ptr(mf);
|
||||
const uint32_t pos = mf->read_pos + mf->offset;
|
||||
|
||||
hash_3_calc();
|
||||
|
||||
const uint32_t cur_match
|
||||
= mf->hash[FIX_3_HASH_SIZE + hash_value];
|
||||
|
||||
mf->hash[hash_2_value] = pos;
|
||||
mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
|
||||
|
||||
hc_skip();
|
||||
|
||||
} while (--amount != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_MF_HC4
|
||||
extern uint32_t
|
||||
lzma_mf_hc4_find(lzma_mf *mf, lzma_match *matches)
|
||||
{
|
||||
header_find(false, 4);
|
||||
|
||||
hash_4_calc();
|
||||
|
||||
uint32_t delta2 = pos - mf->hash[hash_2_value];
|
||||
const uint32_t delta3
|
||||
= pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value];
|
||||
const uint32_t cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value];
|
||||
|
||||
mf->hash[hash_2_value ] = pos;
|
||||
mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
|
||||
mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
|
||||
|
||||
uint32_t len_best = 1;
|
||||
|
||||
if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
|
||||
len_best = 2;
|
||||
matches[0].len = 2;
|
||||
matches[0].dist = delta2 - 1;
|
||||
matches_count = 1;
|
||||
}
|
||||
|
||||
if (delta2 != delta3 && delta3 < mf->cyclic_size
|
||||
&& *(cur - delta3) == *cur) {
|
||||
len_best = 3;
|
||||
matches[matches_count++].dist = delta3 - 1;
|
||||
delta2 = delta3;
|
||||
}
|
||||
|
||||
if (matches_count != 0) {
|
||||
len_best = lzma_memcmplen(cur - delta2, cur,
|
||||
len_best, len_limit);
|
||||
|
||||
matches[matches_count - 1].len = len_best;
|
||||
|
||||
if (len_best == len_limit) {
|
||||
hc_skip();
|
||||
return matches_count;
|
||||
}
|
||||
}
|
||||
|
||||
if (len_best < 3)
|
||||
len_best = 3;
|
||||
|
||||
hc_find(len_best);
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lzma_mf_hc4_skip(lzma_mf *mf, uint32_t amount)
|
||||
{
|
||||
do {
|
||||
if (mf_avail(mf) < 4) {
|
||||
move_pending(mf);
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint8_t *cur = mf_ptr(mf);
|
||||
const uint32_t pos = mf->read_pos + mf->offset;
|
||||
|
||||
hash_4_calc();
|
||||
|
||||
const uint32_t cur_match
|
||||
= mf->hash[FIX_4_HASH_SIZE + hash_value];
|
||||
|
||||
mf->hash[hash_2_value] = pos;
|
||||
mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
|
||||
mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
|
||||
|
||||
hc_skip();
|
||||
|
||||
} while (--amount != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////
|
||||
// Binary Tree //
|
||||
/////////////////
|
||||
|
||||
#if defined(HAVE_MF_BT2) || defined(HAVE_MF_BT3) || defined(HAVE_MF_BT4)
|
||||
static lzma_match *
|
||||
bt_find_func(
|
||||
const uint32_t len_limit,
|
||||
const uint32_t pos,
|
||||
const uint8_t *const cur,
|
||||
uint32_t cur_match,
|
||||
uint32_t depth,
|
||||
uint32_t *const son,
|
||||
const uint32_t cyclic_pos,
|
||||
const uint32_t cyclic_size,
|
||||
lzma_match *matches,
|
||||
uint32_t len_best)
|
||||
{
|
||||
uint32_t *ptr0 = son + (cyclic_pos << 1) + 1;
|
||||
uint32_t *ptr1 = son + (cyclic_pos << 1);
|
||||
|
||||
uint32_t len0 = 0;
|
||||
uint32_t len1 = 0;
|
||||
|
||||
while (true) {
|
||||
const uint32_t delta = pos - cur_match;
|
||||
if (depth-- == 0 || delta >= cyclic_size) {
|
||||
*ptr0 = EMPTY_HASH_VALUE;
|
||||
*ptr1 = EMPTY_HASH_VALUE;
|
||||
return matches;
|
||||
}
|
||||
|
||||
uint32_t *const pair = son + ((cyclic_pos - delta
|
||||
+ (delta > cyclic_pos ? cyclic_size : 0))
|
||||
<< 1);
|
||||
|
||||
const uint8_t *const pb = cur - delta;
|
||||
uint32_t len = my_min(len0, len1);
|
||||
|
||||
if (pb[len] == cur[len]) {
|
||||
len = lzma_memcmplen(pb, cur, len + 1, len_limit);
|
||||
|
||||
if (len_best < len) {
|
||||
len_best = len;
|
||||
matches->len = len;
|
||||
matches->dist = delta - 1;
|
||||
++matches;
|
||||
|
||||
if (len == len_limit) {
|
||||
*ptr1 = pair[0];
|
||||
*ptr0 = pair[1];
|
||||
return matches;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pb[len] < cur[len]) {
|
||||
*ptr1 = cur_match;
|
||||
ptr1 = pair + 1;
|
||||
cur_match = *ptr1;
|
||||
len1 = len;
|
||||
} else {
|
||||
*ptr0 = cur_match;
|
||||
ptr0 = pair;
|
||||
cur_match = *ptr0;
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
bt_skip_func(
|
||||
const uint32_t len_limit,
|
||||
const uint32_t pos,
|
||||
const uint8_t *const cur,
|
||||
uint32_t cur_match,
|
||||
uint32_t depth,
|
||||
uint32_t *const son,
|
||||
const uint32_t cyclic_pos,
|
||||
const uint32_t cyclic_size)
|
||||
{
|
||||
uint32_t *ptr0 = son + (cyclic_pos << 1) + 1;
|
||||
uint32_t *ptr1 = son + (cyclic_pos << 1);
|
||||
|
||||
uint32_t len0 = 0;
|
||||
uint32_t len1 = 0;
|
||||
|
||||
while (true) {
|
||||
const uint32_t delta = pos - cur_match;
|
||||
if (depth-- == 0 || delta >= cyclic_size) {
|
||||
*ptr0 = EMPTY_HASH_VALUE;
|
||||
*ptr1 = EMPTY_HASH_VALUE;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t *pair = son + ((cyclic_pos - delta
|
||||
+ (delta > cyclic_pos ? cyclic_size : 0))
|
||||
<< 1);
|
||||
const uint8_t *pb = cur - delta;
|
||||
uint32_t len = my_min(len0, len1);
|
||||
|
||||
if (pb[len] == cur[len]) {
|
||||
len = lzma_memcmplen(pb, cur, len + 1, len_limit);
|
||||
|
||||
if (len == len_limit) {
|
||||
*ptr1 = pair[0];
|
||||
*ptr0 = pair[1];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (pb[len] < cur[len]) {
|
||||
*ptr1 = cur_match;
|
||||
ptr1 = pair + 1;
|
||||
cur_match = *ptr1;
|
||||
len1 = len;
|
||||
} else {
|
||||
*ptr0 = cur_match;
|
||||
ptr0 = pair;
|
||||
cur_match = *ptr0;
|
||||
len0 = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define bt_find(len_best) \
|
||||
call_find(bt_find_func, len_best)
|
||||
|
||||
#define bt_skip() \
|
||||
do { \
|
||||
bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, \
|
||||
mf->son, mf->cyclic_pos, \
|
||||
mf->cyclic_size); \
|
||||
move_pos(mf); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_MF_BT2
|
||||
extern uint32_t
|
||||
lzma_mf_bt2_find(lzma_mf *mf, lzma_match *matches)
|
||||
{
|
||||
header_find(true, 2);
|
||||
|
||||
hash_2_calc();
|
||||
|
||||
const uint32_t cur_match = mf->hash[hash_value];
|
||||
mf->hash[hash_value] = pos;
|
||||
|
||||
bt_find(1);
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lzma_mf_bt2_skip(lzma_mf *mf, uint32_t amount)
|
||||
{
|
||||
do {
|
||||
header_skip(true, 2);
|
||||
|
||||
hash_2_calc();
|
||||
|
||||
const uint32_t cur_match = mf->hash[hash_value];
|
||||
mf->hash[hash_value] = pos;
|
||||
|
||||
bt_skip();
|
||||
|
||||
} while (--amount != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_MF_BT3
|
||||
extern uint32_t
|
||||
lzma_mf_bt3_find(lzma_mf *mf, lzma_match *matches)
|
||||
{
|
||||
header_find(true, 3);
|
||||
|
||||
hash_3_calc();
|
||||
|
||||
const uint32_t delta2 = pos - mf->hash[hash_2_value];
|
||||
const uint32_t cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value];
|
||||
|
||||
mf->hash[hash_2_value] = pos;
|
||||
mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
|
||||
|
||||
uint32_t len_best = 2;
|
||||
|
||||
if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
|
||||
len_best = lzma_memcmplen(
|
||||
cur, cur - delta2, len_best, len_limit);
|
||||
|
||||
matches[0].len = len_best;
|
||||
matches[0].dist = delta2 - 1;
|
||||
matches_count = 1;
|
||||
|
||||
if (len_best == len_limit) {
|
||||
bt_skip();
|
||||
return 1; // matches_count
|
||||
}
|
||||
}
|
||||
|
||||
bt_find(len_best);
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lzma_mf_bt3_skip(lzma_mf *mf, uint32_t amount)
|
||||
{
|
||||
do {
|
||||
header_skip(true, 3);
|
||||
|
||||
hash_3_calc();
|
||||
|
||||
const uint32_t cur_match
|
||||
= mf->hash[FIX_3_HASH_SIZE + hash_value];
|
||||
|
||||
mf->hash[hash_2_value] = pos;
|
||||
mf->hash[FIX_3_HASH_SIZE + hash_value] = pos;
|
||||
|
||||
bt_skip();
|
||||
|
||||
} while (--amount != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_MF_BT4
|
||||
extern uint32_t
|
||||
lzma_mf_bt4_find(lzma_mf *mf, lzma_match *matches)
|
||||
{
|
||||
header_find(true, 4);
|
||||
|
||||
hash_4_calc();
|
||||
|
||||
uint32_t delta2 = pos - mf->hash[hash_2_value];
|
||||
const uint32_t delta3
|
||||
= pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value];
|
||||
const uint32_t cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value];
|
||||
|
||||
mf->hash[hash_2_value] = pos;
|
||||
mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
|
||||
mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
|
||||
|
||||
uint32_t len_best = 1;
|
||||
|
||||
if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) {
|
||||
len_best = 2;
|
||||
matches[0].len = 2;
|
||||
matches[0].dist = delta2 - 1;
|
||||
matches_count = 1;
|
||||
}
|
||||
|
||||
if (delta2 != delta3 && delta3 < mf->cyclic_size
|
||||
&& *(cur - delta3) == *cur) {
|
||||
len_best = 3;
|
||||
matches[matches_count++].dist = delta3 - 1;
|
||||
delta2 = delta3;
|
||||
}
|
||||
|
||||
if (matches_count != 0) {
|
||||
len_best = lzma_memcmplen(
|
||||
cur, cur - delta2, len_best, len_limit);
|
||||
|
||||
matches[matches_count - 1].len = len_best;
|
||||
|
||||
if (len_best == len_limit) {
|
||||
bt_skip();
|
||||
return matches_count;
|
||||
}
|
||||
}
|
||||
|
||||
if (len_best < 3)
|
||||
len_best = 3;
|
||||
|
||||
bt_find(len_best);
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lzma_mf_bt4_skip(lzma_mf *mf, uint32_t amount)
|
||||
{
|
||||
do {
|
||||
header_skip(true, 4);
|
||||
|
||||
hash_4_calc();
|
||||
|
||||
const uint32_t cur_match
|
||||
= mf->hash[FIX_4_HASH_SIZE + hash_value];
|
||||
|
||||
mf->hash[hash_2_value] = pos;
|
||||
mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos;
|
||||
mf->hash[FIX_4_HASH_SIZE + hash_value] = pos;
|
||||
|
||||
bt_skip();
|
||||
|
||||
} while (--amount != 0);
|
||||
}
|
||||
#endif
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file fastpos.h
|
||||
/// \brief Kind of two-bit version of bit scan reverse
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_FASTPOS_H
|
||||
#define LZMA_FASTPOS_H
|
||||
|
||||
// LZMA encodes match distances by storing the highest two bits using
|
||||
// a six-bit value [0, 63], and then the missing lower bits.
|
||||
// Dictionary size is also stored using this encoding in the .xz
|
||||
// file format header.
|
||||
//
|
||||
// fastpos.h provides a way to quickly find out the correct six-bit
|
||||
// values. The following table gives some examples of this encoding:
|
||||
//
|
||||
// dist return
|
||||
// 0 0
|
||||
// 1 1
|
||||
// 2 2
|
||||
// 3 3
|
||||
// 4 4
|
||||
// 5 4
|
||||
// 6 5
|
||||
// 7 5
|
||||
// 8 6
|
||||
// 11 6
|
||||
// 12 7
|
||||
// ... ...
|
||||
// 15 7
|
||||
// 16 8
|
||||
// 17 8
|
||||
// ... ...
|
||||
// 23 8
|
||||
// 24 9
|
||||
// 25 9
|
||||
// ... ...
|
||||
//
|
||||
//
|
||||
// Provided functions or macros
|
||||
// ----------------------------
|
||||
//
|
||||
// get_dist_slot(dist) is the basic version. get_dist_slot_2(dist)
|
||||
// assumes that dist >= FULL_DISTANCES, thus the result is at least
|
||||
// FULL_DISTANCES_BITS * 2. Using get_dist_slot(dist) instead of
|
||||
// get_dist_slot_2(dist) would give the same result, but get_dist_slot_2(dist)
|
||||
// should be tiny bit faster due to the assumption being made.
|
||||
//
|
||||
//
|
||||
// Size vs. speed
|
||||
// --------------
|
||||
//
|
||||
// With some CPUs that have fast BSR (bit scan reverse) instruction, the
|
||||
// size optimized version is slightly faster than the bigger table based
|
||||
// approach. Such CPUs include Intel Pentium Pro, Pentium II, Pentium III
|
||||
// and Core 2 (possibly others). AMD K7 seems to have slower BSR, but that
|
||||
// would still have speed roughly comparable to the table version. Older
|
||||
// x86 CPUs like the original Pentium have very slow BSR; on those systems
|
||||
// the table version is a lot faster.
|
||||
//
|
||||
// On some CPUs, the table version is a lot faster when using position
|
||||
// dependent code, but with position independent code the size optimized
|
||||
// version is slightly faster. This occurs at least on 32-bit SPARC (no
|
||||
// ASM optimizations).
|
||||
//
|
||||
// I'm making the table version the default, because that has good speed
|
||||
// on all systems I have tried. The size optimized version is sometimes
|
||||
// slightly faster, but sometimes it is a lot slower.
|
||||
|
||||
#ifdef HAVE_SMALL
|
||||
# define get_dist_slot(dist) \
|
||||
((dist) <= 4 ? (dist) : get_dist_slot_2(dist))
|
||||
|
||||
static inline uint32_t
|
||||
get_dist_slot_2(uint32_t dist)
|
||||
{
|
||||
const uint32_t i = bsr32(dist);
|
||||
return (i + i) + ((dist >> (i - 1)) & 1);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#define FASTPOS_BITS 13
|
||||
|
||||
extern const uint8_t lzma_fastpos[1 << FASTPOS_BITS];
|
||||
|
||||
|
||||
#define fastpos_shift(extra, n) \
|
||||
((extra) + (n) * (FASTPOS_BITS - 1))
|
||||
|
||||
#define fastpos_limit(extra, n) \
|
||||
(UINT32_C(1) << (FASTPOS_BITS + fastpos_shift(extra, n)))
|
||||
|
||||
#define fastpos_result(dist, extra, n) \
|
||||
lzma_fastpos[(dist) >> fastpos_shift(extra, n)] \
|
||||
+ 2 * fastpos_shift(extra, n)
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
get_dist_slot(uint32_t dist)
|
||||
{
|
||||
// If it is small enough, we can pick the result directly from
|
||||
// the precalculated table.
|
||||
if (dist < fastpos_limit(0, 0))
|
||||
return lzma_fastpos[dist];
|
||||
|
||||
if (dist < fastpos_limit(0, 1))
|
||||
return fastpos_result(dist, 0, 1);
|
||||
|
||||
return fastpos_result(dist, 0, 2);
|
||||
}
|
||||
|
||||
|
||||
#ifdef FULL_DISTANCES_BITS
|
||||
static inline uint32_t
|
||||
get_dist_slot_2(uint32_t dist)
|
||||
{
|
||||
assert(dist >= FULL_DISTANCES);
|
||||
|
||||
if (dist < fastpos_limit(FULL_DISTANCES_BITS - 1, 0))
|
||||
return fastpos_result(dist, FULL_DISTANCES_BITS - 1, 0);
|
||||
|
||||
if (dist < fastpos_limit(FULL_DISTANCES_BITS - 1, 1))
|
||||
return fastpos_result(dist, FULL_DISTANCES_BITS - 1, 1);
|
||||
|
||||
return fastpos_result(dist, FULL_DISTANCES_BITS - 1, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+519
@@ -0,0 +1,519 @@
|
||||
/* This file has been automatically generated by fastpos_tablegen.c. */
|
||||
|
||||
#include "common.h"
|
||||
#include "fastpos.h"
|
||||
|
||||
const uint8_t lzma_fastpos[1 << FASTPOS_BITS] = {
|
||||
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
|
||||
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lzma2_encoder.h
|
||||
/// \brief LZMA2 encoder
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_LZMA2_ENCODER_H
|
||||
#define LZMA_LZMA2_ENCODER_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/// Maximum number of bytes of actual data per chunk (no headers)
|
||||
#define LZMA2_CHUNK_MAX (UINT32_C(1) << 16)
|
||||
|
||||
/// Maximum uncompressed size of LZMA chunk (no headers)
|
||||
#define LZMA2_UNCOMPRESSED_MAX (UINT32_C(1) << 21)
|
||||
|
||||
/// Maximum size of LZMA2 headers
|
||||
#define LZMA2_HEADER_MAX 6
|
||||
|
||||
/// Size of a header for uncompressed chunk
|
||||
#define LZMA2_HEADER_UNCOMPRESSED 3
|
||||
|
||||
|
||||
extern lzma_ret lzma_lzma2_encoder_init(
|
||||
lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
extern uint64_t lzma_lzma2_encoder_memusage(const void *options);
|
||||
|
||||
extern lzma_ret lzma_lzma2_props_encode(const void *options, uint8_t *out);
|
||||
|
||||
extern uint64_t lzma_lzma2_block_size(const void *options);
|
||||
|
||||
#endif
|
||||
+224
@@ -0,0 +1,224 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lzma_common.h
|
||||
/// \brief Private definitions common to LZMA encoder and decoder
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_LZMA_COMMON_H
|
||||
#define LZMA_LZMA_COMMON_H
|
||||
|
||||
#include "common.h"
|
||||
#include "range_common.h"
|
||||
|
||||
|
||||
///////////////////
|
||||
// Miscellaneous //
|
||||
///////////////////
|
||||
|
||||
/// Maximum number of position states. A position state is the lowest pos bits
|
||||
/// number of bits of the current uncompressed offset. In some places there
|
||||
/// are different sets of probabilities for different pos states.
|
||||
#define POS_STATES_MAX (1 << LZMA_PB_MAX)
|
||||
|
||||
|
||||
/// Validates lc, lp, and pb.
|
||||
static inline bool
|
||||
is_lclppb_valid(const lzma_options_lzma *options)
|
||||
{
|
||||
return options->lc <= LZMA_LCLP_MAX && options->lp <= LZMA_LCLP_MAX
|
||||
&& options->lc + options->lp <= LZMA_LCLP_MAX
|
||||
&& options->pb <= LZMA_PB_MAX;
|
||||
}
|
||||
|
||||
|
||||
///////////
|
||||
// State //
|
||||
///////////
|
||||
|
||||
/// This enum is used to track which events have occurred most recently and
|
||||
/// in which order. This information is used to predict the next event.
|
||||
///
|
||||
/// Events:
|
||||
/// - Literal: One 8-bit byte
|
||||
/// - Match: Repeat a chunk of data at some distance
|
||||
/// - Long repeat: Multi-byte match at a recently seen distance
|
||||
/// - Short repeat: One-byte repeat at a recently seen distance
|
||||
///
|
||||
/// The event names are in from STATE_oldest_older_previous. REP means
|
||||
/// either short or long repeated match, and NONLIT means any non-literal.
|
||||
typedef enum {
|
||||
STATE_LIT_LIT,
|
||||
STATE_MATCH_LIT_LIT,
|
||||
STATE_REP_LIT_LIT,
|
||||
STATE_SHORTREP_LIT_LIT,
|
||||
STATE_MATCH_LIT,
|
||||
STATE_REP_LIT,
|
||||
STATE_SHORTREP_LIT,
|
||||
STATE_LIT_MATCH,
|
||||
STATE_LIT_LONGREP,
|
||||
STATE_LIT_SHORTREP,
|
||||
STATE_NONLIT_MATCH,
|
||||
STATE_NONLIT_REP,
|
||||
} lzma_lzma_state;
|
||||
|
||||
|
||||
/// Total number of states
|
||||
#define STATES 12
|
||||
|
||||
/// The lowest 7 states indicate that the previous state was a literal.
|
||||
#define LIT_STATES 7
|
||||
|
||||
|
||||
/// Indicate that the latest state was a literal.
|
||||
#define update_literal(state) \
|
||||
state = ((state) <= STATE_SHORTREP_LIT_LIT \
|
||||
? STATE_LIT_LIT \
|
||||
: ((state) <= STATE_LIT_SHORTREP \
|
||||
? (state) - 3 \
|
||||
: (state) - 6))
|
||||
|
||||
/// Indicate that the latest state was a match.
|
||||
#define update_match(state) \
|
||||
state = ((state) < LIT_STATES ? STATE_LIT_MATCH : STATE_NONLIT_MATCH)
|
||||
|
||||
/// Indicate that the latest state was a long repeated match.
|
||||
#define update_long_rep(state) \
|
||||
state = ((state) < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP)
|
||||
|
||||
/// Indicate that the latest state was a short match.
|
||||
#define update_short_rep(state) \
|
||||
state = ((state) < LIT_STATES ? STATE_LIT_SHORTREP : STATE_NONLIT_REP)
|
||||
|
||||
/// Test if the previous state was a literal.
|
||||
#define is_literal_state(state) \
|
||||
((state) < LIT_STATES)
|
||||
|
||||
|
||||
/////////////
|
||||
// Literal //
|
||||
/////////////
|
||||
|
||||
/// Each literal coder is divided in three sections:
|
||||
/// - 0x001-0x0FF: Without match byte
|
||||
/// - 0x101-0x1FF: With match byte; match bit is 0
|
||||
/// - 0x201-0x2FF: With match byte; match bit is 1
|
||||
///
|
||||
/// Match byte is used when the previous LZMA symbol was something else than
|
||||
/// a literal (that is, it was some kind of match).
|
||||
#define LITERAL_CODER_SIZE 0x300
|
||||
|
||||
/// Maximum number of literal coders
|
||||
#define LITERAL_CODERS_MAX (1 << LZMA_LCLP_MAX)
|
||||
|
||||
/// Locate the literal coder for the next literal byte. The choice depends on
|
||||
/// - the lowest literal_pos_bits bits of the position of the current
|
||||
/// byte; and
|
||||
/// - the highest literal_context_bits bits of the previous byte.
|
||||
#define literal_subcoder(probs, lc, lp_mask, pos, prev_byte) \
|
||||
((probs)[(((pos) & lp_mask) << lc) + ((prev_byte) >> (8 - lc))])
|
||||
|
||||
|
||||
static inline void
|
||||
literal_init(probability (*probs)[LITERAL_CODER_SIZE],
|
||||
uint32_t lc, uint32_t lp)
|
||||
{
|
||||
assert(lc + lp <= LZMA_LCLP_MAX);
|
||||
|
||||
const uint32_t coders = 1U << (lc + lp);
|
||||
|
||||
for (uint32_t i = 0; i < coders; ++i)
|
||||
for (uint32_t j = 0; j < LITERAL_CODER_SIZE; ++j)
|
||||
bit_reset(probs[i][j]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//////////////////
|
||||
// Match length //
|
||||
//////////////////
|
||||
|
||||
// Minimum length of a match is two bytes.
|
||||
#define MATCH_LEN_MIN 2
|
||||
|
||||
// Match length is encoded with 4, 5, or 10 bits.
|
||||
//
|
||||
// Length Bits
|
||||
// 2-9 4 = Choice=0 + 3 bits
|
||||
// 10-17 5 = Choice=1 + Choice2=0 + 3 bits
|
||||
// 18-273 10 = Choice=1 + Choice2=1 + 8 bits
|
||||
#define LEN_LOW_BITS 3
|
||||
#define LEN_LOW_SYMBOLS (1 << LEN_LOW_BITS)
|
||||
#define LEN_MID_BITS 3
|
||||
#define LEN_MID_SYMBOLS (1 << LEN_MID_BITS)
|
||||
#define LEN_HIGH_BITS 8
|
||||
#define LEN_HIGH_SYMBOLS (1 << LEN_HIGH_BITS)
|
||||
#define LEN_SYMBOLS (LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS + LEN_HIGH_SYMBOLS)
|
||||
|
||||
// Maximum length of a match is 273 which is a result of the encoding
|
||||
// described above.
|
||||
#define MATCH_LEN_MAX (MATCH_LEN_MIN + LEN_SYMBOLS - 1)
|
||||
|
||||
|
||||
////////////////////
|
||||
// Match distance //
|
||||
////////////////////
|
||||
|
||||
// Different sets of probabilities are used for match distances that have very
|
||||
// short match length: Lengths of 2, 3, and 4 bytes have a separate set of
|
||||
// probabilities for each length. The matches with longer length use a shared
|
||||
// set of probabilities.
|
||||
#define DIST_STATES 4
|
||||
|
||||
// Macro to get the index of the appropriate probability array.
|
||||
#define get_dist_state(len) \
|
||||
((len) < DIST_STATES + MATCH_LEN_MIN \
|
||||
? (len) - MATCH_LEN_MIN \
|
||||
: DIST_STATES - 1)
|
||||
|
||||
// The highest two bits of a match distance (distance slot) are encoded
|
||||
// using six bits. See fastpos.h for more explanation.
|
||||
#define DIST_SLOT_BITS 6
|
||||
#define DIST_SLOTS (1 << DIST_SLOT_BITS)
|
||||
|
||||
// Match distances up to 127 are fully encoded using probabilities. Since
|
||||
// the highest two bits (distance slot) are always encoded using six bits,
|
||||
// the distances 0-3 don't need any additional bits to encode, since the
|
||||
// distance slot itself is the same as the actual distance. DIST_MODEL_START
|
||||
// indicates the first distance slot where at least one additional bit is
|
||||
// needed.
|
||||
#define DIST_MODEL_START 4
|
||||
|
||||
// Match distances greater than 127 are encoded in three pieces:
|
||||
// - distance slot: the highest two bits
|
||||
// - direct bits: 2-26 bits below the highest two bits
|
||||
// - alignment bits: four lowest bits
|
||||
//
|
||||
// Direct bits don't use any probabilities.
|
||||
//
|
||||
// The distance slot value of 14 is for distances 128-191 (see the table in
|
||||
// fastpos.h to understand why).
|
||||
#define DIST_MODEL_END 14
|
||||
|
||||
// Distance slots that indicate a distance <= 127.
|
||||
#define FULL_DISTANCES_BITS (DIST_MODEL_END / 2)
|
||||
#define FULL_DISTANCES (1 << FULL_DISTANCES_BITS)
|
||||
|
||||
// For match distances greater than 127, only the highest two bits and the
|
||||
// lowest four bits (alignment) is encoded using probabilities.
|
||||
#define ALIGN_BITS 4
|
||||
#define ALIGN_SIZE (1 << ALIGN_BITS)
|
||||
#define ALIGN_MASK (ALIGN_SIZE - 1)
|
||||
|
||||
// LZMA remembers the four most recent match distances. Reusing these distances
|
||||
// tends to take less space than re-encoding the actual distance value.
|
||||
#define REPS 4
|
||||
|
||||
#endif
|
||||
+1058
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,53 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lzma_decoder.h
|
||||
/// \brief LZMA decoder API
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_LZMA_DECODER_H
|
||||
#define LZMA_LZMA_DECODER_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/// Allocates and initializes LZMA decoder
|
||||
extern lzma_ret lzma_lzma_decoder_init(lzma_next_coder *next,
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
extern uint64_t lzma_lzma_decoder_memusage(const void *options);
|
||||
|
||||
extern lzma_ret lzma_lzma_props_decode(
|
||||
void **options, const lzma_allocator *allocator,
|
||||
const uint8_t *props, size_t props_size);
|
||||
|
||||
|
||||
/// \brief Decodes the LZMA Properties byte (lc/lp/pb)
|
||||
///
|
||||
/// \return true if error occurred, false on success
|
||||
///
|
||||
extern bool lzma_lzma_lclppb_decode(
|
||||
lzma_options_lzma *options, uint8_t byte);
|
||||
|
||||
|
||||
#ifdef LZMA_LZ_DECODER_H
|
||||
/// Allocate and setup function pointers only. This is used by LZMA1 and
|
||||
/// LZMA2 decoders.
|
||||
extern lzma_ret lzma_lzma_decoder_create(
|
||||
lzma_lz_decoder *lz, const lzma_allocator *allocator,
|
||||
const void *opt, lzma_lz_options *lz_options);
|
||||
|
||||
/// Gets memory usage without validating lc/lp/pb. This is used by LZMA2
|
||||
/// decoder, because raw LZMA2 decoding doesn't need lc/lp/pb.
|
||||
extern uint64_t lzma_lzma_decoder_memusage_nocheck(const void *options);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+677
@@ -0,0 +1,677 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lzma_encoder.c
|
||||
/// \brief LZMA encoder
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "lzma2_encoder.h"
|
||||
#include "lzma_encoder_private.h"
|
||||
#include "fastpos.h"
|
||||
|
||||
|
||||
/////////////
|
||||
// Literal //
|
||||
/////////////
|
||||
|
||||
static inline void
|
||||
literal_matched(lzma_range_encoder *rc, probability *subcoder,
|
||||
uint32_t match_byte, uint32_t symbol)
|
||||
{
|
||||
uint32_t offset = 0x100;
|
||||
symbol += UINT32_C(1) << 8;
|
||||
|
||||
do {
|
||||
match_byte <<= 1;
|
||||
const uint32_t match_bit = match_byte & offset;
|
||||
const uint32_t subcoder_index
|
||||
= offset + match_bit + (symbol >> 8);
|
||||
const uint32_t bit = (symbol >> 7) & 1;
|
||||
rc_bit(rc, &subcoder[subcoder_index], bit);
|
||||
|
||||
symbol <<= 1;
|
||||
offset &= ~(match_byte ^ symbol);
|
||||
|
||||
} while (symbol < (UINT32_C(1) << 16));
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
literal(lzma_lzma1_encoder *coder, lzma_mf *mf, uint32_t position)
|
||||
{
|
||||
// Locate the literal byte to be encoded and the subcoder.
|
||||
const uint8_t cur_byte = mf->buffer[
|
||||
mf->read_pos - mf->read_ahead];
|
||||
probability *subcoder = literal_subcoder(coder->literal,
|
||||
coder->literal_context_bits, coder->literal_pos_mask,
|
||||
position, mf->buffer[mf->read_pos - mf->read_ahead - 1]);
|
||||
|
||||
if (is_literal_state(coder->state)) {
|
||||
// Previous LZMA-symbol was a literal. Encode a normal
|
||||
// literal without a match byte.
|
||||
rc_bittree(&coder->rc, subcoder, 8, cur_byte);
|
||||
} else {
|
||||
// Previous LZMA-symbol was a match. Use the last byte of
|
||||
// the match as a "match byte". That is, compare the bits
|
||||
// of the current literal and the match byte.
|
||||
const uint8_t match_byte = mf->buffer[
|
||||
mf->read_pos - coder->reps[0] - 1
|
||||
- mf->read_ahead];
|
||||
literal_matched(&coder->rc, subcoder, match_byte, cur_byte);
|
||||
}
|
||||
|
||||
update_literal(coder->state);
|
||||
}
|
||||
|
||||
|
||||
//////////////////
|
||||
// Match length //
|
||||
//////////////////
|
||||
|
||||
static void
|
||||
length_update_prices(lzma_length_encoder *lc, const uint32_t pos_state)
|
||||
{
|
||||
const uint32_t table_size = lc->table_size;
|
||||
lc->counters[pos_state] = table_size;
|
||||
|
||||
const uint32_t a0 = rc_bit_0_price(lc->choice);
|
||||
const uint32_t a1 = rc_bit_1_price(lc->choice);
|
||||
const uint32_t b0 = a1 + rc_bit_0_price(lc->choice2);
|
||||
const uint32_t b1 = a1 + rc_bit_1_price(lc->choice2);
|
||||
uint32_t *const prices = lc->prices[pos_state];
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0; i < table_size && i < LEN_LOW_SYMBOLS; ++i)
|
||||
prices[i] = a0 + rc_bittree_price(lc->low[pos_state],
|
||||
LEN_LOW_BITS, i);
|
||||
|
||||
for (; i < table_size && i < LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; ++i)
|
||||
prices[i] = b0 + rc_bittree_price(lc->mid[pos_state],
|
||||
LEN_MID_BITS, i - LEN_LOW_SYMBOLS);
|
||||
|
||||
for (; i < table_size; ++i)
|
||||
prices[i] = b1 + rc_bittree_price(lc->high, LEN_HIGH_BITS,
|
||||
i - LEN_LOW_SYMBOLS - LEN_MID_SYMBOLS);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
length(lzma_range_encoder *rc, lzma_length_encoder *lc,
|
||||
const uint32_t pos_state, uint32_t len, const bool fast_mode)
|
||||
{
|
||||
assert(len <= MATCH_LEN_MAX);
|
||||
len -= MATCH_LEN_MIN;
|
||||
|
||||
if (len < LEN_LOW_SYMBOLS) {
|
||||
rc_bit(rc, &lc->choice, 0);
|
||||
rc_bittree(rc, lc->low[pos_state], LEN_LOW_BITS, len);
|
||||
} else {
|
||||
rc_bit(rc, &lc->choice, 1);
|
||||
len -= LEN_LOW_SYMBOLS;
|
||||
|
||||
if (len < LEN_MID_SYMBOLS) {
|
||||
rc_bit(rc, &lc->choice2, 0);
|
||||
rc_bittree(rc, lc->mid[pos_state], LEN_MID_BITS, len);
|
||||
} else {
|
||||
rc_bit(rc, &lc->choice2, 1);
|
||||
len -= LEN_MID_SYMBOLS;
|
||||
rc_bittree(rc, lc->high, LEN_HIGH_BITS, len);
|
||||
}
|
||||
}
|
||||
|
||||
// Only getoptimum uses the prices so don't update the table when
|
||||
// in fast mode.
|
||||
if (!fast_mode)
|
||||
if (--lc->counters[pos_state] == 0)
|
||||
length_update_prices(lc, pos_state);
|
||||
}
|
||||
|
||||
|
||||
///////////
|
||||
// Match //
|
||||
///////////
|
||||
|
||||
static inline void
|
||||
match(lzma_lzma1_encoder *coder, const uint32_t pos_state,
|
||||
const uint32_t distance, const uint32_t len)
|
||||
{
|
||||
update_match(coder->state);
|
||||
|
||||
length(&coder->rc, &coder->match_len_encoder, pos_state, len,
|
||||
coder->fast_mode);
|
||||
|
||||
const uint32_t dist_slot = get_dist_slot(distance);
|
||||
const uint32_t dist_state = get_dist_state(len);
|
||||
rc_bittree(&coder->rc, coder->dist_slot[dist_state],
|
||||
DIST_SLOT_BITS, dist_slot);
|
||||
|
||||
if (dist_slot >= DIST_MODEL_START) {
|
||||
const uint32_t footer_bits = (dist_slot >> 1) - 1;
|
||||
const uint32_t base = (2 | (dist_slot & 1)) << footer_bits;
|
||||
const uint32_t dist_reduced = distance - base;
|
||||
|
||||
if (dist_slot < DIST_MODEL_END) {
|
||||
// Careful here: base - dist_slot - 1 can be -1, but
|
||||
// rc_bittree_reverse starts at probs[1], not probs[0].
|
||||
rc_bittree_reverse(&coder->rc,
|
||||
coder->dist_special + base - dist_slot - 1,
|
||||
footer_bits, dist_reduced);
|
||||
} else {
|
||||
rc_direct(&coder->rc, dist_reduced >> ALIGN_BITS,
|
||||
footer_bits - ALIGN_BITS);
|
||||
rc_bittree_reverse(
|
||||
&coder->rc, coder->dist_align,
|
||||
ALIGN_BITS, dist_reduced & ALIGN_MASK);
|
||||
++coder->align_price_count;
|
||||
}
|
||||
}
|
||||
|
||||
coder->reps[3] = coder->reps[2];
|
||||
coder->reps[2] = coder->reps[1];
|
||||
coder->reps[1] = coder->reps[0];
|
||||
coder->reps[0] = distance;
|
||||
++coder->match_price_count;
|
||||
}
|
||||
|
||||
|
||||
////////////////////
|
||||
// Repeated match //
|
||||
////////////////////
|
||||
|
||||
static inline void
|
||||
rep_match(lzma_lzma1_encoder *coder, const uint32_t pos_state,
|
||||
const uint32_t rep, const uint32_t len)
|
||||
{
|
||||
if (rep == 0) {
|
||||
rc_bit(&coder->rc, &coder->is_rep0[coder->state], 0);
|
||||
rc_bit(&coder->rc,
|
||||
&coder->is_rep0_long[coder->state][pos_state],
|
||||
len != 1);
|
||||
} else {
|
||||
const uint32_t distance = coder->reps[rep];
|
||||
rc_bit(&coder->rc, &coder->is_rep0[coder->state], 1);
|
||||
|
||||
if (rep == 1) {
|
||||
rc_bit(&coder->rc, &coder->is_rep1[coder->state], 0);
|
||||
} else {
|
||||
rc_bit(&coder->rc, &coder->is_rep1[coder->state], 1);
|
||||
rc_bit(&coder->rc, &coder->is_rep2[coder->state],
|
||||
rep - 2);
|
||||
|
||||
if (rep == 3)
|
||||
coder->reps[3] = coder->reps[2];
|
||||
|
||||
coder->reps[2] = coder->reps[1];
|
||||
}
|
||||
|
||||
coder->reps[1] = coder->reps[0];
|
||||
coder->reps[0] = distance;
|
||||
}
|
||||
|
||||
if (len == 1) {
|
||||
update_short_rep(coder->state);
|
||||
} else {
|
||||
length(&coder->rc, &coder->rep_len_encoder, pos_state, len,
|
||||
coder->fast_mode);
|
||||
update_long_rep(coder->state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////
|
||||
// Main //
|
||||
//////////
|
||||
|
||||
static void
|
||||
encode_symbol(lzma_lzma1_encoder *coder, lzma_mf *mf,
|
||||
uint32_t back, uint32_t len, uint32_t position)
|
||||
{
|
||||
const uint32_t pos_state = position & coder->pos_mask;
|
||||
|
||||
if (back == UINT32_MAX) {
|
||||
// Literal i.e. eight-bit byte
|
||||
assert(len == 1);
|
||||
rc_bit(&coder->rc,
|
||||
&coder->is_match[coder->state][pos_state], 0);
|
||||
literal(coder, mf, position);
|
||||
} else {
|
||||
// Some type of match
|
||||
rc_bit(&coder->rc,
|
||||
&coder->is_match[coder->state][pos_state], 1);
|
||||
|
||||
if (back < REPS) {
|
||||
// It's a repeated match i.e. the same distance
|
||||
// has been used earlier.
|
||||
rc_bit(&coder->rc, &coder->is_rep[coder->state], 1);
|
||||
rep_match(coder, pos_state, back, len);
|
||||
} else {
|
||||
// Normal match
|
||||
rc_bit(&coder->rc, &coder->is_rep[coder->state], 0);
|
||||
match(coder, pos_state, back - REPS, len);
|
||||
}
|
||||
}
|
||||
|
||||
assert(mf->read_ahead >= len);
|
||||
mf->read_ahead -= len;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
encode_init(lzma_lzma1_encoder *coder, lzma_mf *mf)
|
||||
{
|
||||
assert(mf_position(mf) == 0);
|
||||
|
||||
if (mf->read_pos == mf->read_limit) {
|
||||
if (mf->action == LZMA_RUN)
|
||||
return false; // We cannot do anything.
|
||||
|
||||
// We are finishing (we cannot get here when flushing).
|
||||
assert(mf->write_pos == mf->read_pos);
|
||||
assert(mf->action == LZMA_FINISH);
|
||||
} else {
|
||||
// Do the actual initialization. The first LZMA symbol must
|
||||
// always be a literal.
|
||||
mf_skip(mf, 1);
|
||||
mf->read_ahead = 0;
|
||||
rc_bit(&coder->rc, &coder->is_match[0][0], 0);
|
||||
rc_bittree(&coder->rc, coder->literal[0], 8, mf->buffer[0]);
|
||||
}
|
||||
|
||||
// Initialization is done (except if empty file).
|
||||
coder->is_initialized = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
encode_eopm(lzma_lzma1_encoder *coder, uint32_t position)
|
||||
{
|
||||
const uint32_t pos_state = position & coder->pos_mask;
|
||||
rc_bit(&coder->rc, &coder->is_match[coder->state][pos_state], 1);
|
||||
rc_bit(&coder->rc, &coder->is_rep[coder->state], 0);
|
||||
match(coder, pos_state, UINT32_MAX, MATCH_LEN_MIN);
|
||||
}
|
||||
|
||||
|
||||
/// Number of bytes that a single encoding loop in lzma_lzma_encode() can
|
||||
/// consume from the dictionary. This limit comes from lzma_lzma_optimum()
|
||||
/// and may need to be updated if that function is significantly modified.
|
||||
#define LOOP_INPUT_MAX (OPTS + 1)
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lzma_encode(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf,
|
||||
uint8_t *restrict out, size_t *restrict out_pos,
|
||||
size_t out_size, uint32_t limit)
|
||||
{
|
||||
// Initialize the stream if no data has been encoded yet.
|
||||
if (!coder->is_initialized && !encode_init(coder, mf))
|
||||
return LZMA_OK;
|
||||
|
||||
// Get the lowest bits of the uncompressed offset from the LZ layer.
|
||||
uint32_t position = mf_position(mf);
|
||||
|
||||
while (true) {
|
||||
// Encode pending bits, if any. Calling this before encoding
|
||||
// the next symbol is needed only with plain LZMA, since
|
||||
// LZMA2 always provides big enough buffer to flush
|
||||
// everything out from the range encoder. For the same reason,
|
||||
// rc_encode() never returns true when this function is used
|
||||
// as part of LZMA2 encoder.
|
||||
if (rc_encode(&coder->rc, out, out_pos, out_size)) {
|
||||
assert(limit == UINT32_MAX);
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
// With LZMA2 we need to take care that compressed size of
|
||||
// a chunk doesn't get too big.
|
||||
// FIXME? Check if this could be improved.
|
||||
if (limit != UINT32_MAX
|
||||
&& (mf->read_pos - mf->read_ahead >= limit
|
||||
|| *out_pos + rc_pending(&coder->rc)
|
||||
>= LZMA2_CHUNK_MAX
|
||||
- LOOP_INPUT_MAX))
|
||||
break;
|
||||
|
||||
// Check that there is some input to process.
|
||||
if (mf->read_pos >= mf->read_limit) {
|
||||
if (mf->action == LZMA_RUN)
|
||||
return LZMA_OK;
|
||||
|
||||
if (mf->read_ahead == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Get optimal match (repeat position and length).
|
||||
// Value ranges for pos:
|
||||
// - [0, REPS): repeated match
|
||||
// - [REPS, UINT32_MAX):
|
||||
// match at (pos - REPS)
|
||||
// - UINT32_MAX: not a match but a literal
|
||||
// Value ranges for len:
|
||||
// - [MATCH_LEN_MIN, MATCH_LEN_MAX]
|
||||
uint32_t len;
|
||||
uint32_t back;
|
||||
|
||||
if (coder->fast_mode)
|
||||
lzma_lzma_optimum_fast(coder, mf, &back, &len);
|
||||
else
|
||||
lzma_lzma_optimum_normal(
|
||||
coder, mf, &back, &len, position);
|
||||
|
||||
encode_symbol(coder, mf, back, len, position);
|
||||
|
||||
position += len;
|
||||
}
|
||||
|
||||
if (!coder->is_flushed) {
|
||||
coder->is_flushed = true;
|
||||
|
||||
// We don't support encoding plain LZMA streams without EOPM,
|
||||
// and LZMA2 doesn't use EOPM at LZMA level.
|
||||
if (limit == UINT32_MAX)
|
||||
encode_eopm(coder, position);
|
||||
|
||||
// Flush the remaining bytes from the range encoder.
|
||||
rc_flush(&coder->rc);
|
||||
|
||||
// Copy the remaining bytes to the output buffer. If there
|
||||
// isn't enough output space, we will copy out the remaining
|
||||
// bytes on the next call to this function by using
|
||||
// the rc_encode() call in the encoding loop above.
|
||||
if (rc_encode(&coder->rc, out, out_pos, out_size)) {
|
||||
assert(limit == UINT32_MAX);
|
||||
return LZMA_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Make it ready for the next LZMA2 chunk.
|
||||
coder->is_flushed = false;
|
||||
|
||||
return LZMA_STREAM_END;
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
lzma_encode(void *coder, lzma_mf *restrict mf,
|
||||
uint8_t *restrict out, size_t *restrict out_pos,
|
||||
size_t out_size)
|
||||
{
|
||||
// Plain LZMA has no support for sync-flushing.
|
||||
if (unlikely(mf->action == LZMA_SYNC_FLUSH))
|
||||
return LZMA_OPTIONS_ERROR;
|
||||
|
||||
return lzma_lzma_encode(coder, mf, out, out_pos, out_size, UINT32_MAX);
|
||||
}
|
||||
|
||||
|
||||
////////////////////
|
||||
// Initialization //
|
||||
////////////////////
|
||||
|
||||
static bool
|
||||
is_options_valid(const lzma_options_lzma *options)
|
||||
{
|
||||
// Validate some of the options. LZ encoder validates nice_len too
|
||||
// but we need a valid value here earlier.
|
||||
return is_lclppb_valid(options)
|
||||
&& options->nice_len >= MATCH_LEN_MIN
|
||||
&& options->nice_len <= MATCH_LEN_MAX
|
||||
&& (options->mode == LZMA_MODE_FAST
|
||||
|| options->mode == LZMA_MODE_NORMAL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_lz_options(lzma_lz_options *lz_options, const lzma_options_lzma *options)
|
||||
{
|
||||
// LZ encoder initialization does the validation for these so we
|
||||
// don't need to validate here.
|
||||
lz_options->before_size = OPTS;
|
||||
lz_options->dict_size = options->dict_size;
|
||||
lz_options->after_size = LOOP_INPUT_MAX;
|
||||
lz_options->match_len_max = MATCH_LEN_MAX;
|
||||
lz_options->nice_len = options->nice_len;
|
||||
lz_options->match_finder = options->mf;
|
||||
lz_options->depth = options->depth;
|
||||
lz_options->preset_dict = options->preset_dict;
|
||||
lz_options->preset_dict_size = options->preset_dict_size;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
length_encoder_reset(lzma_length_encoder *lencoder,
|
||||
const uint32_t num_pos_states, const bool fast_mode)
|
||||
{
|
||||
bit_reset(lencoder->choice);
|
||||
bit_reset(lencoder->choice2);
|
||||
|
||||
for (size_t pos_state = 0; pos_state < num_pos_states; ++pos_state) {
|
||||
bittree_reset(lencoder->low[pos_state], LEN_LOW_BITS);
|
||||
bittree_reset(lencoder->mid[pos_state], LEN_MID_BITS);
|
||||
}
|
||||
|
||||
bittree_reset(lencoder->high, LEN_HIGH_BITS);
|
||||
|
||||
if (!fast_mode)
|
||||
for (uint32_t pos_state = 0; pos_state < num_pos_states;
|
||||
++pos_state)
|
||||
length_update_prices(lencoder, pos_state);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lzma_encoder_reset(lzma_lzma1_encoder *coder,
|
||||
const lzma_options_lzma *options)
|
||||
{
|
||||
if (!is_options_valid(options))
|
||||
return LZMA_OPTIONS_ERROR;
|
||||
|
||||
coder->pos_mask = (1U << options->pb) - 1;
|
||||
coder->literal_context_bits = options->lc;
|
||||
coder->literal_pos_mask = (1U << options->lp) - 1;
|
||||
|
||||
// Range coder
|
||||
rc_reset(&coder->rc);
|
||||
|
||||
// State
|
||||
coder->state = STATE_LIT_LIT;
|
||||
for (size_t i = 0; i < REPS; ++i)
|
||||
coder->reps[i] = 0;
|
||||
|
||||
literal_init(coder->literal, options->lc, options->lp);
|
||||
|
||||
// Bit encoders
|
||||
for (size_t i = 0; i < STATES; ++i) {
|
||||
for (size_t j = 0; j <= coder->pos_mask; ++j) {
|
||||
bit_reset(coder->is_match[i][j]);
|
||||
bit_reset(coder->is_rep0_long[i][j]);
|
||||
}
|
||||
|
||||
bit_reset(coder->is_rep[i]);
|
||||
bit_reset(coder->is_rep0[i]);
|
||||
bit_reset(coder->is_rep1[i]);
|
||||
bit_reset(coder->is_rep2[i]);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < FULL_DISTANCES - DIST_MODEL_END; ++i)
|
||||
bit_reset(coder->dist_special[i]);
|
||||
|
||||
// Bit tree encoders
|
||||
for (size_t i = 0; i < DIST_STATES; ++i)
|
||||
bittree_reset(coder->dist_slot[i], DIST_SLOT_BITS);
|
||||
|
||||
bittree_reset(coder->dist_align, ALIGN_BITS);
|
||||
|
||||
// Length encoders
|
||||
length_encoder_reset(&coder->match_len_encoder,
|
||||
1U << options->pb, coder->fast_mode);
|
||||
|
||||
length_encoder_reset(&coder->rep_len_encoder,
|
||||
1U << options->pb, coder->fast_mode);
|
||||
|
||||
// Price counts are incremented every time appropriate probabilities
|
||||
// are changed. price counts are set to zero when the price tables
|
||||
// are updated, which is done when the appropriate price counts have
|
||||
// big enough value, and lzma_mf.read_ahead == 0 which happens at
|
||||
// least every OPTS (a few thousand) possible price count increments.
|
||||
//
|
||||
// By resetting price counts to UINT32_MAX / 2, we make sure that the
|
||||
// price tables will be initialized before they will be used (since
|
||||
// the value is definitely big enough), and that it is OK to increment
|
||||
// price counts without risk of integer overflow (since UINT32_MAX / 2
|
||||
// is small enough). The current code doesn't increment price counts
|
||||
// before initializing price tables, but it maybe done in future if
|
||||
// we add support for saving the state between LZMA2 chunks.
|
||||
coder->match_price_count = UINT32_MAX / 2;
|
||||
coder->align_price_count = UINT32_MAX / 2;
|
||||
|
||||
coder->opts_end_index = 0;
|
||||
coder->opts_current_index = 0;
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lzma_encoder_create(void **coder_ptr,
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_options_lzma *options, lzma_lz_options *lz_options)
|
||||
{
|
||||
// Allocate lzma_lzma1_encoder if it wasn't already allocated.
|
||||
if (*coder_ptr == NULL) {
|
||||
*coder_ptr = lzma_alloc(sizeof(lzma_lzma1_encoder), allocator);
|
||||
if (*coder_ptr == NULL)
|
||||
return LZMA_MEM_ERROR;
|
||||
}
|
||||
|
||||
lzma_lzma1_encoder *coder = *coder_ptr;
|
||||
|
||||
// Set compression mode. We haven't validates the options yet,
|
||||
// but it's OK here, since nothing bad happens with invalid
|
||||
// options in the code below, and they will get rejected by
|
||||
// lzma_lzma_encoder_reset() call at the end of this function.
|
||||
switch (options->mode) {
|
||||
case LZMA_MODE_FAST:
|
||||
coder->fast_mode = true;
|
||||
break;
|
||||
|
||||
case LZMA_MODE_NORMAL: {
|
||||
coder->fast_mode = false;
|
||||
|
||||
// Set dist_table_size.
|
||||
// Round the dictionary size up to next 2^n.
|
||||
uint32_t log_size = 0;
|
||||
while ((UINT32_C(1) << log_size) < options->dict_size)
|
||||
++log_size;
|
||||
|
||||
coder->dist_table_size = log_size * 2;
|
||||
|
||||
// Length encoders' price table size
|
||||
coder->match_len_encoder.table_size
|
||||
= options->nice_len + 1 - MATCH_LEN_MIN;
|
||||
coder->rep_len_encoder.table_size
|
||||
= options->nice_len + 1 - MATCH_LEN_MIN;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return LZMA_OPTIONS_ERROR;
|
||||
}
|
||||
|
||||
// We don't need to write the first byte as literal if there is
|
||||
// a non-empty preset dictionary. encode_init() wouldn't even work
|
||||
// if there is a non-empty preset dictionary, because encode_init()
|
||||
// assumes that position is zero and previous byte is also zero.
|
||||
coder->is_initialized = options->preset_dict != NULL
|
||||
&& options->preset_dict_size > 0;
|
||||
coder->is_flushed = false;
|
||||
|
||||
set_lz_options(lz_options, options);
|
||||
|
||||
return lzma_lzma_encoder_reset(coder, options);
|
||||
}
|
||||
|
||||
|
||||
static lzma_ret
|
||||
lzma_encoder_init(lzma_lz_encoder *lz, const lzma_allocator *allocator,
|
||||
const void *options, lzma_lz_options *lz_options)
|
||||
{
|
||||
lz->code = &lzma_encode;
|
||||
return lzma_lzma_encoder_create(
|
||||
&lz->coder, allocator, options, lz_options);
|
||||
}
|
||||
|
||||
|
||||
extern lzma_ret
|
||||
lzma_lzma_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters)
|
||||
{
|
||||
return lzma_lz_encoder_init(
|
||||
next, allocator, filters, &lzma_encoder_init);
|
||||
}
|
||||
|
||||
|
||||
extern uint64_t
|
||||
lzma_lzma_encoder_memusage(const void *options)
|
||||
{
|
||||
if (!is_options_valid(options))
|
||||
return UINT64_MAX;
|
||||
|
||||
lzma_lz_options lz_options;
|
||||
set_lz_options(&lz_options, options);
|
||||
|
||||
const uint64_t lz_memusage = lzma_lz_encoder_memusage(&lz_options);
|
||||
if (lz_memusage == UINT64_MAX)
|
||||
return UINT64_MAX;
|
||||
|
||||
return (uint64_t)(sizeof(lzma_lzma1_encoder)) + lz_memusage;
|
||||
}
|
||||
|
||||
|
||||
extern bool
|
||||
lzma_lzma_lclppb_encode(const lzma_options_lzma *options, uint8_t *byte)
|
||||
{
|
||||
if (!is_lclppb_valid(options))
|
||||
return true;
|
||||
|
||||
*byte = (options->pb * 5 + options->lp) * 9 + options->lc;
|
||||
assert(*byte <= (4 * 5 + 4) * 9 + 8);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_ENCODER_LZMA1
|
||||
extern lzma_ret
|
||||
lzma_lzma_props_encode(const void *options, uint8_t *out)
|
||||
{
|
||||
const lzma_options_lzma *const opt = options;
|
||||
|
||||
if (lzma_lzma_lclppb_encode(opt, out))
|
||||
return LZMA_PROG_ERROR;
|
||||
|
||||
unaligned_write32le(out + 1, opt->dict_size);
|
||||
|
||||
return LZMA_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
extern LZMA_API(lzma_bool)
|
||||
lzma_mode_is_supported(lzma_mode mode)
|
||||
{
|
||||
return mode == LZMA_MODE_FAST || mode == LZMA_MODE_NORMAL;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lzma_encoder.h
|
||||
/// \brief LZMA encoder API
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_LZMA_ENCODER_H
|
||||
#define LZMA_LZMA_ENCODER_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
typedef struct lzma_lzma1_encoder_s lzma_lzma1_encoder;
|
||||
|
||||
|
||||
extern lzma_ret lzma_lzma_encoder_init(lzma_next_coder *next,
|
||||
const lzma_allocator *allocator,
|
||||
const lzma_filter_info *filters);
|
||||
|
||||
|
||||
extern uint64_t lzma_lzma_encoder_memusage(const void *options);
|
||||
|
||||
extern lzma_ret lzma_lzma_props_encode(const void *options, uint8_t *out);
|
||||
|
||||
|
||||
/// Encodes lc/lp/pb into one byte. Returns false on success and true on error.
|
||||
extern bool lzma_lzma_lclppb_encode(
|
||||
const lzma_options_lzma *options, uint8_t *byte);
|
||||
|
||||
|
||||
#ifdef LZMA_LZ_ENCODER_H
|
||||
|
||||
/// Initializes raw LZMA encoder; this is used by LZMA2.
|
||||
extern lzma_ret lzma_lzma_encoder_create(
|
||||
void **coder_ptr, const lzma_allocator *allocator,
|
||||
const lzma_options_lzma *options, lzma_lz_options *lz_options);
|
||||
|
||||
|
||||
/// Resets an already initialized LZMA encoder; this is used by LZMA2.
|
||||
extern lzma_ret lzma_lzma_encoder_reset(
|
||||
lzma_lzma1_encoder *coder, const lzma_options_lzma *options);
|
||||
|
||||
|
||||
extern lzma_ret lzma_lzma_encode(lzma_lzma1_encoder *restrict coder,
|
||||
lzma_mf *restrict mf, uint8_t *restrict out,
|
||||
size_t *restrict out_pos, size_t out_size,
|
||||
uint32_t read_limit);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,170 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lzma_encoder_optimum_fast.c
|
||||
//
|
||||
// Author: Igor Pavlov
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "lzma_encoder_private.h"
|
||||
#include "memcmplen.h"
|
||||
|
||||
|
||||
#define change_pair(small_dist, big_dist) \
|
||||
(((big_dist) >> 7) > (small_dist))
|
||||
|
||||
|
||||
extern void
|
||||
lzma_lzma_optimum_fast(lzma_lzma1_encoder *restrict coder,
|
||||
lzma_mf *restrict mf,
|
||||
uint32_t *restrict back_res, uint32_t *restrict len_res)
|
||||
{
|
||||
const uint32_t nice_len = mf->nice_len;
|
||||
|
||||
uint32_t len_main;
|
||||
uint32_t matches_count;
|
||||
if (mf->read_ahead == 0) {
|
||||
len_main = mf_find(mf, &matches_count, coder->matches);
|
||||
} else {
|
||||
assert(mf->read_ahead == 1);
|
||||
len_main = coder->longest_match_length;
|
||||
matches_count = coder->matches_count;
|
||||
}
|
||||
|
||||
const uint8_t *buf = mf_ptr(mf) - 1;
|
||||
const uint32_t buf_avail = my_min(mf_avail(mf) + 1, MATCH_LEN_MAX);
|
||||
|
||||
if (buf_avail < 2) {
|
||||
// There's not enough input left to encode a match.
|
||||
*back_res = UINT32_MAX;
|
||||
*len_res = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Look for repeated matches; scan the previous four match distances
|
||||
uint32_t rep_len = 0;
|
||||
uint32_t rep_index = 0;
|
||||
|
||||
for (uint32_t i = 0; i < REPS; ++i) {
|
||||
// Pointer to the beginning of the match candidate
|
||||
const uint8_t *const buf_back = buf - coder->reps[i] - 1;
|
||||
|
||||
// If the first two bytes (2 == MATCH_LEN_MIN) do not match,
|
||||
// this rep is not useful.
|
||||
if (not_equal_16(buf, buf_back))
|
||||
continue;
|
||||
|
||||
// The first two bytes matched.
|
||||
// Calculate the length of the match.
|
||||
const uint32_t len = lzma_memcmplen(
|
||||
buf, buf_back, 2, buf_avail);
|
||||
|
||||
// If we have found a repeated match that is at least
|
||||
// nice_len long, return it immediately.
|
||||
if (len >= nice_len) {
|
||||
*back_res = i;
|
||||
*len_res = len;
|
||||
mf_skip(mf, len - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (len > rep_len) {
|
||||
rep_index = i;
|
||||
rep_len = len;
|
||||
}
|
||||
}
|
||||
|
||||
// We didn't find a long enough repeated match. Encode it as a normal
|
||||
// match if the match length is at least nice_len.
|
||||
if (len_main >= nice_len) {
|
||||
*back_res = coder->matches[matches_count - 1].dist + REPS;
|
||||
*len_res = len_main;
|
||||
mf_skip(mf, len_main - 1);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t back_main = 0;
|
||||
if (len_main >= 2) {
|
||||
back_main = coder->matches[matches_count - 1].dist;
|
||||
|
||||
while (matches_count > 1 && len_main ==
|
||||
coder->matches[matches_count - 2].len + 1) {
|
||||
if (!change_pair(coder->matches[
|
||||
matches_count - 2].dist,
|
||||
back_main))
|
||||
break;
|
||||
|
||||
--matches_count;
|
||||
len_main = coder->matches[matches_count - 1].len;
|
||||
back_main = coder->matches[matches_count - 1].dist;
|
||||
}
|
||||
|
||||
if (len_main == 2 && back_main >= 0x80)
|
||||
len_main = 1;
|
||||
}
|
||||
|
||||
if (rep_len >= 2) {
|
||||
if (rep_len + 1 >= len_main
|
||||
|| (rep_len + 2 >= len_main
|
||||
&& back_main > (UINT32_C(1) << 9))
|
||||
|| (rep_len + 3 >= len_main
|
||||
&& back_main > (UINT32_C(1) << 15))) {
|
||||
*back_res = rep_index;
|
||||
*len_res = rep_len;
|
||||
mf_skip(mf, rep_len - 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (len_main < 2 || buf_avail <= 2) {
|
||||
*back_res = UINT32_MAX;
|
||||
*len_res = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the matches for the next byte. If we find a better match,
|
||||
// the current byte is encoded as a literal.
|
||||
coder->longest_match_length = mf_find(mf,
|
||||
&coder->matches_count, coder->matches);
|
||||
|
||||
if (coder->longest_match_length >= 2) {
|
||||
const uint32_t new_dist = coder->matches[
|
||||
coder->matches_count - 1].dist;
|
||||
|
||||
if ((coder->longest_match_length >= len_main
|
||||
&& new_dist < back_main)
|
||||
|| (coder->longest_match_length == len_main + 1
|
||||
&& !change_pair(back_main, new_dist))
|
||||
|| (coder->longest_match_length > len_main + 1)
|
||||
|| (coder->longest_match_length + 1 >= len_main
|
||||
&& len_main >= 3
|
||||
&& change_pair(new_dist, back_main))) {
|
||||
*back_res = UINT32_MAX;
|
||||
*len_res = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// In contrast to LZMA SDK, dictionary could not have been moved
|
||||
// between mf_find() calls, thus it is safe to just increment
|
||||
// the old buf pointer instead of recalculating it with mf_ptr().
|
||||
++buf;
|
||||
|
||||
const uint32_t limit = my_max(2, len_main - 1);
|
||||
|
||||
for (uint32_t i = 0; i < REPS; ++i) {
|
||||
if (memcmp(buf, buf - coder->reps[i] - 1, limit) == 0) {
|
||||
*back_res = UINT32_MAX;
|
||||
*len_res = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
*back_res = back_main + REPS;
|
||||
*len_res = len_main;
|
||||
mf_skip(mf, len_main - 2);
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,855 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lzma_encoder_optimum_normal.c
|
||||
//
|
||||
// Author: Igor Pavlov
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "lzma_encoder_private.h"
|
||||
#include "fastpos.h"
|
||||
#include "memcmplen.h"
|
||||
|
||||
|
||||
////////////
|
||||
// Prices //
|
||||
////////////
|
||||
|
||||
static uint32_t
|
||||
get_literal_price(const lzma_lzma1_encoder *const coder, const uint32_t pos,
|
||||
const uint32_t prev_byte, const bool match_mode,
|
||||
uint32_t match_byte, uint32_t symbol)
|
||||
{
|
||||
const probability *const subcoder = literal_subcoder(coder->literal,
|
||||
coder->literal_context_bits, coder->literal_pos_mask,
|
||||
pos, prev_byte);
|
||||
|
||||
uint32_t price = 0;
|
||||
|
||||
if (!match_mode) {
|
||||
price = rc_bittree_price(subcoder, 8, symbol);
|
||||
} else {
|
||||
uint32_t offset = 0x100;
|
||||
symbol += UINT32_C(1) << 8;
|
||||
|
||||
do {
|
||||
match_byte <<= 1;
|
||||
|
||||
const uint32_t match_bit = match_byte & offset;
|
||||
const uint32_t subcoder_index
|
||||
= offset + match_bit + (symbol >> 8);
|
||||
const uint32_t bit = (symbol >> 7) & 1;
|
||||
price += rc_bit_price(subcoder[subcoder_index], bit);
|
||||
|
||||
symbol <<= 1;
|
||||
offset &= ~(match_byte ^ symbol);
|
||||
|
||||
} while (symbol < (UINT32_C(1) << 16));
|
||||
}
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
get_len_price(const lzma_length_encoder *const lencoder,
|
||||
const uint32_t len, const uint32_t pos_state)
|
||||
{
|
||||
// NOTE: Unlike the other price tables, length prices are updated
|
||||
// in lzma_encoder.c
|
||||
return lencoder->prices[pos_state][len - MATCH_LEN_MIN];
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
get_short_rep_price(const lzma_lzma1_encoder *const coder,
|
||||
const lzma_lzma_state state, const uint32_t pos_state)
|
||||
{
|
||||
return rc_bit_0_price(coder->is_rep0[state])
|
||||
+ rc_bit_0_price(coder->is_rep0_long[state][pos_state]);
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
get_pure_rep_price(const lzma_lzma1_encoder *const coder, const uint32_t rep_index,
|
||||
const lzma_lzma_state state, uint32_t pos_state)
|
||||
{
|
||||
uint32_t price;
|
||||
|
||||
if (rep_index == 0) {
|
||||
price = rc_bit_0_price(coder->is_rep0[state]);
|
||||
price += rc_bit_1_price(coder->is_rep0_long[state][pos_state]);
|
||||
} else {
|
||||
price = rc_bit_1_price(coder->is_rep0[state]);
|
||||
|
||||
if (rep_index == 1) {
|
||||
price += rc_bit_0_price(coder->is_rep1[state]);
|
||||
} else {
|
||||
price += rc_bit_1_price(coder->is_rep1[state]);
|
||||
price += rc_bit_price(coder->is_rep2[state],
|
||||
rep_index - 2);
|
||||
}
|
||||
}
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
get_rep_price(const lzma_lzma1_encoder *const coder, const uint32_t rep_index,
|
||||
const uint32_t len, const lzma_lzma_state state,
|
||||
const uint32_t pos_state)
|
||||
{
|
||||
return get_len_price(&coder->rep_len_encoder, len, pos_state)
|
||||
+ get_pure_rep_price(coder, rep_index, state, pos_state);
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
get_dist_len_price(const lzma_lzma1_encoder *const coder, const uint32_t dist,
|
||||
const uint32_t len, const uint32_t pos_state)
|
||||
{
|
||||
const uint32_t dist_state = get_dist_state(len);
|
||||
uint32_t price;
|
||||
|
||||
if (dist < FULL_DISTANCES) {
|
||||
price = coder->dist_prices[dist_state][dist];
|
||||
} else {
|
||||
const uint32_t dist_slot = get_dist_slot_2(dist);
|
||||
price = coder->dist_slot_prices[dist_state][dist_slot]
|
||||
+ coder->align_prices[dist & ALIGN_MASK];
|
||||
}
|
||||
|
||||
price += get_len_price(&coder->match_len_encoder, len, pos_state);
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fill_dist_prices(lzma_lzma1_encoder *coder)
|
||||
{
|
||||
for (uint32_t dist_state = 0; dist_state < DIST_STATES; ++dist_state) {
|
||||
|
||||
uint32_t *const dist_slot_prices
|
||||
= coder->dist_slot_prices[dist_state];
|
||||
|
||||
// Price to encode the dist_slot.
|
||||
for (uint32_t dist_slot = 0;
|
||||
dist_slot < coder->dist_table_size; ++dist_slot)
|
||||
dist_slot_prices[dist_slot] = rc_bittree_price(
|
||||
coder->dist_slot[dist_state],
|
||||
DIST_SLOT_BITS, dist_slot);
|
||||
|
||||
// For matches with distance >= FULL_DISTANCES, add the price
|
||||
// of the direct bits part of the match distance. (Align bits
|
||||
// are handled by fill_align_prices()).
|
||||
for (uint32_t dist_slot = DIST_MODEL_END;
|
||||
dist_slot < coder->dist_table_size;
|
||||
++dist_slot)
|
||||
dist_slot_prices[dist_slot] += rc_direct_price(
|
||||
((dist_slot >> 1) - 1) - ALIGN_BITS);
|
||||
|
||||
// Distances in the range [0, 3] are fully encoded with
|
||||
// dist_slot, so they are used for coder->dist_prices
|
||||
// as is.
|
||||
for (uint32_t i = 0; i < DIST_MODEL_START; ++i)
|
||||
coder->dist_prices[dist_state][i]
|
||||
= dist_slot_prices[i];
|
||||
}
|
||||
|
||||
// Distances in the range [4, 127] depend on dist_slot and
|
||||
// dist_special. We do this in a loop separate from the above
|
||||
// loop to avoid redundant calls to get_dist_slot().
|
||||
for (uint32_t i = DIST_MODEL_START; i < FULL_DISTANCES; ++i) {
|
||||
const uint32_t dist_slot = get_dist_slot(i);
|
||||
const uint32_t footer_bits = ((dist_slot >> 1) - 1);
|
||||
const uint32_t base = (2 | (dist_slot & 1)) << footer_bits;
|
||||
const uint32_t price = rc_bittree_reverse_price(
|
||||
coder->dist_special + base - dist_slot - 1,
|
||||
footer_bits, i - base);
|
||||
|
||||
for (uint32_t dist_state = 0; dist_state < DIST_STATES;
|
||||
++dist_state)
|
||||
coder->dist_prices[dist_state][i]
|
||||
= price + coder->dist_slot_prices[
|
||||
dist_state][dist_slot];
|
||||
}
|
||||
|
||||
coder->match_price_count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fill_align_prices(lzma_lzma1_encoder *coder)
|
||||
{
|
||||
for (uint32_t i = 0; i < ALIGN_SIZE; ++i)
|
||||
coder->align_prices[i] = rc_bittree_reverse_price(
|
||||
coder->dist_align, ALIGN_BITS, i);
|
||||
|
||||
coder->align_price_count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/////////////
|
||||
// Optimal //
|
||||
/////////////
|
||||
|
||||
static inline void
|
||||
make_literal(lzma_optimal *optimal)
|
||||
{
|
||||
optimal->back_prev = UINT32_MAX;
|
||||
optimal->prev_1_is_literal = false;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
make_short_rep(lzma_optimal *optimal)
|
||||
{
|
||||
optimal->back_prev = 0;
|
||||
optimal->prev_1_is_literal = false;
|
||||
}
|
||||
|
||||
|
||||
#define is_short_rep(optimal) \
|
||||
((optimal).back_prev == 0)
|
||||
|
||||
|
||||
static void
|
||||
backward(lzma_lzma1_encoder *restrict coder, uint32_t *restrict len_res,
|
||||
uint32_t *restrict back_res, uint32_t cur)
|
||||
{
|
||||
coder->opts_end_index = cur;
|
||||
|
||||
uint32_t pos_mem = coder->opts[cur].pos_prev;
|
||||
uint32_t back_mem = coder->opts[cur].back_prev;
|
||||
|
||||
do {
|
||||
if (coder->opts[cur].prev_1_is_literal) {
|
||||
make_literal(&coder->opts[pos_mem]);
|
||||
coder->opts[pos_mem].pos_prev = pos_mem - 1;
|
||||
|
||||
if (coder->opts[cur].prev_2) {
|
||||
coder->opts[pos_mem - 1].prev_1_is_literal
|
||||
= false;
|
||||
coder->opts[pos_mem - 1].pos_prev
|
||||
= coder->opts[cur].pos_prev_2;
|
||||
coder->opts[pos_mem - 1].back_prev
|
||||
= coder->opts[cur].back_prev_2;
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t pos_prev = pos_mem;
|
||||
const uint32_t back_cur = back_mem;
|
||||
|
||||
back_mem = coder->opts[pos_prev].back_prev;
|
||||
pos_mem = coder->opts[pos_prev].pos_prev;
|
||||
|
||||
coder->opts[pos_prev].back_prev = back_cur;
|
||||
coder->opts[pos_prev].pos_prev = cur;
|
||||
cur = pos_prev;
|
||||
|
||||
} while (cur != 0);
|
||||
|
||||
coder->opts_current_index = coder->opts[0].pos_prev;
|
||||
*len_res = coder->opts[0].pos_prev;
|
||||
*back_res = coder->opts[0].back_prev;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//////////
|
||||
// Main //
|
||||
//////////
|
||||
|
||||
static inline uint32_t
|
||||
helper1(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf,
|
||||
uint32_t *restrict back_res, uint32_t *restrict len_res,
|
||||
uint32_t position)
|
||||
{
|
||||
const uint32_t nice_len = mf->nice_len;
|
||||
|
||||
uint32_t len_main;
|
||||
uint32_t matches_count;
|
||||
|
||||
if (mf->read_ahead == 0) {
|
||||
len_main = mf_find(mf, &matches_count, coder->matches);
|
||||
} else {
|
||||
assert(mf->read_ahead == 1);
|
||||
len_main = coder->longest_match_length;
|
||||
matches_count = coder->matches_count;
|
||||
}
|
||||
|
||||
const uint32_t buf_avail = my_min(mf_avail(mf) + 1, MATCH_LEN_MAX);
|
||||
if (buf_avail < 2) {
|
||||
*back_res = UINT32_MAX;
|
||||
*len_res = 1;
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
const uint8_t *const buf = mf_ptr(mf) - 1;
|
||||
|
||||
uint32_t rep_lens[REPS];
|
||||
uint32_t rep_max_index = 0;
|
||||
|
||||
for (uint32_t i = 0; i < REPS; ++i) {
|
||||
const uint8_t *const buf_back = buf - coder->reps[i] - 1;
|
||||
|
||||
if (not_equal_16(buf, buf_back)) {
|
||||
rep_lens[i] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
rep_lens[i] = lzma_memcmplen(buf, buf_back, 2, buf_avail);
|
||||
|
||||
if (rep_lens[i] > rep_lens[rep_max_index])
|
||||
rep_max_index = i;
|
||||
}
|
||||
|
||||
if (rep_lens[rep_max_index] >= nice_len) {
|
||||
*back_res = rep_max_index;
|
||||
*len_res = rep_lens[rep_max_index];
|
||||
mf_skip(mf, *len_res - 1);
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
|
||||
if (len_main >= nice_len) {
|
||||
*back_res = coder->matches[matches_count - 1].dist + REPS;
|
||||
*len_res = len_main;
|
||||
mf_skip(mf, len_main - 1);
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
const uint8_t current_byte = *buf;
|
||||
const uint8_t match_byte = *(buf - coder->reps[0] - 1);
|
||||
|
||||
if (len_main < 2 && current_byte != match_byte
|
||||
&& rep_lens[rep_max_index] < 2) {
|
||||
*back_res = UINT32_MAX;
|
||||
*len_res = 1;
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
coder->opts[0].state = coder->state;
|
||||
|
||||
const uint32_t pos_state = position & coder->pos_mask;
|
||||
|
||||
coder->opts[1].price = rc_bit_0_price(
|
||||
coder->is_match[coder->state][pos_state])
|
||||
+ get_literal_price(coder, position, buf[-1],
|
||||
!is_literal_state(coder->state),
|
||||
match_byte, current_byte);
|
||||
|
||||
make_literal(&coder->opts[1]);
|
||||
|
||||
const uint32_t match_price = rc_bit_1_price(
|
||||
coder->is_match[coder->state][pos_state]);
|
||||
const uint32_t rep_match_price = match_price
|
||||
+ rc_bit_1_price(coder->is_rep[coder->state]);
|
||||
|
||||
if (match_byte == current_byte) {
|
||||
const uint32_t short_rep_price = rep_match_price
|
||||
+ get_short_rep_price(
|
||||
coder, coder->state, pos_state);
|
||||
|
||||
if (short_rep_price < coder->opts[1].price) {
|
||||
coder->opts[1].price = short_rep_price;
|
||||
make_short_rep(&coder->opts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
const uint32_t len_end = my_max(len_main, rep_lens[rep_max_index]);
|
||||
|
||||
if (len_end < 2) {
|
||||
*back_res = coder->opts[1].back_prev;
|
||||
*len_res = 1;
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
coder->opts[1].pos_prev = 0;
|
||||
|
||||
for (uint32_t i = 0; i < REPS; ++i)
|
||||
coder->opts[0].backs[i] = coder->reps[i];
|
||||
|
||||
uint32_t len = len_end;
|
||||
do {
|
||||
coder->opts[len].price = RC_INFINITY_PRICE;
|
||||
} while (--len >= 2);
|
||||
|
||||
|
||||
for (uint32_t i = 0; i < REPS; ++i) {
|
||||
uint32_t rep_len = rep_lens[i];
|
||||
if (rep_len < 2)
|
||||
continue;
|
||||
|
||||
const uint32_t price = rep_match_price + get_pure_rep_price(
|
||||
coder, i, coder->state, pos_state);
|
||||
|
||||
do {
|
||||
const uint32_t cur_and_len_price = price
|
||||
+ get_len_price(
|
||||
&coder->rep_len_encoder,
|
||||
rep_len, pos_state);
|
||||
|
||||
if (cur_and_len_price < coder->opts[rep_len].price) {
|
||||
coder->opts[rep_len].price = cur_and_len_price;
|
||||
coder->opts[rep_len].pos_prev = 0;
|
||||
coder->opts[rep_len].back_prev = i;
|
||||
coder->opts[rep_len].prev_1_is_literal = false;
|
||||
}
|
||||
} while (--rep_len >= 2);
|
||||
}
|
||||
|
||||
|
||||
const uint32_t normal_match_price = match_price
|
||||
+ rc_bit_0_price(coder->is_rep[coder->state]);
|
||||
|
||||
len = rep_lens[0] >= 2 ? rep_lens[0] + 1 : 2;
|
||||
if (len <= len_main) {
|
||||
uint32_t i = 0;
|
||||
while (len > coder->matches[i].len)
|
||||
++i;
|
||||
|
||||
for(; ; ++len) {
|
||||
const uint32_t dist = coder->matches[i].dist;
|
||||
const uint32_t cur_and_len_price = normal_match_price
|
||||
+ get_dist_len_price(coder,
|
||||
dist, len, pos_state);
|
||||
|
||||
if (cur_and_len_price < coder->opts[len].price) {
|
||||
coder->opts[len].price = cur_and_len_price;
|
||||
coder->opts[len].pos_prev = 0;
|
||||
coder->opts[len].back_prev = dist + REPS;
|
||||
coder->opts[len].prev_1_is_literal = false;
|
||||
}
|
||||
|
||||
if (len == coder->matches[i].len)
|
||||
if (++i == matches_count)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return len_end;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
helper2(lzma_lzma1_encoder *coder, uint32_t *reps, const uint8_t *buf,
|
||||
uint32_t len_end, uint32_t position, const uint32_t cur,
|
||||
const uint32_t nice_len, const uint32_t buf_avail_full)
|
||||
{
|
||||
uint32_t matches_count = coder->matches_count;
|
||||
uint32_t new_len = coder->longest_match_length;
|
||||
uint32_t pos_prev = coder->opts[cur].pos_prev;
|
||||
lzma_lzma_state state;
|
||||
|
||||
if (coder->opts[cur].prev_1_is_literal) {
|
||||
--pos_prev;
|
||||
|
||||
if (coder->opts[cur].prev_2) {
|
||||
state = coder->opts[coder->opts[cur].pos_prev_2].state;
|
||||
|
||||
if (coder->opts[cur].back_prev_2 < REPS)
|
||||
update_long_rep(state);
|
||||
else
|
||||
update_match(state);
|
||||
|
||||
} else {
|
||||
state = coder->opts[pos_prev].state;
|
||||
}
|
||||
|
||||
update_literal(state);
|
||||
|
||||
} else {
|
||||
state = coder->opts[pos_prev].state;
|
||||
}
|
||||
|
||||
if (pos_prev == cur - 1) {
|
||||
if (is_short_rep(coder->opts[cur]))
|
||||
update_short_rep(state);
|
||||
else
|
||||
update_literal(state);
|
||||
} else {
|
||||
uint32_t pos;
|
||||
if (coder->opts[cur].prev_1_is_literal
|
||||
&& coder->opts[cur].prev_2) {
|
||||
pos_prev = coder->opts[cur].pos_prev_2;
|
||||
pos = coder->opts[cur].back_prev_2;
|
||||
update_long_rep(state);
|
||||
} else {
|
||||
pos = coder->opts[cur].back_prev;
|
||||
if (pos < REPS)
|
||||
update_long_rep(state);
|
||||
else
|
||||
update_match(state);
|
||||
}
|
||||
|
||||
if (pos < REPS) {
|
||||
reps[0] = coder->opts[pos_prev].backs[pos];
|
||||
|
||||
uint32_t i;
|
||||
for (i = 1; i <= pos; ++i)
|
||||
reps[i] = coder->opts[pos_prev].backs[i - 1];
|
||||
|
||||
for (; i < REPS; ++i)
|
||||
reps[i] = coder->opts[pos_prev].backs[i];
|
||||
|
||||
} else {
|
||||
reps[0] = pos - REPS;
|
||||
|
||||
for (uint32_t i = 1; i < REPS; ++i)
|
||||
reps[i] = coder->opts[pos_prev].backs[i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
coder->opts[cur].state = state;
|
||||
|
||||
for (uint32_t i = 0; i < REPS; ++i)
|
||||
coder->opts[cur].backs[i] = reps[i];
|
||||
|
||||
const uint32_t cur_price = coder->opts[cur].price;
|
||||
|
||||
const uint8_t current_byte = *buf;
|
||||
const uint8_t match_byte = *(buf - reps[0] - 1);
|
||||
|
||||
const uint32_t pos_state = position & coder->pos_mask;
|
||||
|
||||
const uint32_t cur_and_1_price = cur_price
|
||||
+ rc_bit_0_price(coder->is_match[state][pos_state])
|
||||
+ get_literal_price(coder, position, buf[-1],
|
||||
!is_literal_state(state), match_byte, current_byte);
|
||||
|
||||
bool next_is_literal = false;
|
||||
|
||||
if (cur_and_1_price < coder->opts[cur + 1].price) {
|
||||
coder->opts[cur + 1].price = cur_and_1_price;
|
||||
coder->opts[cur + 1].pos_prev = cur;
|
||||
make_literal(&coder->opts[cur + 1]);
|
||||
next_is_literal = true;
|
||||
}
|
||||
|
||||
const uint32_t match_price = cur_price
|
||||
+ rc_bit_1_price(coder->is_match[state][pos_state]);
|
||||
const uint32_t rep_match_price = match_price
|
||||
+ rc_bit_1_price(coder->is_rep[state]);
|
||||
|
||||
if (match_byte == current_byte
|
||||
&& !(coder->opts[cur + 1].pos_prev < cur
|
||||
&& coder->opts[cur + 1].back_prev == 0)) {
|
||||
|
||||
const uint32_t short_rep_price = rep_match_price
|
||||
+ get_short_rep_price(coder, state, pos_state);
|
||||
|
||||
if (short_rep_price <= coder->opts[cur + 1].price) {
|
||||
coder->opts[cur + 1].price = short_rep_price;
|
||||
coder->opts[cur + 1].pos_prev = cur;
|
||||
make_short_rep(&coder->opts[cur + 1]);
|
||||
next_is_literal = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (buf_avail_full < 2)
|
||||
return len_end;
|
||||
|
||||
const uint32_t buf_avail = my_min(buf_avail_full, nice_len);
|
||||
|
||||
if (!next_is_literal && match_byte != current_byte) { // speed optimization
|
||||
// try literal + rep0
|
||||
const uint8_t *const buf_back = buf - reps[0] - 1;
|
||||
const uint32_t limit = my_min(buf_avail_full, nice_len + 1);
|
||||
|
||||
const uint32_t len_test = lzma_memcmplen(buf, buf_back, 1, limit) - 1;
|
||||
|
||||
if (len_test >= 2) {
|
||||
lzma_lzma_state state_2 = state;
|
||||
update_literal(state_2);
|
||||
|
||||
const uint32_t pos_state_next = (position + 1) & coder->pos_mask;
|
||||
const uint32_t next_rep_match_price = cur_and_1_price
|
||||
+ rc_bit_1_price(coder->is_match[state_2][pos_state_next])
|
||||
+ rc_bit_1_price(coder->is_rep[state_2]);
|
||||
|
||||
//for (; len_test >= 2; --len_test) {
|
||||
const uint32_t offset = cur + 1 + len_test;
|
||||
|
||||
while (len_end < offset)
|
||||
coder->opts[++len_end].price = RC_INFINITY_PRICE;
|
||||
|
||||
const uint32_t cur_and_len_price = next_rep_match_price
|
||||
+ get_rep_price(coder, 0, len_test,
|
||||
state_2, pos_state_next);
|
||||
|
||||
if (cur_and_len_price < coder->opts[offset].price) {
|
||||
coder->opts[offset].price = cur_and_len_price;
|
||||
coder->opts[offset].pos_prev = cur + 1;
|
||||
coder->opts[offset].back_prev = 0;
|
||||
coder->opts[offset].prev_1_is_literal = true;
|
||||
coder->opts[offset].prev_2 = false;
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint32_t start_len = 2; // speed optimization
|
||||
|
||||
for (uint32_t rep_index = 0; rep_index < REPS; ++rep_index) {
|
||||
const uint8_t *const buf_back = buf - reps[rep_index] - 1;
|
||||
if (not_equal_16(buf, buf_back))
|
||||
continue;
|
||||
|
||||
uint32_t len_test = lzma_memcmplen(buf, buf_back, 2, buf_avail);
|
||||
|
||||
while (len_end < cur + len_test)
|
||||
coder->opts[++len_end].price = RC_INFINITY_PRICE;
|
||||
|
||||
const uint32_t len_test_temp = len_test;
|
||||
const uint32_t price = rep_match_price + get_pure_rep_price(
|
||||
coder, rep_index, state, pos_state);
|
||||
|
||||
do {
|
||||
const uint32_t cur_and_len_price = price
|
||||
+ get_len_price(&coder->rep_len_encoder,
|
||||
len_test, pos_state);
|
||||
|
||||
if (cur_and_len_price < coder->opts[cur + len_test].price) {
|
||||
coder->opts[cur + len_test].price = cur_and_len_price;
|
||||
coder->opts[cur + len_test].pos_prev = cur;
|
||||
coder->opts[cur + len_test].back_prev = rep_index;
|
||||
coder->opts[cur + len_test].prev_1_is_literal = false;
|
||||
}
|
||||
} while (--len_test >= 2);
|
||||
|
||||
len_test = len_test_temp;
|
||||
|
||||
if (rep_index == 0)
|
||||
start_len = len_test + 1;
|
||||
|
||||
|
||||
uint32_t len_test_2 = len_test + 1;
|
||||
const uint32_t limit = my_min(buf_avail_full,
|
||||
len_test_2 + nice_len);
|
||||
for (; len_test_2 < limit
|
||||
&& buf[len_test_2] == buf_back[len_test_2];
|
||||
++len_test_2) ;
|
||||
|
||||
len_test_2 -= len_test + 1;
|
||||
|
||||
if (len_test_2 >= 2) {
|
||||
lzma_lzma_state state_2 = state;
|
||||
update_long_rep(state_2);
|
||||
|
||||
uint32_t pos_state_next = (position + len_test) & coder->pos_mask;
|
||||
|
||||
const uint32_t cur_and_len_literal_price = price
|
||||
+ get_len_price(&coder->rep_len_encoder,
|
||||
len_test, pos_state)
|
||||
+ rc_bit_0_price(coder->is_match[state_2][pos_state_next])
|
||||
+ get_literal_price(coder, position + len_test,
|
||||
buf[len_test - 1], true,
|
||||
buf_back[len_test], buf[len_test]);
|
||||
|
||||
update_literal(state_2);
|
||||
|
||||
pos_state_next = (position + len_test + 1) & coder->pos_mask;
|
||||
|
||||
const uint32_t next_rep_match_price = cur_and_len_literal_price
|
||||
+ rc_bit_1_price(coder->is_match[state_2][pos_state_next])
|
||||
+ rc_bit_1_price(coder->is_rep[state_2]);
|
||||
|
||||
//for(; len_test_2 >= 2; len_test_2--) {
|
||||
const uint32_t offset = cur + len_test + 1 + len_test_2;
|
||||
|
||||
while (len_end < offset)
|
||||
coder->opts[++len_end].price = RC_INFINITY_PRICE;
|
||||
|
||||
const uint32_t cur_and_len_price = next_rep_match_price
|
||||
+ get_rep_price(coder, 0, len_test_2,
|
||||
state_2, pos_state_next);
|
||||
|
||||
if (cur_and_len_price < coder->opts[offset].price) {
|
||||
coder->opts[offset].price = cur_and_len_price;
|
||||
coder->opts[offset].pos_prev = cur + len_test + 1;
|
||||
coder->opts[offset].back_prev = 0;
|
||||
coder->opts[offset].prev_1_is_literal = true;
|
||||
coder->opts[offset].prev_2 = true;
|
||||
coder->opts[offset].pos_prev_2 = cur;
|
||||
coder->opts[offset].back_prev_2 = rep_index;
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//for (uint32_t len_test = 2; len_test <= new_len; ++len_test)
|
||||
if (new_len > buf_avail) {
|
||||
new_len = buf_avail;
|
||||
|
||||
matches_count = 0;
|
||||
while (new_len > coder->matches[matches_count].len)
|
||||
++matches_count;
|
||||
|
||||
coder->matches[matches_count++].len = new_len;
|
||||
}
|
||||
|
||||
|
||||
if (new_len >= start_len) {
|
||||
const uint32_t normal_match_price = match_price
|
||||
+ rc_bit_0_price(coder->is_rep[state]);
|
||||
|
||||
while (len_end < cur + new_len)
|
||||
coder->opts[++len_end].price = RC_INFINITY_PRICE;
|
||||
|
||||
uint32_t i = 0;
|
||||
while (start_len > coder->matches[i].len)
|
||||
++i;
|
||||
|
||||
for (uint32_t len_test = start_len; ; ++len_test) {
|
||||
const uint32_t cur_back = coder->matches[i].dist;
|
||||
uint32_t cur_and_len_price = normal_match_price
|
||||
+ get_dist_len_price(coder,
|
||||
cur_back, len_test, pos_state);
|
||||
|
||||
if (cur_and_len_price < coder->opts[cur + len_test].price) {
|
||||
coder->opts[cur + len_test].price = cur_and_len_price;
|
||||
coder->opts[cur + len_test].pos_prev = cur;
|
||||
coder->opts[cur + len_test].back_prev
|
||||
= cur_back + REPS;
|
||||
coder->opts[cur + len_test].prev_1_is_literal = false;
|
||||
}
|
||||
|
||||
if (len_test == coder->matches[i].len) {
|
||||
// Try Match + Literal + Rep0
|
||||
const uint8_t *const buf_back = buf - cur_back - 1;
|
||||
uint32_t len_test_2 = len_test + 1;
|
||||
const uint32_t limit = my_min(buf_avail_full,
|
||||
len_test_2 + nice_len);
|
||||
|
||||
for (; len_test_2 < limit &&
|
||||
buf[len_test_2] == buf_back[len_test_2];
|
||||
++len_test_2) ;
|
||||
|
||||
len_test_2 -= len_test + 1;
|
||||
|
||||
if (len_test_2 >= 2) {
|
||||
lzma_lzma_state state_2 = state;
|
||||
update_match(state_2);
|
||||
uint32_t pos_state_next
|
||||
= (position + len_test) & coder->pos_mask;
|
||||
|
||||
const uint32_t cur_and_len_literal_price = cur_and_len_price
|
||||
+ rc_bit_0_price(
|
||||
coder->is_match[state_2][pos_state_next])
|
||||
+ get_literal_price(coder,
|
||||
position + len_test,
|
||||
buf[len_test - 1],
|
||||
true,
|
||||
buf_back[len_test],
|
||||
buf[len_test]);
|
||||
|
||||
update_literal(state_2);
|
||||
pos_state_next = (pos_state_next + 1) & coder->pos_mask;
|
||||
|
||||
const uint32_t next_rep_match_price
|
||||
= cur_and_len_literal_price
|
||||
+ rc_bit_1_price(
|
||||
coder->is_match[state_2][pos_state_next])
|
||||
+ rc_bit_1_price(coder->is_rep[state_2]);
|
||||
|
||||
// for(; len_test_2 >= 2; --len_test_2) {
|
||||
const uint32_t offset = cur + len_test + 1 + len_test_2;
|
||||
|
||||
while (len_end < offset)
|
||||
coder->opts[++len_end].price = RC_INFINITY_PRICE;
|
||||
|
||||
cur_and_len_price = next_rep_match_price
|
||||
+ get_rep_price(coder, 0, len_test_2,
|
||||
state_2, pos_state_next);
|
||||
|
||||
if (cur_and_len_price < coder->opts[offset].price) {
|
||||
coder->opts[offset].price = cur_and_len_price;
|
||||
coder->opts[offset].pos_prev = cur + len_test + 1;
|
||||
coder->opts[offset].back_prev = 0;
|
||||
coder->opts[offset].prev_1_is_literal = true;
|
||||
coder->opts[offset].prev_2 = true;
|
||||
coder->opts[offset].pos_prev_2 = cur;
|
||||
coder->opts[offset].back_prev_2
|
||||
= cur_back + REPS;
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
if (++i == matches_count)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return len_end;
|
||||
}
|
||||
|
||||
|
||||
extern void
|
||||
lzma_lzma_optimum_normal(lzma_lzma1_encoder *restrict coder,
|
||||
lzma_mf *restrict mf,
|
||||
uint32_t *restrict back_res, uint32_t *restrict len_res,
|
||||
uint32_t position)
|
||||
{
|
||||
// If we have symbols pending, return the next pending symbol.
|
||||
if (coder->opts_end_index != coder->opts_current_index) {
|
||||
assert(mf->read_ahead > 0);
|
||||
*len_res = coder->opts[coder->opts_current_index].pos_prev
|
||||
- coder->opts_current_index;
|
||||
*back_res = coder->opts[coder->opts_current_index].back_prev;
|
||||
coder->opts_current_index = coder->opts[
|
||||
coder->opts_current_index].pos_prev;
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the price tables. In LZMA SDK <= 4.60 (and possibly later)
|
||||
// this was done in both initialization function and in the main loop.
|
||||
// In liblzma they were moved into this single place.
|
||||
if (mf->read_ahead == 0) {
|
||||
if (coder->match_price_count >= (1 << 7))
|
||||
fill_dist_prices(coder);
|
||||
|
||||
if (coder->align_price_count >= ALIGN_SIZE)
|
||||
fill_align_prices(coder);
|
||||
}
|
||||
|
||||
// TODO: This needs quite a bit of cleaning still. But splitting
|
||||
// the original function into two pieces makes it at least a little
|
||||
// more readable, since those two parts don't share many variables.
|
||||
|
||||
uint32_t len_end = helper1(coder, mf, back_res, len_res, position);
|
||||
if (len_end == UINT32_MAX)
|
||||
return;
|
||||
|
||||
uint32_t reps[REPS];
|
||||
memcpy(reps, coder->reps, sizeof(reps));
|
||||
|
||||
uint32_t cur;
|
||||
for (cur = 1; cur < len_end; ++cur) {
|
||||
assert(cur < OPTS);
|
||||
|
||||
coder->longest_match_length = mf_find(
|
||||
mf, &coder->matches_count, coder->matches);
|
||||
|
||||
if (coder->longest_match_length >= mf->nice_len)
|
||||
break;
|
||||
|
||||
len_end = helper2(coder, reps, mf_ptr(mf) - 1, len_end,
|
||||
position + cur, cur, mf->nice_len,
|
||||
my_min(mf_avail(mf) + 1, OPTS - 1 - cur));
|
||||
}
|
||||
|
||||
backward(coder, len_res, back_res, cur);
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lzma_encoder_presets.c
|
||||
/// \brief Encoder presets
|
||||
/// \note xz needs this even when only decoding is enabled.
|
||||
//
|
||||
// Author: Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
extern LZMA_API(lzma_bool)
|
||||
lzma_lzma_preset(lzma_options_lzma *options, uint32_t preset)
|
||||
{
|
||||
const uint32_t level = preset & LZMA_PRESET_LEVEL_MASK;
|
||||
const uint32_t flags = preset & ~LZMA_PRESET_LEVEL_MASK;
|
||||
const uint32_t supported_flags = LZMA_PRESET_EXTREME;
|
||||
|
||||
if (level > 9 || (flags & ~supported_flags))
|
||||
return true;
|
||||
|
||||
options->preset_dict = NULL;
|
||||
options->preset_dict_size = 0;
|
||||
|
||||
options->lc = LZMA_LC_DEFAULT;
|
||||
options->lp = LZMA_LP_DEFAULT;
|
||||
options->pb = LZMA_PB_DEFAULT;
|
||||
|
||||
static const uint8_t dict_pow2[]
|
||||
= { 18, 20, 21, 22, 22, 23, 23, 24, 25, 26 };
|
||||
options->dict_size = UINT32_C(1) << dict_pow2[level];
|
||||
|
||||
if (level <= 3) {
|
||||
options->mode = LZMA_MODE_FAST;
|
||||
options->mf = level == 0 ? LZMA_MF_HC3 : LZMA_MF_HC4;
|
||||
options->nice_len = level <= 1 ? 128 : 273;
|
||||
static const uint8_t depths[] = { 4, 8, 24, 48 };
|
||||
options->depth = depths[level];
|
||||
} else {
|
||||
options->mode = LZMA_MODE_NORMAL;
|
||||
options->mf = LZMA_MF_BT4;
|
||||
options->nice_len = level == 4 ? 16 : level == 5 ? 32 : 64;
|
||||
options->depth = 0;
|
||||
}
|
||||
|
||||
if (flags & LZMA_PRESET_EXTREME) {
|
||||
options->mode = LZMA_MODE_NORMAL;
|
||||
options->mf = LZMA_MF_BT4;
|
||||
if (level == 3 || level == 5) {
|
||||
options->nice_len = 192;
|
||||
options->depth = 0;
|
||||
} else {
|
||||
options->nice_len = 273;
|
||||
options->depth = 512;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file lzma_encoder_private.h
|
||||
/// \brief Private definitions for LZMA encoder
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_LZMA_ENCODER_PRIVATE_H
|
||||
#define LZMA_LZMA_ENCODER_PRIVATE_H
|
||||
|
||||
#include "lz_encoder.h"
|
||||
#include "range_encoder.h"
|
||||
#include "lzma_common.h"
|
||||
#include "lzma_encoder.h"
|
||||
|
||||
|
||||
// Macro to compare if the first two bytes in two buffers differ. This is
|
||||
// needed in lzma_lzma_optimum_*() to test if the match is at least
|
||||
// MATCH_LEN_MIN bytes. Unaligned access gives tiny gain so there's no
|
||||
// reason to not use it when it is supported.
|
||||
#ifdef TUKLIB_FAST_UNALIGNED_ACCESS
|
||||
# define not_equal_16(a, b) \
|
||||
(*(const uint16_t *)(a) != *(const uint16_t *)(b))
|
||||
#else
|
||||
# define not_equal_16(a, b) \
|
||||
((a)[0] != (b)[0] || (a)[1] != (b)[1])
|
||||
#endif
|
||||
|
||||
|
||||
// Optimal - Number of entries in the optimum array.
|
||||
#define OPTS (1 << 12)
|
||||
|
||||
|
||||
typedef struct {
|
||||
probability choice;
|
||||
probability choice2;
|
||||
probability low[POS_STATES_MAX][LEN_LOW_SYMBOLS];
|
||||
probability mid[POS_STATES_MAX][LEN_MID_SYMBOLS];
|
||||
probability high[LEN_HIGH_SYMBOLS];
|
||||
|
||||
uint32_t prices[POS_STATES_MAX][LEN_SYMBOLS];
|
||||
uint32_t table_size;
|
||||
uint32_t counters[POS_STATES_MAX];
|
||||
|
||||
} lzma_length_encoder;
|
||||
|
||||
|
||||
typedef struct {
|
||||
lzma_lzma_state state;
|
||||
|
||||
bool prev_1_is_literal;
|
||||
bool prev_2;
|
||||
|
||||
uint32_t pos_prev_2;
|
||||
uint32_t back_prev_2;
|
||||
|
||||
uint32_t price;
|
||||
uint32_t pos_prev; // pos_next;
|
||||
uint32_t back_prev;
|
||||
|
||||
uint32_t backs[REPS];
|
||||
|
||||
} lzma_optimal;
|
||||
|
||||
|
||||
struct lzma_lzma1_encoder_s {
|
||||
/// Range encoder
|
||||
lzma_range_encoder rc;
|
||||
|
||||
/// State
|
||||
lzma_lzma_state state;
|
||||
|
||||
/// The four most recent match distances
|
||||
uint32_t reps[REPS];
|
||||
|
||||
/// Array of match candidates
|
||||
lzma_match matches[MATCH_LEN_MAX + 1];
|
||||
|
||||
/// Number of match candidates in matches[]
|
||||
uint32_t matches_count;
|
||||
|
||||
/// Variable to hold the length of the longest match between calls
|
||||
/// to lzma_lzma_optimum_*().
|
||||
uint32_t longest_match_length;
|
||||
|
||||
/// True if using getoptimumfast
|
||||
bool fast_mode;
|
||||
|
||||
/// True if the encoder has been initialized by encoding the first
|
||||
/// byte as a literal.
|
||||
bool is_initialized;
|
||||
|
||||
/// True if the range encoder has been flushed, but not all bytes
|
||||
/// have been written to the output buffer yet.
|
||||
bool is_flushed;
|
||||
|
||||
uint32_t pos_mask; ///< (1 << pos_bits) - 1
|
||||
uint32_t literal_context_bits;
|
||||
uint32_t literal_pos_mask;
|
||||
|
||||
// These are the same as in lzma_decoder.c. See comments there.
|
||||
probability literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
|
||||
probability is_match[STATES][POS_STATES_MAX];
|
||||
probability is_rep[STATES];
|
||||
probability is_rep0[STATES];
|
||||
probability is_rep1[STATES];
|
||||
probability is_rep2[STATES];
|
||||
probability is_rep0_long[STATES][POS_STATES_MAX];
|
||||
probability dist_slot[DIST_STATES][DIST_SLOTS];
|
||||
probability dist_special[FULL_DISTANCES - DIST_MODEL_END];
|
||||
probability dist_align[ALIGN_SIZE];
|
||||
|
||||
// These are the same as in lzma_decoder.c except that the encoders
|
||||
// include also price tables.
|
||||
lzma_length_encoder match_len_encoder;
|
||||
lzma_length_encoder rep_len_encoder;
|
||||
|
||||
// Price tables
|
||||
uint32_t dist_slot_prices[DIST_STATES][DIST_SLOTS];
|
||||
uint32_t dist_prices[DIST_STATES][FULL_DISTANCES];
|
||||
uint32_t dist_table_size;
|
||||
uint32_t match_price_count;
|
||||
|
||||
uint32_t align_prices[ALIGN_SIZE];
|
||||
uint32_t align_price_count;
|
||||
|
||||
// Optimal
|
||||
uint32_t opts_end_index;
|
||||
uint32_t opts_current_index;
|
||||
lzma_optimal opts[OPTS];
|
||||
};
|
||||
|
||||
|
||||
extern void lzma_lzma_optimum_fast(
|
||||
lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf,
|
||||
uint32_t *restrict back_res, uint32_t *restrict len_res);
|
||||
|
||||
extern void lzma_lzma_optimum_normal(lzma_lzma1_encoder *restrict coder,
|
||||
lzma_mf *restrict mf, uint32_t *restrict back_res,
|
||||
uint32_t *restrict len_res, uint32_t position);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,92 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file price.h
|
||||
/// \brief Probability price calculation
|
||||
//
|
||||
// Author: Igor Pavlov
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_PRICE_H
|
||||
#define LZMA_PRICE_H
|
||||
|
||||
|
||||
#define RC_MOVE_REDUCING_BITS 4
|
||||
#define RC_BIT_PRICE_SHIFT_BITS 4
|
||||
#define RC_PRICE_TABLE_SIZE (RC_BIT_MODEL_TOTAL >> RC_MOVE_REDUCING_BITS)
|
||||
|
||||
#define RC_INFINITY_PRICE (UINT32_C(1) << 30)
|
||||
|
||||
|
||||
/// Lookup table for the inline functions defined in this file.
|
||||
extern const uint8_t lzma_rc_prices[RC_PRICE_TABLE_SIZE];
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
rc_bit_price(const probability prob, const uint32_t bit)
|
||||
{
|
||||
return lzma_rc_prices[(prob ^ ((UINT32_C(0) - bit)
|
||||
& (RC_BIT_MODEL_TOTAL - 1))) >> RC_MOVE_REDUCING_BITS];
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
rc_bit_0_price(const probability prob)
|
||||
{
|
||||
return lzma_rc_prices[prob >> RC_MOVE_REDUCING_BITS];
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
rc_bit_1_price(const probability prob)
|
||||
{
|
||||
return lzma_rc_prices[(prob ^ (RC_BIT_MODEL_TOTAL - 1))
|
||||
>> RC_MOVE_REDUCING_BITS];
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
rc_bittree_price(const probability *const probs,
|
||||
const uint32_t bit_levels, uint32_t symbol)
|
||||
{
|
||||
uint32_t price = 0;
|
||||
symbol += UINT32_C(1) << bit_levels;
|
||||
|
||||
do {
|
||||
const uint32_t bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += rc_bit_price(probs[symbol], bit);
|
||||
} while (symbol != 1);
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
rc_bittree_reverse_price(const probability *const probs,
|
||||
uint32_t bit_levels, uint32_t symbol)
|
||||
{
|
||||
uint32_t price = 0;
|
||||
uint32_t model_index = 1;
|
||||
|
||||
do {
|
||||
const uint32_t bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
price += rc_bit_price(probs[model_index], bit);
|
||||
model_index = (model_index << 1) + bit;
|
||||
} while (--bit_levels != 0);
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
|
||||
static inline uint32_t
|
||||
rc_direct_price(const uint32_t bits)
|
||||
{
|
||||
return bits << RC_BIT_PRICE_SHIFT_BITS;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
/* This file has been automatically generated by price_tablegen.c. */
|
||||
|
||||
#include "range_encoder.h"
|
||||
|
||||
const uint8_t lzma_rc_prices[RC_PRICE_TABLE_SIZE] = {
|
||||
128, 103, 91, 84, 78, 73, 69, 66,
|
||||
63, 61, 58, 56, 54, 52, 51, 49,
|
||||
48, 46, 45, 44, 43, 42, 41, 40,
|
||||
39, 38, 37, 36, 35, 34, 34, 33,
|
||||
32, 31, 31, 30, 29, 29, 28, 28,
|
||||
27, 26, 26, 25, 25, 24, 24, 23,
|
||||
23, 22, 22, 22, 21, 21, 20, 20,
|
||||
19, 19, 19, 18, 18, 17, 17, 17,
|
||||
16, 16, 16, 15, 15, 15, 14, 14,
|
||||
14, 13, 13, 13, 12, 12, 12, 11,
|
||||
11, 11, 11, 10, 10, 10, 10, 9,
|
||||
9, 9, 9, 8, 8, 8, 8, 7,
|
||||
7, 7, 7, 6, 6, 6, 6, 5,
|
||||
5, 5, 5, 5, 4, 4, 4, 4,
|
||||
3, 3, 3, 3, 3, 2, 2, 2,
|
||||
2, 2, 2, 1, 1, 1, 1, 1
|
||||
};
|
||||
@@ -0,0 +1,73 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file range_common.h
|
||||
/// \brief Common things for range encoder and decoder
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_RANGE_COMMON_H
|
||||
#define LZMA_RANGE_COMMON_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "common.h"
|
||||
#endif
|
||||
|
||||
|
||||
///////////////
|
||||
// Constants //
|
||||
///////////////
|
||||
|
||||
#define RC_SHIFT_BITS 8
|
||||
#define RC_TOP_BITS 24
|
||||
#define RC_TOP_VALUE (UINT32_C(1) << RC_TOP_BITS)
|
||||
#define RC_BIT_MODEL_TOTAL_BITS 11
|
||||
#define RC_BIT_MODEL_TOTAL (UINT32_C(1) << RC_BIT_MODEL_TOTAL_BITS)
|
||||
#define RC_MOVE_BITS 5
|
||||
|
||||
|
||||
////////////
|
||||
// Macros //
|
||||
////////////
|
||||
|
||||
// Resets the probability so that both 0 and 1 have probability of 50 %
|
||||
#define bit_reset(prob) \
|
||||
prob = RC_BIT_MODEL_TOTAL >> 1
|
||||
|
||||
// This does the same for a complete bit tree.
|
||||
// (A tree represented as an array.)
|
||||
#define bittree_reset(probs, bit_levels) \
|
||||
for (uint32_t bt_i = 0; bt_i < (1 << (bit_levels)); ++bt_i) \
|
||||
bit_reset((probs)[bt_i])
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Type definitions //
|
||||
//////////////////////
|
||||
|
||||
/// \brief Type of probabilities used with range coder
|
||||
///
|
||||
/// This needs to be at least 12-bit integer, so uint16_t is a logical choice.
|
||||
/// However, on some architecture and compiler combinations, a bigger type
|
||||
/// may give better speed, because the probability variables are accessed
|
||||
/// a lot. On the other hand, bigger probability type increases cache
|
||||
/// footprint, since there are 2 to 14 thousand probability variables in
|
||||
/// LZMA (assuming the limit of lc + lp <= 4; with lc + lp <= 12 there
|
||||
/// would be about 1.5 million variables).
|
||||
///
|
||||
/// With malicious files, the initialization speed of the LZMA decoder can
|
||||
/// become important. In that case, smaller probability variables mean that
|
||||
/// there is less bytes to write to RAM, which makes initialization faster.
|
||||
/// With big probability type, the initialization can become so slow that it
|
||||
/// can be a problem e.g. for email servers doing virus scanning.
|
||||
///
|
||||
/// I will be sticking to uint16_t unless some specific architectures
|
||||
/// are *much* faster (20-50 %) with uint32_t.
|
||||
typedef uint16_t probability;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,185 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file range_decoder.h
|
||||
/// \brief Range Decoder
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_RANGE_DECODER_H
|
||||
#define LZMA_RANGE_DECODER_H
|
||||
|
||||
#include "range_common.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t range;
|
||||
uint32_t code;
|
||||
uint32_t init_bytes_left;
|
||||
} lzma_range_decoder;
|
||||
|
||||
|
||||
/// Reads the first five bytes to initialize the range decoder.
|
||||
static inline lzma_ret
|
||||
rc_read_init(lzma_range_decoder *rc, const uint8_t *restrict in,
|
||||
size_t *restrict in_pos, size_t in_size)
|
||||
{
|
||||
while (rc->init_bytes_left > 0) {
|
||||
if (*in_pos == in_size)
|
||||
return LZMA_OK;
|
||||
|
||||
// The first byte is always 0x00. It could have been omitted
|
||||
// in LZMA2 but it wasn't, so one byte is wasted in every
|
||||
// LZMA2 chunk.
|
||||
if (rc->init_bytes_left == 5 && in[*in_pos] != 0x00)
|
||||
return LZMA_DATA_ERROR;
|
||||
|
||||
rc->code = (rc->code << 8) | in[*in_pos];
|
||||
++*in_pos;
|
||||
--rc->init_bytes_left;
|
||||
}
|
||||
|
||||
return LZMA_STREAM_END;
|
||||
}
|
||||
|
||||
|
||||
/// Makes local copies of range decoder and *in_pos variables. Doing this
|
||||
/// improves speed significantly. The range decoder macros expect also
|
||||
/// variables `in' and `in_size' to be defined.
|
||||
#define rc_to_local(range_decoder, in_pos) \
|
||||
lzma_range_decoder rc = range_decoder; \
|
||||
size_t rc_in_pos = (in_pos); \
|
||||
uint32_t rc_bound
|
||||
|
||||
|
||||
/// Stores the local copes back to the range decoder structure.
|
||||
#define rc_from_local(range_decoder, in_pos) \
|
||||
do { \
|
||||
range_decoder = rc; \
|
||||
in_pos = rc_in_pos; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/// Resets the range decoder structure.
|
||||
#define rc_reset(range_decoder) \
|
||||
do { \
|
||||
(range_decoder).range = UINT32_MAX; \
|
||||
(range_decoder).code = 0; \
|
||||
(range_decoder).init_bytes_left = 5; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/// When decoding has been properly finished, rc.code is always zero unless
|
||||
/// the input stream is corrupt. So checking this can catch some corrupt
|
||||
/// files especially if they don't have any other integrity check.
|
||||
#define rc_is_finished(range_decoder) \
|
||||
((range_decoder).code == 0)
|
||||
|
||||
|
||||
/// Read the next input byte if needed. If more input is needed but there is
|
||||
/// no more input available, "goto out" is used to jump out of the main
|
||||
/// decoder loop.
|
||||
#define rc_normalize(seq) \
|
||||
do { \
|
||||
if (rc.range < RC_TOP_VALUE) { \
|
||||
if (unlikely(rc_in_pos == in_size)) { \
|
||||
coder->sequence = seq; \
|
||||
goto out; \
|
||||
} \
|
||||
rc.range <<= RC_SHIFT_BITS; \
|
||||
rc.code = (rc.code << RC_SHIFT_BITS) | in[rc_in_pos++]; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/// Start decoding a bit. This must be used together with rc_update_0()
|
||||
/// and rc_update_1():
|
||||
///
|
||||
/// rc_if_0(prob, seq) {
|
||||
/// rc_update_0(prob);
|
||||
/// // Do something
|
||||
/// } else {
|
||||
/// rc_update_1(prob);
|
||||
/// // Do something else
|
||||
/// }
|
||||
///
|
||||
#define rc_if_0(prob, seq) \
|
||||
rc_normalize(seq); \
|
||||
rc_bound = (rc.range >> RC_BIT_MODEL_TOTAL_BITS) * (prob); \
|
||||
if (rc.code < rc_bound)
|
||||
|
||||
|
||||
/// Update the range decoder state and the used probability variable to
|
||||
/// match a decoded bit of 0.
|
||||
#define rc_update_0(prob) \
|
||||
do { \
|
||||
rc.range = rc_bound; \
|
||||
prob += (RC_BIT_MODEL_TOTAL - (prob)) >> RC_MOVE_BITS; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/// Update the range decoder state and the used probability variable to
|
||||
/// match a decoded bit of 1.
|
||||
#define rc_update_1(prob) \
|
||||
do { \
|
||||
rc.range -= rc_bound; \
|
||||
rc.code -= rc_bound; \
|
||||
prob -= (prob) >> RC_MOVE_BITS; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/// Decodes one bit and runs action0 or action1 depending on the decoded bit.
|
||||
/// This macro is used as the last step in bittree reverse decoders since
|
||||
/// those don't use "symbol" for anything else than indexing the probability
|
||||
/// arrays.
|
||||
#define rc_bit_last(prob, action0, action1, seq) \
|
||||
do { \
|
||||
rc_if_0(prob, seq) { \
|
||||
rc_update_0(prob); \
|
||||
action0; \
|
||||
} else { \
|
||||
rc_update_1(prob); \
|
||||
action1; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/// Decodes one bit, updates "symbol", and runs action0 or action1 depending
|
||||
/// on the decoded bit.
|
||||
#define rc_bit(prob, action0, action1, seq) \
|
||||
rc_bit_last(prob, \
|
||||
symbol <<= 1; action0, \
|
||||
symbol = (symbol << 1) + 1; action1, \
|
||||
seq);
|
||||
|
||||
|
||||
/// Like rc_bit() but add "case seq:" as a prefix. This makes the unrolled
|
||||
/// loops more readable because the code isn't littered with "case"
|
||||
/// statements. On the other hand this also makes it less readable, since
|
||||
/// spotting the places where the decoder loop may be restarted is less
|
||||
/// obvious.
|
||||
#define rc_bit_case(prob, action0, action1, seq) \
|
||||
case seq: rc_bit(prob, action0, action1, seq)
|
||||
|
||||
|
||||
/// Decode a bit without using a probability.
|
||||
#define rc_direct(dest, seq) \
|
||||
do { \
|
||||
rc_normalize(seq); \
|
||||
rc.range >>= 1; \
|
||||
rc.code -= rc.range; \
|
||||
rc_bound = UINT32_C(0) - (rc.code >> 31); \
|
||||
rc.code += rc.range & rc_bound; \
|
||||
dest = (dest << 1) + (rc_bound + 1); \
|
||||
} while (0)
|
||||
|
||||
|
||||
// NOTE: No macros are provided for bittree decoding. It seems to be simpler
|
||||
// to just write them open in the code.
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,231 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
/// \file range_encoder.h
|
||||
/// \brief Range Encoder
|
||||
///
|
||||
// Authors: Igor Pavlov
|
||||
// Lasse Collin
|
||||
//
|
||||
// This file has been put into the public domain.
|
||||
// You can do whatever you want with this file.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef LZMA_RANGE_ENCODER_H
|
||||
#define LZMA_RANGE_ENCODER_H
|
||||
|
||||
#include "range_common.h"
|
||||
#include "price.h"
|
||||
|
||||
|
||||
/// Maximum number of symbols that can be put pending into lzma_range_encoder
|
||||
/// structure between calls to lzma_rc_encode(). For LZMA, 52+5 is enough
|
||||
/// (match with big distance and length followed by range encoder flush).
|
||||
#define RC_SYMBOLS_MAX 58
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint64_t low;
|
||||
uint64_t cache_size;
|
||||
uint32_t range;
|
||||
uint8_t cache;
|
||||
|
||||
/// Number of symbols in the tables
|
||||
size_t count;
|
||||
|
||||
/// rc_encode()'s position in the tables
|
||||
size_t pos;
|
||||
|
||||
/// Symbols to encode
|
||||
enum {
|
||||
RC_BIT_0,
|
||||
RC_BIT_1,
|
||||
RC_DIRECT_0,
|
||||
RC_DIRECT_1,
|
||||
RC_FLUSH,
|
||||
} symbols[RC_SYMBOLS_MAX];
|
||||
|
||||
/// Probabilities associated with RC_BIT_0 or RC_BIT_1
|
||||
probability *probs[RC_SYMBOLS_MAX];
|
||||
|
||||
} lzma_range_encoder;
|
||||
|
||||
|
||||
static inline void
|
||||
rc_reset(lzma_range_encoder *rc)
|
||||
{
|
||||
rc->low = 0;
|
||||
rc->cache_size = 1;
|
||||
rc->range = UINT32_MAX;
|
||||
rc->cache = 0;
|
||||
rc->count = 0;
|
||||
rc->pos = 0;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
rc_bit(lzma_range_encoder *rc, probability *prob, uint32_t bit)
|
||||
{
|
||||
rc->symbols[rc->count] = bit;
|
||||
rc->probs[rc->count] = prob;
|
||||
++rc->count;
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
rc_bittree(lzma_range_encoder *rc, probability *probs,
|
||||
uint32_t bit_count, uint32_t symbol)
|
||||
{
|
||||
uint32_t model_index = 1;
|
||||
|
||||
do {
|
||||
const uint32_t bit = (symbol >> --bit_count) & 1;
|
||||
rc_bit(rc, &probs[model_index], bit);
|
||||
model_index = (model_index << 1) + bit;
|
||||
} while (bit_count != 0);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
rc_bittree_reverse(lzma_range_encoder *rc, probability *probs,
|
||||
uint32_t bit_count, uint32_t symbol)
|
||||
{
|
||||
uint32_t model_index = 1;
|
||||
|
||||
do {
|
||||
const uint32_t bit = symbol & 1;
|
||||
symbol >>= 1;
|
||||
rc_bit(rc, &probs[model_index], bit);
|
||||
model_index = (model_index << 1) + bit;
|
||||
} while (--bit_count != 0);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
rc_direct(lzma_range_encoder *rc,
|
||||
uint32_t value, uint32_t bit_count)
|
||||
{
|
||||
do {
|
||||
rc->symbols[rc->count++]
|
||||
= RC_DIRECT_0 + ((value >> --bit_count) & 1);
|
||||
} while (bit_count != 0);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
rc_flush(lzma_range_encoder *rc)
|
||||
{
|
||||
for (size_t i = 0; i < 5; ++i)
|
||||
rc->symbols[rc->count++] = RC_FLUSH;
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
rc_shift_low(lzma_range_encoder *rc,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
{
|
||||
if ((uint32_t)(rc->low) < (uint32_t)(0xFF000000)
|
||||
|| (uint32_t)(rc->low >> 32) != 0) {
|
||||
do {
|
||||
if (*out_pos == out_size)
|
||||
return true;
|
||||
|
||||
out[*out_pos] = rc->cache + (uint8_t)(rc->low >> 32);
|
||||
++*out_pos;
|
||||
rc->cache = 0xFF;
|
||||
|
||||
} while (--rc->cache_size != 0);
|
||||
|
||||
rc->cache = (rc->low >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
++rc->cache_size;
|
||||
rc->low = (rc->low & 0x00FFFFFF) << RC_SHIFT_BITS;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
rc_encode(lzma_range_encoder *rc,
|
||||
uint8_t *out, size_t *out_pos, size_t out_size)
|
||||
{
|
||||
assert(rc->count <= RC_SYMBOLS_MAX);
|
||||
|
||||
while (rc->pos < rc->count) {
|
||||
// Normalize
|
||||
if (rc->range < RC_TOP_VALUE) {
|
||||
if (rc_shift_low(rc, out, out_pos, out_size))
|
||||
return true;
|
||||
|
||||
rc->range <<= RC_SHIFT_BITS;
|
||||
}
|
||||
|
||||
// Encode a bit
|
||||
switch (rc->symbols[rc->pos]) {
|
||||
case RC_BIT_0: {
|
||||
probability prob = *rc->probs[rc->pos];
|
||||
rc->range = (rc->range >> RC_BIT_MODEL_TOTAL_BITS)
|
||||
* prob;
|
||||
prob += (RC_BIT_MODEL_TOTAL - prob) >> RC_MOVE_BITS;
|
||||
*rc->probs[rc->pos] = prob;
|
||||
break;
|
||||
}
|
||||
|
||||
case RC_BIT_1: {
|
||||
probability prob = *rc->probs[rc->pos];
|
||||
const uint32_t bound = prob * (rc->range
|
||||
>> RC_BIT_MODEL_TOTAL_BITS);
|
||||
rc->low += bound;
|
||||
rc->range -= bound;
|
||||
prob -= prob >> RC_MOVE_BITS;
|
||||
*rc->probs[rc->pos] = prob;
|
||||
break;
|
||||
}
|
||||
|
||||
case RC_DIRECT_0:
|
||||
rc->range >>= 1;
|
||||
break;
|
||||
|
||||
case RC_DIRECT_1:
|
||||
rc->range >>= 1;
|
||||
rc->low += rc->range;
|
||||
break;
|
||||
|
||||
case RC_FLUSH:
|
||||
// Prevent further normalizations.
|
||||
rc->range = UINT32_MAX;
|
||||
|
||||
// Flush the last five bytes (see rc_flush()).
|
||||
do {
|
||||
if (rc_shift_low(rc, out, out_pos, out_size))
|
||||
return true;
|
||||
} while (++rc->pos < rc->count);
|
||||
|
||||
// Reset the range encoder so we are ready to continue
|
||||
// encoding if we weren't finishing the stream.
|
||||
rc_reset(rc);
|
||||
return false;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
++rc->pos;
|
||||
}
|
||||
|
||||
rc->count = 0;
|
||||
rc->pos = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static inline uint64_t
|
||||
rc_pending(const lzma_range_encoder *rc)
|
||||
{
|
||||
return rc->cache_size + 5 - 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user