/* Bcj2.h -- BCJ2 Converter for x86 code 2014-11-10 : Igor Pavlov : Public domain */ #ifndef __BCJ2_H #define __BCJ2_H #include "7zTypes.h" EXTERN_C_BEGIN #define BCJ2_NUM_STREAMS 4 enum { BCJ2_STREAM_MAIN, BCJ2_STREAM_CALL, BCJ2_STREAM_JUMP, BCJ2_STREAM_RC }; enum { BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS, BCJ2_DEC_STATE_ORIG_1, BCJ2_DEC_STATE_ORIG_2, BCJ2_DEC_STATE_ORIG_3, BCJ2_DEC_STATE_ORIG, BCJ2_DEC_STATE_OK }; enum { BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS, BCJ2_ENC_STATE_OK }; #define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) /* CBcj2Dec / CBcj2Enc bufs sizes: BUF_SIZE(n) = lims[n] - bufs[n] bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4: (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0 (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0 */ /* CBcj2Dec: dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions: bufs[BCJ2_STREAM_MAIN] >= dest && bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv + BUF_SIZE(BCJ2_STREAM_CALL) + BUF_SIZE(BCJ2_STREAM_JUMP) tempReserv = 0 : for first call of Bcj2Dec_Decode tempReserv = 4 : for any other calls of Bcj2Dec_Decode overlap with offset = 1 is not allowed */ typedef struct { const Byte *bufs[BCJ2_NUM_STREAMS]; const Byte *lims[BCJ2_NUM_STREAMS]; Byte *dest; const Byte *destLim; unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */ uint32_t ip; Byte temp[4]; uint32_t range; uint32_t code; uint16_t probs[2 + 256]; } CBcj2Dec; void Bcj2Dec_Init(CBcj2Dec *p); /* Returns: SZ_OK or SZ_ERROR_DATA */ SRes Bcj2Dec_Decode(CBcj2Dec *p); #define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0) typedef enum { BCJ2_ENC_FINISH_MODE_CONTINUE, BCJ2_ENC_FINISH_MODE_END_BLOCK, BCJ2_ENC_FINISH_MODE_END_STREAM } EBcj2Enc_FinishMode; typedef struct { Byte *bufs[BCJ2_NUM_STREAMS]; const Byte *lims[BCJ2_NUM_STREAMS]; const Byte *src; const Byte *srcLim; unsigned state; EBcj2Enc_FinishMode finishMode; Byte prevByte; Byte cache; uint32_t range; uint64_t low; uint64_t cacheSize; uint32_t ip; /* 32-bit ralative offset in JUMP/CALL commands is - (mod 4 GB) in 32-bit mode - signed Int32 in 64-bit mode We use (mod 4 GB) check for fileSize. Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */ uint32_t fileIp; uint32_t fileSize; /* (fileSize <= ((uint32_t)1 << 31)), 0 means no_limit */ uint32_t relatLimit; /* (relatLimit <= ((uint32_t)1 << 31)), 0 means desable_conversion */ uint32_t tempTarget; unsigned tempPos; Byte temp[4 * 2]; unsigned flushPos; uint16_t probs[2 + 256]; } CBcj2Enc; void Bcj2Enc_Init(CBcj2Enc *p); void Bcj2Enc_Encode(CBcj2Enc *p); #define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos) #define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5) #define BCJ2_RELAT_LIMIT_NUM_BITS 26 #define BCJ2_RELAT_LIMIT ((uint32_t)1 << BCJ2_RELAT_LIMIT_NUM_BITS) /* limit for CBcj2Enc::fileSize variable */ #define BCJ2_FileSize_MAX ((uint32_t)1 << 31) EXTERN_C_END #endif