10d2711a69397d2971079121df4326d84736c181elgao/** @file 20d2711a69397d2971079121df4326d84736c181elgao Based on LZMA SDK 4.65: 30d2711a69397d2971079121df4326d84736c181elgao LzmaEnc.c -- LZMA Encoder 40d2711a69397d2971079121df4326d84736c181elgao 2009-02-02 : Igor Pavlov : Public domain 50d2711a69397d2971079121df4326d84736c181elgao 60d2711a69397d2971079121df4326d84736c181elgao Copyright (c) 2011, Intel Corporation. All rights reserved.<BR> 70d2711a69397d2971079121df4326d84736c181elgao This program and the accompanying materials 80d2711a69397d2971079121df4326d84736c181elgao are licensed and made available under the terms and conditions of the BSD License 90d2711a69397d2971079121df4326d84736c181elgao which accompanies this distribution. The full text of the license may be found at 100d2711a69397d2971079121df4326d84736c181elgao http://opensource.org/licenses/bsd-license.php 110d2711a69397d2971079121df4326d84736c181elgao 120d2711a69397d2971079121df4326d84736c181elgao THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 130d2711a69397d2971079121df4326d84736c181elgao WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 140d2711a69397d2971079121df4326d84736c181elgao 150d2711a69397d2971079121df4326d84736c181elgao**/ 1630fdf1140b8d1ce93f3821d986fa165552023440lgao 1730fdf1140b8d1ce93f3821d986fa165552023440lgao#include <string.h> 1830fdf1140b8d1ce93f3821d986fa165552023440lgao 1930fdf1140b8d1ce93f3821d986fa165552023440lgao/* #define SHOW_STAT */ 2030fdf1140b8d1ce93f3821d986fa165552023440lgao/* #define SHOW_STAT2 */ 2130fdf1140b8d1ce93f3821d986fa165552023440lgao 2230fdf1140b8d1ce93f3821d986fa165552023440lgao#if defined(SHOW_STAT) || defined(SHOW_STAT2) 2330fdf1140b8d1ce93f3821d986fa165552023440lgao#include <stdio.h> 2430fdf1140b8d1ce93f3821d986fa165552023440lgao#endif 2530fdf1140b8d1ce93f3821d986fa165552023440lgao 2630fdf1140b8d1ce93f3821d986fa165552023440lgao#include "LzmaEnc.h" 2730fdf1140b8d1ce93f3821d986fa165552023440lgao 2830fdf1140b8d1ce93f3821d986fa165552023440lgao#include "LzFind.h" 2930fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef COMPRESS_MF_MT 3030fdf1140b8d1ce93f3821d986fa165552023440lgao#include "LzFindMt.h" 3130fdf1140b8d1ce93f3821d986fa165552023440lgao#endif 3230fdf1140b8d1ce93f3821d986fa165552023440lgao 3330fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef SHOW_STAT 3430fdf1140b8d1ce93f3821d986fa165552023440lgaostatic int ttt = 0; 3530fdf1140b8d1ce93f3821d986fa165552023440lgao#endif 3630fdf1140b8d1ce93f3821d986fa165552023440lgao 3730fdf1140b8d1ce93f3821d986fa165552023440lgao#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) 3830fdf1140b8d1ce93f3821d986fa165552023440lgao 3930fdf1140b8d1ce93f3821d986fa165552023440lgao#define kBlockSize (9 << 10) 4030fdf1140b8d1ce93f3821d986fa165552023440lgao#define kUnpackBlockSize (1 << 18) 4130fdf1140b8d1ce93f3821d986fa165552023440lgao#define kMatchArraySize (1 << 21) 4230fdf1140b8d1ce93f3821d986fa165552023440lgao#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) 4330fdf1140b8d1ce93f3821d986fa165552023440lgao 4430fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumMaxDirectBits (31) 4530fdf1140b8d1ce93f3821d986fa165552023440lgao 4630fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumTopBits 24 4730fdf1140b8d1ce93f3821d986fa165552023440lgao#define kTopValue ((UInt32)1 << kNumTopBits) 4830fdf1140b8d1ce93f3821d986fa165552023440lgao 4930fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumBitModelTotalBits 11 5030fdf1140b8d1ce93f3821d986fa165552023440lgao#define kBitModelTotal (1 << kNumBitModelTotalBits) 5130fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumMoveBits 5 5230fdf1140b8d1ce93f3821d986fa165552023440lgao#define kProbInitValue (kBitModelTotal >> 1) 5330fdf1140b8d1ce93f3821d986fa165552023440lgao 5430fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumMoveReducingBits 4 5530fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumBitPriceShiftBits 4 5630fdf1140b8d1ce93f3821d986fa165552023440lgao#define kBitPrice (1 << kNumBitPriceShiftBits) 5730fdf1140b8d1ce93f3821d986fa165552023440lgao 5830fdf1140b8d1ce93f3821d986fa165552023440lgaovoid LzmaEncProps_Init(CLzmaEncProps *p) 5930fdf1140b8d1ce93f3821d986fa165552023440lgao{ 6030fdf1140b8d1ce93f3821d986fa165552023440lgao p->level = 5; 6130fdf1140b8d1ce93f3821d986fa165552023440lgao p->dictSize = p->mc = 0; 6230fdf1140b8d1ce93f3821d986fa165552023440lgao p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; 6330fdf1140b8d1ce93f3821d986fa165552023440lgao p->writeEndMark = 0; 6430fdf1140b8d1ce93f3821d986fa165552023440lgao} 6530fdf1140b8d1ce93f3821d986fa165552023440lgao 6630fdf1140b8d1ce93f3821d986fa165552023440lgaovoid LzmaEncProps_Normalize(CLzmaEncProps *p) 6730fdf1140b8d1ce93f3821d986fa165552023440lgao{ 6830fdf1140b8d1ce93f3821d986fa165552023440lgao int level = p->level; 6930fdf1140b8d1ce93f3821d986fa165552023440lgao if (level < 0) level = 5; 7030fdf1140b8d1ce93f3821d986fa165552023440lgao p->level = level; 7130fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); 7230fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->lc < 0) p->lc = 3; 7330fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->lp < 0) p->lp = 0; 7430fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->pb < 0) p->pb = 2; 7530fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); 7630fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); 7730fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); 7830fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->numHashBytes < 0) p->numHashBytes = 4; 7930fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); 8030fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->numThreads < 0) 8130fdf1140b8d1ce93f3821d986fa165552023440lgao p->numThreads = 8230fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef COMPRESS_MF_MT 8330fdf1140b8d1ce93f3821d986fa165552023440lgao ((p->btMode && p->algo) ? 2 : 1); 8430fdf1140b8d1ce93f3821d986fa165552023440lgao #else 8530fdf1140b8d1ce93f3821d986fa165552023440lgao 1; 8630fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 8730fdf1140b8d1ce93f3821d986fa165552023440lgao} 8830fdf1140b8d1ce93f3821d986fa165552023440lgao 8930fdf1140b8d1ce93f3821d986fa165552023440lgaoUInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) 9030fdf1140b8d1ce93f3821d986fa165552023440lgao{ 9130fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEncProps props = *props2; 9230fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEncProps_Normalize(&props); 9330fdf1140b8d1ce93f3821d986fa165552023440lgao return props.dictSize; 9430fdf1140b8d1ce93f3821d986fa165552023440lgao} 9530fdf1140b8d1ce93f3821d986fa165552023440lgao 9630fdf1140b8d1ce93f3821d986fa165552023440lgao/* #define LZMA_LOG_BSR */ 9730fdf1140b8d1ce93f3821d986fa165552023440lgao/* Define it for Intel's CPU */ 9830fdf1140b8d1ce93f3821d986fa165552023440lgao 9930fdf1140b8d1ce93f3821d986fa165552023440lgao 10030fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef LZMA_LOG_BSR 10130fdf1140b8d1ce93f3821d986fa165552023440lgao 10230fdf1140b8d1ce93f3821d986fa165552023440lgao#define kDicLogSizeMaxCompress 30 10330fdf1140b8d1ce93f3821d986fa165552023440lgao 10430fdf1140b8d1ce93f3821d986fa165552023440lgao#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } 10530fdf1140b8d1ce93f3821d986fa165552023440lgao 10630fdf1140b8d1ce93f3821d986fa165552023440lgaoUInt32 GetPosSlot1(UInt32 pos) 10730fdf1140b8d1ce93f3821d986fa165552023440lgao{ 10830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 res; 10930fdf1140b8d1ce93f3821d986fa165552023440lgao BSR2_RET(pos, res); 11030fdf1140b8d1ce93f3821d986fa165552023440lgao return res; 11130fdf1140b8d1ce93f3821d986fa165552023440lgao} 11230fdf1140b8d1ce93f3821d986fa165552023440lgao#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } 11330fdf1140b8d1ce93f3821d986fa165552023440lgao#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } 11430fdf1140b8d1ce93f3821d986fa165552023440lgao 11530fdf1140b8d1ce93f3821d986fa165552023440lgao#else 11630fdf1140b8d1ce93f3821d986fa165552023440lgao 11730fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumLogBits (9 + (int)sizeof(size_t) / 2) 11830fdf1140b8d1ce93f3821d986fa165552023440lgao#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) 11930fdf1140b8d1ce93f3821d986fa165552023440lgao 12030fdf1140b8d1ce93f3821d986fa165552023440lgaovoid LzmaEnc_FastPosInit(Byte *g_FastPos) 12130fdf1140b8d1ce93f3821d986fa165552023440lgao{ 12230fdf1140b8d1ce93f3821d986fa165552023440lgao int c = 2, slotFast; 12330fdf1140b8d1ce93f3821d986fa165552023440lgao g_FastPos[0] = 0; 12430fdf1140b8d1ce93f3821d986fa165552023440lgao g_FastPos[1] = 1; 12530fdf1140b8d1ce93f3821d986fa165552023440lgao 12630fdf1140b8d1ce93f3821d986fa165552023440lgao for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) 12730fdf1140b8d1ce93f3821d986fa165552023440lgao { 12830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 k = (1 << ((slotFast >> 1) - 1)); 12930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 j; 13030fdf1140b8d1ce93f3821d986fa165552023440lgao for (j = 0; j < k; j++, c++) 13130fdf1140b8d1ce93f3821d986fa165552023440lgao g_FastPos[c] = (Byte)slotFast; 13230fdf1140b8d1ce93f3821d986fa165552023440lgao } 13330fdf1140b8d1ce93f3821d986fa165552023440lgao} 13430fdf1140b8d1ce93f3821d986fa165552023440lgao 13530fdf1140b8d1ce93f3821d986fa165552023440lgao#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ 13630fdf1140b8d1ce93f3821d986fa165552023440lgao (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ 13730fdf1140b8d1ce93f3821d986fa165552023440lgao res = p->g_FastPos[pos >> i] + (i * 2); } 13830fdf1140b8d1ce93f3821d986fa165552023440lgao/* 13930fdf1140b8d1ce93f3821d986fa165552023440lgao#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ 14030fdf1140b8d1ce93f3821d986fa165552023440lgao p->g_FastPos[pos >> 6] + 12 : \ 14130fdf1140b8d1ce93f3821d986fa165552023440lgao p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } 14230fdf1140b8d1ce93f3821d986fa165552023440lgao*/ 14330fdf1140b8d1ce93f3821d986fa165552023440lgao 14430fdf1140b8d1ce93f3821d986fa165552023440lgao#define GetPosSlot1(pos) p->g_FastPos[pos] 14530fdf1140b8d1ce93f3821d986fa165552023440lgao#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } 14630fdf1140b8d1ce93f3821d986fa165552023440lgao#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } 14730fdf1140b8d1ce93f3821d986fa165552023440lgao 14830fdf1140b8d1ce93f3821d986fa165552023440lgao#endif 14930fdf1140b8d1ce93f3821d986fa165552023440lgao 15030fdf1140b8d1ce93f3821d986fa165552023440lgao 15130fdf1140b8d1ce93f3821d986fa165552023440lgao#define LZMA_NUM_REPS 4 15230fdf1140b8d1ce93f3821d986fa165552023440lgao 15330fdf1140b8d1ce93f3821d986fa165552023440lgaotypedef unsigned CState; 15430fdf1140b8d1ce93f3821d986fa165552023440lgao 15530fdf1140b8d1ce93f3821d986fa165552023440lgaotypedef struct _COptimal 15630fdf1140b8d1ce93f3821d986fa165552023440lgao{ 15730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 price; 15830fdf1140b8d1ce93f3821d986fa165552023440lgao 15930fdf1140b8d1ce93f3821d986fa165552023440lgao CState state; 16030fdf1140b8d1ce93f3821d986fa165552023440lgao int prev1IsChar; 16130fdf1140b8d1ce93f3821d986fa165552023440lgao int prev2; 16230fdf1140b8d1ce93f3821d986fa165552023440lgao 16330fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 posPrev2; 16430fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 backPrev2; 16530fdf1140b8d1ce93f3821d986fa165552023440lgao 16630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 posPrev; 16730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 backPrev; 16830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 backs[LZMA_NUM_REPS]; 16930fdf1140b8d1ce93f3821d986fa165552023440lgao} COptimal; 17030fdf1140b8d1ce93f3821d986fa165552023440lgao 17130fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumOpts (1 << 12) 17230fdf1140b8d1ce93f3821d986fa165552023440lgao 17330fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumLenToPosStates 4 17430fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumPosSlotBits 6 17530fdf1140b8d1ce93f3821d986fa165552023440lgao#define kDicLogSizeMin 0 17630fdf1140b8d1ce93f3821d986fa165552023440lgao#define kDicLogSizeMax 32 17730fdf1140b8d1ce93f3821d986fa165552023440lgao#define kDistTableSizeMax (kDicLogSizeMax * 2) 17830fdf1140b8d1ce93f3821d986fa165552023440lgao 17930fdf1140b8d1ce93f3821d986fa165552023440lgao 18030fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumAlignBits 4 18130fdf1140b8d1ce93f3821d986fa165552023440lgao#define kAlignTableSize (1 << kNumAlignBits) 18230fdf1140b8d1ce93f3821d986fa165552023440lgao#define kAlignMask (kAlignTableSize - 1) 18330fdf1140b8d1ce93f3821d986fa165552023440lgao 18430fdf1140b8d1ce93f3821d986fa165552023440lgao#define kStartPosModelIndex 4 18530fdf1140b8d1ce93f3821d986fa165552023440lgao#define kEndPosModelIndex 14 18630fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) 18730fdf1140b8d1ce93f3821d986fa165552023440lgao 18830fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumFullDistances (1 << (kEndPosModelIndex / 2)) 18930fdf1140b8d1ce93f3821d986fa165552023440lgao 19030fdf1140b8d1ce93f3821d986fa165552023440lgao#ifdef _LZMA_PROB32 19130fdf1140b8d1ce93f3821d986fa165552023440lgao#define CLzmaProb UInt32 19230fdf1140b8d1ce93f3821d986fa165552023440lgao#else 19330fdf1140b8d1ce93f3821d986fa165552023440lgao#define CLzmaProb UInt16 19430fdf1140b8d1ce93f3821d986fa165552023440lgao#endif 19530fdf1140b8d1ce93f3821d986fa165552023440lgao 19630fdf1140b8d1ce93f3821d986fa165552023440lgao#define LZMA_PB_MAX 4 19730fdf1140b8d1ce93f3821d986fa165552023440lgao#define LZMA_LC_MAX 8 19830fdf1140b8d1ce93f3821d986fa165552023440lgao#define LZMA_LP_MAX 4 19930fdf1140b8d1ce93f3821d986fa165552023440lgao 20030fdf1140b8d1ce93f3821d986fa165552023440lgao#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) 20130fdf1140b8d1ce93f3821d986fa165552023440lgao 20230fdf1140b8d1ce93f3821d986fa165552023440lgao 20330fdf1140b8d1ce93f3821d986fa165552023440lgao#define kLenNumLowBits 3 20430fdf1140b8d1ce93f3821d986fa165552023440lgao#define kLenNumLowSymbols (1 << kLenNumLowBits) 20530fdf1140b8d1ce93f3821d986fa165552023440lgao#define kLenNumMidBits 3 20630fdf1140b8d1ce93f3821d986fa165552023440lgao#define kLenNumMidSymbols (1 << kLenNumMidBits) 20730fdf1140b8d1ce93f3821d986fa165552023440lgao#define kLenNumHighBits 8 20830fdf1140b8d1ce93f3821d986fa165552023440lgao#define kLenNumHighSymbols (1 << kLenNumHighBits) 20930fdf1140b8d1ce93f3821d986fa165552023440lgao 21030fdf1140b8d1ce93f3821d986fa165552023440lgao#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) 21130fdf1140b8d1ce93f3821d986fa165552023440lgao 21230fdf1140b8d1ce93f3821d986fa165552023440lgao#define LZMA_MATCH_LEN_MIN 2 21330fdf1140b8d1ce93f3821d986fa165552023440lgao#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) 21430fdf1140b8d1ce93f3821d986fa165552023440lgao 21530fdf1140b8d1ce93f3821d986fa165552023440lgao#define kNumStates 12 21630fdf1140b8d1ce93f3821d986fa165552023440lgao 21730fdf1140b8d1ce93f3821d986fa165552023440lgaotypedef struct 21830fdf1140b8d1ce93f3821d986fa165552023440lgao{ 21930fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb choice; 22030fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb choice2; 22130fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; 22230fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; 22330fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb high[kLenNumHighSymbols]; 22430fdf1140b8d1ce93f3821d986fa165552023440lgao} CLenEnc; 22530fdf1140b8d1ce93f3821d986fa165552023440lgao 22630fdf1140b8d1ce93f3821d986fa165552023440lgaotypedef struct 22730fdf1140b8d1ce93f3821d986fa165552023440lgao{ 22830fdf1140b8d1ce93f3821d986fa165552023440lgao CLenEnc p; 22930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; 23030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 tableSize; 23130fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 counters[LZMA_NUM_PB_STATES_MAX]; 23230fdf1140b8d1ce93f3821d986fa165552023440lgao} CLenPriceEnc; 23330fdf1140b8d1ce93f3821d986fa165552023440lgao 23430fdf1140b8d1ce93f3821d986fa165552023440lgaotypedef struct _CRangeEnc 23530fdf1140b8d1ce93f3821d986fa165552023440lgao{ 23630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 range; 23730fdf1140b8d1ce93f3821d986fa165552023440lgao Byte cache; 23830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt64 low; 23930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt64 cacheSize; 24030fdf1140b8d1ce93f3821d986fa165552023440lgao Byte *buf; 24130fdf1140b8d1ce93f3821d986fa165552023440lgao Byte *bufLim; 24230fdf1140b8d1ce93f3821d986fa165552023440lgao Byte *bufBase; 24330fdf1140b8d1ce93f3821d986fa165552023440lgao ISeqOutStream *outStream; 24430fdf1140b8d1ce93f3821d986fa165552023440lgao UInt64 processed; 24530fdf1140b8d1ce93f3821d986fa165552023440lgao SRes res; 24630fdf1140b8d1ce93f3821d986fa165552023440lgao} CRangeEnc; 24730fdf1140b8d1ce93f3821d986fa165552023440lgao 24830fdf1140b8d1ce93f3821d986fa165552023440lgaotypedef struct _CSeqInStreamBuf 24930fdf1140b8d1ce93f3821d986fa165552023440lgao{ 25030fdf1140b8d1ce93f3821d986fa165552023440lgao ISeqInStream funcTable; 25130fdf1140b8d1ce93f3821d986fa165552023440lgao const Byte *data; 25230fdf1140b8d1ce93f3821d986fa165552023440lgao SizeT rem; 25330fdf1140b8d1ce93f3821d986fa165552023440lgao} CSeqInStreamBuf; 25430fdf1140b8d1ce93f3821d986fa165552023440lgao 25530fdf1140b8d1ce93f3821d986fa165552023440lgaostatic SRes MyRead(void *pp, void *data, size_t *size) 25630fdf1140b8d1ce93f3821d986fa165552023440lgao{ 25730fdf1140b8d1ce93f3821d986fa165552023440lgao size_t curSize = *size; 25830fdf1140b8d1ce93f3821d986fa165552023440lgao CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp; 25930fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->rem < curSize) 26030fdf1140b8d1ce93f3821d986fa165552023440lgao curSize = p->rem; 26130fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(data, p->data, curSize); 26230fdf1140b8d1ce93f3821d986fa165552023440lgao p->rem -= curSize; 26330fdf1140b8d1ce93f3821d986fa165552023440lgao p->data += curSize; 26430fdf1140b8d1ce93f3821d986fa165552023440lgao *size = curSize; 26530fdf1140b8d1ce93f3821d986fa165552023440lgao return SZ_OK; 26630fdf1140b8d1ce93f3821d986fa165552023440lgao} 26730fdf1140b8d1ce93f3821d986fa165552023440lgao 26830fdf1140b8d1ce93f3821d986fa165552023440lgaotypedef struct 26930fdf1140b8d1ce93f3821d986fa165552023440lgao{ 27030fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb *litProbs; 27130fdf1140b8d1ce93f3821d986fa165552023440lgao 27230fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; 27330fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb isRep[kNumStates]; 27430fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb isRepG0[kNumStates]; 27530fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb isRepG1[kNumStates]; 27630fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb isRepG2[kNumStates]; 27730fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; 27830fdf1140b8d1ce93f3821d986fa165552023440lgao 27930fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; 28030fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; 28130fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb posAlignEncoder[1 << kNumAlignBits]; 28230fdf1140b8d1ce93f3821d986fa165552023440lgao 28330fdf1140b8d1ce93f3821d986fa165552023440lgao CLenPriceEnc lenEnc; 28430fdf1140b8d1ce93f3821d986fa165552023440lgao CLenPriceEnc repLenEnc; 28530fdf1140b8d1ce93f3821d986fa165552023440lgao 28630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 reps[LZMA_NUM_REPS]; 28730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 state; 28830fdf1140b8d1ce93f3821d986fa165552023440lgao} CSaveState; 28930fdf1140b8d1ce93f3821d986fa165552023440lgao 29030fdf1140b8d1ce93f3821d986fa165552023440lgaotypedef struct _CLzmaEnc 29130fdf1140b8d1ce93f3821d986fa165552023440lgao{ 29230fdf1140b8d1ce93f3821d986fa165552023440lgao IMatchFinder matchFinder; 29330fdf1140b8d1ce93f3821d986fa165552023440lgao void *matchFinderObj; 29430fdf1140b8d1ce93f3821d986fa165552023440lgao 29530fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef COMPRESS_MF_MT 29630fdf1140b8d1ce93f3821d986fa165552023440lgao Bool mtMode; 29730fdf1140b8d1ce93f3821d986fa165552023440lgao CMatchFinderMt matchFinderMt; 29830fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 29930fdf1140b8d1ce93f3821d986fa165552023440lgao 30030fdf1140b8d1ce93f3821d986fa165552023440lgao CMatchFinder matchFinderBase; 30130fdf1140b8d1ce93f3821d986fa165552023440lgao 30230fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef COMPRESS_MF_MT 30330fdf1140b8d1ce93f3821d986fa165552023440lgao Byte pad[128]; 30430fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 30530fdf1140b8d1ce93f3821d986fa165552023440lgao 30630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 optimumEndIndex; 30730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 optimumCurrentIndex; 30830fdf1140b8d1ce93f3821d986fa165552023440lgao 30930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 longestMatchLength; 31030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 numPairs; 31130fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 numAvail; 31230fdf1140b8d1ce93f3821d986fa165552023440lgao COptimal opt[kNumOpts]; 31330fdf1140b8d1ce93f3821d986fa165552023440lgao 31430fdf1140b8d1ce93f3821d986fa165552023440lgao #ifndef LZMA_LOG_BSR 31530fdf1140b8d1ce93f3821d986fa165552023440lgao Byte g_FastPos[1 << kNumLogBits]; 31630fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 31730fdf1140b8d1ce93f3821d986fa165552023440lgao 31830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; 31930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; 32030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 numFastBytes; 32130fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 additionalOffset; 32230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 reps[LZMA_NUM_REPS]; 32330fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 state; 32430fdf1140b8d1ce93f3821d986fa165552023440lgao 32530fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; 32630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; 32730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 alignPrices[kAlignTableSize]; 32830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 alignPriceCount; 32930fdf1140b8d1ce93f3821d986fa165552023440lgao 33030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 distTableSize; 33130fdf1140b8d1ce93f3821d986fa165552023440lgao 33230fdf1140b8d1ce93f3821d986fa165552023440lgao unsigned lc, lp, pb; 33330fdf1140b8d1ce93f3821d986fa165552023440lgao unsigned lpMask, pbMask; 33430fdf1140b8d1ce93f3821d986fa165552023440lgao 33530fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb *litProbs; 33630fdf1140b8d1ce93f3821d986fa165552023440lgao 33730fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; 33830fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb isRep[kNumStates]; 33930fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb isRepG0[kNumStates]; 34030fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb isRepG1[kNumStates]; 34130fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb isRepG2[kNumStates]; 34230fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; 34330fdf1140b8d1ce93f3821d986fa165552023440lgao 34430fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; 34530fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; 34630fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb posAlignEncoder[1 << kNumAlignBits]; 34730fdf1140b8d1ce93f3821d986fa165552023440lgao 34830fdf1140b8d1ce93f3821d986fa165552023440lgao CLenPriceEnc lenEnc; 34930fdf1140b8d1ce93f3821d986fa165552023440lgao CLenPriceEnc repLenEnc; 35030fdf1140b8d1ce93f3821d986fa165552023440lgao 35130fdf1140b8d1ce93f3821d986fa165552023440lgao unsigned lclp; 35230fdf1140b8d1ce93f3821d986fa165552023440lgao 35330fdf1140b8d1ce93f3821d986fa165552023440lgao Bool fastMode; 35430fdf1140b8d1ce93f3821d986fa165552023440lgao 35530fdf1140b8d1ce93f3821d986fa165552023440lgao CRangeEnc rc; 35630fdf1140b8d1ce93f3821d986fa165552023440lgao 35730fdf1140b8d1ce93f3821d986fa165552023440lgao Bool writeEndMark; 35830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt64 nowPos64; 35930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 matchPriceCount; 36030fdf1140b8d1ce93f3821d986fa165552023440lgao Bool finished; 36130fdf1140b8d1ce93f3821d986fa165552023440lgao Bool multiThread; 36230fdf1140b8d1ce93f3821d986fa165552023440lgao 36330fdf1140b8d1ce93f3821d986fa165552023440lgao SRes result; 36430fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 dictSize; 36530fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 matchFinderCycles; 36630fdf1140b8d1ce93f3821d986fa165552023440lgao 36730fdf1140b8d1ce93f3821d986fa165552023440lgao ISeqInStream *inStream; 36830fdf1140b8d1ce93f3821d986fa165552023440lgao CSeqInStreamBuf seqBufInStream; 36930fdf1140b8d1ce93f3821d986fa165552023440lgao 37030fdf1140b8d1ce93f3821d986fa165552023440lgao CSaveState saveState; 37130fdf1140b8d1ce93f3821d986fa165552023440lgao} CLzmaEnc; 37230fdf1140b8d1ce93f3821d986fa165552023440lgao 37330fdf1140b8d1ce93f3821d986fa165552023440lgaovoid LzmaEnc_SaveState(CLzmaEncHandle pp) 37430fdf1140b8d1ce93f3821d986fa165552023440lgao{ 37530fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEnc *p = (CLzmaEnc *)pp; 37630fdf1140b8d1ce93f3821d986fa165552023440lgao CSaveState *dest = &p->saveState; 37730fdf1140b8d1ce93f3821d986fa165552023440lgao int i; 37830fdf1140b8d1ce93f3821d986fa165552023440lgao dest->lenEnc = p->lenEnc; 37930fdf1140b8d1ce93f3821d986fa165552023440lgao dest->repLenEnc = p->repLenEnc; 38030fdf1140b8d1ce93f3821d986fa165552023440lgao dest->state = p->state; 38130fdf1140b8d1ce93f3821d986fa165552023440lgao 38230fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < kNumStates; i++) 38330fdf1140b8d1ce93f3821d986fa165552023440lgao { 38430fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); 38530fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); 38630fdf1140b8d1ce93f3821d986fa165552023440lgao } 38730fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < kNumLenToPosStates; i++) 38830fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); 38930fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); 39030fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); 39130fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); 39230fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); 39330fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); 39430fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); 39530fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->reps, p->reps, sizeof(p->reps)); 39630fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); 39730fdf1140b8d1ce93f3821d986fa165552023440lgao} 39830fdf1140b8d1ce93f3821d986fa165552023440lgao 39930fdf1140b8d1ce93f3821d986fa165552023440lgaovoid LzmaEnc_RestoreState(CLzmaEncHandle pp) 40030fdf1140b8d1ce93f3821d986fa165552023440lgao{ 40130fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEnc *dest = (CLzmaEnc *)pp; 40230fdf1140b8d1ce93f3821d986fa165552023440lgao const CSaveState *p = &dest->saveState; 40330fdf1140b8d1ce93f3821d986fa165552023440lgao int i; 40430fdf1140b8d1ce93f3821d986fa165552023440lgao dest->lenEnc = p->lenEnc; 40530fdf1140b8d1ce93f3821d986fa165552023440lgao dest->repLenEnc = p->repLenEnc; 40630fdf1140b8d1ce93f3821d986fa165552023440lgao dest->state = p->state; 40730fdf1140b8d1ce93f3821d986fa165552023440lgao 40830fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < kNumStates; i++) 40930fdf1140b8d1ce93f3821d986fa165552023440lgao { 41030fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); 41130fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); 41230fdf1140b8d1ce93f3821d986fa165552023440lgao } 41330fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < kNumLenToPosStates; i++) 41430fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); 41530fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); 41630fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); 41730fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); 41830fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); 41930fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); 42030fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); 42130fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->reps, p->reps, sizeof(p->reps)); 42230fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); 42330fdf1140b8d1ce93f3821d986fa165552023440lgao} 42430fdf1140b8d1ce93f3821d986fa165552023440lgao 42530fdf1140b8d1ce93f3821d986fa165552023440lgaoSRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) 42630fdf1140b8d1ce93f3821d986fa165552023440lgao{ 42730fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEnc *p = (CLzmaEnc *)pp; 42830fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEncProps props = *props2; 42930fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEncProps_Normalize(&props); 43030fdf1140b8d1ce93f3821d986fa165552023440lgao 43130fdf1140b8d1ce93f3821d986fa165552023440lgao if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || 43230fdf1140b8d1ce93f3821d986fa165552023440lgao props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) 43330fdf1140b8d1ce93f3821d986fa165552023440lgao return SZ_ERROR_PARAM; 43430fdf1140b8d1ce93f3821d986fa165552023440lgao p->dictSize = props.dictSize; 43530fdf1140b8d1ce93f3821d986fa165552023440lgao p->matchFinderCycles = props.mc; 43630fdf1140b8d1ce93f3821d986fa165552023440lgao { 43730fdf1140b8d1ce93f3821d986fa165552023440lgao unsigned fb = props.fb; 43830fdf1140b8d1ce93f3821d986fa165552023440lgao if (fb < 5) 43930fdf1140b8d1ce93f3821d986fa165552023440lgao fb = 5; 44030fdf1140b8d1ce93f3821d986fa165552023440lgao if (fb > LZMA_MATCH_LEN_MAX) 44130fdf1140b8d1ce93f3821d986fa165552023440lgao fb = LZMA_MATCH_LEN_MAX; 44230fdf1140b8d1ce93f3821d986fa165552023440lgao p->numFastBytes = fb; 44330fdf1140b8d1ce93f3821d986fa165552023440lgao } 44430fdf1140b8d1ce93f3821d986fa165552023440lgao p->lc = props.lc; 44530fdf1140b8d1ce93f3821d986fa165552023440lgao p->lp = props.lp; 44630fdf1140b8d1ce93f3821d986fa165552023440lgao p->pb = props.pb; 44730fdf1140b8d1ce93f3821d986fa165552023440lgao p->fastMode = (props.algo == 0); 44830fdf1140b8d1ce93f3821d986fa165552023440lgao p->matchFinderBase.btMode = props.btMode; 44930fdf1140b8d1ce93f3821d986fa165552023440lgao { 45030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 numHashBytes = 4; 45130fdf1140b8d1ce93f3821d986fa165552023440lgao if (props.btMode) 45230fdf1140b8d1ce93f3821d986fa165552023440lgao { 45330fdf1140b8d1ce93f3821d986fa165552023440lgao if (props.numHashBytes < 2) 45430fdf1140b8d1ce93f3821d986fa165552023440lgao numHashBytes = 2; 45530fdf1140b8d1ce93f3821d986fa165552023440lgao else if (props.numHashBytes < 4) 45630fdf1140b8d1ce93f3821d986fa165552023440lgao numHashBytes = props.numHashBytes; 45730fdf1140b8d1ce93f3821d986fa165552023440lgao } 45830fdf1140b8d1ce93f3821d986fa165552023440lgao p->matchFinderBase.numHashBytes = numHashBytes; 45930fdf1140b8d1ce93f3821d986fa165552023440lgao } 46030fdf1140b8d1ce93f3821d986fa165552023440lgao 46130fdf1140b8d1ce93f3821d986fa165552023440lgao p->matchFinderBase.cutValue = props.mc; 46230fdf1140b8d1ce93f3821d986fa165552023440lgao 46330fdf1140b8d1ce93f3821d986fa165552023440lgao p->writeEndMark = props.writeEndMark; 46430fdf1140b8d1ce93f3821d986fa165552023440lgao 46530fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef COMPRESS_MF_MT 46630fdf1140b8d1ce93f3821d986fa165552023440lgao /* 46730fdf1140b8d1ce93f3821d986fa165552023440lgao if (newMultiThread != _multiThread) 46830fdf1140b8d1ce93f3821d986fa165552023440lgao { 46930fdf1140b8d1ce93f3821d986fa165552023440lgao ReleaseMatchFinder(); 47030fdf1140b8d1ce93f3821d986fa165552023440lgao _multiThread = newMultiThread; 47130fdf1140b8d1ce93f3821d986fa165552023440lgao } 47230fdf1140b8d1ce93f3821d986fa165552023440lgao */ 47330fdf1140b8d1ce93f3821d986fa165552023440lgao p->multiThread = (props.numThreads > 1); 47430fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 47530fdf1140b8d1ce93f3821d986fa165552023440lgao 47630fdf1140b8d1ce93f3821d986fa165552023440lgao return SZ_OK; 47730fdf1140b8d1ce93f3821d986fa165552023440lgao} 47830fdf1140b8d1ce93f3821d986fa165552023440lgao 47930fdf1140b8d1ce93f3821d986fa165552023440lgaostatic const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; 48030fdf1140b8d1ce93f3821d986fa165552023440lgaostatic const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; 48130fdf1140b8d1ce93f3821d986fa165552023440lgaostatic const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; 48230fdf1140b8d1ce93f3821d986fa165552023440lgaostatic const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; 48330fdf1140b8d1ce93f3821d986fa165552023440lgao 48430fdf1140b8d1ce93f3821d986fa165552023440lgao#define IsCharState(s) ((s) < 7) 48530fdf1140b8d1ce93f3821d986fa165552023440lgao 48630fdf1140b8d1ce93f3821d986fa165552023440lgao#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) 48730fdf1140b8d1ce93f3821d986fa165552023440lgao 48830fdf1140b8d1ce93f3821d986fa165552023440lgao#define kInfinityPrice (1 << 30) 48930fdf1140b8d1ce93f3821d986fa165552023440lgao 49030fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void RangeEnc_Construct(CRangeEnc *p) 49130fdf1140b8d1ce93f3821d986fa165552023440lgao{ 49230fdf1140b8d1ce93f3821d986fa165552023440lgao p->outStream = 0; 49330fdf1140b8d1ce93f3821d986fa165552023440lgao p->bufBase = 0; 49430fdf1140b8d1ce93f3821d986fa165552023440lgao} 49530fdf1140b8d1ce93f3821d986fa165552023440lgao 49630fdf1140b8d1ce93f3821d986fa165552023440lgao#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) 49730fdf1140b8d1ce93f3821d986fa165552023440lgao 49830fdf1140b8d1ce93f3821d986fa165552023440lgao#define RC_BUF_SIZE (1 << 16) 49930fdf1140b8d1ce93f3821d986fa165552023440lgaostatic int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) 50030fdf1140b8d1ce93f3821d986fa165552023440lgao{ 50130fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->bufBase == 0) 50230fdf1140b8d1ce93f3821d986fa165552023440lgao { 50330fdf1140b8d1ce93f3821d986fa165552023440lgao p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); 50430fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->bufBase == 0) 50530fdf1140b8d1ce93f3821d986fa165552023440lgao return 0; 50630fdf1140b8d1ce93f3821d986fa165552023440lgao p->bufLim = p->bufBase + RC_BUF_SIZE; 50730fdf1140b8d1ce93f3821d986fa165552023440lgao } 50830fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 50930fdf1140b8d1ce93f3821d986fa165552023440lgao} 51030fdf1140b8d1ce93f3821d986fa165552023440lgao 51130fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) 51230fdf1140b8d1ce93f3821d986fa165552023440lgao{ 51330fdf1140b8d1ce93f3821d986fa165552023440lgao alloc->Free(alloc, p->bufBase); 51430fdf1140b8d1ce93f3821d986fa165552023440lgao p->bufBase = 0; 51530fdf1140b8d1ce93f3821d986fa165552023440lgao} 51630fdf1140b8d1ce93f3821d986fa165552023440lgao 51730fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void RangeEnc_Init(CRangeEnc *p) 51830fdf1140b8d1ce93f3821d986fa165552023440lgao{ 51930fdf1140b8d1ce93f3821d986fa165552023440lgao /* Stream.Init(); */ 52030fdf1140b8d1ce93f3821d986fa165552023440lgao p->low = 0; 52130fdf1140b8d1ce93f3821d986fa165552023440lgao p->range = 0xFFFFFFFF; 52230fdf1140b8d1ce93f3821d986fa165552023440lgao p->cacheSize = 1; 52330fdf1140b8d1ce93f3821d986fa165552023440lgao p->cache = 0; 52430fdf1140b8d1ce93f3821d986fa165552023440lgao 52530fdf1140b8d1ce93f3821d986fa165552023440lgao p->buf = p->bufBase; 52630fdf1140b8d1ce93f3821d986fa165552023440lgao 52730fdf1140b8d1ce93f3821d986fa165552023440lgao p->processed = 0; 52830fdf1140b8d1ce93f3821d986fa165552023440lgao p->res = SZ_OK; 52930fdf1140b8d1ce93f3821d986fa165552023440lgao} 53030fdf1140b8d1ce93f3821d986fa165552023440lgao 53130fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void RangeEnc_FlushStream(CRangeEnc *p) 53230fdf1140b8d1ce93f3821d986fa165552023440lgao{ 53330fdf1140b8d1ce93f3821d986fa165552023440lgao size_t num; 53430fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->res != SZ_OK) 53530fdf1140b8d1ce93f3821d986fa165552023440lgao return; 53630fdf1140b8d1ce93f3821d986fa165552023440lgao num = p->buf - p->bufBase; 53730fdf1140b8d1ce93f3821d986fa165552023440lgao if (num != p->outStream->Write(p->outStream, p->bufBase, num)) 53830fdf1140b8d1ce93f3821d986fa165552023440lgao p->res = SZ_ERROR_WRITE; 53930fdf1140b8d1ce93f3821d986fa165552023440lgao p->processed += num; 54030fdf1140b8d1ce93f3821d986fa165552023440lgao p->buf = p->bufBase; 54130fdf1140b8d1ce93f3821d986fa165552023440lgao} 54230fdf1140b8d1ce93f3821d986fa165552023440lgao 54330fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) 54430fdf1140b8d1ce93f3821d986fa165552023440lgao{ 54530fdf1140b8d1ce93f3821d986fa165552023440lgao if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) 54630fdf1140b8d1ce93f3821d986fa165552023440lgao { 54730fdf1140b8d1ce93f3821d986fa165552023440lgao Byte temp = p->cache; 54830fdf1140b8d1ce93f3821d986fa165552023440lgao do 54930fdf1140b8d1ce93f3821d986fa165552023440lgao { 55030fdf1140b8d1ce93f3821d986fa165552023440lgao Byte *buf = p->buf; 55130fdf1140b8d1ce93f3821d986fa165552023440lgao *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); 55230fdf1140b8d1ce93f3821d986fa165552023440lgao p->buf = buf; 55330fdf1140b8d1ce93f3821d986fa165552023440lgao if (buf == p->bufLim) 55430fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_FlushStream(p); 55530fdf1140b8d1ce93f3821d986fa165552023440lgao temp = 0xFF; 55630fdf1140b8d1ce93f3821d986fa165552023440lgao } 55730fdf1140b8d1ce93f3821d986fa165552023440lgao while (--p->cacheSize != 0); 55830fdf1140b8d1ce93f3821d986fa165552023440lgao p->cache = (Byte)((UInt32)p->low >> 24); 55930fdf1140b8d1ce93f3821d986fa165552023440lgao } 56030fdf1140b8d1ce93f3821d986fa165552023440lgao p->cacheSize++; 56130fdf1140b8d1ce93f3821d986fa165552023440lgao p->low = (UInt32)p->low << 8; 56230fdf1140b8d1ce93f3821d986fa165552023440lgao} 56330fdf1140b8d1ce93f3821d986fa165552023440lgao 56430fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void RangeEnc_FlushData(CRangeEnc *p) 56530fdf1140b8d1ce93f3821d986fa165552023440lgao{ 56630fdf1140b8d1ce93f3821d986fa165552023440lgao int i; 56730fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < 5; i++) 56830fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_ShiftLow(p); 56930fdf1140b8d1ce93f3821d986fa165552023440lgao} 57030fdf1140b8d1ce93f3821d986fa165552023440lgao 57130fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) 57230fdf1140b8d1ce93f3821d986fa165552023440lgao{ 57330fdf1140b8d1ce93f3821d986fa165552023440lgao do 57430fdf1140b8d1ce93f3821d986fa165552023440lgao { 57530fdf1140b8d1ce93f3821d986fa165552023440lgao p->range >>= 1; 57630fdf1140b8d1ce93f3821d986fa165552023440lgao p->low += p->range & (0 - ((value >> --numBits) & 1)); 57730fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->range < kTopValue) 57830fdf1140b8d1ce93f3821d986fa165552023440lgao { 57930fdf1140b8d1ce93f3821d986fa165552023440lgao p->range <<= 8; 58030fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_ShiftLow(p); 58130fdf1140b8d1ce93f3821d986fa165552023440lgao } 58230fdf1140b8d1ce93f3821d986fa165552023440lgao } 58330fdf1140b8d1ce93f3821d986fa165552023440lgao while (numBits != 0); 58430fdf1140b8d1ce93f3821d986fa165552023440lgao} 58530fdf1140b8d1ce93f3821d986fa165552023440lgao 58630fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) 58730fdf1140b8d1ce93f3821d986fa165552023440lgao{ 58830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 ttt = *prob; 58930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; 59030fdf1140b8d1ce93f3821d986fa165552023440lgao if (symbol == 0) 59130fdf1140b8d1ce93f3821d986fa165552023440lgao { 59230fdf1140b8d1ce93f3821d986fa165552023440lgao p->range = newBound; 59330fdf1140b8d1ce93f3821d986fa165552023440lgao ttt += (kBitModelTotal - ttt) >> kNumMoveBits; 59430fdf1140b8d1ce93f3821d986fa165552023440lgao } 59530fdf1140b8d1ce93f3821d986fa165552023440lgao else 59630fdf1140b8d1ce93f3821d986fa165552023440lgao { 59730fdf1140b8d1ce93f3821d986fa165552023440lgao p->low += newBound; 59830fdf1140b8d1ce93f3821d986fa165552023440lgao p->range -= newBound; 59930fdf1140b8d1ce93f3821d986fa165552023440lgao ttt -= ttt >> kNumMoveBits; 60030fdf1140b8d1ce93f3821d986fa165552023440lgao } 60130fdf1140b8d1ce93f3821d986fa165552023440lgao *prob = (CLzmaProb)ttt; 60230fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->range < kTopValue) 60330fdf1140b8d1ce93f3821d986fa165552023440lgao { 60430fdf1140b8d1ce93f3821d986fa165552023440lgao p->range <<= 8; 60530fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_ShiftLow(p); 60630fdf1140b8d1ce93f3821d986fa165552023440lgao } 60730fdf1140b8d1ce93f3821d986fa165552023440lgao} 60830fdf1140b8d1ce93f3821d986fa165552023440lgao 60930fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) 61030fdf1140b8d1ce93f3821d986fa165552023440lgao{ 61130fdf1140b8d1ce93f3821d986fa165552023440lgao symbol |= 0x100; 61230fdf1140b8d1ce93f3821d986fa165552023440lgao do 61330fdf1140b8d1ce93f3821d986fa165552023440lgao { 61430fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); 61530fdf1140b8d1ce93f3821d986fa165552023440lgao symbol <<= 1; 61630fdf1140b8d1ce93f3821d986fa165552023440lgao } 61730fdf1140b8d1ce93f3821d986fa165552023440lgao while (symbol < 0x10000); 61830fdf1140b8d1ce93f3821d986fa165552023440lgao} 61930fdf1140b8d1ce93f3821d986fa165552023440lgao 62030fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) 62130fdf1140b8d1ce93f3821d986fa165552023440lgao{ 62230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 offs = 0x100; 62330fdf1140b8d1ce93f3821d986fa165552023440lgao symbol |= 0x100; 62430fdf1140b8d1ce93f3821d986fa165552023440lgao do 62530fdf1140b8d1ce93f3821d986fa165552023440lgao { 62630fdf1140b8d1ce93f3821d986fa165552023440lgao matchByte <<= 1; 62730fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); 62830fdf1140b8d1ce93f3821d986fa165552023440lgao symbol <<= 1; 62930fdf1140b8d1ce93f3821d986fa165552023440lgao offs &= ~(matchByte ^ symbol); 63030fdf1140b8d1ce93f3821d986fa165552023440lgao } 63130fdf1140b8d1ce93f3821d986fa165552023440lgao while (symbol < 0x10000); 63230fdf1140b8d1ce93f3821d986fa165552023440lgao} 63330fdf1140b8d1ce93f3821d986fa165552023440lgao 63430fdf1140b8d1ce93f3821d986fa165552023440lgaovoid LzmaEnc_InitPriceTables(UInt32 *ProbPrices) 63530fdf1140b8d1ce93f3821d986fa165552023440lgao{ 63630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 i; 63730fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) 63830fdf1140b8d1ce93f3821d986fa165552023440lgao { 63930fdf1140b8d1ce93f3821d986fa165552023440lgao const int kCyclesBits = kNumBitPriceShiftBits; 64030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 w = i; 64130fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 bitCount = 0; 64230fdf1140b8d1ce93f3821d986fa165552023440lgao int j; 64330fdf1140b8d1ce93f3821d986fa165552023440lgao for (j = 0; j < kCyclesBits; j++) 64430fdf1140b8d1ce93f3821d986fa165552023440lgao { 64530fdf1140b8d1ce93f3821d986fa165552023440lgao w = w * w; 64630fdf1140b8d1ce93f3821d986fa165552023440lgao bitCount <<= 1; 64730fdf1140b8d1ce93f3821d986fa165552023440lgao while (w >= ((UInt32)1 << 16)) 64830fdf1140b8d1ce93f3821d986fa165552023440lgao { 64930fdf1140b8d1ce93f3821d986fa165552023440lgao w >>= 1; 65030fdf1140b8d1ce93f3821d986fa165552023440lgao bitCount++; 65130fdf1140b8d1ce93f3821d986fa165552023440lgao } 65230fdf1140b8d1ce93f3821d986fa165552023440lgao } 65330fdf1140b8d1ce93f3821d986fa165552023440lgao ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); 65430fdf1140b8d1ce93f3821d986fa165552023440lgao } 65530fdf1140b8d1ce93f3821d986fa165552023440lgao} 65630fdf1140b8d1ce93f3821d986fa165552023440lgao 65730fdf1140b8d1ce93f3821d986fa165552023440lgao 65830fdf1140b8d1ce93f3821d986fa165552023440lgao#define GET_PRICE(prob, symbol) \ 65930fdf1140b8d1ce93f3821d986fa165552023440lgao p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; 66030fdf1140b8d1ce93f3821d986fa165552023440lgao 66130fdf1140b8d1ce93f3821d986fa165552023440lgao#define GET_PRICEa(prob, symbol) \ 66230fdf1140b8d1ce93f3821d986fa165552023440lgao ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; 66330fdf1140b8d1ce93f3821d986fa165552023440lgao 66430fdf1140b8d1ce93f3821d986fa165552023440lgao#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] 66530fdf1140b8d1ce93f3821d986fa165552023440lgao#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] 66630fdf1140b8d1ce93f3821d986fa165552023440lgao 66730fdf1140b8d1ce93f3821d986fa165552023440lgao#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] 66830fdf1140b8d1ce93f3821d986fa165552023440lgao#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] 66930fdf1140b8d1ce93f3821d986fa165552023440lgao 67030fdf1140b8d1ce93f3821d986fa165552023440lgaostatic UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) 67130fdf1140b8d1ce93f3821d986fa165552023440lgao{ 67230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 price = 0; 67330fdf1140b8d1ce93f3821d986fa165552023440lgao symbol |= 0x100; 67430fdf1140b8d1ce93f3821d986fa165552023440lgao do 67530fdf1140b8d1ce93f3821d986fa165552023440lgao { 67630fdf1140b8d1ce93f3821d986fa165552023440lgao price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); 67730fdf1140b8d1ce93f3821d986fa165552023440lgao symbol <<= 1; 67830fdf1140b8d1ce93f3821d986fa165552023440lgao } 67930fdf1140b8d1ce93f3821d986fa165552023440lgao while (symbol < 0x10000); 68030fdf1140b8d1ce93f3821d986fa165552023440lgao return price; 68130fdf1140b8d1ce93f3821d986fa165552023440lgao} 68230fdf1140b8d1ce93f3821d986fa165552023440lgao 68330fdf1140b8d1ce93f3821d986fa165552023440lgaostatic UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) 68430fdf1140b8d1ce93f3821d986fa165552023440lgao{ 68530fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 price = 0; 68630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 offs = 0x100; 68730fdf1140b8d1ce93f3821d986fa165552023440lgao symbol |= 0x100; 68830fdf1140b8d1ce93f3821d986fa165552023440lgao do 68930fdf1140b8d1ce93f3821d986fa165552023440lgao { 69030fdf1140b8d1ce93f3821d986fa165552023440lgao matchByte <<= 1; 69130fdf1140b8d1ce93f3821d986fa165552023440lgao price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); 69230fdf1140b8d1ce93f3821d986fa165552023440lgao symbol <<= 1; 69330fdf1140b8d1ce93f3821d986fa165552023440lgao offs &= ~(matchByte ^ symbol); 69430fdf1140b8d1ce93f3821d986fa165552023440lgao } 69530fdf1140b8d1ce93f3821d986fa165552023440lgao while (symbol < 0x10000); 69630fdf1140b8d1ce93f3821d986fa165552023440lgao return price; 69730fdf1140b8d1ce93f3821d986fa165552023440lgao} 69830fdf1140b8d1ce93f3821d986fa165552023440lgao 69930fdf1140b8d1ce93f3821d986fa165552023440lgao 70030fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) 70130fdf1140b8d1ce93f3821d986fa165552023440lgao{ 70230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 m = 1; 70330fdf1140b8d1ce93f3821d986fa165552023440lgao int i; 70430fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = numBitLevels; i != 0;) 70530fdf1140b8d1ce93f3821d986fa165552023440lgao { 70630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 bit; 70730fdf1140b8d1ce93f3821d986fa165552023440lgao i--; 70830fdf1140b8d1ce93f3821d986fa165552023440lgao bit = (symbol >> i) & 1; 70930fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(rc, probs + m, bit); 71030fdf1140b8d1ce93f3821d986fa165552023440lgao m = (m << 1) | bit; 71130fdf1140b8d1ce93f3821d986fa165552023440lgao } 71230fdf1140b8d1ce93f3821d986fa165552023440lgao} 71330fdf1140b8d1ce93f3821d986fa165552023440lgao 71430fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) 71530fdf1140b8d1ce93f3821d986fa165552023440lgao{ 71630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 m = 1; 71730fdf1140b8d1ce93f3821d986fa165552023440lgao int i; 71830fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < numBitLevels; i++) 71930fdf1140b8d1ce93f3821d986fa165552023440lgao { 72030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 bit = symbol & 1; 72130fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(rc, probs + m, bit); 72230fdf1140b8d1ce93f3821d986fa165552023440lgao m = (m << 1) | bit; 72330fdf1140b8d1ce93f3821d986fa165552023440lgao symbol >>= 1; 72430fdf1140b8d1ce93f3821d986fa165552023440lgao } 72530fdf1140b8d1ce93f3821d986fa165552023440lgao} 72630fdf1140b8d1ce93f3821d986fa165552023440lgao 72730fdf1140b8d1ce93f3821d986fa165552023440lgaostatic UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) 72830fdf1140b8d1ce93f3821d986fa165552023440lgao{ 72930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 price = 0; 73030fdf1140b8d1ce93f3821d986fa165552023440lgao symbol |= (1 << numBitLevels); 73130fdf1140b8d1ce93f3821d986fa165552023440lgao while (symbol != 1) 73230fdf1140b8d1ce93f3821d986fa165552023440lgao { 73330fdf1140b8d1ce93f3821d986fa165552023440lgao price += GET_PRICEa(probs[symbol >> 1], symbol & 1); 73430fdf1140b8d1ce93f3821d986fa165552023440lgao symbol >>= 1; 73530fdf1140b8d1ce93f3821d986fa165552023440lgao } 73630fdf1140b8d1ce93f3821d986fa165552023440lgao return price; 73730fdf1140b8d1ce93f3821d986fa165552023440lgao} 73830fdf1140b8d1ce93f3821d986fa165552023440lgao 73930fdf1140b8d1ce93f3821d986fa165552023440lgaostatic UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) 74030fdf1140b8d1ce93f3821d986fa165552023440lgao{ 74130fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 price = 0; 74230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 m = 1; 74330fdf1140b8d1ce93f3821d986fa165552023440lgao int i; 74430fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = numBitLevels; i != 0; i--) 74530fdf1140b8d1ce93f3821d986fa165552023440lgao { 74630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 bit = symbol & 1; 74730fdf1140b8d1ce93f3821d986fa165552023440lgao symbol >>= 1; 74830fdf1140b8d1ce93f3821d986fa165552023440lgao price += GET_PRICEa(probs[m], bit); 74930fdf1140b8d1ce93f3821d986fa165552023440lgao m = (m << 1) | bit; 75030fdf1140b8d1ce93f3821d986fa165552023440lgao } 75130fdf1140b8d1ce93f3821d986fa165552023440lgao return price; 75230fdf1140b8d1ce93f3821d986fa165552023440lgao} 75330fdf1140b8d1ce93f3821d986fa165552023440lgao 75430fdf1140b8d1ce93f3821d986fa165552023440lgao 75530fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void LenEnc_Init(CLenEnc *p) 75630fdf1140b8d1ce93f3821d986fa165552023440lgao{ 75730fdf1140b8d1ce93f3821d986fa165552023440lgao unsigned i; 75830fdf1140b8d1ce93f3821d986fa165552023440lgao p->choice = p->choice2 = kProbInitValue; 75930fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) 76030fdf1140b8d1ce93f3821d986fa165552023440lgao p->low[i] = kProbInitValue; 76130fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) 76230fdf1140b8d1ce93f3821d986fa165552023440lgao p->mid[i] = kProbInitValue; 76330fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < kLenNumHighSymbols; i++) 76430fdf1140b8d1ce93f3821d986fa165552023440lgao p->high[i] = kProbInitValue; 76530fdf1140b8d1ce93f3821d986fa165552023440lgao} 76630fdf1140b8d1ce93f3821d986fa165552023440lgao 76730fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) 76830fdf1140b8d1ce93f3821d986fa165552023440lgao{ 76930fdf1140b8d1ce93f3821d986fa165552023440lgao if (symbol < kLenNumLowSymbols) 77030fdf1140b8d1ce93f3821d986fa165552023440lgao { 77130fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(rc, &p->choice, 0); 77230fdf1140b8d1ce93f3821d986fa165552023440lgao RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); 77330fdf1140b8d1ce93f3821d986fa165552023440lgao } 77430fdf1140b8d1ce93f3821d986fa165552023440lgao else 77530fdf1140b8d1ce93f3821d986fa165552023440lgao { 77630fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(rc, &p->choice, 1); 77730fdf1140b8d1ce93f3821d986fa165552023440lgao if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) 77830fdf1140b8d1ce93f3821d986fa165552023440lgao { 77930fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(rc, &p->choice2, 0); 78030fdf1140b8d1ce93f3821d986fa165552023440lgao RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); 78130fdf1140b8d1ce93f3821d986fa165552023440lgao } 78230fdf1140b8d1ce93f3821d986fa165552023440lgao else 78330fdf1140b8d1ce93f3821d986fa165552023440lgao { 78430fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(rc, &p->choice2, 1); 78530fdf1140b8d1ce93f3821d986fa165552023440lgao RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); 78630fdf1140b8d1ce93f3821d986fa165552023440lgao } 78730fdf1140b8d1ce93f3821d986fa165552023440lgao } 78830fdf1140b8d1ce93f3821d986fa165552023440lgao} 78930fdf1140b8d1ce93f3821d986fa165552023440lgao 79030fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) 79130fdf1140b8d1ce93f3821d986fa165552023440lgao{ 79230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 a0 = GET_PRICE_0a(p->choice); 79330fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 a1 = GET_PRICE_1a(p->choice); 79430fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); 79530fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); 79630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 i = 0; 79730fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < kLenNumLowSymbols; i++) 79830fdf1140b8d1ce93f3821d986fa165552023440lgao { 79930fdf1140b8d1ce93f3821d986fa165552023440lgao if (i >= numSymbols) 80030fdf1140b8d1ce93f3821d986fa165552023440lgao return; 80130fdf1140b8d1ce93f3821d986fa165552023440lgao prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); 80230fdf1140b8d1ce93f3821d986fa165552023440lgao } 80330fdf1140b8d1ce93f3821d986fa165552023440lgao for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) 80430fdf1140b8d1ce93f3821d986fa165552023440lgao { 80530fdf1140b8d1ce93f3821d986fa165552023440lgao if (i >= numSymbols) 80630fdf1140b8d1ce93f3821d986fa165552023440lgao return; 80730fdf1140b8d1ce93f3821d986fa165552023440lgao prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); 80830fdf1140b8d1ce93f3821d986fa165552023440lgao } 80930fdf1140b8d1ce93f3821d986fa165552023440lgao for (; i < numSymbols; i++) 81030fdf1140b8d1ce93f3821d986fa165552023440lgao prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); 81130fdf1140b8d1ce93f3821d986fa165552023440lgao} 81230fdf1140b8d1ce93f3821d986fa165552023440lgao 81330fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) 81430fdf1140b8d1ce93f3821d986fa165552023440lgao{ 81530fdf1140b8d1ce93f3821d986fa165552023440lgao LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); 81630fdf1140b8d1ce93f3821d986fa165552023440lgao p->counters[posState] = p->tableSize; 81730fdf1140b8d1ce93f3821d986fa165552023440lgao} 81830fdf1140b8d1ce93f3821d986fa165552023440lgao 81930fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) 82030fdf1140b8d1ce93f3821d986fa165552023440lgao{ 82130fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 posState; 82230fdf1140b8d1ce93f3821d986fa165552023440lgao for (posState = 0; posState < numPosStates; posState++) 82330fdf1140b8d1ce93f3821d986fa165552023440lgao LenPriceEnc_UpdateTable(p, posState, ProbPrices); 82430fdf1140b8d1ce93f3821d986fa165552023440lgao} 82530fdf1140b8d1ce93f3821d986fa165552023440lgao 82630fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) 82730fdf1140b8d1ce93f3821d986fa165552023440lgao{ 82830fdf1140b8d1ce93f3821d986fa165552023440lgao LenEnc_Encode(&p->p, rc, symbol, posState); 82930fdf1140b8d1ce93f3821d986fa165552023440lgao if (updatePrice) 83030fdf1140b8d1ce93f3821d986fa165552023440lgao if (--p->counters[posState] == 0) 83130fdf1140b8d1ce93f3821d986fa165552023440lgao LenPriceEnc_UpdateTable(p, posState, ProbPrices); 83230fdf1140b8d1ce93f3821d986fa165552023440lgao} 83330fdf1140b8d1ce93f3821d986fa165552023440lgao 83430fdf1140b8d1ce93f3821d986fa165552023440lgao 83530fdf1140b8d1ce93f3821d986fa165552023440lgao 83630fdf1140b8d1ce93f3821d986fa165552023440lgao 83730fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void MovePos(CLzmaEnc *p, UInt32 num) 83830fdf1140b8d1ce93f3821d986fa165552023440lgao{ 83930fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef SHOW_STAT 84030fdf1140b8d1ce93f3821d986fa165552023440lgao ttt += num; 84130fdf1140b8d1ce93f3821d986fa165552023440lgao printf("\n MovePos %d", num); 84230fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 84330fdf1140b8d1ce93f3821d986fa165552023440lgao if (num != 0) 84430fdf1140b8d1ce93f3821d986fa165552023440lgao { 84530fdf1140b8d1ce93f3821d986fa165552023440lgao p->additionalOffset += num; 84630fdf1140b8d1ce93f3821d986fa165552023440lgao p->matchFinder.Skip(p->matchFinderObj, num); 84730fdf1140b8d1ce93f3821d986fa165552023440lgao } 84830fdf1140b8d1ce93f3821d986fa165552023440lgao} 84930fdf1140b8d1ce93f3821d986fa165552023440lgao 85030fdf1140b8d1ce93f3821d986fa165552023440lgaostatic UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) 85130fdf1140b8d1ce93f3821d986fa165552023440lgao{ 85230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 lenRes = 0, numPairs; 85330fdf1140b8d1ce93f3821d986fa165552023440lgao p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); 85430fdf1140b8d1ce93f3821d986fa165552023440lgao numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); 85530fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef SHOW_STAT 85630fdf1140b8d1ce93f3821d986fa165552023440lgao printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); 85730fdf1140b8d1ce93f3821d986fa165552023440lgao ttt++; 85830fdf1140b8d1ce93f3821d986fa165552023440lgao { 85930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 i; 86030fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < numPairs; i += 2) 86130fdf1140b8d1ce93f3821d986fa165552023440lgao printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); 86230fdf1140b8d1ce93f3821d986fa165552023440lgao } 86330fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 86430fdf1140b8d1ce93f3821d986fa165552023440lgao if (numPairs > 0) 86530fdf1140b8d1ce93f3821d986fa165552023440lgao { 86630fdf1140b8d1ce93f3821d986fa165552023440lgao lenRes = p->matches[numPairs - 2]; 86730fdf1140b8d1ce93f3821d986fa165552023440lgao if (lenRes == p->numFastBytes) 86830fdf1140b8d1ce93f3821d986fa165552023440lgao { 86930fdf1140b8d1ce93f3821d986fa165552023440lgao const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; 87030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 distance = p->matches[numPairs - 1] + 1; 87130fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 numAvail = p->numAvail; 87230fdf1140b8d1ce93f3821d986fa165552023440lgao if (numAvail > LZMA_MATCH_LEN_MAX) 87330fdf1140b8d1ce93f3821d986fa165552023440lgao numAvail = LZMA_MATCH_LEN_MAX; 87430fdf1140b8d1ce93f3821d986fa165552023440lgao { 87530fdf1140b8d1ce93f3821d986fa165552023440lgao const Byte *pby2 = pby - distance; 87630fdf1140b8d1ce93f3821d986fa165552023440lgao for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); 87730fdf1140b8d1ce93f3821d986fa165552023440lgao } 87830fdf1140b8d1ce93f3821d986fa165552023440lgao } 87930fdf1140b8d1ce93f3821d986fa165552023440lgao } 88030fdf1140b8d1ce93f3821d986fa165552023440lgao p->additionalOffset++; 88130fdf1140b8d1ce93f3821d986fa165552023440lgao *numDistancePairsRes = numPairs; 88230fdf1140b8d1ce93f3821d986fa165552023440lgao return lenRes; 88330fdf1140b8d1ce93f3821d986fa165552023440lgao} 88430fdf1140b8d1ce93f3821d986fa165552023440lgao 88530fdf1140b8d1ce93f3821d986fa165552023440lgao 88630fdf1140b8d1ce93f3821d986fa165552023440lgao#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; 88730fdf1140b8d1ce93f3821d986fa165552023440lgao#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; 88830fdf1140b8d1ce93f3821d986fa165552023440lgao#define IsShortRep(p) ((p)->backPrev == 0) 88930fdf1140b8d1ce93f3821d986fa165552023440lgao 89030fdf1140b8d1ce93f3821d986fa165552023440lgaostatic UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) 89130fdf1140b8d1ce93f3821d986fa165552023440lgao{ 89230fdf1140b8d1ce93f3821d986fa165552023440lgao return 89330fdf1140b8d1ce93f3821d986fa165552023440lgao GET_PRICE_0(p->isRepG0[state]) + 89430fdf1140b8d1ce93f3821d986fa165552023440lgao GET_PRICE_0(p->isRep0Long[state][posState]); 89530fdf1140b8d1ce93f3821d986fa165552023440lgao} 89630fdf1140b8d1ce93f3821d986fa165552023440lgao 89730fdf1140b8d1ce93f3821d986fa165552023440lgaostatic UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) 89830fdf1140b8d1ce93f3821d986fa165552023440lgao{ 89930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 price; 90030fdf1140b8d1ce93f3821d986fa165552023440lgao if (repIndex == 0) 90130fdf1140b8d1ce93f3821d986fa165552023440lgao { 90230fdf1140b8d1ce93f3821d986fa165552023440lgao price = GET_PRICE_0(p->isRepG0[state]); 90330fdf1140b8d1ce93f3821d986fa165552023440lgao price += GET_PRICE_1(p->isRep0Long[state][posState]); 90430fdf1140b8d1ce93f3821d986fa165552023440lgao } 90530fdf1140b8d1ce93f3821d986fa165552023440lgao else 90630fdf1140b8d1ce93f3821d986fa165552023440lgao { 90730fdf1140b8d1ce93f3821d986fa165552023440lgao price = GET_PRICE_1(p->isRepG0[state]); 90830fdf1140b8d1ce93f3821d986fa165552023440lgao if (repIndex == 1) 90930fdf1140b8d1ce93f3821d986fa165552023440lgao price += GET_PRICE_0(p->isRepG1[state]); 91030fdf1140b8d1ce93f3821d986fa165552023440lgao else 91130fdf1140b8d1ce93f3821d986fa165552023440lgao { 91230fdf1140b8d1ce93f3821d986fa165552023440lgao price += GET_PRICE_1(p->isRepG1[state]); 91330fdf1140b8d1ce93f3821d986fa165552023440lgao price += GET_PRICE(p->isRepG2[state], repIndex - 2); 91430fdf1140b8d1ce93f3821d986fa165552023440lgao } 91530fdf1140b8d1ce93f3821d986fa165552023440lgao } 91630fdf1140b8d1ce93f3821d986fa165552023440lgao return price; 91730fdf1140b8d1ce93f3821d986fa165552023440lgao} 91830fdf1140b8d1ce93f3821d986fa165552023440lgao 91930fdf1140b8d1ce93f3821d986fa165552023440lgaostatic UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) 92030fdf1140b8d1ce93f3821d986fa165552023440lgao{ 92130fdf1140b8d1ce93f3821d986fa165552023440lgao return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + 92230fdf1140b8d1ce93f3821d986fa165552023440lgao GetPureRepPrice(p, repIndex, state, posState); 92330fdf1140b8d1ce93f3821d986fa165552023440lgao} 92430fdf1140b8d1ce93f3821d986fa165552023440lgao 92530fdf1140b8d1ce93f3821d986fa165552023440lgaostatic UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) 92630fdf1140b8d1ce93f3821d986fa165552023440lgao{ 92730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 posMem = p->opt[cur].posPrev; 92830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 backMem = p->opt[cur].backPrev; 92930fdf1140b8d1ce93f3821d986fa165552023440lgao p->optimumEndIndex = cur; 93030fdf1140b8d1ce93f3821d986fa165552023440lgao do 93130fdf1140b8d1ce93f3821d986fa165552023440lgao { 93230fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->opt[cur].prev1IsChar) 93330fdf1140b8d1ce93f3821d986fa165552023440lgao { 93430fdf1140b8d1ce93f3821d986fa165552023440lgao MakeAsChar(&p->opt[posMem]) 93530fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[posMem].posPrev = posMem - 1; 93630fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->opt[cur].prev2) 93730fdf1140b8d1ce93f3821d986fa165552023440lgao { 93830fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[posMem - 1].prev1IsChar = False; 93930fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; 94030fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; 94130fdf1140b8d1ce93f3821d986fa165552023440lgao } 94230fdf1140b8d1ce93f3821d986fa165552023440lgao } 94330fdf1140b8d1ce93f3821d986fa165552023440lgao { 94430fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 posPrev = posMem; 94530fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 backCur = backMem; 94630fdf1140b8d1ce93f3821d986fa165552023440lgao 94730fdf1140b8d1ce93f3821d986fa165552023440lgao backMem = p->opt[posPrev].backPrev; 94830fdf1140b8d1ce93f3821d986fa165552023440lgao posMem = p->opt[posPrev].posPrev; 94930fdf1140b8d1ce93f3821d986fa165552023440lgao 95030fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[posPrev].backPrev = backCur; 95130fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[posPrev].posPrev = cur; 95230fdf1140b8d1ce93f3821d986fa165552023440lgao cur = posPrev; 95330fdf1140b8d1ce93f3821d986fa165552023440lgao } 95430fdf1140b8d1ce93f3821d986fa165552023440lgao } 95530fdf1140b8d1ce93f3821d986fa165552023440lgao while (cur != 0); 95630fdf1140b8d1ce93f3821d986fa165552023440lgao *backRes = p->opt[0].backPrev; 95730fdf1140b8d1ce93f3821d986fa165552023440lgao p->optimumCurrentIndex = p->opt[0].posPrev; 95830fdf1140b8d1ce93f3821d986fa165552023440lgao return p->optimumCurrentIndex; 95930fdf1140b8d1ce93f3821d986fa165552023440lgao} 96030fdf1140b8d1ce93f3821d986fa165552023440lgao 96130fdf1140b8d1ce93f3821d986fa165552023440lgao#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) 96230fdf1140b8d1ce93f3821d986fa165552023440lgao 96330fdf1140b8d1ce93f3821d986fa165552023440lgaostatic UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) 96430fdf1140b8d1ce93f3821d986fa165552023440lgao{ 96530fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur; 96630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 matchPrice, repMatchPrice, normalMatchPrice; 96730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; 96830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 *matches; 96930fdf1140b8d1ce93f3821d986fa165552023440lgao const Byte *data; 97030fdf1140b8d1ce93f3821d986fa165552023440lgao Byte curByte, matchByte; 97130fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->optimumEndIndex != p->optimumCurrentIndex) 97230fdf1140b8d1ce93f3821d986fa165552023440lgao { 97330fdf1140b8d1ce93f3821d986fa165552023440lgao const COptimal *opt = &p->opt[p->optimumCurrentIndex]; 97430fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; 97530fdf1140b8d1ce93f3821d986fa165552023440lgao *backRes = opt->backPrev; 97630fdf1140b8d1ce93f3821d986fa165552023440lgao p->optimumCurrentIndex = opt->posPrev; 97730fdf1140b8d1ce93f3821d986fa165552023440lgao return lenRes; 97830fdf1140b8d1ce93f3821d986fa165552023440lgao } 97930fdf1140b8d1ce93f3821d986fa165552023440lgao p->optimumCurrentIndex = p->optimumEndIndex = 0; 98030fdf1140b8d1ce93f3821d986fa165552023440lgao 98130fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->additionalOffset == 0) 98230fdf1140b8d1ce93f3821d986fa165552023440lgao mainLen = ReadMatchDistances(p, &numPairs); 98330fdf1140b8d1ce93f3821d986fa165552023440lgao else 98430fdf1140b8d1ce93f3821d986fa165552023440lgao { 98530fdf1140b8d1ce93f3821d986fa165552023440lgao mainLen = p->longestMatchLength; 98630fdf1140b8d1ce93f3821d986fa165552023440lgao numPairs = p->numPairs; 98730fdf1140b8d1ce93f3821d986fa165552023440lgao } 98830fdf1140b8d1ce93f3821d986fa165552023440lgao 98930fdf1140b8d1ce93f3821d986fa165552023440lgao numAvail = p->numAvail; 99030fdf1140b8d1ce93f3821d986fa165552023440lgao if (numAvail < 2) 99130fdf1140b8d1ce93f3821d986fa165552023440lgao { 99230fdf1140b8d1ce93f3821d986fa165552023440lgao *backRes = (UInt32)(-1); 99330fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 99430fdf1140b8d1ce93f3821d986fa165552023440lgao } 99530fdf1140b8d1ce93f3821d986fa165552023440lgao if (numAvail > LZMA_MATCH_LEN_MAX) 99630fdf1140b8d1ce93f3821d986fa165552023440lgao numAvail = LZMA_MATCH_LEN_MAX; 99730fdf1140b8d1ce93f3821d986fa165552023440lgao 99830fdf1140b8d1ce93f3821d986fa165552023440lgao data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; 99930fdf1140b8d1ce93f3821d986fa165552023440lgao repMaxIndex = 0; 100030fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < LZMA_NUM_REPS; i++) 100130fdf1140b8d1ce93f3821d986fa165552023440lgao { 100230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 lenTest; 100330fdf1140b8d1ce93f3821d986fa165552023440lgao const Byte *data2; 100430fdf1140b8d1ce93f3821d986fa165552023440lgao reps[i] = p->reps[i]; 100530fdf1140b8d1ce93f3821d986fa165552023440lgao data2 = data - (reps[i] + 1); 100630fdf1140b8d1ce93f3821d986fa165552023440lgao if (data[0] != data2[0] || data[1] != data2[1]) 100730fdf1140b8d1ce93f3821d986fa165552023440lgao { 100830fdf1140b8d1ce93f3821d986fa165552023440lgao repLens[i] = 0; 100930fdf1140b8d1ce93f3821d986fa165552023440lgao continue; 101030fdf1140b8d1ce93f3821d986fa165552023440lgao } 101130fdf1140b8d1ce93f3821d986fa165552023440lgao for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); 101230fdf1140b8d1ce93f3821d986fa165552023440lgao repLens[i] = lenTest; 101330fdf1140b8d1ce93f3821d986fa165552023440lgao if (lenTest > repLens[repMaxIndex]) 101430fdf1140b8d1ce93f3821d986fa165552023440lgao repMaxIndex = i; 101530fdf1140b8d1ce93f3821d986fa165552023440lgao } 101630fdf1140b8d1ce93f3821d986fa165552023440lgao if (repLens[repMaxIndex] >= p->numFastBytes) 101730fdf1140b8d1ce93f3821d986fa165552023440lgao { 101830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 lenRes; 101930fdf1140b8d1ce93f3821d986fa165552023440lgao *backRes = repMaxIndex; 102030fdf1140b8d1ce93f3821d986fa165552023440lgao lenRes = repLens[repMaxIndex]; 102130fdf1140b8d1ce93f3821d986fa165552023440lgao MovePos(p, lenRes - 1); 102230fdf1140b8d1ce93f3821d986fa165552023440lgao return lenRes; 102330fdf1140b8d1ce93f3821d986fa165552023440lgao } 102430fdf1140b8d1ce93f3821d986fa165552023440lgao 102530fdf1140b8d1ce93f3821d986fa165552023440lgao matches = p->matches; 102630fdf1140b8d1ce93f3821d986fa165552023440lgao if (mainLen >= p->numFastBytes) 102730fdf1140b8d1ce93f3821d986fa165552023440lgao { 102830fdf1140b8d1ce93f3821d986fa165552023440lgao *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; 102930fdf1140b8d1ce93f3821d986fa165552023440lgao MovePos(p, mainLen - 1); 103030fdf1140b8d1ce93f3821d986fa165552023440lgao return mainLen; 103130fdf1140b8d1ce93f3821d986fa165552023440lgao } 103230fdf1140b8d1ce93f3821d986fa165552023440lgao curByte = *data; 103330fdf1140b8d1ce93f3821d986fa165552023440lgao matchByte = *(data - (reps[0] + 1)); 103430fdf1140b8d1ce93f3821d986fa165552023440lgao 103530fdf1140b8d1ce93f3821d986fa165552023440lgao if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2) 103630fdf1140b8d1ce93f3821d986fa165552023440lgao { 103730fdf1140b8d1ce93f3821d986fa165552023440lgao *backRes = (UInt32)-1; 103830fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 103930fdf1140b8d1ce93f3821d986fa165552023440lgao } 104030fdf1140b8d1ce93f3821d986fa165552023440lgao 104130fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[0].state = (CState)p->state; 104230fdf1140b8d1ce93f3821d986fa165552023440lgao 104330fdf1140b8d1ce93f3821d986fa165552023440lgao posState = (position & p->pbMask); 104430fdf1140b8d1ce93f3821d986fa165552023440lgao 104530fdf1140b8d1ce93f3821d986fa165552023440lgao { 104630fdf1140b8d1ce93f3821d986fa165552023440lgao const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); 104730fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + 104830fdf1140b8d1ce93f3821d986fa165552023440lgao (!IsCharState(p->state) ? 104930fdf1140b8d1ce93f3821d986fa165552023440lgao LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : 105030fdf1140b8d1ce93f3821d986fa165552023440lgao LitEnc_GetPrice(probs, curByte, p->ProbPrices)); 105130fdf1140b8d1ce93f3821d986fa165552023440lgao } 105230fdf1140b8d1ce93f3821d986fa165552023440lgao 105330fdf1140b8d1ce93f3821d986fa165552023440lgao MakeAsChar(&p->opt[1]); 105430fdf1140b8d1ce93f3821d986fa165552023440lgao 105530fdf1140b8d1ce93f3821d986fa165552023440lgao matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); 105630fdf1140b8d1ce93f3821d986fa165552023440lgao repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); 105730fdf1140b8d1ce93f3821d986fa165552023440lgao 105830fdf1140b8d1ce93f3821d986fa165552023440lgao if (matchByte == curByte) 105930fdf1140b8d1ce93f3821d986fa165552023440lgao { 106030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); 106130fdf1140b8d1ce93f3821d986fa165552023440lgao if (shortRepPrice < p->opt[1].price) 106230fdf1140b8d1ce93f3821d986fa165552023440lgao { 106330fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[1].price = shortRepPrice; 106430fdf1140b8d1ce93f3821d986fa165552023440lgao MakeAsShortRep(&p->opt[1]); 106530fdf1140b8d1ce93f3821d986fa165552023440lgao } 106630fdf1140b8d1ce93f3821d986fa165552023440lgao } 106730fdf1140b8d1ce93f3821d986fa165552023440lgao lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]); 106830fdf1140b8d1ce93f3821d986fa165552023440lgao 106930fdf1140b8d1ce93f3821d986fa165552023440lgao if (lenEnd < 2) 107030fdf1140b8d1ce93f3821d986fa165552023440lgao { 107130fdf1140b8d1ce93f3821d986fa165552023440lgao *backRes = p->opt[1].backPrev; 107230fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 107330fdf1140b8d1ce93f3821d986fa165552023440lgao } 107430fdf1140b8d1ce93f3821d986fa165552023440lgao 107530fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[1].posPrev = 0; 107630fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < LZMA_NUM_REPS; i++) 107730fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[0].backs[i] = reps[i]; 107830fdf1140b8d1ce93f3821d986fa165552023440lgao 107930fdf1140b8d1ce93f3821d986fa165552023440lgao len = lenEnd; 108030fdf1140b8d1ce93f3821d986fa165552023440lgao do 108130fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[len--].price = kInfinityPrice; 108230fdf1140b8d1ce93f3821d986fa165552023440lgao while (len >= 2); 108330fdf1140b8d1ce93f3821d986fa165552023440lgao 108430fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < LZMA_NUM_REPS; i++) 108530fdf1140b8d1ce93f3821d986fa165552023440lgao { 108630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 repLen = repLens[i]; 108730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 price; 108830fdf1140b8d1ce93f3821d986fa165552023440lgao if (repLen < 2) 108930fdf1140b8d1ce93f3821d986fa165552023440lgao continue; 109030fdf1140b8d1ce93f3821d986fa165552023440lgao price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); 109130fdf1140b8d1ce93f3821d986fa165552023440lgao do 109230fdf1140b8d1ce93f3821d986fa165552023440lgao { 109330fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; 109430fdf1140b8d1ce93f3821d986fa165552023440lgao COptimal *opt = &p->opt[repLen]; 109530fdf1140b8d1ce93f3821d986fa165552023440lgao if (curAndLenPrice < opt->price) 109630fdf1140b8d1ce93f3821d986fa165552023440lgao { 109730fdf1140b8d1ce93f3821d986fa165552023440lgao opt->price = curAndLenPrice; 109830fdf1140b8d1ce93f3821d986fa165552023440lgao opt->posPrev = 0; 109930fdf1140b8d1ce93f3821d986fa165552023440lgao opt->backPrev = i; 110030fdf1140b8d1ce93f3821d986fa165552023440lgao opt->prev1IsChar = False; 110130fdf1140b8d1ce93f3821d986fa165552023440lgao } 110230fdf1140b8d1ce93f3821d986fa165552023440lgao } 110330fdf1140b8d1ce93f3821d986fa165552023440lgao while (--repLen >= 2); 110430fdf1140b8d1ce93f3821d986fa165552023440lgao } 110530fdf1140b8d1ce93f3821d986fa165552023440lgao 110630fdf1140b8d1ce93f3821d986fa165552023440lgao normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); 110730fdf1140b8d1ce93f3821d986fa165552023440lgao 110830fdf1140b8d1ce93f3821d986fa165552023440lgao len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); 110930fdf1140b8d1ce93f3821d986fa165552023440lgao if (len <= mainLen) 111030fdf1140b8d1ce93f3821d986fa165552023440lgao { 111130fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 offs = 0; 111230fdf1140b8d1ce93f3821d986fa165552023440lgao while (len > matches[offs]) 111330fdf1140b8d1ce93f3821d986fa165552023440lgao offs += 2; 111430fdf1140b8d1ce93f3821d986fa165552023440lgao for (; ; len++) 111530fdf1140b8d1ce93f3821d986fa165552023440lgao { 111630fdf1140b8d1ce93f3821d986fa165552023440lgao COptimal *opt; 111730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 distance = matches[offs + 1]; 111830fdf1140b8d1ce93f3821d986fa165552023440lgao 111930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; 112030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 lenToPosState = GetLenToPosState(len); 112130fdf1140b8d1ce93f3821d986fa165552023440lgao if (distance < kNumFullDistances) 112230fdf1140b8d1ce93f3821d986fa165552023440lgao curAndLenPrice += p->distancesPrices[lenToPosState][distance]; 112330fdf1140b8d1ce93f3821d986fa165552023440lgao else 112430fdf1140b8d1ce93f3821d986fa165552023440lgao { 112530fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 slot; 112630fdf1140b8d1ce93f3821d986fa165552023440lgao GetPosSlot2(distance, slot); 112730fdf1140b8d1ce93f3821d986fa165552023440lgao curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; 112830fdf1140b8d1ce93f3821d986fa165552023440lgao } 112930fdf1140b8d1ce93f3821d986fa165552023440lgao opt = &p->opt[len]; 113030fdf1140b8d1ce93f3821d986fa165552023440lgao if (curAndLenPrice < opt->price) 113130fdf1140b8d1ce93f3821d986fa165552023440lgao { 113230fdf1140b8d1ce93f3821d986fa165552023440lgao opt->price = curAndLenPrice; 113330fdf1140b8d1ce93f3821d986fa165552023440lgao opt->posPrev = 0; 113430fdf1140b8d1ce93f3821d986fa165552023440lgao opt->backPrev = distance + LZMA_NUM_REPS; 113530fdf1140b8d1ce93f3821d986fa165552023440lgao opt->prev1IsChar = False; 113630fdf1140b8d1ce93f3821d986fa165552023440lgao } 113730fdf1140b8d1ce93f3821d986fa165552023440lgao if (len == matches[offs]) 113830fdf1140b8d1ce93f3821d986fa165552023440lgao { 113930fdf1140b8d1ce93f3821d986fa165552023440lgao offs += 2; 114030fdf1140b8d1ce93f3821d986fa165552023440lgao if (offs == numPairs) 114130fdf1140b8d1ce93f3821d986fa165552023440lgao break; 114230fdf1140b8d1ce93f3821d986fa165552023440lgao } 114330fdf1140b8d1ce93f3821d986fa165552023440lgao } 114430fdf1140b8d1ce93f3821d986fa165552023440lgao } 114530fdf1140b8d1ce93f3821d986fa165552023440lgao 114630fdf1140b8d1ce93f3821d986fa165552023440lgao cur = 0; 114730fdf1140b8d1ce93f3821d986fa165552023440lgao 114830fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef SHOW_STAT2 114930fdf1140b8d1ce93f3821d986fa165552023440lgao if (position >= 0) 115030fdf1140b8d1ce93f3821d986fa165552023440lgao { 115130fdf1140b8d1ce93f3821d986fa165552023440lgao unsigned i; 115230fdf1140b8d1ce93f3821d986fa165552023440lgao printf("\n pos = %4X", position); 115330fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = cur; i <= lenEnd; i++) 115430fdf1140b8d1ce93f3821d986fa165552023440lgao printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); 115530fdf1140b8d1ce93f3821d986fa165552023440lgao } 115630fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 115730fdf1140b8d1ce93f3821d986fa165552023440lgao 115830fdf1140b8d1ce93f3821d986fa165552023440lgao for (;;) 115930fdf1140b8d1ce93f3821d986fa165552023440lgao { 116030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; 116130fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; 116230fdf1140b8d1ce93f3821d986fa165552023440lgao Bool nextIsChar; 116330fdf1140b8d1ce93f3821d986fa165552023440lgao Byte curByte, matchByte; 116430fdf1140b8d1ce93f3821d986fa165552023440lgao const Byte *data; 116530fdf1140b8d1ce93f3821d986fa165552023440lgao COptimal *curOpt; 116630fdf1140b8d1ce93f3821d986fa165552023440lgao COptimal *nextOpt; 116730fdf1140b8d1ce93f3821d986fa165552023440lgao 116830fdf1140b8d1ce93f3821d986fa165552023440lgao cur++; 116930fdf1140b8d1ce93f3821d986fa165552023440lgao if (cur == lenEnd) 117030fdf1140b8d1ce93f3821d986fa165552023440lgao return Backward(p, backRes, cur); 117130fdf1140b8d1ce93f3821d986fa165552023440lgao 117230fdf1140b8d1ce93f3821d986fa165552023440lgao newLen = ReadMatchDistances(p, &numPairs); 117330fdf1140b8d1ce93f3821d986fa165552023440lgao if (newLen >= p->numFastBytes) 117430fdf1140b8d1ce93f3821d986fa165552023440lgao { 117530fdf1140b8d1ce93f3821d986fa165552023440lgao p->numPairs = numPairs; 117630fdf1140b8d1ce93f3821d986fa165552023440lgao p->longestMatchLength = newLen; 117730fdf1140b8d1ce93f3821d986fa165552023440lgao return Backward(p, backRes, cur); 117830fdf1140b8d1ce93f3821d986fa165552023440lgao } 117930fdf1140b8d1ce93f3821d986fa165552023440lgao position++; 118030fdf1140b8d1ce93f3821d986fa165552023440lgao curOpt = &p->opt[cur]; 118130fdf1140b8d1ce93f3821d986fa165552023440lgao posPrev = curOpt->posPrev; 118230fdf1140b8d1ce93f3821d986fa165552023440lgao if (curOpt->prev1IsChar) 118330fdf1140b8d1ce93f3821d986fa165552023440lgao { 118430fdf1140b8d1ce93f3821d986fa165552023440lgao posPrev--; 118530fdf1140b8d1ce93f3821d986fa165552023440lgao if (curOpt->prev2) 118630fdf1140b8d1ce93f3821d986fa165552023440lgao { 118730fdf1140b8d1ce93f3821d986fa165552023440lgao state = p->opt[curOpt->posPrev2].state; 118830fdf1140b8d1ce93f3821d986fa165552023440lgao if (curOpt->backPrev2 < LZMA_NUM_REPS) 118930fdf1140b8d1ce93f3821d986fa165552023440lgao state = kRepNextStates[state]; 119030fdf1140b8d1ce93f3821d986fa165552023440lgao else 119130fdf1140b8d1ce93f3821d986fa165552023440lgao state = kMatchNextStates[state]; 119230fdf1140b8d1ce93f3821d986fa165552023440lgao } 119330fdf1140b8d1ce93f3821d986fa165552023440lgao else 119430fdf1140b8d1ce93f3821d986fa165552023440lgao state = p->opt[posPrev].state; 119530fdf1140b8d1ce93f3821d986fa165552023440lgao state = kLiteralNextStates[state]; 119630fdf1140b8d1ce93f3821d986fa165552023440lgao } 119730fdf1140b8d1ce93f3821d986fa165552023440lgao else 119830fdf1140b8d1ce93f3821d986fa165552023440lgao state = p->opt[posPrev].state; 119930fdf1140b8d1ce93f3821d986fa165552023440lgao if (posPrev == cur - 1) 120030fdf1140b8d1ce93f3821d986fa165552023440lgao { 120130fdf1140b8d1ce93f3821d986fa165552023440lgao if (IsShortRep(curOpt)) 120230fdf1140b8d1ce93f3821d986fa165552023440lgao state = kShortRepNextStates[state]; 120330fdf1140b8d1ce93f3821d986fa165552023440lgao else 120430fdf1140b8d1ce93f3821d986fa165552023440lgao state = kLiteralNextStates[state]; 120530fdf1140b8d1ce93f3821d986fa165552023440lgao } 120630fdf1140b8d1ce93f3821d986fa165552023440lgao else 120730fdf1140b8d1ce93f3821d986fa165552023440lgao { 120830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 pos; 120930fdf1140b8d1ce93f3821d986fa165552023440lgao const COptimal *prevOpt; 121030fdf1140b8d1ce93f3821d986fa165552023440lgao if (curOpt->prev1IsChar && curOpt->prev2) 121130fdf1140b8d1ce93f3821d986fa165552023440lgao { 121230fdf1140b8d1ce93f3821d986fa165552023440lgao posPrev = curOpt->posPrev2; 121330fdf1140b8d1ce93f3821d986fa165552023440lgao pos = curOpt->backPrev2; 121430fdf1140b8d1ce93f3821d986fa165552023440lgao state = kRepNextStates[state]; 121530fdf1140b8d1ce93f3821d986fa165552023440lgao } 121630fdf1140b8d1ce93f3821d986fa165552023440lgao else 121730fdf1140b8d1ce93f3821d986fa165552023440lgao { 121830fdf1140b8d1ce93f3821d986fa165552023440lgao pos = curOpt->backPrev; 121930fdf1140b8d1ce93f3821d986fa165552023440lgao if (pos < LZMA_NUM_REPS) 122030fdf1140b8d1ce93f3821d986fa165552023440lgao state = kRepNextStates[state]; 122130fdf1140b8d1ce93f3821d986fa165552023440lgao else 122230fdf1140b8d1ce93f3821d986fa165552023440lgao state = kMatchNextStates[state]; 122330fdf1140b8d1ce93f3821d986fa165552023440lgao } 122430fdf1140b8d1ce93f3821d986fa165552023440lgao prevOpt = &p->opt[posPrev]; 122530fdf1140b8d1ce93f3821d986fa165552023440lgao if (pos < LZMA_NUM_REPS) 122630fdf1140b8d1ce93f3821d986fa165552023440lgao { 122730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 i; 122830fdf1140b8d1ce93f3821d986fa165552023440lgao reps[0] = prevOpt->backs[pos]; 122930fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 1; i <= pos; i++) 123030fdf1140b8d1ce93f3821d986fa165552023440lgao reps[i] = prevOpt->backs[i - 1]; 123130fdf1140b8d1ce93f3821d986fa165552023440lgao for (; i < LZMA_NUM_REPS; i++) 123230fdf1140b8d1ce93f3821d986fa165552023440lgao reps[i] = prevOpt->backs[i]; 123330fdf1140b8d1ce93f3821d986fa165552023440lgao } 123430fdf1140b8d1ce93f3821d986fa165552023440lgao else 123530fdf1140b8d1ce93f3821d986fa165552023440lgao { 123630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 i; 123730fdf1140b8d1ce93f3821d986fa165552023440lgao reps[0] = (pos - LZMA_NUM_REPS); 123830fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 1; i < LZMA_NUM_REPS; i++) 123930fdf1140b8d1ce93f3821d986fa165552023440lgao reps[i] = prevOpt->backs[i - 1]; 124030fdf1140b8d1ce93f3821d986fa165552023440lgao } 124130fdf1140b8d1ce93f3821d986fa165552023440lgao } 124230fdf1140b8d1ce93f3821d986fa165552023440lgao curOpt->state = (CState)state; 124330fdf1140b8d1ce93f3821d986fa165552023440lgao 124430fdf1140b8d1ce93f3821d986fa165552023440lgao curOpt->backs[0] = reps[0]; 124530fdf1140b8d1ce93f3821d986fa165552023440lgao curOpt->backs[1] = reps[1]; 124630fdf1140b8d1ce93f3821d986fa165552023440lgao curOpt->backs[2] = reps[2]; 124730fdf1140b8d1ce93f3821d986fa165552023440lgao curOpt->backs[3] = reps[3]; 124830fdf1140b8d1ce93f3821d986fa165552023440lgao 124930fdf1140b8d1ce93f3821d986fa165552023440lgao curPrice = curOpt->price; 125030fdf1140b8d1ce93f3821d986fa165552023440lgao nextIsChar = False; 125130fdf1140b8d1ce93f3821d986fa165552023440lgao data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; 125230fdf1140b8d1ce93f3821d986fa165552023440lgao curByte = *data; 125330fdf1140b8d1ce93f3821d986fa165552023440lgao matchByte = *(data - (reps[0] + 1)); 125430fdf1140b8d1ce93f3821d986fa165552023440lgao 125530fdf1140b8d1ce93f3821d986fa165552023440lgao posState = (position & p->pbMask); 125630fdf1140b8d1ce93f3821d986fa165552023440lgao 125730fdf1140b8d1ce93f3821d986fa165552023440lgao curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); 125830fdf1140b8d1ce93f3821d986fa165552023440lgao { 125930fdf1140b8d1ce93f3821d986fa165552023440lgao const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); 126030fdf1140b8d1ce93f3821d986fa165552023440lgao curAnd1Price += 126130fdf1140b8d1ce93f3821d986fa165552023440lgao (!IsCharState(state) ? 126230fdf1140b8d1ce93f3821d986fa165552023440lgao LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) : 126330fdf1140b8d1ce93f3821d986fa165552023440lgao LitEnc_GetPrice(probs, curByte, p->ProbPrices)); 126430fdf1140b8d1ce93f3821d986fa165552023440lgao } 126530fdf1140b8d1ce93f3821d986fa165552023440lgao 126630fdf1140b8d1ce93f3821d986fa165552023440lgao nextOpt = &p->opt[cur + 1]; 126730fdf1140b8d1ce93f3821d986fa165552023440lgao 126830fdf1140b8d1ce93f3821d986fa165552023440lgao if (curAnd1Price < nextOpt->price) 126930fdf1140b8d1ce93f3821d986fa165552023440lgao { 127030fdf1140b8d1ce93f3821d986fa165552023440lgao nextOpt->price = curAnd1Price; 127130fdf1140b8d1ce93f3821d986fa165552023440lgao nextOpt->posPrev = cur; 127230fdf1140b8d1ce93f3821d986fa165552023440lgao MakeAsChar(nextOpt); 127330fdf1140b8d1ce93f3821d986fa165552023440lgao nextIsChar = True; 127430fdf1140b8d1ce93f3821d986fa165552023440lgao } 127530fdf1140b8d1ce93f3821d986fa165552023440lgao 127630fdf1140b8d1ce93f3821d986fa165552023440lgao matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); 127730fdf1140b8d1ce93f3821d986fa165552023440lgao repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); 127830fdf1140b8d1ce93f3821d986fa165552023440lgao 127930fdf1140b8d1ce93f3821d986fa165552023440lgao if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) 128030fdf1140b8d1ce93f3821d986fa165552023440lgao { 128130fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); 128230fdf1140b8d1ce93f3821d986fa165552023440lgao if (shortRepPrice <= nextOpt->price) 128330fdf1140b8d1ce93f3821d986fa165552023440lgao { 128430fdf1140b8d1ce93f3821d986fa165552023440lgao nextOpt->price = shortRepPrice; 128530fdf1140b8d1ce93f3821d986fa165552023440lgao nextOpt->posPrev = cur; 128630fdf1140b8d1ce93f3821d986fa165552023440lgao MakeAsShortRep(nextOpt); 128730fdf1140b8d1ce93f3821d986fa165552023440lgao nextIsChar = True; 128830fdf1140b8d1ce93f3821d986fa165552023440lgao } 128930fdf1140b8d1ce93f3821d986fa165552023440lgao } 129030fdf1140b8d1ce93f3821d986fa165552023440lgao numAvailFull = p->numAvail; 129130fdf1140b8d1ce93f3821d986fa165552023440lgao { 129230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 temp = kNumOpts - 1 - cur; 129330fdf1140b8d1ce93f3821d986fa165552023440lgao if (temp < numAvailFull) 129430fdf1140b8d1ce93f3821d986fa165552023440lgao numAvailFull = temp; 129530fdf1140b8d1ce93f3821d986fa165552023440lgao } 129630fdf1140b8d1ce93f3821d986fa165552023440lgao 129730fdf1140b8d1ce93f3821d986fa165552023440lgao if (numAvailFull < 2) 129830fdf1140b8d1ce93f3821d986fa165552023440lgao continue; 129930fdf1140b8d1ce93f3821d986fa165552023440lgao numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes); 130030fdf1140b8d1ce93f3821d986fa165552023440lgao 130130fdf1140b8d1ce93f3821d986fa165552023440lgao if (!nextIsChar && matchByte != curByte) /* speed optimization */ 130230fdf1140b8d1ce93f3821d986fa165552023440lgao { 130330fdf1140b8d1ce93f3821d986fa165552023440lgao /* try Literal + rep0 */ 130430fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 temp; 130530fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 lenTest2; 130630fdf1140b8d1ce93f3821d986fa165552023440lgao const Byte *data2 = data - (reps[0] + 1); 130730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 limit = p->numFastBytes + 1; 130830fdf1140b8d1ce93f3821d986fa165552023440lgao if (limit > numAvailFull) 130930fdf1140b8d1ce93f3821d986fa165552023440lgao limit = numAvailFull; 131030fdf1140b8d1ce93f3821d986fa165552023440lgao 131130fdf1140b8d1ce93f3821d986fa165552023440lgao for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); 131230fdf1140b8d1ce93f3821d986fa165552023440lgao lenTest2 = temp - 1; 131330fdf1140b8d1ce93f3821d986fa165552023440lgao if (lenTest2 >= 2) 131430fdf1140b8d1ce93f3821d986fa165552023440lgao { 131530fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 state2 = kLiteralNextStates[state]; 131630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 posStateNext = (position + 1) & p->pbMask; 131730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 nextRepMatchPrice = curAnd1Price + 131830fdf1140b8d1ce93f3821d986fa165552023440lgao GET_PRICE_1(p->isMatch[state2][posStateNext]) + 131930fdf1140b8d1ce93f3821d986fa165552023440lgao GET_PRICE_1(p->isRep[state2]); 132030fdf1140b8d1ce93f3821d986fa165552023440lgao /* for (; lenTest2 >= 2; lenTest2--) */ 132130fdf1140b8d1ce93f3821d986fa165552023440lgao { 132230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 curAndLenPrice; 132330fdf1140b8d1ce93f3821d986fa165552023440lgao COptimal *opt; 132430fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 offset = cur + 1 + lenTest2; 132530fdf1140b8d1ce93f3821d986fa165552023440lgao while (lenEnd < offset) 132630fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[++lenEnd].price = kInfinityPrice; 132730fdf1140b8d1ce93f3821d986fa165552023440lgao curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); 132830fdf1140b8d1ce93f3821d986fa165552023440lgao opt = &p->opt[offset]; 132930fdf1140b8d1ce93f3821d986fa165552023440lgao if (curAndLenPrice < opt->price) 133030fdf1140b8d1ce93f3821d986fa165552023440lgao { 133130fdf1140b8d1ce93f3821d986fa165552023440lgao opt->price = curAndLenPrice; 133230fdf1140b8d1ce93f3821d986fa165552023440lgao opt->posPrev = cur + 1; 133330fdf1140b8d1ce93f3821d986fa165552023440lgao opt->backPrev = 0; 133430fdf1140b8d1ce93f3821d986fa165552023440lgao opt->prev1IsChar = True; 133530fdf1140b8d1ce93f3821d986fa165552023440lgao opt->prev2 = False; 133630fdf1140b8d1ce93f3821d986fa165552023440lgao } 133730fdf1140b8d1ce93f3821d986fa165552023440lgao } 133830fdf1140b8d1ce93f3821d986fa165552023440lgao } 133930fdf1140b8d1ce93f3821d986fa165552023440lgao } 134030fdf1140b8d1ce93f3821d986fa165552023440lgao 134130fdf1140b8d1ce93f3821d986fa165552023440lgao startLen = 2; /* speed optimization */ 134230fdf1140b8d1ce93f3821d986fa165552023440lgao { 134330fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 repIndex; 134430fdf1140b8d1ce93f3821d986fa165552023440lgao for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) 134530fdf1140b8d1ce93f3821d986fa165552023440lgao { 134630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 lenTest; 134730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 lenTestTemp; 134830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 price; 134930fdf1140b8d1ce93f3821d986fa165552023440lgao const Byte *data2 = data - (reps[repIndex] + 1); 135030fdf1140b8d1ce93f3821d986fa165552023440lgao if (data[0] != data2[0] || data[1] != data2[1]) 135130fdf1140b8d1ce93f3821d986fa165552023440lgao continue; 135230fdf1140b8d1ce93f3821d986fa165552023440lgao for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); 135330fdf1140b8d1ce93f3821d986fa165552023440lgao while (lenEnd < cur + lenTest) 135430fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[++lenEnd].price = kInfinityPrice; 135530fdf1140b8d1ce93f3821d986fa165552023440lgao lenTestTemp = lenTest; 135630fdf1140b8d1ce93f3821d986fa165552023440lgao price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); 135730fdf1140b8d1ce93f3821d986fa165552023440lgao do 135830fdf1140b8d1ce93f3821d986fa165552023440lgao { 135930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; 136030fdf1140b8d1ce93f3821d986fa165552023440lgao COptimal *opt = &p->opt[cur + lenTest]; 136130fdf1140b8d1ce93f3821d986fa165552023440lgao if (curAndLenPrice < opt->price) 136230fdf1140b8d1ce93f3821d986fa165552023440lgao { 136330fdf1140b8d1ce93f3821d986fa165552023440lgao opt->price = curAndLenPrice; 136430fdf1140b8d1ce93f3821d986fa165552023440lgao opt->posPrev = cur; 136530fdf1140b8d1ce93f3821d986fa165552023440lgao opt->backPrev = repIndex; 136630fdf1140b8d1ce93f3821d986fa165552023440lgao opt->prev1IsChar = False; 136730fdf1140b8d1ce93f3821d986fa165552023440lgao } 136830fdf1140b8d1ce93f3821d986fa165552023440lgao } 136930fdf1140b8d1ce93f3821d986fa165552023440lgao while (--lenTest >= 2); 137030fdf1140b8d1ce93f3821d986fa165552023440lgao lenTest = lenTestTemp; 137130fdf1140b8d1ce93f3821d986fa165552023440lgao 137230fdf1140b8d1ce93f3821d986fa165552023440lgao if (repIndex == 0) 137330fdf1140b8d1ce93f3821d986fa165552023440lgao startLen = lenTest + 1; 137430fdf1140b8d1ce93f3821d986fa165552023440lgao 137530fdf1140b8d1ce93f3821d986fa165552023440lgao /* if (_maxMode) */ 137630fdf1140b8d1ce93f3821d986fa165552023440lgao { 137730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 lenTest2 = lenTest + 1; 137830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 limit = lenTest2 + p->numFastBytes; 137930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 nextRepMatchPrice; 138030fdf1140b8d1ce93f3821d986fa165552023440lgao if (limit > numAvailFull) 138130fdf1140b8d1ce93f3821d986fa165552023440lgao limit = numAvailFull; 138230fdf1140b8d1ce93f3821d986fa165552023440lgao for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); 138330fdf1140b8d1ce93f3821d986fa165552023440lgao lenTest2 -= lenTest + 1; 138430fdf1140b8d1ce93f3821d986fa165552023440lgao if (lenTest2 >= 2) 138530fdf1140b8d1ce93f3821d986fa165552023440lgao { 138630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 state2 = kRepNextStates[state]; 138730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 posStateNext = (position + lenTest) & p->pbMask; 138830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 curAndLenCharPrice = 138930fdf1140b8d1ce93f3821d986fa165552023440lgao price + p->repLenEnc.prices[posState][lenTest - 2] + 139030fdf1140b8d1ce93f3821d986fa165552023440lgao GET_PRICE_0(p->isMatch[state2][posStateNext]) + 139130fdf1140b8d1ce93f3821d986fa165552023440lgao LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), 139230fdf1140b8d1ce93f3821d986fa165552023440lgao data[lenTest], data2[lenTest], p->ProbPrices); 139330fdf1140b8d1ce93f3821d986fa165552023440lgao state2 = kLiteralNextStates[state2]; 139430fdf1140b8d1ce93f3821d986fa165552023440lgao posStateNext = (position + lenTest + 1) & p->pbMask; 139530fdf1140b8d1ce93f3821d986fa165552023440lgao nextRepMatchPrice = curAndLenCharPrice + 139630fdf1140b8d1ce93f3821d986fa165552023440lgao GET_PRICE_1(p->isMatch[state2][posStateNext]) + 139730fdf1140b8d1ce93f3821d986fa165552023440lgao GET_PRICE_1(p->isRep[state2]); 139830fdf1140b8d1ce93f3821d986fa165552023440lgao 139930fdf1140b8d1ce93f3821d986fa165552023440lgao /* for (; lenTest2 >= 2; lenTest2--) */ 140030fdf1140b8d1ce93f3821d986fa165552023440lgao { 140130fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 curAndLenPrice; 140230fdf1140b8d1ce93f3821d986fa165552023440lgao COptimal *opt; 140330fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 offset = cur + lenTest + 1 + lenTest2; 140430fdf1140b8d1ce93f3821d986fa165552023440lgao while (lenEnd < offset) 140530fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[++lenEnd].price = kInfinityPrice; 140630fdf1140b8d1ce93f3821d986fa165552023440lgao curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); 140730fdf1140b8d1ce93f3821d986fa165552023440lgao opt = &p->opt[offset]; 140830fdf1140b8d1ce93f3821d986fa165552023440lgao if (curAndLenPrice < opt->price) 140930fdf1140b8d1ce93f3821d986fa165552023440lgao { 141030fdf1140b8d1ce93f3821d986fa165552023440lgao opt->price = curAndLenPrice; 141130fdf1140b8d1ce93f3821d986fa165552023440lgao opt->posPrev = cur + lenTest + 1; 141230fdf1140b8d1ce93f3821d986fa165552023440lgao opt->backPrev = 0; 141330fdf1140b8d1ce93f3821d986fa165552023440lgao opt->prev1IsChar = True; 141430fdf1140b8d1ce93f3821d986fa165552023440lgao opt->prev2 = True; 141530fdf1140b8d1ce93f3821d986fa165552023440lgao opt->posPrev2 = cur; 141630fdf1140b8d1ce93f3821d986fa165552023440lgao opt->backPrev2 = repIndex; 141730fdf1140b8d1ce93f3821d986fa165552023440lgao } 141830fdf1140b8d1ce93f3821d986fa165552023440lgao } 141930fdf1140b8d1ce93f3821d986fa165552023440lgao } 142030fdf1140b8d1ce93f3821d986fa165552023440lgao } 142130fdf1140b8d1ce93f3821d986fa165552023440lgao } 142230fdf1140b8d1ce93f3821d986fa165552023440lgao } 142330fdf1140b8d1ce93f3821d986fa165552023440lgao /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ 142430fdf1140b8d1ce93f3821d986fa165552023440lgao if (newLen > numAvail) 142530fdf1140b8d1ce93f3821d986fa165552023440lgao { 142630fdf1140b8d1ce93f3821d986fa165552023440lgao newLen = numAvail; 142730fdf1140b8d1ce93f3821d986fa165552023440lgao for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2); 142830fdf1140b8d1ce93f3821d986fa165552023440lgao matches[numPairs] = newLen; 142930fdf1140b8d1ce93f3821d986fa165552023440lgao numPairs += 2; 143030fdf1140b8d1ce93f3821d986fa165552023440lgao } 143130fdf1140b8d1ce93f3821d986fa165552023440lgao if (newLen >= startLen) 143230fdf1140b8d1ce93f3821d986fa165552023440lgao { 143330fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); 143430fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 offs, curBack, posSlot; 143530fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 lenTest; 143630fdf1140b8d1ce93f3821d986fa165552023440lgao while (lenEnd < cur + newLen) 143730fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[++lenEnd].price = kInfinityPrice; 143830fdf1140b8d1ce93f3821d986fa165552023440lgao 143930fdf1140b8d1ce93f3821d986fa165552023440lgao offs = 0; 144030fdf1140b8d1ce93f3821d986fa165552023440lgao while (startLen > matches[offs]) 144130fdf1140b8d1ce93f3821d986fa165552023440lgao offs += 2; 144230fdf1140b8d1ce93f3821d986fa165552023440lgao curBack = matches[offs + 1]; 144330fdf1140b8d1ce93f3821d986fa165552023440lgao GetPosSlot2(curBack, posSlot); 144430fdf1140b8d1ce93f3821d986fa165552023440lgao for (lenTest = /*2*/ startLen; ; lenTest++) 144530fdf1140b8d1ce93f3821d986fa165552023440lgao { 144630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; 144730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 lenToPosState = GetLenToPosState(lenTest); 144830fdf1140b8d1ce93f3821d986fa165552023440lgao COptimal *opt; 144930fdf1140b8d1ce93f3821d986fa165552023440lgao if (curBack < kNumFullDistances) 145030fdf1140b8d1ce93f3821d986fa165552023440lgao curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; 145130fdf1140b8d1ce93f3821d986fa165552023440lgao else 145230fdf1140b8d1ce93f3821d986fa165552023440lgao curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; 145330fdf1140b8d1ce93f3821d986fa165552023440lgao 145430fdf1140b8d1ce93f3821d986fa165552023440lgao opt = &p->opt[cur + lenTest]; 145530fdf1140b8d1ce93f3821d986fa165552023440lgao if (curAndLenPrice < opt->price) 145630fdf1140b8d1ce93f3821d986fa165552023440lgao { 145730fdf1140b8d1ce93f3821d986fa165552023440lgao opt->price = curAndLenPrice; 145830fdf1140b8d1ce93f3821d986fa165552023440lgao opt->posPrev = cur; 145930fdf1140b8d1ce93f3821d986fa165552023440lgao opt->backPrev = curBack + LZMA_NUM_REPS; 146030fdf1140b8d1ce93f3821d986fa165552023440lgao opt->prev1IsChar = False; 146130fdf1140b8d1ce93f3821d986fa165552023440lgao } 146230fdf1140b8d1ce93f3821d986fa165552023440lgao 146330fdf1140b8d1ce93f3821d986fa165552023440lgao if (/*_maxMode && */lenTest == matches[offs]) 146430fdf1140b8d1ce93f3821d986fa165552023440lgao { 146530fdf1140b8d1ce93f3821d986fa165552023440lgao /* Try Match + Literal + Rep0 */ 146630fdf1140b8d1ce93f3821d986fa165552023440lgao const Byte *data2 = data - (curBack + 1); 146730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 lenTest2 = lenTest + 1; 146830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 limit = lenTest2 + p->numFastBytes; 146930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 nextRepMatchPrice; 147030fdf1140b8d1ce93f3821d986fa165552023440lgao if (limit > numAvailFull) 147130fdf1140b8d1ce93f3821d986fa165552023440lgao limit = numAvailFull; 147230fdf1140b8d1ce93f3821d986fa165552023440lgao for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); 147330fdf1140b8d1ce93f3821d986fa165552023440lgao lenTest2 -= lenTest + 1; 147430fdf1140b8d1ce93f3821d986fa165552023440lgao if (lenTest2 >= 2) 147530fdf1140b8d1ce93f3821d986fa165552023440lgao { 147630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 state2 = kMatchNextStates[state]; 147730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 posStateNext = (position + lenTest) & p->pbMask; 147830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 curAndLenCharPrice = curAndLenPrice + 147930fdf1140b8d1ce93f3821d986fa165552023440lgao GET_PRICE_0(p->isMatch[state2][posStateNext]) + 148030fdf1140b8d1ce93f3821d986fa165552023440lgao LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), 148130fdf1140b8d1ce93f3821d986fa165552023440lgao data[lenTest], data2[lenTest], p->ProbPrices); 148230fdf1140b8d1ce93f3821d986fa165552023440lgao state2 = kLiteralNextStates[state2]; 148330fdf1140b8d1ce93f3821d986fa165552023440lgao posStateNext = (posStateNext + 1) & p->pbMask; 148430fdf1140b8d1ce93f3821d986fa165552023440lgao nextRepMatchPrice = curAndLenCharPrice + 148530fdf1140b8d1ce93f3821d986fa165552023440lgao GET_PRICE_1(p->isMatch[state2][posStateNext]) + 148630fdf1140b8d1ce93f3821d986fa165552023440lgao GET_PRICE_1(p->isRep[state2]); 148730fdf1140b8d1ce93f3821d986fa165552023440lgao 148830fdf1140b8d1ce93f3821d986fa165552023440lgao /* for (; lenTest2 >= 2; lenTest2--) */ 148930fdf1140b8d1ce93f3821d986fa165552023440lgao { 149030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 offset = cur + lenTest + 1 + lenTest2; 149130fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 curAndLenPrice; 149230fdf1140b8d1ce93f3821d986fa165552023440lgao COptimal *opt; 149330fdf1140b8d1ce93f3821d986fa165552023440lgao while (lenEnd < offset) 149430fdf1140b8d1ce93f3821d986fa165552023440lgao p->opt[++lenEnd].price = kInfinityPrice; 149530fdf1140b8d1ce93f3821d986fa165552023440lgao curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); 149630fdf1140b8d1ce93f3821d986fa165552023440lgao opt = &p->opt[offset]; 149730fdf1140b8d1ce93f3821d986fa165552023440lgao if (curAndLenPrice < opt->price) 149830fdf1140b8d1ce93f3821d986fa165552023440lgao { 149930fdf1140b8d1ce93f3821d986fa165552023440lgao opt->price = curAndLenPrice; 150030fdf1140b8d1ce93f3821d986fa165552023440lgao opt->posPrev = cur + lenTest + 1; 150130fdf1140b8d1ce93f3821d986fa165552023440lgao opt->backPrev = 0; 150230fdf1140b8d1ce93f3821d986fa165552023440lgao opt->prev1IsChar = True; 150330fdf1140b8d1ce93f3821d986fa165552023440lgao opt->prev2 = True; 150430fdf1140b8d1ce93f3821d986fa165552023440lgao opt->posPrev2 = cur; 150530fdf1140b8d1ce93f3821d986fa165552023440lgao opt->backPrev2 = curBack + LZMA_NUM_REPS; 150630fdf1140b8d1ce93f3821d986fa165552023440lgao } 150730fdf1140b8d1ce93f3821d986fa165552023440lgao } 150830fdf1140b8d1ce93f3821d986fa165552023440lgao } 150930fdf1140b8d1ce93f3821d986fa165552023440lgao offs += 2; 151030fdf1140b8d1ce93f3821d986fa165552023440lgao if (offs == numPairs) 151130fdf1140b8d1ce93f3821d986fa165552023440lgao break; 151230fdf1140b8d1ce93f3821d986fa165552023440lgao curBack = matches[offs + 1]; 151330fdf1140b8d1ce93f3821d986fa165552023440lgao if (curBack >= kNumFullDistances) 151430fdf1140b8d1ce93f3821d986fa165552023440lgao GetPosSlot2(curBack, posSlot); 151530fdf1140b8d1ce93f3821d986fa165552023440lgao } 151630fdf1140b8d1ce93f3821d986fa165552023440lgao } 151730fdf1140b8d1ce93f3821d986fa165552023440lgao } 151830fdf1140b8d1ce93f3821d986fa165552023440lgao } 151930fdf1140b8d1ce93f3821d986fa165552023440lgao} 152030fdf1140b8d1ce93f3821d986fa165552023440lgao 152130fdf1140b8d1ce93f3821d986fa165552023440lgao#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) 152230fdf1140b8d1ce93f3821d986fa165552023440lgao 152330fdf1140b8d1ce93f3821d986fa165552023440lgaostatic UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) 152430fdf1140b8d1ce93f3821d986fa165552023440lgao{ 152530fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i; 152630fdf1140b8d1ce93f3821d986fa165552023440lgao const Byte *data; 152730fdf1140b8d1ce93f3821d986fa165552023440lgao const UInt32 *matches; 152830fdf1140b8d1ce93f3821d986fa165552023440lgao 152930fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->additionalOffset == 0) 153030fdf1140b8d1ce93f3821d986fa165552023440lgao mainLen = ReadMatchDistances(p, &numPairs); 153130fdf1140b8d1ce93f3821d986fa165552023440lgao else 153230fdf1140b8d1ce93f3821d986fa165552023440lgao { 153330fdf1140b8d1ce93f3821d986fa165552023440lgao mainLen = p->longestMatchLength; 153430fdf1140b8d1ce93f3821d986fa165552023440lgao numPairs = p->numPairs; 153530fdf1140b8d1ce93f3821d986fa165552023440lgao } 153630fdf1140b8d1ce93f3821d986fa165552023440lgao 153730fdf1140b8d1ce93f3821d986fa165552023440lgao numAvail = p->numAvail; 153830fdf1140b8d1ce93f3821d986fa165552023440lgao *backRes = (UInt32)-1; 153930fdf1140b8d1ce93f3821d986fa165552023440lgao if (numAvail < 2) 154030fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 154130fdf1140b8d1ce93f3821d986fa165552023440lgao if (numAvail > LZMA_MATCH_LEN_MAX) 154230fdf1140b8d1ce93f3821d986fa165552023440lgao numAvail = LZMA_MATCH_LEN_MAX; 154330fdf1140b8d1ce93f3821d986fa165552023440lgao data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; 154430fdf1140b8d1ce93f3821d986fa165552023440lgao 154530fdf1140b8d1ce93f3821d986fa165552023440lgao repLen = repIndex = 0; 154630fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < LZMA_NUM_REPS; i++) 154730fdf1140b8d1ce93f3821d986fa165552023440lgao { 154830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 len; 154930fdf1140b8d1ce93f3821d986fa165552023440lgao const Byte *data2 = data - (p->reps[i] + 1); 155030fdf1140b8d1ce93f3821d986fa165552023440lgao if (data[0] != data2[0] || data[1] != data2[1]) 155130fdf1140b8d1ce93f3821d986fa165552023440lgao continue; 155230fdf1140b8d1ce93f3821d986fa165552023440lgao for (len = 2; len < numAvail && data[len] == data2[len]; len++); 155330fdf1140b8d1ce93f3821d986fa165552023440lgao if (len >= p->numFastBytes) 155430fdf1140b8d1ce93f3821d986fa165552023440lgao { 155530fdf1140b8d1ce93f3821d986fa165552023440lgao *backRes = i; 155630fdf1140b8d1ce93f3821d986fa165552023440lgao MovePos(p, len - 1); 155730fdf1140b8d1ce93f3821d986fa165552023440lgao return len; 155830fdf1140b8d1ce93f3821d986fa165552023440lgao } 155930fdf1140b8d1ce93f3821d986fa165552023440lgao if (len > repLen) 156030fdf1140b8d1ce93f3821d986fa165552023440lgao { 156130fdf1140b8d1ce93f3821d986fa165552023440lgao repIndex = i; 156230fdf1140b8d1ce93f3821d986fa165552023440lgao repLen = len; 156330fdf1140b8d1ce93f3821d986fa165552023440lgao } 156430fdf1140b8d1ce93f3821d986fa165552023440lgao } 156530fdf1140b8d1ce93f3821d986fa165552023440lgao 156630fdf1140b8d1ce93f3821d986fa165552023440lgao matches = p->matches; 156730fdf1140b8d1ce93f3821d986fa165552023440lgao if (mainLen >= p->numFastBytes) 156830fdf1140b8d1ce93f3821d986fa165552023440lgao { 156930fdf1140b8d1ce93f3821d986fa165552023440lgao *backRes = matches[numPairs - 1] + LZMA_NUM_REPS; 157030fdf1140b8d1ce93f3821d986fa165552023440lgao MovePos(p, mainLen - 1); 157130fdf1140b8d1ce93f3821d986fa165552023440lgao return mainLen; 157230fdf1140b8d1ce93f3821d986fa165552023440lgao } 157330fdf1140b8d1ce93f3821d986fa165552023440lgao 157430fdf1140b8d1ce93f3821d986fa165552023440lgao mainDist = 0; /* for GCC */ 157530fdf1140b8d1ce93f3821d986fa165552023440lgao if (mainLen >= 2) 157630fdf1140b8d1ce93f3821d986fa165552023440lgao { 157730fdf1140b8d1ce93f3821d986fa165552023440lgao mainDist = matches[numPairs - 1]; 157830fdf1140b8d1ce93f3821d986fa165552023440lgao while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1) 157930fdf1140b8d1ce93f3821d986fa165552023440lgao { 158030fdf1140b8d1ce93f3821d986fa165552023440lgao if (!ChangePair(matches[numPairs - 3], mainDist)) 158130fdf1140b8d1ce93f3821d986fa165552023440lgao break; 158230fdf1140b8d1ce93f3821d986fa165552023440lgao numPairs -= 2; 158330fdf1140b8d1ce93f3821d986fa165552023440lgao mainLen = matches[numPairs - 2]; 158430fdf1140b8d1ce93f3821d986fa165552023440lgao mainDist = matches[numPairs - 1]; 158530fdf1140b8d1ce93f3821d986fa165552023440lgao } 158630fdf1140b8d1ce93f3821d986fa165552023440lgao if (mainLen == 2 && mainDist >= 0x80) 158730fdf1140b8d1ce93f3821d986fa165552023440lgao mainLen = 1; 158830fdf1140b8d1ce93f3821d986fa165552023440lgao } 158930fdf1140b8d1ce93f3821d986fa165552023440lgao 159030fdf1140b8d1ce93f3821d986fa165552023440lgao if (repLen >= 2 && ( 159130fdf1140b8d1ce93f3821d986fa165552023440lgao (repLen + 1 >= mainLen) || 159230fdf1140b8d1ce93f3821d986fa165552023440lgao (repLen + 2 >= mainLen && mainDist >= (1 << 9)) || 159330fdf1140b8d1ce93f3821d986fa165552023440lgao (repLen + 3 >= mainLen && mainDist >= (1 << 15)))) 159430fdf1140b8d1ce93f3821d986fa165552023440lgao { 159530fdf1140b8d1ce93f3821d986fa165552023440lgao *backRes = repIndex; 159630fdf1140b8d1ce93f3821d986fa165552023440lgao MovePos(p, repLen - 1); 159730fdf1140b8d1ce93f3821d986fa165552023440lgao return repLen; 159830fdf1140b8d1ce93f3821d986fa165552023440lgao } 159930fdf1140b8d1ce93f3821d986fa165552023440lgao 160030fdf1140b8d1ce93f3821d986fa165552023440lgao if (mainLen < 2 || numAvail <= 2) 160130fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 160230fdf1140b8d1ce93f3821d986fa165552023440lgao 160330fdf1140b8d1ce93f3821d986fa165552023440lgao p->longestMatchLength = ReadMatchDistances(p, &p->numPairs); 160430fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->longestMatchLength >= 2) 160530fdf1140b8d1ce93f3821d986fa165552023440lgao { 160630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 newDistance = matches[p->numPairs - 1]; 160730fdf1140b8d1ce93f3821d986fa165552023440lgao if ((p->longestMatchLength >= mainLen && newDistance < mainDist) || 160830fdf1140b8d1ce93f3821d986fa165552023440lgao (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) || 160930fdf1140b8d1ce93f3821d986fa165552023440lgao (p->longestMatchLength > mainLen + 1) || 161030fdf1140b8d1ce93f3821d986fa165552023440lgao (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) 161130fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 161230fdf1140b8d1ce93f3821d986fa165552023440lgao } 161330fdf1140b8d1ce93f3821d986fa165552023440lgao 161430fdf1140b8d1ce93f3821d986fa165552023440lgao data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; 161530fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < LZMA_NUM_REPS; i++) 161630fdf1140b8d1ce93f3821d986fa165552023440lgao { 161730fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 len, limit; 161830fdf1140b8d1ce93f3821d986fa165552023440lgao const Byte *data2 = data - (p->reps[i] + 1); 161930fdf1140b8d1ce93f3821d986fa165552023440lgao if (data[0] != data2[0] || data[1] != data2[1]) 162030fdf1140b8d1ce93f3821d986fa165552023440lgao continue; 162130fdf1140b8d1ce93f3821d986fa165552023440lgao limit = mainLen - 1; 162230fdf1140b8d1ce93f3821d986fa165552023440lgao for (len = 2; len < limit && data[len] == data2[len]; len++); 162330fdf1140b8d1ce93f3821d986fa165552023440lgao if (len >= limit) 162430fdf1140b8d1ce93f3821d986fa165552023440lgao return 1; 162530fdf1140b8d1ce93f3821d986fa165552023440lgao } 162630fdf1140b8d1ce93f3821d986fa165552023440lgao *backRes = mainDist + LZMA_NUM_REPS; 162730fdf1140b8d1ce93f3821d986fa165552023440lgao MovePos(p, mainLen - 2); 162830fdf1140b8d1ce93f3821d986fa165552023440lgao return mainLen; 162930fdf1140b8d1ce93f3821d986fa165552023440lgao} 163030fdf1140b8d1ce93f3821d986fa165552023440lgao 163130fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void WriteEndMarker(CLzmaEnc *p, UInt32 posState) 163230fdf1140b8d1ce93f3821d986fa165552023440lgao{ 163330fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 len; 163430fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); 163530fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); 163630fdf1140b8d1ce93f3821d986fa165552023440lgao p->state = kMatchNextStates[p->state]; 163730fdf1140b8d1ce93f3821d986fa165552023440lgao len = LZMA_MATCH_LEN_MIN; 163830fdf1140b8d1ce93f3821d986fa165552023440lgao LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); 163930fdf1140b8d1ce93f3821d986fa165552023440lgao RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); 164030fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); 164130fdf1140b8d1ce93f3821d986fa165552023440lgao RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); 164230fdf1140b8d1ce93f3821d986fa165552023440lgao} 164330fdf1140b8d1ce93f3821d986fa165552023440lgao 164430fdf1140b8d1ce93f3821d986fa165552023440lgaostatic SRes CheckErrors(CLzmaEnc *p) 164530fdf1140b8d1ce93f3821d986fa165552023440lgao{ 164630fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->result != SZ_OK) 164730fdf1140b8d1ce93f3821d986fa165552023440lgao return p->result; 164830fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->rc.res != SZ_OK) 164930fdf1140b8d1ce93f3821d986fa165552023440lgao p->result = SZ_ERROR_WRITE; 165030fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->matchFinderBase.result != SZ_OK) 165130fdf1140b8d1ce93f3821d986fa165552023440lgao p->result = SZ_ERROR_READ; 165230fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->result != SZ_OK) 165330fdf1140b8d1ce93f3821d986fa165552023440lgao p->finished = True; 165430fdf1140b8d1ce93f3821d986fa165552023440lgao return p->result; 165530fdf1140b8d1ce93f3821d986fa165552023440lgao} 165630fdf1140b8d1ce93f3821d986fa165552023440lgao 165730fdf1140b8d1ce93f3821d986fa165552023440lgaostatic SRes Flush(CLzmaEnc *p, UInt32 nowPos) 165830fdf1140b8d1ce93f3821d986fa165552023440lgao{ 165930fdf1140b8d1ce93f3821d986fa165552023440lgao /* ReleaseMFStream(); */ 166030fdf1140b8d1ce93f3821d986fa165552023440lgao p->finished = True; 166130fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->writeEndMark) 166230fdf1140b8d1ce93f3821d986fa165552023440lgao WriteEndMarker(p, nowPos & p->pbMask); 166330fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_FlushData(&p->rc); 166430fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_FlushStream(&p->rc); 166530fdf1140b8d1ce93f3821d986fa165552023440lgao return CheckErrors(p); 166630fdf1140b8d1ce93f3821d986fa165552023440lgao} 166730fdf1140b8d1ce93f3821d986fa165552023440lgao 166830fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void FillAlignPrices(CLzmaEnc *p) 166930fdf1140b8d1ce93f3821d986fa165552023440lgao{ 167030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 i; 167130fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < kAlignTableSize; i++) 167230fdf1140b8d1ce93f3821d986fa165552023440lgao p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); 167330fdf1140b8d1ce93f3821d986fa165552023440lgao p->alignPriceCount = 0; 167430fdf1140b8d1ce93f3821d986fa165552023440lgao} 167530fdf1140b8d1ce93f3821d986fa165552023440lgao 167630fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void FillDistancesPrices(CLzmaEnc *p) 167730fdf1140b8d1ce93f3821d986fa165552023440lgao{ 167830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 tempPrices[kNumFullDistances]; 167930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 i, lenToPosState; 168030fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = kStartPosModelIndex; i < kNumFullDistances; i++) 168130fdf1140b8d1ce93f3821d986fa165552023440lgao { 168230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 posSlot = GetPosSlot1(i); 168330fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 footerBits = ((posSlot >> 1) - 1); 168430fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 base = ((2 | (posSlot & 1)) << footerBits); 168530fdf1140b8d1ce93f3821d986fa165552023440lgao tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); 168630fdf1140b8d1ce93f3821d986fa165552023440lgao } 168730fdf1140b8d1ce93f3821d986fa165552023440lgao 168830fdf1140b8d1ce93f3821d986fa165552023440lgao for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) 168930fdf1140b8d1ce93f3821d986fa165552023440lgao { 169030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 posSlot; 169130fdf1140b8d1ce93f3821d986fa165552023440lgao const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; 169230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; 169330fdf1140b8d1ce93f3821d986fa165552023440lgao for (posSlot = 0; posSlot < p->distTableSize; posSlot++) 169430fdf1140b8d1ce93f3821d986fa165552023440lgao posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); 169530fdf1140b8d1ce93f3821d986fa165552023440lgao for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) 169630fdf1140b8d1ce93f3821d986fa165552023440lgao posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); 169730fdf1140b8d1ce93f3821d986fa165552023440lgao 169830fdf1140b8d1ce93f3821d986fa165552023440lgao { 169930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; 170030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 i; 170130fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < kStartPosModelIndex; i++) 170230fdf1140b8d1ce93f3821d986fa165552023440lgao distancesPrices[i] = posSlotPrices[i]; 170330fdf1140b8d1ce93f3821d986fa165552023440lgao for (; i < kNumFullDistances; i++) 170430fdf1140b8d1ce93f3821d986fa165552023440lgao distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; 170530fdf1140b8d1ce93f3821d986fa165552023440lgao } 170630fdf1140b8d1ce93f3821d986fa165552023440lgao } 170730fdf1140b8d1ce93f3821d986fa165552023440lgao p->matchPriceCount = 0; 170830fdf1140b8d1ce93f3821d986fa165552023440lgao} 170930fdf1140b8d1ce93f3821d986fa165552023440lgao 171030fdf1140b8d1ce93f3821d986fa165552023440lgaovoid LzmaEnc_Construct(CLzmaEnc *p) 171130fdf1140b8d1ce93f3821d986fa165552023440lgao{ 171230fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_Construct(&p->rc); 171330fdf1140b8d1ce93f3821d986fa165552023440lgao MatchFinder_Construct(&p->matchFinderBase); 171430fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef COMPRESS_MF_MT 171530fdf1140b8d1ce93f3821d986fa165552023440lgao MatchFinderMt_Construct(&p->matchFinderMt); 171630fdf1140b8d1ce93f3821d986fa165552023440lgao p->matchFinderMt.MatchFinder = &p->matchFinderBase; 171730fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 171830fdf1140b8d1ce93f3821d986fa165552023440lgao 171930fdf1140b8d1ce93f3821d986fa165552023440lgao { 172030fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEncProps props; 172130fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEncProps_Init(&props); 172230fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_SetProps(p, &props); 172330fdf1140b8d1ce93f3821d986fa165552023440lgao } 172430fdf1140b8d1ce93f3821d986fa165552023440lgao 172530fdf1140b8d1ce93f3821d986fa165552023440lgao #ifndef LZMA_LOG_BSR 172630fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_FastPosInit(p->g_FastPos); 172730fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 172830fdf1140b8d1ce93f3821d986fa165552023440lgao 172930fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_InitPriceTables(p->ProbPrices); 173030fdf1140b8d1ce93f3821d986fa165552023440lgao p->litProbs = 0; 173130fdf1140b8d1ce93f3821d986fa165552023440lgao p->saveState.litProbs = 0; 173230fdf1140b8d1ce93f3821d986fa165552023440lgao} 173330fdf1140b8d1ce93f3821d986fa165552023440lgao 173430fdf1140b8d1ce93f3821d986fa165552023440lgaoCLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) 173530fdf1140b8d1ce93f3821d986fa165552023440lgao{ 173630fdf1140b8d1ce93f3821d986fa165552023440lgao void *p; 173730fdf1140b8d1ce93f3821d986fa165552023440lgao p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); 173830fdf1140b8d1ce93f3821d986fa165552023440lgao if (p != 0) 173930fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_Construct((CLzmaEnc *)p); 174030fdf1140b8d1ce93f3821d986fa165552023440lgao return p; 174130fdf1140b8d1ce93f3821d986fa165552023440lgao} 174230fdf1140b8d1ce93f3821d986fa165552023440lgao 174330fdf1140b8d1ce93f3821d986fa165552023440lgaovoid LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) 174430fdf1140b8d1ce93f3821d986fa165552023440lgao{ 174530fdf1140b8d1ce93f3821d986fa165552023440lgao alloc->Free(alloc, p->litProbs); 174630fdf1140b8d1ce93f3821d986fa165552023440lgao alloc->Free(alloc, p->saveState.litProbs); 174730fdf1140b8d1ce93f3821d986fa165552023440lgao p->litProbs = 0; 174830fdf1140b8d1ce93f3821d986fa165552023440lgao p->saveState.litProbs = 0; 174930fdf1140b8d1ce93f3821d986fa165552023440lgao} 175030fdf1140b8d1ce93f3821d986fa165552023440lgao 175130fdf1140b8d1ce93f3821d986fa165552023440lgaovoid LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) 175230fdf1140b8d1ce93f3821d986fa165552023440lgao{ 175330fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef COMPRESS_MF_MT 175430fdf1140b8d1ce93f3821d986fa165552023440lgao MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); 175530fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 175630fdf1140b8d1ce93f3821d986fa165552023440lgao MatchFinder_Free(&p->matchFinderBase, allocBig); 175730fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_FreeLits(p, alloc); 175830fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_Free(&p->rc, alloc); 175930fdf1140b8d1ce93f3821d986fa165552023440lgao} 176030fdf1140b8d1ce93f3821d986fa165552023440lgao 176130fdf1140b8d1ce93f3821d986fa165552023440lgaovoid LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) 176230fdf1140b8d1ce93f3821d986fa165552023440lgao{ 176330fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); 176430fdf1140b8d1ce93f3821d986fa165552023440lgao alloc->Free(alloc, p); 176530fdf1140b8d1ce93f3821d986fa165552023440lgao} 176630fdf1140b8d1ce93f3821d986fa165552023440lgao 176730fdf1140b8d1ce93f3821d986fa165552023440lgaostatic SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) 176830fdf1140b8d1ce93f3821d986fa165552023440lgao{ 176930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 nowPos32, startPos32; 177030fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->inStream != 0) 177130fdf1140b8d1ce93f3821d986fa165552023440lgao { 177230fdf1140b8d1ce93f3821d986fa165552023440lgao p->matchFinderBase.stream = p->inStream; 177330fdf1140b8d1ce93f3821d986fa165552023440lgao p->matchFinder.Init(p->matchFinderObj); 177430fdf1140b8d1ce93f3821d986fa165552023440lgao p->inStream = 0; 177530fdf1140b8d1ce93f3821d986fa165552023440lgao } 177630fdf1140b8d1ce93f3821d986fa165552023440lgao 177730fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->finished) 177830fdf1140b8d1ce93f3821d986fa165552023440lgao return p->result; 177930fdf1140b8d1ce93f3821d986fa165552023440lgao RINOK(CheckErrors(p)); 178030fdf1140b8d1ce93f3821d986fa165552023440lgao 178130fdf1140b8d1ce93f3821d986fa165552023440lgao nowPos32 = (UInt32)p->nowPos64; 178230fdf1140b8d1ce93f3821d986fa165552023440lgao startPos32 = nowPos32; 178330fdf1140b8d1ce93f3821d986fa165552023440lgao 178430fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->nowPos64 == 0) 178530fdf1140b8d1ce93f3821d986fa165552023440lgao { 178630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 numPairs; 178730fdf1140b8d1ce93f3821d986fa165552023440lgao Byte curByte; 178830fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) 178930fdf1140b8d1ce93f3821d986fa165552023440lgao return Flush(p, nowPos32); 179030fdf1140b8d1ce93f3821d986fa165552023440lgao ReadMatchDistances(p, &numPairs); 179130fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); 179230fdf1140b8d1ce93f3821d986fa165552023440lgao p->state = kLiteralNextStates[p->state]; 179330fdf1140b8d1ce93f3821d986fa165552023440lgao curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); 179430fdf1140b8d1ce93f3821d986fa165552023440lgao LitEnc_Encode(&p->rc, p->litProbs, curByte); 179530fdf1140b8d1ce93f3821d986fa165552023440lgao p->additionalOffset--; 179630fdf1140b8d1ce93f3821d986fa165552023440lgao nowPos32++; 179730fdf1140b8d1ce93f3821d986fa165552023440lgao } 179830fdf1140b8d1ce93f3821d986fa165552023440lgao 179930fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) 180030fdf1140b8d1ce93f3821d986fa165552023440lgao for (;;) 180130fdf1140b8d1ce93f3821d986fa165552023440lgao { 180230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 pos, len, posState; 180330fdf1140b8d1ce93f3821d986fa165552023440lgao 180430fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->fastMode) 180530fdf1140b8d1ce93f3821d986fa165552023440lgao len = GetOptimumFast(p, &pos); 180630fdf1140b8d1ce93f3821d986fa165552023440lgao else 180730fdf1140b8d1ce93f3821d986fa165552023440lgao len = GetOptimum(p, nowPos32, &pos); 180830fdf1140b8d1ce93f3821d986fa165552023440lgao 180930fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef SHOW_STAT2 181030fdf1140b8d1ce93f3821d986fa165552023440lgao printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); 181130fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 181230fdf1140b8d1ce93f3821d986fa165552023440lgao 181330fdf1140b8d1ce93f3821d986fa165552023440lgao posState = nowPos32 & p->pbMask; 181430fdf1140b8d1ce93f3821d986fa165552023440lgao if (len == 1 && pos == (UInt32)-1) 181530fdf1140b8d1ce93f3821d986fa165552023440lgao { 181630fdf1140b8d1ce93f3821d986fa165552023440lgao Byte curByte; 181730fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb *probs; 181830fdf1140b8d1ce93f3821d986fa165552023440lgao const Byte *data; 181930fdf1140b8d1ce93f3821d986fa165552023440lgao 182030fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); 182130fdf1140b8d1ce93f3821d986fa165552023440lgao data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; 182230fdf1140b8d1ce93f3821d986fa165552023440lgao curByte = *data; 182330fdf1140b8d1ce93f3821d986fa165552023440lgao probs = LIT_PROBS(nowPos32, *(data - 1)); 182430fdf1140b8d1ce93f3821d986fa165552023440lgao if (IsCharState(p->state)) 182530fdf1140b8d1ce93f3821d986fa165552023440lgao LitEnc_Encode(&p->rc, probs, curByte); 182630fdf1140b8d1ce93f3821d986fa165552023440lgao else 182730fdf1140b8d1ce93f3821d986fa165552023440lgao LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); 182830fdf1140b8d1ce93f3821d986fa165552023440lgao p->state = kLiteralNextStates[p->state]; 182930fdf1140b8d1ce93f3821d986fa165552023440lgao } 183030fdf1140b8d1ce93f3821d986fa165552023440lgao else 183130fdf1140b8d1ce93f3821d986fa165552023440lgao { 183230fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); 183330fdf1140b8d1ce93f3821d986fa165552023440lgao if (pos < LZMA_NUM_REPS) 183430fdf1140b8d1ce93f3821d986fa165552023440lgao { 183530fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); 183630fdf1140b8d1ce93f3821d986fa165552023440lgao if (pos == 0) 183730fdf1140b8d1ce93f3821d986fa165552023440lgao { 183830fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); 183930fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); 184030fdf1140b8d1ce93f3821d986fa165552023440lgao } 184130fdf1140b8d1ce93f3821d986fa165552023440lgao else 184230fdf1140b8d1ce93f3821d986fa165552023440lgao { 184330fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 distance = p->reps[pos]; 184430fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); 184530fdf1140b8d1ce93f3821d986fa165552023440lgao if (pos == 1) 184630fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); 184730fdf1140b8d1ce93f3821d986fa165552023440lgao else 184830fdf1140b8d1ce93f3821d986fa165552023440lgao { 184930fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); 185030fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); 185130fdf1140b8d1ce93f3821d986fa165552023440lgao if (pos == 3) 185230fdf1140b8d1ce93f3821d986fa165552023440lgao p->reps[3] = p->reps[2]; 185330fdf1140b8d1ce93f3821d986fa165552023440lgao p->reps[2] = p->reps[1]; 185430fdf1140b8d1ce93f3821d986fa165552023440lgao } 185530fdf1140b8d1ce93f3821d986fa165552023440lgao p->reps[1] = p->reps[0]; 185630fdf1140b8d1ce93f3821d986fa165552023440lgao p->reps[0] = distance; 185730fdf1140b8d1ce93f3821d986fa165552023440lgao } 185830fdf1140b8d1ce93f3821d986fa165552023440lgao if (len == 1) 185930fdf1140b8d1ce93f3821d986fa165552023440lgao p->state = kShortRepNextStates[p->state]; 186030fdf1140b8d1ce93f3821d986fa165552023440lgao else 186130fdf1140b8d1ce93f3821d986fa165552023440lgao { 186230fdf1140b8d1ce93f3821d986fa165552023440lgao LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); 186330fdf1140b8d1ce93f3821d986fa165552023440lgao p->state = kRepNextStates[p->state]; 186430fdf1140b8d1ce93f3821d986fa165552023440lgao } 186530fdf1140b8d1ce93f3821d986fa165552023440lgao } 186630fdf1140b8d1ce93f3821d986fa165552023440lgao else 186730fdf1140b8d1ce93f3821d986fa165552023440lgao { 186830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 posSlot; 186930fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); 187030fdf1140b8d1ce93f3821d986fa165552023440lgao p->state = kMatchNextStates[p->state]; 187130fdf1140b8d1ce93f3821d986fa165552023440lgao LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); 187230fdf1140b8d1ce93f3821d986fa165552023440lgao pos -= LZMA_NUM_REPS; 187330fdf1140b8d1ce93f3821d986fa165552023440lgao GetPosSlot(pos, posSlot); 187430fdf1140b8d1ce93f3821d986fa165552023440lgao RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); 187530fdf1140b8d1ce93f3821d986fa165552023440lgao 187630fdf1140b8d1ce93f3821d986fa165552023440lgao if (posSlot >= kStartPosModelIndex) 187730fdf1140b8d1ce93f3821d986fa165552023440lgao { 187830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 footerBits = ((posSlot >> 1) - 1); 187930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 base = ((2 | (posSlot & 1)) << footerBits); 188030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 posReduced = pos - base; 188130fdf1140b8d1ce93f3821d986fa165552023440lgao 188230fdf1140b8d1ce93f3821d986fa165552023440lgao if (posSlot < kEndPosModelIndex) 188330fdf1140b8d1ce93f3821d986fa165552023440lgao RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); 188430fdf1140b8d1ce93f3821d986fa165552023440lgao else 188530fdf1140b8d1ce93f3821d986fa165552023440lgao { 188630fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); 188730fdf1140b8d1ce93f3821d986fa165552023440lgao RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); 188830fdf1140b8d1ce93f3821d986fa165552023440lgao p->alignPriceCount++; 188930fdf1140b8d1ce93f3821d986fa165552023440lgao } 189030fdf1140b8d1ce93f3821d986fa165552023440lgao } 189130fdf1140b8d1ce93f3821d986fa165552023440lgao p->reps[3] = p->reps[2]; 189230fdf1140b8d1ce93f3821d986fa165552023440lgao p->reps[2] = p->reps[1]; 189330fdf1140b8d1ce93f3821d986fa165552023440lgao p->reps[1] = p->reps[0]; 189430fdf1140b8d1ce93f3821d986fa165552023440lgao p->reps[0] = pos; 189530fdf1140b8d1ce93f3821d986fa165552023440lgao p->matchPriceCount++; 189630fdf1140b8d1ce93f3821d986fa165552023440lgao } 189730fdf1140b8d1ce93f3821d986fa165552023440lgao } 189830fdf1140b8d1ce93f3821d986fa165552023440lgao p->additionalOffset -= len; 189930fdf1140b8d1ce93f3821d986fa165552023440lgao nowPos32 += len; 190030fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->additionalOffset == 0) 190130fdf1140b8d1ce93f3821d986fa165552023440lgao { 190230fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 processed; 190330fdf1140b8d1ce93f3821d986fa165552023440lgao if (!p->fastMode) 190430fdf1140b8d1ce93f3821d986fa165552023440lgao { 190530fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->matchPriceCount >= (1 << 7)) 190630fdf1140b8d1ce93f3821d986fa165552023440lgao FillDistancesPrices(p); 190730fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->alignPriceCount >= kAlignTableSize) 190830fdf1140b8d1ce93f3821d986fa165552023440lgao FillAlignPrices(p); 190930fdf1140b8d1ce93f3821d986fa165552023440lgao } 191030fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) 191130fdf1140b8d1ce93f3821d986fa165552023440lgao break; 191230fdf1140b8d1ce93f3821d986fa165552023440lgao processed = nowPos32 - startPos32; 191330fdf1140b8d1ce93f3821d986fa165552023440lgao if (useLimits) 191430fdf1140b8d1ce93f3821d986fa165552023440lgao { 191530fdf1140b8d1ce93f3821d986fa165552023440lgao if (processed + kNumOpts + 300 >= maxUnpackSize || 191630fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) 191730fdf1140b8d1ce93f3821d986fa165552023440lgao break; 191830fdf1140b8d1ce93f3821d986fa165552023440lgao } 191930fdf1140b8d1ce93f3821d986fa165552023440lgao else if (processed >= (1 << 15)) 192030fdf1140b8d1ce93f3821d986fa165552023440lgao { 192130fdf1140b8d1ce93f3821d986fa165552023440lgao p->nowPos64 += nowPos32 - startPos32; 192230fdf1140b8d1ce93f3821d986fa165552023440lgao return CheckErrors(p); 192330fdf1140b8d1ce93f3821d986fa165552023440lgao } 192430fdf1140b8d1ce93f3821d986fa165552023440lgao } 192530fdf1140b8d1ce93f3821d986fa165552023440lgao } 192630fdf1140b8d1ce93f3821d986fa165552023440lgao p->nowPos64 += nowPos32 - startPos32; 192730fdf1140b8d1ce93f3821d986fa165552023440lgao return Flush(p, nowPos32); 192830fdf1140b8d1ce93f3821d986fa165552023440lgao} 192930fdf1140b8d1ce93f3821d986fa165552023440lgao 193030fdf1140b8d1ce93f3821d986fa165552023440lgao#define kBigHashDicLimit ((UInt32)1 << 24) 193130fdf1140b8d1ce93f3821d986fa165552023440lgao 193230fdf1140b8d1ce93f3821d986fa165552023440lgaostatic SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) 193330fdf1140b8d1ce93f3821d986fa165552023440lgao{ 193430fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 beforeSize = kNumOpts; 19350d2711a69397d2971079121df4326d84736c181elgao #ifdef COMPRESS_MF_MT 193630fdf1140b8d1ce93f3821d986fa165552023440lgao Bool btMode; 19370d2711a69397d2971079121df4326d84736c181elgao #endif 193830fdf1140b8d1ce93f3821d986fa165552023440lgao if (!RangeEnc_Alloc(&p->rc, alloc)) 193930fdf1140b8d1ce93f3821d986fa165552023440lgao return SZ_ERROR_MEM; 194030fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef COMPRESS_MF_MT 19410d2711a69397d2971079121df4326d84736c181elgao btMode = (p->matchFinderBase.btMode != 0); 194230fdf1140b8d1ce93f3821d986fa165552023440lgao p->mtMode = (p->multiThread && !p->fastMode && btMode); 194330fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 194430fdf1140b8d1ce93f3821d986fa165552023440lgao 194530fdf1140b8d1ce93f3821d986fa165552023440lgao { 194630fdf1140b8d1ce93f3821d986fa165552023440lgao unsigned lclp = p->lc + p->lp; 194730fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) 194830fdf1140b8d1ce93f3821d986fa165552023440lgao { 194930fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_FreeLits(p, alloc); 195030fdf1140b8d1ce93f3821d986fa165552023440lgao p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); 195130fdf1140b8d1ce93f3821d986fa165552023440lgao p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); 195230fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->litProbs == 0 || p->saveState.litProbs == 0) 195330fdf1140b8d1ce93f3821d986fa165552023440lgao { 195430fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_FreeLits(p, alloc); 195530fdf1140b8d1ce93f3821d986fa165552023440lgao return SZ_ERROR_MEM; 195630fdf1140b8d1ce93f3821d986fa165552023440lgao } 195730fdf1140b8d1ce93f3821d986fa165552023440lgao p->lclp = lclp; 195830fdf1140b8d1ce93f3821d986fa165552023440lgao } 195930fdf1140b8d1ce93f3821d986fa165552023440lgao } 196030fdf1140b8d1ce93f3821d986fa165552023440lgao 196130fdf1140b8d1ce93f3821d986fa165552023440lgao p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); 196230fdf1140b8d1ce93f3821d986fa165552023440lgao 196330fdf1140b8d1ce93f3821d986fa165552023440lgao if (beforeSize + p->dictSize < keepWindowSize) 196430fdf1140b8d1ce93f3821d986fa165552023440lgao beforeSize = keepWindowSize - p->dictSize; 196530fdf1140b8d1ce93f3821d986fa165552023440lgao 196630fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef COMPRESS_MF_MT 196730fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->mtMode) 196830fdf1140b8d1ce93f3821d986fa165552023440lgao { 196930fdf1140b8d1ce93f3821d986fa165552023440lgao RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)); 197030fdf1140b8d1ce93f3821d986fa165552023440lgao p->matchFinderObj = &p->matchFinderMt; 197130fdf1140b8d1ce93f3821d986fa165552023440lgao MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder); 197230fdf1140b8d1ce93f3821d986fa165552023440lgao } 197330fdf1140b8d1ce93f3821d986fa165552023440lgao else 197430fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 197530fdf1140b8d1ce93f3821d986fa165552023440lgao { 197630fdf1140b8d1ce93f3821d986fa165552023440lgao if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) 197730fdf1140b8d1ce93f3821d986fa165552023440lgao return SZ_ERROR_MEM; 197830fdf1140b8d1ce93f3821d986fa165552023440lgao p->matchFinderObj = &p->matchFinderBase; 197930fdf1140b8d1ce93f3821d986fa165552023440lgao MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); 198030fdf1140b8d1ce93f3821d986fa165552023440lgao } 198130fdf1140b8d1ce93f3821d986fa165552023440lgao return SZ_OK; 198230fdf1140b8d1ce93f3821d986fa165552023440lgao} 198330fdf1140b8d1ce93f3821d986fa165552023440lgao 198430fdf1140b8d1ce93f3821d986fa165552023440lgaovoid LzmaEnc_Init(CLzmaEnc *p) 198530fdf1140b8d1ce93f3821d986fa165552023440lgao{ 198630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 i; 198730fdf1140b8d1ce93f3821d986fa165552023440lgao p->state = 0; 198830fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0 ; i < LZMA_NUM_REPS; i++) 198930fdf1140b8d1ce93f3821d986fa165552023440lgao p->reps[i] = 0; 199030fdf1140b8d1ce93f3821d986fa165552023440lgao 199130fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_Init(&p->rc); 199230fdf1140b8d1ce93f3821d986fa165552023440lgao 199330fdf1140b8d1ce93f3821d986fa165552023440lgao 199430fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < kNumStates; i++) 199530fdf1140b8d1ce93f3821d986fa165552023440lgao { 199630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 j; 199730fdf1140b8d1ce93f3821d986fa165552023440lgao for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) 199830fdf1140b8d1ce93f3821d986fa165552023440lgao { 199930fdf1140b8d1ce93f3821d986fa165552023440lgao p->isMatch[i][j] = kProbInitValue; 200030fdf1140b8d1ce93f3821d986fa165552023440lgao p->isRep0Long[i][j] = kProbInitValue; 200130fdf1140b8d1ce93f3821d986fa165552023440lgao } 200230fdf1140b8d1ce93f3821d986fa165552023440lgao p->isRep[i] = kProbInitValue; 200330fdf1140b8d1ce93f3821d986fa165552023440lgao p->isRepG0[i] = kProbInitValue; 200430fdf1140b8d1ce93f3821d986fa165552023440lgao p->isRepG1[i] = kProbInitValue; 200530fdf1140b8d1ce93f3821d986fa165552023440lgao p->isRepG2[i] = kProbInitValue; 200630fdf1140b8d1ce93f3821d986fa165552023440lgao } 200730fdf1140b8d1ce93f3821d986fa165552023440lgao 200830fdf1140b8d1ce93f3821d986fa165552023440lgao { 200930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 num = 0x300 << (p->lp + p->lc); 201030fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < num; i++) 201130fdf1140b8d1ce93f3821d986fa165552023440lgao p->litProbs[i] = kProbInitValue; 201230fdf1140b8d1ce93f3821d986fa165552023440lgao } 201330fdf1140b8d1ce93f3821d986fa165552023440lgao 201430fdf1140b8d1ce93f3821d986fa165552023440lgao { 201530fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < kNumLenToPosStates; i++) 201630fdf1140b8d1ce93f3821d986fa165552023440lgao { 201730fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaProb *probs = p->posSlotEncoder[i]; 201830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 j; 201930fdf1140b8d1ce93f3821d986fa165552023440lgao for (j = 0; j < (1 << kNumPosSlotBits); j++) 202030fdf1140b8d1ce93f3821d986fa165552023440lgao probs[j] = kProbInitValue; 202130fdf1140b8d1ce93f3821d986fa165552023440lgao } 202230fdf1140b8d1ce93f3821d986fa165552023440lgao } 202330fdf1140b8d1ce93f3821d986fa165552023440lgao { 202430fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) 202530fdf1140b8d1ce93f3821d986fa165552023440lgao p->posEncoders[i] = kProbInitValue; 202630fdf1140b8d1ce93f3821d986fa165552023440lgao } 202730fdf1140b8d1ce93f3821d986fa165552023440lgao 202830fdf1140b8d1ce93f3821d986fa165552023440lgao LenEnc_Init(&p->lenEnc.p); 202930fdf1140b8d1ce93f3821d986fa165552023440lgao LenEnc_Init(&p->repLenEnc.p); 203030fdf1140b8d1ce93f3821d986fa165552023440lgao 203130fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < (1 << kNumAlignBits); i++) 203230fdf1140b8d1ce93f3821d986fa165552023440lgao p->posAlignEncoder[i] = kProbInitValue; 203330fdf1140b8d1ce93f3821d986fa165552023440lgao 203430fdf1140b8d1ce93f3821d986fa165552023440lgao p->optimumEndIndex = 0; 203530fdf1140b8d1ce93f3821d986fa165552023440lgao p->optimumCurrentIndex = 0; 203630fdf1140b8d1ce93f3821d986fa165552023440lgao p->additionalOffset = 0; 203730fdf1140b8d1ce93f3821d986fa165552023440lgao 203830fdf1140b8d1ce93f3821d986fa165552023440lgao p->pbMask = (1 << p->pb) - 1; 203930fdf1140b8d1ce93f3821d986fa165552023440lgao p->lpMask = (1 << p->lp) - 1; 204030fdf1140b8d1ce93f3821d986fa165552023440lgao} 204130fdf1140b8d1ce93f3821d986fa165552023440lgao 204230fdf1140b8d1ce93f3821d986fa165552023440lgaovoid LzmaEnc_InitPrices(CLzmaEnc *p) 204330fdf1140b8d1ce93f3821d986fa165552023440lgao{ 204430fdf1140b8d1ce93f3821d986fa165552023440lgao if (!p->fastMode) 204530fdf1140b8d1ce93f3821d986fa165552023440lgao { 204630fdf1140b8d1ce93f3821d986fa165552023440lgao FillDistancesPrices(p); 204730fdf1140b8d1ce93f3821d986fa165552023440lgao FillAlignPrices(p); 204830fdf1140b8d1ce93f3821d986fa165552023440lgao } 204930fdf1140b8d1ce93f3821d986fa165552023440lgao 205030fdf1140b8d1ce93f3821d986fa165552023440lgao p->lenEnc.tableSize = 205130fdf1140b8d1ce93f3821d986fa165552023440lgao p->repLenEnc.tableSize = 205230fdf1140b8d1ce93f3821d986fa165552023440lgao p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; 205330fdf1140b8d1ce93f3821d986fa165552023440lgao LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); 205430fdf1140b8d1ce93f3821d986fa165552023440lgao LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); 205530fdf1140b8d1ce93f3821d986fa165552023440lgao} 205630fdf1140b8d1ce93f3821d986fa165552023440lgao 205730fdf1140b8d1ce93f3821d986fa165552023440lgaostatic SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) 205830fdf1140b8d1ce93f3821d986fa165552023440lgao{ 205930fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 i; 206030fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) 206130fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->dictSize <= ((UInt32)1 << i)) 206230fdf1140b8d1ce93f3821d986fa165552023440lgao break; 206330fdf1140b8d1ce93f3821d986fa165552023440lgao p->distTableSize = i * 2; 206430fdf1140b8d1ce93f3821d986fa165552023440lgao 206530fdf1140b8d1ce93f3821d986fa165552023440lgao p->finished = False; 206630fdf1140b8d1ce93f3821d986fa165552023440lgao p->result = SZ_OK; 206730fdf1140b8d1ce93f3821d986fa165552023440lgao RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); 206830fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_Init(p); 206930fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_InitPrices(p); 207030fdf1140b8d1ce93f3821d986fa165552023440lgao p->nowPos64 = 0; 207130fdf1140b8d1ce93f3821d986fa165552023440lgao return SZ_OK; 207230fdf1140b8d1ce93f3821d986fa165552023440lgao} 207330fdf1140b8d1ce93f3821d986fa165552023440lgao 207430fdf1140b8d1ce93f3821d986fa165552023440lgaostatic SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream, 207530fdf1140b8d1ce93f3821d986fa165552023440lgao ISzAlloc *alloc, ISzAlloc *allocBig) 207630fdf1140b8d1ce93f3821d986fa165552023440lgao{ 207730fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEnc *p = (CLzmaEnc *)pp; 207830fdf1140b8d1ce93f3821d986fa165552023440lgao p->inStream = inStream; 207930fdf1140b8d1ce93f3821d986fa165552023440lgao p->rc.outStream = outStream; 208030fdf1140b8d1ce93f3821d986fa165552023440lgao return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); 208130fdf1140b8d1ce93f3821d986fa165552023440lgao} 208230fdf1140b8d1ce93f3821d986fa165552023440lgao 208330fdf1140b8d1ce93f3821d986fa165552023440lgaoSRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, 208430fdf1140b8d1ce93f3821d986fa165552023440lgao ISeqInStream *inStream, UInt32 keepWindowSize, 208530fdf1140b8d1ce93f3821d986fa165552023440lgao ISzAlloc *alloc, ISzAlloc *allocBig) 208630fdf1140b8d1ce93f3821d986fa165552023440lgao{ 208730fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEnc *p = (CLzmaEnc *)pp; 208830fdf1140b8d1ce93f3821d986fa165552023440lgao p->inStream = inStream; 208930fdf1140b8d1ce93f3821d986fa165552023440lgao return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); 209030fdf1140b8d1ce93f3821d986fa165552023440lgao} 209130fdf1140b8d1ce93f3821d986fa165552023440lgao 209230fdf1140b8d1ce93f3821d986fa165552023440lgaostatic void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) 209330fdf1140b8d1ce93f3821d986fa165552023440lgao{ 209430fdf1140b8d1ce93f3821d986fa165552023440lgao p->seqBufInStream.funcTable.Read = MyRead; 209530fdf1140b8d1ce93f3821d986fa165552023440lgao p->seqBufInStream.data = src; 209630fdf1140b8d1ce93f3821d986fa165552023440lgao p->seqBufInStream.rem = srcLen; 209730fdf1140b8d1ce93f3821d986fa165552023440lgao} 209830fdf1140b8d1ce93f3821d986fa165552023440lgao 209930fdf1140b8d1ce93f3821d986fa165552023440lgaoSRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, 210030fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) 210130fdf1140b8d1ce93f3821d986fa165552023440lgao{ 210230fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEnc *p = (CLzmaEnc *)pp; 210330fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_SetInputBuf(p, src, srcLen); 210430fdf1140b8d1ce93f3821d986fa165552023440lgao p->inStream = &p->seqBufInStream.funcTable; 210530fdf1140b8d1ce93f3821d986fa165552023440lgao return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); 210630fdf1140b8d1ce93f3821d986fa165552023440lgao} 210730fdf1140b8d1ce93f3821d986fa165552023440lgao 210830fdf1140b8d1ce93f3821d986fa165552023440lgaovoid LzmaEnc_Finish(CLzmaEncHandle pp) 210930fdf1140b8d1ce93f3821d986fa165552023440lgao{ 211030fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef COMPRESS_MF_MT 211130fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEnc *p = (CLzmaEnc *)pp; 211230fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->mtMode) 211330fdf1140b8d1ce93f3821d986fa165552023440lgao MatchFinderMt_ReleaseStream(&p->matchFinderMt); 211430fdf1140b8d1ce93f3821d986fa165552023440lgao #else 21155ddccf34c4f57e6e7fca767c1628a0d98ce8bdafBruce Cran (void)pp; 211630fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 211730fdf1140b8d1ce93f3821d986fa165552023440lgao} 211830fdf1140b8d1ce93f3821d986fa165552023440lgao 211930fdf1140b8d1ce93f3821d986fa165552023440lgaotypedef struct _CSeqOutStreamBuf 212030fdf1140b8d1ce93f3821d986fa165552023440lgao{ 212130fdf1140b8d1ce93f3821d986fa165552023440lgao ISeqOutStream funcTable; 212230fdf1140b8d1ce93f3821d986fa165552023440lgao Byte *data; 212330fdf1140b8d1ce93f3821d986fa165552023440lgao SizeT rem; 212430fdf1140b8d1ce93f3821d986fa165552023440lgao Bool overflow; 212530fdf1140b8d1ce93f3821d986fa165552023440lgao} CSeqOutStreamBuf; 212630fdf1140b8d1ce93f3821d986fa165552023440lgao 212730fdf1140b8d1ce93f3821d986fa165552023440lgaostatic size_t MyWrite(void *pp, const void *data, size_t size) 212830fdf1140b8d1ce93f3821d986fa165552023440lgao{ 212930fdf1140b8d1ce93f3821d986fa165552023440lgao CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; 213030fdf1140b8d1ce93f3821d986fa165552023440lgao if (p->rem < size) 213130fdf1140b8d1ce93f3821d986fa165552023440lgao { 213230fdf1140b8d1ce93f3821d986fa165552023440lgao size = p->rem; 213330fdf1140b8d1ce93f3821d986fa165552023440lgao p->overflow = True; 213430fdf1140b8d1ce93f3821d986fa165552023440lgao } 213530fdf1140b8d1ce93f3821d986fa165552023440lgao memcpy(p->data, data, size); 213630fdf1140b8d1ce93f3821d986fa165552023440lgao p->rem -= size; 213730fdf1140b8d1ce93f3821d986fa165552023440lgao p->data += size; 213830fdf1140b8d1ce93f3821d986fa165552023440lgao return size; 213930fdf1140b8d1ce93f3821d986fa165552023440lgao} 214030fdf1140b8d1ce93f3821d986fa165552023440lgao 214130fdf1140b8d1ce93f3821d986fa165552023440lgao 214230fdf1140b8d1ce93f3821d986fa165552023440lgaoUInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) 214330fdf1140b8d1ce93f3821d986fa165552023440lgao{ 214430fdf1140b8d1ce93f3821d986fa165552023440lgao const CLzmaEnc *p = (CLzmaEnc *)pp; 214530fdf1140b8d1ce93f3821d986fa165552023440lgao return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); 214630fdf1140b8d1ce93f3821d986fa165552023440lgao} 214730fdf1140b8d1ce93f3821d986fa165552023440lgao 214830fdf1140b8d1ce93f3821d986fa165552023440lgaoconst Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) 214930fdf1140b8d1ce93f3821d986fa165552023440lgao{ 215030fdf1140b8d1ce93f3821d986fa165552023440lgao const CLzmaEnc *p = (CLzmaEnc *)pp; 215130fdf1140b8d1ce93f3821d986fa165552023440lgao return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; 215230fdf1140b8d1ce93f3821d986fa165552023440lgao} 215330fdf1140b8d1ce93f3821d986fa165552023440lgao 215430fdf1140b8d1ce93f3821d986fa165552023440lgaoSRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, 215530fdf1140b8d1ce93f3821d986fa165552023440lgao Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) 215630fdf1140b8d1ce93f3821d986fa165552023440lgao{ 215730fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEnc *p = (CLzmaEnc *)pp; 215830fdf1140b8d1ce93f3821d986fa165552023440lgao UInt64 nowPos64; 215930fdf1140b8d1ce93f3821d986fa165552023440lgao SRes res; 216030fdf1140b8d1ce93f3821d986fa165552023440lgao CSeqOutStreamBuf outStream; 216130fdf1140b8d1ce93f3821d986fa165552023440lgao 216230fdf1140b8d1ce93f3821d986fa165552023440lgao outStream.funcTable.Write = MyWrite; 216330fdf1140b8d1ce93f3821d986fa165552023440lgao outStream.data = dest; 216430fdf1140b8d1ce93f3821d986fa165552023440lgao outStream.rem = *destLen; 216530fdf1140b8d1ce93f3821d986fa165552023440lgao outStream.overflow = False; 216630fdf1140b8d1ce93f3821d986fa165552023440lgao 216730fdf1140b8d1ce93f3821d986fa165552023440lgao p->writeEndMark = False; 216830fdf1140b8d1ce93f3821d986fa165552023440lgao p->finished = False; 216930fdf1140b8d1ce93f3821d986fa165552023440lgao p->result = SZ_OK; 217030fdf1140b8d1ce93f3821d986fa165552023440lgao 217130fdf1140b8d1ce93f3821d986fa165552023440lgao if (reInit) 217230fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_Init(p); 217330fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_InitPrices(p); 217430fdf1140b8d1ce93f3821d986fa165552023440lgao nowPos64 = p->nowPos64; 217530fdf1140b8d1ce93f3821d986fa165552023440lgao RangeEnc_Init(&p->rc); 217630fdf1140b8d1ce93f3821d986fa165552023440lgao p->rc.outStream = &outStream.funcTable; 217730fdf1140b8d1ce93f3821d986fa165552023440lgao 217830fdf1140b8d1ce93f3821d986fa165552023440lgao res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize); 217930fdf1140b8d1ce93f3821d986fa165552023440lgao 218030fdf1140b8d1ce93f3821d986fa165552023440lgao *unpackSize = (UInt32)(p->nowPos64 - nowPos64); 218130fdf1140b8d1ce93f3821d986fa165552023440lgao *destLen -= outStream.rem; 218230fdf1140b8d1ce93f3821d986fa165552023440lgao if (outStream.overflow) 218330fdf1140b8d1ce93f3821d986fa165552023440lgao return SZ_ERROR_OUTPUT_EOF; 218430fdf1140b8d1ce93f3821d986fa165552023440lgao 218530fdf1140b8d1ce93f3821d986fa165552023440lgao return res; 218630fdf1140b8d1ce93f3821d986fa165552023440lgao} 218730fdf1140b8d1ce93f3821d986fa165552023440lgao 218830fdf1140b8d1ce93f3821d986fa165552023440lgaoSRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, 218930fdf1140b8d1ce93f3821d986fa165552023440lgao ISzAlloc *alloc, ISzAlloc *allocBig) 219030fdf1140b8d1ce93f3821d986fa165552023440lgao{ 219130fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEnc *p = (CLzmaEnc *)pp; 219230fdf1140b8d1ce93f3821d986fa165552023440lgao SRes res = SZ_OK; 219330fdf1140b8d1ce93f3821d986fa165552023440lgao 219430fdf1140b8d1ce93f3821d986fa165552023440lgao #ifdef COMPRESS_MF_MT 219530fdf1140b8d1ce93f3821d986fa165552023440lgao Byte allocaDummy[0x300]; 219630fdf1140b8d1ce93f3821d986fa165552023440lgao int i = 0; 219730fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < 16; i++) 219830fdf1140b8d1ce93f3821d986fa165552023440lgao allocaDummy[i] = (Byte)i; 219930fdf1140b8d1ce93f3821d986fa165552023440lgao #endif 220030fdf1140b8d1ce93f3821d986fa165552023440lgao 220130fdf1140b8d1ce93f3821d986fa165552023440lgao RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig)); 220230fdf1140b8d1ce93f3821d986fa165552023440lgao 220330fdf1140b8d1ce93f3821d986fa165552023440lgao for (;;) 220430fdf1140b8d1ce93f3821d986fa165552023440lgao { 220530fdf1140b8d1ce93f3821d986fa165552023440lgao res = LzmaEnc_CodeOneBlock(p, False, 0, 0); 220630fdf1140b8d1ce93f3821d986fa165552023440lgao if (res != SZ_OK || p->finished != 0) 220730fdf1140b8d1ce93f3821d986fa165552023440lgao break; 220830fdf1140b8d1ce93f3821d986fa165552023440lgao if (progress != 0) 220930fdf1140b8d1ce93f3821d986fa165552023440lgao { 221030fdf1140b8d1ce93f3821d986fa165552023440lgao res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); 221130fdf1140b8d1ce93f3821d986fa165552023440lgao if (res != SZ_OK) 221230fdf1140b8d1ce93f3821d986fa165552023440lgao { 221330fdf1140b8d1ce93f3821d986fa165552023440lgao res = SZ_ERROR_PROGRESS; 221430fdf1140b8d1ce93f3821d986fa165552023440lgao break; 221530fdf1140b8d1ce93f3821d986fa165552023440lgao } 221630fdf1140b8d1ce93f3821d986fa165552023440lgao } 221730fdf1140b8d1ce93f3821d986fa165552023440lgao } 221830fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_Finish(pp); 221930fdf1140b8d1ce93f3821d986fa165552023440lgao return res; 222030fdf1140b8d1ce93f3821d986fa165552023440lgao} 222130fdf1140b8d1ce93f3821d986fa165552023440lgao 222230fdf1140b8d1ce93f3821d986fa165552023440lgaoSRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) 222330fdf1140b8d1ce93f3821d986fa165552023440lgao{ 222430fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEnc *p = (CLzmaEnc *)pp; 222530fdf1140b8d1ce93f3821d986fa165552023440lgao int i; 222630fdf1140b8d1ce93f3821d986fa165552023440lgao UInt32 dictSize = p->dictSize; 222730fdf1140b8d1ce93f3821d986fa165552023440lgao if (*size < LZMA_PROPS_SIZE) 222830fdf1140b8d1ce93f3821d986fa165552023440lgao return SZ_ERROR_PARAM; 222930fdf1140b8d1ce93f3821d986fa165552023440lgao *size = LZMA_PROPS_SIZE; 223030fdf1140b8d1ce93f3821d986fa165552023440lgao props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); 223130fdf1140b8d1ce93f3821d986fa165552023440lgao 223230fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 11; i <= 30; i++) 223330fdf1140b8d1ce93f3821d986fa165552023440lgao { 223430fdf1140b8d1ce93f3821d986fa165552023440lgao if (dictSize <= ((UInt32)2 << i)) 223530fdf1140b8d1ce93f3821d986fa165552023440lgao { 223630fdf1140b8d1ce93f3821d986fa165552023440lgao dictSize = (2 << i); 223730fdf1140b8d1ce93f3821d986fa165552023440lgao break; 223830fdf1140b8d1ce93f3821d986fa165552023440lgao } 223930fdf1140b8d1ce93f3821d986fa165552023440lgao if (dictSize <= ((UInt32)3 << i)) 224030fdf1140b8d1ce93f3821d986fa165552023440lgao { 224130fdf1140b8d1ce93f3821d986fa165552023440lgao dictSize = (3 << i); 224230fdf1140b8d1ce93f3821d986fa165552023440lgao break; 224330fdf1140b8d1ce93f3821d986fa165552023440lgao } 224430fdf1140b8d1ce93f3821d986fa165552023440lgao } 224530fdf1140b8d1ce93f3821d986fa165552023440lgao 224630fdf1140b8d1ce93f3821d986fa165552023440lgao for (i = 0; i < 4; i++) 224730fdf1140b8d1ce93f3821d986fa165552023440lgao props[1 + i] = (Byte)(dictSize >> (8 * i)); 224830fdf1140b8d1ce93f3821d986fa165552023440lgao return SZ_OK; 224930fdf1140b8d1ce93f3821d986fa165552023440lgao} 225030fdf1140b8d1ce93f3821d986fa165552023440lgao 225130fdf1140b8d1ce93f3821d986fa165552023440lgaoSRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, 225230fdf1140b8d1ce93f3821d986fa165552023440lgao int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) 225330fdf1140b8d1ce93f3821d986fa165552023440lgao{ 225430fdf1140b8d1ce93f3821d986fa165552023440lgao SRes res; 225530fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEnc *p = (CLzmaEnc *)pp; 225630fdf1140b8d1ce93f3821d986fa165552023440lgao 225730fdf1140b8d1ce93f3821d986fa165552023440lgao CSeqOutStreamBuf outStream; 225830fdf1140b8d1ce93f3821d986fa165552023440lgao 225930fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_SetInputBuf(p, src, srcLen); 226030fdf1140b8d1ce93f3821d986fa165552023440lgao 226130fdf1140b8d1ce93f3821d986fa165552023440lgao outStream.funcTable.Write = MyWrite; 226230fdf1140b8d1ce93f3821d986fa165552023440lgao outStream.data = dest; 226330fdf1140b8d1ce93f3821d986fa165552023440lgao outStream.rem = *destLen; 226430fdf1140b8d1ce93f3821d986fa165552023440lgao outStream.overflow = False; 226530fdf1140b8d1ce93f3821d986fa165552023440lgao 226630fdf1140b8d1ce93f3821d986fa165552023440lgao p->writeEndMark = writeEndMark; 226730fdf1140b8d1ce93f3821d986fa165552023440lgao res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable, 226830fdf1140b8d1ce93f3821d986fa165552023440lgao progress, alloc, allocBig); 226930fdf1140b8d1ce93f3821d986fa165552023440lgao 227030fdf1140b8d1ce93f3821d986fa165552023440lgao *destLen -= outStream.rem; 227130fdf1140b8d1ce93f3821d986fa165552023440lgao if (outStream.overflow) 227230fdf1140b8d1ce93f3821d986fa165552023440lgao return SZ_ERROR_OUTPUT_EOF; 227330fdf1140b8d1ce93f3821d986fa165552023440lgao return res; 227430fdf1140b8d1ce93f3821d986fa165552023440lgao} 227530fdf1140b8d1ce93f3821d986fa165552023440lgao 227630fdf1140b8d1ce93f3821d986fa165552023440lgaoSRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, 227730fdf1140b8d1ce93f3821d986fa165552023440lgao const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, 227830fdf1140b8d1ce93f3821d986fa165552023440lgao ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) 227930fdf1140b8d1ce93f3821d986fa165552023440lgao{ 228030fdf1140b8d1ce93f3821d986fa165552023440lgao CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); 228130fdf1140b8d1ce93f3821d986fa165552023440lgao SRes res; 228230fdf1140b8d1ce93f3821d986fa165552023440lgao if (p == 0) 228330fdf1140b8d1ce93f3821d986fa165552023440lgao return SZ_ERROR_MEM; 228430fdf1140b8d1ce93f3821d986fa165552023440lgao 228530fdf1140b8d1ce93f3821d986fa165552023440lgao res = LzmaEnc_SetProps(p, props); 228630fdf1140b8d1ce93f3821d986fa165552023440lgao if (res == SZ_OK) 228730fdf1140b8d1ce93f3821d986fa165552023440lgao { 228830fdf1140b8d1ce93f3821d986fa165552023440lgao res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); 228930fdf1140b8d1ce93f3821d986fa165552023440lgao if (res == SZ_OK) 229030fdf1140b8d1ce93f3821d986fa165552023440lgao res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, 229130fdf1140b8d1ce93f3821d986fa165552023440lgao writeEndMark, progress, alloc, allocBig); 229230fdf1140b8d1ce93f3821d986fa165552023440lgao } 229330fdf1140b8d1ce93f3821d986fa165552023440lgao 229430fdf1140b8d1ce93f3821d986fa165552023440lgao LzmaEnc_Destroy(p, alloc, allocBig); 229530fdf1140b8d1ce93f3821d986fa165552023440lgao return res; 229630fdf1140b8d1ce93f3821d986fa165552023440lgao} 2297