OLD | NEW |
1 /* Bcj2.h -- Converter for x86 code (BCJ2) | 1 /* Bcj2.h -- BCJ2 Converter for x86 code |
2 2009-02-07 : Igor Pavlov : Public domain */ | 2 2014-11-10 : Igor Pavlov : Public domain */ |
3 | 3 |
4 #ifndef __BCJ2_H | 4 #ifndef __BCJ2_H |
5 #define __BCJ2_H | 5 #define __BCJ2_H |
6 | 6 |
7 #include "Types.h" | 7 #include "7zTypes.h" |
8 | 8 |
9 #ifdef __cplusplus | 9 EXTERN_C_BEGIN |
10 extern "C" { | 10 |
11 #endif | 11 #define BCJ2_NUM_STREAMS 4 |
| 12 |
| 13 enum |
| 14 { |
| 15 BCJ2_STREAM_MAIN, |
| 16 BCJ2_STREAM_CALL, |
| 17 BCJ2_STREAM_JUMP, |
| 18 BCJ2_STREAM_RC |
| 19 }; |
| 20 |
| 21 enum |
| 22 { |
| 23 BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS, |
| 24 BCJ2_DEC_STATE_ORIG_1, |
| 25 BCJ2_DEC_STATE_ORIG_2, |
| 26 BCJ2_DEC_STATE_ORIG_3, |
| 27 |
| 28 BCJ2_DEC_STATE_ORIG, |
| 29 BCJ2_DEC_STATE_OK |
| 30 }; |
| 31 |
| 32 enum |
| 33 { |
| 34 BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS, |
| 35 BCJ2_ENC_STATE_OK |
| 36 }; |
| 37 |
| 38 |
| 39 #define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_J
UMP) |
12 | 40 |
13 /* | 41 /* |
14 Conditions: | 42 CBcj2Dec / CBcj2Enc |
15 outSize <= FullOutputSize, | 43 bufs sizes: |
16 where FullOutputSize is full size of output stream of x86_2 filter. | 44 BUF_SIZE(n) = lims[n] - bufs[n] |
17 | 45 bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4: |
18 If buf0 overlaps outBuf, there are two required conditions: | 46 (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0 |
19 1) (buf0 >= outBuf) | 47 (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0 |
20 2) (buf0 + size0 >= outBuf + FullOutputSize). | |
21 | |
22 Returns: | |
23 SZ_OK | |
24 SZ_ERROR_DATA - Data error | |
25 */ | 48 */ |
26 | 49 |
27 int Bcj2_Decode( | 50 /* |
28 const Byte *buf0, SizeT size0, | 51 CBcj2Dec: |
29 const Byte *buf1, SizeT size1, | 52 dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following condi
tions: |
30 const Byte *buf2, SizeT size2, | 53 bufs[BCJ2_STREAM_MAIN] >= dest && |
31 const Byte *buf3, SizeT size3, | 54 bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv + |
32 Byte *outBuf, SizeT outSize); | 55 BUF_SIZE(BCJ2_STREAM_CALL) + |
| 56 BUF_SIZE(BCJ2_STREAM_JUMP) |
| 57 tempReserv = 0 : for first call of Bcj2Dec_Decode |
| 58 tempReserv = 4 : for any other calls of Bcj2Dec_Decode |
| 59 overlap with offset = 1 is not allowed |
| 60 */ |
33 | 61 |
34 #ifdef __cplusplus | 62 typedef struct |
35 } | 63 { |
36 #endif | 64 const Byte *bufs[BCJ2_NUM_STREAMS]; |
| 65 const Byte *lims[BCJ2_NUM_STREAMS]; |
| 66 Byte *dest; |
| 67 const Byte *destLim; |
| 68 |
| 69 unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */ |
| 70 |
| 71 UInt32 ip; |
| 72 Byte temp[4]; |
| 73 UInt32 range; |
| 74 UInt32 code; |
| 75 UInt16 probs[2 + 256]; |
| 76 } CBcj2Dec; |
| 77 |
| 78 void Bcj2Dec_Init(CBcj2Dec *p); |
| 79 |
| 80 /* Returns: SZ_OK or SZ_ERROR_DATA */ |
| 81 SRes Bcj2Dec_Decode(CBcj2Dec *p); |
| 82 |
| 83 #define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0) |
| 84 |
| 85 |
| 86 |
| 87 typedef enum |
| 88 { |
| 89 BCJ2_ENC_FINISH_MODE_CONTINUE, |
| 90 BCJ2_ENC_FINISH_MODE_END_BLOCK, |
| 91 BCJ2_ENC_FINISH_MODE_END_STREAM |
| 92 } EBcj2Enc_FinishMode; |
| 93 |
| 94 typedef struct |
| 95 { |
| 96 Byte *bufs[BCJ2_NUM_STREAMS]; |
| 97 const Byte *lims[BCJ2_NUM_STREAMS]; |
| 98 const Byte *src; |
| 99 const Byte *srcLim; |
| 100 |
| 101 unsigned state; |
| 102 EBcj2Enc_FinishMode finishMode; |
| 103 |
| 104 Byte prevByte; |
| 105 |
| 106 Byte cache; |
| 107 UInt32 range; |
| 108 UInt64 low; |
| 109 UInt64 cacheSize; |
| 110 |
| 111 UInt32 ip; |
| 112 |
| 113 /* 32-bit ralative offset in JUMP/CALL commands is |
| 114 - (mod 4 GB) in 32-bit mode |
| 115 - signed Int32 in 64-bit mode |
| 116 We use (mod 4 GB) check for fileSize. |
| 117 Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conv
ersion. */ |
| 118 UInt32 fileIp; |
| 119 UInt32 fileSize; /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */ |
| 120 UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conv
ersion */ |
| 121 |
| 122 UInt32 tempTarget; |
| 123 unsigned tempPos; |
| 124 Byte temp[4 * 2]; |
| 125 |
| 126 unsigned flushPos; |
| 127 |
| 128 UInt16 probs[2 + 256]; |
| 129 } CBcj2Enc; |
| 130 |
| 131 void Bcj2Enc_Init(CBcj2Enc *p); |
| 132 void Bcj2Enc_Encode(CBcj2Enc *p); |
| 133 |
| 134 #define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->te
mpPos) |
| 135 #define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5) |
| 136 |
| 137 |
| 138 #define BCJ2_RELAT_LIMIT_NUM_BITS 26 |
| 139 #define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS) |
| 140 |
| 141 /* limit for CBcj2Enc::fileSize variable */ |
| 142 #define BCJ2_FileSize_MAX ((UInt32)1 << 31) |
| 143 |
| 144 EXTERN_C_END |
37 | 145 |
38 #endif | 146 #endif |
OLD | NEW |