1 | package org.j7zip.SevenZip.Compression.Branch;
|
---|
2 |
|
---|
3 | import org.j7zip.SevenZip.HRESULT;
|
---|
4 | import org.j7zip.SevenZip.ICompressFilter;
|
---|
5 |
|
---|
6 | public class BCJ_x86_Decoder implements ICompressFilter {
|
---|
7 |
|
---|
8 | // struct CBranch86 - begin
|
---|
9 | int [] _prevMask = new int[1]; // UInt32
|
---|
10 | int [] _prevPos = new int[1]; // UInt32
|
---|
11 | void x86Init() {
|
---|
12 | _prevMask[0] = 0;
|
---|
13 | _prevPos[0] = -5;
|
---|
14 | }
|
---|
15 | // struct CBranch86 - end
|
---|
16 |
|
---|
17 | static final boolean [] kMaskToAllowedStatus = {true, true, true, false, true, false, false, false };
|
---|
18 |
|
---|
19 | static final int [] kMaskToBitNumber = {0, 1, 2, 2, 3, 3, 3, 3};
|
---|
20 |
|
---|
21 | static final boolean Test86MSByte(int b) { return ((b) == 0 || (b) == 0xFF); }
|
---|
22 |
|
---|
23 | static final int x86_Convert(byte [] buffer, int endPos, int nowPos,
|
---|
24 | int [] prevMask, int [] prevPos, boolean encoding) {
|
---|
25 | int bufferPos = 0;
|
---|
26 | int limit;
|
---|
27 |
|
---|
28 | if (endPos < 5)
|
---|
29 | return 0;
|
---|
30 |
|
---|
31 | if (nowPos - prevPos[0] > 5)
|
---|
32 | prevPos[0] = nowPos - 5;
|
---|
33 |
|
---|
34 | limit = endPos - 5;
|
---|
35 | while(bufferPos <= limit) {
|
---|
36 | int b = (buffer[bufferPos] & 0xFF);
|
---|
37 | int offset;
|
---|
38 | if (b != 0xE8 && b != 0xE9) {
|
---|
39 | bufferPos++;
|
---|
40 | continue;
|
---|
41 | }
|
---|
42 | offset = (nowPos + bufferPos - prevPos[0]);
|
---|
43 | prevPos[0] = (nowPos + bufferPos);
|
---|
44 | if (offset > 5)
|
---|
45 | prevMask[0] = 0;
|
---|
46 | else {
|
---|
47 | for (int i = 0; i < offset; i++) {
|
---|
48 | prevMask[0] &= 0x77;
|
---|
49 | prevMask[0] <<= 1;
|
---|
50 | }
|
---|
51 | }
|
---|
52 | b = (buffer[bufferPos + 4] & 0xFF);
|
---|
53 | if (Test86MSByte(b) && kMaskToAllowedStatus[(prevMask[0] >> 1) & 0x7] &&
|
---|
54 | (prevMask[0] >>> 1) < 0x10) {
|
---|
55 | int src =
|
---|
56 | ((b) << 24) |
|
---|
57 | ((buffer[bufferPos + 3] & 0xFF) << 16) |
|
---|
58 | ((buffer[bufferPos + 2] & 0xFF) << 8) |
|
---|
59 | (buffer[bufferPos + 1] & 0xFF);
|
---|
60 |
|
---|
61 | int dest;
|
---|
62 | for (;;) {
|
---|
63 | int index;
|
---|
64 | if (encoding)
|
---|
65 | dest = (nowPos + bufferPos + 5) + src;
|
---|
66 | else
|
---|
67 | dest = src - (nowPos + bufferPos + 5);
|
---|
68 | if (prevMask[0] == 0)
|
---|
69 | break;
|
---|
70 | index = kMaskToBitNumber[prevMask[0] >>> 1];
|
---|
71 | b = (dest >> (24 - index * 8)) & 0xFF;
|
---|
72 | if (!Test86MSByte(b))
|
---|
73 | break;
|
---|
74 | src = dest ^ ((1 << (32 - index * 8)) - 1);
|
---|
75 | }
|
---|
76 | buffer[bufferPos + 4] = (byte)(~(((dest >> 24) & 1) - 1));
|
---|
77 | buffer[bufferPos + 3] = (byte)(dest >> 16);
|
---|
78 | buffer[bufferPos + 2] = (byte)(dest >> 8);
|
---|
79 | buffer[bufferPos + 1] = (byte)dest;
|
---|
80 | bufferPos += 5;
|
---|
81 | prevMask[0] = 0;
|
---|
82 | } else {
|
---|
83 | bufferPos++;
|
---|
84 | prevMask[0] |= 1;
|
---|
85 | if (Test86MSByte(b))
|
---|
86 | prevMask[0] |= 0x10;
|
---|
87 | }
|
---|
88 | }
|
---|
89 | return bufferPos;
|
---|
90 | }
|
---|
91 |
|
---|
92 | public int SubFilter(byte [] data, int size) {
|
---|
93 | return x86_Convert(data, size, _bufferPos, _prevMask, _prevPos, false);
|
---|
94 | }
|
---|
95 |
|
---|
96 | public void SubInit() {
|
---|
97 | x86Init();
|
---|
98 | }
|
---|
99 |
|
---|
100 | int _bufferPos; // UInt32
|
---|
101 |
|
---|
102 | // ICompressFilter interface
|
---|
103 | public int Init() {
|
---|
104 | _bufferPos = 0;
|
---|
105 | SubInit();
|
---|
106 | return HRESULT.S_OK;
|
---|
107 | }
|
---|
108 |
|
---|
109 | public int Filter(byte [] data, int size) {
|
---|
110 | int processedSize = SubFilter(data, size);
|
---|
111 | _bufferPos += processedSize;
|
---|
112 | return processedSize;
|
---|
113 | }
|
---|
114 | }
|
---|