LzmaEnc.c 82 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150
  1. /* LzmaEnc.c -- LZMA Encoder
  2. Igor Pavlov : Public domain */
  3. #include "Precomp.h"
  4. #include <string.h>
  5. /* #define SHOW_STAT */
  6. /* #define SHOW_STAT2 */
  7. #if defined(SHOW_STAT) || defined(SHOW_STAT2)
  8. #include <stdio.h>
  9. #endif
  10. #include "CpuArch.h"
  11. #include "LzmaEnc.h"
  12. #include "LzFind.h"
  13. #ifndef Z7_ST
  14. #include "LzFindMt.h"
  15. #endif
  16. /* the following LzmaEnc_* declarations is internal LZMA interface for LZMA2 encoder */
  17. SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p, ISeqInStreamPtr inStream, UInt32 keepWindowSize,
  18. ISzAllocPtr alloc, ISzAllocPtr allocBig);
  19. SRes LzmaEnc_MemPrepare(CLzmaEncHandle p, const Byte *src, SizeT srcLen,
  20. UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig);
  21. SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit,
  22. Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize);
  23. const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p);
  24. void LzmaEnc_Finish(CLzmaEncHandle p);
  25. void LzmaEnc_SaveState(CLzmaEncHandle p);
  26. void LzmaEnc_RestoreState(CLzmaEncHandle p);
  27. #ifdef SHOW_STAT
  28. static unsigned g_STAT_OFFSET = 0;
  29. #endif
  30. /* for good normalization speed we still reserve 256 MB before 4 GB range */
  31. #define kLzmaMaxHistorySize ((UInt32)15 << 28)
  32. // #define kNumTopBits 24
  33. #define kTopValue ((UInt32)1 << 24)
  34. #define kNumBitModelTotalBits 11
  35. #define kBitModelTotal (1 << kNumBitModelTotalBits)
  36. #define kNumMoveBits 5
  37. #define kProbInitValue (kBitModelTotal >> 1)
  38. #define kNumMoveReducingBits 4
  39. #define kNumBitPriceShiftBits 4
  40. // #define kBitPrice (1 << kNumBitPriceShiftBits)
  41. #define REP_LEN_COUNT 64
  42. void LzmaEncProps_Init(CLzmaEncProps *p)
  43. {
  44. p->level = 5;
  45. p->dictSize = p->mc = 0;
  46. p->reduceSize = (UInt64)(Int64)-1;
  47. p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
  48. p->numHashOutBits = 0;
  49. p->writeEndMark = 0;
  50. p->affinityGroup = -1;
  51. p->affinity = 0;
  52. p->affinityInGroup = 0;
  53. }
  54. void LzmaEncProps_Normalize(CLzmaEncProps *p)
  55. {
  56. int level = p->level;
  57. if (level < 0) level = 5;
  58. p->level = level;
  59. if (p->dictSize == 0)
  60. p->dictSize = (unsigned)level <= 4 ?
  61. (UInt32)1 << (level * 2 + 16) :
  62. (unsigned)level <= sizeof(size_t) / 2 + 4 ?
  63. (UInt32)1 << (level + 20) :
  64. (UInt32)1 << (sizeof(size_t) / 2 + 24);
  65. if (p->dictSize > p->reduceSize)
  66. {
  67. UInt32 v = (UInt32)p->reduceSize;
  68. const UInt32 kReduceMin = ((UInt32)1 << 12);
  69. if (v < kReduceMin)
  70. v = kReduceMin;
  71. if (p->dictSize > v)
  72. p->dictSize = v;
  73. }
  74. if (p->lc < 0) p->lc = 3;
  75. if (p->lp < 0) p->lp = 0;
  76. if (p->pb < 0) p->pb = 2;
  77. if (p->algo < 0) p->algo = (unsigned)level < 5 ? 0 : 1;
  78. if (p->fb < 0) p->fb = (unsigned)level < 7 ? 32 : 64;
  79. if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
  80. if (p->numHashBytes < 0) p->numHashBytes = (p->btMode ? 4 : 5);
  81. if (p->mc == 0) p->mc = (16 + ((unsigned)p->fb >> 1)) >> (p->btMode ? 0 : 1);
  82. if (p->numThreads < 0)
  83. p->numThreads =
  84. #ifndef Z7_ST
  85. ((p->btMode && p->algo) ? 2 : 1);
  86. #else
  87. 1;
  88. #endif
  89. }
  90. UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
  91. {
  92. CLzmaEncProps props = *props2;
  93. LzmaEncProps_Normalize(&props);
  94. return props.dictSize;
  95. }
  96. /*
  97. x86/x64:
  98. BSR:
  99. IF (SRC == 0) ZF = 1, DEST is undefined;
  100. AMD : DEST is unchanged;
  101. IF (SRC != 0) ZF = 0; DEST is index of top non-zero bit
  102. BSR is slow in some processors
  103. LZCNT:
  104. IF (SRC == 0) CF = 1, DEST is size_in_bits_of_register(src) (32 or 64)
  105. IF (SRC != 0) CF = 0, DEST = num_lead_zero_bits
  106. IF (DEST == 0) ZF = 1;
  107. LZCNT works only in new processors starting from Haswell.
  108. if LZCNT is not supported by processor, then it's executed as BSR.
  109. LZCNT can be faster than BSR, if supported.
  110. */
  111. // #define LZMA_LOG_BSR
  112. #if defined(MY_CPU_ARM_OR_ARM64) /* || defined(MY_CPU_X86_OR_AMD64) */
  113. #if (defined(__clang__) && (__clang_major__ >= 6)) \
  114. || (defined(__GNUC__) && (__GNUC__ >= 6))
  115. #define LZMA_LOG_BSR
  116. #elif defined(_MSC_VER) && (_MSC_VER >= 1300)
  117. // #if defined(MY_CPU_ARM_OR_ARM64)
  118. #define LZMA_LOG_BSR
  119. // #endif
  120. #endif
  121. #endif
  122. // #include <intrin.h>
  123. #ifdef LZMA_LOG_BSR
  124. #if defined(__clang__) \
  125. || defined(__GNUC__)
  126. /*
  127. C code: : (30 - __builtin_clz(x))
  128. gcc9/gcc10 for x64 /x86 : 30 - (bsr(x) xor 31)
  129. clang10 for x64 : 31 + (bsr(x) xor -32)
  130. */
  131. #define MY_clz(x) ((unsigned)__builtin_clz(x))
  132. // __lzcnt32
  133. // __builtin_ia32_lzcnt_u32
  134. #else // #if defined(_MSC_VER)
  135. #ifdef MY_CPU_ARM_OR_ARM64
  136. #define MY_clz _CountLeadingZeros
  137. #else // if defined(MY_CPU_X86_OR_AMD64)
  138. // #define MY_clz __lzcnt // we can use lzcnt (unsupported by old CPU)
  139. // _BitScanReverse code is not optimal for some MSVC compilers
  140. #define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); zz--; \
  141. res = (zz + zz) + (pos >> zz); }
  142. #endif // MY_CPU_X86_OR_AMD64
  143. #endif // _MSC_VER
  144. #ifndef BSR2_RET
  145. #define BSR2_RET(pos, res) { unsigned zz = 30 - MY_clz(pos); \
  146. res = (zz + zz) + (pos >> zz); }
  147. #endif
  148. unsigned GetPosSlot1(UInt32 pos);
  149. unsigned GetPosSlot1(UInt32 pos)
  150. {
  151. unsigned res;
  152. BSR2_RET(pos, res)
  153. return res;
  154. }
  155. #define GetPosSlot2(pos, res) { BSR2_RET(pos, res) }
  156. #define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res) }
  157. #else // ! LZMA_LOG_BSR
  158. #define kNumLogBits (11 + sizeof(size_t) / 8 * 3)
  159. #define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
  160. static void LzmaEnc_FastPosInit(Byte *g_FastPos)
  161. {
  162. unsigned slot;
  163. g_FastPos[0] = 0;
  164. g_FastPos[1] = 1;
  165. g_FastPos += 2;
  166. for (slot = 2; slot < kNumLogBits * 2; slot++)
  167. {
  168. size_t k = ((size_t)1 << ((slot >> 1) - 1));
  169. size_t j;
  170. for (j = 0; j < k; j++)
  171. g_FastPos[j] = (Byte)slot;
  172. g_FastPos += k;
  173. }
  174. }
  175. /* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */
  176. /*
  177. #define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \
  178. (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
  179. res = p->g_FastPos[pos >> zz] + (zz * 2); }
  180. */
  181. /*
  182. #define BSR2_RET(pos, res) { unsigned zz = 6 + ((kNumLogBits - 1) & \
  183. (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \
  184. res = p->g_FastPos[pos >> zz] + (zz * 2); }
  185. */
  186. #define BSR2_RET(pos, res) { unsigned zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \
  187. res = p->g_FastPos[pos >> zz] + (zz * 2); }
  188. /*
  189. #define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
  190. p->g_FastPos[pos >> 6] + 12 : \
  191. p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
  192. */
  193. #define GetPosSlot1(pos) p->g_FastPos[pos]
  194. #define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
  195. #define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos & (kNumFullDistances - 1)]; else BSR2_RET(pos, res); }
  196. #endif // LZMA_LOG_BSR
  197. #define LZMA_NUM_REPS 4
  198. typedef UInt16 CState;
  199. typedef UInt16 CExtra;
  200. typedef struct
  201. {
  202. UInt32 price;
  203. CState state;
  204. CExtra extra;
  205. // 0 : normal
  206. // 1 : LIT : MATCH
  207. // > 1 : MATCH (extra-1) : LIT : REP0 (len)
  208. UInt32 len;
  209. UInt32 dist;
  210. UInt32 reps[LZMA_NUM_REPS];
  211. } COptimal;
  212. // 18.06
  213. #define kNumOpts (1 << 11)
  214. #define kPackReserve (kNumOpts * 8)
  215. // #define kNumOpts (1 << 12)
  216. // #define kPackReserve (1 + kNumOpts * 2)
  217. #define kNumLenToPosStates 4
  218. #define kNumPosSlotBits 6
  219. // #define kDicLogSizeMin 0
  220. #define kDicLogSizeMax 32
  221. #define kDistTableSizeMax (kDicLogSizeMax * 2)
  222. #define kNumAlignBits 4
  223. #define kAlignTableSize (1 << kNumAlignBits)
  224. #define kAlignMask (kAlignTableSize - 1)
  225. #define kStartPosModelIndex 4
  226. #define kEndPosModelIndex 14
  227. #define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
  228. typedef
  229. #ifdef Z7_LZMA_PROB32
  230. UInt32
  231. #else
  232. UInt16
  233. #endif
  234. CLzmaProb;
  235. #define LZMA_PB_MAX 4
  236. #define LZMA_LC_MAX 8
  237. #define LZMA_LP_MAX 4
  238. #define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
  239. #define kLenNumLowBits 3
  240. #define kLenNumLowSymbols (1 << kLenNumLowBits)
  241. #define kLenNumHighBits 8
  242. #define kLenNumHighSymbols (1 << kLenNumHighBits)
  243. #define kLenNumSymbolsTotal (kLenNumLowSymbols * 2 + kLenNumHighSymbols)
  244. #define LZMA_MATCH_LEN_MIN 2
  245. #define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
  246. #define kNumStates 12
  247. typedef struct
  248. {
  249. CLzmaProb low[LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)];
  250. CLzmaProb high[kLenNumHighSymbols];
  251. } CLenEnc;
  252. typedef struct
  253. {
  254. unsigned tableSize;
  255. UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
  256. // UInt32 prices1[LZMA_NUM_PB_STATES_MAX][kLenNumLowSymbols * 2];
  257. // UInt32 prices2[kLenNumSymbolsTotal];
  258. } CLenPriceEnc;
  259. #define GET_PRICE_LEN(p, posState, len) \
  260. ((p)->prices[posState][(size_t)(len) - LZMA_MATCH_LEN_MIN])
  261. /*
  262. #define GET_PRICE_LEN(p, posState, len) \
  263. ((p)->prices2[(size_t)(len) - 2] + ((p)->prices1[posState][((len) - 2) & (kLenNumLowSymbols * 2 - 1)] & (((len) - 2 - kLenNumLowSymbols * 2) >> 9)))
  264. */
  265. typedef struct
  266. {
  267. UInt32 range;
  268. unsigned cache;
  269. UInt64 low;
  270. UInt64 cacheSize;
  271. Byte *buf;
  272. Byte *bufLim;
  273. Byte *bufBase;
  274. ISeqOutStreamPtr outStream;
  275. UInt64 processed;
  276. SRes res;
  277. } CRangeEnc;
  278. typedef struct
  279. {
  280. CLzmaProb *litProbs;
  281. unsigned state;
  282. UInt32 reps[LZMA_NUM_REPS];
  283. CLzmaProb posAlignEncoder[1 << kNumAlignBits];
  284. CLzmaProb isRep[kNumStates];
  285. CLzmaProb isRepG0[kNumStates];
  286. CLzmaProb isRepG1[kNumStates];
  287. CLzmaProb isRepG2[kNumStates];
  288. CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
  289. CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
  290. CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
  291. CLzmaProb posEncoders[kNumFullDistances];
  292. CLenEnc lenProbs;
  293. CLenEnc repLenProbs;
  294. } CSaveState;
  295. typedef UInt32 CProbPrice;
  296. struct CLzmaEnc
  297. {
  298. void *matchFinderObj;
  299. IMatchFinder2 matchFinder;
  300. unsigned optCur;
  301. unsigned optEnd;
  302. unsigned longestMatchLen;
  303. unsigned numPairs;
  304. UInt32 numAvail;
  305. unsigned state;
  306. unsigned numFastBytes;
  307. unsigned additionalOffset;
  308. UInt32 reps[LZMA_NUM_REPS];
  309. unsigned lpMask, pbMask;
  310. CLzmaProb *litProbs;
  311. CRangeEnc rc;
  312. UInt32 backRes;
  313. unsigned lc, lp, pb;
  314. unsigned lclp;
  315. BoolInt fastMode;
  316. BoolInt writeEndMark;
  317. BoolInt finished;
  318. BoolInt multiThread;
  319. BoolInt needInit;
  320. // BoolInt _maxMode;
  321. UInt64 nowPos64;
  322. unsigned matchPriceCount;
  323. // unsigned alignPriceCount;
  324. int repLenEncCounter;
  325. unsigned distTableSize;
  326. UInt32 dictSize;
  327. SRes result;
  328. #ifndef Z7_ST
  329. BoolInt mtMode;
  330. // begin of CMatchFinderMt is used in LZ thread
  331. CMatchFinderMt matchFinderMt;
  332. // end of CMatchFinderMt is used in BT and HASH threads
  333. // #else
  334. // CMatchFinder matchFinderBase;
  335. #endif
  336. CMatchFinder matchFinderBase;
  337. // we suppose that we have 8-bytes alignment after CMatchFinder
  338. #ifndef Z7_ST
  339. Byte pad[128];
  340. #endif
  341. // LZ thread
  342. CProbPrice ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
  343. // we want {len , dist} pairs to be 8-bytes aligned in matches array
  344. UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2];
  345. // we want 8-bytes alignment here
  346. UInt32 alignPrices[kAlignTableSize];
  347. UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
  348. UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
  349. CLzmaProb posAlignEncoder[1 << kNumAlignBits];
  350. CLzmaProb isRep[kNumStates];
  351. CLzmaProb isRepG0[kNumStates];
  352. CLzmaProb isRepG1[kNumStates];
  353. CLzmaProb isRepG2[kNumStates];
  354. CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
  355. CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
  356. CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
  357. CLzmaProb posEncoders[kNumFullDistances];
  358. CLenEnc lenProbs;
  359. CLenEnc repLenProbs;
  360. #ifndef LZMA_LOG_BSR
  361. Byte g_FastPos[1 << kNumLogBits];
  362. #endif
  363. CLenPriceEnc lenEnc;
  364. CLenPriceEnc repLenEnc;
  365. COptimal opt[kNumOpts];
  366. CSaveState saveState;
  367. // BoolInt mf_Failure;
  368. #ifndef Z7_ST
  369. Byte pad2[128];
  370. #endif
  371. };
  372. #define MFB (p->matchFinderBase)
  373. /*
  374. #ifndef Z7_ST
  375. #define MFB (p->matchFinderMt.MatchFinder)
  376. #endif
  377. */
  378. // #define GET_CLzmaEnc_p CLzmaEnc *p = (CLzmaEnc*)(void *)p;
  379. // #define GET_const_CLzmaEnc_p const CLzmaEnc *p = (const CLzmaEnc*)(const void *)p;
  380. #define COPY_ARR(dest, src, arr) memcpy((dest)->arr, (src)->arr, sizeof((src)->arr));
  381. #define COPY_LZMA_ENC_STATE(d, s, p) \
  382. (d)->state = (s)->state; \
  383. COPY_ARR(d, s, reps) \
  384. COPY_ARR(d, s, posAlignEncoder) \
  385. COPY_ARR(d, s, isRep) \
  386. COPY_ARR(d, s, isRepG0) \
  387. COPY_ARR(d, s, isRepG1) \
  388. COPY_ARR(d, s, isRepG2) \
  389. COPY_ARR(d, s, isMatch) \
  390. COPY_ARR(d, s, isRep0Long) \
  391. COPY_ARR(d, s, posSlotEncoder) \
  392. COPY_ARR(d, s, posEncoders) \
  393. (d)->lenProbs = (s)->lenProbs; \
  394. (d)->repLenProbs = (s)->repLenProbs; \
  395. memcpy((d)->litProbs, (s)->litProbs, ((size_t)0x300 * sizeof(CLzmaProb)) << (p)->lclp);
  396. void LzmaEnc_SaveState(CLzmaEncHandle p)
  397. {
  398. // GET_CLzmaEnc_p
  399. CSaveState *v = &p->saveState;
  400. COPY_LZMA_ENC_STATE(v, p, p)
  401. }
  402. void LzmaEnc_RestoreState(CLzmaEncHandle p)
  403. {
  404. // GET_CLzmaEnc_p
  405. const CSaveState *v = &p->saveState;
  406. COPY_LZMA_ENC_STATE(p, v, p)
  407. }
  408. Z7_NO_INLINE
  409. SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props2)
  410. {
  411. // GET_CLzmaEnc_p
  412. CLzmaEncProps props = *props2;
  413. LzmaEncProps_Normalize(&props);
  414. if (props.lc > LZMA_LC_MAX
  415. || props.lp > LZMA_LP_MAX
  416. || props.pb > LZMA_PB_MAX)
  417. return SZ_ERROR_PARAM;
  418. if (props.dictSize > kLzmaMaxHistorySize)
  419. props.dictSize = kLzmaMaxHistorySize;
  420. #ifndef LZMA_LOG_BSR
  421. {
  422. const UInt64 dict64 = props.dictSize;
  423. if (dict64 > ((UInt64)1 << kDicLogSizeMaxCompress))
  424. return SZ_ERROR_PARAM;
  425. }
  426. #endif
  427. p->dictSize = props.dictSize;
  428. {
  429. unsigned fb = (unsigned)props.fb;
  430. if (fb < 5)
  431. fb = 5;
  432. if (fb > LZMA_MATCH_LEN_MAX)
  433. fb = LZMA_MATCH_LEN_MAX;
  434. p->numFastBytes = fb;
  435. }
  436. p->lc = (unsigned)props.lc;
  437. p->lp = (unsigned)props.lp;
  438. p->pb = (unsigned)props.pb;
  439. p->fastMode = (props.algo == 0);
  440. // p->_maxMode = True;
  441. MFB.btMode = (Byte)(props.btMode ? 1 : 0);
  442. // MFB.btMode = (Byte)(props.btMode);
  443. {
  444. unsigned numHashBytes = 4;
  445. if (props.btMode)
  446. {
  447. if (props.numHashBytes < 2) numHashBytes = 2;
  448. else if (props.numHashBytes < 4) numHashBytes = (unsigned)props.numHashBytes;
  449. }
  450. if (props.numHashBytes >= 5) numHashBytes = 5;
  451. MFB.numHashBytes = numHashBytes;
  452. // MFB.numHashBytes_Min = 2;
  453. MFB.numHashOutBits = (Byte)props.numHashOutBits;
  454. }
  455. MFB.cutValue = props.mc;
  456. p->writeEndMark = (BoolInt)props.writeEndMark;
  457. #ifndef Z7_ST
  458. /*
  459. if (newMultiThread != _multiThread)
  460. {
  461. ReleaseMatchFinder();
  462. _multiThread = newMultiThread;
  463. }
  464. */
  465. p->multiThread = (props.numThreads > 1);
  466. p->matchFinderMt.btSync.affinity =
  467. p->matchFinderMt.hashSync.affinity = props.affinity;
  468. p->matchFinderMt.btSync.affinityGroup =
  469. p->matchFinderMt.hashSync.affinityGroup = props.affinityGroup;
  470. p->matchFinderMt.btSync.affinityInGroup =
  471. p->matchFinderMt.hashSync.affinityInGroup = props.affinityInGroup;
  472. #endif
  473. return SZ_OK;
  474. }
  475. void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize)
  476. {
  477. // GET_CLzmaEnc_p
  478. MFB.expectedDataSize = expectedDataSiize;
  479. }
  480. #define kState_Start 0
  481. #define kState_LitAfterMatch 4
  482. #define kState_LitAfterRep 5
  483. #define kState_MatchAfterLit 7
  484. #define kState_RepAfterLit 8
  485. static const Byte kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
  486. static const Byte kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
  487. static const Byte kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
  488. static const Byte kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
  489. #define IsLitState(s) ((s) < 7)
  490. #define GetLenToPosState2(len) (((len) < kNumLenToPosStates - 1) ? (len) : kNumLenToPosStates - 1)
  491. #define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
  492. #define kInfinityPrice (1 << 30)
  493. static void RangeEnc_Construct(CRangeEnc *p)
  494. {
  495. p->outStream = NULL;
  496. p->bufBase = NULL;
  497. }
  498. #define RangeEnc_GetProcessed(p) ( (p)->processed + (size_t)((p)->buf - (p)->bufBase) + (p)->cacheSize)
  499. #define RangeEnc_GetProcessed_sizet(p) ((size_t)(p)->processed + (size_t)((p)->buf - (p)->bufBase) + (size_t)(p)->cacheSize)
  500. #define RC_BUF_SIZE (1 << 16)
  501. static int RangeEnc_Alloc(CRangeEnc *p, ISzAllocPtr alloc)
  502. {
  503. if (!p->bufBase)
  504. {
  505. p->bufBase = (Byte *)ISzAlloc_Alloc(alloc, RC_BUF_SIZE);
  506. if (!p->bufBase)
  507. return 0;
  508. p->bufLim = p->bufBase + RC_BUF_SIZE;
  509. }
  510. return 1;
  511. }
  512. static void RangeEnc_Free(CRangeEnc *p, ISzAllocPtr alloc)
  513. {
  514. ISzAlloc_Free(alloc, p->bufBase);
  515. p->bufBase = NULL;
  516. }
  517. static void RangeEnc_Init(CRangeEnc *p)
  518. {
  519. p->range = 0xFFFFFFFF;
  520. p->cache = 0;
  521. p->low = 0;
  522. p->cacheSize = 0;
  523. p->buf = p->bufBase;
  524. p->processed = 0;
  525. p->res = SZ_OK;
  526. }
  527. Z7_NO_INLINE static void RangeEnc_FlushStream(CRangeEnc *p)
  528. {
  529. const size_t num = (size_t)(p->buf - p->bufBase);
  530. if (p->res == SZ_OK)
  531. {
  532. if (num != ISeqOutStream_Write(p->outStream, p->bufBase, num))
  533. p->res = SZ_ERROR_WRITE;
  534. }
  535. p->processed += num;
  536. p->buf = p->bufBase;
  537. }
  538. Z7_NO_INLINE static void Z7_FASTCALL RangeEnc_ShiftLow(CRangeEnc *p)
  539. {
  540. UInt32 low = (UInt32)p->low;
  541. unsigned high = (unsigned)(p->low >> 32);
  542. p->low = (UInt32)(low << 8);
  543. if (low < (UInt32)0xFF000000 || high != 0)
  544. {
  545. {
  546. Byte *buf = p->buf;
  547. *buf++ = (Byte)(p->cache + high);
  548. p->cache = (unsigned)(low >> 24);
  549. p->buf = buf;
  550. if (buf == p->bufLim)
  551. RangeEnc_FlushStream(p);
  552. if (p->cacheSize == 0)
  553. return;
  554. }
  555. high += 0xFF;
  556. for (;;)
  557. {
  558. Byte *buf = p->buf;
  559. *buf++ = (Byte)(high);
  560. p->buf = buf;
  561. if (buf == p->bufLim)
  562. RangeEnc_FlushStream(p);
  563. if (--p->cacheSize == 0)
  564. return;
  565. }
  566. }
  567. p->cacheSize++;
  568. }
  569. static void RangeEnc_FlushData(CRangeEnc *p)
  570. {
  571. int i;
  572. for (i = 0; i < 5; i++)
  573. RangeEnc_ShiftLow(p);
  574. }
  575. #define RC_NORM(p) if (range < kTopValue) { range <<= 8; RangeEnc_ShiftLow(p); }
  576. #define RC_BIT_PRE(p, prob) \
  577. ttt = *(prob); \
  578. newBound = (range >> kNumBitModelTotalBits) * ttt;
  579. // #define Z7_LZMA_ENC_USE_BRANCH
  580. #ifdef Z7_LZMA_ENC_USE_BRANCH
  581. #define RC_BIT(p, prob, bit) { \
  582. RC_BIT_PRE(p, prob) \
  583. if (bit == 0) { range = newBound; ttt += (kBitModelTotal - ttt) >> kNumMoveBits; } \
  584. else { (p)->low += newBound; range -= newBound; ttt -= ttt >> kNumMoveBits; } \
  585. *(prob) = (CLzmaProb)ttt; \
  586. RC_NORM(p) \
  587. }
  588. #else
  589. #define RC_BIT(p, prob, bit) { \
  590. UInt32 mask; \
  591. RC_BIT_PRE(p, prob) \
  592. mask = 0 - (UInt32)bit; \
  593. range &= mask; \
  594. mask &= newBound; \
  595. range -= mask; \
  596. (p)->low += mask; \
  597. mask = (UInt32)bit - 1; \
  598. range += newBound & mask; \
  599. mask &= (kBitModelTotal - ((1 << kNumMoveBits) - 1)); \
  600. mask += ((1 << kNumMoveBits) - 1); \
  601. ttt += (UInt32)((Int32)(mask - ttt) >> kNumMoveBits); \
  602. *(prob) = (CLzmaProb)ttt; \
  603. RC_NORM(p) \
  604. }
  605. #endif
  606. #define RC_BIT_0_BASE(p, prob) \
  607. range = newBound; *(prob) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
  608. #define RC_BIT_1_BASE(p, prob) \
  609. range -= newBound; (p)->low += newBound; *(prob) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits)); \
  610. #define RC_BIT_0(p, prob) \
  611. RC_BIT_0_BASE(p, prob) \
  612. RC_NORM(p)
  613. #define RC_BIT_1(p, prob) \
  614. RC_BIT_1_BASE(p, prob) \
  615. RC_NORM(p)
  616. static void RangeEnc_EncodeBit_0(CRangeEnc *p, CLzmaProb *prob)
  617. {
  618. UInt32 range, ttt, newBound;
  619. range = p->range;
  620. RC_BIT_PRE(p, prob)
  621. RC_BIT_0(p, prob)
  622. p->range = range;
  623. }
  624. static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 sym)
  625. {
  626. UInt32 range = p->range;
  627. sym |= 0x100;
  628. do
  629. {
  630. UInt32 ttt, newBound;
  631. // RangeEnc_EncodeBit(p, probs + (sym >> 8), (sym >> 7) & 1);
  632. CLzmaProb *prob = probs + (sym >> 8);
  633. UInt32 bit = (sym >> 7) & 1;
  634. sym <<= 1;
  635. RC_BIT(p, prob, bit)
  636. }
  637. while (sym < 0x10000);
  638. p->range = range;
  639. }
  640. static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 sym, UInt32 matchByte)
  641. {
  642. UInt32 range = p->range;
  643. UInt32 offs = 0x100;
  644. sym |= 0x100;
  645. do
  646. {
  647. UInt32 ttt, newBound;
  648. CLzmaProb *prob;
  649. UInt32 bit;
  650. matchByte <<= 1;
  651. // RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (sym >> 8)), (sym >> 7) & 1);
  652. prob = probs + (offs + (matchByte & offs) + (sym >> 8));
  653. bit = (sym >> 7) & 1;
  654. sym <<= 1;
  655. offs &= ~(matchByte ^ sym);
  656. RC_BIT(p, prob, bit)
  657. }
  658. while (sym < 0x10000);
  659. p->range = range;
  660. }
  661. static void LzmaEnc_InitPriceTables(CProbPrice *ProbPrices)
  662. {
  663. UInt32 i;
  664. for (i = 0; i < (kBitModelTotal >> kNumMoveReducingBits); i++)
  665. {
  666. const unsigned kCyclesBits = kNumBitPriceShiftBits;
  667. UInt32 w = (i << kNumMoveReducingBits) + (1 << (kNumMoveReducingBits - 1));
  668. unsigned bitCount = 0;
  669. unsigned j;
  670. for (j = 0; j < kCyclesBits; j++)
  671. {
  672. w = w * w;
  673. bitCount <<= 1;
  674. while (w >= ((UInt32)1 << 16))
  675. {
  676. w >>= 1;
  677. bitCount++;
  678. }
  679. }
  680. ProbPrices[i] = (CProbPrice)(((unsigned)kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
  681. // printf("\n%3d: %5d", i, ProbPrices[i]);
  682. }
  683. }
  684. #define GET_PRICE(prob, bit) \
  685. p->ProbPrices[((prob) ^ (unsigned)(((-(int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]
  686. #define GET_PRICEa(prob, bit) \
  687. ProbPrices[((prob) ^ (unsigned)((-((int)(bit))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]
  688. #define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
  689. #define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
  690. #define GET_PRICEa_0(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
  691. #define GET_PRICEa_1(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
  692. static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 sym, const CProbPrice *ProbPrices)
  693. {
  694. UInt32 price = 0;
  695. sym |= 0x100;
  696. do
  697. {
  698. unsigned bit = sym & 1;
  699. sym >>= 1;
  700. price += GET_PRICEa(probs[sym], bit);
  701. }
  702. while (sym >= 2);
  703. return price;
  704. }
  705. static UInt32 LitEnc_Matched_GetPrice(const CLzmaProb *probs, UInt32 sym, UInt32 matchByte, const CProbPrice *ProbPrices)
  706. {
  707. UInt32 price = 0;
  708. UInt32 offs = 0x100;
  709. sym |= 0x100;
  710. do
  711. {
  712. matchByte <<= 1;
  713. price += GET_PRICEa(probs[offs + (matchByte & offs) + (sym >> 8)], (sym >> 7) & 1);
  714. sym <<= 1;
  715. offs &= ~(matchByte ^ sym);
  716. }
  717. while (sym < 0x10000);
  718. return price;
  719. }
  720. static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, unsigned numBits, unsigned sym)
  721. {
  722. UInt32 range = rc->range;
  723. unsigned m = 1;
  724. do
  725. {
  726. UInt32 ttt, newBound;
  727. unsigned bit = sym & 1;
  728. // RangeEnc_EncodeBit(rc, probs + m, bit);
  729. sym >>= 1;
  730. RC_BIT(rc, probs + m, bit)
  731. m = (m << 1) | bit;
  732. }
  733. while (--numBits);
  734. rc->range = range;
  735. }
  736. static void LenEnc_Init(CLenEnc *p)
  737. {
  738. unsigned i;
  739. for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << (kLenNumLowBits + 1)); i++)
  740. p->low[i] = kProbInitValue;
  741. for (i = 0; i < kLenNumHighSymbols; i++)
  742. p->high[i] = kProbInitValue;
  743. }
  744. static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, unsigned sym, unsigned posState)
  745. {
  746. UInt32 range, ttt, newBound;
  747. CLzmaProb *probs = p->low;
  748. range = rc->range;
  749. RC_BIT_PRE(rc, probs)
  750. if (sym >= kLenNumLowSymbols)
  751. {
  752. RC_BIT_1(rc, probs)
  753. probs += kLenNumLowSymbols;
  754. RC_BIT_PRE(rc, probs)
  755. if (sym >= kLenNumLowSymbols * 2)
  756. {
  757. RC_BIT_1(rc, probs)
  758. rc->range = range;
  759. // RcTree_Encode(rc, p->high, kLenNumHighBits, sym - kLenNumLowSymbols * 2);
  760. LitEnc_Encode(rc, p->high, sym - kLenNumLowSymbols * 2);
  761. return;
  762. }
  763. sym -= kLenNumLowSymbols;
  764. }
  765. // RcTree_Encode(rc, probs + (posState << kLenNumLowBits), kLenNumLowBits, sym);
  766. {
  767. unsigned m;
  768. unsigned bit;
  769. RC_BIT_0(rc, probs)
  770. probs += (posState << (1 + kLenNumLowBits));
  771. bit = (sym >> 2) ; RC_BIT(rc, probs + 1, bit) m = (1 << 1) + bit;
  772. bit = (sym >> 1) & 1; RC_BIT(rc, probs + m, bit) m = (m << 1) + bit;
  773. bit = sym & 1; RC_BIT(rc, probs + m, bit)
  774. rc->range = range;
  775. }
  776. }
  777. static void SetPrices_3(const CLzmaProb *probs, UInt32 startPrice, UInt32 *prices, const CProbPrice *ProbPrices)
  778. {
  779. unsigned i;
  780. for (i = 0; i < 8; i += 2)
  781. {
  782. UInt32 price = startPrice;
  783. UInt32 prob;
  784. price += GET_PRICEa(probs[1 ], (i >> 2));
  785. price += GET_PRICEa(probs[2 + (i >> 2)], (i >> 1) & 1);
  786. prob = probs[4 + (i >> 1)];
  787. prices[i ] = price + GET_PRICEa_0(prob);
  788. prices[i + 1] = price + GET_PRICEa_1(prob);
  789. }
  790. }
  791. Z7_NO_INLINE static void Z7_FASTCALL LenPriceEnc_UpdateTables(
  792. CLenPriceEnc *p,
  793. unsigned numPosStates,
  794. const CLenEnc *enc,
  795. const CProbPrice *ProbPrices)
  796. {
  797. UInt32 b;
  798. {
  799. unsigned prob = enc->low[0];
  800. UInt32 a, c;
  801. unsigned posState;
  802. b = GET_PRICEa_1(prob);
  803. a = GET_PRICEa_0(prob);
  804. c = b + GET_PRICEa_0(enc->low[kLenNumLowSymbols]);
  805. for (posState = 0; posState < numPosStates; posState++)
  806. {
  807. UInt32 *prices = p->prices[posState];
  808. const CLzmaProb *probs = enc->low + (posState << (1 + kLenNumLowBits));
  809. SetPrices_3(probs, a, prices, ProbPrices);
  810. SetPrices_3(probs + kLenNumLowSymbols, c, prices + kLenNumLowSymbols, ProbPrices);
  811. }
  812. }
  813. /*
  814. {
  815. unsigned i;
  816. UInt32 b;
  817. a = GET_PRICEa_0(enc->low[0]);
  818. for (i = 0; i < kLenNumLowSymbols; i++)
  819. p->prices2[i] = a;
  820. a = GET_PRICEa_1(enc->low[0]);
  821. b = a + GET_PRICEa_0(enc->low[kLenNumLowSymbols]);
  822. for (i = kLenNumLowSymbols; i < kLenNumLowSymbols * 2; i++)
  823. p->prices2[i] = b;
  824. a += GET_PRICEa_1(enc->low[kLenNumLowSymbols]);
  825. }
  826. */
  827. // p->counter = numSymbols;
  828. // p->counter = 64;
  829. {
  830. unsigned i = p->tableSize;
  831. if (i > kLenNumLowSymbols * 2)
  832. {
  833. const CLzmaProb *probs = enc->high;
  834. UInt32 *prices = p->prices[0] + kLenNumLowSymbols * 2;
  835. i -= kLenNumLowSymbols * 2 - 1;
  836. i >>= 1;
  837. b += GET_PRICEa_1(enc->low[kLenNumLowSymbols]);
  838. do
  839. {
  840. /*
  841. p->prices2[i] = a +
  842. // RcTree_GetPrice(enc->high, kLenNumHighBits, i - kLenNumLowSymbols * 2, ProbPrices);
  843. LitEnc_GetPrice(probs, i - kLenNumLowSymbols * 2, ProbPrices);
  844. */
  845. // UInt32 price = a + RcTree_GetPrice(probs, kLenNumHighBits - 1, sym, ProbPrices);
  846. unsigned sym = --i + (1 << (kLenNumHighBits - 1));
  847. UInt32 price = b;
  848. do
  849. {
  850. const unsigned bit = sym & 1;
  851. sym >>= 1;
  852. price += GET_PRICEa(probs[sym], bit);
  853. }
  854. while (sym >= 2);
  855. {
  856. const unsigned prob = probs[(size_t)i + (1 << (kLenNumHighBits - 1))];
  857. prices[(size_t)i * 2 ] = price + GET_PRICEa_0(prob);
  858. prices[(size_t)i * 2 + 1] = price + GET_PRICEa_1(prob);
  859. }
  860. }
  861. while (i);
  862. {
  863. unsigned posState;
  864. const size_t num = (p->tableSize - kLenNumLowSymbols * 2) * sizeof(p->prices[0][0]);
  865. for (posState = 1; posState < numPosStates; posState++)
  866. memcpy(p->prices[posState] + kLenNumLowSymbols * 2, p->prices[0] + kLenNumLowSymbols * 2, num);
  867. }
  868. }
  869. }
  870. }
  871. /*
  872. #ifdef SHOW_STAT
  873. g_STAT_OFFSET += num;
  874. printf("\n MovePos %u", num);
  875. #endif
  876. */
  877. #define MOVE_POS(p, num) { \
  878. p->additionalOffset += (num); \
  879. p->matchFinder.Skip(p->matchFinderObj, (UInt32)(num)); }
  880. static unsigned ReadMatchDistances(CLzmaEnc *p, unsigned *numPairsRes)
  881. {
  882. unsigned numPairs;
  883. p->additionalOffset++;
  884. p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
  885. {
  886. const UInt32 *d = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
  887. // if (!d) { p->mf_Failure = True; *numPairsRes = 0; return 0; }
  888. numPairs = (unsigned)(d - p->matches);
  889. }
  890. *numPairsRes = numPairs;
  891. #ifdef SHOW_STAT
  892. printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2);
  893. g_STAT_OFFSET++;
  894. {
  895. unsigned i;
  896. for (i = 0; i < numPairs; i += 2)
  897. printf("%2u %6u | ", p->matches[i], p->matches[i + 1]);
  898. }
  899. #endif
  900. if (numPairs == 0)
  901. return 0;
  902. {
  903. const unsigned len = p->matches[(size_t)numPairs - 2];
  904. if (len != p->numFastBytes)
  905. return len;
  906. {
  907. UInt32 numAvail = p->numAvail;
  908. if (numAvail > LZMA_MATCH_LEN_MAX)
  909. numAvail = LZMA_MATCH_LEN_MAX;
  910. {
  911. const Byte *p1 = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
  912. const Byte *p2 = p1 + len;
  913. const ptrdiff_t dif = (ptrdiff_t)-1 - (ptrdiff_t)p->matches[(size_t)numPairs - 1];
  914. const Byte *lim = p1 + numAvail;
  915. for (; p2 != lim && *p2 == p2[dif]; p2++)
  916. {}
  917. return (unsigned)(p2 - p1);
  918. }
  919. }
  920. }
  921. }
  922. #define MARK_LIT ((UInt32)(Int32)-1)
  923. #define MakeAs_Lit(p) { (p)->dist = MARK_LIT; (p)->extra = 0; }
  924. #define MakeAs_ShortRep(p) { (p)->dist = 0; (p)->extra = 0; }
  925. #define IsShortRep(p) ((p)->dist == 0)
  926. #define GetPrice_ShortRep(p, state, posState) \
  927. ( GET_PRICE_0(p->isRepG0[state]) + GET_PRICE_0(p->isRep0Long[state][posState]))
  928. #define GetPrice_Rep_0(p, state, posState) ( \
  929. GET_PRICE_1(p->isMatch[state][posState]) \
  930. + GET_PRICE_1(p->isRep0Long[state][posState])) \
  931. + GET_PRICE_1(p->isRep[state]) \
  932. + GET_PRICE_0(p->isRepG0[state])
  933. Z7_FORCE_INLINE
  934. static UInt32 GetPrice_PureRep(const CLzmaEnc *p, unsigned repIndex, size_t state, size_t posState)
  935. {
  936. UInt32 price;
  937. UInt32 prob = p->isRepG0[state];
  938. if (repIndex == 0)
  939. {
  940. price = GET_PRICE_0(prob);
  941. price += GET_PRICE_1(p->isRep0Long[state][posState]);
  942. }
  943. else
  944. {
  945. price = GET_PRICE_1(prob);
  946. prob = p->isRepG1[state];
  947. if (repIndex == 1)
  948. price += GET_PRICE_0(prob);
  949. else
  950. {
  951. price += GET_PRICE_1(prob);
  952. price += GET_PRICE(p->isRepG2[state], repIndex - 2);
  953. }
  954. }
  955. return price;
  956. }
  957. static unsigned Backward(CLzmaEnc *p, unsigned cur)
  958. {
  959. unsigned wr = cur + 1;
  960. p->optEnd = wr;
  961. for (;;)
  962. {
  963. UInt32 dist = p->opt[cur].dist;
  964. unsigned len = (unsigned)p->opt[cur].len;
  965. unsigned extra = (unsigned)p->opt[cur].extra;
  966. cur -= len;
  967. if (extra)
  968. {
  969. wr--;
  970. p->opt[wr].len = (UInt32)len;
  971. cur -= extra;
  972. len = extra;
  973. if (extra == 1)
  974. {
  975. p->opt[wr].dist = dist;
  976. dist = MARK_LIT;
  977. }
  978. else
  979. {
  980. p->opt[wr].dist = 0;
  981. len--;
  982. wr--;
  983. p->opt[wr].dist = MARK_LIT;
  984. p->opt[wr].len = 1;
  985. }
  986. }
  987. if (cur == 0)
  988. {
  989. p->backRes = dist;
  990. p->optCur = wr;
  991. return len;
  992. }
  993. wr--;
  994. p->opt[wr].dist = dist;
  995. p->opt[wr].len = (UInt32)len;
  996. }
  997. }
  998. #define LIT_PROBS(pos, prevByte) \
  999. (p->litProbs + (UInt32)3 * (((((pos) << 8) + (prevByte)) & p->lpMask) << p->lc))
  1000. static unsigned GetOptimum(CLzmaEnc *p, UInt32 position)
  1001. {
  1002. unsigned last, cur;
  1003. UInt32 reps[LZMA_NUM_REPS];
  1004. unsigned repLens[LZMA_NUM_REPS];
  1005. UInt32 *matches;
  1006. {
  1007. UInt32 numAvail;
  1008. unsigned numPairs, mainLen, repMaxIndex, i, posState;
  1009. UInt32 matchPrice, repMatchPrice;
  1010. const Byte *data;
  1011. Byte curByte, matchByte;
  1012. p->optCur = p->optEnd = 0;
  1013. if (p->additionalOffset == 0)
  1014. mainLen = ReadMatchDistances(p, &numPairs);
  1015. else
  1016. {
  1017. mainLen = p->longestMatchLen;
  1018. numPairs = p->numPairs;
  1019. }
  1020. numAvail = p->numAvail;
  1021. if (numAvail < 2)
  1022. {
  1023. p->backRes = MARK_LIT;
  1024. return 1;
  1025. }
  1026. if (numAvail > LZMA_MATCH_LEN_MAX)
  1027. numAvail = LZMA_MATCH_LEN_MAX;
  1028. data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
  1029. repMaxIndex = 0;
  1030. for (i = 0; i < LZMA_NUM_REPS; i++)
  1031. {
  1032. unsigned len;
  1033. const Byte *data2;
  1034. reps[i] = p->reps[i];
  1035. data2 = data - reps[i];
  1036. if (data[0] != data2[0] || data[1] != data2[1])
  1037. {
  1038. repLens[i] = 0;
  1039. continue;
  1040. }
  1041. for (len = 2; len < numAvail && data[len] == data2[len]; len++)
  1042. {}
  1043. repLens[i] = len;
  1044. if (len > repLens[repMaxIndex])
  1045. repMaxIndex = i;
  1046. if (len == LZMA_MATCH_LEN_MAX) // 21.03 : optimization
  1047. break;
  1048. }
  1049. if (repLens[repMaxIndex] >= p->numFastBytes)
  1050. {
  1051. unsigned len;
  1052. p->backRes = (UInt32)repMaxIndex;
  1053. len = repLens[repMaxIndex];
  1054. MOVE_POS(p, len - 1)
  1055. return len;
  1056. }
  1057. matches = p->matches;
  1058. #define MATCHES matches
  1059. // #define MATCHES p->matches
  1060. if (mainLen >= p->numFastBytes)
  1061. {
  1062. p->backRes = MATCHES[(size_t)numPairs - 1] + LZMA_NUM_REPS;
  1063. MOVE_POS(p, mainLen - 1)
  1064. return mainLen;
  1065. }
  1066. curByte = *data;
  1067. matchByte = *(data - reps[0]);
  1068. last = repLens[repMaxIndex];
  1069. if (last <= mainLen)
  1070. last = mainLen;
  1071. if (last < 2 && curByte != matchByte)
  1072. {
  1073. p->backRes = MARK_LIT;
  1074. return 1;
  1075. }
  1076. p->opt[0].state = (CState)p->state;
  1077. posState = (position & p->pbMask);
  1078. {
  1079. const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
  1080. p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
  1081. (!IsLitState(p->state) ?
  1082. LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) :
  1083. LitEnc_GetPrice(probs, curByte, p->ProbPrices));
  1084. }
  1085. MakeAs_Lit(&p->opt[1])
  1086. matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
  1087. repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
  1088. // 18.06
  1089. if (matchByte == curByte && repLens[0] == 0)
  1090. {
  1091. UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, p->state, posState);
  1092. if (shortRepPrice < p->opt[1].price)
  1093. {
  1094. p->opt[1].price = shortRepPrice;
  1095. MakeAs_ShortRep(&p->opt[1])
  1096. }
  1097. if (last < 2)
  1098. {
  1099. p->backRes = p->opt[1].dist;
  1100. return 1;
  1101. }
  1102. }
  1103. p->opt[1].len = 1;
  1104. p->opt[0].reps[0] = reps[0];
  1105. p->opt[0].reps[1] = reps[1];
  1106. p->opt[0].reps[2] = reps[2];
  1107. p->opt[0].reps[3] = reps[3];
  1108. // ---------- REP ----------
  1109. for (i = 0; i < LZMA_NUM_REPS; i++)
  1110. {
  1111. unsigned repLen = repLens[i];
  1112. UInt32 price;
  1113. if (repLen < 2)
  1114. continue;
  1115. price = repMatchPrice + GetPrice_PureRep(p, i, p->state, posState);
  1116. do
  1117. {
  1118. UInt32 price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState, repLen);
  1119. COptimal *opt = &p->opt[repLen];
  1120. if (price2 < opt->price)
  1121. {
  1122. opt->price = price2;
  1123. opt->len = (UInt32)repLen;
  1124. opt->dist = (UInt32)i;
  1125. opt->extra = 0;
  1126. }
  1127. }
  1128. while (--repLen >= 2);
  1129. }
  1130. // ---------- MATCH ----------
  1131. {
  1132. unsigned len = repLens[0] + 1;
  1133. if (len <= mainLen)
  1134. {
  1135. unsigned offs = 0;
  1136. UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
  1137. if (len < 2)
  1138. len = 2;
  1139. else
  1140. while (len > MATCHES[offs])
  1141. offs += 2;
  1142. for (; ; len++)
  1143. {
  1144. COptimal *opt;
  1145. UInt32 dist = MATCHES[(size_t)offs + 1];
  1146. UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len);
  1147. unsigned lenToPosState = GetLenToPosState(len);
  1148. if (dist < kNumFullDistances)
  1149. price += p->distancesPrices[lenToPosState][dist & (kNumFullDistances - 1)];
  1150. else
  1151. {
  1152. unsigned slot;
  1153. GetPosSlot2(dist, slot)
  1154. price += p->alignPrices[dist & kAlignMask];
  1155. price += p->posSlotPrices[lenToPosState][slot];
  1156. }
  1157. opt = &p->opt[len];
  1158. if (price < opt->price)
  1159. {
  1160. opt->price = price;
  1161. opt->len = (UInt32)len;
  1162. opt->dist = dist + LZMA_NUM_REPS;
  1163. opt->extra = 0;
  1164. }
  1165. if (len == MATCHES[offs])
  1166. {
  1167. offs += 2;
  1168. if (offs == numPairs)
  1169. break;
  1170. }
  1171. }
  1172. }
  1173. }
  1174. cur = 0;
  1175. #ifdef SHOW_STAT2
  1176. /* if (position >= 0) */
  1177. {
  1178. unsigned i;
  1179. printf("\n pos = %4X", position);
  1180. for (i = cur; i <= last; i++)
  1181. printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price);
  1182. }
  1183. #endif
  1184. }
  1185. // ---------- Optimal Parsing ----------
  1186. for (;;)
  1187. {
  1188. unsigned numAvail;
  1189. UInt32 numAvailFull;
  1190. unsigned newLen, numPairs, prev, state, posState, startLen;
  1191. UInt32 litPrice, matchPrice, repMatchPrice;
  1192. BoolInt nextIsLit;
  1193. Byte curByte, matchByte;
  1194. const Byte *data;
  1195. COptimal *curOpt, *nextOpt;
  1196. if (++cur == last)
  1197. break;
  1198. // 18.06
  1199. if (cur >= kNumOpts - 64)
  1200. {
  1201. unsigned j, best;
  1202. UInt32 price = p->opt[cur].price;
  1203. best = cur;
  1204. for (j = cur + 1; j <= last; j++)
  1205. {
  1206. UInt32 price2 = p->opt[j].price;
  1207. if (price >= price2)
  1208. {
  1209. price = price2;
  1210. best = j;
  1211. }
  1212. }
  1213. {
  1214. unsigned delta = best - cur;
  1215. if (delta != 0)
  1216. {
  1217. MOVE_POS(p, delta)
  1218. }
  1219. }
  1220. cur = best;
  1221. break;
  1222. }
  1223. newLen = ReadMatchDistances(p, &numPairs);
  1224. if (newLen >= p->numFastBytes)
  1225. {
  1226. p->numPairs = numPairs;
  1227. p->longestMatchLen = newLen;
  1228. break;
  1229. }
  1230. curOpt = &p->opt[cur];
  1231. position++;
  1232. // we need that check here, if skip_items in p->opt are possible
  1233. /*
  1234. if (curOpt->price >= kInfinityPrice)
  1235. continue;
  1236. */
  1237. prev = cur - curOpt->len;
  1238. if (curOpt->len == 1)
  1239. {
  1240. state = (unsigned)p->opt[prev].state;
  1241. if (IsShortRep(curOpt))
  1242. state = kShortRepNextStates[state];
  1243. else
  1244. state = kLiteralNextStates[state];
  1245. }
  1246. else
  1247. {
  1248. const COptimal *prevOpt;
  1249. UInt32 b0;
  1250. UInt32 dist = curOpt->dist;
  1251. if (curOpt->extra)
  1252. {
  1253. prev -= (unsigned)curOpt->extra;
  1254. state = kState_RepAfterLit;
  1255. if (curOpt->extra == 1)
  1256. state = (dist < LZMA_NUM_REPS ? kState_RepAfterLit : kState_MatchAfterLit);
  1257. }
  1258. else
  1259. {
  1260. state = (unsigned)p->opt[prev].state;
  1261. if (dist < LZMA_NUM_REPS)
  1262. state = kRepNextStates[state];
  1263. else
  1264. state = kMatchNextStates[state];
  1265. }
  1266. prevOpt = &p->opt[prev];
  1267. b0 = prevOpt->reps[0];
  1268. if (dist < LZMA_NUM_REPS)
  1269. {
  1270. if (dist == 0)
  1271. {
  1272. reps[0] = b0;
  1273. reps[1] = prevOpt->reps[1];
  1274. reps[2] = prevOpt->reps[2];
  1275. reps[3] = prevOpt->reps[3];
  1276. }
  1277. else
  1278. {
  1279. reps[1] = b0;
  1280. b0 = prevOpt->reps[1];
  1281. if (dist == 1)
  1282. {
  1283. reps[0] = b0;
  1284. reps[2] = prevOpt->reps[2];
  1285. reps[3] = prevOpt->reps[3];
  1286. }
  1287. else
  1288. {
  1289. reps[2] = b0;
  1290. reps[0] = prevOpt->reps[dist];
  1291. reps[3] = prevOpt->reps[dist ^ 1];
  1292. }
  1293. }
  1294. }
  1295. else
  1296. {
  1297. reps[0] = (dist - LZMA_NUM_REPS + 1);
  1298. reps[1] = b0;
  1299. reps[2] = prevOpt->reps[1];
  1300. reps[3] = prevOpt->reps[2];
  1301. }
  1302. }
  1303. curOpt->state = (CState)state;
  1304. curOpt->reps[0] = reps[0];
  1305. curOpt->reps[1] = reps[1];
  1306. curOpt->reps[2] = reps[2];
  1307. curOpt->reps[3] = reps[3];
  1308. data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
  1309. curByte = *data;
  1310. matchByte = *(data - reps[0]);
  1311. posState = (position & p->pbMask);
  1312. /*
  1313. The order of Price checks:
  1314. < LIT
  1315. <= SHORT_REP
  1316. < LIT : REP_0
  1317. < REP [ : LIT : REP_0 ]
  1318. < MATCH [ : LIT : REP_0 ]
  1319. */
  1320. {
  1321. UInt32 curPrice = curOpt->price;
  1322. unsigned prob = p->isMatch[state][posState];
  1323. matchPrice = curPrice + GET_PRICE_1(prob);
  1324. litPrice = curPrice + GET_PRICE_0(prob);
  1325. }
  1326. nextOpt = &p->opt[(size_t)cur + 1];
  1327. nextIsLit = False;
  1328. // here we can allow skip_items in p->opt, if we don't check (nextOpt->price < kInfinityPrice)
  1329. // 18.new.06
  1330. if ((nextOpt->price < kInfinityPrice
  1331. // && !IsLitState(state)
  1332. && matchByte == curByte)
  1333. || litPrice > nextOpt->price
  1334. )
  1335. litPrice = 0;
  1336. else
  1337. {
  1338. const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
  1339. litPrice += (!IsLitState(state) ?
  1340. LitEnc_Matched_GetPrice(probs, curByte, matchByte, p->ProbPrices) :
  1341. LitEnc_GetPrice(probs, curByte, p->ProbPrices));
  1342. if (litPrice < nextOpt->price)
  1343. {
  1344. nextOpt->price = litPrice;
  1345. nextOpt->len = 1;
  1346. MakeAs_Lit(nextOpt)
  1347. nextIsLit = True;
  1348. }
  1349. }
  1350. repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
  1351. numAvailFull = p->numAvail;
  1352. {
  1353. unsigned temp = kNumOpts - 1 - cur;
  1354. if (numAvailFull > temp)
  1355. numAvailFull = (UInt32)temp;
  1356. }
  1357. // 18.06
  1358. // ---------- SHORT_REP ----------
  1359. if (IsLitState(state)) // 18.new
  1360. if (matchByte == curByte)
  1361. if (repMatchPrice < nextOpt->price) // 18.new
  1362. // if (numAvailFull < 2 || data[1] != *(data - reps[0] + 1))
  1363. if (
  1364. // nextOpt->price >= kInfinityPrice ||
  1365. nextOpt->len < 2 // we can check nextOpt->len, if skip items are not allowed in p->opt
  1366. || (nextOpt->dist != 0
  1367. // && nextOpt->extra <= 1 // 17.old
  1368. )
  1369. )
  1370. {
  1371. UInt32 shortRepPrice = repMatchPrice + GetPrice_ShortRep(p, state, posState);
  1372. // if (shortRepPrice <= nextOpt->price) // 17.old
  1373. if (shortRepPrice < nextOpt->price) // 18.new
  1374. {
  1375. nextOpt->price = shortRepPrice;
  1376. nextOpt->len = 1;
  1377. MakeAs_ShortRep(nextOpt)
  1378. nextIsLit = False;
  1379. }
  1380. }
  1381. if (numAvailFull < 2)
  1382. continue;
  1383. numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
  1384. // numAvail <= p->numFastBytes
  1385. // ---------- LIT : REP_0 ----------
  1386. if (!nextIsLit
  1387. && litPrice != 0 // 18.new
  1388. && matchByte != curByte
  1389. && numAvailFull > 2)
  1390. {
  1391. const Byte *data2 = data - reps[0];
  1392. if (data[1] == data2[1] && data[2] == data2[2])
  1393. {
  1394. unsigned len;
  1395. unsigned limit = p->numFastBytes + 1;
  1396. if (limit > numAvailFull)
  1397. limit = numAvailFull;
  1398. for (len = 3; len < limit && data[len] == data2[len]; len++)
  1399. {}
  1400. {
  1401. unsigned state2 = kLiteralNextStates[state];
  1402. unsigned posState2 = (position + 1) & p->pbMask;
  1403. UInt32 price = litPrice + GetPrice_Rep_0(p, state2, posState2);
  1404. {
  1405. unsigned offset = cur + len;
  1406. if (last < offset)
  1407. last = offset;
  1408. // do
  1409. {
  1410. UInt32 price2;
  1411. COptimal *opt;
  1412. len--;
  1413. // price2 = price + GetPrice_Len_Rep_0(p, len, state2, posState2);
  1414. price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len);
  1415. opt = &p->opt[offset];
  1416. // offset--;
  1417. if (price2 < opt->price)
  1418. {
  1419. opt->price = price2;
  1420. opt->len = (UInt32)len;
  1421. opt->dist = 0;
  1422. opt->extra = 1;
  1423. }
  1424. }
  1425. // while (len >= 3);
  1426. }
  1427. }
  1428. }
  1429. }
  1430. startLen = 2; /* speed optimization */
  1431. {
  1432. // ---------- REP ----------
  1433. unsigned repIndex = 0; // 17.old
  1434. // unsigned repIndex = IsLitState(state) ? 0 : 1; // 18.notused
  1435. for (; repIndex < LZMA_NUM_REPS; repIndex++)
  1436. {
  1437. unsigned len;
  1438. UInt32 price;
  1439. const Byte *data2 = data - reps[repIndex];
  1440. if (data[0] != data2[0] || data[1] != data2[1])
  1441. continue;
  1442. for (len = 2; len < numAvail && data[len] == data2[len]; len++)
  1443. {}
  1444. // if (len < startLen) continue; // 18.new: speed optimization
  1445. {
  1446. unsigned offset = cur + len;
  1447. if (last < offset)
  1448. last = offset;
  1449. }
  1450. {
  1451. unsigned len2 = len;
  1452. price = repMatchPrice + GetPrice_PureRep(p, repIndex, state, posState);
  1453. do
  1454. {
  1455. UInt32 price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState, len2);
  1456. COptimal *opt = &p->opt[cur + len2];
  1457. if (price2 < opt->price)
  1458. {
  1459. opt->price = price2;
  1460. opt->len = (UInt32)len2;
  1461. opt->dist = (UInt32)repIndex;
  1462. opt->extra = 0;
  1463. }
  1464. }
  1465. while (--len2 >= 2);
  1466. }
  1467. if (repIndex == 0) startLen = len + 1; // 17.old
  1468. // startLen = len + 1; // 18.new
  1469. /* if (_maxMode) */
  1470. {
  1471. // ---------- REP : LIT : REP_0 ----------
  1472. // numFastBytes + 1 + numFastBytes
  1473. unsigned len2 = len + 1;
  1474. unsigned limit = len2 + p->numFastBytes;
  1475. if (limit > numAvailFull)
  1476. limit = numAvailFull;
  1477. len2 += 2;
  1478. if (len2 <= limit)
  1479. if (data[len2 - 2] == data2[len2 - 2])
  1480. if (data[len2 - 1] == data2[len2 - 1])
  1481. {
  1482. unsigned state2 = kRepNextStates[state];
  1483. unsigned posState2 = (position + len) & p->pbMask;
  1484. price += GET_PRICE_LEN(&p->repLenEnc, posState, len)
  1485. + GET_PRICE_0(p->isMatch[state2][posState2])
  1486. + LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]),
  1487. data[len], data2[len], p->ProbPrices);
  1488. // state2 = kLiteralNextStates[state2];
  1489. state2 = kState_LitAfterRep;
  1490. posState2 = (posState2 + 1) & p->pbMask;
  1491. price += GetPrice_Rep_0(p, state2, posState2);
  1492. for (; len2 < limit && data[len2] == data2[len2]; len2++)
  1493. {}
  1494. len2 -= len;
  1495. // if (len2 >= 3)
  1496. {
  1497. {
  1498. unsigned offset = cur + len + len2;
  1499. if (last < offset)
  1500. last = offset;
  1501. // do
  1502. {
  1503. UInt32 price2;
  1504. COptimal *opt;
  1505. len2--;
  1506. // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2);
  1507. price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len2);
  1508. opt = &p->opt[offset];
  1509. // offset--;
  1510. if (price2 < opt->price)
  1511. {
  1512. opt->price = price2;
  1513. opt->len = (UInt32)len2;
  1514. opt->extra = (CExtra)(len + 1);
  1515. opt->dist = (UInt32)repIndex;
  1516. }
  1517. }
  1518. // while (len2 >= 3);
  1519. }
  1520. }
  1521. }
  1522. }
  1523. }
  1524. }
  1525. // ---------- MATCH ----------
  1526. /* for (unsigned len = 2; len <= newLen; len++) */
  1527. if (newLen > numAvail)
  1528. {
  1529. newLen = numAvail;
  1530. for (numPairs = 0; newLen > MATCHES[numPairs]; numPairs += 2);
  1531. MATCHES[numPairs] = (UInt32)newLen;
  1532. numPairs += 2;
  1533. }
  1534. // startLen = 2; /* speed optimization */
  1535. if (newLen >= startLen)
  1536. {
  1537. UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
  1538. UInt32 dist;
  1539. unsigned offs, posSlot, len;
  1540. {
  1541. unsigned offset = cur + newLen;
  1542. if (last < offset)
  1543. last = offset;
  1544. }
  1545. offs = 0;
  1546. while (startLen > MATCHES[offs])
  1547. offs += 2;
  1548. dist = MATCHES[(size_t)offs + 1];
  1549. // if (dist >= kNumFullDistances)
  1550. GetPosSlot2(dist, posSlot)
  1551. for (len = /*2*/ startLen; ; len++)
  1552. {
  1553. UInt32 price = normalMatchPrice + GET_PRICE_LEN(&p->lenEnc, posState, len);
  1554. {
  1555. COptimal *opt;
  1556. unsigned lenNorm = len - 2;
  1557. lenNorm = GetLenToPosState2(lenNorm);
  1558. if (dist < kNumFullDistances)
  1559. price += p->distancesPrices[lenNorm][dist & (kNumFullDistances - 1)];
  1560. else
  1561. price += p->posSlotPrices[lenNorm][posSlot] + p->alignPrices[dist & kAlignMask];
  1562. opt = &p->opt[cur + len];
  1563. if (price < opt->price)
  1564. {
  1565. opt->price = price;
  1566. opt->len = (UInt32)len;
  1567. opt->dist = dist + LZMA_NUM_REPS;
  1568. opt->extra = 0;
  1569. }
  1570. }
  1571. if (len == MATCHES[offs])
  1572. {
  1573. // if (p->_maxMode) {
  1574. // MATCH : LIT : REP_0
  1575. const Byte *data2 = data - dist - 1;
  1576. unsigned len2 = len + 1;
  1577. unsigned limit = len2 + p->numFastBytes;
  1578. if (limit > numAvailFull)
  1579. limit = numAvailFull;
  1580. len2 += 2;
  1581. if (len2 <= limit)
  1582. if (data[len2 - 2] == data2[len2 - 2])
  1583. if (data[len2 - 1] == data2[len2 - 1])
  1584. {
  1585. for (; len2 < limit && data[len2] == data2[len2]; len2++)
  1586. {}
  1587. len2 -= len;
  1588. // if (len2 >= 3)
  1589. {
  1590. unsigned state2 = kMatchNextStates[state];
  1591. unsigned posState2 = (position + len) & p->pbMask;
  1592. unsigned offset;
  1593. price += GET_PRICE_0(p->isMatch[state2][posState2]);
  1594. price += LitEnc_Matched_GetPrice(LIT_PROBS(position + len, data[(size_t)len - 1]),
  1595. data[len], data2[len], p->ProbPrices);
  1596. // state2 = kLiteralNextStates[state2];
  1597. state2 = kState_LitAfterMatch;
  1598. posState2 = (posState2 + 1) & p->pbMask;
  1599. price += GetPrice_Rep_0(p, state2, posState2);
  1600. offset = cur + len + len2;
  1601. if (last < offset)
  1602. last = offset;
  1603. // do
  1604. {
  1605. UInt32 price2;
  1606. COptimal *opt;
  1607. len2--;
  1608. // price2 = price + GetPrice_Len_Rep_0(p, len2, state2, posState2);
  1609. price2 = price + GET_PRICE_LEN(&p->repLenEnc, posState2, len2);
  1610. opt = &p->opt[offset];
  1611. // offset--;
  1612. if (price2 < opt->price)
  1613. {
  1614. opt->price = price2;
  1615. opt->len = (UInt32)len2;
  1616. opt->extra = (CExtra)(len + 1);
  1617. opt->dist = dist + LZMA_NUM_REPS;
  1618. }
  1619. }
  1620. // while (len2 >= 3);
  1621. }
  1622. }
  1623. offs += 2;
  1624. if (offs == numPairs)
  1625. break;
  1626. dist = MATCHES[(size_t)offs + 1];
  1627. // if (dist >= kNumFullDistances)
  1628. GetPosSlot2(dist, posSlot)
  1629. }
  1630. }
  1631. }
  1632. }
  1633. do
  1634. p->opt[last].price = kInfinityPrice;
  1635. while (--last);
  1636. return Backward(p, cur);
  1637. }
  1638. #define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
  1639. static unsigned GetOptimumFast(CLzmaEnc *p)
  1640. {
  1641. UInt32 numAvail, mainDist;
  1642. unsigned mainLen, numPairs, repIndex, repLen, i;
  1643. const Byte *data;
  1644. if (p->additionalOffset == 0)
  1645. mainLen = ReadMatchDistances(p, &numPairs);
  1646. else
  1647. {
  1648. mainLen = p->longestMatchLen;
  1649. numPairs = p->numPairs;
  1650. }
  1651. numAvail = p->numAvail;
  1652. p->backRes = MARK_LIT;
  1653. if (numAvail < 2)
  1654. return 1;
  1655. // if (mainLen < 2 && p->state == 0) return 1; // 18.06.notused
  1656. if (numAvail > LZMA_MATCH_LEN_MAX)
  1657. numAvail = LZMA_MATCH_LEN_MAX;
  1658. data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
  1659. repLen = repIndex = 0;
  1660. for (i = 0; i < LZMA_NUM_REPS; i++)
  1661. {
  1662. unsigned len;
  1663. const Byte *data2 = data - p->reps[i];
  1664. if (data[0] != data2[0] || data[1] != data2[1])
  1665. continue;
  1666. for (len = 2; len < numAvail && data[len] == data2[len]; len++)
  1667. {}
  1668. if (len >= p->numFastBytes)
  1669. {
  1670. p->backRes = (UInt32)i;
  1671. MOVE_POS(p, len - 1)
  1672. return len;
  1673. }
  1674. if (len > repLen)
  1675. {
  1676. repIndex = i;
  1677. repLen = len;
  1678. }
  1679. }
  1680. if (mainLen >= p->numFastBytes)
  1681. {
  1682. p->backRes = p->matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
  1683. MOVE_POS(p, mainLen - 1)
  1684. return mainLen;
  1685. }
  1686. mainDist = 0; /* for GCC */
  1687. if (mainLen >= 2)
  1688. {
  1689. mainDist = p->matches[(size_t)numPairs - 1];
  1690. while (numPairs > 2)
  1691. {
  1692. UInt32 dist2;
  1693. if (mainLen != p->matches[(size_t)numPairs - 4] + 1)
  1694. break;
  1695. dist2 = p->matches[(size_t)numPairs - 3];
  1696. if (!ChangePair(dist2, mainDist))
  1697. break;
  1698. numPairs -= 2;
  1699. mainLen--;
  1700. mainDist = dist2;
  1701. }
  1702. if (mainLen == 2 && mainDist >= 0x80)
  1703. mainLen = 1;
  1704. }
  1705. if (repLen >= 2)
  1706. if ( repLen + 1 >= mainLen
  1707. || (repLen + 2 >= mainLen && mainDist >= (1 << 9))
  1708. || (repLen + 3 >= mainLen && mainDist >= (1 << 15)))
  1709. {
  1710. p->backRes = (UInt32)repIndex;
  1711. MOVE_POS(p, repLen - 1)
  1712. return repLen;
  1713. }
  1714. if (mainLen < 2 || numAvail <= 2)
  1715. return 1;
  1716. {
  1717. unsigned len1 = ReadMatchDistances(p, &p->numPairs);
  1718. p->longestMatchLen = len1;
  1719. if (len1 >= 2)
  1720. {
  1721. UInt32 newDist = p->matches[(size_t)p->numPairs - 1];
  1722. if ( (len1 >= mainLen && newDist < mainDist)
  1723. || (len1 == mainLen + 1 && !ChangePair(mainDist, newDist))
  1724. || (len1 > mainLen + 1)
  1725. || (len1 + 1 >= mainLen && mainLen >= 3 && ChangePair(newDist, mainDist)))
  1726. return 1;
  1727. }
  1728. }
  1729. data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
  1730. for (i = 0; i < LZMA_NUM_REPS; i++)
  1731. {
  1732. unsigned len, limit;
  1733. const Byte *data2 = data - p->reps[i];
  1734. if (data[0] != data2[0] || data[1] != data2[1])
  1735. continue;
  1736. limit = mainLen - 1;
  1737. for (len = 2;; len++)
  1738. {
  1739. if (len >= limit)
  1740. return 1;
  1741. if (data[len] != data2[len])
  1742. break;
  1743. }
  1744. }
  1745. p->backRes = mainDist + LZMA_NUM_REPS;
  1746. if (mainLen != 2)
  1747. {
  1748. MOVE_POS(p, mainLen - 2)
  1749. }
  1750. return mainLen;
  1751. }
  1752. static void WriteEndMarker(CLzmaEnc *p, unsigned posState)
  1753. {
  1754. UInt32 range;
  1755. range = p->rc.range;
  1756. {
  1757. UInt32 ttt, newBound;
  1758. CLzmaProb *prob = &p->isMatch[p->state][posState];
  1759. RC_BIT_PRE(&p->rc, prob)
  1760. RC_BIT_1(&p->rc, prob)
  1761. prob = &p->isRep[p->state];
  1762. RC_BIT_PRE(&p->rc, prob)
  1763. RC_BIT_0(&p->rc, prob)
  1764. }
  1765. p->state = kMatchNextStates[p->state];
  1766. p->rc.range = range;
  1767. LenEnc_Encode(&p->lenProbs, &p->rc, 0, posState);
  1768. range = p->rc.range;
  1769. {
  1770. // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[0], (1 << kNumPosSlotBits) - 1);
  1771. CLzmaProb *probs = p->posSlotEncoder[0];
  1772. unsigned m = 1;
  1773. do
  1774. {
  1775. UInt32 ttt, newBound;
  1776. RC_BIT_PRE(p, probs + m)
  1777. RC_BIT_1(&p->rc, probs + m)
  1778. m = (m << 1) + 1;
  1779. }
  1780. while (m < (1 << kNumPosSlotBits));
  1781. }
  1782. {
  1783. // RangeEnc_EncodeDirectBits(&p->rc, ((UInt32)1 << (30 - kNumAlignBits)) - 1, 30 - kNumAlignBits); UInt32 range = p->range;
  1784. unsigned numBits = 30 - kNumAlignBits;
  1785. do
  1786. {
  1787. range >>= 1;
  1788. p->rc.low += range;
  1789. RC_NORM(&p->rc)
  1790. }
  1791. while (--numBits);
  1792. }
  1793. {
  1794. // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
  1795. CLzmaProb *probs = p->posAlignEncoder;
  1796. unsigned m = 1;
  1797. do
  1798. {
  1799. UInt32 ttt, newBound;
  1800. RC_BIT_PRE(p, probs + m)
  1801. RC_BIT_1(&p->rc, probs + m)
  1802. m = (m << 1) + 1;
  1803. }
  1804. while (m < kAlignTableSize);
  1805. }
  1806. p->rc.range = range;
  1807. }
  1808. static SRes CheckErrors(CLzmaEnc *p)
  1809. {
  1810. if (p->result != SZ_OK)
  1811. return p->result;
  1812. if (p->rc.res != SZ_OK)
  1813. p->result = SZ_ERROR_WRITE;
  1814. #ifndef Z7_ST
  1815. if (
  1816. // p->mf_Failure ||
  1817. (p->mtMode &&
  1818. ( // p->matchFinderMt.failure_LZ_LZ ||
  1819. p->matchFinderMt.failure_LZ_BT))
  1820. )
  1821. {
  1822. p->result = MY_HRES_ERROR_INTERNAL_ERROR;
  1823. // printf("\nCheckErrors p->matchFinderMt.failureLZ\n");
  1824. }
  1825. #endif
  1826. if (MFB.result != SZ_OK)
  1827. p->result = SZ_ERROR_READ;
  1828. if (p->result != SZ_OK)
  1829. p->finished = True;
  1830. return p->result;
  1831. }
  1832. Z7_NO_INLINE static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
  1833. {
  1834. /* ReleaseMFStream(); */
  1835. p->finished = True;
  1836. if (p->writeEndMark)
  1837. WriteEndMarker(p, nowPos & p->pbMask);
  1838. RangeEnc_FlushData(&p->rc);
  1839. RangeEnc_FlushStream(&p->rc);
  1840. return CheckErrors(p);
  1841. }
  1842. Z7_NO_INLINE static void FillAlignPrices(CLzmaEnc *p)
  1843. {
  1844. unsigned i;
  1845. const CProbPrice *ProbPrices = p->ProbPrices;
  1846. const CLzmaProb *probs = p->posAlignEncoder;
  1847. // p->alignPriceCount = 0;
  1848. for (i = 0; i < kAlignTableSize / 2; i++)
  1849. {
  1850. UInt32 price = 0;
  1851. unsigned sym = i;
  1852. unsigned m = 1;
  1853. unsigned bit;
  1854. UInt32 prob;
  1855. bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
  1856. bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
  1857. bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[m], bit); m = (m << 1) + bit;
  1858. prob = probs[m];
  1859. p->alignPrices[i ] = price + GET_PRICEa_0(prob);
  1860. p->alignPrices[i + 8] = price + GET_PRICEa_1(prob);
  1861. // p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
  1862. }
  1863. }
  1864. Z7_NO_INLINE static void FillDistancesPrices(CLzmaEnc *p)
  1865. {
  1866. // int y; for (y = 0; y < 100; y++) {
  1867. UInt32 tempPrices[kNumFullDistances];
  1868. unsigned i, lps;
  1869. const CProbPrice *ProbPrices = p->ProbPrices;
  1870. p->matchPriceCount = 0;
  1871. for (i = kStartPosModelIndex / 2; i < kNumFullDistances / 2; i++)
  1872. {
  1873. unsigned posSlot = GetPosSlot1(i);
  1874. unsigned footerBits = (posSlot >> 1) - 1;
  1875. unsigned base = ((2 | (posSlot & 1)) << footerBits);
  1876. const CLzmaProb *probs = p->posEncoders + (size_t)base * 2;
  1877. // tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base, footerBits, i - base, p->ProbPrices);
  1878. UInt32 price = 0;
  1879. unsigned m = 1;
  1880. unsigned sym = i;
  1881. unsigned offset = (unsigned)1 << footerBits;
  1882. base += i;
  1883. if (footerBits)
  1884. do
  1885. {
  1886. unsigned bit = sym & 1;
  1887. sym >>= 1;
  1888. price += GET_PRICEa(probs[m], bit);
  1889. m = (m << 1) + bit;
  1890. }
  1891. while (--footerBits);
  1892. {
  1893. unsigned prob = probs[m];
  1894. tempPrices[base ] = price + GET_PRICEa_0(prob);
  1895. tempPrices[base + offset] = price + GET_PRICEa_1(prob);
  1896. }
  1897. }
  1898. for (lps = 0; lps < kNumLenToPosStates; lps++)
  1899. {
  1900. unsigned slot;
  1901. unsigned distTableSize2 = (p->distTableSize + 1) >> 1;
  1902. UInt32 *posSlotPrices = p->posSlotPrices[lps];
  1903. const CLzmaProb *probs = p->posSlotEncoder[lps];
  1904. for (slot = 0; slot < distTableSize2; slot++)
  1905. {
  1906. // posSlotPrices[slot] = RcTree_GetPrice(encoder, kNumPosSlotBits, slot, p->ProbPrices);
  1907. UInt32 price;
  1908. unsigned bit;
  1909. unsigned sym = slot + (1 << (kNumPosSlotBits - 1));
  1910. unsigned prob;
  1911. bit = sym & 1; sym >>= 1; price = GET_PRICEa(probs[sym], bit);
  1912. bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit);
  1913. bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit);
  1914. bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit);
  1915. bit = sym & 1; sym >>= 1; price += GET_PRICEa(probs[sym], bit);
  1916. prob = probs[(size_t)slot + (1 << (kNumPosSlotBits - 1))];
  1917. posSlotPrices[(size_t)slot * 2 ] = price + GET_PRICEa_0(prob);
  1918. posSlotPrices[(size_t)slot * 2 + 1] = price + GET_PRICEa_1(prob);
  1919. }
  1920. {
  1921. UInt32 delta = ((UInt32)((kEndPosModelIndex / 2 - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
  1922. for (slot = kEndPosModelIndex / 2; slot < distTableSize2; slot++)
  1923. {
  1924. posSlotPrices[(size_t)slot * 2 ] += delta;
  1925. posSlotPrices[(size_t)slot * 2 + 1] += delta;
  1926. delta += ((UInt32)1 << kNumBitPriceShiftBits);
  1927. }
  1928. }
  1929. {
  1930. UInt32 *dp = p->distancesPrices[lps];
  1931. dp[0] = posSlotPrices[0];
  1932. dp[1] = posSlotPrices[1];
  1933. dp[2] = posSlotPrices[2];
  1934. dp[3] = posSlotPrices[3];
  1935. for (i = 4; i < kNumFullDistances; i += 2)
  1936. {
  1937. UInt32 slotPrice = posSlotPrices[GetPosSlot1(i)];
  1938. dp[i ] = slotPrice + tempPrices[i];
  1939. dp[i + 1] = slotPrice + tempPrices[i + 1];
  1940. }
  1941. }
  1942. }
  1943. // }
  1944. }
  1945. static void LzmaEnc_Construct(CLzmaEnc *p)
  1946. {
  1947. RangeEnc_Construct(&p->rc);
  1948. MatchFinder_Construct(&MFB);
  1949. #ifndef Z7_ST
  1950. p->matchFinderMt.MatchFinder = &MFB;
  1951. MatchFinderMt_Construct(&p->matchFinderMt);
  1952. #endif
  1953. {
  1954. CLzmaEncProps props;
  1955. LzmaEncProps_Init(&props);
  1956. LzmaEnc_SetProps((CLzmaEncHandle)(void *)p, &props);
  1957. }
  1958. #ifndef LZMA_LOG_BSR
  1959. LzmaEnc_FastPosInit(p->g_FastPos);
  1960. #endif
  1961. LzmaEnc_InitPriceTables(p->ProbPrices);
  1962. p->litProbs = NULL;
  1963. p->saveState.litProbs = NULL;
  1964. }
  1965. CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc)
  1966. {
  1967. void *p;
  1968. p = ISzAlloc_Alloc(alloc, sizeof(CLzmaEnc));
  1969. if (p)
  1970. LzmaEnc_Construct((CLzmaEnc *)p);
  1971. return p;
  1972. }
  1973. static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAllocPtr alloc)
  1974. {
  1975. ISzAlloc_Free(alloc, p->litProbs);
  1976. ISzAlloc_Free(alloc, p->saveState.litProbs);
  1977. p->litProbs = NULL;
  1978. p->saveState.litProbs = NULL;
  1979. }
  1980. static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
  1981. {
  1982. #ifndef Z7_ST
  1983. MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
  1984. #endif
  1985. MatchFinder_Free(&MFB, allocBig);
  1986. LzmaEnc_FreeLits(p, alloc);
  1987. RangeEnc_Free(&p->rc, alloc);
  1988. }
  1989. void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig)
  1990. {
  1991. // GET_CLzmaEnc_p
  1992. LzmaEnc_Destruct(p, alloc, allocBig);
  1993. ISzAlloc_Free(alloc, p);
  1994. }
  1995. Z7_NO_INLINE
  1996. static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, UInt32 maxPackSize, UInt32 maxUnpackSize)
  1997. {
  1998. UInt32 nowPos32, startPos32;
  1999. if (p->needInit)
  2000. {
  2001. #ifndef Z7_ST
  2002. if (p->mtMode)
  2003. {
  2004. RINOK(MatchFinderMt_InitMt(&p->matchFinderMt))
  2005. }
  2006. #endif
  2007. p->matchFinder.Init(p->matchFinderObj);
  2008. p->needInit = 0;
  2009. }
  2010. if (p->finished)
  2011. return p->result;
  2012. RINOK(CheckErrors(p))
  2013. nowPos32 = (UInt32)p->nowPos64;
  2014. startPos32 = nowPos32;
  2015. if (p->nowPos64 == 0)
  2016. {
  2017. unsigned numPairs;
  2018. Byte curByte;
  2019. if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
  2020. return Flush(p, nowPos32);
  2021. ReadMatchDistances(p, &numPairs);
  2022. RangeEnc_EncodeBit_0(&p->rc, &p->isMatch[kState_Start][0]);
  2023. // p->state = kLiteralNextStates[p->state];
  2024. curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset);
  2025. LitEnc_Encode(&p->rc, p->litProbs, curByte);
  2026. p->additionalOffset--;
  2027. nowPos32++;
  2028. }
  2029. if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
  2030. for (;;)
  2031. {
  2032. UInt32 dist;
  2033. unsigned len, posState;
  2034. UInt32 range, ttt, newBound;
  2035. CLzmaProb *probs;
  2036. if (p->fastMode)
  2037. len = GetOptimumFast(p);
  2038. else
  2039. {
  2040. unsigned oci = p->optCur;
  2041. if (p->optEnd == oci)
  2042. len = GetOptimum(p, nowPos32);
  2043. else
  2044. {
  2045. const COptimal *opt = &p->opt[oci];
  2046. len = opt->len;
  2047. p->backRes = opt->dist;
  2048. p->optCur = oci + 1;
  2049. }
  2050. }
  2051. posState = (unsigned)nowPos32 & p->pbMask;
  2052. range = p->rc.range;
  2053. probs = &p->isMatch[p->state][posState];
  2054. RC_BIT_PRE(&p->rc, probs)
  2055. dist = p->backRes;
  2056. #ifdef SHOW_STAT2
  2057. printf("\n pos = %6X, len = %3u pos = %6u", nowPos32, len, dist);
  2058. #endif
  2059. if (dist == MARK_LIT)
  2060. {
  2061. Byte curByte;
  2062. const Byte *data;
  2063. unsigned state;
  2064. RC_BIT_0(&p->rc, probs)
  2065. p->rc.range = range;
  2066. data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
  2067. probs = LIT_PROBS(nowPos32, *(data - 1));
  2068. curByte = *data;
  2069. state = p->state;
  2070. p->state = kLiteralNextStates[state];
  2071. if (IsLitState(state))
  2072. LitEnc_Encode(&p->rc, probs, curByte);
  2073. else
  2074. LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0]));
  2075. }
  2076. else
  2077. {
  2078. RC_BIT_1(&p->rc, probs)
  2079. probs = &p->isRep[p->state];
  2080. RC_BIT_PRE(&p->rc, probs)
  2081. if (dist < LZMA_NUM_REPS)
  2082. {
  2083. RC_BIT_1(&p->rc, probs)
  2084. probs = &p->isRepG0[p->state];
  2085. RC_BIT_PRE(&p->rc, probs)
  2086. if (dist == 0)
  2087. {
  2088. RC_BIT_0(&p->rc, probs)
  2089. probs = &p->isRep0Long[p->state][posState];
  2090. RC_BIT_PRE(&p->rc, probs)
  2091. if (len != 1)
  2092. {
  2093. RC_BIT_1_BASE(&p->rc, probs)
  2094. }
  2095. else
  2096. {
  2097. RC_BIT_0_BASE(&p->rc, probs)
  2098. p->state = kShortRepNextStates[p->state];
  2099. }
  2100. }
  2101. else
  2102. {
  2103. RC_BIT_1(&p->rc, probs)
  2104. probs = &p->isRepG1[p->state];
  2105. RC_BIT_PRE(&p->rc, probs)
  2106. if (dist == 1)
  2107. {
  2108. RC_BIT_0_BASE(&p->rc, probs)
  2109. dist = p->reps[1];
  2110. }
  2111. else
  2112. {
  2113. RC_BIT_1(&p->rc, probs)
  2114. probs = &p->isRepG2[p->state];
  2115. RC_BIT_PRE(&p->rc, probs)
  2116. if (dist == 2)
  2117. {
  2118. RC_BIT_0_BASE(&p->rc, probs)
  2119. dist = p->reps[2];
  2120. }
  2121. else
  2122. {
  2123. RC_BIT_1_BASE(&p->rc, probs)
  2124. dist = p->reps[3];
  2125. p->reps[3] = p->reps[2];
  2126. }
  2127. p->reps[2] = p->reps[1];
  2128. }
  2129. p->reps[1] = p->reps[0];
  2130. p->reps[0] = dist;
  2131. }
  2132. RC_NORM(&p->rc)
  2133. p->rc.range = range;
  2134. if (len != 1)
  2135. {
  2136. LenEnc_Encode(&p->repLenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState);
  2137. --p->repLenEncCounter;
  2138. p->state = kRepNextStates[p->state];
  2139. }
  2140. }
  2141. else
  2142. {
  2143. unsigned posSlot;
  2144. RC_BIT_0(&p->rc, probs)
  2145. p->rc.range = range;
  2146. p->state = kMatchNextStates[p->state];
  2147. LenEnc_Encode(&p->lenProbs, &p->rc, len - LZMA_MATCH_LEN_MIN, posState);
  2148. // --p->lenEnc.counter;
  2149. dist -= LZMA_NUM_REPS;
  2150. p->reps[3] = p->reps[2];
  2151. p->reps[2] = p->reps[1];
  2152. p->reps[1] = p->reps[0];
  2153. p->reps[0] = dist + 1;
  2154. p->matchPriceCount++;
  2155. GetPosSlot(dist, posSlot)
  2156. // RcTree_Encode_PosSlot(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], posSlot);
  2157. {
  2158. UInt32 sym = (UInt32)posSlot + (1 << kNumPosSlotBits);
  2159. range = p->rc.range;
  2160. probs = p->posSlotEncoder[GetLenToPosState(len)];
  2161. do
  2162. {
  2163. CLzmaProb *prob = probs + (sym >> kNumPosSlotBits);
  2164. UInt32 bit = (sym >> (kNumPosSlotBits - 1)) & 1;
  2165. sym <<= 1;
  2166. RC_BIT(&p->rc, prob, bit)
  2167. }
  2168. while (sym < (1 << kNumPosSlotBits * 2));
  2169. p->rc.range = range;
  2170. }
  2171. if (dist >= kStartPosModelIndex)
  2172. {
  2173. unsigned footerBits = ((posSlot >> 1) - 1);
  2174. if (dist < kNumFullDistances)
  2175. {
  2176. unsigned base = ((2 | (posSlot & 1)) << footerBits);
  2177. RcTree_ReverseEncode(&p->rc, p->posEncoders + base, footerBits, (unsigned)(dist /* - base */));
  2178. }
  2179. else
  2180. {
  2181. UInt32 pos2 = (dist | 0xF) << (32 - footerBits);
  2182. range = p->rc.range;
  2183. // RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
  2184. /*
  2185. do
  2186. {
  2187. range >>= 1;
  2188. p->rc.low += range & (0 - ((dist >> --footerBits) & 1));
  2189. RC_NORM(&p->rc)
  2190. }
  2191. while (footerBits > kNumAlignBits);
  2192. */
  2193. do
  2194. {
  2195. range >>= 1;
  2196. p->rc.low += range & (0 - (pos2 >> 31));
  2197. pos2 += pos2;
  2198. RC_NORM(&p->rc)
  2199. }
  2200. while (pos2 != 0xF0000000);
  2201. // RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
  2202. {
  2203. unsigned m = 1;
  2204. unsigned bit;
  2205. bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit;
  2206. bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit;
  2207. bit = dist & 1; dist >>= 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit) m = (m << 1) + bit;
  2208. bit = dist & 1; RC_BIT(&p->rc, p->posAlignEncoder + m, bit)
  2209. p->rc.range = range;
  2210. // p->alignPriceCount++;
  2211. }
  2212. }
  2213. }
  2214. }
  2215. }
  2216. nowPos32 += (UInt32)len;
  2217. p->additionalOffset -= len;
  2218. if (p->additionalOffset == 0)
  2219. {
  2220. UInt32 processed;
  2221. if (!p->fastMode)
  2222. {
  2223. /*
  2224. if (p->alignPriceCount >= 16) // kAlignTableSize
  2225. FillAlignPrices(p);
  2226. if (p->matchPriceCount >= 128)
  2227. FillDistancesPrices(p);
  2228. if (p->lenEnc.counter <= 0)
  2229. LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, &p->lenProbs, p->ProbPrices);
  2230. */
  2231. if (p->matchPriceCount >= 64)
  2232. {
  2233. FillAlignPrices(p);
  2234. // { int y; for (y = 0; y < 100; y++) {
  2235. FillDistancesPrices(p);
  2236. // }}
  2237. LenPriceEnc_UpdateTables(&p->lenEnc, (unsigned)1 << p->pb, &p->lenProbs, p->ProbPrices);
  2238. }
  2239. if (p->repLenEncCounter <= 0)
  2240. {
  2241. p->repLenEncCounter = REP_LEN_COUNT;
  2242. LenPriceEnc_UpdateTables(&p->repLenEnc, (unsigned)1 << p->pb, &p->repLenProbs, p->ProbPrices);
  2243. }
  2244. }
  2245. if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
  2246. break;
  2247. processed = nowPos32 - startPos32;
  2248. if (maxPackSize)
  2249. {
  2250. if (processed + kNumOpts + 300 >= maxUnpackSize
  2251. || RangeEnc_GetProcessed_sizet(&p->rc) + kPackReserve >= maxPackSize)
  2252. break;
  2253. }
  2254. else if (processed >= (1 << 17))
  2255. {
  2256. p->nowPos64 += nowPos32 - startPos32;
  2257. return CheckErrors(p);
  2258. }
  2259. }
  2260. }
  2261. p->nowPos64 += nowPos32 - startPos32;
  2262. return Flush(p, nowPos32);
  2263. }
  2264. #define kBigHashDicLimit ((UInt32)1 << 24)
  2265. static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
  2266. {
  2267. UInt32 beforeSize = kNumOpts;
  2268. UInt32 dictSize;
  2269. if (!RangeEnc_Alloc(&p->rc, alloc))
  2270. return SZ_ERROR_MEM;
  2271. #ifndef Z7_ST
  2272. p->mtMode = (p->multiThread && !p->fastMode && (MFB.btMode != 0));
  2273. #endif
  2274. {
  2275. const unsigned lclp = p->lc + p->lp;
  2276. if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp)
  2277. {
  2278. LzmaEnc_FreeLits(p, alloc);
  2279. p->litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((size_t)0x300 * sizeof(CLzmaProb)) << lclp);
  2280. p->saveState.litProbs = (CLzmaProb *)ISzAlloc_Alloc(alloc, ((size_t)0x300 * sizeof(CLzmaProb)) << lclp);
  2281. if (!p->litProbs || !p->saveState.litProbs)
  2282. {
  2283. LzmaEnc_FreeLits(p, alloc);
  2284. return SZ_ERROR_MEM;
  2285. }
  2286. p->lclp = lclp;
  2287. }
  2288. }
  2289. MFB.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0);
  2290. dictSize = p->dictSize;
  2291. if (dictSize == ((UInt32)2 << 30) ||
  2292. dictSize == ((UInt32)3 << 30))
  2293. {
  2294. /* 21.03 : here we reduce the dictionary for 2 reasons:
  2295. 1) we don't want 32-bit back_distance matches in decoder for 2 GB dictionary.
  2296. 2) we want to elimate useless last MatchFinder_Normalize3() for corner cases,
  2297. where data size is aligned for 1 GB: 5/6/8 GB.
  2298. That reducing must be >= 1 for such corner cases. */
  2299. dictSize -= 1;
  2300. }
  2301. if (beforeSize + dictSize < keepWindowSize)
  2302. beforeSize = keepWindowSize - dictSize;
  2303. /* in worst case we can look ahead for
  2304. max(LZMA_MATCH_LEN_MAX, numFastBytes + 1 + numFastBytes) bytes.
  2305. we send larger value for (keepAfter) to MantchFinder_Create():
  2306. (numFastBytes + LZMA_MATCH_LEN_MAX + 1)
  2307. */
  2308. #ifndef Z7_ST
  2309. if (p->mtMode)
  2310. {
  2311. RINOK(MatchFinderMt_Create(&p->matchFinderMt, dictSize, beforeSize,
  2312. p->numFastBytes, LZMA_MATCH_LEN_MAX + 1 /* 18.04 */
  2313. , allocBig))
  2314. p->matchFinderObj = &p->matchFinderMt;
  2315. MFB.bigHash = (Byte)(MFB.hashMask >= 0xFFFFFF ? 1 : 0);
  2316. MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
  2317. }
  2318. else
  2319. #endif
  2320. {
  2321. if (!MatchFinder_Create(&MFB, dictSize, beforeSize,
  2322. p->numFastBytes, LZMA_MATCH_LEN_MAX + 1 /* 21.03 */
  2323. , allocBig))
  2324. return SZ_ERROR_MEM;
  2325. p->matchFinderObj = &MFB;
  2326. MatchFinder_CreateVTable(&MFB, &p->matchFinder);
  2327. }
  2328. return SZ_OK;
  2329. }
  2330. static void LzmaEnc_Init(CLzmaEnc *p)
  2331. {
  2332. unsigned i;
  2333. p->state = 0;
  2334. p->reps[0] =
  2335. p->reps[1] =
  2336. p->reps[2] =
  2337. p->reps[3] = 1;
  2338. RangeEnc_Init(&p->rc);
  2339. for (i = 0; i < (1 << kNumAlignBits); i++)
  2340. p->posAlignEncoder[i] = kProbInitValue;
  2341. for (i = 0; i < kNumStates; i++)
  2342. {
  2343. unsigned j;
  2344. for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
  2345. {
  2346. p->isMatch[i][j] = kProbInitValue;
  2347. p->isRep0Long[i][j] = kProbInitValue;
  2348. }
  2349. p->isRep[i] = kProbInitValue;
  2350. p->isRepG0[i] = kProbInitValue;
  2351. p->isRepG1[i] = kProbInitValue;
  2352. p->isRepG2[i] = kProbInitValue;
  2353. }
  2354. {
  2355. for (i = 0; i < kNumLenToPosStates; i++)
  2356. {
  2357. CLzmaProb *probs = p->posSlotEncoder[i];
  2358. unsigned j;
  2359. for (j = 0; j < (1 << kNumPosSlotBits); j++)
  2360. probs[j] = kProbInitValue;
  2361. }
  2362. }
  2363. {
  2364. for (i = 0; i < kNumFullDistances; i++)
  2365. p->posEncoders[i] = kProbInitValue;
  2366. }
  2367. {
  2368. const size_t num = (size_t)0x300 << (p->lp + p->lc);
  2369. size_t k;
  2370. CLzmaProb *probs = p->litProbs;
  2371. for (k = 0; k < num; k++)
  2372. probs[k] = kProbInitValue;
  2373. }
  2374. LenEnc_Init(&p->lenProbs);
  2375. LenEnc_Init(&p->repLenProbs);
  2376. p->optEnd = 0;
  2377. p->optCur = 0;
  2378. {
  2379. for (i = 0; i < kNumOpts; i++)
  2380. p->opt[i].price = kInfinityPrice;
  2381. }
  2382. p->additionalOffset = 0;
  2383. p->pbMask = ((unsigned)1 << p->pb) - 1;
  2384. p->lpMask = ((UInt32)0x100 << p->lp) - ((unsigned)0x100 >> p->lc);
  2385. // p->mf_Failure = False;
  2386. }
  2387. static void LzmaEnc_InitPrices(CLzmaEnc *p)
  2388. {
  2389. if (!p->fastMode)
  2390. {
  2391. FillDistancesPrices(p);
  2392. FillAlignPrices(p);
  2393. }
  2394. p->lenEnc.tableSize =
  2395. p->repLenEnc.tableSize =
  2396. p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
  2397. p->repLenEncCounter = REP_LEN_COUNT;
  2398. LenPriceEnc_UpdateTables(&p->lenEnc, (unsigned)1 << p->pb, &p->lenProbs, p->ProbPrices);
  2399. LenPriceEnc_UpdateTables(&p->repLenEnc, (unsigned)1 << p->pb, &p->repLenProbs, p->ProbPrices);
  2400. }
  2401. static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAllocPtr alloc, ISzAllocPtr allocBig)
  2402. {
  2403. unsigned i;
  2404. for (i = kEndPosModelIndex / 2; i < kDicLogSizeMax; i++)
  2405. if (p->dictSize <= ((UInt32)1 << i))
  2406. break;
  2407. p->distTableSize = i * 2;
  2408. p->finished = False;
  2409. p->result = SZ_OK;
  2410. p->nowPos64 = 0;
  2411. p->needInit = 1;
  2412. RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig))
  2413. LzmaEnc_Init(p);
  2414. LzmaEnc_InitPrices(p);
  2415. return SZ_OK;
  2416. }
  2417. static SRes LzmaEnc_Prepare(CLzmaEncHandle p,
  2418. ISeqOutStreamPtr outStream,
  2419. ISeqInStreamPtr inStream,
  2420. ISzAllocPtr alloc, ISzAllocPtr allocBig)
  2421. {
  2422. // GET_CLzmaEnc_p
  2423. MatchFinder_SET_STREAM(&MFB, inStream)
  2424. p->rc.outStream = outStream;
  2425. return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
  2426. }
  2427. SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle p,
  2428. ISeqInStreamPtr inStream, UInt32 keepWindowSize,
  2429. ISzAllocPtr alloc, ISzAllocPtr allocBig)
  2430. {
  2431. // GET_CLzmaEnc_p
  2432. MatchFinder_SET_STREAM(&MFB, inStream)
  2433. return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
  2434. }
  2435. SRes LzmaEnc_MemPrepare(CLzmaEncHandle p,
  2436. const Byte *src, SizeT srcLen,
  2437. UInt32 keepWindowSize,
  2438. ISzAllocPtr alloc, ISzAllocPtr allocBig)
  2439. {
  2440. // GET_CLzmaEnc_p
  2441. MatchFinder_SET_DIRECT_INPUT_BUF(&MFB, src, srcLen)
  2442. LzmaEnc_SetDataSize(p, srcLen);
  2443. return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
  2444. }
  2445. void LzmaEnc_Finish(CLzmaEncHandle p)
  2446. {
  2447. #ifndef Z7_ST
  2448. // GET_CLzmaEnc_p
  2449. if (p->mtMode)
  2450. MatchFinderMt_ReleaseStream(&p->matchFinderMt);
  2451. #else
  2452. UNUSED_VAR(p)
  2453. #endif
  2454. }
  2455. typedef struct
  2456. {
  2457. ISeqOutStream vt;
  2458. Byte *data;
  2459. size_t rem;
  2460. BoolInt overflow;
  2461. } CLzmaEnc_SeqOutStreamBuf;
  2462. static size_t SeqOutStreamBuf_Write(ISeqOutStreamPtr pp, const void *data, size_t size)
  2463. {
  2464. Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(CLzmaEnc_SeqOutStreamBuf)
  2465. if (p->rem < size)
  2466. {
  2467. size = p->rem;
  2468. p->overflow = True;
  2469. }
  2470. if (size != 0)
  2471. {
  2472. memcpy(p->data, data, size);
  2473. p->rem -= size;
  2474. p->data += size;
  2475. }
  2476. return size;
  2477. }
  2478. /*
  2479. UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle p)
  2480. {
  2481. GET_const_CLzmaEnc_p
  2482. return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
  2483. }
  2484. */
  2485. const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle p)
  2486. {
  2487. // GET_const_CLzmaEnc_p
  2488. return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
  2489. }
  2490. // (desiredPackSize == 0) is not allowed
  2491. SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle p, BoolInt reInit,
  2492. Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
  2493. {
  2494. // GET_CLzmaEnc_p
  2495. UInt64 nowPos64;
  2496. SRes res;
  2497. CLzmaEnc_SeqOutStreamBuf outStream;
  2498. outStream.vt.Write = SeqOutStreamBuf_Write;
  2499. outStream.data = dest;
  2500. outStream.rem = *destLen;
  2501. outStream.overflow = False;
  2502. p->writeEndMark = False;
  2503. p->finished = False;
  2504. p->result = SZ_OK;
  2505. if (reInit)
  2506. LzmaEnc_Init(p);
  2507. LzmaEnc_InitPrices(p);
  2508. RangeEnc_Init(&p->rc);
  2509. p->rc.outStream = &outStream.vt;
  2510. nowPos64 = p->nowPos64;
  2511. res = LzmaEnc_CodeOneBlock(p, desiredPackSize, *unpackSize);
  2512. *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
  2513. *destLen -= outStream.rem;
  2514. if (outStream.overflow)
  2515. return SZ_ERROR_OUTPUT_EOF;
  2516. return res;
  2517. }
  2518. Z7_NO_INLINE
  2519. static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgressPtr progress)
  2520. {
  2521. SRes res = SZ_OK;
  2522. #ifndef Z7_ST
  2523. Byte allocaDummy[0x300];
  2524. allocaDummy[0] = 0;
  2525. allocaDummy[1] = allocaDummy[0];
  2526. #endif
  2527. for (;;)
  2528. {
  2529. res = LzmaEnc_CodeOneBlock(p, 0, 0);
  2530. if (res != SZ_OK || p->finished)
  2531. break;
  2532. if (progress)
  2533. {
  2534. res = ICompressProgress_Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
  2535. if (res != SZ_OK)
  2536. {
  2537. res = SZ_ERROR_PROGRESS;
  2538. break;
  2539. }
  2540. }
  2541. }
  2542. LzmaEnc_Finish((CLzmaEncHandle)(void *)p);
  2543. /*
  2544. if (res == SZ_OK && !Inline_MatchFinder_IsFinishedOK(&MFB))
  2545. res = SZ_ERROR_FAIL;
  2546. }
  2547. */
  2548. return res;
  2549. }
  2550. SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream, ICompressProgressPtr progress,
  2551. ISzAllocPtr alloc, ISzAllocPtr allocBig)
  2552. {
  2553. // GET_CLzmaEnc_p
  2554. RINOK(LzmaEnc_Prepare(p, outStream, inStream, alloc, allocBig))
  2555. return LzmaEnc_Encode2(p, progress);
  2556. }
  2557. SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *props, SizeT *size)
  2558. {
  2559. if (*size < LZMA_PROPS_SIZE)
  2560. return SZ_ERROR_PARAM;
  2561. *size = LZMA_PROPS_SIZE;
  2562. {
  2563. // GET_CLzmaEnc_p
  2564. const UInt32 dictSize = p->dictSize;
  2565. UInt32 v;
  2566. props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
  2567. // we write aligned dictionary value to properties for lzma decoder
  2568. if (dictSize >= ((UInt32)1 << 21))
  2569. {
  2570. const UInt32 kDictMask = ((UInt32)1 << 20) - 1;
  2571. v = (dictSize + kDictMask) & ~kDictMask;
  2572. if (v < dictSize)
  2573. v = dictSize;
  2574. }
  2575. else
  2576. {
  2577. unsigned i = 11 * 2;
  2578. do
  2579. {
  2580. v = (UInt32)(2 + (i & 1)) << (i >> 1);
  2581. i++;
  2582. }
  2583. while (v < dictSize);
  2584. }
  2585. SetUi32(props + 1, v)
  2586. return SZ_OK;
  2587. }
  2588. }
  2589. unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p)
  2590. {
  2591. // GET_CLzmaEnc_p
  2592. return (unsigned)p->writeEndMark;
  2593. }
  2594. SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
  2595. int writeEndMark, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
  2596. {
  2597. SRes res;
  2598. // GET_CLzmaEnc_p
  2599. CLzmaEnc_SeqOutStreamBuf outStream;
  2600. outStream.vt.Write = SeqOutStreamBuf_Write;
  2601. outStream.data = dest;
  2602. outStream.rem = *destLen;
  2603. outStream.overflow = False;
  2604. p->writeEndMark = writeEndMark;
  2605. p->rc.outStream = &outStream.vt;
  2606. res = LzmaEnc_MemPrepare(p, src, srcLen, 0, alloc, allocBig);
  2607. if (res == SZ_OK)
  2608. {
  2609. res = LzmaEnc_Encode2(p, progress);
  2610. if (res == SZ_OK && p->nowPos64 != srcLen)
  2611. res = SZ_ERROR_FAIL;
  2612. }
  2613. *destLen -= (SizeT)outStream.rem;
  2614. if (outStream.overflow)
  2615. return SZ_ERROR_OUTPUT_EOF;
  2616. return res;
  2617. }
  2618. SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
  2619. const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
  2620. ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig)
  2621. {
  2622. CLzmaEncHandle p = LzmaEnc_Create(alloc);
  2623. SRes res;
  2624. if (!p)
  2625. return SZ_ERROR_MEM;
  2626. res = LzmaEnc_SetProps(p, props);
  2627. if (res == SZ_OK)
  2628. {
  2629. res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
  2630. if (res == SZ_OK)
  2631. res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
  2632. writeEndMark, progress, alloc, allocBig);
  2633. }
  2634. LzmaEnc_Destroy(p, alloc, allocBig);
  2635. return res;
  2636. }
  2637. /*
  2638. #ifndef Z7_ST
  2639. void LzmaEnc_GetLzThreads(CLzmaEncHandle p, HANDLE lz_threads[2])
  2640. {
  2641. GET_const_CLzmaEnc_p
  2642. lz_threads[0] = p->matchFinderMt.hashSync.thread;
  2643. lz_threads[1] = p->matchFinderMt.btSync.thread;
  2644. }
  2645. #endif
  2646. */