xref: /aosp_15_r20/external/lzma/C/Bcj2.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker /* Bcj2.h -- BCJ2 converter for x86 code (Branch CALL/JUMP variant2)
2*f6dc9357SAndroid Build Coastguard Worker 2023-03-02 : Igor Pavlov : Public domain */
3*f6dc9357SAndroid Build Coastguard Worker 
4*f6dc9357SAndroid Build Coastguard Worker #ifndef ZIP7_INC_BCJ2_H
5*f6dc9357SAndroid Build Coastguard Worker #define ZIP7_INC_BCJ2_H
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "7zTypes.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_BEGIN
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker #define BCJ2_NUM_STREAMS 4
12*f6dc9357SAndroid Build Coastguard Worker 
13*f6dc9357SAndroid Build Coastguard Worker enum
14*f6dc9357SAndroid Build Coastguard Worker {
15*f6dc9357SAndroid Build Coastguard Worker   BCJ2_STREAM_MAIN,
16*f6dc9357SAndroid Build Coastguard Worker   BCJ2_STREAM_CALL,
17*f6dc9357SAndroid Build Coastguard Worker   BCJ2_STREAM_JUMP,
18*f6dc9357SAndroid Build Coastguard Worker   BCJ2_STREAM_RC
19*f6dc9357SAndroid Build Coastguard Worker };
20*f6dc9357SAndroid Build Coastguard Worker 
21*f6dc9357SAndroid Build Coastguard Worker enum
22*f6dc9357SAndroid Build Coastguard Worker {
23*f6dc9357SAndroid Build Coastguard Worker   BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS,
24*f6dc9357SAndroid Build Coastguard Worker   BCJ2_DEC_STATE_ORIG_1,
25*f6dc9357SAndroid Build Coastguard Worker   BCJ2_DEC_STATE_ORIG_2,
26*f6dc9357SAndroid Build Coastguard Worker   BCJ2_DEC_STATE_ORIG_3,
27*f6dc9357SAndroid Build Coastguard Worker 
28*f6dc9357SAndroid Build Coastguard Worker   BCJ2_DEC_STATE_ORIG,
29*f6dc9357SAndroid Build Coastguard Worker   BCJ2_DEC_STATE_ERROR     /* after detected data error */
30*f6dc9357SAndroid Build Coastguard Worker };
31*f6dc9357SAndroid Build Coastguard Worker 
32*f6dc9357SAndroid Build Coastguard Worker enum
33*f6dc9357SAndroid Build Coastguard Worker {
34*f6dc9357SAndroid Build Coastguard Worker   BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS,
35*f6dc9357SAndroid Build Coastguard Worker   BCJ2_ENC_STATE_FINISHED  /* it's state after fully encoded stream */
36*f6dc9357SAndroid Build Coastguard Worker };
37*f6dc9357SAndroid Build Coastguard Worker 
38*f6dc9357SAndroid Build Coastguard Worker 
39*f6dc9357SAndroid Build Coastguard Worker /* #define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) */
40*f6dc9357SAndroid Build Coastguard Worker #define BCJ2_IS_32BIT_STREAM(s) ((unsigned)((unsigned)(s) - (unsigned)BCJ2_STREAM_CALL) < 2)
41*f6dc9357SAndroid Build Coastguard Worker 
42*f6dc9357SAndroid Build Coastguard Worker /*
43*f6dc9357SAndroid Build Coastguard Worker CBcj2Dec / CBcj2Enc
44*f6dc9357SAndroid Build Coastguard Worker bufs sizes:
45*f6dc9357SAndroid Build Coastguard Worker   BUF_SIZE(n) = lims[n] - bufs[n]
46*f6dc9357SAndroid Build Coastguard Worker bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be multiply of 4:
47*f6dc9357SAndroid Build Coastguard Worker     (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0
48*f6dc9357SAndroid Build Coastguard Worker     (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0
49*f6dc9357SAndroid Build Coastguard Worker */
50*f6dc9357SAndroid Build Coastguard Worker 
51*f6dc9357SAndroid Build Coastguard Worker // typedef UInt32 CBcj2Prob;
52*f6dc9357SAndroid Build Coastguard Worker typedef UInt16 CBcj2Prob;
53*f6dc9357SAndroid Build Coastguard Worker 
54*f6dc9357SAndroid Build Coastguard Worker /*
55*f6dc9357SAndroid Build Coastguard Worker BCJ2 encoder / decoder internal requirements:
56*f6dc9357SAndroid Build Coastguard Worker   - If last bytes of stream contain marker (e8/e8/0f8x), then
57*f6dc9357SAndroid Build Coastguard Worker     there is also encoded symbol (0 : no conversion) in RC stream.
58*f6dc9357SAndroid Build Coastguard Worker   - One case of overlapped instructions is supported,
59*f6dc9357SAndroid Build Coastguard Worker     if last byte of converted instruction is (0f) and next byte is (8x):
60*f6dc9357SAndroid Build Coastguard Worker       marker [xx xx xx 0f] 8x
61*f6dc9357SAndroid Build Coastguard Worker     then the pair (0f 8x) is treated as marker.
62*f6dc9357SAndroid Build Coastguard Worker */
63*f6dc9357SAndroid Build Coastguard Worker 
64*f6dc9357SAndroid Build Coastguard Worker /* ---------- BCJ2 Decoder ---------- */
65*f6dc9357SAndroid Build Coastguard Worker 
66*f6dc9357SAndroid Build Coastguard Worker /*
67*f6dc9357SAndroid Build Coastguard Worker CBcj2Dec:
68*f6dc9357SAndroid Build Coastguard Worker (dest) is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions:
69*f6dc9357SAndroid Build Coastguard Worker   bufs[BCJ2_STREAM_MAIN] >= dest &&
70*f6dc9357SAndroid Build Coastguard Worker   bufs[BCJ2_STREAM_MAIN] - dest >=
71*f6dc9357SAndroid Build Coastguard Worker         BUF_SIZE(BCJ2_STREAM_CALL) +
72*f6dc9357SAndroid Build Coastguard Worker         BUF_SIZE(BCJ2_STREAM_JUMP)
73*f6dc9357SAndroid Build Coastguard Worker   reserve = bufs[BCJ2_STREAM_MAIN] - dest -
74*f6dc9357SAndroid Build Coastguard Worker       ( BUF_SIZE(BCJ2_STREAM_CALL) +
75*f6dc9357SAndroid Build Coastguard Worker         BUF_SIZE(BCJ2_STREAM_JUMP) )
76*f6dc9357SAndroid Build Coastguard Worker   and additional conditions:
77*f6dc9357SAndroid Build Coastguard Worker   if (it's first call of Bcj2Dec_Decode() after Bcj2Dec_Init())
78*f6dc9357SAndroid Build Coastguard Worker   {
79*f6dc9357SAndroid Build Coastguard Worker     (reserve != 1) : if (ver <  v23.00)
80*f6dc9357SAndroid Build Coastguard Worker   }
81*f6dc9357SAndroid Build Coastguard Worker   else // if there are more than one calls of Bcj2Dec_Decode() after Bcj2Dec_Init())
82*f6dc9357SAndroid Build Coastguard Worker   {
83*f6dc9357SAndroid Build Coastguard Worker     (reserve >= 6) : if (ver <  v23.00)
84*f6dc9357SAndroid Build Coastguard Worker     (reserve >= 4) : if (ver >= v23.00)
85*f6dc9357SAndroid Build Coastguard Worker     We need that (reserve) because after first call of Bcj2Dec_Decode(),
86*f6dc9357SAndroid Build Coastguard Worker     CBcj2Dec::temp can contain up to 4 bytes for writing to (dest).
87*f6dc9357SAndroid Build Coastguard Worker   }
88*f6dc9357SAndroid Build Coastguard Worker   (reserve == 0) is allowed, if we decode full stream via single call of Bcj2Dec_Decode().
89*f6dc9357SAndroid Build Coastguard Worker   (reserve == 0) also is allowed in case of multi-call, if we use fixed buffers,
90*f6dc9357SAndroid Build Coastguard Worker      and (reserve) is calculated from full (final) sizes of all streams before first call.
91*f6dc9357SAndroid Build Coastguard Worker */
92*f6dc9357SAndroid Build Coastguard Worker 
93*f6dc9357SAndroid Build Coastguard Worker typedef struct
94*f6dc9357SAndroid Build Coastguard Worker {
95*f6dc9357SAndroid Build Coastguard Worker   const Byte *bufs[BCJ2_NUM_STREAMS];
96*f6dc9357SAndroid Build Coastguard Worker   const Byte *lims[BCJ2_NUM_STREAMS];
97*f6dc9357SAndroid Build Coastguard Worker   Byte *dest;
98*f6dc9357SAndroid Build Coastguard Worker   const Byte *destLim;
99*f6dc9357SAndroid Build Coastguard Worker 
100*f6dc9357SAndroid Build Coastguard Worker   unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */
101*f6dc9357SAndroid Build Coastguard Worker 
102*f6dc9357SAndroid Build Coastguard Worker   UInt32 ip;      /* property of starting base for decoding */
103*f6dc9357SAndroid Build Coastguard Worker   UInt32 temp;    /* Byte temp[4]; */
104*f6dc9357SAndroid Build Coastguard Worker   UInt32 range;
105*f6dc9357SAndroid Build Coastguard Worker   UInt32 code;
106*f6dc9357SAndroid Build Coastguard Worker   CBcj2Prob probs[2 + 256];
107*f6dc9357SAndroid Build Coastguard Worker } CBcj2Dec;
108*f6dc9357SAndroid Build Coastguard Worker 
109*f6dc9357SAndroid Build Coastguard Worker 
110*f6dc9357SAndroid Build Coastguard Worker /* Note:
111*f6dc9357SAndroid Build Coastguard Worker    Bcj2Dec_Init() sets (CBcj2Dec::ip = 0)
112*f6dc9357SAndroid Build Coastguard Worker    if (ip != 0) property is required, the caller must set CBcj2Dec::ip after Bcj2Dec_Init()
113*f6dc9357SAndroid Build Coastguard Worker */
114*f6dc9357SAndroid Build Coastguard Worker void Bcj2Dec_Init(CBcj2Dec *p);
115*f6dc9357SAndroid Build Coastguard Worker 
116*f6dc9357SAndroid Build Coastguard Worker 
117*f6dc9357SAndroid Build Coastguard Worker /* Bcj2Dec_Decode():
118*f6dc9357SAndroid Build Coastguard Worker    returns:
119*f6dc9357SAndroid Build Coastguard Worker      SZ_OK
120*f6dc9357SAndroid Build Coastguard Worker      SZ_ERROR_DATA : if data in 5 starting bytes of BCJ2_STREAM_RC stream are not correct
121*f6dc9357SAndroid Build Coastguard Worker */
122*f6dc9357SAndroid Build Coastguard Worker SRes Bcj2Dec_Decode(CBcj2Dec *p);
123*f6dc9357SAndroid Build Coastguard Worker 
124*f6dc9357SAndroid Build Coastguard Worker /* To check that decoding was finished you can compare
125*f6dc9357SAndroid Build Coastguard Worker    sizes of processed streams with sizes known from another sources.
126*f6dc9357SAndroid Build Coastguard Worker    You must do at least one mandatory check from the two following options:
127*f6dc9357SAndroid Build Coastguard Worker       - the check for size of processed output (ORIG) stream.
128*f6dc9357SAndroid Build Coastguard Worker       - the check for size of processed input  (MAIN) stream.
129*f6dc9357SAndroid Build Coastguard Worker    additional optional checks:
130*f6dc9357SAndroid Build Coastguard Worker       - the checks for processed sizes of all input streams (MAIN, CALL, JUMP, RC)
131*f6dc9357SAndroid Build Coastguard Worker       - the checks Bcj2Dec_IsMaybeFinished*()
132*f6dc9357SAndroid Build Coastguard Worker    also before actual decoding you can check that the
133*f6dc9357SAndroid Build Coastguard Worker    following condition is met for stream sizes:
134*f6dc9357SAndroid Build Coastguard Worker      ( size(ORIG) == size(MAIN) + size(CALL) + size(JUMP) )
135*f6dc9357SAndroid Build Coastguard Worker */
136*f6dc9357SAndroid Build Coastguard Worker 
137*f6dc9357SAndroid Build Coastguard Worker /* (state == BCJ2_STREAM_MAIN) means that decoder is ready for
138*f6dc9357SAndroid Build Coastguard Worker       additional input data in BCJ2_STREAM_MAIN stream.
139*f6dc9357SAndroid Build Coastguard Worker    Note that (state == BCJ2_STREAM_MAIN) is allowed for non-finished decoding.
140*f6dc9357SAndroid Build Coastguard Worker */
141*f6dc9357SAndroid Build Coastguard Worker #define Bcj2Dec_IsMaybeFinished_state_MAIN(_p_) ((_p_)->state == BCJ2_STREAM_MAIN)
142*f6dc9357SAndroid Build Coastguard Worker 
143*f6dc9357SAndroid Build Coastguard Worker /* if the stream decoding was finished correctly, then range decoder
144*f6dc9357SAndroid Build Coastguard Worker    part of CBcj2Dec also was finished, and then (CBcj2Dec::code == 0).
145*f6dc9357SAndroid Build Coastguard Worker    Note that (CBcj2Dec::code == 0) is allowed for non-finished decoding.
146*f6dc9357SAndroid Build Coastguard Worker */
147*f6dc9357SAndroid Build Coastguard Worker #define Bcj2Dec_IsMaybeFinished_code(_p_) ((_p_)->code == 0)
148*f6dc9357SAndroid Build Coastguard Worker 
149*f6dc9357SAndroid Build Coastguard Worker /* use Bcj2Dec_IsMaybeFinished() only as additional check
150*f6dc9357SAndroid Build Coastguard Worker     after at least one mandatory check from the two following options:
151*f6dc9357SAndroid Build Coastguard Worker       - the check for size of processed output (ORIG) stream.
152*f6dc9357SAndroid Build Coastguard Worker       - the check for size of processed input  (MAIN) stream.
153*f6dc9357SAndroid Build Coastguard Worker */
154*f6dc9357SAndroid Build Coastguard Worker #define Bcj2Dec_IsMaybeFinished(_p_) ( \
155*f6dc9357SAndroid Build Coastguard Worker         Bcj2Dec_IsMaybeFinished_state_MAIN(_p_) && \
156*f6dc9357SAndroid Build Coastguard Worker         Bcj2Dec_IsMaybeFinished_code(_p_))
157*f6dc9357SAndroid Build Coastguard Worker 
158*f6dc9357SAndroid Build Coastguard Worker 
159*f6dc9357SAndroid Build Coastguard Worker 
160*f6dc9357SAndroid Build Coastguard Worker /* ---------- BCJ2 Encoder ---------- */
161*f6dc9357SAndroid Build Coastguard Worker 
162*f6dc9357SAndroid Build Coastguard Worker typedef enum
163*f6dc9357SAndroid Build Coastguard Worker {
164*f6dc9357SAndroid Build Coastguard Worker   BCJ2_ENC_FINISH_MODE_CONTINUE,
165*f6dc9357SAndroid Build Coastguard Worker   BCJ2_ENC_FINISH_MODE_END_BLOCK,
166*f6dc9357SAndroid Build Coastguard Worker   BCJ2_ENC_FINISH_MODE_END_STREAM
167*f6dc9357SAndroid Build Coastguard Worker } EBcj2Enc_FinishMode;
168*f6dc9357SAndroid Build Coastguard Worker 
169*f6dc9357SAndroid Build Coastguard Worker /*
170*f6dc9357SAndroid Build Coastguard Worker   BCJ2_ENC_FINISH_MODE_CONTINUE:
171*f6dc9357SAndroid Build Coastguard Worker      process non finished encoding.
172*f6dc9357SAndroid Build Coastguard Worker      It notifies the encoder that additional further calls
173*f6dc9357SAndroid Build Coastguard Worker      can provide more input data (src) than provided by current call.
174*f6dc9357SAndroid Build Coastguard Worker      In  that case the CBcj2Enc encoder still can move (src) pointer
175*f6dc9357SAndroid Build Coastguard Worker      up to (srcLim), but CBcj2Enc encoder can store some of the last
176*f6dc9357SAndroid Build Coastguard Worker      processed bytes (up to 4 bytes) from src to internal CBcj2Enc::temp[] buffer.
177*f6dc9357SAndroid Build Coastguard Worker    at return:
178*f6dc9357SAndroid Build Coastguard Worker        (CBcj2Enc::src will point to position that includes
179*f6dc9357SAndroid Build Coastguard Worker        processed data and data copied to (temp[]) buffer)
180*f6dc9357SAndroid Build Coastguard Worker        That data from (temp[]) buffer will be used in further calls.
181*f6dc9357SAndroid Build Coastguard Worker 
182*f6dc9357SAndroid Build Coastguard Worker   BCJ2_ENC_FINISH_MODE_END_BLOCK:
183*f6dc9357SAndroid Build Coastguard Worker      finish encoding of current block (ended at srcLim) without RC flushing.
184*f6dc9357SAndroid Build Coastguard Worker    at return: if (CBcj2Enc::state == BCJ2_ENC_STATE_ORIG) &&
185*f6dc9357SAndroid Build Coastguard Worker                   CBcj2Enc::src == CBcj2Enc::srcLim)
186*f6dc9357SAndroid Build Coastguard Worker         :  it shows that block encoding was finished. And the encoder is
187*f6dc9357SAndroid Build Coastguard Worker            ready for new (src) data or for stream finish operation.
188*f6dc9357SAndroid Build Coastguard Worker      finished block means
189*f6dc9357SAndroid Build Coastguard Worker      {
190*f6dc9357SAndroid Build Coastguard Worker        CBcj2Enc has completed block encoding up to (srcLim).
191*f6dc9357SAndroid Build Coastguard Worker        (1 + 4 bytes) or (2 + 4 bytes) CALL/JUMP cortages will
192*f6dc9357SAndroid Build Coastguard Worker        not cross block boundary at (srcLim).
193*f6dc9357SAndroid Build Coastguard Worker        temporary CBcj2Enc buffer for (ORIG) src data is empty.
194*f6dc9357SAndroid Build Coastguard Worker        3 output uncompressed streams (MAIN, CALL, JUMP) were flushed.
195*f6dc9357SAndroid Build Coastguard Worker        RC stream was not flushed. And RC stream will cross block boundary.
196*f6dc9357SAndroid Build Coastguard Worker      }
197*f6dc9357SAndroid Build Coastguard Worker      Note: some possible implementation of BCJ2 encoder could
198*f6dc9357SAndroid Build Coastguard Worker      write branch marker (e8/e8/0f8x) in one call of Bcj2Enc_Encode(),
199*f6dc9357SAndroid Build Coastguard Worker      and it could calculate symbol for RC in another call of Bcj2Enc_Encode().
200*f6dc9357SAndroid Build Coastguard Worker      BCJ2 encoder uses ip/fileIp/fileSize/relatLimit values to calculate RC symbol.
201*f6dc9357SAndroid Build Coastguard Worker      And these CBcj2Enc variables can have different values in different Bcj2Enc_Encode() calls.
202*f6dc9357SAndroid Build Coastguard Worker      So caller must finish each block with BCJ2_ENC_FINISH_MODE_END_BLOCK
203*f6dc9357SAndroid Build Coastguard Worker      to ensure that RC symbol is calculated and written in proper block.
204*f6dc9357SAndroid Build Coastguard Worker 
205*f6dc9357SAndroid Build Coastguard Worker   BCJ2_ENC_FINISH_MODE_END_STREAM
206*f6dc9357SAndroid Build Coastguard Worker      finish encoding of stream (ended at srcLim) fully including RC flushing.
207*f6dc9357SAndroid Build Coastguard Worker    at return: if (CBcj2Enc::state == BCJ2_ENC_STATE_FINISHED)
208*f6dc9357SAndroid Build Coastguard Worker         : it shows that stream encoding was finished fully,
209*f6dc9357SAndroid Build Coastguard Worker           and all output streams were flushed fully.
210*f6dc9357SAndroid Build Coastguard Worker      also Bcj2Enc_IsFinished() can be called.
211*f6dc9357SAndroid Build Coastguard Worker */
212*f6dc9357SAndroid Build Coastguard Worker 
213*f6dc9357SAndroid Build Coastguard Worker 
214*f6dc9357SAndroid Build Coastguard Worker /*
215*f6dc9357SAndroid Build Coastguard Worker   32-bit relative offset in JUMP/CALL commands is
216*f6dc9357SAndroid Build Coastguard Worker     - (mod 4 GiB)  for 32-bit x86 code
217*f6dc9357SAndroid Build Coastguard Worker     - signed Int32 for 64-bit x86-64 code
218*f6dc9357SAndroid Build Coastguard Worker   BCJ2 encoder also does internal relative to absolute address conversions.
219*f6dc9357SAndroid Build Coastguard Worker   And there are 2 possible ways to do it:
220*f6dc9357SAndroid Build Coastguard Worker     before v23: we used 32-bit variables and (mod 4 GiB) conversion
221*f6dc9357SAndroid Build Coastguard Worker     since  v23: we use  64-bit variables and (signed Int32 offset) conversion.
222*f6dc9357SAndroid Build Coastguard Worker   The absolute address condition for conversion in v23:
223*f6dc9357SAndroid Build Coastguard Worker     ((UInt64)((Int64)ip64 - (Int64)fileIp64 + 5 + (Int32)offset) < (UInt64)fileSize64)
224*f6dc9357SAndroid Build Coastguard Worker   note that if (fileSize64 > 2 GiB). there is difference between
225*f6dc9357SAndroid Build Coastguard Worker   old (mod 4 GiB) way (v22) and new (signed Int32 offset) way (v23).
226*f6dc9357SAndroid Build Coastguard Worker   And new (v23) way is more suitable to encode 64-bit x86-64 code for (fileSize64 > 2 GiB) cases.
227*f6dc9357SAndroid Build Coastguard Worker */
228*f6dc9357SAndroid Build Coastguard Worker 
229*f6dc9357SAndroid Build Coastguard Worker /*
230*f6dc9357SAndroid Build Coastguard Worker // for old (v22) way for conversion:
231*f6dc9357SAndroid Build Coastguard Worker typedef UInt32 CBcj2Enc_ip_unsigned;
232*f6dc9357SAndroid Build Coastguard Worker typedef  Int32 CBcj2Enc_ip_signed;
233*f6dc9357SAndroid Build Coastguard Worker #define BCJ2_ENC_FileSize_MAX ((UInt32)1 << 31)
234*f6dc9357SAndroid Build Coastguard Worker */
235*f6dc9357SAndroid Build Coastguard Worker typedef UInt64 CBcj2Enc_ip_unsigned;
236*f6dc9357SAndroid Build Coastguard Worker typedef  Int64 CBcj2Enc_ip_signed;
237*f6dc9357SAndroid Build Coastguard Worker 
238*f6dc9357SAndroid Build Coastguard Worker /* maximum size of file that can be used for conversion condition */
239*f6dc9357SAndroid Build Coastguard Worker #define BCJ2_ENC_FileSize_MAX             ((CBcj2Enc_ip_unsigned)0 - 2)
240*f6dc9357SAndroid Build Coastguard Worker 
241*f6dc9357SAndroid Build Coastguard Worker /* default value of fileSize64_minus1 variable that means
242*f6dc9357SAndroid Build Coastguard Worker    that absolute address limitation will not be used */
243*f6dc9357SAndroid Build Coastguard Worker #define BCJ2_ENC_FileSizeField_UNLIMITED  ((CBcj2Enc_ip_unsigned)0 - 1)
244*f6dc9357SAndroid Build Coastguard Worker 
245*f6dc9357SAndroid Build Coastguard Worker /* calculate value that later can be set to CBcj2Enc::fileSize64_minus1 */
246*f6dc9357SAndroid Build Coastguard Worker #define BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(fileSize) \
247*f6dc9357SAndroid Build Coastguard Worker     ((CBcj2Enc_ip_unsigned)(fileSize) - 1)
248*f6dc9357SAndroid Build Coastguard Worker 
249*f6dc9357SAndroid Build Coastguard Worker /* set CBcj2Enc::fileSize64_minus1 variable from size of file */
250*f6dc9357SAndroid Build Coastguard Worker #define Bcj2Enc_SET_FileSize(p, fileSize) \
251*f6dc9357SAndroid Build Coastguard Worker     (p)->fileSize64_minus1 = BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(fileSize);
252*f6dc9357SAndroid Build Coastguard Worker 
253*f6dc9357SAndroid Build Coastguard Worker 
254*f6dc9357SAndroid Build Coastguard Worker typedef struct
255*f6dc9357SAndroid Build Coastguard Worker {
256*f6dc9357SAndroid Build Coastguard Worker   Byte *bufs[BCJ2_NUM_STREAMS];
257*f6dc9357SAndroid Build Coastguard Worker   const Byte *lims[BCJ2_NUM_STREAMS];
258*f6dc9357SAndroid Build Coastguard Worker   const Byte *src;
259*f6dc9357SAndroid Build Coastguard Worker   const Byte *srcLim;
260*f6dc9357SAndroid Build Coastguard Worker 
261*f6dc9357SAndroid Build Coastguard Worker   unsigned state;
262*f6dc9357SAndroid Build Coastguard Worker   EBcj2Enc_FinishMode finishMode;
263*f6dc9357SAndroid Build Coastguard Worker 
264*f6dc9357SAndroid Build Coastguard Worker   Byte context;
265*f6dc9357SAndroid Build Coastguard Worker   Byte flushRem;
266*f6dc9357SAndroid Build Coastguard Worker   Byte isFlushState;
267*f6dc9357SAndroid Build Coastguard Worker 
268*f6dc9357SAndroid Build Coastguard Worker   Byte cache;
269*f6dc9357SAndroid Build Coastguard Worker   UInt32 range;
270*f6dc9357SAndroid Build Coastguard Worker   UInt64 low;
271*f6dc9357SAndroid Build Coastguard Worker   UInt64 cacheSize;
272*f6dc9357SAndroid Build Coastguard Worker 
273*f6dc9357SAndroid Build Coastguard Worker   // UInt32 context;  // for marker version, it can include marker flag.
274*f6dc9357SAndroid Build Coastguard Worker 
275*f6dc9357SAndroid Build Coastguard Worker   /* (ip64) and (fileIp64) correspond to virtual source stream position
276*f6dc9357SAndroid Build Coastguard Worker      that doesn't include data in temp[] */
277*f6dc9357SAndroid Build Coastguard Worker   CBcj2Enc_ip_unsigned ip64;         /* current (ip) position */
278*f6dc9357SAndroid Build Coastguard Worker   CBcj2Enc_ip_unsigned fileIp64;     /* start (ip) position of current file */
279*f6dc9357SAndroid Build Coastguard Worker   CBcj2Enc_ip_unsigned fileSize64_minus1;   /* size of current file (for conversion limitation) */
280*f6dc9357SAndroid Build Coastguard Worker   UInt32 relatLimit;  /* (relatLimit <= ((UInt32)1 << 31)) : 0 means disable_conversion */
281*f6dc9357SAndroid Build Coastguard Worker   // UInt32 relatExcludeBits;
282*f6dc9357SAndroid Build Coastguard Worker 
283*f6dc9357SAndroid Build Coastguard Worker   UInt32 tempTarget;
284*f6dc9357SAndroid Build Coastguard Worker   unsigned tempPos; /* the number of bytes that were copied to temp[] buffer
285*f6dc9357SAndroid Build Coastguard Worker                        (tempPos <= 4) outside of Bcj2Enc_Encode() */
286*f6dc9357SAndroid Build Coastguard Worker   // Byte temp[4]; // for marker version
287*f6dc9357SAndroid Build Coastguard Worker   Byte temp[8];
288*f6dc9357SAndroid Build Coastguard Worker   CBcj2Prob probs[2 + 256];
289*f6dc9357SAndroid Build Coastguard Worker } CBcj2Enc;
290*f6dc9357SAndroid Build Coastguard Worker 
291*f6dc9357SAndroid Build Coastguard Worker void Bcj2Enc_Init(CBcj2Enc *p);
292*f6dc9357SAndroid Build Coastguard Worker 
293*f6dc9357SAndroid Build Coastguard Worker 
294*f6dc9357SAndroid Build Coastguard Worker /*
295*f6dc9357SAndroid Build Coastguard Worker Bcj2Enc_Encode(): at exit:
296*f6dc9357SAndroid Build Coastguard Worker   p->State <  BCJ2_NUM_STREAMS    : we need more buffer space for output stream
297*f6dc9357SAndroid Build Coastguard Worker                                     (bufs[p->State] == lims[p->State])
298*f6dc9357SAndroid Build Coastguard Worker   p->State == BCJ2_ENC_STATE_ORIG : we need more data in input src stream
299*f6dc9357SAndroid Build Coastguard Worker                                     (src == srcLim)
300*f6dc9357SAndroid Build Coastguard Worker   p->State == BCJ2_ENC_STATE_FINISHED : after fully encoded stream
301*f6dc9357SAndroid Build Coastguard Worker */
302*f6dc9357SAndroid Build Coastguard Worker void Bcj2Enc_Encode(CBcj2Enc *p);
303*f6dc9357SAndroid Build Coastguard Worker 
304*f6dc9357SAndroid Build Coastguard Worker /* Bcj2Enc encoder can look ahead for up 4 bytes of source stream.
305*f6dc9357SAndroid Build Coastguard Worker    CBcj2Enc::tempPos : is the number of bytes that were copied from input stream to temp[] buffer.
306*f6dc9357SAndroid Build Coastguard Worker    (CBcj2Enc::src) after Bcj2Enc_Encode() is starting position after
307*f6dc9357SAndroid Build Coastguard Worker    fully processed data and after data copied to temp buffer.
308*f6dc9357SAndroid Build Coastguard Worker    So if the caller needs to get real number of fully processed input
309*f6dc9357SAndroid Build Coastguard Worker    bytes (without look ahead data in temp buffer),
310*f6dc9357SAndroid Build Coastguard Worker    the caller must subtruct (CBcj2Enc::tempPos) value from processed size
311*f6dc9357SAndroid Build Coastguard Worker    value that is calculated based on current (CBcj2Enc::src):
312*f6dc9357SAndroid Build Coastguard Worker      cur_processed_pos = Calc_Big_Processed_Pos(enc.src)) -
313*f6dc9357SAndroid Build Coastguard Worker         Bcj2Enc_Get_AvailInputSize_in_Temp(&enc);
314*f6dc9357SAndroid Build Coastguard Worker */
315*f6dc9357SAndroid Build Coastguard Worker /* get the size of input data that was stored in temp[] buffer: */
316*f6dc9357SAndroid Build Coastguard Worker #define Bcj2Enc_Get_AvailInputSize_in_Temp(p) ((p)->tempPos)
317*f6dc9357SAndroid Build Coastguard Worker 
318*f6dc9357SAndroid Build Coastguard Worker #define Bcj2Enc_IsFinished(p) ((p)->flushRem == 0)
319*f6dc9357SAndroid Build Coastguard Worker 
320*f6dc9357SAndroid Build Coastguard Worker /* Note : the decoder supports overlapping of marker (0f 80).
321*f6dc9357SAndroid Build Coastguard Worker    But we can eliminate such overlapping cases by setting
322*f6dc9357SAndroid Build Coastguard Worker    the limit for relative offset conversion as
323*f6dc9357SAndroid Build Coastguard Worker      CBcj2Enc::relatLimit <= (0x0f << 24) == (240 MiB)
324*f6dc9357SAndroid Build Coastguard Worker */
325*f6dc9357SAndroid Build Coastguard Worker /* default value for CBcj2Enc::relatLimit */
326*f6dc9357SAndroid Build Coastguard Worker #define BCJ2_ENC_RELAT_LIMIT_DEFAULT  ((UInt32)0x0f << 24)
327*f6dc9357SAndroid Build Coastguard Worker #define BCJ2_ENC_RELAT_LIMIT_MAX      ((UInt32)1 << 31)
328*f6dc9357SAndroid Build Coastguard Worker // #define BCJ2_RELAT_EXCLUDE_NUM_BITS 5
329*f6dc9357SAndroid Build Coastguard Worker 
330*f6dc9357SAndroid Build Coastguard Worker EXTERN_C_END
331*f6dc9357SAndroid Build Coastguard Worker 
332*f6dc9357SAndroid Build Coastguard Worker #endif
333