1370b324cSopenharmony_ci/* Bcj2.h -- BCJ2 converter for x86 code (Branch CALL/JUMP variant2) 2370b324cSopenharmony_ci2023-03-02 : Igor Pavlov : Public domain */ 3370b324cSopenharmony_ci 4370b324cSopenharmony_ci#ifndef ZIP7_INC_BCJ2_H 5370b324cSopenharmony_ci#define ZIP7_INC_BCJ2_H 6370b324cSopenharmony_ci 7370b324cSopenharmony_ci#include "7zTypes.h" 8370b324cSopenharmony_ci 9370b324cSopenharmony_ciEXTERN_C_BEGIN 10370b324cSopenharmony_ci 11370b324cSopenharmony_ci#define BCJ2_NUM_STREAMS 4 12370b324cSopenharmony_ci 13370b324cSopenharmony_cienum 14370b324cSopenharmony_ci{ 15370b324cSopenharmony_ci BCJ2_STREAM_MAIN, 16370b324cSopenharmony_ci BCJ2_STREAM_CALL, 17370b324cSopenharmony_ci BCJ2_STREAM_JUMP, 18370b324cSopenharmony_ci BCJ2_STREAM_RC 19370b324cSopenharmony_ci}; 20370b324cSopenharmony_ci 21370b324cSopenharmony_cienum 22370b324cSopenharmony_ci{ 23370b324cSopenharmony_ci BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS, 24370b324cSopenharmony_ci BCJ2_DEC_STATE_ORIG_1, 25370b324cSopenharmony_ci BCJ2_DEC_STATE_ORIG_2, 26370b324cSopenharmony_ci BCJ2_DEC_STATE_ORIG_3, 27370b324cSopenharmony_ci 28370b324cSopenharmony_ci BCJ2_DEC_STATE_ORIG, 29370b324cSopenharmony_ci BCJ2_DEC_STATE_ERROR /* after detected data error */ 30370b324cSopenharmony_ci}; 31370b324cSopenharmony_ci 32370b324cSopenharmony_cienum 33370b324cSopenharmony_ci{ 34370b324cSopenharmony_ci BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS, 35370b324cSopenharmony_ci BCJ2_ENC_STATE_FINISHED /* it's state after fully encoded stream */ 36370b324cSopenharmony_ci}; 37370b324cSopenharmony_ci 38370b324cSopenharmony_ci 39370b324cSopenharmony_ci/* #define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) */ 40370b324cSopenharmony_ci#define BCJ2_IS_32BIT_STREAM(s) ((unsigned)((unsigned)(s) - (unsigned)BCJ2_STREAM_CALL) < 2) 41370b324cSopenharmony_ci 42370b324cSopenharmony_ci/* 43370b324cSopenharmony_ciCBcj2Dec / CBcj2Enc 44370b324cSopenharmony_cibufs sizes: 45370b324cSopenharmony_ci BUF_SIZE(n) = lims[n] - bufs[n] 46370b324cSopenharmony_cibufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be multiply of 4: 47370b324cSopenharmony_ci (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0 48370b324cSopenharmony_ci (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0 49370b324cSopenharmony_ci*/ 50370b324cSopenharmony_ci 51370b324cSopenharmony_ci// typedef UInt32 CBcj2Prob; 52370b324cSopenharmony_citypedef UInt16 CBcj2Prob; 53370b324cSopenharmony_ci 54370b324cSopenharmony_ci/* 55370b324cSopenharmony_ciBCJ2 encoder / decoder internal requirements: 56370b324cSopenharmony_ci - If last bytes of stream contain marker (e8/e8/0f8x), then 57370b324cSopenharmony_ci there is also encoded symbol (0 : no conversion) in RC stream. 58370b324cSopenharmony_ci - One case of overlapped instructions is supported, 59370b324cSopenharmony_ci if last byte of converted instruction is (0f) and next byte is (8x): 60370b324cSopenharmony_ci marker [xx xx xx 0f] 8x 61370b324cSopenharmony_ci then the pair (0f 8x) is treated as marker. 62370b324cSopenharmony_ci*/ 63370b324cSopenharmony_ci 64370b324cSopenharmony_ci/* ---------- BCJ2 Decoder ---------- */ 65370b324cSopenharmony_ci 66370b324cSopenharmony_ci/* 67370b324cSopenharmony_ciCBcj2Dec: 68370b324cSopenharmony_ci(dest) is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions: 69370b324cSopenharmony_ci bufs[BCJ2_STREAM_MAIN] >= dest && 70370b324cSopenharmony_ci bufs[BCJ2_STREAM_MAIN] - dest >= 71370b324cSopenharmony_ci BUF_SIZE(BCJ2_STREAM_CALL) + 72370b324cSopenharmony_ci BUF_SIZE(BCJ2_STREAM_JUMP) 73370b324cSopenharmony_ci reserve = bufs[BCJ2_STREAM_MAIN] - dest - 74370b324cSopenharmony_ci ( BUF_SIZE(BCJ2_STREAM_CALL) + 75370b324cSopenharmony_ci BUF_SIZE(BCJ2_STREAM_JUMP) ) 76370b324cSopenharmony_ci and additional conditions: 77370b324cSopenharmony_ci if (it's first call of Bcj2Dec_Decode() after Bcj2Dec_Init()) 78370b324cSopenharmony_ci { 79370b324cSopenharmony_ci (reserve != 1) : if (ver < v23.00) 80370b324cSopenharmony_ci } 81370b324cSopenharmony_ci else // if there are more than one calls of Bcj2Dec_Decode() after Bcj2Dec_Init()) 82370b324cSopenharmony_ci { 83370b324cSopenharmony_ci (reserve >= 6) : if (ver < v23.00) 84370b324cSopenharmony_ci (reserve >= 4) : if (ver >= v23.00) 85370b324cSopenharmony_ci We need that (reserve) because after first call of Bcj2Dec_Decode(), 86370b324cSopenharmony_ci CBcj2Dec::temp can contain up to 4 bytes for writing to (dest). 87370b324cSopenharmony_ci } 88370b324cSopenharmony_ci (reserve == 0) is allowed, if we decode full stream via single call of Bcj2Dec_Decode(). 89370b324cSopenharmony_ci (reserve == 0) also is allowed in case of multi-call, if we use fixed buffers, 90370b324cSopenharmony_ci and (reserve) is calculated from full (final) sizes of all streams before first call. 91370b324cSopenharmony_ci*/ 92370b324cSopenharmony_ci 93370b324cSopenharmony_citypedef struct 94370b324cSopenharmony_ci{ 95370b324cSopenharmony_ci const Byte *bufs[BCJ2_NUM_STREAMS]; 96370b324cSopenharmony_ci const Byte *lims[BCJ2_NUM_STREAMS]; 97370b324cSopenharmony_ci Byte *dest; 98370b324cSopenharmony_ci const Byte *destLim; 99370b324cSopenharmony_ci 100370b324cSopenharmony_ci unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */ 101370b324cSopenharmony_ci 102370b324cSopenharmony_ci UInt32 ip; /* property of starting base for decoding */ 103370b324cSopenharmony_ci UInt32 temp; /* Byte temp[4]; */ 104370b324cSopenharmony_ci UInt32 range; 105370b324cSopenharmony_ci UInt32 code; 106370b324cSopenharmony_ci CBcj2Prob probs[2 + 256]; 107370b324cSopenharmony_ci} CBcj2Dec; 108370b324cSopenharmony_ci 109370b324cSopenharmony_ci 110370b324cSopenharmony_ci/* Note: 111370b324cSopenharmony_ci Bcj2Dec_Init() sets (CBcj2Dec::ip = 0) 112370b324cSopenharmony_ci if (ip != 0) property is required, the caller must set CBcj2Dec::ip after Bcj2Dec_Init() 113370b324cSopenharmony_ci*/ 114370b324cSopenharmony_civoid Bcj2Dec_Init(CBcj2Dec *p); 115370b324cSopenharmony_ci 116370b324cSopenharmony_ci 117370b324cSopenharmony_ci/* Bcj2Dec_Decode(): 118370b324cSopenharmony_ci returns: 119370b324cSopenharmony_ci SZ_OK 120370b324cSopenharmony_ci SZ_ERROR_DATA : if data in 5 starting bytes of BCJ2_STREAM_RC stream are not correct 121370b324cSopenharmony_ci*/ 122370b324cSopenharmony_ciSRes Bcj2Dec_Decode(CBcj2Dec *p); 123370b324cSopenharmony_ci 124370b324cSopenharmony_ci/* To check that decoding was finished you can compare 125370b324cSopenharmony_ci sizes of processed streams with sizes known from another sources. 126370b324cSopenharmony_ci You must do at least one mandatory check from the two following options: 127370b324cSopenharmony_ci - the check for size of processed output (ORIG) stream. 128370b324cSopenharmony_ci - the check for size of processed input (MAIN) stream. 129370b324cSopenharmony_ci additional optional checks: 130370b324cSopenharmony_ci - the checks for processed sizes of all input streams (MAIN, CALL, JUMP, RC) 131370b324cSopenharmony_ci - the checks Bcj2Dec_IsMaybeFinished*() 132370b324cSopenharmony_ci also before actual decoding you can check that the 133370b324cSopenharmony_ci following condition is met for stream sizes: 134370b324cSopenharmony_ci ( size(ORIG) == size(MAIN) + size(CALL) + size(JUMP) ) 135370b324cSopenharmony_ci*/ 136370b324cSopenharmony_ci 137370b324cSopenharmony_ci/* (state == BCJ2_STREAM_MAIN) means that decoder is ready for 138370b324cSopenharmony_ci additional input data in BCJ2_STREAM_MAIN stream. 139370b324cSopenharmony_ci Note that (state == BCJ2_STREAM_MAIN) is allowed for non-finished decoding. 140370b324cSopenharmony_ci*/ 141370b324cSopenharmony_ci#define Bcj2Dec_IsMaybeFinished_state_MAIN(_p_) ((_p_)->state == BCJ2_STREAM_MAIN) 142370b324cSopenharmony_ci 143370b324cSopenharmony_ci/* if the stream decoding was finished correctly, then range decoder 144370b324cSopenharmony_ci part of CBcj2Dec also was finished, and then (CBcj2Dec::code == 0). 145370b324cSopenharmony_ci Note that (CBcj2Dec::code == 0) is allowed for non-finished decoding. 146370b324cSopenharmony_ci*/ 147370b324cSopenharmony_ci#define Bcj2Dec_IsMaybeFinished_code(_p_) ((_p_)->code == 0) 148370b324cSopenharmony_ci 149370b324cSopenharmony_ci/* use Bcj2Dec_IsMaybeFinished() only as additional check 150370b324cSopenharmony_ci after at least one mandatory check from the two following options: 151370b324cSopenharmony_ci - the check for size of processed output (ORIG) stream. 152370b324cSopenharmony_ci - the check for size of processed input (MAIN) stream. 153370b324cSopenharmony_ci*/ 154370b324cSopenharmony_ci#define Bcj2Dec_IsMaybeFinished(_p_) ( \ 155370b324cSopenharmony_ci Bcj2Dec_IsMaybeFinished_state_MAIN(_p_) && \ 156370b324cSopenharmony_ci Bcj2Dec_IsMaybeFinished_code(_p_)) 157370b324cSopenharmony_ci 158370b324cSopenharmony_ci 159370b324cSopenharmony_ci 160370b324cSopenharmony_ci/* ---------- BCJ2 Encoder ---------- */ 161370b324cSopenharmony_ci 162370b324cSopenharmony_citypedef enum 163370b324cSopenharmony_ci{ 164370b324cSopenharmony_ci BCJ2_ENC_FINISH_MODE_CONTINUE, 165370b324cSopenharmony_ci BCJ2_ENC_FINISH_MODE_END_BLOCK, 166370b324cSopenharmony_ci BCJ2_ENC_FINISH_MODE_END_STREAM 167370b324cSopenharmony_ci} EBcj2Enc_FinishMode; 168370b324cSopenharmony_ci 169370b324cSopenharmony_ci/* 170370b324cSopenharmony_ci BCJ2_ENC_FINISH_MODE_CONTINUE: 171370b324cSopenharmony_ci process non finished encoding. 172370b324cSopenharmony_ci It notifies the encoder that additional further calls 173370b324cSopenharmony_ci can provide more input data (src) than provided by current call. 174370b324cSopenharmony_ci In that case the CBcj2Enc encoder still can move (src) pointer 175370b324cSopenharmony_ci up to (srcLim), but CBcj2Enc encoder can store some of the last 176370b324cSopenharmony_ci processed bytes (up to 4 bytes) from src to internal CBcj2Enc::temp[] buffer. 177370b324cSopenharmony_ci at return: 178370b324cSopenharmony_ci (CBcj2Enc::src will point to position that includes 179370b324cSopenharmony_ci processed data and data copied to (temp[]) buffer) 180370b324cSopenharmony_ci That data from (temp[]) buffer will be used in further calls. 181370b324cSopenharmony_ci 182370b324cSopenharmony_ci BCJ2_ENC_FINISH_MODE_END_BLOCK: 183370b324cSopenharmony_ci finish encoding of current block (ended at srcLim) without RC flushing. 184370b324cSopenharmony_ci at return: if (CBcj2Enc::state == BCJ2_ENC_STATE_ORIG) && 185370b324cSopenharmony_ci CBcj2Enc::src == CBcj2Enc::srcLim) 186370b324cSopenharmony_ci : it shows that block encoding was finished. And the encoder is 187370b324cSopenharmony_ci ready for new (src) data or for stream finish operation. 188370b324cSopenharmony_ci finished block means 189370b324cSopenharmony_ci { 190370b324cSopenharmony_ci CBcj2Enc has completed block encoding up to (srcLim). 191370b324cSopenharmony_ci (1 + 4 bytes) or (2 + 4 bytes) CALL/JUMP cortages will 192370b324cSopenharmony_ci not cross block boundary at (srcLim). 193370b324cSopenharmony_ci temporary CBcj2Enc buffer for (ORIG) src data is empty. 194370b324cSopenharmony_ci 3 output uncompressed streams (MAIN, CALL, JUMP) were flushed. 195370b324cSopenharmony_ci RC stream was not flushed. And RC stream will cross block boundary. 196370b324cSopenharmony_ci } 197370b324cSopenharmony_ci Note: some possible implementation of BCJ2 encoder could 198370b324cSopenharmony_ci write branch marker (e8/e8/0f8x) in one call of Bcj2Enc_Encode(), 199370b324cSopenharmony_ci and it could calculate symbol for RC in another call of Bcj2Enc_Encode(). 200370b324cSopenharmony_ci BCJ2 encoder uses ip/fileIp/fileSize/relatLimit values to calculate RC symbol. 201370b324cSopenharmony_ci And these CBcj2Enc variables can have different values in different Bcj2Enc_Encode() calls. 202370b324cSopenharmony_ci So caller must finish each block with BCJ2_ENC_FINISH_MODE_END_BLOCK 203370b324cSopenharmony_ci to ensure that RC symbol is calculated and written in proper block. 204370b324cSopenharmony_ci 205370b324cSopenharmony_ci BCJ2_ENC_FINISH_MODE_END_STREAM 206370b324cSopenharmony_ci finish encoding of stream (ended at srcLim) fully including RC flushing. 207370b324cSopenharmony_ci at return: if (CBcj2Enc::state == BCJ2_ENC_STATE_FINISHED) 208370b324cSopenharmony_ci : it shows that stream encoding was finished fully, 209370b324cSopenharmony_ci and all output streams were flushed fully. 210370b324cSopenharmony_ci also Bcj2Enc_IsFinished() can be called. 211370b324cSopenharmony_ci*/ 212370b324cSopenharmony_ci 213370b324cSopenharmony_ci 214370b324cSopenharmony_ci/* 215370b324cSopenharmony_ci 32-bit relative offset in JUMP/CALL commands is 216370b324cSopenharmony_ci - (mod 4 GiB) for 32-bit x86 code 217370b324cSopenharmony_ci - signed Int32 for 64-bit x86-64 code 218370b324cSopenharmony_ci BCJ2 encoder also does internal relative to absolute address conversions. 219370b324cSopenharmony_ci And there are 2 possible ways to do it: 220370b324cSopenharmony_ci before v23: we used 32-bit variables and (mod 4 GiB) conversion 221370b324cSopenharmony_ci since v23: we use 64-bit variables and (signed Int32 offset) conversion. 222370b324cSopenharmony_ci The absolute address condition for conversion in v23: 223370b324cSopenharmony_ci ((UInt64)((Int64)ip64 - (Int64)fileIp64 + 5 + (Int32)offset) < (UInt64)fileSize64) 224370b324cSopenharmony_ci note that if (fileSize64 > 2 GiB). there is difference between 225370b324cSopenharmony_ci old (mod 4 GiB) way (v22) and new (signed Int32 offset) way (v23). 226370b324cSopenharmony_ci And new (v23) way is more suitable to encode 64-bit x86-64 code for (fileSize64 > 2 GiB) cases. 227370b324cSopenharmony_ci*/ 228370b324cSopenharmony_ci 229370b324cSopenharmony_ci/* 230370b324cSopenharmony_ci// for old (v22) way for conversion: 231370b324cSopenharmony_citypedef UInt32 CBcj2Enc_ip_unsigned; 232370b324cSopenharmony_citypedef Int32 CBcj2Enc_ip_signed; 233370b324cSopenharmony_ci#define BCJ2_ENC_FileSize_MAX ((UInt32)1 << 31) 234370b324cSopenharmony_ci*/ 235370b324cSopenharmony_citypedef UInt64 CBcj2Enc_ip_unsigned; 236370b324cSopenharmony_citypedef Int64 CBcj2Enc_ip_signed; 237370b324cSopenharmony_ci 238370b324cSopenharmony_ci/* maximum size of file that can be used for conversion condition */ 239370b324cSopenharmony_ci#define BCJ2_ENC_FileSize_MAX ((CBcj2Enc_ip_unsigned)0 - 2) 240370b324cSopenharmony_ci 241370b324cSopenharmony_ci/* default value of fileSize64_minus1 variable that means 242370b324cSopenharmony_ci that absolute address limitation will not be used */ 243370b324cSopenharmony_ci#define BCJ2_ENC_FileSizeField_UNLIMITED ((CBcj2Enc_ip_unsigned)0 - 1) 244370b324cSopenharmony_ci 245370b324cSopenharmony_ci/* calculate value that later can be set to CBcj2Enc::fileSize64_minus1 */ 246370b324cSopenharmony_ci#define BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(fileSize) \ 247370b324cSopenharmony_ci ((CBcj2Enc_ip_unsigned)(fileSize) - 1) 248370b324cSopenharmony_ci 249370b324cSopenharmony_ci/* set CBcj2Enc::fileSize64_minus1 variable from size of file */ 250370b324cSopenharmony_ci#define Bcj2Enc_SET_FileSize(p, fileSize) \ 251370b324cSopenharmony_ci (p)->fileSize64_minus1 = BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(fileSize); 252370b324cSopenharmony_ci 253370b324cSopenharmony_ci 254370b324cSopenharmony_citypedef struct 255370b324cSopenharmony_ci{ 256370b324cSopenharmony_ci Byte *bufs[BCJ2_NUM_STREAMS]; 257370b324cSopenharmony_ci const Byte *lims[BCJ2_NUM_STREAMS]; 258370b324cSopenharmony_ci const Byte *src; 259370b324cSopenharmony_ci const Byte *srcLim; 260370b324cSopenharmony_ci 261370b324cSopenharmony_ci unsigned state; 262370b324cSopenharmony_ci EBcj2Enc_FinishMode finishMode; 263370b324cSopenharmony_ci 264370b324cSopenharmony_ci Byte context; 265370b324cSopenharmony_ci Byte flushRem; 266370b324cSopenharmony_ci Byte isFlushState; 267370b324cSopenharmony_ci 268370b324cSopenharmony_ci Byte cache; 269370b324cSopenharmony_ci UInt32 range; 270370b324cSopenharmony_ci UInt64 low; 271370b324cSopenharmony_ci UInt64 cacheSize; 272370b324cSopenharmony_ci 273370b324cSopenharmony_ci // UInt32 context; // for marker version, it can include marker flag. 274370b324cSopenharmony_ci 275370b324cSopenharmony_ci /* (ip64) and (fileIp64) correspond to virtual source stream position 276370b324cSopenharmony_ci that doesn't include data in temp[] */ 277370b324cSopenharmony_ci CBcj2Enc_ip_unsigned ip64; /* current (ip) position */ 278370b324cSopenharmony_ci CBcj2Enc_ip_unsigned fileIp64; /* start (ip) position of current file */ 279370b324cSopenharmony_ci CBcj2Enc_ip_unsigned fileSize64_minus1; /* size of current file (for conversion limitation) */ 280370b324cSopenharmony_ci UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)) : 0 means disable_conversion */ 281370b324cSopenharmony_ci // UInt32 relatExcludeBits; 282370b324cSopenharmony_ci 283370b324cSopenharmony_ci UInt32 tempTarget; 284370b324cSopenharmony_ci unsigned tempPos; /* the number of bytes that were copied to temp[] buffer 285370b324cSopenharmony_ci (tempPos <= 4) outside of Bcj2Enc_Encode() */ 286370b324cSopenharmony_ci // Byte temp[4]; // for marker version 287370b324cSopenharmony_ci Byte temp[8]; 288370b324cSopenharmony_ci CBcj2Prob probs[2 + 256]; 289370b324cSopenharmony_ci} CBcj2Enc; 290370b324cSopenharmony_ci 291370b324cSopenharmony_civoid Bcj2Enc_Init(CBcj2Enc *p); 292370b324cSopenharmony_ci 293370b324cSopenharmony_ci 294370b324cSopenharmony_ci/* 295370b324cSopenharmony_ciBcj2Enc_Encode(): at exit: 296370b324cSopenharmony_ci p->State < BCJ2_NUM_STREAMS : we need more buffer space for output stream 297370b324cSopenharmony_ci (bufs[p->State] == lims[p->State]) 298370b324cSopenharmony_ci p->State == BCJ2_ENC_STATE_ORIG : we need more data in input src stream 299370b324cSopenharmony_ci (src == srcLim) 300370b324cSopenharmony_ci p->State == BCJ2_ENC_STATE_FINISHED : after fully encoded stream 301370b324cSopenharmony_ci*/ 302370b324cSopenharmony_civoid Bcj2Enc_Encode(CBcj2Enc *p); 303370b324cSopenharmony_ci 304370b324cSopenharmony_ci/* Bcj2Enc encoder can look ahead for up 4 bytes of source stream. 305370b324cSopenharmony_ci CBcj2Enc::tempPos : is the number of bytes that were copied from input stream to temp[] buffer. 306370b324cSopenharmony_ci (CBcj2Enc::src) after Bcj2Enc_Encode() is starting position after 307370b324cSopenharmony_ci fully processed data and after data copied to temp buffer. 308370b324cSopenharmony_ci So if the caller needs to get real number of fully processed input 309370b324cSopenharmony_ci bytes (without look ahead data in temp buffer), 310370b324cSopenharmony_ci the caller must subtruct (CBcj2Enc::tempPos) value from processed size 311370b324cSopenharmony_ci value that is calculated based on current (CBcj2Enc::src): 312370b324cSopenharmony_ci cur_processed_pos = Calc_Big_Processed_Pos(enc.src)) - 313370b324cSopenharmony_ci Bcj2Enc_Get_AvailInputSize_in_Temp(&enc); 314370b324cSopenharmony_ci*/ 315370b324cSopenharmony_ci/* get the size of input data that was stored in temp[] buffer: */ 316370b324cSopenharmony_ci#define Bcj2Enc_Get_AvailInputSize_in_Temp(p) ((p)->tempPos) 317370b324cSopenharmony_ci 318370b324cSopenharmony_ci#define Bcj2Enc_IsFinished(p) ((p)->flushRem == 0) 319370b324cSopenharmony_ci 320370b324cSopenharmony_ci/* Note : the decoder supports overlapping of marker (0f 80). 321370b324cSopenharmony_ci But we can eliminate such overlapping cases by setting 322370b324cSopenharmony_ci the limit for relative offset conversion as 323370b324cSopenharmony_ci CBcj2Enc::relatLimit <= (0x0f << 24) == (240 MiB) 324370b324cSopenharmony_ci*/ 325370b324cSopenharmony_ci/* default value for CBcj2Enc::relatLimit */ 326370b324cSopenharmony_ci#define BCJ2_ENC_RELAT_LIMIT_DEFAULT ((UInt32)0x0f << 24) 327370b324cSopenharmony_ci#define BCJ2_ENC_RELAT_LIMIT_MAX ((UInt32)1 << 31) 328370b324cSopenharmony_ci// #define BCJ2_RELAT_EXCLUDE_NUM_BITS 5 329370b324cSopenharmony_ci 330370b324cSopenharmony_ciEXTERN_C_END 331370b324cSopenharmony_ci 332370b324cSopenharmony_ci#endif 333