source: trunk/target/linux/generic/patches-3.6/510-jffs2_make_lzma_available.patch @ 33911

Last change on this file since 33911 was 33911, checked in by florian, 5 years ago

[kernel] make all 3.6 patches apply and build

File size: 140.5 KB
  • fs/jffs2/Kconfig

    a b config JFFS2_LZO 
    139139          This feature was added in July, 2007. Say 'N' if you need 
    140140          compatibility with older bootloaders or kernels. 
    141141 
     142config JFFS2_LZMA 
     143        bool "JFFS2 LZMA compression support" if JFFS2_COMPRESSION_OPTIONS 
     144        select LZMA_COMPRESS 
     145        select LZMA_DECOMPRESS 
     146        depends on JFFS2_FS 
     147        default n 
     148        help 
     149          JFFS2 wrapper to the LZMA C SDK 
     150 
    142151config JFFS2_RTIME 
    143152        bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS 
    144153        depends on JFFS2_FS 
  • fs/jffs2/Makefile

    a b jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rub 
    1818jffs2-$(CONFIG_JFFS2_RTIME)     += compr_rtime.o 
    1919jffs2-$(CONFIG_JFFS2_ZLIB)      += compr_zlib.o 
    2020jffs2-$(CONFIG_JFFS2_LZO)       += compr_lzo.o 
     21jffs2-$(CONFIG_JFFS2_LZMA)      += compr_lzma.o 
    2122jffs2-$(CONFIG_JFFS2_SUMMARY)   += summary.o 
     23 
     24CFLAGS_compr_lzma.o += -Iinclude/linux -Ilib/lzma 
  • fs/jffs2/compr.c

    a b int __init jffs2_compressors_init(void) 
    378378#ifdef CONFIG_JFFS2_LZO 
    379379        jffs2_lzo_init(); 
    380380#endif 
     381#ifdef CONFIG_JFFS2_LZMA 
     382        jffs2_lzma_init(); 
     383#endif 
    381384/* Setting default compression mode */ 
    382385#ifdef CONFIG_JFFS2_CMODE_NONE 
    383386        jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; 
    int __init jffs2_compressors_init(void) 
    401404int jffs2_compressors_exit(void) 
    402405{ 
    403406/* Unregistering compressors */ 
     407#ifdef CONFIG_JFFS2_LZMA 
     408        jffs2_lzma_exit(); 
     409#endif 
    404410#ifdef CONFIG_JFFS2_LZO 
    405411        jffs2_lzo_exit(); 
    406412#endif 
  • fs/jffs2/compr.h

    a b  
    2929#define JFFS2_DYNRUBIN_PRIORITY  20 
    3030#define JFFS2_LZARI_PRIORITY     30 
    3131#define JFFS2_RTIME_PRIORITY     50 
    32 #define JFFS2_ZLIB_PRIORITY      60 
    33 #define JFFS2_LZO_PRIORITY       80 
    34  
     32#define JFFS2_LZMA_PRIORITY      70 
     33#define JFFS2_ZLIB_PRIORITY      80 
     34#define JFFS2_LZO_PRIORITY       90 
    3535 
    3636#define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ 
    3737#define JFFS2_DYNRUBIN_DISABLED  /*        for decompression */ 
    void jffs2_zlib_exit(void); 
    101101int jffs2_lzo_init(void); 
    102102void jffs2_lzo_exit(void); 
    103103#endif 
     104#ifdef CONFIG_JFFS2_LZMA 
     105int jffs2_lzma_init(void); 
     106void jffs2_lzma_exit(void); 
     107#endif 
    104108 
    105109#endif /* __JFFS2_COMPR_H__ */ 
  • new file fs/jffs2/compr_lzma.c

    - +  
     1/* 
     2 * JFFS2 -- Journalling Flash File System, Version 2. 
     3 * 
     4 * For licensing information, see the file 'LICENCE' in this directory. 
     5 * 
     6 * JFFS2 wrapper to the LZMA C SDK 
     7 * 
     8 */ 
     9 
     10#include <linux/lzma.h> 
     11#include "compr.h" 
     12 
     13#ifdef __KERNEL__ 
     14        static DEFINE_MUTEX(deflate_mutex); 
     15#endif 
     16 
     17CLzmaEncHandle *p; 
     18Byte propsEncoded[LZMA_PROPS_SIZE]; 
     19SizeT propsSize = sizeof(propsEncoded); 
     20 
     21STATIC void lzma_free_workspace(void) 
     22{ 
     23        LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc); 
     24} 
     25 
     26STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props) 
     27{ 
     28        if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL) 
     29        { 
     30                PRINT_ERROR("Failed to allocate lzma deflate workspace\n"); 
     31                return -ENOMEM; 
     32        } 
     33 
     34        if (LzmaEnc_SetProps(p, props) != SZ_OK) 
     35        { 
     36                lzma_free_workspace(); 
     37                return -1; 
     38        } 
     39         
     40        if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK) 
     41        { 
     42                lzma_free_workspace(); 
     43                return -1; 
     44        } 
     45 
     46        return 0; 
     47} 
     48 
     49STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out, 
     50                              uint32_t *sourcelen, uint32_t *dstlen) 
     51{ 
     52        SizeT compress_size = (SizeT)(*dstlen); 
     53        int ret; 
     54 
     55        #ifdef __KERNEL__ 
     56                mutex_lock(&deflate_mutex); 
     57        #endif 
     58 
     59        ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen, 
     60                0, NULL, &lzma_alloc, &lzma_alloc); 
     61 
     62        #ifdef __KERNEL__ 
     63                mutex_unlock(&deflate_mutex); 
     64        #endif 
     65 
     66        if (ret != SZ_OK) 
     67                return -1; 
     68 
     69        *dstlen = (uint32_t)compress_size; 
     70 
     71        return 0; 
     72} 
     73 
     74STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out, 
     75                                 uint32_t srclen, uint32_t destlen) 
     76{ 
     77        int ret; 
     78        SizeT dl = (SizeT)destlen; 
     79        SizeT sl = (SizeT)srclen; 
     80        ELzmaStatus status; 
     81         
     82        ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded, 
     83                propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc); 
     84 
     85        if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen) 
     86                return -1; 
     87 
     88        return 0; 
     89} 
     90 
     91static struct jffs2_compressor jffs2_lzma_comp = { 
     92        .priority = JFFS2_LZMA_PRIORITY, 
     93        .name = "lzma", 
     94        .compr = JFFS2_COMPR_LZMA, 
     95        .compress = &jffs2_lzma_compress, 
     96        .decompress = &jffs2_lzma_decompress, 
     97        .disabled = 0, 
     98}; 
     99 
     100int INIT jffs2_lzma_init(void) 
     101{ 
     102        int ret; 
     103        CLzmaEncProps props; 
     104        LzmaEncProps_Init(&props); 
     105 
     106        props.dictSize = LZMA_BEST_DICT(0x2000); 
     107        props.level = LZMA_BEST_LEVEL; 
     108        props.lc = LZMA_BEST_LC; 
     109        props.lp = LZMA_BEST_LP; 
     110        props.pb = LZMA_BEST_PB; 
     111        props.fb = LZMA_BEST_FB; 
     112 
     113        ret = lzma_alloc_workspace(&props); 
     114        if (ret < 0) 
     115                return ret; 
     116 
     117        ret = jffs2_register_compressor(&jffs2_lzma_comp); 
     118        if (ret) 
     119                lzma_free_workspace(); 
     120         
     121        return ret; 
     122} 
     123 
     124void jffs2_lzma_exit(void) 
     125{ 
     126        jffs2_unregister_compressor(&jffs2_lzma_comp); 
     127        lzma_free_workspace(); 
     128} 
  • fs/jffs2/super.c

    a b static int __init init_jffs2_fs(void) 
    373373        BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68); 
    374374        BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32); 
    375375 
    376         pr_info("version 2.2." 
     376        pr_info("version 2.2" 
    377377#ifdef CONFIG_JFFS2_FS_WRITEBUFFER 
    378378               " (NAND)" 
    379379#endif 
    380380#ifdef CONFIG_JFFS2_SUMMARY 
    381                " (SUMMARY) " 
     381               " (SUMMARY)" 
    382382#endif 
    383                " © 2001-2006 Red Hat, Inc.\n"); 
     383#ifdef CONFIG_JFFS2_ZLIB 
     384               " (ZLIB)" 
     385#endif 
     386#ifdef CONFIG_JFFS2_LZO 
     387               " (LZO)" 
     388#endif 
     389#ifdef CONFIG_JFFS2_LZMA 
     390               " (LZMA)" 
     391#endif 
     392#ifdef CONFIG_JFFS2_RTIME 
     393               " (RTIME)" 
     394#endif 
     395#ifdef CONFIG_JFFS2_RUBIN 
     396               " (RUBIN)" 
     397#endif 
     398#ifdef  CONFIG_JFFS2_CMODE_NONE 
     399               " (CMODE_NONE)" 
     400#endif 
     401#ifdef CONFIG_JFFS2_CMODE_PRIORITY 
     402               " (CMODE_PRIORITY)" 
     403#endif 
     404#ifdef CONFIG_JFFS2_CMODE_SIZE 
     405               " (CMODE_SIZE)" 
     406#endif 
     407#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO 
     408               " (CMODE_FAVOURLZO)" 
     409#endif 
     410               " (c) 2001-2006 Red Hat, Inc.\n"); 
    384411 
    385412        jffs2_inode_cachep = kmem_cache_create("jffs2_i", 
    386413                                             sizeof(struct jffs2_inode_info), 
  • include/linux/jffs2.h

    a b  
    4646#define JFFS2_COMPR_DYNRUBIN    0x05 
    4747#define JFFS2_COMPR_ZLIB        0x06 
    4848#define JFFS2_COMPR_LZO         0x07 
     49#define JFFS2_COMPR_LZMA        0x08 
    4950/* Compatibility flags. */ 
    5051#define JFFS2_COMPAT_MASK 0xc000      /* What do to if an unknown nodetype is found */ 
    5152#define JFFS2_NODE_ACCURATE 0x2000 
  • new file include/linux/lzma.h

    - +  
     1#ifndef __LZMA_H__ 
     2#define __LZMA_H__ 
     3 
     4#ifdef __KERNEL__ 
     5        #include <linux/kernel.h> 
     6        #include <linux/sched.h> 
     7        #include <linux/slab.h> 
     8        #include <linux/vmalloc.h> 
     9        #include <linux/init.h> 
     10        #define LZMA_MALLOC vmalloc 
     11        #define LZMA_FREE vfree 
     12        #define PRINT_ERROR(msg) printk(KERN_WARNING #msg) 
     13        #define INIT __init 
     14        #define STATIC static 
     15#else 
     16        #include <stdint.h> 
     17        #include <stdlib.h> 
     18        #include <stdio.h> 
     19        #include <unistd.h> 
     20        #include <string.h> 
     21        #include <asm/types.h> 
     22        #include <errno.h> 
     23        #include <linux/jffs2.h> 
     24        #ifndef PAGE_SIZE 
     25                extern int page_size; 
     26                #define PAGE_SIZE page_size 
     27        #endif 
     28        #define LZMA_MALLOC malloc 
     29        #define LZMA_FREE free 
     30        #define PRINT_ERROR(msg) fprintf(stderr, msg) 
     31        #define INIT 
     32        #define STATIC 
     33#endif 
     34 
     35#include "lzma/LzmaDec.h" 
     36#include "lzma/LzmaEnc.h" 
     37 
     38#define LZMA_BEST_LEVEL (9) 
     39#define LZMA_BEST_LC    (0) 
     40#define LZMA_BEST_LP    (0) 
     41#define LZMA_BEST_PB    (0) 
     42#define LZMA_BEST_FB  (273) 
     43 
     44#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2) 
     45 
     46static void *p_lzma_malloc(void *p, size_t size) 
     47{ 
     48        if (size == 0) 
     49                return NULL; 
     50 
     51        return LZMA_MALLOC(size); 
     52} 
     53 
     54static void p_lzma_free(void *p, void *address) 
     55{ 
     56        if (address != NULL) 
     57                LZMA_FREE(address); 
     58} 
     59 
     60static ISzAlloc lzma_alloc = {p_lzma_malloc, p_lzma_free}; 
     61 
     62#endif 
  • new file include/linux/lzma/LzFind.h

    - +  
     1/* LzFind.h -- Match finder for LZ algorithms 
     22009-04-22 : Igor Pavlov : Public domain */ 
     3 
     4#ifndef __LZ_FIND_H 
     5#define __LZ_FIND_H 
     6 
     7#include "Types.h" 
     8 
     9#ifdef __cplusplus 
     10extern "C" { 
     11#endif 
     12 
     13typedef UInt32 CLzRef; 
     14 
     15typedef struct _CMatchFinder 
     16{ 
     17  Byte *buffer; 
     18  UInt32 pos; 
     19  UInt32 posLimit; 
     20  UInt32 streamPos; 
     21  UInt32 lenLimit; 
     22 
     23  UInt32 cyclicBufferPos; 
     24  UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ 
     25 
     26  UInt32 matchMaxLen; 
     27  CLzRef *hash; 
     28  CLzRef *son; 
     29  UInt32 hashMask; 
     30  UInt32 cutValue; 
     31 
     32  Byte *bufferBase; 
     33  ISeqInStream *stream; 
     34  int streamEndWasReached; 
     35 
     36  UInt32 blockSize; 
     37  UInt32 keepSizeBefore; 
     38  UInt32 keepSizeAfter; 
     39 
     40  UInt32 numHashBytes; 
     41  int directInput; 
     42  size_t directInputRem; 
     43  int btMode; 
     44  int bigHash; 
     45  UInt32 historySize; 
     46  UInt32 fixedHashSize; 
     47  UInt32 hashSizeSum; 
     48  UInt32 numSons; 
     49  SRes result; 
     50  UInt32 crc[256]; 
     51} CMatchFinder; 
     52 
     53#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) 
     54#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) 
     55 
     56#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) 
     57 
     58int MatchFinder_NeedMove(CMatchFinder *p); 
     59Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); 
     60void MatchFinder_MoveBlock(CMatchFinder *p); 
     61void MatchFinder_ReadIfRequired(CMatchFinder *p); 
     62 
     63void MatchFinder_Construct(CMatchFinder *p); 
     64 
     65/* Conditions: 
     66     historySize <= 3 GB 
     67     keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB 
     68*/ 
     69int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, 
     70    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, 
     71    ISzAlloc *alloc); 
     72void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); 
     73void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); 
     74void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); 
     75 
     76UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, 
     77    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, 
     78    UInt32 *distances, UInt32 maxLen); 
     79 
     80/* 
     81Conditions: 
     82  Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. 
     83  Mf_GetPointerToCurrentPos_Func's result must be used only before any other function 
     84*/ 
     85 
     86typedef void (*Mf_Init_Func)(void *object); 
     87typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); 
     88typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); 
     89typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); 
     90typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); 
     91typedef void (*Mf_Skip_Func)(void *object, UInt32); 
     92 
     93typedef struct _IMatchFinder 
     94{ 
     95  Mf_Init_Func Init; 
     96  Mf_GetIndexByte_Func GetIndexByte; 
     97  Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; 
     98  Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; 
     99  Mf_GetMatches_Func GetMatches; 
     100  Mf_Skip_Func Skip; 
     101} IMatchFinder; 
     102 
     103void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); 
     104 
     105void MatchFinder_Init(CMatchFinder *p); 
     106UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); 
     107UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); 
     108void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); 
     109void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); 
     110 
     111#ifdef __cplusplus 
     112} 
     113#endif 
     114 
     115#endif 
  • new file include/linux/lzma/LzHash.h

    - +  
     1/* LzHash.h -- HASH functions for LZ algorithms 
     22009-02-07 : Igor Pavlov : Public domain */ 
     3 
     4#ifndef __LZ_HASH_H 
     5#define __LZ_HASH_H 
     6 
     7#define kHash2Size (1 << 10) 
     8#define kHash3Size (1 << 16) 
     9#define kHash4Size (1 << 20) 
     10 
     11#define kFix3HashSize (kHash2Size) 
     12#define kFix4HashSize (kHash2Size + kHash3Size) 
     13#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) 
     14 
     15#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); 
     16 
     17#define HASH3_CALC { \ 
     18  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 
     19  hash2Value = temp & (kHash2Size - 1); \ 
     20  hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } 
     21 
     22#define HASH4_CALC { \ 
     23  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 
     24  hash2Value = temp & (kHash2Size - 1); \ 
     25  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ 
     26  hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } 
     27 
     28#define HASH5_CALC { \ 
     29  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 
     30  hash2Value = temp & (kHash2Size - 1); \ 
     31  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ 
     32  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ 
     33  hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ 
     34  hash4Value &= (kHash4Size - 1); } 
     35 
     36/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ 
     37#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; 
     38 
     39 
     40#define MT_HASH2_CALC \ 
     41  hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); 
     42 
     43#define MT_HASH3_CALC { \ 
     44  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 
     45  hash2Value = temp & (kHash2Size - 1); \ 
     46  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } 
     47 
     48#define MT_HASH4_CALC { \ 
     49  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ 
     50  hash2Value = temp & (kHash2Size - 1); \ 
     51  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ 
     52  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } 
     53 
     54#endif 
  • new file include/linux/lzma/LzmaDec.h

    - +  
     1/* LzmaDec.h -- LZMA Decoder 
     22009-02-07 : Igor Pavlov : Public domain */ 
     3 
     4#ifndef __LZMA_DEC_H 
     5#define __LZMA_DEC_H 
     6 
     7#include "Types.h" 
     8 
     9#ifdef __cplusplus 
     10extern "C" { 
     11#endif 
     12 
     13/* #define _LZMA_PROB32 */ 
     14/* _LZMA_PROB32 can increase the speed on some CPUs, 
     15   but memory usage for CLzmaDec::probs will be doubled in that case */ 
     16 
     17#ifdef _LZMA_PROB32 
     18#define CLzmaProb UInt32 
     19#else 
     20#define CLzmaProb UInt16 
     21#endif 
     22 
     23 
     24/* ---------- LZMA Properties ---------- */ 
     25 
     26#define LZMA_PROPS_SIZE 5 
     27 
     28typedef struct _CLzmaProps 
     29{ 
     30  unsigned lc, lp, pb; 
     31  UInt32 dicSize; 
     32} CLzmaProps; 
     33 
     34/* LzmaProps_Decode - decodes properties 
     35Returns: 
     36  SZ_OK 
     37  SZ_ERROR_UNSUPPORTED - Unsupported properties 
     38*/ 
     39 
     40SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size); 
     41 
     42 
     43/* ---------- LZMA Decoder state ---------- */ 
     44 
     45/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. 
     46   Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ 
     47 
     48#define LZMA_REQUIRED_INPUT_MAX 20 
     49 
     50typedef struct 
     51{ 
     52  CLzmaProps prop; 
     53  CLzmaProb *probs; 
     54  Byte *dic; 
     55  const Byte *buf; 
     56  UInt32 range, code; 
     57  SizeT dicPos; 
     58  SizeT dicBufSize; 
     59  UInt32 processedPos; 
     60  UInt32 checkDicSize; 
     61  unsigned state; 
     62  UInt32 reps[4]; 
     63  unsigned remainLen; 
     64  int needFlush; 
     65  int needInitState; 
     66  UInt32 numProbs; 
     67  unsigned tempBufSize; 
     68  Byte tempBuf[LZMA_REQUIRED_INPUT_MAX]; 
     69} CLzmaDec; 
     70 
     71#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } 
     72 
     73void LzmaDec_Init(CLzmaDec *p); 
     74 
     75/* There are two types of LZMA streams: 
     76     0) Stream with end mark. That end mark adds about 6 bytes to compressed size. 
     77     1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ 
     78 
     79typedef enum 
     80{ 
     81  LZMA_FINISH_ANY,   /* finish at any point */ 
     82  LZMA_FINISH_END    /* block must be finished at the end */ 
     83} ELzmaFinishMode; 
     84 
     85/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! 
     86 
     87   You must use LZMA_FINISH_END, when you know that current output buffer 
     88   covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. 
     89 
     90   If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, 
     91   and output value of destLen will be less than output buffer size limit. 
     92   You can check status result also. 
     93 
     94   You can use multiple checks to test data integrity after full decompression: 
     95     1) Check Result and "status" variable. 
     96     2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. 
     97     3) Check that output(srcLen) = compressedSize, if you know real compressedSize. 
     98        You must use correct finish mode in that case. */ 
     99 
     100typedef enum 
     101{ 
     102  LZMA_STATUS_NOT_SPECIFIED,               /* use main error code instead */ 
     103  LZMA_STATUS_FINISHED_WITH_MARK,          /* stream was finished with end mark. */ 
     104  LZMA_STATUS_NOT_FINISHED,                /* stream was not finished */ 
     105  LZMA_STATUS_NEEDS_MORE_INPUT,            /* you must provide more input bytes */ 
     106  LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK  /* there is probability that stream was finished without end mark */ 
     107} ELzmaStatus; 
     108 
     109/* ELzmaStatus is used only as output value for function call */ 
     110 
     111 
     112/* ---------- Interfaces ---------- */ 
     113 
     114/* There are 3 levels of interfaces: 
     115     1) Dictionary Interface 
     116     2) Buffer Interface 
     117     3) One Call Interface 
     118   You can select any of these interfaces, but don't mix functions from different 
     119   groups for same object. */ 
     120 
     121 
     122/* There are two variants to allocate state for Dictionary Interface: 
     123     1) LzmaDec_Allocate / LzmaDec_Free 
     124     2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs 
     125   You can use variant 2, if you set dictionary buffer manually. 
     126   For Buffer Interface you must always use variant 1. 
     127 
     128LzmaDec_Allocate* can return: 
     129  SZ_OK 
     130  SZ_ERROR_MEM         - Memory allocation error 
     131  SZ_ERROR_UNSUPPORTED - Unsupported properties 
     132*/ 
     133    
     134SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc); 
     135void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); 
     136 
     137SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc); 
     138void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); 
     139 
     140/* ---------- Dictionary Interface ---------- */ 
     141 
     142/* You can use it, if you want to eliminate the overhead for data copying from 
     143   dictionary to some other external buffer. 
     144   You must work with CLzmaDec variables directly in this interface. 
     145 
     146   STEPS: 
     147     LzmaDec_Constr() 
     148     LzmaDec_Allocate() 
     149     for (each new stream) 
     150     { 
     151       LzmaDec_Init() 
     152       while (it needs more decompression) 
     153       { 
     154         LzmaDec_DecodeToDic() 
     155         use data from CLzmaDec::dic and update CLzmaDec::dicPos 
     156       } 
     157     } 
     158     LzmaDec_Free() 
     159*/ 
     160 
     161/* LzmaDec_DecodeToDic 
     162    
     163   The decoding to internal dictionary buffer (CLzmaDec::dic). 
     164   You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! 
     165 
     166finishMode: 
     167  It has meaning only if the decoding reaches output limit (dicLimit). 
     168  LZMA_FINISH_ANY - Decode just dicLimit bytes. 
     169  LZMA_FINISH_END - Stream must be finished after dicLimit. 
     170 
     171Returns: 
     172  SZ_OK 
     173    status: 
     174      LZMA_STATUS_FINISHED_WITH_MARK 
     175      LZMA_STATUS_NOT_FINISHED 
     176      LZMA_STATUS_NEEDS_MORE_INPUT 
     177      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK 
     178  SZ_ERROR_DATA - Data error 
     179*/ 
     180 
     181SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, 
     182    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); 
     183 
     184 
     185/* ---------- Buffer Interface ---------- */ 
     186 
     187/* It's zlib-like interface. 
     188   See LzmaDec_DecodeToDic description for information about STEPS and return results, 
     189   but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need 
     190   to work with CLzmaDec variables manually. 
     191 
     192finishMode: 
     193  It has meaning only if the decoding reaches output limit (*destLen). 
     194  LZMA_FINISH_ANY - Decode just destLen bytes. 
     195  LZMA_FINISH_END - Stream must be finished after (*destLen). 
     196*/ 
     197 
     198SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, 
     199    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); 
     200 
     201 
     202/* ---------- One Call Interface ---------- */ 
     203 
     204/* LzmaDecode 
     205 
     206finishMode: 
     207  It has meaning only if the decoding reaches output limit (*destLen). 
     208  LZMA_FINISH_ANY - Decode just destLen bytes. 
     209  LZMA_FINISH_END - Stream must be finished after (*destLen). 
     210 
     211Returns: 
     212  SZ_OK 
     213    status: 
     214      LZMA_STATUS_FINISHED_WITH_MARK 
     215      LZMA_STATUS_NOT_FINISHED 
     216      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK 
     217  SZ_ERROR_DATA - Data error 
     218  SZ_ERROR_MEM  - Memory allocation error 
     219  SZ_ERROR_UNSUPPORTED - Unsupported properties 
     220  SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). 
     221*/ 
     222 
     223SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 
     224    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, 
     225    ELzmaStatus *status, ISzAlloc *alloc); 
     226 
     227#ifdef __cplusplus 
     228} 
     229#endif 
     230 
     231#endif 
  • new file include/linux/lzma/LzmaEnc.h

    - +  
     1/*  LzmaEnc.h -- LZMA Encoder 
     22009-02-07 : Igor Pavlov : Public domain */ 
     3 
     4#ifndef __LZMA_ENC_H 
     5#define __LZMA_ENC_H 
     6 
     7#include "Types.h" 
     8 
     9#ifdef __cplusplus 
     10extern "C" { 
     11#endif 
     12 
     13#define LZMA_PROPS_SIZE 5 
     14 
     15typedef struct _CLzmaEncProps 
     16{ 
     17  int level;       /*  0 <= level <= 9 */ 
     18  UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version 
     19                      (1 << 12) <= dictSize <= (1 << 30) for 64-bit version 
     20                       default = (1 << 24) */ 
     21  int lc;          /* 0 <= lc <= 8, default = 3 */ 
     22  int lp;          /* 0 <= lp <= 4, default = 0 */ 
     23  int pb;          /* 0 <= pb <= 4, default = 2 */ 
     24  int algo;        /* 0 - fast, 1 - normal, default = 1 */ 
     25  int fb;          /* 5 <= fb <= 273, default = 32 */ 
     26  int btMode;      /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ 
     27  int numHashBytes; /* 2, 3 or 4, default = 4 */ 
     28  UInt32 mc;        /* 1 <= mc <= (1 << 30), default = 32 */ 
     29  unsigned writeEndMark;  /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ 
     30  int numThreads;  /* 1 or 2, default = 2 */ 
     31} CLzmaEncProps; 
     32 
     33void LzmaEncProps_Init(CLzmaEncProps *p); 
     34void LzmaEncProps_Normalize(CLzmaEncProps *p); 
     35UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); 
     36 
     37 
     38/* ---------- CLzmaEncHandle Interface ---------- */ 
     39 
     40/* LzmaEnc_* functions can return the following exit codes: 
     41Returns: 
     42  SZ_OK           - OK 
     43  SZ_ERROR_MEM    - Memory allocation error 
     44  SZ_ERROR_PARAM  - Incorrect paramater in props 
     45  SZ_ERROR_WRITE  - Write callback error. 
     46  SZ_ERROR_PROGRESS - some break from progress callback 
     47  SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) 
     48*/ 
     49 
     50typedef void * CLzmaEncHandle; 
     51 
     52CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); 
     53void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); 
     54SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); 
     55SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); 
     56SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, 
     57    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); 
     58SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, 
     59    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); 
     60 
     61/* ---------- One Call Interface ---------- */ 
     62 
     63/* LzmaEncode 
     64Return code: 
     65  SZ_OK               - OK 
     66  SZ_ERROR_MEM        - Memory allocation error 
     67  SZ_ERROR_PARAM      - Incorrect paramater 
     68  SZ_ERROR_OUTPUT_EOF - output buffer overflow 
     69  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version) 
     70*/ 
     71 
     72SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, 
     73    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, 
     74    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); 
     75 
     76#ifdef __cplusplus 
     77} 
     78#endif 
     79 
     80#endif 
  • new file include/linux/lzma/Types.h

    - +  
     1/* Types.h -- Basic types 
     22009-11-23 : Igor Pavlov : Public domain */ 
     3 
     4#ifndef __7Z_TYPES_H 
     5#define __7Z_TYPES_H 
     6 
     7#include <stddef.h> 
     8 
     9#ifdef _WIN32 
     10#include <windows.h> 
     11#endif 
     12 
     13#ifndef EXTERN_C_BEGIN 
     14#ifdef __cplusplus 
     15#define EXTERN_C_BEGIN extern "C" { 
     16#define EXTERN_C_END } 
     17#else 
     18#define EXTERN_C_BEGIN 
     19#define EXTERN_C_END 
     20#endif 
     21#endif 
     22 
     23EXTERN_C_BEGIN 
     24 
     25#define SZ_OK 0 
     26 
     27#define SZ_ERROR_DATA 1 
     28#define SZ_ERROR_MEM 2 
     29#define SZ_ERROR_CRC 3 
     30#define SZ_ERROR_UNSUPPORTED 4 
     31#define SZ_ERROR_PARAM 5 
     32#define SZ_ERROR_INPUT_EOF 6 
     33#define SZ_ERROR_OUTPUT_EOF 7 
     34#define SZ_ERROR_READ 8 
     35#define SZ_ERROR_WRITE 9 
     36#define SZ_ERROR_PROGRESS 10 
     37#define SZ_ERROR_FAIL 11 
     38#define SZ_ERROR_THREAD 12 
     39 
     40#define SZ_ERROR_ARCHIVE 16 
     41#define SZ_ERROR_NO_ARCHIVE 17 
     42 
     43typedef int SRes; 
     44 
     45#ifdef _WIN32 
     46typedef DWORD WRes; 
     47#else 
     48typedef int WRes; 
     49#endif 
     50 
     51#ifndef RINOK 
     52#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } 
     53#endif 
     54 
     55typedef unsigned char Byte; 
     56typedef short Int16; 
     57typedef unsigned short UInt16; 
     58 
     59#ifdef _LZMA_UINT32_IS_ULONG 
     60typedef long Int32; 
     61typedef unsigned long UInt32; 
     62#else 
     63typedef int Int32; 
     64typedef unsigned int UInt32; 
     65#endif 
     66 
     67#ifdef _SZ_NO_INT_64 
     68 
     69/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers. 
     70   NOTES: Some code will work incorrectly in that case! */ 
     71 
     72typedef long Int64; 
     73typedef unsigned long UInt64; 
     74 
     75#else 
     76 
     77#if defined(_MSC_VER) || defined(__BORLANDC__) 
     78typedef __int64 Int64; 
     79typedef unsigned __int64 UInt64; 
     80#else 
     81typedef long long int Int64; 
     82typedef unsigned long long int UInt64; 
     83#endif 
     84 
     85#endif 
     86 
     87#ifdef _LZMA_NO_SYSTEM_SIZE_T 
     88typedef UInt32 SizeT; 
     89#else 
     90typedef size_t SizeT; 
     91#endif 
     92 
     93typedef int Bool; 
     94#define True 1 
     95#define False 0 
     96 
     97 
     98#ifdef _WIN32 
     99#define MY_STD_CALL __stdcall 
     100#else 
     101#define MY_STD_CALL 
     102#endif 
     103 
     104#ifdef _MSC_VER 
     105 
     106#if _MSC_VER >= 1300 
     107#define MY_NO_INLINE __declspec(noinline) 
     108#else 
     109#define MY_NO_INLINE 
     110#endif 
     111 
     112#define MY_CDECL __cdecl 
     113#define MY_FAST_CALL __fastcall 
     114 
     115#else 
     116 
     117#define MY_CDECL 
     118#define MY_FAST_CALL 
     119 
     120#endif 
     121 
     122 
     123/* The following interfaces use first parameter as pointer to structure */ 
     124 
     125typedef struct 
     126{ 
     127  SRes (*Read)(void *p, void *buf, size_t *size); 
     128    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. 
     129       (output(*size) < input(*size)) is allowed */ 
     130} ISeqInStream; 
     131 
     132/* it can return SZ_ERROR_INPUT_EOF */ 
     133SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size); 
     134SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType); 
     135SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf); 
     136 
     137typedef struct 
     138{ 
     139  size_t (*Write)(void *p, const void *buf, size_t size); 
     140    /* Returns: result - the number of actually written bytes. 
     141       (result < size) means error */ 
     142} ISeqOutStream; 
     143 
     144typedef enum 
     145{ 
     146  SZ_SEEK_SET = 0, 
     147  SZ_SEEK_CUR = 1, 
     148  SZ_SEEK_END = 2 
     149} ESzSeek; 
     150 
     151typedef struct 
     152{ 
     153  SRes (*Read)(void *p, void *buf, size_t *size);  /* same as ISeqInStream::Read */ 
     154  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); 
     155} ISeekInStream; 
     156 
     157typedef struct 
     158{ 
     159  SRes (*Look)(void *p, void **buf, size_t *size); 
     160    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. 
     161       (output(*size) > input(*size)) is not allowed 
     162       (output(*size) < input(*size)) is allowed */ 
     163  SRes (*Skip)(void *p, size_t offset); 
     164    /* offset must be <= output(*size) of Look */ 
     165 
     166  SRes (*Read)(void *p, void *buf, size_t *size); 
     167    /* reads directly (without buffer). It's same as ISeqInStream::Read */ 
     168  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin); 
     169} ILookInStream; 
     170 
     171SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size); 
     172SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset); 
     173 
     174/* reads via ILookInStream::Read */ 
     175SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType); 
     176SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size); 
     177 
     178#define LookToRead_BUF_SIZE (1 << 14) 
     179 
     180typedef struct 
     181{ 
     182  ILookInStream s; 
     183  ISeekInStream *realStream; 
     184  size_t pos; 
     185  size_t size; 
     186  Byte buf[LookToRead_BUF_SIZE]; 
     187} CLookToRead; 
     188 
     189void LookToRead_CreateVTable(CLookToRead *p, int lookahead); 
     190void LookToRead_Init(CLookToRead *p); 
     191 
     192typedef struct 
     193{ 
     194  ISeqInStream s; 
     195  ILookInStream *realStream; 
     196} CSecToLook; 
     197 
     198void SecToLook_CreateVTable(CSecToLook *p); 
     199 
     200typedef struct 
     201{ 
     202  ISeqInStream s; 
     203  ILookInStream *realStream; 
     204} CSecToRead; 
     205 
     206void SecToRead_CreateVTable(CSecToRead *p); 
     207 
     208typedef struct 
     209{ 
     210  SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); 
     211    /* Returns: result. (result != SZ_OK) means break. 
     212       Value (UInt64)(Int64)-1 for size means unknown value. */ 
     213} ICompressProgress; 
     214 
     215typedef struct 
     216{ 
     217  void *(*Alloc)(void *p, size_t size); 
     218  void (*Free)(void *p, void *address); /* address can be 0 */ 
     219} ISzAlloc; 
     220 
     221#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) 
     222#define IAlloc_Free(p, a) (p)->Free((p), a) 
     223 
     224EXTERN_C_END 
     225 
     226#endif 
  • lib/Kconfig

    a b config LZO_DECOMPRESS 
    188188 
    189189source "lib/xz/Kconfig" 
    190190 
     191config LZMA_COMPRESS 
     192    tristate 
     193 
     194config LZMA_DECOMPRESS 
     195    tristate 
     196 
    191197# 
    192198# These all provide a common interface (hence the apparent duplication with 
    193199# ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.) 
  • lib/Makefile

    a b  
    22# Makefile for some libs needed in the kernel. 
    33# 
    44 
     5ifdef CONFIG_JFFS2_ZLIB 
     6        CONFIG_ZLIB_INFLATE:=y 
     7        CONFIG_ZLIB_DEFLATE:=y 
     8endif 
     9 
     10ifdef CONFIG_JFFS2_LZMA 
     11        CONFIG_LZMA_DECOMPRESS:=y 
     12        CONFIG_LZMA_COMPRESS:=y 
     13endif 
     14 
    515ifdef CONFIG_FUNCTION_TRACER 
    616ORIG_CFLAGS := $(KBUILD_CFLAGS) 
    717KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS)) 
    obj-$(CONFIG_LZO_COMPRESS) += lzo/ 
    7383obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ 
    7484obj-$(CONFIG_XZ_DEC) += xz/ 
    7585obj-$(CONFIG_RAID6_PQ) += raid6/ 
     86obj-$(CONFIG_LZMA_COMPRESS) += lzma/ 
     87obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/ 
    7688 
    7789lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o 
    7890lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o 
  • new file lib/lzma/LzFind.c

    - +  
     1/* LzFind.c -- Match finder for LZ algorithms 
     22009-04-22 : Igor Pavlov : Public domain */ 
     3 
     4#include <string.h> 
     5 
     6#include "LzFind.h" 
     7#include "LzHash.h" 
     8 
     9#define kEmptyHashValue 0 
     10#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) 
     11#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ 
     12#define kNormalizeMask (~(kNormalizeStepMin - 1)) 
     13#define kMaxHistorySize ((UInt32)3 << 30) 
     14 
     15#define kStartMaxLen 3 
     16 
     17static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) 
     18{ 
     19  if (!p->directInput) 
     20  { 
     21    alloc->Free(alloc, p->bufferBase); 
     22    p->bufferBase = 0; 
     23  } 
     24} 
     25 
     26/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ 
     27 
     28static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) 
     29{ 
     30  UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; 
     31  if (p->directInput) 
     32  { 
     33    p->blockSize = blockSize; 
     34    return 1; 
     35  } 
     36  if (p->bufferBase == 0 || p->blockSize != blockSize) 
     37  { 
     38    LzInWindow_Free(p, alloc); 
     39    p->blockSize = blockSize; 
     40    p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); 
     41  } 
     42  return (p->bufferBase != 0); 
     43} 
     44 
     45Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } 
     46Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } 
     47 
     48UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } 
     49 
     50void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) 
     51{ 
     52  p->posLimit -= subValue; 
     53  p->pos -= subValue; 
     54  p->streamPos -= subValue; 
     55} 
     56 
     57static void MatchFinder_ReadBlock(CMatchFinder *p) 
     58{ 
     59  if (p->streamEndWasReached || p->result != SZ_OK) 
     60    return; 
     61  if (p->directInput) 
     62  { 
     63    UInt32 curSize = 0xFFFFFFFF - p->streamPos; 
     64    if (curSize > p->directInputRem) 
     65      curSize = (UInt32)p->directInputRem; 
     66    p->directInputRem -= curSize; 
     67    p->streamPos += curSize; 
     68    if (p->directInputRem == 0) 
     69      p->streamEndWasReached = 1; 
     70    return; 
     71  } 
     72  for (;;) 
     73  { 
     74    Byte *dest = p->buffer + (p->streamPos - p->pos); 
     75    size_t size = (p->bufferBase + p->blockSize - dest); 
     76    if (size == 0) 
     77      return; 
     78    p->result = p->stream->Read(p->stream, dest, &size); 
     79    if (p->result != SZ_OK) 
     80      return; 
     81    if (size == 0) 
     82    { 
     83      p->streamEndWasReached = 1; 
     84      return; 
     85    } 
     86    p->streamPos += (UInt32)size; 
     87    if (p->streamPos - p->pos > p->keepSizeAfter) 
     88      return; 
     89  } 
     90} 
     91 
     92void MatchFinder_MoveBlock(CMatchFinder *p) 
     93{ 
     94  memmove(p->bufferBase, 
     95    p->buffer - p->keepSizeBefore, 
     96    (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); 
     97  p->buffer = p->bufferBase + p->keepSizeBefore; 
     98} 
     99 
     100int MatchFinder_NeedMove(CMatchFinder *p) 
     101{ 
     102  if (p->directInput) 
     103    return 0; 
     104  /* if (p->streamEndWasReached) return 0; */ 
     105  return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); 
     106} 
     107 
     108void MatchFinder_ReadIfRequired(CMatchFinder *p) 
     109{ 
     110  if (p->streamEndWasReached) 
     111    return; 
     112  if (p->keepSizeAfter >= p->streamPos - p->pos) 
     113    MatchFinder_ReadBlock(p); 
     114} 
     115 
     116static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) 
     117{ 
     118  if (MatchFinder_NeedMove(p)) 
     119    MatchFinder_MoveBlock(p); 
     120  MatchFinder_ReadBlock(p); 
     121} 
     122 
     123static void MatchFinder_SetDefaultSettings(CMatchFinder *p) 
     124{ 
     125  p->cutValue = 32; 
     126  p->btMode = 1; 
     127  p->numHashBytes = 4; 
     128  p->bigHash = 0; 
     129} 
     130 
     131#define kCrcPoly 0xEDB88320 
     132 
     133void MatchFinder_Construct(CMatchFinder *p) 
     134{ 
     135  UInt32 i; 
     136  p->bufferBase = 0; 
     137  p->directInput = 0; 
     138  p->hash = 0; 
     139  MatchFinder_SetDefaultSettings(p); 
     140 
     141  for (i = 0; i < 256; i++) 
     142  { 
     143    UInt32 r = i; 
     144    int j; 
     145    for (j = 0; j < 8; j++) 
     146      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); 
     147    p->crc[i] = r; 
     148  } 
     149} 
     150 
     151static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) 
     152{ 
     153  alloc->Free(alloc, p->hash); 
     154  p->hash = 0; 
     155} 
     156 
     157void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) 
     158{ 
     159  MatchFinder_FreeThisClassMemory(p, alloc); 
     160  LzInWindow_Free(p, alloc); 
     161} 
     162 
     163static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) 
     164{ 
     165  size_t sizeInBytes = (size_t)num * sizeof(CLzRef); 
     166  if (sizeInBytes / sizeof(CLzRef) != num) 
     167    return 0; 
     168  return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); 
     169} 
     170 
     171int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, 
     172    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, 
     173    ISzAlloc *alloc) 
     174{ 
     175  UInt32 sizeReserv; 
     176  if (historySize > kMaxHistorySize) 
     177  { 
     178    MatchFinder_Free(p, alloc); 
     179    return 0; 
     180  } 
     181  sizeReserv = historySize >> 1; 
     182  if (historySize > ((UInt32)2 << 30)) 
     183    sizeReserv = historySize >> 2; 
     184  sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); 
     185 
     186  p->keepSizeBefore = historySize + keepAddBufferBefore + 1; 
     187  p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; 
     188  /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ 
     189  if (LzInWindow_Create(p, sizeReserv, alloc)) 
     190  { 
     191    UInt32 newCyclicBufferSize = historySize + 1; 
     192    UInt32 hs; 
     193    p->matchMaxLen = matchMaxLen; 
     194    { 
     195      p->fixedHashSize = 0; 
     196      if (p->numHashBytes == 2) 
     197        hs = (1 << 16) - 1; 
     198      else 
     199      { 
     200        hs = historySize - 1; 
     201        hs |= (hs >> 1); 
     202        hs |= (hs >> 2); 
     203        hs |= (hs >> 4); 
     204        hs |= (hs >> 8); 
     205        hs >>= 1; 
     206        hs |= 0xFFFF; /* don't change it! It's required for Deflate */ 
     207        if (hs > (1 << 24)) 
     208        { 
     209          if (p->numHashBytes == 3) 
     210            hs = (1 << 24) - 1; 
     211          else 
     212            hs >>= 1; 
     213        } 
     214      } 
     215      p->hashMask = hs; 
     216      hs++; 
     217      if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; 
     218      if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; 
     219      if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; 
     220      hs += p->fixedHashSize; 
     221    } 
     222 
     223    { 
     224      UInt32 prevSize = p->hashSizeSum + p->numSons; 
     225      UInt32 newSize; 
     226      p->historySize = historySize; 
     227      p->hashSizeSum = hs; 
     228      p->cyclicBufferSize = newCyclicBufferSize; 
     229      p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); 
     230      newSize = p->hashSizeSum + p->numSons; 
     231      if (p->hash != 0 && prevSize == newSize) 
     232        return 1; 
     233      MatchFinder_FreeThisClassMemory(p, alloc); 
     234      p->hash = AllocRefs(newSize, alloc); 
     235      if (p->hash != 0) 
     236      { 
     237        p->son = p->hash + p->hashSizeSum; 
     238        return 1; 
     239      } 
     240    } 
     241  } 
     242  MatchFinder_Free(p, alloc); 
     243  return 0; 
     244} 
     245 
     246static void MatchFinder_SetLimits(CMatchFinder *p) 
     247{ 
     248  UInt32 limit = kMaxValForNormalize - p->pos; 
     249  UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; 
     250  if (limit2 < limit) 
     251    limit = limit2; 
     252  limit2 = p->streamPos - p->pos; 
     253  if (limit2 <= p->keepSizeAfter) 
     254  { 
     255    if (limit2 > 0) 
     256      limit2 = 1; 
     257  } 
     258  else 
     259    limit2 -= p->keepSizeAfter; 
     260  if (limit2 < limit) 
     261    limit = limit2; 
     262  { 
     263    UInt32 lenLimit = p->streamPos - p->pos; 
     264    if (lenLimit > p->matchMaxLen) 
     265      lenLimit = p->matchMaxLen; 
     266    p->lenLimit = lenLimit; 
     267  } 
     268  p->posLimit = p->pos + limit; 
     269} 
     270 
     271void MatchFinder_Init(CMatchFinder *p) 
     272{ 
     273  UInt32 i; 
     274  for (i = 0; i < p->hashSizeSum; i++) 
     275    p->hash[i] = kEmptyHashValue; 
     276  p->cyclicBufferPos = 0; 
     277  p->buffer = p->bufferBase; 
     278  p->pos = p->streamPos = p->cyclicBufferSize; 
     279  p->result = SZ_OK; 
     280  p->streamEndWasReached = 0; 
     281  MatchFinder_ReadBlock(p); 
     282  MatchFinder_SetLimits(p); 
     283} 
     284 
     285static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) 
     286{ 
     287  return (p->pos - p->historySize - 1) & kNormalizeMask; 
     288} 
     289 
     290void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) 
     291{ 
     292  UInt32 i; 
     293  for (i = 0; i < numItems; i++) 
     294  { 
     295    UInt32 value = items[i]; 
     296    if (value <= subValue) 
     297      value = kEmptyHashValue; 
     298    else 
     299      value -= subValue; 
     300    items[i] = value; 
     301  } 
     302} 
     303 
     304static void MatchFinder_Normalize(CMatchFinder *p) 
     305{ 
     306  UInt32 subValue = MatchFinder_GetSubValue(p); 
     307  MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); 
     308  MatchFinder_ReduceOffsets(p, subValue); 
     309} 
     310 
     311static void MatchFinder_CheckLimits(CMatchFinder *p) 
     312{ 
     313  if (p->pos == kMaxValForNormalize) 
     314    MatchFinder_Normalize(p); 
     315  if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) 
     316    MatchFinder_CheckAndMoveAndRead(p); 
     317  if (p->cyclicBufferPos == p->cyclicBufferSize) 
     318    p->cyclicBufferPos = 0; 
     319  MatchFinder_SetLimits(p); 
     320} 
     321 
     322static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, 
     323    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, 
     324    UInt32 *distances, UInt32 maxLen) 
     325{ 
     326  son[_cyclicBufferPos] = curMatch; 
     327  for (;;) 
     328  { 
     329    UInt32 delta = pos - curMatch; 
     330    if (cutValue-- == 0 || delta >= _cyclicBufferSize) 
     331      return distances; 
     332    { 
     333      const Byte *pb = cur - delta; 
     334      curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; 
     335      if (pb[maxLen] == cur[maxLen] && *pb == *cur) 
     336      { 
     337        UInt32 len = 0; 
     338        while (++len != lenLimit) 
     339          if (pb[len] != cur[len]) 
     340            break; 
     341        if (maxLen < len) 
     342        { 
     343          *distances++ = maxLen = len; 
     344          *distances++ = delta - 1; 
     345          if (len == lenLimit) 
     346            return distances; 
     347        } 
     348      } 
     349    } 
     350  } 
     351} 
     352 
     353UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, 
     354    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, 
     355    UInt32 *distances, UInt32 maxLen) 
     356{ 
     357  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; 
     358  CLzRef *ptr1 = son + (_cyclicBufferPos << 1); 
     359  UInt32 len0 = 0, len1 = 0; 
     360  for (;;) 
     361  { 
     362    UInt32 delta = pos - curMatch; 
     363    if (cutValue-- == 0 || delta >= _cyclicBufferSize) 
     364    { 
     365      *ptr0 = *ptr1 = kEmptyHashValue; 
     366      return distances; 
     367    } 
     368    { 
     369      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); 
     370      const Byte *pb = cur - delta; 
     371      UInt32 len = (len0 < len1 ? len0 : len1); 
     372      if (pb[len] == cur[len]) 
     373      { 
     374        if (++len != lenLimit && pb[len] == cur[len]) 
     375          while (++len != lenLimit) 
     376            if (pb[len] != cur[len]) 
     377              break; 
     378        if (maxLen < len) 
     379        { 
     380          *distances++ = maxLen = len; 
     381          *distances++ = delta - 1; 
     382          if (len == lenLimit) 
     383          { 
     384            *ptr1 = pair[0]; 
     385            *ptr0 = pair[1]; 
     386            return distances; 
     387          } 
     388        } 
     389      } 
     390      if (pb[len] < cur[len]) 
     391      { 
     392        *ptr1 = curMatch; 
     393        ptr1 = pair + 1; 
     394        curMatch = *ptr1; 
     395        len1 = len; 
     396      } 
     397      else 
     398      { 
     399        *ptr0 = curMatch; 
     400        ptr0 = pair; 
     401        curMatch = *ptr0; 
     402        len0 = len; 
     403      } 
     404    } 
     405  } 
     406} 
     407 
     408static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, 
     409    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) 
     410{ 
     411  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; 
     412  CLzRef *ptr1 = son + (_cyclicBufferPos << 1); 
     413  UInt32 len0 = 0, len1 = 0; 
     414  for (;;) 
     415  { 
     416    UInt32 delta = pos - curMatch; 
     417    if (cutValue-- == 0 || delta >= _cyclicBufferSize) 
     418    { 
     419      *ptr0 = *ptr1 = kEmptyHashValue; 
     420      return; 
     421    } 
     422    { 
     423      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); 
     424      const Byte *pb = cur - delta; 
     425      UInt32 len = (len0 < len1 ? len0 : len1); 
     426      if (pb[len] == cur[len]) 
     427      { 
     428        while (++len != lenLimit) 
     429          if (pb[len] != cur[len]) 
     430            break; 
     431        { 
     432          if (len == lenLimit) 
     433          { 
     434            *ptr1 = pair[0]; 
     435            *ptr0 = pair[1]; 
     436            return; 
     437          } 
     438        } 
     439      } 
     440      if (pb[len] < cur[len]) 
     441      { 
     442        *ptr1 = curMatch; 
     443        ptr1 = pair + 1; 
     444        curMatch = *ptr1; 
     445        len1 = len; 
     446      } 
     447      else 
     448      { 
     449        *ptr0 = curMatch; 
     450        ptr0 = pair; 
     451        curMatch = *ptr0; 
     452        len0 = len; 
     453      } 
     454    } 
     455  } 
     456} 
     457 
     458#define MOVE_POS \ 
     459  ++p->cyclicBufferPos; \ 
     460  p->buffer++; \ 
     461  if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); 
     462 
     463#define MOVE_POS_RET MOVE_POS return offset; 
     464 
     465static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } 
     466 
     467#define GET_MATCHES_HEADER2(minLen, ret_op) \ 
     468  UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ 
     469  lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ 
     470  cur = p->buffer; 
     471 
     472#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) 
     473#define SKIP_HEADER(minLen)        GET_MATCHES_HEADER2(minLen, continue) 
     474 
     475#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue 
     476 
     477#define GET_MATCHES_FOOTER(offset, maxLen) \ 
     478  offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ 
     479  distances + offset, maxLen) - distances); MOVE_POS_RET; 
     480 
     481#define SKIP_FOOTER \ 
     482  SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; 
     483 
     484static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) 
     485{ 
     486  UInt32 offset; 
     487  GET_MATCHES_HEADER(2) 
     488  HASH2_CALC; 
     489  curMatch = p->hash[hashValue]; 
     490  p->hash[hashValue] = p->pos; 
     491  offset = 0; 
     492  GET_MATCHES_FOOTER(offset, 1) 
     493} 
     494 
     495UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) 
     496{ 
     497  UInt32 offset; 
     498  GET_MATCHES_HEADER(3) 
     499  HASH_ZIP_CALC; 
     500  curMatch = p->hash[hashValue]; 
     501  p->hash[hashValue] = p->pos; 
     502  offset = 0; 
     503  GET_MATCHES_FOOTER(offset, 2) 
     504} 
     505 
     506static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) 
     507{ 
     508  UInt32 hash2Value, delta2, maxLen, offset; 
     509  GET_MATCHES_HEADER(3) 
     510 
     511  HASH3_CALC; 
     512 
     513  delta2 = p->pos - p->hash[hash2Value]; 
     514  curMatch = p->hash[kFix3HashSize + hashValue]; 
     515   
     516  p->hash[hash2Value] = 
     517  p->hash[kFix3HashSize + hashValue] = p->pos; 
     518 
     519 
     520  maxLen = 2; 
     521  offset = 0; 
     522  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) 
     523  { 
     524    for (; maxLen != lenLimit; maxLen++) 
     525      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) 
     526        break; 
     527    distances[0] = maxLen; 
     528    distances[1] = delta2 - 1; 
     529    offset = 2; 
     530    if (maxLen == lenLimit) 
     531    { 
     532      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); 
     533      MOVE_POS_RET; 
     534    } 
     535  } 
     536  GET_MATCHES_FOOTER(offset, maxLen) 
     537} 
     538 
     539static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) 
     540{ 
     541  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; 
     542  GET_MATCHES_HEADER(4) 
     543 
     544  HASH4_CALC; 
     545 
     546  delta2 = p->pos - p->hash[                hash2Value]; 
     547  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; 
     548  curMatch = p->hash[kFix4HashSize + hashValue]; 
     549   
     550  p->hash[                hash2Value] = 
     551  p->hash[kFix3HashSize + hash3Value] = 
     552  p->hash[kFix4HashSize + hashValue] = p->pos; 
     553 
     554  maxLen = 1; 
     555  offset = 0; 
     556  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) 
     557  { 
     558    distances[0] = maxLen = 2; 
     559    distances[1] = delta2 - 1; 
     560    offset = 2; 
     561  } 
     562  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) 
     563  { 
     564    maxLen = 3; 
     565    distances[offset + 1] = delta3 - 1; 
     566    offset += 2; 
     567    delta2 = delta3; 
     568  } 
     569  if (offset != 0) 
     570  { 
     571    for (; maxLen != lenLimit; maxLen++) 
     572      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) 
     573        break; 
     574    distances[offset - 2] = maxLen; 
     575    if (maxLen == lenLimit) 
     576    { 
     577      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); 
     578      MOVE_POS_RET; 
     579    } 
     580  } 
     581  if (maxLen < 3) 
     582    maxLen = 3; 
     583  GET_MATCHES_FOOTER(offset, maxLen) 
     584} 
     585 
     586static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) 
     587{ 
     588  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; 
     589  GET_MATCHES_HEADER(4) 
     590 
     591  HASH4_CALC; 
     592 
     593  delta2 = p->pos - p->hash[                hash2Value]; 
     594  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; 
     595  curMatch = p->hash[kFix4HashSize + hashValue]; 
     596 
     597  p->hash[                hash2Value] = 
     598  p->hash[kFix3HashSize + hash3Value] = 
     599  p->hash[kFix4HashSize + hashValue] = p->pos; 
     600 
     601  maxLen = 1; 
     602  offset = 0; 
     603  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) 
     604  { 
     605    distances[0] = maxLen = 2; 
     606    distances[1] = delta2 - 1; 
     607    offset = 2; 
     608  } 
     609  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) 
     610  { 
     611    maxLen = 3; 
     612    distances[offset + 1] = delta3 - 1; 
     613    offset += 2; 
     614    delta2 = delta3; 
     615  } 
     616  if (offset != 0) 
     617  { 
     618    for (; maxLen != lenLimit; maxLen++) 
     619      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) 
     620        break; 
     621    distances[offset - 2] = maxLen; 
     622    if (maxLen == lenLimit) 
     623    { 
     624      p->son[p->cyclicBufferPos] = curMatch; 
     625      MOVE_POS_RET; 
     626    } 
     627  } 
     628  if (maxLen < 3) 
     629    maxLen = 3; 
     630  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), 
     631    distances + offset, maxLen) - (distances)); 
     632  MOVE_POS_RET 
     633} 
     634 
     635UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) 
     636{ 
     637  UInt32 offset; 
     638  GET_MATCHES_HEADER(3) 
     639  HASH_ZIP_CALC; 
     640  curMatch = p->hash[hashValue]; 
     641  p->hash[hashValue] = p->pos; 
     642  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), 
     643    distances, 2) - (distances)); 
     644  MOVE_POS_RET 
     645} 
     646 
     647static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) 
     648{ 
     649  do 
     650  { 
     651    SKIP_HEADER(2) 
     652    HASH2_CALC; 
     653    curMatch = p->hash[hashValue]; 
     654    p->hash[hashValue] = p->pos; 
     655    SKIP_FOOTER 
     656  } 
     657  while (--num != 0); 
     658} 
     659 
     660void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) 
     661{ 
     662  do 
     663  { 
     664    SKIP_HEADER(3) 
     665    HASH_ZIP_CALC; 
     666    curMatch = p->hash[hashValue]; 
     667    p->hash[hashValue] = p->pos; 
     668    SKIP_FOOTER 
     669  } 
     670  while (--num != 0); 
     671} 
     672 
     673static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) 
     674{ 
     675  do 
     676  { 
     677    UInt32 hash2Value; 
     678    SKIP_HEADER(3) 
     679    HASH3_CALC; 
     680    curMatch = p->hash[kFix3HashSize + hashValue]; 
     681    p->hash[hash2Value] = 
     682    p->hash[kFix3HashSize + hashValue] = p->pos; 
     683    SKIP_FOOTER 
     684  } 
     685  while (--num != 0); 
     686} 
     687 
     688static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) 
     689{ 
     690  do 
     691  { 
     692    UInt32 hash2Value, hash3Value; 
     693    SKIP_HEADER(4) 
     694    HASH4_CALC; 
     695    curMatch = p->hash[kFix4HashSize + hashValue]; 
     696    p->hash[                hash2Value] = 
     697    p->hash[kFix3HashSize + hash3Value] = p->pos; 
     698    p->hash[kFix4HashSize + hashValue] = p->pos; 
     699    SKIP_FOOTER 
     700  } 
     701  while (--num != 0); 
     702} 
     703 
     704static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) 
     705{ 
     706  do 
     707  { 
     708    UInt32 hash2Value, hash3Value; 
     709    SKIP_HEADER(4) 
     710    HASH4_CALC; 
     711    curMatch = p->hash[kFix4HashSize + hashValue]; 
     712    p->hash[                hash2Value] = 
     713    p->hash[kFix3HashSize + hash3Value] = 
     714    p->hash[kFix4HashSize + hashValue] = p->pos; 
     715    p->son[p->cyclicBufferPos] = curMatch; 
     716    MOVE_POS 
     717  } 
     718  while (--num != 0); 
     719} 
     720 
     721void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) 
     722{ 
     723  do 
     724  { 
     725    SKIP_HEADER(3) 
     726    HASH_ZIP_CALC; 
     727    curMatch = p->hash[hashValue]; 
     728    p->hash[hashValue] = p->pos; 
     729    p->son[p->cyclicBufferPos] = curMatch; 
     730    MOVE_POS 
     731  } 
     732  while (--num != 0); 
     733} 
     734 
     735void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) 
     736{ 
     737  vTable->Init = (Mf_Init_Func)MatchFinder_Init; 
     738  vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; 
     739  vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; 
     740  vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; 
     741  if (!p->btMode) 
     742  { 
     743    vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; 
     744    vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; 
     745  } 
     746  else if (p->numHashBytes == 2) 
     747  { 
     748    vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; 
     749    vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; 
     750  } 
     751  else if (p->numHashBytes == 3) 
     752  { 
     753    vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; 
     754    vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; 
     755  } 
     756  else 
     757  { 
     758    vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; 
     759    vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; 
     760  } 
     761} 
  • new file lib/lzma/LzmaDec.c

    - +  
     1/* LzmaDec.c -- LZMA Decoder 
     22009-09-20 : Igor Pavlov : Public domain */ 
     3 
     4#include "LzmaDec.h" 
     5 
     6#include <string.h> 
     7 
     8#define kNumTopBits 24 
     9#define kTopValue ((UInt32)1 << kNumTopBits) 
     10 
     11#define kNumBitModelTotalBits 11 
     12#define kBitModelTotal (1 << kNumBitModelTotalBits) 
     13#define kNumMoveBits 5 
     14 
     15#define RC_INIT_SIZE 5 
     16 
     17#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); } 
     18 
     19#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) 
     20#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); 
     21#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); 
     22#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \ 
     23  { UPDATE_0(p); i = (i + i); A0; } else \ 
     24  { UPDATE_1(p); i = (i + i) + 1; A1; } 
     25#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) 
     26 
     27#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } 
     28#define TREE_DECODE(probs, limit, i) \ 
     29  { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } 
     30 
     31/* #define _LZMA_SIZE_OPT */ 
     32 
     33#ifdef _LZMA_SIZE_OPT 
     34#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) 
     35#else 
     36#define TREE_6_DECODE(probs, i) \ 
     37  { i = 1; \ 
     38  TREE_GET_BIT(probs, i); \ 
     39  TREE_GET_BIT(probs, i); \ 
     40  TREE_GET_BIT(probs, i); \ 
     41  TREE_GET_BIT(probs, i); \ 
     42  TREE_GET_BIT(probs, i); \ 
     43  TREE_GET_BIT(probs, i); \ 
     44  i -= 0x40; } 
     45#endif 
     46 
     47#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); } 
     48 
     49#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) 
     50#define UPDATE_0_CHECK range = bound; 
     51#define UPDATE_1_CHECK range -= bound; code -= bound; 
     52#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ 
     53  { UPDATE_0_CHECK; i = (i + i); A0; } else \ 
     54  { UPDATE_1_CHECK; i = (i + i) + 1; A1; } 
     55#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) 
     56#define TREE_DECODE_CHECK(probs, limit, i) \ 
     57  { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } 
     58 
     59 
     60#define kNumPosBitsMax 4 
     61#define kNumPosStatesMax (1 << kNumPosBitsMax) 
     62 
     63#define kLenNumLowBits 3 
     64#define kLenNumLowSymbols (1 << kLenNumLowBits) 
     65#define kLenNumMidBits 3 
     66#define kLenNumMidSymbols (1 << kLenNumMidBits) 
     67#define kLenNumHighBits 8 
     68#define kLenNumHighSymbols (1 << kLenNumHighBits) 
     69 
     70#define LenChoice 0 
     71#define LenChoice2 (LenChoice + 1) 
     72#define LenLow (LenChoice2 + 1) 
     73#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) 
     74#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) 
     75#define kNumLenProbs (LenHigh + kLenNumHighSymbols) 
     76 
     77 
     78#define kNumStates 12 
     79#define kNumLitStates 7 
     80 
     81#define kStartPosModelIndex 4 
     82#define kEndPosModelIndex 14 
     83#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) 
     84 
     85#define kNumPosSlotBits 6 
     86#define kNumLenToPosStates 4 
     87 
     88#define kNumAlignBits 4 
     89#define kAlignTableSize (1 << kNumAlignBits) 
     90 
     91#define kMatchMinLen 2 
     92#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) 
     93 
     94#define IsMatch 0 
     95#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) 
     96#define IsRepG0 (IsRep + kNumStates) 
     97#define IsRepG1 (IsRepG0 + kNumStates) 
     98#define IsRepG2 (IsRepG1 + kNumStates) 
     99#define IsRep0Long (IsRepG2 + kNumStates) 
     100#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) 
     101#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) 
     102#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) 
     103#define LenCoder (Align + kAlignTableSize) 
     104#define RepLenCoder (LenCoder + kNumLenProbs) 
     105#define Literal (RepLenCoder + kNumLenProbs) 
     106 
     107#define LZMA_BASE_SIZE 1846 
     108#define LZMA_LIT_SIZE 768 
     109 
     110#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) 
     111 
     112#if Literal != LZMA_BASE_SIZE 
     113StopCompilingDueBUG 
     114#endif 
     115 
     116#define LZMA_DIC_MIN (1 << 12) 
     117 
     118/* First LZMA-symbol is always decoded. 
     119And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization 
     120Out: 
     121  Result: 
     122    SZ_OK - OK 
     123    SZ_ERROR_DATA - Error 
     124  p->remainLen: 
     125    < kMatchSpecLenStart : normal remain 
     126    = kMatchSpecLenStart : finished 
     127    = kMatchSpecLenStart + 1 : Flush marker 
     128    = kMatchSpecLenStart + 2 : State Init Marker 
     129*/ 
     130 
     131static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit) 
     132{ 
     133  CLzmaProb *probs = p->probs; 
     134 
     135  unsigned state = p->state; 
     136  UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; 
     137  unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; 
     138  unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; 
     139  unsigned lc = p->prop.lc; 
     140 
     141  Byte *dic = p->dic; 
     142  SizeT dicBufSize = p->dicBufSize; 
     143  SizeT dicPos = p->dicPos; 
     144   
     145  UInt32 processedPos = p->processedPos; 
     146  UInt32 checkDicSize = p->checkDicSize; 
     147  unsigned len = 0; 
     148 
     149  const Byte *buf = p->buf; 
     150  UInt32 range = p->range; 
     151  UInt32 code = p->code; 
     152 
     153  do 
     154  { 
     155    CLzmaProb *prob; 
     156    UInt32 bound; 
     157    unsigned ttt; 
     158    unsigned posState = processedPos & pbMask; 
     159 
     160    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; 
     161    IF_BIT_0(prob) 
     162    { 
     163      unsigned symbol; 
     164      UPDATE_0(prob); 
     165      prob = probs + Literal; 
     166      if (checkDicSize != 0 || processedPos != 0) 
     167        prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + 
     168        (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); 
     169 
     170      if (state < kNumLitStates) 
     171      { 
     172        state -= (state < 4) ? state : 3; 
     173        symbol = 1; 
     174        do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); 
     175      } 
     176      else 
     177      { 
     178        unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; 
     179        unsigned offs = 0x100; 
     180        state -= (state < 10) ? 3 : 6; 
     181        symbol = 1; 
     182        do 
     183        { 
     184          unsigned bit; 
     185          CLzmaProb *probLit; 
     186          matchByte <<= 1; 
     187          bit = (matchByte & offs); 
     188          probLit = prob + offs + bit + symbol; 
     189          GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) 
     190        } 
     191        while (symbol < 0x100); 
     192      } 
     193      dic[dicPos++] = (Byte)symbol; 
     194      processedPos++; 
     195      continue; 
     196    } 
     197    else 
     198    { 
     199      UPDATE_1(prob); 
     200      prob = probs + IsRep + state; 
     201      IF_BIT_0(prob) 
     202      { 
     203        UPDATE_0(prob); 
     204        state += kNumStates; 
     205        prob = probs + LenCoder; 
     206      } 
     207      else 
     208      { 
     209        UPDATE_1(prob); 
     210        if (checkDicSize == 0 && processedPos == 0) 
     211          return SZ_ERROR_DATA; 
     212        prob = probs + IsRepG0 + state; 
     213        IF_BIT_0(prob) 
     214        { 
     215          UPDATE_0(prob); 
     216          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; 
     217          IF_BIT_0(prob) 
     218          { 
     219            UPDATE_0(prob); 
     220            dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; 
     221            dicPos++; 
     222            processedPos++; 
     223            state = state < kNumLitStates ? 9 : 11; 
     224            continue; 
     225          } 
     226          UPDATE_1(prob); 
     227        } 
     228        else 
     229        { 
     230          UInt32 distance; 
     231          UPDATE_1(prob); 
     232          prob = probs + IsRepG1 + state; 
     233          IF_BIT_0(prob) 
     234          { 
     235            UPDATE_0(prob); 
     236            distance = rep1; 
     237          } 
     238          else 
     239          { 
     240            UPDATE_1(prob); 
     241            prob = probs + IsRepG2 + state; 
     242            IF_BIT_0(prob) 
     243            { 
     244              UPDATE_0(prob); 
     245              distance = rep2; 
     246            } 
     247            else 
     248            { 
     249              UPDATE_1(prob); 
     250              distance = rep3; 
     251              rep3 = rep2; 
     252            } 
     253            rep2 = rep1; 
     254          } 
     255          rep1 = rep0; 
     256          rep0 = distance; 
     257        } 
     258        state = state < kNumLitStates ? 8 : 11; 
     259        prob = probs + RepLenCoder; 
     260      } 
     261      { 
     262        unsigned limit, offset; 
     263        CLzmaProb *probLen = prob + LenChoice; 
     264        IF_BIT_0(probLen) 
     265        { 
     266          UPDATE_0(probLen); 
     267          probLen = prob + LenLow + (posState << kLenNumLowBits); 
     268          offset = 0; 
     269          limit = (1 << kLenNumLowBits); 
     270        } 
     271        else 
     272        { 
     273          UPDATE_1(probLen); 
     274          probLen = prob + LenChoice2; 
     275          IF_BIT_0(probLen) 
     276          { 
     277            UPDATE_0(probLen); 
     278            probLen = prob + LenMid + (posState << kLenNumMidBits); 
     279            offset = kLenNumLowSymbols; 
     280            limit = (1 << kLenNumMidBits); 
     281          } 
     282          else 
     283          { 
     284            UPDATE_1(probLen); 
     285            probLen = prob + LenHigh; 
     286            offset = kLenNumLowSymbols + kLenNumMidSymbols; 
     287            limit = (1 << kLenNumHighBits); 
     288          } 
     289        } 
     290        TREE_DECODE(probLen, limit, len); 
     291        len += offset; 
     292      } 
     293 
     294      if (state >= kNumStates) 
     295      { 
     296        UInt32 distance; 
     297        prob = probs + PosSlot + 
     298            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); 
     299        TREE_6_DECODE(prob, distance); 
     300        if (distance >= kStartPosModelIndex) 
     301        { 
     302          unsigned posSlot = (unsigned)distance; 
     303          int numDirectBits = (int)(((distance >> 1) - 1)); 
     304          distance = (2 | (distance & 1)); 
     305          if (posSlot < kEndPosModelIndex) 
     306          { 
     307            distance <<= numDirectBits; 
     308            prob = probs + SpecPos + distance - posSlot - 1; 
     309            { 
     310              UInt32 mask = 1; 
     311              unsigned i = 1; 
     312              do 
     313              { 
     314                GET_BIT2(prob + i, i, ; , distance |= mask); 
     315                mask <<= 1; 
     316              } 
     317              while (--numDirectBits != 0); 
     318            } 
     319          } 
     320          else 
     321          { 
     322            numDirectBits -= kNumAlignBits; 
     323            do 
     324            { 
     325              NORMALIZE 
     326              range >>= 1; 
     327               
     328              { 
     329                UInt32 t; 
     330                code -= range; 
     331                t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */ 
     332                distance = (distance << 1) + (t + 1); 
     333                code += range & t; 
     334              } 
     335              /* 
     336              distance <<= 1; 
     337              if (code >= range) 
     338              { 
     339                code -= range; 
     340                distance |= 1; 
     341              } 
     342              */ 
     343            } 
     344            while (--numDirectBits != 0); 
     345            prob = probs + Align; 
     346            distance <<= kNumAlignBits; 
     347            { 
     348              unsigned i = 1; 
     349              GET_BIT2(prob + i, i, ; , distance |= 1); 
     350              GET_BIT2(prob + i, i, ; , distance |= 2); 
     351              GET_BIT2(prob + i, i, ; , distance |= 4); 
     352              GET_BIT2(prob + i, i, ; , distance |= 8); 
     353            } 
     354            if (distance == (UInt32)0xFFFFFFFF) 
     355            { 
     356              len += kMatchSpecLenStart; 
     357              state -= kNumStates; 
     358              break; 
     359            } 
     360          } 
     361        } 
     362        rep3 = rep2; 
     363        rep2 = rep1; 
     364        rep1 = rep0; 
     365        rep0 = distance + 1; 
     366        if (checkDicSize == 0) 
     367        { 
     368          if (distance >= processedPos) 
     369            return SZ_ERROR_DATA; 
     370        } 
     371        else if (distance >= checkDicSize) 
     372          return SZ_ERROR_DATA; 
     373        state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; 
     374      } 
     375 
     376      len += kMatchMinLen; 
     377 
     378      if (limit == dicPos) 
     379        return SZ_ERROR_DATA; 
     380      { 
     381        SizeT rem = limit - dicPos; 
     382        unsigned curLen = ((rem < len) ? (unsigned)rem : len); 
     383        SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); 
     384 
     385        processedPos += curLen; 
     386 
     387        len -= curLen; 
     388        if (pos + curLen <= dicBufSize) 
     389        { 
     390          Byte *dest = dic + dicPos; 
     391          ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; 
     392          const Byte *lim = dest + curLen; 
     393          dicPos += curLen; 
     394          do 
     395            *(dest) = (Byte)*(dest + src); 
     396          while (++dest != lim); 
     397        } 
     398        else 
     399        { 
     400          do 
     401          { 
     402            dic[dicPos++] = dic[pos]; 
     403            if (++pos == dicBufSize) 
     404              pos = 0; 
     405          } 
     406          while (--curLen != 0); 
     407        } 
     408      } 
     409    } 
     410  } 
     411  while (dicPos < limit && buf < bufLimit); 
     412  NORMALIZE; 
     413  p->buf = buf; 
     414  p->range = range; 
     415  p->code = code; 
     416  p->remainLen = len; 
     417  p->dicPos = dicPos; 
     418  p->processedPos = processedPos; 
     419  p->reps[0] = rep0; 
     420  p->reps[1] = rep1; 
     421  p->reps[2] = rep2; 
     422  p->reps[3] = rep3; 
     423  p->state = state; 
     424 
     425  return SZ_OK; 
     426} 
     427 
     428static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit) 
     429{ 
     430  if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) 
     431  { 
     432    Byte *dic = p->dic; 
     433    SizeT dicPos = p->dicPos; 
     434    SizeT dicBufSize = p->dicBufSize; 
     435    unsigned len = p->remainLen; 
     436    UInt32 rep0 = p->reps[0]; 
     437    if (limit - dicPos < len) 
     438      len = (unsigned)(limit - dicPos); 
     439 
     440    if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) 
     441      p->checkDicSize = p->prop.dicSize; 
     442 
     443    p->processedPos += len; 
     444    p->remainLen -= len; 
     445    while (len-- != 0) 
     446    { 
     447      dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; 
     448      dicPos++; 
     449    } 
     450    p->dicPos = dicPos; 
     451  } 
     452} 
     453 
     454static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit) 
     455{ 
     456  do 
     457  { 
     458    SizeT limit2 = limit; 
     459    if (p->checkDicSize == 0) 
     460    { 
     461      UInt32 rem = p->prop.dicSize - p->processedPos; 
     462      if (limit - p->dicPos > rem) 
     463        limit2 = p->dicPos + rem; 
     464    } 
     465    RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); 
     466    if (p->processedPos >= p->prop.dicSize) 
     467      p->checkDicSize = p->prop.dicSize; 
     468    LzmaDec_WriteRem(p, limit); 
     469  } 
     470  while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); 
     471 
     472  if (p->remainLen > kMatchSpecLenStart) 
     473  { 
     474    p->remainLen = kMatchSpecLenStart; 
     475  } 
     476  return 0; 
     477} 
     478 
     479typedef enum 
     480{ 
     481  DUMMY_ERROR, /* unexpected end of input stream */ 
     482  DUMMY_LIT, 
     483  DUMMY_MATCH, 
     484  DUMMY_REP 
     485} ELzmaDummy; 
     486 
     487static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize) 
     488{ 
     489  UInt32 range = p->range; 
     490  UInt32 code = p->code; 
     491  const Byte *bufLimit = buf + inSize; 
     492  CLzmaProb *probs = p->probs; 
     493  unsigned state = p->state; 
     494  ELzmaDummy res; 
     495 
     496  { 
     497    CLzmaProb *prob; 
     498    UInt32 bound; 
     499    unsigned ttt; 
     500    unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); 
     501 
     502    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; 
     503    IF_BIT_0_CHECK(prob) 
     504    { 
     505      UPDATE_0_CHECK 
     506 
     507      /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ 
     508 
     509      prob = probs + Literal; 
     510      if (p->checkDicSize != 0 || p->processedPos != 0) 
     511        prob += (LZMA_LIT_SIZE * 
     512          ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + 
     513          (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); 
     514 
     515      if (state < kNumLitStates) 
     516      { 
     517        unsigned symbol = 1; 
     518        do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); 
     519      } 
     520      else 
     521      { 
     522        unsigned matchByte = p->dic[p->dicPos - p->reps[0] + 
     523            ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; 
     524        unsigned offs = 0x100; 
     525        unsigned symbol = 1; 
     526        do 
     527        { 
     528          unsigned bit; 
     529          CLzmaProb *probLit; 
     530          matchByte <<= 1; 
     531          bit = (matchByte & offs); 
     532          probLit = prob + offs + bit + symbol; 
     533          GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) 
     534        } 
     535        while (symbol < 0x100); 
     536      } 
     537      res = DUMMY_LIT; 
     538    } 
     539    else 
     540    { 
     541      unsigned len; 
     542      UPDATE_1_CHECK; 
     543 
     544      prob = probs + IsRep + state; 
     545      IF_BIT_0_CHECK(prob) 
     546      { 
     547        UPDATE_0_CHECK; 
     548        state = 0; 
     549        prob = probs + LenCoder; 
     550        res = DUMMY_MATCH; 
     551      } 
     552      else 
     553      { 
     554        UPDATE_1_CHECK; 
     555        res = DUMMY_REP; 
     556        prob = probs + IsRepG0 + state; 
     557        IF_BIT_0_CHECK(prob) 
     558        { 
     559          UPDATE_0_CHECK; 
     560          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; 
     561          IF_BIT_0_CHECK(prob) 
     562          { 
     563            UPDATE_0_CHECK; 
     564            NORMALIZE_CHECK; 
     565            return DUMMY_REP; 
     566          } 
     567          else 
     568          { 
     569            UPDATE_1_CHECK; 
     570          } 
     571        } 
     572        else 
     573        { 
     574          UPDATE_1_CHECK; 
     575          prob = probs + IsRepG1 + state; 
     576          IF_BIT_0_CHECK(prob) 
     577          { 
     578            UPDATE_0_CHECK; 
     579          } 
     580          else 
     581          { 
     582            UPDATE_1_CHECK; 
     583            prob = probs + IsRepG2 + state; 
     584            IF_BIT_0_CHECK(prob) 
     585            { 
     586              UPDATE_0_CHECK; 
     587            } 
     588            else 
     589            { 
     590              UPDATE_1_CHECK; 
     591            } 
     592          } 
     593        } 
     594        state = kNumStates; 
     595        prob = probs + RepLenCoder; 
     596      } 
     597      { 
     598        unsigned limit, offset; 
     599        CLzmaProb *probLen = prob + LenChoice; 
     600        IF_BIT_0_CHECK(probLen) 
     601        { 
     602          UPDATE_0_CHECK; 
     603          probLen = prob + LenLow + (posState << kLenNumLowBits); 
     604          offset = 0; 
     605          limit = 1 << kLenNumLowBits; 
     606        } 
     607        else 
     608        { 
     609          UPDATE_1_CHECK; 
     610          probLen = prob + LenChoice2; 
     611          IF_BIT_0_CHECK(probLen) 
     612          { 
     613            UPDATE_0_CHECK; 
     614            probLen = prob + LenMid + (posState << kLenNumMidBits); 
     615            offset = kLenNumLowSymbols; 
     616            limit = 1 << kLenNumMidBits; 
     617          } 
     618          else 
     619          { 
     620            UPDATE_1_CHECK; 
     621            probLen = prob + LenHigh; 
     622            offset = kLenNumLowSymbols + kLenNumMidSymbols; 
     623            limit = 1 << kLenNumHighBits; 
     624          } 
     625        } 
     626        TREE_DECODE_CHECK(probLen, limit, len); 
     627        len += offset; 
     628      } 
     629 
     630      if (state < 4) 
     631      { 
     632        unsigned posSlot; 
     633        prob = probs + PosSlot + 
     634            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 
     635            kNumPosSlotBits); 
     636        TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); 
     637        if (posSlot >= kStartPosModelIndex) 
     638        { 
     639          int numDirectBits = ((posSlot >> 1) - 1); 
     640 
     641          /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ 
     642 
     643          if (posSlot < kEndPosModelIndex) 
     644          { 
     645            prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; 
     646          } 
     647          else 
     648          { 
     649            numDirectBits -= kNumAlignBits; 
     650            do 
     651            { 
     652              NORMALIZE_CHECK 
     653              range >>= 1; 
     654              code -= range & (((code - range) >> 31) - 1); 
     655              /* if (code >= range) code -= range; */ 
     656            } 
     657            while (--numDirectBits != 0); 
     658            prob = probs + Align; 
     659            numDirectBits = kNumAlignBits; 
     660          } 
     661          { 
     662            unsigned i = 1; 
     663            do 
     664            { 
     665              GET_BIT_CHECK(prob + i, i); 
     666            } 
     667            while (--numDirectBits != 0); 
     668          } 
     669        } 
     670      } 
     671    } 
     672  } 
     673  NORMALIZE_CHECK; 
     674  return res; 
     675} 
     676 
     677 
     678static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data) 
     679{ 
     680  p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]); 
     681  p->range = 0xFFFFFFFF; 
     682  p->needFlush = 0; 
     683} 
     684 
     685void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState) 
     686{ 
     687  p->needFlush = 1; 
     688  p->remainLen = 0; 
     689  p->tempBufSize = 0; 
     690 
     691  if (initDic) 
     692  { 
     693    p->processedPos = 0; 
     694    p->checkDicSize = 0; 
     695    p->needInitState = 1; 
     696  } 
     697  if (initState) 
     698    p->needInitState = 1; 
     699} 
     700 
     701void LzmaDec_Init(CLzmaDec *p) 
     702{ 
     703  p->dicPos = 0; 
     704  LzmaDec_InitDicAndState(p, True, True); 
     705} 
     706 
     707static void LzmaDec_InitStateReal(CLzmaDec *p) 
     708{ 
     709  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); 
     710  UInt32 i; 
     711  CLzmaProb *probs = p->probs; 
     712  for (i = 0; i < numProbs; i++) 
     713    probs[i] = kBitModelTotal >> 1; 
     714  p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; 
     715  p->state = 0; 
     716  p->needInitState = 0; 
     717} 
     718 
     719SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen, 
     720    ELzmaFinishMode finishMode, ELzmaStatus *status) 
     721{ 
     722  SizeT inSize = *srcLen; 
     723  (*srcLen) = 0; 
     724  LzmaDec_WriteRem(p, dicLimit); 
     725   
     726  *status = LZMA_STATUS_NOT_SPECIFIED; 
     727 
     728  while (p->remainLen != kMatchSpecLenStart) 
     729  { 
     730      int checkEndMarkNow; 
     731 
     732      if (p->needFlush != 0) 
     733      { 
     734        for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) 
     735          p->tempBuf[p->tempBufSize++] = *src++; 
     736        if (p->tempBufSize < RC_INIT_SIZE) 
     737        { 
     738          *status = LZMA_STATUS_NEEDS_MORE_INPUT; 
     739          return SZ_OK; 
     740        } 
     741        if (p->tempBuf[0] != 0) 
     742          return SZ_ERROR_DATA; 
     743 
     744        LzmaDec_InitRc(p, p->tempBuf); 
     745        p->tempBufSize = 0; 
     746      } 
     747 
     748      checkEndMarkNow = 0; 
     749      if (p->dicPos >= dicLimit) 
     750      { 
     751        if (p->remainLen == 0 && p->code == 0) 
     752        { 
     753          *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; 
     754          return SZ_OK; 
     755        } 
     756        if (finishMode == LZMA_FINISH_ANY) 
     757        { 
     758          *status = LZMA_STATUS_NOT_FINISHED; 
     759          return SZ_OK; 
     760        } 
     761        if (p->remainLen != 0) 
     762        { 
     763          *status = LZMA_STATUS_NOT_FINISHED; 
     764          return SZ_ERROR_DATA; 
     765        } 
     766        checkEndMarkNow = 1; 
     767      } 
     768 
     769      if (p->needInitState) 
     770        LzmaDec_InitStateReal(p); 
     771   
     772      if (p->tempBufSize == 0) 
     773      { 
     774        SizeT processed; 
     775        const Byte *bufLimit; 
     776        if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) 
     777        { 
     778          int dummyRes = LzmaDec_TryDummy(p, src, inSize); 
     779          if (dummyRes == DUMMY_ERROR) 
     780          { 
     781            memcpy(p->tempBuf, src, inSize); 
     782            p->tempBufSize = (unsigned)inSize; 
     783            (*srcLen) += inSize; 
     784            *status = LZMA_STATUS_NEEDS_MORE_INPUT; 
     785            return SZ_OK; 
     786          } 
     787          if (checkEndMarkNow && dummyRes != DUMMY_MATCH) 
     788          { 
     789            *status = LZMA_STATUS_NOT_FINISHED; 
     790            return SZ_ERROR_DATA; 
     791          } 
     792          bufLimit = src; 
     793        } 
     794        else 
     795          bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; 
     796        p->buf = src; 
     797        if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) 
     798          return SZ_ERROR_DATA; 
     799        processed = (SizeT)(p->buf - src); 
     800        (*srcLen) += processed; 
     801        src += processed; 
     802        inSize -= processed; 
     803      } 
     804      else 
     805      { 
     806        unsigned rem = p->tempBufSize, lookAhead = 0; 
     807        while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) 
     808          p->tempBuf[rem++] = src[lookAhead++]; 
     809        p->tempBufSize = rem; 
     810        if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) 
     811        { 
     812          int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); 
     813          if (dummyRes == DUMMY_ERROR) 
     814          { 
     815            (*srcLen) += lookAhead; 
     816            *status = LZMA_STATUS_NEEDS_MORE_INPUT; 
     817            return SZ_OK; 
     818          } 
     819          if (checkEndMarkNow && dummyRes != DUMMY_MATCH) 
     820          { 
     821            *status = LZMA_STATUS_NOT_FINISHED; 
     822            return SZ_ERROR_DATA; 
     823          } 
     824        } 
     825        p->buf = p->tempBuf; 
     826        if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) 
     827          return SZ_ERROR_DATA; 
     828        lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); 
     829        (*srcLen) += lookAhead; 
     830        src += lookAhead; 
     831        inSize -= lookAhead; 
     832        p->tempBufSize = 0; 
     833      } 
     834  } 
     835  if (p->code == 0) 
     836    *status = LZMA_STATUS_FINISHED_WITH_MARK; 
     837  return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; 
     838} 
     839 
     840SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) 
     841{ 
     842  SizeT outSize = *destLen; 
     843  SizeT inSize = *srcLen; 
     844  *srcLen = *destLen = 0; 
     845  for (;;) 
     846  { 
     847    SizeT inSizeCur = inSize, outSizeCur, dicPos; 
     848    ELzmaFinishMode curFinishMode; 
     849    SRes res; 
     850    if (p->dicPos == p->dicBufSize) 
     851      p->dicPos = 0; 
     852    dicPos = p->dicPos; 
     853    if (outSize > p->dicBufSize - dicPos) 
     854    { 
     855      outSizeCur = p->dicBufSize; 
     856      curFinishMode = LZMA_FINISH_ANY; 
     857    } 
     858    else 
     859    { 
     860      outSizeCur = dicPos + outSize; 
     861      curFinishMode = finishMode; 
     862    } 
     863 
     864    res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); 
     865    src += inSizeCur; 
     866    inSize -= inSizeCur; 
     867    *srcLen += inSizeCur; 
     868    outSizeCur = p->dicPos - dicPos; 
     869    memcpy(dest, p->dic + dicPos, outSizeCur); 
     870    dest += outSizeCur; 
     871    outSize -= outSizeCur; 
     872    *destLen += outSizeCur; 
     873    if (res != 0) 
     874      return res; 
     875    if (outSizeCur == 0 || outSize == 0) 
     876      return SZ_OK; 
     877  } 
     878} 
     879 
     880void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) 
     881{ 
     882  alloc->Free(alloc, p->probs); 
     883  p->probs = 0; 
     884} 
     885 
     886static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) 
     887{ 
     888  alloc->Free(alloc, p->dic); 
     889  p->dic = 0; 
     890} 
     891 
     892void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) 
     893{ 
     894  LzmaDec_FreeProbs(p, alloc); 
     895  LzmaDec_FreeDict(p, alloc); 
     896} 
     897 
     898SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size) 
     899{ 
     900  UInt32 dicSize; 
     901  Byte d; 
     902   
     903  if (size < LZMA_PROPS_SIZE) 
     904    return SZ_ERROR_UNSUPPORTED; 
     905  else 
     906    dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24); 
     907  
     908  if (dicSize < LZMA_DIC_MIN) 
     909    dicSize = LZMA_DIC_MIN; 
     910  p->dicSize = dicSize; 
     911 
     912  d = data[0]; 
     913  if (d >= (9 * 5 * 5)) 
     914    return SZ_ERROR_UNSUPPORTED; 
     915 
     916  p->lc = d % 9; 
     917  d /= 9; 
     918  p->pb = d / 5; 
     919  p->lp = d % 5; 
     920 
     921  return SZ_OK; 
     922} 
     923 
     924static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) 
     925{ 
     926  UInt32 numProbs = LzmaProps_GetNumProbs(propNew); 
     927  if (p->probs == 0 || numProbs != p->numProbs) 
     928  { 
     929    LzmaDec_FreeProbs(p, alloc); 
     930    p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb)); 
     931    p->numProbs = numProbs; 
     932    if (p->probs == 0) 
     933      return SZ_ERROR_MEM; 
     934  } 
     935  return SZ_OK; 
     936} 
     937 
     938SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) 
     939{ 
     940  CLzmaProps propNew; 
     941  RINOK(LzmaProps_Decode(&propNew, props, propsSize)); 
     942  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); 
     943  p->prop = propNew; 
     944  return SZ_OK; 
     945} 
     946 
     947SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc) 
     948{ 
     949  CLzmaProps propNew; 
     950  SizeT dicBufSize; 
     951  RINOK(LzmaProps_Decode(&propNew, props, propsSize)); 
     952  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); 
     953  dicBufSize = propNew.dicSize; 
     954  if (p->dic == 0 || dicBufSize != p->dicBufSize) 
     955  { 
     956    LzmaDec_FreeDict(p, alloc); 
     957    p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize); 
     958    if (p->dic == 0) 
     959    { 
     960      LzmaDec_FreeProbs(p, alloc); 
     961      return SZ_ERROR_MEM; 
     962    } 
     963  } 
     964  p->dicBufSize = dicBufSize; 
     965  p->prop = propNew; 
     966  return SZ_OK; 
     967} 
     968 
     969SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 
     970    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, 
     971    ELzmaStatus *status, ISzAlloc *alloc) 
     972{ 
     973  CLzmaDec p; 
     974  SRes res; 
     975  SizeT inSize = *srcLen; 
     976  SizeT outSize = *destLen; 
     977  *srcLen = *destLen = 0; 
     978  if (inSize < RC_INIT_SIZE) 
     979    return SZ_ERROR_INPUT_EOF; 
     980 
     981  LzmaDec_Construct(&p); 
     982  res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); 
     983  if (res != 0) 
     984    return res; 
     985  p.dic = dest; 
     986  p.dicBufSize = outSize; 
     987 
     988  LzmaDec_Init(&p); 
     989   
     990  *srcLen = inSize; 
     991  res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); 
     992 
     993  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) 
     994    res = SZ_ERROR_INPUT_EOF; 
     995 
     996  (*destLen) = p.dicPos; 
     997  LzmaDec_FreeProbs(&p, alloc); 
     998  return res; 
     999} 
  • new file lib/lzma/LzmaEnc.c

    - +  
     1/* LzmaEnc.c -- LZMA Encoder 
     22009-11-24 : Igor Pavlov : Public domain */ 
     3 
     4#include <string.h> 
     5 
     6/* #define SHOW_STAT */ 
     7/* #define SHOW_STAT2 */ 
     8 
     9#if defined(SHOW_STAT) || defined(SHOW_STAT2) 
     10#include <stdio.h> 
     11#endif 
     12 
     13#include "LzmaEnc.h" 
     14 
     15/* disable MT */ 
     16#define _7ZIP_ST 
     17 
     18#include "LzFind.h" 
     19#ifndef _7ZIP_ST 
     20#include "LzFindMt.h" 
     21#endif 
     22 
     23#ifdef SHOW_STAT 
     24static int ttt = 0; 
     25#endif 
     26 
     27#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) 
     28 
     29#define kBlockSize (9 << 10) 
     30#define kUnpackBlockSize (1 << 18) 
     31#define kMatchArraySize (1 << 21) 
     32#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) 
     33 
     34#define kNumMaxDirectBits (31) 
     35 
     36#define kNumTopBits 24 
     37#define kTopValue ((UInt32)1 << kNumTopBits) 
     38 
     39#define kNumBitModelTotalBits 11 
     40#define kBitModelTotal (1 << kNumBitModelTotalBits) 
     41#define kNumMoveBits 5 
     42#define kProbInitValue (kBitModelTotal >> 1) 
     43 
     44#define kNumMoveReducingBits 4 
     45#define kNumBitPriceShiftBits 4 
     46#define kBitPrice (1 << kNumBitPriceShiftBits) 
     47 
     48void LzmaEncProps_Init(CLzmaEncProps *p) 
     49{ 
     50  p->level = 5; 
     51  p->dictSize = p->mc = 0; 
     52  p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; 
     53  p->writeEndMark = 0; 
     54} 
     55 
     56void LzmaEncProps_Normalize(CLzmaEncProps *p) 
     57{ 
     58  int level = p->level; 
     59  if (level < 0) level = 5; 
     60  p->level = level; 
     61  if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); 
     62  if (p->lc < 0) p->lc = 3; 
     63  if (p->lp < 0) p->lp = 0; 
     64  if (p->pb < 0) p->pb = 2; 
     65  if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); 
     66  if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); 
     67  if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); 
     68  if (p->numHashBytes < 0) p->numHashBytes = 4; 
     69  if (p->mc == 0)  p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); 
     70  if (p->numThreads < 0) 
     71    p->numThreads = 
     72      #ifndef _7ZIP_ST 
     73      ((p->btMode && p->algo) ? 2 : 1); 
     74      #else 
     75      1; 
     76      #endif 
     77} 
     78 
     79UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) 
     80{ 
     81  CLzmaEncProps props = *props2; 
     82  LzmaEncProps_Normalize(&props); 
     83  return props.dictSize; 
     84} 
     85 
     86/* #define LZMA_LOG_BSR */ 
     87/* Define it for Intel's CPU */ 
     88 
     89 
     90#ifdef LZMA_LOG_BSR 
     91 
     92#define kDicLogSizeMaxCompress 30 
     93 
     94#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } 
     95 
     96UInt32 GetPosSlot1(UInt32 pos) 
     97{ 
     98  UInt32 res; 
     99  BSR2_RET(pos, res); 
     100  return res; 
     101} 
     102#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } 
     103#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } 
     104 
     105#else 
     106 
     107#define kNumLogBits (9 + (int)sizeof(size_t) / 2) 
     108#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) 
     109 
     110void LzmaEnc_FastPosInit(Byte *g_FastPos) 
     111{ 
     112  int c = 2, slotFast; 
     113  g_FastPos[0] = 0; 
     114  g_FastPos[1] = 1; 
     115   
     116  for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) 
     117  { 
     118    UInt32 k = (1 << ((slotFast >> 1) - 1)); 
     119    UInt32 j; 
     120    for (j = 0; j < k; j++, c++) 
     121      g_FastPos[c] = (Byte)slotFast; 
     122  } 
     123} 
     124 
     125#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ 
     126  (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ 
     127  res = p->g_FastPos[pos >> i] + (i * 2); } 
     128/* 
     129#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ 
     130  p->g_FastPos[pos >> 6] + 12 : \ 
     131  p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } 
     132*/ 
     133 
     134#define GetPosSlot1(pos) p->g_FastPos[pos] 
     135#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } 
     136#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } 
     137 
     138#endif 
     139 
     140 
     141#define LZMA_NUM_REPS 4 
     142 
     143typedef unsigned CState; 
     144 
     145typedef struct 
     146{ 
     147  UInt32 price; 
     148 
     149  CState state; 
     150  int prev1IsChar; 
     151  int prev2; 
     152 
     153  UInt32 posPrev2; 
     154  UInt32 backPrev2; 
     155 
     156  UInt32 posPrev; 
     157  UInt32 backPrev; 
     158  UInt32 backs[LZMA_NUM_REPS]; 
     159} COptimal; 
     160 
     161#define kNumOpts (1 << 12) 
     162 
     163#define kNumLenToPosStates 4 
     164#define kNumPosSlotBits 6 
     165#define kDicLogSizeMin 0 
     166#define kDicLogSizeMax 32 
     167#define kDistTableSizeMax (kDicLogSizeMax * 2) 
     168 
     169 
     170#define kNumAlignBits 4 
     171#define kAlignTableSize (1 << kNumAlignBits) 
     172#define kAlignMask (kAlignTableSize - 1) 
     173 
     174#define kStartPosModelIndex 4 
     175#define kEndPosModelIndex 14 
     176#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) 
     177 
     178#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) 
     179 
     180#ifdef _LZMA_PROB32 
     181#define CLzmaProb UInt32 
     182#else 
     183#define CLzmaProb UInt16 
     184#endif 
     185 
     186#define LZMA_PB_MAX 4 
     187#define LZMA_LC_MAX 8 
     188#define LZMA_LP_MAX 4 
     189 
     190#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) 
     191 
     192 
     193#define kLenNumLowBits 3 
     194#define kLenNumLowSymbols (1 << kLenNumLowBits) 
     195#define kLenNumMidBits 3 
     196#define kLenNumMidSymbols (1 << kLenNumMidBits) 
     197#define kLenNumHighBits 8 
     198#define kLenNumHighSymbols (1 << kLenNumHighBits) 
     199 
     200#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) 
     201 
     202#define LZMA_MATCH_LEN_MIN 2 
     203#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) 
     204 
     205#define kNumStates 12 
     206 
     207typedef struct 
     208{ 
     209  CLzmaProb choice; 
     210  CLzmaProb choice2; 
     211  CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; 
     212  CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; 
     213  CLzmaProb high[kLenNumHighSymbols]; 
     214} CLenEnc; 
     215 
     216typedef struct 
     217{ 
     218  CLenEnc p; 
     219  UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; 
     220  UInt32 tableSize; 
     221  UInt32 counters[LZMA_NUM_PB_STATES_MAX]; 
     222} CLenPriceEnc; 
     223 
     224typedef struct 
     225{ 
     226  UInt32 range; 
     227  Byte cache; 
     228  UInt64 low; 
     229  UInt64 cacheSize; 
     230  Byte *buf; 
     231  Byte *bufLim; 
     232  Byte *bufBase; 
     233  ISeqOutStream *outStream; 
     234  UInt64 processed; 
     235  SRes res; 
     236} CRangeEnc; 
     237 
     238typedef struct 
     239{ 
     240  CLzmaProb *litProbs; 
     241 
     242  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; 
     243  CLzmaProb isRep[kNumStates]; 
     244  CLzmaProb isRepG0[kNumStates]; 
     245  CLzmaProb isRepG1[kNumStates]; 
     246  CLzmaProb isRepG2[kNumStates]; 
     247  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; 
     248 
     249  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; 
     250  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; 
     251  CLzmaProb posAlignEncoder[1 << kNumAlignBits]; 
     252   
     253  CLenPriceEnc lenEnc; 
     254  CLenPriceEnc repLenEnc; 
     255 
     256  UInt32 reps[LZMA_NUM_REPS]; 
     257  UInt32 state; 
     258} CSaveState; 
     259 
     260typedef struct 
     261{ 
     262  IMatchFinder matchFinder; 
     263  void *matchFinderObj; 
     264 
     265  #ifndef _7ZIP_ST 
     266  Bool mtMode; 
     267  CMatchFinderMt matchFinderMt; 
     268  #endif 
     269 
     270  CMatchFinder matchFinderBase; 
     271 
     272  #ifndef _7ZIP_ST 
     273  Byte pad[128]; 
     274  #endif 
     275   
     276  UInt32 optimumEndIndex; 
     277  UInt32 optimumCurrentIndex; 
     278 
     279  UInt32 longestMatchLength; 
     280  UInt32 numPairs; 
     281  UInt32 numAvail; 
     282  COptimal opt[kNumOpts]; 
     283   
     284  #ifndef LZMA_LOG_BSR 
     285  Byte g_FastPos[1 << kNumLogBits]; 
     286  #endif 
     287 
     288  UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; 
     289  UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; 
     290  UInt32 numFastBytes; 
     291  UInt32 additionalOffset; 
     292  UInt32 reps[LZMA_NUM_REPS]; 
     293  UInt32 state; 
     294 
     295  UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; 
     296  UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; 
     297  UInt32 alignPrices[kAlignTableSize]; 
     298  UInt32 alignPriceCount; 
     299 
     300  UInt32 distTableSize; 
     301 
     302  unsigned lc, lp, pb; 
     303  unsigned lpMask, pbMask; 
     304 
     305  CLzmaProb *litProbs; 
     306 
     307  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; 
     308  CLzmaProb isRep[kNumStates]; 
     309  CLzmaProb isRepG0[kNumStates]; 
     310  CLzmaProb isRepG1[kNumStates]; 
     311  CLzmaProb isRepG2[kNumStates]; 
     312  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; 
     313 
     314  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; 
     315  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; 
     316  CLzmaProb posAlignEncoder[1 << kNumAlignBits]; 
     317   
     318  CLenPriceEnc lenEnc; 
     319  CLenPriceEnc repLenEnc; 
     320 
     321  unsigned lclp; 
     322 
     323  Bool fastMode; 
     324   
     325  CRangeEnc rc; 
     326 
     327  Bool writeEndMark; 
     328  UInt64 nowPos64; 
     329  UInt32 matchPriceCount; 
     330  Bool finished; 
     331  Bool multiThread; 
     332 
     333  SRes result; 
     334  UInt32 dictSize; 
     335  UInt32 matchFinderCycles; 
     336 
     337  int needInit; 
     338 
     339  CSaveState saveState; 
     340} CLzmaEnc; 
     341 
     342void LzmaEnc_SaveState(CLzmaEncHandle pp) 
     343{ 
     344  CLzmaEnc *p = (CLzmaEnc *)pp; 
     345  CSaveState *dest = &p->saveState; 
     346  int i; 
     347  dest->lenEnc = p->lenEnc; 
     348  dest->repLenEnc = p->repLenEnc; 
     349  dest->state = p->state; 
     350 
     351  for (i = 0; i < kNumStates; i++) 
     352  { 
     353    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); 
     354    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); 
     355  } 
     356  for (i = 0; i < kNumLenToPosStates; i++) 
     357    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); 
     358  memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); 
     359  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); 
     360  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); 
     361  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); 
     362  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); 
     363  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); 
     364  memcpy(dest->reps, p->reps, sizeof(p->reps)); 
     365  memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); 
     366} 
     367 
     368void LzmaEnc_RestoreState(CLzmaEncHandle pp) 
     369{ 
     370  CLzmaEnc *dest = (CLzmaEnc *)pp; 
     371  const CSaveState *p = &dest->saveState; 
     372  int i; 
     373  dest->lenEnc = p->lenEnc; 
     374  dest->repLenEnc = p->repLenEnc; 
     375  dest->state = p->state; 
     376 
     377  for (i = 0; i < kNumStates; i++) 
     378  { 
     379    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); 
     380    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); 
     381  } 
     382  for (i = 0; i < kNumLenToPosStates; i++) 
     383    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); 
     384  memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); 
     385  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); 
     386  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); 
     387  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); 
     388  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); 
     389  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); 
     390  memcpy(dest->reps, p->reps, sizeof(p->reps)); 
     391  memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); 
     392} 
     393 
     394SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) 
     395{ 
     396  CLzmaEnc *p = (CLzmaEnc *)pp; 
     397  CLzmaEncProps props = *props2; 
     398  LzmaEncProps_Normalize(&props); 
     399 
     400  if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || 
     401      props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) 
     402    return SZ_ERROR_PARAM; 
     403  p->dictSize = props.dictSize; 
     404  p->matchFinderCycles = props.mc; 
     405  { 
     406    unsigned fb = props.fb; 
     407    if (fb < 5) 
     408      fb = 5; 
     409    if (fb > LZMA_MATCH_LEN_MAX) 
     410      fb = LZMA_MATCH_LEN_MAX; 
     411    p->numFastBytes = fb; 
     412  } 
     413  p->lc = props.lc; 
     414  p->lp = props.lp; 
     415  p->pb = props.pb; 
     416  p->fastMode = (props.algo == 0); 
     417  p->matchFinderBase.btMode = props.btMode; 
     418  { 
     419    UInt32 numHashBytes = 4; 
     420    if (props.btMode) 
     421    { 
     422      if (props.numHashBytes < 2) 
     423        numHashBytes = 2; 
     424      else if (props.numHashBytes < 4) 
     425        numHashBytes = props.numHashBytes; 
     426    } 
     427    p->matchFinderBase.numHashBytes = numHashBytes; 
     428  } 
     429 
     430  p->matchFinderBase.cutValue = props.mc; 
     431 
     432  p->writeEndMark = props.writeEndMark; 
     433 
     434  #ifndef _7ZIP_ST 
     435  /* 
     436  if (newMultiThread != _multiThread) 
     437  { 
     438    ReleaseMatchFinder(); 
     439    _multiThread = newMultiThread; 
     440  } 
     441  */ 
     442  p->multiThread = (props.numThreads > 1); 
     443  #endif 
     444 
     445  return SZ_OK; 
     446} 
     447 
     448static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5}; 
     449static const int kMatchNextStates[kNumStates]   = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; 
     450static const int kRepNextStates[kNumStates]     = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; 
     451static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; 
     452 
     453#define IsCharState(s) ((s) < 7) 
     454 
     455#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) 
     456 
     457#define kInfinityPrice (1 << 30) 
     458 
     459static void RangeEnc_Construct(CRangeEnc *p) 
     460{ 
     461  p->outStream = 0; 
     462  p->bufBase = 0; 
     463} 
     464 
     465#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) 
     466 
     467#define RC_BUF_SIZE (1 << 16) 
     468static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) 
     469{ 
     470  if (p->bufBase == 0) 
     471  { 
     472    p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); 
     473    if (p->bufBase == 0) 
     474      return 0; 
     475    p->bufLim = p->bufBase + RC_BUF_SIZE; 
     476  } 
     477  return 1; 
     478} 
     479 
     480static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) 
     481{ 
     482  alloc->Free(alloc, p->bufBase); 
     483  p->bufBase = 0; 
     484} 
     485 
     486static void RangeEnc_Init(CRangeEnc *p) 
     487{ 
     488  /* Stream.Init(); */ 
     489  p->low = 0; 
     490  p->range = 0xFFFFFFFF; 
     491  p->cacheSize = 1; 
     492  p->cache = 0; 
     493 
     494  p->buf = p->bufBase; 
     495 
     496  p->processed = 0; 
     497  p->res = SZ_OK; 
     498} 
     499 
     500static void RangeEnc_FlushStream(CRangeEnc *p) 
     501{ 
     502  size_t num; 
     503  if (p->res != SZ_OK) 
     504    return; 
     505  num = p->buf - p->bufBase; 
     506  if (num != p->outStream->Write(p->outStream, p->bufBase, num)) 
     507    p->res = SZ_ERROR_WRITE; 
     508  p->processed += num; 
     509  p->buf = p->bufBase; 
     510} 
     511 
     512static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) 
     513{ 
     514  if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) 
     515  { 
     516    Byte temp = p->cache; 
     517    do 
     518    { 
     519      Byte *buf = p->buf; 
     520      *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); 
     521      p->buf = buf; 
     522      if (buf == p->bufLim) 
     523        RangeEnc_FlushStream(p); 
     524      temp = 0xFF; 
     525    } 
     526    while (--p->cacheSize != 0); 
     527    p->cache = (Byte)((UInt32)p->low >> 24); 
     528  } 
     529  p->cacheSize++; 
     530  p->low = (UInt32)p->low << 8; 
     531} 
     532 
     533static void RangeEnc_FlushData(CRangeEnc *p) 
     534{ 
     535  int i; 
     536  for (i = 0; i < 5; i++) 
     537    RangeEnc_ShiftLow(p); 
     538} 
     539 
     540static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) 
     541{ 
     542  do 
     543  { 
     544    p->range >>= 1; 
     545    p->low += p->range & (0 - ((value >> --numBits) & 1)); 
     546    if (p->range < kTopValue) 
     547    { 
     548      p->range <<= 8; 
     549      RangeEnc_ShiftLow(p); 
     550    } 
     551  } 
     552  while (numBits != 0); 
     553} 
     554 
     555static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) 
     556{ 
     557  UInt32 ttt = *prob; 
     558  UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; 
     559  if (symbol == 0) 
     560  { 
     561    p->range = newBound; 
     562    ttt += (kBitModelTotal - ttt) >> kNumMoveBits; 
     563  } 
     564  else 
     565  { 
     566    p->low += newBound; 
     567    p->range -= newBound; 
     568    ttt -= ttt >> kNumMoveBits; 
     569  } 
     570  *prob = (CLzmaProb)ttt; 
     571  if (p->range < kTopValue) 
     572  { 
     573    p->range <<= 8; 
     574    RangeEnc_ShiftLow(p); 
     575  } 
     576} 
     577 
     578static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) 
     579{ 
     580  symbol |= 0x100; 
     581  do 
     582  { 
     583    RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); 
     584    symbol <<= 1; 
     585  } 
     586  while (symbol < 0x10000); 
     587} 
     588 
     589static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) 
     590{ 
     591  UInt32 offs = 0x100; 
     592  symbol |= 0x100; 
     593  do 
     594  { 
     595    matchByte <<= 1; 
     596    RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); 
     597    symbol <<= 1; 
     598    offs &= ~(matchByte ^ symbol); 
     599  } 
     600  while (symbol < 0x10000); 
     601} 
     602 
     603void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) 
     604{ 
     605  UInt32 i; 
     606  for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) 
     607  { 
     608    const int kCyclesBits = kNumBitPriceShiftBits; 
     609    UInt32 w = i; 
     610    UInt32 bitCount = 0; 
     611    int j; 
     612    for (j = 0; j < kCyclesBits; j++) 
     613    { 
     614      w = w * w; 
     615      bitCount <<= 1; 
     616      while (w >= ((UInt32)1 << 16)) 
     617      { 
     618        w >>= 1; 
     619        bitCount++; 
     620      } 
     621    } 
     622    ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); 
     623  } 
     624} 
     625 
     626 
     627#define GET_PRICE(prob, symbol) \ 
     628  p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; 
     629 
     630#define GET_PRICEa(prob, symbol) \ 
     631  ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; 
     632 
     633#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] 
     634#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] 
     635 
     636#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] 
     637#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] 
     638 
     639static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) 
     640{ 
     641  UInt32 price = 0; 
     642  symbol |= 0x100; 
     643  do 
     644  { 
     645    price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); 
     646    symbol <<= 1; 
     647  } 
     648  while (symbol < 0x10000); 
     649  return price; 
     650} 
     651 
     652static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) 
     653{ 
     654  UInt32 price = 0; 
     655  UInt32 offs = 0x100; 
     656  symbol |= 0x100; 
     657  do 
     658  { 
     659    matchByte <<= 1; 
     660    price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); 
     661    symbol <<= 1; 
     662    offs &= ~(matchByte ^ symbol); 
     663  } 
     664  while (symbol < 0x10000); 
     665  return price; 
     666} 
     667 
     668 
     669static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) 
     670{ 
     671  UInt32 m = 1; 
     672  int i; 
     673  for (i = numBitLevels; i != 0;) 
     674  { 
     675    UInt32 bit; 
     676    i--; 
     677    bit = (symbol >> i) & 1; 
     678    RangeEnc_EncodeBit(rc, probs + m, bit); 
     679    m = (m << 1) | bit; 
     680  } 
     681} 
     682 
     683static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) 
     684{ 
     685  UInt32 m = 1; 
     686  int i; 
     687  for (i = 0; i < numBitLevels; i++) 
     688  { 
     689    UInt32 bit = symbol & 1; 
     690    RangeEnc_EncodeBit(rc, probs + m, bit); 
     691    m = (m << 1) | bit; 
     692    symbol >>= 1; 
     693  } 
     694} 
     695 
     696static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) 
     697{ 
     698  UInt32 price = 0; 
     699  symbol |= (1 << numBitLevels); 
     700  while (symbol != 1) 
     701  { 
     702    price += GET_PRICEa(probs[symbol >> 1], symbol & 1); 
     703    symbol >>= 1; 
     704  } 
     705  return price; 
     706} 
     707 
     708static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) 
     709{ 
     710  UInt32 price = 0; 
     711  UInt32 m = 1; 
     712  int i; 
     713  for (i = numBitLevels; i != 0; i--) 
     714  { 
     715    UInt32 bit = symbol & 1; 
     716    symbol >>= 1; 
     717    price += GET_PRICEa(probs[m], bit); 
     718    m = (m << 1) | bit; 
     719  } 
     720  return price; 
     721} 
     722 
     723 
     724static void LenEnc_Init(CLenEnc *p) 
     725{ 
     726  unsigned i; 
     727  p->choice = p->choice2 = kProbInitValue; 
     728  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) 
     729    p->low[i] = kProbInitValue; 
     730  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) 
     731    p->mid[i] = kProbInitValue; 
     732  for (i = 0; i < kLenNumHighSymbols; i++) 
     733    p->high[i] = kProbInitValue; 
     734} 
     735 
     736static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) 
     737{ 
     738  if (symbol < kLenNumLowSymbols) 
     739  { 
     740    RangeEnc_EncodeBit(rc, &p->choice, 0); 
     741    RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); 
     742  } 
     743  else 
     744  { 
     745    RangeEnc_EncodeBit(rc, &p->choice, 1); 
     746    if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) 
     747    { 
     748      RangeEnc_EncodeBit(rc, &p->choice2, 0); 
     749      RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); 
     750    } 
     751    else 
     752    { 
     753      RangeEnc_EncodeBit(rc, &p->choice2, 1); 
     754      RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); 
     755    } 
     756  } 
     757} 
     758 
     759static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) 
     760{ 
     761  UInt32 a0 = GET_PRICE_0a(p->choice); 
     762  UInt32 a1 = GET_PRICE_1a(p->choice); 
     763  UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); 
     764  UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); 
     765  UInt32 i = 0; 
     766  for (i = 0; i < kLenNumLowSymbols; i++) 
     767  { 
     768    if (i >= numSymbols) 
     769      return; 
     770    prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); 
     771  } 
     772  for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) 
     773  { 
     774    if (i >= numSymbols) 
     775      return; 
     776    prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); 
     777  } 
     778  for (; i < numSymbols; i++) 
     779    prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); 
     780} 
     781 
     782static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) 
     783{ 
     784  LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); 
     785  p->counters[posState] = p->tableSize; 
     786} 
     787 
     788static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) 
     789{ 
     790  UInt32 posState; 
     791  for (posState = 0; posState < numPosStates; posState++) 
     792    LenPriceEnc_UpdateTable(p, posState, ProbPrices); 
     793} 
     794 
     795static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) 
     796{ 
     797  LenEnc_Encode(&p->p, rc, symbol, posState); 
     798  if (updatePrice) 
     799    if (--p->counters[posState] == 0) 
     800      LenPriceEnc_UpdateTable(p, posState, ProbPrices); 
     801} 
     802 
     803 
     804 
     805 
     806static void MovePos(CLzmaEnc *p, UInt32 num) 
     807{ 
     808  #ifdef SHOW_STAT 
     809  ttt += num; 
     810  printf("\n MovePos %d", num); 
     811  #endif 
     812  if (num != 0) 
     813  { 
     814    p->additionalOffset += num; 
     815    p->matchFinder.Skip(p->matchFinderObj, num); 
     816  } 
     817} 
     818 
     819static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) 
     820{ 
     821  UInt32 lenRes = 0, numPairs; 
     822  p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); 
     823  numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); 
     824  #ifdef SHOW_STAT 
     825  printf("\n i = %d numPairs = %d    ", ttt, numPairs / 2); 
     826  ttt++; 
     827  { 
     828    UInt32 i; 
     829    for (i = 0; i < numPairs; i += 2) 
     830      printf("%2d %6d   | ", p->matches[i], p->matches[i + 1]); 
     831  } 
     832  #endif 
     833  if (numPairs > 0) 
     834  { 
     835    lenRes = p->matches[numPairs - 2]; 
     836    if (lenRes == p->numFastBytes) 
     837    { 
     838      const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; 
     839      UInt32 distance = p->matches[numPairs - 1] + 1; 
     840      UInt32 numAvail = p->numAvail; 
     841      if (numAvail > LZMA_MATCH_LEN_MAX) 
     842        numAvail = LZMA_MATCH_LEN_MAX; 
     843      { 
     844        const Byte *pby2 = pby - distance; 
     845        for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); 
     846      } 
     847    } 
     848  } 
     849  p->additionalOffset++; 
     850  *numDistancePairsRes = numPairs; 
     851  return lenRes; 
     852} 
     853 
     854 
     855#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; 
     856#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; 
     857#define IsShortRep(p) ((p)->backPrev == 0) 
     858 
     859static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) 
     860{ 
     861  return 
     862    GET_PRICE_0(p->isRepG0[state]) + 
     863    GET_PRICE_0(p->isRep0Long[state][posState]); 
     864} 
     865 
     866static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) 
     867{ 
     868  UInt32 price; 
     869  if (repIndex == 0) 
     870  { 
     871    price = GET_PRICE_0(p->isRepG0[state]); 
     872    price += GET_PRICE_1(p->isRep0Long[state][posState]); 
     873  } 
     874  else 
     875  { 
     876    price = GET_PRICE_1(p->isRepG0[state]); 
     877    if (repIndex == 1) 
     878      price += GET_PRICE_0(p->isRepG1[state]); 
     879    else 
     880    { 
     881      price += GET_PRICE_1(p->isRepG1[state]); 
     882      price += GET_PRICE(p->isRepG2[state], repIndex - 2); 
     883    } 
     884  } 
     885  return price; 
     886} 
     887 
     888static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) 
     889{ 
     890  return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + 
     891    GetPureRepPrice(p, repIndex, state, posState); 
     892} 
     893 
     894static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) 
     895{ 
     896  UInt32 posMem = p->opt[cur].posPrev; 
     897  UInt32 backMem = p->opt[cur].backPrev; 
     898  p->optimumEndIndex = cur; 
     899  do 
     900  { 
     901    if (p->opt[cur].prev1IsChar) 
     902    { 
     903      MakeAsChar(&p->opt[posMem]) 
     904      p->opt[posMem].posPrev = posMem - 1; 
     905      if (p->opt[cur].prev2) 
     906      { 
     907        p->opt[posMem - 1].prev1IsChar = False; 
     908        p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; 
     909        p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; 
     910      } 
     911    } 
     912    { 
     913      UInt32 posPrev = posMem; 
     914      UInt32 backCur = backMem; 
     915       
     916      backMem = p->opt[posPrev].backPrev; 
     917      posMem = p->opt[posPrev].posPrev; 
     918       
     919      p->opt[posPrev].backPrev = backCur; 
     920      p->opt[posPrev].posPrev = cur; 
     921      cur = posPrev; 
     922    } 
     923  } 
     924  while (cur != 0); 
     925  *backRes = p->opt[0].backPrev; 
     926  p->optimumCurrentIndex  = p->opt[0].posPrev; 
     927  return p->optimumCurrentIndex; 
     928} 
     929 
     930#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) 
     931 
     932static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) 
     933{ 
     934  UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; 
     935  UInt32 matchPrice, repMatchPrice, normalMatchPrice; 
     936  UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; 
     937  UInt32 *matches; 
     938  const Byte *data; 
     939  Byte curByte, matchByte; 
     940  if (p->optimumEndIndex != p->optimumCurrentIndex) 
     941  { 
     942    const COptimal *opt = &p->opt[p->optimumCurrentIndex]; 
     943    UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; 
     944    *backRes = opt->backPrev; 
     945    p->optimumCurrentIndex = opt->posPrev; 
     946    return lenRes; 
     947  } 
     948  p->optimumCurrentIndex = p->optimumEndIndex = 0; 
     949   
     950  if (p->additionalOffset == 0) 
     951    mainLen = ReadMatchDistances(p, &numPairs); 
     952  else 
     953  { 
     954    mainLen = p->longestMatchLength; 
     955    numPairs = p->numPairs; 
     956  } 
     957 
     958  numAvail = p->numAvail; 
     959  if (numAvail < 2) 
     960  { 
     961    *backRes = (UInt32)(-1); 
     962    return 1; 
     963  } 
     964  if (numAvail > LZMA_MATCH_LEN_MAX) 
     965    numAvail = LZMA_MATCH_LEN_MAX; 
     966 
     967  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; 
     968  repMaxIndex = 0; 
     969  for (i = 0; i < LZMA_NUM_REPS; i++) 
     970  { 
     971    UInt32 lenTest; 
     972    const Byte *data2; 
     973    reps[i] = p->reps[i]; 
     974    data2 = data - (reps[i] + 1); 
     975    if (data[0] != data2[0] || data[1] != data2[1]) 
     976    { 
     977      repLens[i] = 0; 
     978      continue; 
     979    } 
     980    for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); 
     981    repLens[i] = lenTest; 
     982    if (lenTest > repLens[repMaxIndex]) 
     983      repMaxIndex = i; 
     984  } 
     985  if (repLens[repMaxIndex] >= p->numFastBytes) 
     986  { 
     987    UInt32 lenRes; 
     988    *backRes = repMaxIndex; 
     989    lenRes = repLens[repMaxIndex]; 
     990    MovePos(p, lenRes - 1); 
     991    return lenRes; 
     992  } 
     993 
     994  matches = p->matches; 
     995  if (mainLen >= p->numFastBytes) 
     996  { 
     997    *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; 
     998    MovePos(p, mainLen - 1); 
     999    return mainLen; 
     1000  } 
     1001  curByte = *data; 
     1002  matchByte = *(data - (reps[0] + 1)); 
     1003 
     1004  if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) 
     1005  { 
     1006    *backRes = (UInt32)-1; 
     1007    return 1; 
     1008  } 
     1009 
     1010  p->opt[0].state = (CState)p->state; 
     1011 
     1012  posState = (position & p->pbMask); 
     1013 
     1014  { 
     1015    const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); 
     1016    p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + 
     1017        (!IsCharState(p->state) ? 
     1018          LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : 
     1019          LitEnc_GetPrice(probs, curByte, p->ProbPrices)); 
     1020  } 
     1021 
     1022  MakeAsChar(&p->opt[1]); 
     1023 
     1024  matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); 
     1025  repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); 
     1026 
     1027  if (matchByte == curByte) 
     1028  { 
     1029    UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); 
     1030    if (shortRepPrice < p->opt[1].price) 
     1031    { 
     1032      p->opt[1].price = shortRepPrice; 
     1033      MakeAsShortRep(&p->opt[1]); 
     1034    } 
     1035  } 
     1036  lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); 
     1037 
     1038  if (lenEnd < 2) 
     1039  { 
     1040    *backRes = p->opt[1].backPrev; 
     1041    return 1; 
     1042  } 
     1043 
     1044  p->opt[1].posPrev = 0; 
     1045  for (i = 0; i < LZMA_NUM_REPS; i++) 
     1046    p->opt[0].backs[i] = reps[i]; 
     1047 
     1048  len = lenEnd; 
     1049  do 
     1050    p->opt[len--].price = kInfinityPrice; 
     1051  while (len >= 2); 
     1052 
     1053  for (i = 0; i < LZMA_NUM_REPS; i++) 
     1054  { 
     1055    UInt32 repLen = repLens[i]; 
     1056    UInt32 price; 
     1057    if (repLen < 2) 
     1058      continue; 
     1059    price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); 
     1060    do 
     1061    { 
     1062      UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; 
     1063      COptimal *opt = &p->opt[repLen]; 
     1064      if (curAndLenPrice < opt->price) 
     1065      { 
     1066        opt->price = curAndLenPrice; 
     1067        opt->posPrev = 0; 
     1068        opt->backPrev = i; 
     1069        opt->prev1IsChar = False; 
     1070      } 
     1071    } 
     1072    while (--repLen >= 2); 
     1073  } 
     1074 
     1075  normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); 
     1076 
     1077  len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); 
     1078  if (len <= mainLen) 
     1079  { 
     1080    UInt32 offs = 0; 
     1081    while (len > matches[offs]) 
     1082      offs += 2; 
     1083    for (; ; len++) 
     1084    { 
     1085      COptimal *opt; 
     1086      UInt32 distance = matches[offs + 1]; 
     1087 
     1088      UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; 
     1089      UInt32 lenToPosState = GetLenToPosState(len); 
     1090      if (distance < kNumFullDistances) 
     1091        curAndLenPrice += p->distancesPrices[lenToPosState][distance]; 
     1092      else 
     1093      { 
     1094        UInt32 slot; 
     1095        GetPosSlot2(distance, slot); 
     1096        curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; 
     1097      } 
     1098      opt = &p->opt[len]; 
     1099      if (curAndLenPrice < opt->price) 
     1100      { 
     1101        opt->price = curAndLenPrice; 
     1102        opt->posPrev = 0; 
     1103        opt->backPrev = distance + LZMA_NUM_REPS; 
     1104        opt->prev1IsChar = False; 
     1105      } 
     1106      if (len == matches[offs]) 
     1107      { 
     1108        offs += 2; 
     1109        if (offs == numPairs) 
     1110          break; 
     1111      } 
     1112    } 
     1113  } 
     1114 
     1115  cur = 0; 
     1116 
     1117    #ifdef SHOW_STAT2 
     1118    if (position >= 0) 
     1119    { 
     1120      unsigned i; 
     1121      printf("\n pos = %4X", position); 
     1122      for (i = cur; i <= lenEnd; i++) 
     1123      printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); 
     1124    } 
     1125    #endif 
     1126 
     1127  for (;;) 
     1128  { 
     1129    UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; 
     1130    UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; 
     1131    Bool nextIsChar; 
     1132    Byte curByte, matchByte; 
     1133    const Byte *data; 
     1134    COptimal *curOpt; 
     1135    COptimal *nextOpt; 
     1136 
     1137    cur++; 
     1138    if (cur == lenEnd) 
     1139      return Backward(p, backRes, cur); 
     1140 
     1141    newLen = ReadMatchDistances(p, &numPairs); 
     1142    if (newLen >= p->numFastBytes) 
     1143    { 
     1144      p->numPairs = numPairs; 
     1145      p->longestMatchLength = newLen; 
     1146      return Backward(p, backRes, cur); 
     1147    } 
     1148    position++; 
     1149    curOpt = &p->opt[cur]; 
     1150    posPrev = curOpt->posPrev; 
     1151    if (curOpt->prev1IsChar) 
     1152    { 
     1153      posPrev--; 
     1154      if (curOpt->prev2) 
     1155      { 
     1156        state = p->opt[curOpt->posPrev2].state; 
     1157        if (curOpt->backPrev2 < LZMA_NUM_REPS) 
     1158          state = kRepNextStates[state]; 
     1159        else 
     1160          state = kMatchNextStates[state]; 
     1161      } 
     1162      else 
     1163        state = p->opt[posPrev].state; 
     1164      state = kLiteralNextStates[state]; 
     1165    } 
     1166    else 
     1167      state = p->opt[posPrev].state; 
     1168    if (posPrev == cur - 1) 
     1169    { 
     1170      if (IsShortRep(curOpt)) 
     1171        state = kShortRepNextStates[state]; 
     1172      else 
     1173        state = kLiteralNextStates[state]; 
     1174    } 
     1175    else 
     1176    { 
     1177      UInt32 pos; 
     1178      const COptimal *prevOpt; 
     1179      if (curOpt->prev1IsChar && curOpt->prev2) 
     1180      { 
     1181        posPrev = curOpt->posPrev2; 
     1182        pos = curOpt->backPrev2; 
     1183        state = kRepNextStates[state]; 
     1184      } 
     1185      else 
     1186      { 
     1187        pos = curOpt->backPrev; 
     1188        if (pos < LZMA_NUM_REPS) 
     1189          state = kRepNextStates[state]; 
     1190        else 
     1191          state = kMatchNextStates[state]; 
     1192      } 
     1193      prevOpt = &p->opt[posPrev]; 
     1194      if (pos < LZMA_NUM_REPS) 
     1195      { 
     1196        UInt32 i; 
     1197        reps[0] = prevOpt->backs[pos]; 
     1198        for (i = 1; i <= pos; i++) 
     1199          reps[i] = prevOpt->backs[i - 1]; 
     1200        for (; i < LZMA_NUM_REPS; i++) 
     1201          reps[i] = prevOpt->backs[i]; 
     1202      } 
     1203      else 
     1204      { 
     1205        UInt32 i; 
     1206        reps[0] = (pos - LZMA_NUM_REPS); 
     1207        for (i = 1; i < LZMA_NUM_REPS; i++) 
     1208          reps[i] = prevOpt->backs[i - 1]; 
     1209      } 
     1210    } 
     1211    curOpt->state = (CState)state; 
     1212 
     1213    curOpt->backs[0] = reps[0]; 
     1214    curOpt->backs[1] = reps[1]; 
     1215    curOpt->backs[2] = reps[2]; 
     1216    curOpt->backs[3] = reps[3]; 
     1217 
     1218    curPrice = curOpt->price; 
     1219    nextIsChar = False; 
     1220    data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; 
     1221    curByte = *data; 
     1222    matchByte = *(data - (reps[0] + 1)); 
     1223 
     1224    posState = (position & p->pbMask); 
     1225 
     1226    curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); 
     1227    { 
     1228      const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); 
     1229      curAnd1Price += 
     1230        (!IsCharState(state) ? 
     1231          LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : 
     1232          LitEnc_GetPrice(probs, curByte, p->ProbPrices)); 
     1233    } 
     1234 
     1235    nextOpt = &p->opt[cur + 1]; 
     1236 
     1237    if (curAnd1Price < nextOpt->price) 
     1238    { 
     1239      nextOpt->price = curAnd1Price; 
     1240      nextOpt->posPrev = cur; 
     1241      MakeAsChar(nextOpt); 
     1242      nextIsChar = True; 
     1243    } 
     1244 
     1245    matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); 
     1246    repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); 
     1247     
     1248    if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) 
     1249    { 
     1250      UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); 
     1251      if (shortRepPrice <= nextOpt->price) 
     1252      { 
     1253        nextOpt->price = shortRepPrice; 
     1254        nextOpt->posPrev = cur; 
     1255        MakeAsShortRep(nextOpt); 
     1256        nextIsChar = True; 
     1257      } 
     1258    } 
     1259    numAvailFull = p->numAvail; 
     1260    { 
     1261      UInt32 temp = kNumOpts - 1 - cur; 
     1262      if (temp < numAvailFull) 
     1263        numAvailFull = temp; 
     1264    } 
     1265 
     1266    if (numAvailFull < 2) 
     1267      continue; 
     1268    numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); 
     1269 
     1270    if (!nextIsChar && matchByte != curByte) /* speed optimization */ 
     1271    { 
     1272      /* try Literal + rep0 */ 
     1273      UInt32 temp; 
     1274      UInt32 lenTest2; 
     1275      const Byte *data2 = data - (reps[0] + 1); 
     1276      UInt32 limit = p->numFastBytes + 1; 
     1277      if (limit > numAvailFull) 
     1278        limit = numAvailFull; 
     1279 
     1280      for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); 
     1281      lenTest2 = temp - 1; 
     1282      if (lenTest2 >= 2) 
     1283      { 
     1284        UInt32 state2 = kLiteralNextStates[state]; 
     1285        UInt32 posStateNext = (position + 1) & p->pbMask; 
     1286        UInt32 nextRepMatchPrice = curAnd1Price + 
     1287            GET_PRICE_1(p->isMatch[state2][posStateNext]) + 
     1288            GET_PRICE_1(p->isRep[state2]); 
     1289        /* for (; lenTest2 >= 2; lenTest2--) */ 
     1290        { 
     1291          UInt32 curAndLenPrice; 
     1292          COptimal *opt; 
     1293          UInt32 offset = cur + 1 + lenTest2; 
     1294          while (lenEnd < offset) 
     1295            p->opt[++lenEnd].price = kInfinityPrice; 
     1296          curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); 
     1297          opt = &p->opt[offset]; 
     1298          if (curAndLenPrice < opt->price) 
     1299          { 
     1300            opt->price = curAndLenPrice; 
     1301            opt->posPrev = cur + 1; 
     1302            opt->backPrev = 0; 
     1303            opt->prev1IsChar = True; 
     1304            opt->prev2 = False; 
     1305          } 
     1306        } 
     1307      } 
     1308    } 
     1309     
     1310    startLen = 2; /* speed optimization */ 
     1311    { 
     1312    UInt32 repIndex; 
     1313    for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) 
     1314    { 
     1315      UInt32 lenTest; 
     1316      UInt32 lenTestTemp; 
     1317      UInt32 price; 
     1318      const Byte *data2 = data - (reps[repIndex] + 1); 
     1319      if (data[0] != data2[0] || data[1] != data2[1]) 
     1320        continue; 
     1321      for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); 
     1322      while (lenEnd < cur + lenTest) 
     1323        p->opt[++lenEnd].price = kInfinityPrice; 
     1324      lenTestTemp = lenTest; 
     1325      price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); 
     1326      do 
     1327      { 
     1328        UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; 
     1329        COptimal *opt = &p->opt[cur + lenTest]; 
     1330        if (curAndLenPrice < opt->price) 
     1331        { 
     1332          opt->price = curAndLenPrice; 
     1333          opt->posPrev = cur; 
     1334          opt->backPrev = repIndex; 
     1335          opt->prev1IsChar = False; 
     1336        } 
     1337      } 
     1338      while (--lenTest >= 2); 
     1339      lenTest = lenTestTemp; 
     1340       
     1341      if (repIndex == 0) 
     1342        startLen = lenTest + 1; 
     1343         
     1344      /* if (_maxMode) */ 
     1345        { 
     1346          UInt32 lenTest2 = lenTest + 1; 
     1347          UInt32 limit = lenTest2 + p->numFastBytes; 
     1348          UInt32 nextRepMatchPrice; 
     1349          if (limit > numAvailFull) 
     1350            limit = numAvailFull; 
     1351          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); 
     1352          lenTest2 -= lenTest + 1; 
     1353          if (lenTest2 >= 2) 
     1354          { 
     1355            UInt32 state2 = kRepNextStates[state]; 
     1356            UInt32 posStateNext = (position + lenTest) & p->pbMask; 
     1357            UInt32 curAndLenCharPrice = 
     1358                price + p->repLenEnc.prices[posState][lenTest - 2] + 
     1359                GET_PRICE_0(p->isMatch[state2][posStateNext]) + 
     1360                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), 
     1361                    data[lenTest], data2[lenTest], p->ProbPrices); 
     1362            state2 = kLiteralNextStates[state2]; 
     1363            posStateNext = (position + lenTest + 1) & p->pbMask; 
     1364            nextRepMatchPrice = curAndLenCharPrice + 
     1365                GET_PRICE_1(p->isMatch[state2][posStateNext]) + 
     1366                GET_PRICE_1(p->isRep[state2]); 
     1367             
     1368            /* for (; lenTest2 >= 2; lenTest2--) */ 
     1369            { 
     1370              UInt32 curAndLenPrice; 
     1371              COptimal *opt; 
     1372              UInt32 offset = cur + lenTest + 1 + lenTest2; 
     1373              while (lenEnd < offset) 
     1374                p->opt[++lenEnd].price = kInfinityPrice; 
     1375              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); 
     1376              opt = &p->opt[offset]; 
     1377              if (curAndLenPrice < opt->price) 
     1378              { 
     1379                opt->price = curAndLenPrice; 
     1380                opt->posPrev = cur + lenTest + 1; 
     1381                opt->backPrev = 0; 
     1382                opt->prev1IsChar = True; 
     1383                opt->prev2 = True; 
     1384                opt->posPrev2 = cur; 
     1385                opt->backPrev2 = repIndex; 
     1386              } 
     1387            } 
     1388          } 
     1389        } 
     1390    } 
     1391    } 
     1392    /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ 
     1393    if (newLen > numAvail) 
     1394    { 
     1395      newLen = numAvail; 
     1396      for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); 
     1397      matches[numPairs] = newLen; 
     1398      numPairs += 2; 
     1399    } 
     1400    if (newLen >= startLen) 
     1401    { 
     1402      UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); 
     1403      UInt32 offs, curBack, posSlot; 
     1404      UInt32 lenTest; 
     1405      while (lenEnd < cur + newLen) 
     1406        p->opt[++lenEnd].price = kInfinityPrice; 
     1407 
     1408      offs = 0; 
     1409      while (startLen > matches[offs]) 
     1410        offs += 2; 
     1411      curBack = matches[offs + 1]; 
     1412      GetPosSlot2(curBack, posSlot); 
     1413      for (lenTest = /*2*/ startLen; ; lenTest++) 
     1414      { 
     1415        UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; 
     1416        UInt32 lenToPosState = GetLenToPosState(lenTest); 
     1417        COptimal *opt; 
     1418        if (curBack < kNumFullDistances) 
     1419          curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; 
     1420        else 
     1421          curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; 
     1422         
     1423        opt = &p->opt[cur + lenTest]; 
     1424        if (curAndLenPrice < opt->price) 
     1425        { 
     1426          opt->price = curAndLenPrice; 
     1427          opt->posPrev = cur; 
     1428          opt->backPrev = curBack + LZMA_NUM_REPS; 
     1429          opt->prev1IsChar = False; 
     1430        } 
     1431 
     1432        if (/*_maxMode && */lenTest == matches[offs]) 
     1433        { 
     1434          /* Try Match + Literal + Rep0 */ 
     1435          const Byte *data2 = data - (curBack + 1); 
     1436          UInt32 lenTest2 = lenTest + 1; 
     1437          UInt32 limit = lenTest2 + p->numFastBytes; 
     1438          UInt32 nextRepMatchPrice; 
     1439          if (limit > numAvailFull) 
     1440            limit = numAvailFull; 
     1441          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); 
     1442          lenTest2 -= lenTest + 1; 
     1443          if (lenTest2 >= 2) 
     1444          { 
     1445            UInt32 state2 = kMatchNextStates[state]; 
     1446            UInt32 posStateNext = (position + lenTest) & p->pbMask; 
     1447            UInt32 curAndLenCharPrice = curAndLenPrice + 
     1448                GET_PRICE_0(p->isMatch[state2][posStateNext]) + 
     1449                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), 
     1450                    data[lenTest], data2[lenTest], p->ProbPrices); 
     1451            state2 = kLiteralNextStates[state2]; 
     1452            posStateNext = (posStateNext + 1) & p->pbMask; 
     1453            nextRepMatchPrice = curAndLenCharPrice + 
     1454                GET_PRICE_1(p->isMatch[state2][posStateNext]) + 
     1455                GET_PRICE_1(p->isRep[state2]); 
     1456             
     1457            /* for (; lenTest2 >= 2; lenTest2--) */ 
     1458            { 
     1459              UInt32 offset = cur + lenTest + 1 + lenTest2; 
     1460              UInt32 curAndLenPrice; 
     1461              COptimal *opt; 
     1462              while (lenEnd < offset) 
     1463                p->opt[++lenEnd].price = kInfinityPrice; 
     1464              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); 
     1465              opt = &p->opt[offset]; 
     1466              if (curAndLenPrice < opt->price) 
     1467              { 
     1468                opt->price = curAndLenPrice; 
     1469                opt->posPrev = cur + lenTest + 1; 
     1470                opt->backPrev = 0; 
     1471                opt->prev1IsChar = True; 
     1472                opt->prev2 = True; 
     1473                opt->posPrev2 = cur; 
     1474                opt->backPrev2 = curBack + LZMA_NUM_REPS; 
     1475              } 
     1476            } 
     1477          } 
     1478          offs += 2; 
     1479          if (offs == numPairs) 
     1480            break; 
     1481          curBack = matches[offs + 1]; 
     1482          if (curBack >= kNumFullDistances) 
     1483            GetPosSlot2(curBack, posSlot); 
     1484        } 
     1485      } 
     1486    } 
     1487  } 
     1488} 
     1489 
     1490#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) 
     1491 
     1492static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) 
     1493{ 
     1494  UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; 
     1495  const Byte *data; 
     1496  const UInt32 *matches; 
     1497 
     1498  if (p->additionalOffset == 0) 
     1499    mainLen = ReadMatchDistances(p, &numPairs); 
     1500  else 
     1501  { 
     1502    mainLen = p->longestMatchLength; 
     1503    numPairs = p->numPairs; 
     1504  } 
     1505 
     1506  numAvail = p->numAvail; 
     1507  *backRes = (UInt32)-1; 
     1508  if (numAvail < 2) 
     1509    return 1; 
     1510  if (numAvail > LZMA_MATCH_LEN_MAX) 
     1511    numAvail = LZMA_MATCH_LEN_MAX; 
     1512  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; 
     1513 
     1514  repLen = repIndex = 0; 
     1515  for (i = 0; i < LZMA_NUM_REPS; i++) 
     1516  { 
     1517    UInt32 len; 
     1518    const Byte *data2 = data - (p->reps[i] + 1); 
     1519    if (data[0] != data2[0] || data[1] != data2[1]) 
     1520      continue; 
     1521    for (len = 2; len < numAvail && data[len] == data2[len]; len++); 
     1522    if (len >= p->numFastBytes) 
     1523    { 
     1524      *backRes = i; 
     1525      MovePos(p, len - 1); 
     1526      return len; 
     1527    } 
     1528    if (len > repLen) 
     1529    { 
     1530      repIndex = i; 
     1531      repLen = len; 
     1532    } 
     1533  } 
     1534 
     1535  matches = p->matches; 
     1536  if (mainLen >= p->numFastBytes) 
     1537  { 
     1538    *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; 
     1539    MovePos(p, mainLen - 1); 
     1540    return mainLen; 
     1541  } 
     1542 
     1543  mainDist = 0; /* for GCC */ 
     1544  if (mainLen >= 2) 
     1545  { 
     1546    mainDist = matches[numPairs - 1]; 
     1547    while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) 
     1548    { 
     1549      if (!ChangePair(matches[numPairs - 3], mainDist)) 
     1550        break; 
     1551      numPairs -= 2; 
     1552      mainLen = matches[numPairs - 2]; 
     1553      mainDist = matches[numPairs - 1]; 
     1554    } 
     1555    if (mainLen == 2 && mainDist >= 0x80) 
     1556      mainLen = 1; 
     1557  } 
     1558 
     1559  if (repLen >= 2 && ( 
     1560        (repLen + 1 >= mainLen) || 
     1561        (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || 
     1562        (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) 
     1563  { 
     1564    *backRes = repIndex; 
     1565    MovePos(p, repLen - 1); 
     1566    return repLen; 
     1567  } 
     1568   
     1569  if (mainLen < 2 || numAvail <= 2) 
     1570    return 1; 
     1571 
     1572  p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); 
     1573  if (p->longestMatchLength >= 2) 
     1574  { 
     1575    UInt32 newDistance = matches[p->numPairs - 1]; 
     1576    if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || 
     1577        (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || 
     1578        (p->longestMatchLength > mainLen + 1) || 
     1579        (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) 
     1580      return 1; 
     1581  } 
     1582   
     1583  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; 
     1584  for (i = 0; i < LZMA_NUM_REPS; i++) 
     1585  { 
     1586    UInt32 len, limit; 
     1587    const Byte *data2 = data - (p->reps[i] + 1); 
     1588    if (data[0] != data2[0] || data[1] != data2[1]) 
     1589      continue; 
     1590    limit = mainLen - 1; 
     1591    for (len = 2; len < limit && data[len] == data2[len]; len++); 
     1592    if (len >= limit) 
     1593      return 1; 
     1594  } 
     1595  *backRes = mainDist + LZMA_NUM_REPS; 
     1596  MovePos(p, mainLen - 2); 
     1597  return mainLen; 
     1598} 
     1599 
     1600static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) 
     1601{ 
     1602  UInt32 len; 
     1603  RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); 
     1604  RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); 
     1605  p->state = kMatchNextStates[p->state]; 
     1606  len = LZMA_MATCH_LEN_MIN; 
     1607  LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); 
     1608  RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); 
     1609  RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); 
     1610  RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); 
     1611} 
     1612 
     1613static SRes CheckErrors(CLzmaEnc *p) 
     1614{ 
     1615  if (p->result != SZ_OK) 
     1616    return p->result; 
     1617  if (p->rc.res != SZ_OK) 
     1618    p->result = SZ_ERROR_WRITE; 
     1619  if (p->matchFinderBase.result != SZ_OK) 
     1620    p->result = SZ_ERROR_READ; 
     1621  if (p->result != SZ_OK) 
     1622    p->finished = True; 
     1623  return p->result; 
     1624} 
     1625 
     1626static SRes Flush(CLzmaEnc *p, UInt32 nowPos) 
     1627{ 
     1628  /* ReleaseMFStream(); */ 
     1629  p->finished = True; 
     1630  if (p->writeEndMark) 
     1631    WriteEndMarker(p, nowPos & p->pbMask); 
     1632  RangeEnc_FlushData(&p->rc); 
     1633  RangeEnc_FlushStream(&p->rc); 
     1634  return CheckErrors(p); 
     1635} 
     1636 
     1637static void FillAlignPrices(CLzmaEnc *p) 
     1638{ 
     1639  UInt32 i; 
     1640  for (i = 0; i < kAlignTableSize; i++) 
     1641    p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); 
     1642  p->alignPriceCount = 0; 
     1643} 
     1644 
     1645static void FillDistancesPrices(CLzmaEnc *p) 
     1646{ 
     1647  UInt32 tempPrices[kNumFullDistances]; 
     1648  UInt32 i, lenToPosState; 
     1649  for (i = kStartPosModelIndex; i < kNumFullDistances; i++) 
     1650  { 
     1651    UInt32 posSlot = GetPosSlot1(i); 
     1652    UInt32 footerBits = ((posSlot >> 1) - 1); 
     1653    UInt32 base = ((2 | (posSlot & 1)) << footerBits); 
     1654    tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); 
     1655  } 
     1656 
     1657  for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) 
     1658  { 
     1659    UInt32 posSlot; 
     1660    const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; 
     1661    UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; 
     1662    for (posSlot = 0; posSlot < p->distTableSize; posSlot++) 
     1663      posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); 
     1664    for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) 
     1665      posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); 
     1666 
     1667    { 
     1668      UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; 
     1669      UInt32 i; 
     1670      for (i = 0; i < kStartPosModelIndex; i++) 
     1671        distancesPrices[i] = posSlotPrices[i]; 
     1672      for (; i < kNumFullDistances; i++) 
     1673        distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; 
     1674    } 
     1675  } 
     1676  p->matchPriceCount = 0; 
     1677} 
     1678 
     1679void LzmaEnc_Construct(CLzmaEnc *p) 
     1680{ 
     1681  RangeEnc_Construct(&p->rc); 
     1682  MatchFinder_Construct(&p->matchFinderBase); 
     1683  #ifndef _7ZIP_ST 
     1684  MatchFinderMt_Construct(&p->matchFinderMt); 
     1685  p->matchFinderMt.MatchFinder = &p->matchFinderBase; 
     1686  #endif 
     1687 
     1688  { 
     1689    CLzmaEncProps props; 
     1690    LzmaEncProps_Init(&props); 
     1691    LzmaEnc_SetProps(p, &props); 
     1692  } 
     1693 
     1694  #ifndef LZMA_LOG_BSR 
     1695  LzmaEnc_FastPosInit(p->g_FastPos); 
     1696  #endif 
     1697 
     1698  LzmaEnc_InitPriceTables(p->ProbPrices); 
     1699  p->litProbs = 0; 
     1700  p->saveState.litProbs = 0; 
     1701} 
     1702 
     1703CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) 
     1704{ 
     1705  void *p; 
     1706  p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); 
     1707  if (p != 0) 
     1708    LzmaEnc_Construct((CLzmaEnc *)p); 
     1709  return p; 
     1710} 
     1711 
     1712void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) 
     1713{ 
     1714  alloc->Free(alloc, p->litProbs); 
     1715  alloc->Free(alloc, p->saveState.litProbs); 
     1716  p->litProbs = 0; 
     1717  p->saveState.litProbs = 0; 
     1718} 
     1719 
     1720void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) 
     1721{ 
     1722  #ifndef _7ZIP_ST 
     1723  MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); 
     1724  #endif 
     1725  MatchFinder_Free(&p->matchFinderBase, allocBig); 
     1726  LzmaEnc_FreeLits(p, alloc); 
     1727  RangeEnc_Free(&p->rc, alloc); 
     1728} 
     1729 
     1730void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) 
     1731{ 
     1732  LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); 
     1733  alloc->Free(alloc, p); 
     1734} 
     1735 
     1736static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) 
     1737{ 
     1738  UInt32 nowPos32, startPos32; 
     1739  if (p->needInit) 
     1740  { 
     1741    p->matchFinder.Init(p->matchFinderObj); 
     1742    p->needInit = 0; 
     1743  } 
     1744 
     1745  if (p->finished) 
     1746    return p->result; 
     1747  RINOK(CheckErrors(p)); 
     1748 
     1749  nowPos32 = (UInt32)p->nowPos64; 
     1750  startPos32 = nowPos32; 
     1751 
     1752  if (p->nowPos64 == 0) 
     1753  { 
     1754    UInt32 numPairs; 
     1755    Byte curByte; 
     1756    if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) 
     1757      return Flush(p, nowPos32); 
     1758    ReadMatchDistances(p, &numPairs); 
     1759    RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); 
     1760    p->state = kLiteralNextStates[p->state]; 
     1761    curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); 
     1762    LitEnc_Encode(&p->rc, p->litProbs, curByte); 
     1763    p->additionalOffset--; 
     1764    nowPos32++; 
     1765  } 
     1766 
     1767  if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) 
     1768  for (;;) 
     1769  { 
     1770    UInt32 pos, len, posState; 
     1771 
     1772    if (p->fastMode) 
     1773      len = GetOptimumFast(p, &pos); 
     1774    else 
     1775      len = GetOptimum(p, nowPos32, &pos); 
     1776 
     1777    #ifdef SHOW_STAT2 
     1778    printf("\n pos = %4X,   len = %d   pos = %d", nowPos32, len, pos); 
     1779    #endif 
     1780 
     1781    posState = nowPos32 & p->pbMask; 
     1782    if (len == 1 && pos == (UInt32)-1) 
     1783    { 
     1784      Byte curByte; 
     1785      CLzmaProb *probs; 
     1786      const Byte *data; 
     1787 
     1788      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); 
     1789      data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; 
     1790      curByte = *data; 
     1791      probs = LIT_PROBS(nowPos32, *(data - 1)); 
     1792      if (IsCharState(p->state)) 
     1793        LitEnc_Encode(&p->rc, probs, curByte); 
     1794      else 
     1795        LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); 
     1796      p->state = kLiteralNextStates[p->state]; 
     1797    } 
     1798    else 
     1799    { 
     1800      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); 
     1801      if (pos < LZMA_NUM_REPS) 
     1802      { 
     1803        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); 
     1804        if (pos == 0) 
     1805        { 
     1806          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); 
     1807          RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); 
     1808        } 
     1809        else 
     1810        { 
     1811          UInt32 distance = p->reps[pos]; 
     1812          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); 
     1813          if (pos == 1) 
     1814            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); 
     1815          else 
     1816          { 
     1817            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); 
     1818            RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); 
     1819            if (pos == 3) 
     1820              p->reps[3] = p->reps[2]; 
     1821            p->reps[2] = p->reps[1]; 
     1822          } 
     1823          p->reps[1] = p->reps[0]; 
     1824          p->reps[0] = distance; 
     1825        } 
     1826        if (len == 1) 
     1827          p->state = kShortRepNextStates[p->state]; 
     1828        else 
     1829        { 
     1830          LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); 
     1831          p->state = kRepNextStates[p->state]; 
     1832        } 
     1833      } 
     1834      else 
     1835      { 
     1836        UInt32 posSlot; 
     1837        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); 
     1838        p->state = kMatchNextStates[p->state]; 
     1839        LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); 
     1840        pos -= LZMA_NUM_REPS; 
     1841        GetPosSlot(pos, posSlot); 
     1842        RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); 
     1843         
     1844        if (posSlot >= kStartPosModelIndex) 
     1845        { 
     1846          UInt32 footerBits = ((posSlot >> 1) - 1); 
     1847          UInt32 base = ((2 | (posSlot & 1)) << footerBits); 
     1848          UInt32 posReduced = pos - base; 
     1849 
     1850          if (posSlot < kEndPosModelIndex) 
     1851            RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); 
     1852          else 
     1853          { 
     1854            RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); 
     1855            RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); 
     1856            p->alignPriceCount++; 
     1857          } 
     1858        } 
     1859        p->reps[3] = p->reps[2]; 
     1860        p->reps[2] = p->reps[1]; 
     1861        p->reps[1] = p->reps[0]; 
     1862        p->reps[0] = pos; 
     1863        p->matchPriceCount++; 
     1864      } 
     1865    } 
     1866    p->additionalOffset -= len; 
     1867    nowPos32 += len; 
     1868    if (p->additionalOffset == 0) 
     1869    { 
     1870      UInt32 processed; 
     1871      if (!p->fastMode) 
     1872      { 
     1873        if (p->matchPriceCount >= (1 << 7)) 
     1874          FillDistancesPrices(p); 
     1875        if (p->alignPriceCount >= kAlignTableSize) 
     1876          FillAlignPrices(p); 
     1877      } 
     1878      if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) 
     1879        break; 
     1880      processed = nowPos32 - startPos32; 
     1881      if (useLimits) 
     1882      { 
     1883        if (processed + kNumOpts + 300 >= maxUnpackSize || 
     1884            RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) 
     1885          break; 
     1886      } 
     1887      else if (processed >= (1 << 15)) 
     1888      { 
     1889        p->nowPos64 += nowPos32 - startPos32; 
     1890        return CheckErrors(p); 
     1891      } 
     1892    } 
     1893  } 
     1894  p->nowPos64 += nowPos32 - startPos32; 
     1895  return Flush(p, nowPos32); 
     1896} 
     1897 
     1898#define kBigHashDicLimit ((UInt32)1 << 24) 
     1899 
     1900static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) 
     1901{ 
     1902  UInt32 beforeSize = kNumOpts; 
     1903  Bool btMode; 
     1904  if (!RangeEnc_Alloc(&p->rc, alloc)) 
     1905    return SZ_ERROR_MEM; 
     1906  btMode = (p->matchFinderBase.btMode != 0); 
     1907  #ifndef _7ZIP_ST 
     1908  p->mtMode = (p->multiThread && !p->fastMode && btMode); 
     1909  #endif 
     1910 
     1911  { 
     1912    unsigned lclp = p->lc + p->lp; 
     1913    if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) 
     1914    { 
     1915      LzmaEnc_FreeLits(p, alloc); 
     1916      p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); 
     1917      p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); 
     1918      if (p->litProbs == 0 || p->saveState.litProbs == 0) 
     1919      { 
     1920        LzmaEnc_FreeLits(p, alloc); 
     1921        return SZ_ERROR_MEM; 
     1922      } 
     1923      p->lclp = lclp; 
     1924    } 
     1925  } 
     1926 
     1927  p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); 
     1928 
     1929  if (beforeSize + p->dictSize < keepWindowSize) 
     1930    beforeSize = keepWindowSize - p->dictSize; 
     1931 
     1932  #ifndef _7ZIP_ST 
     1933  if (p->mtMode) 
     1934  { 
     1935    RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); 
     1936    p->matchFinderObj = &p->matchFinderMt; 
     1937    MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); 
     1938  } 
     1939  else 
     1940  #endif 
     1941  { 
     1942    if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) 
     1943      return SZ_ERROR_MEM; 
     1944    p->matchFinderObj = &p->matchFinderBase; 
     1945    MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); 
     1946  } 
     1947  return SZ_OK; 
     1948} 
     1949 
     1950void LzmaEnc_Init(CLzmaEnc *p) 
     1951{ 
     1952  UInt32 i; 
     1953  p->state = 0; 
     1954  for (i = 0 ; i < LZMA_NUM_REPS; i++) 
     1955    p->reps[i] = 0; 
     1956 
     1957  RangeEnc_Init(&p->rc); 
     1958 
     1959 
     1960  for (i = 0; i < kNumStates; i++) 
     1961  { 
     1962    UInt32 j; 
     1963    for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) 
     1964    { 
     1965      p->isMatch[i][j] = kProbInitValue; 
     1966      p->isRep0Long[i][j] = kProbInitValue; 
     1967    } 
     1968    p->isRep[i] = kProbInitValue; 
     1969    p->isRepG0[i] = kProbInitValue; 
     1970    p->isRepG1[i] = kProbInitValue; 
     1971    p->isRepG2[i] = kProbInitValue; 
     1972  } 
     1973 
     1974  { 
     1975    UInt32 num = 0x300 << (p->lp + p->lc); 
     1976    for (i = 0; i < num; i++) 
     1977      p->litProbs[i] = kProbInitValue; 
     1978  } 
     1979 
     1980  { 
     1981    for (i = 0; i < kNumLenToPosStates; i++) 
     1982    { 
     1983      CLzmaProb *probs = p->posSlotEncoder[i]; 
     1984      UInt32 j; 
     1985      for (j = 0; j < (1 << kNumPosSlotBits); j++) 
     1986        probs[j] = kProbInitValue; 
     1987    } 
     1988  } 
     1989  { 
     1990    for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) 
     1991      p->posEncoders[i] = kProbInitValue; 
     1992  } 
     1993 
     1994  LenEnc_Init(&p->lenEnc.p); 
     1995  LenEnc_Init(&p->repLenEnc.p); 
     1996 
     1997  for (i = 0; i < (1 << kNumAlignBits); i++) 
     1998    p->posAlignEncoder[i] = kProbInitValue; 
     1999 
     2000  p->optimumEndIndex = 0; 
     2001  p->optimumCurrentIndex = 0; 
     2002  p->additionalOffset = 0; 
     2003 
     2004  p->pbMask = (1 << p->pb) - 1; 
     2005  p->lpMask = (1 << p->lp) - 1; 
     2006} 
     2007 
     2008void LzmaEnc_InitPrices(CLzmaEnc *p) 
     2009{ 
     2010  if (!p->fastMode) 
     2011  { 
     2012    FillDistancesPrices(p); 
     2013    FillAlignPrices(p); 
     2014  } 
     2015 
     2016  p->lenEnc.tableSize = 
     2017  p->repLenEnc.tableSize = 
     2018      p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; 
     2019  LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); 
     2020  LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); 
     2021} 
     2022 
     2023static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) 
     2024{ 
     2025  UInt32 i; 
     2026  for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) 
     2027    if (p->dictSize <= ((UInt32)1 << i)) 
     2028      break; 
     2029  p->distTableSize = i * 2; 
     2030 
     2031  p->finished = False; 
     2032  p->result = SZ_OK; 
     2033  RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); 
     2034  LzmaEnc_Init(p); 
     2035  LzmaEnc_InitPrices(p); 
     2036  p->nowPos64 = 0; 
     2037  return SZ_OK; 
     2038} 
     2039 
     2040static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, 
     2041    ISzAlloc *alloc, ISzAlloc *allocBig) 
     2042{ 
     2043  CLzmaEnc *p = (CLzmaEnc *)pp; 
     2044  p->matchFinderBase.stream = inStream; 
     2045  p->needInit = 1; 
     2046  p->rc.outStream = outStream; 
     2047  return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); 
     2048} 
     2049 
     2050SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, 
     2051    ISeqInStream *inStream, UInt32 keepWindowSize, 
     2052    ISzAlloc *alloc, ISzAlloc *allocBig) 
     2053{ 
     2054  CLzmaEnc *p = (CLzmaEnc *)pp; 
     2055  p->matchFinderBase.stream = inStream; 
     2056  p->needInit = 1; 
     2057  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); 
     2058} 
     2059 
     2060static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) 
     2061{ 
     2062  p->matchFinderBase.directInput = 1; 
     2063  p->matchFinderBase.bufferBase = (Byte *)src; 
     2064  p->matchFinderBase.directInputRem = srcLen; 
     2065} 
     2066 
     2067SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, 
     2068    UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) 
     2069{ 
     2070  CLzmaEnc *p = (CLzmaEnc *)pp; 
     2071  LzmaEnc_SetInputBuf(p, src, srcLen); 
     2072  p->needInit = 1; 
     2073 
     2074  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); 
     2075} 
     2076 
     2077void LzmaEnc_Finish(CLzmaEncHandle pp) 
     2078{ 
     2079  #ifndef _7ZIP_ST 
     2080  CLzmaEnc *p = (CLzmaEnc *)pp; 
     2081  if (p->mtMode) 
     2082    MatchFinderMt_ReleaseStream(&p->matchFinderMt); 
     2083  #else 
     2084  pp = pp; 
     2085  #endif 
     2086} 
     2087 
     2088typedef struct 
     2089{ 
     2090  ISeqOutStream funcTable; 
     2091  Byte *data; 
     2092  SizeT rem; 
     2093  Bool overflow; 
     2094} CSeqOutStreamBuf; 
     2095 
     2096static size_t MyWrite(void *pp, const void *data, size_t size) 
     2097{ 
     2098  CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; 
     2099  if (p->rem < size) 
     2100  { 
     2101    size = p->rem; 
     2102    p->overflow = True; 
     2103  } 
     2104  memcpy(p->data, data, size); 
     2105  p->rem -= size; 
     2106  p->data += size; 
     2107  return size; 
     2108} 
     2109 
     2110 
     2111UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) 
     2112{ 
     2113  const CLzmaEnc *p = (CLzmaEnc *)pp; 
     2114  return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); 
     2115} 
     2116 
     2117const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) 
     2118{ 
     2119  const CLzmaEnc *p = (CLzmaEnc *)pp; 
     2120  return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; 
     2121} 
     2122 
     2123SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, 
     2124    Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) 
     2125{ 
     2126  CLzmaEnc *p = (CLzmaEnc *)pp; 
     2127  UInt64 nowPos64; 
     2128  SRes res; 
     2129  CSeqOutStreamBuf outStream; 
     2130 
     2131  outStream.funcTable.Write = MyWrite; 
     2132  outStream.data = dest; 
     2133  outStream.rem = *destLen; 
     2134  outStream.overflow = False; 
     2135 
     2136  p->writeEndMark = False; 
     2137  p->finished = False; 
     2138  p->result = SZ_OK; 
     2139 
     2140  if (reInit) 
     2141    LzmaEnc_Init(p); 
     2142  LzmaEnc_InitPrices(p); 
     2143  nowPos64 = p->nowPos64; 
     2144  RangeEnc_Init(&p->rc); 
     2145  p->rc.outStream = &outStream.funcTable; 
     2146 
     2147  res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); 
     2148   
     2149  *unpackSize = (UInt32)(p->nowPos64 - nowPos64); 
     2150  *destLen -= outStream.rem; 
     2151  if (outStream.overflow) 
     2152    return SZ_ERROR_OUTPUT_EOF; 
     2153 
     2154  return res; 
     2155} 
     2156 
     2157static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) 
     2158{ 
     2159  SRes res = SZ_OK; 
     2160 
     2161  #ifndef _7ZIP_ST 
     2162  Byte allocaDummy[0x300]; 
     2163  int i = 0; 
     2164  for (i = 0; i < 16; i++) 
     2165    allocaDummy[i] = (Byte)i; 
     2166  #endif 
     2167 
     2168  for (;;) 
     2169  { 
     2170    res = LzmaEnc_CodeOneBlock(p, False, 0, 0); 
     2171    if (res != SZ_OK || p->finished != 0) 
     2172      break; 
     2173    if (progress != 0) 
     2174    { 
     2175      res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); 
     2176      if (res != SZ_OK) 
     2177      { 
     2178        res = SZ_ERROR_PROGRESS; 
     2179        break; 
     2180      } 
     2181    } 
     2182  } 
     2183  LzmaEnc_Finish(p); 
     2184  return res; 
     2185} 
     2186 
     2187SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, 
     2188    ISzAlloc *alloc, ISzAlloc *allocBig) 
     2189{ 
     2190  RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig)); 
     2191  return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); 
     2192} 
     2193 
     2194SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) 
     2195{ 
     2196  CLzmaEnc *p = (CLzmaEnc *)pp; 
     2197  int i; 
     2198  UInt32 dictSize = p->dictSize; 
     2199  if (*size < LZMA_PROPS_SIZE) 
     2200    return SZ_ERROR_PARAM; 
     2201  *size = LZMA_PROPS_SIZE; 
     2202  props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); 
     2203 
     2204  for (i = 11; i <= 30; i++) 
     2205  { 
     2206    if (dictSize <= ((UInt32)2 << i)) 
     2207    { 
     2208      dictSize = (2 << i); 
     2209      break; 
     2210    } 
     2211    if (dictSize <= ((UInt32)3 << i)) 
     2212    { 
     2213      dictSize = (3 << i); 
     2214      break; 
     2215    } 
     2216  } 
     2217 
     2218  for (i = 0; i < 4; i++) 
     2219    props[1 + i] = (Byte)(dictSize >> (8 * i)); 
     2220  return SZ_OK; 
     2221} 
     2222 
     2223SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, 
     2224    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) 
     2225{ 
     2226  SRes res; 
     2227  CLzmaEnc *p = (CLzmaEnc *)pp; 
     2228 
     2229  CSeqOutStreamBuf outStream; 
     2230 
     2231  LzmaEnc_SetInputBuf(p, src, srcLen); 
     2232 
     2233  outStream.funcTable.Write = MyWrite; 
     2234  outStream.data = dest; 
     2235  outStream.rem = *destLen; 
     2236  outStream.overflow = False; 
     2237 
     2238  p->writeEndMark = writeEndMark; 
     2239 
     2240  p->rc.outStream = &outStream.funcTable; 
     2241  res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); 
     2242  if (res == SZ_OK) 
     2243    res = LzmaEnc_Encode2(p, progress); 
     2244 
     2245  *destLen -= outStream.rem; 
     2246  if (outStream.overflow) 
     2247    return SZ_ERROR_OUTPUT_EOF; 
     2248  return res; 
     2249} 
     2250 
     2251SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, 
     2252    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, 
     2253    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) 
     2254{ 
     2255  CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); 
     2256  SRes res; 
     2257  if (p == 0) 
     2258    return SZ_ERROR_MEM; 
     2259 
     2260  res = LzmaEnc_SetProps(p, props); 
     2261  if (res == SZ_OK) 
     2262  { 
     2263    res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); 
     2264    if (res == SZ_OK) 
     2265      res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, 
     2266          writeEndMark, progress, alloc, allocBig); 
     2267  } 
     2268 
     2269  LzmaEnc_Destroy(p, alloc, allocBig); 
     2270  return res; 
     2271} 
  • new file lib/lzma/Makefile

    - +  
     1lzma_compress-objs := LzFind.o LzmaEnc.o 
     2lzma_decompress-objs := LzmaDec.o 
     3 
     4obj-$(CONFIG_LZMA_COMPRESS) += lzma_compress.o 
     5obj-$(CONFIG_LZMA_DECOMPRESS) += lzma_decompress.o 
     6 
     7EXTRA_CFLAGS += -Iinclude/linux -Iinclude/linux/lzma -include types.h 
Note: See TracBrowser for help on using the repository browser.