1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* Lzma2Enc.c -- LZMA2 Encoder
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync2010-09-24 : Igor Pavlov : Public domain */
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* #include <stdio.h> */
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include <string.h>
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* #define _7ZIP_ST */
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "Lzma2Enc.h"
10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _7ZIP_ST
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "MtCoder.h"
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#else
14baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define NUM_MT_CODER_THREADS_MAX 1
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
17baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define LZMA2_CONTROL_LZMA (1 << 7)
18baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define LZMA2_CONTROL_COPY_NO_RESET 2
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define LZMA2_CONTROL_COPY_RESET_DIC 1
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define LZMA2_CONTROL_EOF 0
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define LZMA2_LCLP_MAX 4
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define LZMA2_PACK_SIZE_MAX (1 << 16)
27baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define LZMA2_COPY_CHUNK_SIZE LZMA2_PACK_SIZE_MAX
28baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define LZMA2_UNPACK_SIZE_MAX (1 << 21)
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define LZMA2_KEEP_WINDOW_SIZE LZMA2_UNPACK_SIZE_MAX
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
31baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define LZMA2_CHUNK_SIZE_COMPRESSED_MAX ((1 << 16) + 16)
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
34baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define PRF(x) /* x */
35baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* ---------- CLzma2EncInt ---------- */
37baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
38baa3858d3f5d128a5c8466b700098109edcad5f2repo synctypedef struct
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLzmaEncHandle enc;
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 srcPos;
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte props;
43baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Bool needInitState;
44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Bool needInitProp;
45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} CLzma2EncInt;
46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
47baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes Lzma2EncInt_Init(CLzma2EncInt *p, const CLzma2EncProps *props)
48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte propsEncoded[LZMA_PROPS_SIZE];
50baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SizeT propsSize = LZMA_PROPS_SIZE;
51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(LzmaEnc_SetProps(p->enc, &props->lzmaProps));
52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(LzmaEnc_WriteProperties(p->enc, propsEncoded, &propsSize));
53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->srcPos = 0;
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->props = propsEncoded[0];
55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->needInitState = True;
56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->needInitProp = True;
57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
60baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, ISeqInStream *inStream, UInt32 keepWindowSize,
61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISzAlloc *alloc, ISzAlloc *allocBig);
62baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig);
64baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize);
66baa3858d3f5d128a5c8466b700098109edcad5f2repo syncconst Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp);
67baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid LzmaEnc_Finish(CLzmaEncHandle pp);
68baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid LzmaEnc_SaveState(CLzmaEncHandle pp);
69baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid LzmaEnc_RestoreState(CLzmaEncHandle pp);
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
72baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes Lzma2EncInt_EncodeSubblock(CLzma2EncInt *p, Byte *outBuf,
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t *packSizeRes, ISeqOutStream *outStream)
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
75baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t packSizeLimit = *packSizeRes;
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  size_t packSize = packSizeLimit;
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 unpackSize = LZMA2_UNPACK_SIZE_MAX;
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  unsigned lzHeaderSize = 5 + (p->needInitProp ? 1 : 0);
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Bool useCopyBlock;
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SRes res;
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  *packSizeRes = 0;
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (packSize < lzHeaderSize)
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_OUTPUT_EOF;
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  packSize -= lzHeaderSize;
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LzmaEnc_SaveState(p->enc);
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  res = LzmaEnc_CodeOneMemBlock(p->enc, p->needInitState,
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outBuf + lzHeaderSize, &packSize, LZMA2_PACK_SIZE_MAX, &unpackSize);
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
91baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  PRF(printf("\npackSize = %7d unpackSize = %7d  ", packSize, unpackSize));
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (unpackSize == 0)
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return res;
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (res == SZ_OK)
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    useCopyBlock = (packSize + 2 >= unpackSize || packSize > (1 << 16));
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (res != SZ_ERROR_OUTPUT_EOF)
101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return res;
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    res = SZ_OK;
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    useCopyBlock = True;
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (useCopyBlock)
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t destPos = 0;
109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    PRF(printf("################# COPY           "));
110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    while (unpackSize > 0)
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      UInt32 u = (unpackSize < LZMA2_COPY_CHUNK_SIZE) ? unpackSize : LZMA2_COPY_CHUNK_SIZE;
113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (packSizeLimit - destPos < u + 3)
114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return SZ_ERROR_OUTPUT_EOF;
115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outBuf[destPos++] = (Byte)(p->srcPos == 0 ? LZMA2_CONTROL_COPY_RESET_DIC : LZMA2_CONTROL_COPY_NO_RESET);
116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outBuf[destPos++] = (Byte)((u - 1) >> 8);
117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outBuf[destPos++] = (Byte)(u - 1);
118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      memcpy(outBuf + destPos, LzmaEnc_GetCurBuf(p->enc) - unpackSize, u);
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      unpackSize -= u;
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      destPos += u;
121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      p->srcPos += u;
122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (outStream)
123baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        *packSizeRes += destPos;
125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (outStream->Write(outStream, outBuf, destPos) != destPos)
126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          return SZ_ERROR_WRITE;
127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        destPos = 0;
128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      else
130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        *packSizeRes = destPos;
131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      /* needInitState = True; */
132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    LzmaEnc_RestoreState(p->enc);
134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_OK;
135baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t destPos = 0;
138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 u = unpackSize - 1;
139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 pm = (UInt32)(packSize - 1);
140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    unsigned mode = (p->srcPos == 0) ? 3 : (p->needInitState ? (p->needInitProp ? 2 : 1) : 0);
141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    PRF(printf("               "));
143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    outBuf[destPos++] = (Byte)(LZMA2_CONTROL_LZMA | (mode << 5) | ((u >> 16) & 0x1F));
145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    outBuf[destPos++] = (Byte)(u >> 8);
146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    outBuf[destPos++] = (Byte)u;
147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    outBuf[destPos++] = (Byte)(pm >> 8);
148baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    outBuf[destPos++] = (Byte)pm;
149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (p->needInitProp)
151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      outBuf[destPos++] = p->props;
152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->needInitProp = False;
154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->needInitState = False;
155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    destPos += packSize;
156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->srcPos += unpackSize;
157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (outStream)
159baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (outStream->Write(outStream, outBuf, destPos) != destPos)
160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return SZ_ERROR_WRITE;
161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *packSizeRes = destPos;
162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_OK;
163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* ---------- Lzma2 Props ---------- */
167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
168baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid Lzma2EncProps_Init(CLzma2EncProps *p)
169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LzmaEncProps_Init(&p->lzmaProps);
171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->numTotalThreads = -1;
172baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->numBlockThreads = -1;
173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->blockSize = 0;
174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
176baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid Lzma2EncProps_Normalize(CLzma2EncProps *p)
177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int t1, t1n, t2, t3;
179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CLzmaEncProps lzmaProps = p->lzmaProps;
181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    LzmaEncProps_Normalize(&lzmaProps);
182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    t1n = lzmaProps.numThreads;
183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  t1 = p->lzmaProps.numThreads;
186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  t2 = p->numBlockThreads;
187baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  t3 = p->numTotalThreads;
188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (t2 > NUM_MT_CODER_THREADS_MAX)
190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    t2 = NUM_MT_CODER_THREADS_MAX;
191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (t3 <= 0)
193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (t2 <= 0)
195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      t2 = 1;
196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    t3 = t1n * t2;
197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else if (t2 <= 0)
199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    t2 = t3 / t1n;
201baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (t2 == 0)
202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      t1 = 1;
204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      t2 = t3;
205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (t2 > NUM_MT_CODER_THREADS_MAX)
207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      t2 = NUM_MT_CODER_THREADS_MAX;
208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else if (t1 <= 0)
210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    t1 = t3 / t2;
212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (t1 == 0)
213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      t1 = 1;
214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
216baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    t3 = t1n * t2;
217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->lzmaProps.numThreads = t1;
219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->numBlockThreads = t2;
220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->numTotalThreads = t3;
221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LzmaEncProps_Normalize(&p->lzmaProps);
222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (p->blockSize == 0)
224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt32 dictSize = p->lzmaProps.dictSize;
226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UInt64 blockSize = (UInt64)dictSize << 2;
227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const UInt32 kMinSize = (UInt32)1 << 20;
228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const UInt32 kMaxSize = (UInt32)1 << 28;
229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (blockSize < kMinSize) blockSize = kMinSize;
230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (blockSize > kMaxSize) blockSize = kMaxSize;
231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (blockSize < dictSize) blockSize = dictSize;
232baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->blockSize = (size_t)blockSize;
233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
236baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes Progress(ICompressProgress *p, UInt64 inSize, UInt64 outSize)
237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (p && p->Progress(p, inSize, outSize) != SZ_OK) ? SZ_ERROR_PROGRESS : SZ_OK;
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* ---------- Lzma2 ---------- */
242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
243baa3858d3f5d128a5c8466b700098109edcad5f2repo synctypedef struct
244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte propEncoded;
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLzma2EncProps props;
247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Byte *outBuf;
249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ISzAlloc *alloc;
251baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ISzAlloc *allocBig;
252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLzma2EncInt coders[NUM_MT_CODER_THREADS_MAX];
254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMtCoder mtCoder;
257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} CLzma2Enc;
260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* ---------- Lzma2EncThread ---------- */
263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
264baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes Lzma2Enc_EncodeMt1(CLzma2EncInt *p, CLzma2Enc *mainEncoder,
265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress)
266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt64 packTotal = 0;
268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SRes res = SZ_OK;
269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (mainEncoder->outBuf == 0)
271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    mainEncoder->outBuf = (Byte *)IAlloc_Alloc(mainEncoder->alloc, LZMA2_CHUNK_SIZE_COMPRESSED_MAX);
273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (mainEncoder->outBuf == 0)
274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_ERROR_MEM;
275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  RINOK(LzmaEnc_PrepareForLzma2(p->enc, inStream, LZMA2_KEEP_WINDOW_SIZE,
278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      mainEncoder->alloc, mainEncoder->allocBig));
279baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t packSize = LZMA2_CHUNK_SIZE_COMPRESSED_MAX;
282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    res = Lzma2EncInt_EncodeSubblock(p, mainEncoder->outBuf, &packSize, outStream);
283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (res != SZ_OK)
284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    packTotal += packSize;
286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    res = Progress(progress, p->srcPos, packTotal);
287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (res != SZ_OK)
288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (packSize == 0)
290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LzmaEnc_Finish(p->enc);
293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (res == SZ_OK)
294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    Byte b = 0;
296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (outStream->Write(outStream, &b, 1) != 1)
297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return SZ_ERROR_WRITE;
298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return res;
300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _7ZIP_ST
303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
304baa3858d3f5d128a5c8466b700098109edcad5f2repo synctypedef struct
305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IMtCoderCallback funcTable;
307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLzma2Enc *lzma2Enc;
308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync} CMtCallbackImp;
309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
310baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic SRes MtCallbackImp_Code(void *pp, unsigned index, Byte *dest, size_t *destSize,
311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      const Byte *src, size_t srcSize, int finished)
312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CMtCallbackImp *imp = (CMtCallbackImp *)pp;
314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLzma2Enc *mainEncoder = imp->lzma2Enc;
315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLzma2EncInt *p = &mainEncoder->coders[index];
316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  SRes res = SZ_OK;
318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    size_t destLim = *destSize;
320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    *destSize = 0;
321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (srcSize != 0)
323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(Lzma2EncInt_Init(p, &mainEncoder->props));
325baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      RINOK(LzmaEnc_MemPrepare(p->enc, src, srcSize, LZMA2_KEEP_WINDOW_SIZE,
327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          mainEncoder->alloc, mainEncoder->allocBig));
328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      while (p->srcPos < srcSize)
330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      {
331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        size_t packSize = destLim - *destSize;
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        res = Lzma2EncInt_EncodeSubblock(p, dest + *destSize, &packSize, NULL);
333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (res != SZ_OK)
334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          break;
335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        *destSize += packSize;
336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (packSize == 0)
338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          res = SZ_ERROR_FAIL;
340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          break;
341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        if (MtProgress_Set(&mainEncoder->mtCoder.mtProgress, index, p->srcPos, *destSize) != SZ_OK)
344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        {
345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          res = SZ_ERROR_PROGRESS;
346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync          break;
347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        }
348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      }
349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      LzmaEnc_Finish(p->enc);
350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (res != SZ_OK)
351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return res;
352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (finished)
354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (*destSize == destLim)
356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return SZ_ERROR_OUTPUT_EOF;
357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      dest[(*destSize)++] = 0;
358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return res;
361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/* ---------- Lzma2Enc ---------- */
366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
367baa3858d3f5d128a5c8466b700098109edcad5f2repo syncCLzma2EncHandle Lzma2Enc_Create(ISzAlloc *alloc, ISzAlloc *allocBig)
368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLzma2Enc *p = (CLzma2Enc *)alloc->Alloc(alloc, sizeof(CLzma2Enc));
370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (p == 0)
371baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return NULL;
372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Lzma2EncProps_Init(&p->props);
373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Lzma2EncProps_Normalize(&p->props);
374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->outBuf = 0;
375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->alloc = alloc;
376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->allocBig = allocBig;
377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    unsigned i;
379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      p->coders[i].enc = 0;
381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MtCoder_Construct(&p->mtCoder);
384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
386baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return p;
387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
389baa3858d3f5d128a5c8466b700098109edcad5f2repo syncvoid Lzma2Enc_Destroy(CLzma2EncHandle pp)
390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLzma2Enc *p = (CLzma2Enc *)pp;
392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  unsigned i;
393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < NUM_MT_CODER_THREADS_MAX; i++)
394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CLzma2EncInt *t = &p->coders[i];
396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (t->enc)
397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      LzmaEnc_Destroy(t->enc, p->alloc, p->allocBig);
399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      t->enc = 0;
400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
403baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  MtCoder_Destruct(&p->mtCoder);
405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(p->alloc, p->outBuf);
408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  IAlloc_Free(p->alloc, pp);
409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
410baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
411baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSRes Lzma2Enc_SetProps(CLzma2EncHandle pp, const CLzma2EncProps *props)
412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLzma2Enc *p = (CLzma2Enc *)pp;
414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLzmaEncProps lzmaProps = props->lzmaProps;
415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LzmaEncProps_Normalize(&lzmaProps);
416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (lzmaProps.lc + lzmaProps.lp > LZMA2_LCLP_MAX)
417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return SZ_ERROR_PARAM;
418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  p->props = *props;
419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Lzma2EncProps_Normalize(&p->props);
420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return SZ_OK;
421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
423baa3858d3f5d128a5c8466b700098109edcad5f2repo syncByte Lzma2Enc_WriteProperties(CLzma2EncHandle pp)
424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLzma2Enc *p = (CLzma2Enc *)pp;
426baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  unsigned i;
427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UInt32 dicSize = LzmaEncProps_GetDictSize(&p->props.lzmaProps);
428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < 40; i++)
429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (dicSize <= LZMA2_DIC_SIZE_FROM_PROP(i))
430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (Byte)i;
432baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
434baa3858d3f5d128a5c8466b700098109edcad5f2repo syncSRes Lzma2Enc_Encode(CLzma2EncHandle pp,
435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress)
436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CLzma2Enc *p = (CLzma2Enc *)pp;
438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i;
439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = 0; i < p->props.numBlockThreads; i++)
441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CLzma2EncInt *t = &p->coders[i];
443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (t->enc == NULL)
444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      t->enc = LzmaEnc_Create(p->alloc);
446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (t->enc == NULL)
447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return SZ_ERROR_MEM;
448baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (p->props.numBlockThreads <= 1)
453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return Lzma2Enc_EncodeMt1(&p->coders[0], p, outStream, inStream, progress);
455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _7ZIP_ST
457baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CMtCallbackImp mtCallback;
460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    mtCallback.funcTable.Code = MtCallbackImp_Code;
462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    mtCallback.lzma2Enc = p;
463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->mtCoder.progress = progress;
465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->mtCoder.inStream = inStream;
466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->mtCoder.outStream = outStream;
467baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->mtCoder.alloc = p->alloc;
468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->mtCoder.mtCallback = &mtCallback.funcTable;
469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->mtCoder.blockSize = p->props.blockSize;
471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->mtCoder.destBlockSize = p->props.blockSize + (p->props.blockSize >> 10) + 16;
472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    p->mtCoder.numThreads = p->props.numBlockThreads;
473baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return MtCoder_Code(&p->mtCoder);
475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
478