1 /* Bcj2.c -- Converter for x86 code (BCJ2) 2 2008-10-04 : Igor Pavlov : Public domain */ 3 4 #include "Bcj2.h" 5 6 #ifdef _LZMA_PROB32 7 #define CProb UInt32 8 #else 9 #define CProb UInt16 10 #endif 11 12 #define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) 13 #define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) 14 15 #define kNumTopBits 24 16 #define kTopValue ((UInt32)1 << kNumTopBits) 17 18 #define kNumBitModelTotalBits 11 19 #define kBitModelTotal (1 << kNumBitModelTotalBits) 20 #define kNumMoveBits 5 21 22 #define RC_READ_BYTE (*buffer++) 23 #define RC_TEST { if (buffer == bufferLim) return SZ_ERROR_DATA; } 24 #define RC_INIT2 code = 0; range = 0xFFFFFFFF; \ 25 { int i; for (i = 0; i < 5; i++) { RC_TEST; code = (code << 8) | RC_READ_BYTE; }} 26 27 #define NORMALIZE if (range < kTopValue) { RC_TEST; range <<= 8; code = (code << 8) | RC_READ_BYTE; } 28 29 #define IF_BIT_0(p) ttt = *(p); bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound) 30 #define UPDATE_0(p) range = bound; *(p) = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); NORMALIZE; 31 #define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CProb)(ttt - (ttt >> kNumMoveBits)); NORMALIZE; 32 33 int Bcj2_Decode( 34 const Byte *buf0, SizeT size0, 35 const Byte *buf1, SizeT size1, 36 const Byte *buf2, SizeT size2, 37 const Byte *buf3, SizeT size3, 38 Byte *outBuf, SizeT outSize) 39 { 40 CProb p[256 + 2]; 41 SizeT inPos = 0, outPos = 0; 42 43 const Byte *buffer, *bufferLim; 44 UInt32 range, code; 45 Byte prevByte = 0; 46 47 unsigned int i; 48 for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) 49 p[i] = kBitModelTotal >> 1; 50 51 buffer = buf3; 52 bufferLim = buffer + size3; 53 RC_INIT2 54 55 if (outSize == 0) 56 return SZ_OK; 57 58 for (;;) 59 { 60 Byte b; 61 CProb *prob; 62 UInt32 bound; 63 UInt32 ttt; 64 65 SizeT limit = size0 - inPos; 66 if (outSize - outPos < limit) 67 limit = outSize - outPos; 68 while (limit != 0) 69 { 70 Byte b = buf0[inPos]; 71 outBuf[outPos++] = b; 72 if (IsJ(prevByte, b)) 73 break; 74 inPos++; 75 prevByte = b; 76 limit--; 77 } 78 79 if (limit == 0 || outPos == outSize) 80 break; 81 82 b = buf0[inPos++]; 83 84 if (b == 0xE8) 85 prob = p + prevByte; 86 else if (b == 0xE9) 87 prob = p + 256; 88 else 89 prob = p + 257; 90 91 IF_BIT_0(prob) 92 { 93 UPDATE_0(prob) 94 prevByte = b; 95 } 96 else 97 { 98 UInt32 dest; 99 const Byte *v; 100 UPDATE_1(prob) 101 if (b == 0xE8) 102 { 103 v = buf1; 104 if (size1 < 4) 105 return SZ_ERROR_DATA; 106 buf1 += 4; 107 size1 -= 4; 108 } 109 else 110 { 111 v = buf2; 112 if (size2 < 4) 113 return SZ_ERROR_DATA; 114 buf2 += 4; 115 size2 -= 4; 116 } 117 dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) | 118 ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4); 119 outBuf[outPos++] = (Byte)dest; 120 if (outPos == outSize) 121 break; 122 outBuf[outPos++] = (Byte)(dest >> 8); 123 if (outPos == outSize) 124 break; 125 outBuf[outPos++] = (Byte)(dest >> 16); 126 if (outPos == outSize) 127 break; 128 outBuf[outPos++] = prevByte = (Byte)(dest >> 24); 129 } 130 } 131 return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; 132 } 133