Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2007-06-26 04:00:00 +0400
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:15:52 +0300
commitfd8b1d78b496fe38193bf8c5e86af3b43f0b022d (patch)
tree5b1e3812ed4d8b6037e5035faf3b638849f618e2 /C/Compress/Branch
parent0b33f700a66fcf7f55f92b92e0b3e5c7014d769a (diff)
4.48 beta
Diffstat (limited to 'C/Compress/Branch')
-rwxr-xr-xC/Compress/Branch/BranchTypes.h15
-rwxr-xr-xC/Compress/Branch/BranchX86.c113
-rwxr-xr-xC/Compress/Branch/BranchX86.h5
-rwxr-xr-xC/Compress/Branch/BranchX86_2.c135
-rwxr-xr-xC/Compress/Branch/BranchX86_2.h28
5 files changed, 227 insertions, 69 deletions
diff --git a/C/Compress/Branch/BranchTypes.h b/C/Compress/Branch/BranchTypes.h
index bdf75131..1bed56a9 100755
--- a/C/Compress/Branch/BranchTypes.h
+++ b/C/Compress/Branch/BranchTypes.h
@@ -27,7 +27,7 @@ typedef unsigned int UInt32;
#ifdef _SZ_NO_INT_64
typedef unsigned long UInt64;
#else
-#ifdef _MSC_VER
+#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 UInt64;
#else
typedef unsigned long long int UInt64;
@@ -35,4 +35,17 @@ typedef unsigned long long int UInt64;
#endif
#endif
+/* #define _LZMA_NO_SYSTEM_SIZE_T */
+/* You can use it, if you don't want <stddef.h> */
+
+#ifndef _7ZIP_SIZET_DEFINED
+#define _7ZIP_SIZET_DEFINED
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+#include <stddef.h>
+typedef size_t SizeT;
+#endif
+#endif
+
#endif
diff --git a/C/Compress/Branch/BranchX86.c b/C/Compress/Branch/BranchX86.c
index c3f455b8..fd1d334e 100755
--- a/C/Compress/Branch/BranchX86.c
+++ b/C/Compress/Branch/BranchX86.c
@@ -2,100 +2,83 @@
#include "BranchX86.h"
-/*
-static int inline Test86MSByte(Byte b)
-{
- return (b == 0 || b == 0xFF);
-}
-*/
#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
-const int kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
+const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
-/*
-void x86_Convert_Init(UInt32 *prevMask, UInt32 *prevPos)
-{
- *prevMask = 0;
- *prevPos = (UInt32)(-5);
-}
-*/
-
-UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos,
- UInt32 *prevMask, UInt32 *prevPos, int encoding)
+SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *prevMaskMix, int encoding)
{
- UInt32 bufferPos = 0;
- UInt32 limit;
-
+ SizeT bufferPos = 0, prevPosT;
+ UInt32 prevMask = *prevMaskMix & 0x7;
if (endPos < 5)
return 0;
-
- if (nowPos - *prevPos > 5)
- *prevPos = nowPos - 5;
-
- limit = endPos - 5;
- while(bufferPos <= limit)
+ nowPos += 5;
+ prevPosT = (SizeT)0 - 1;
+
+ for(;;)
{
- Byte b = buffer[bufferPos];
- UInt32 offset;
- if (b != 0xE8 && b != 0xE9)
- {
- bufferPos++;
- continue;
- }
- offset = (nowPos + bufferPos - *prevPos);
- *prevPos = (nowPos + bufferPos);
- if (offset > 5)
- *prevMask = 0;
+ Byte *p = buffer + bufferPos;
+ Byte *limit = buffer + endPos - 4;
+ for (; p < limit; p++)
+ if ((*p & 0xFE) == 0xE8)
+ break;
+ bufferPos = (SizeT)(p - buffer);
+ if (p >= limit)
+ break;
+ prevPosT = bufferPos - prevPosT;
+ if (prevPosT > 3)
+ prevMask = 0;
else
{
- UInt32 i;
- for (i = 0; i < offset; i++)
+ prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
+ if (prevMask != 0)
{
- *prevMask &= 0x77;
- *prevMask <<= 1;
+ Byte b = p[4 - kMaskToBitNumber[prevMask]];
+ if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
+ {
+ prevPosT = bufferPos;
+ prevMask = ((prevMask << 1) & 0x7) | 1;
+ bufferPos++;
+ continue;
+ }
}
}
- b = buffer[bufferPos + 4];
- if (Test86MSByte(b) && kMaskToAllowedStatus[(*prevMask >> 1) & 0x7] &&
- (*prevMask >> 1) < 0x10)
+ prevPosT = bufferPos;
+
+ if (Test86MSByte(p[4]))
{
- UInt32 src =
- ((UInt32)(b) << 24) |
- ((UInt32)(buffer[bufferPos + 3]) << 16) |
- ((UInt32)(buffer[bufferPos + 2]) << 8) |
- (buffer[bufferPos + 1]);
-
+ UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
UInt32 dest;
for (;;)
{
- UInt32 index;
+ Byte b;
+ int index;
if (encoding)
- dest = (nowPos + bufferPos + 5) + src;
+ dest = (nowPos + (UInt32)bufferPos) + src;
else
- dest = src - (nowPos + bufferPos + 5);
- if (*prevMask == 0)
+ dest = src - (nowPos + (UInt32)bufferPos);
+ if (prevMask == 0)
break;
- index = kMaskToBitNumber[*prevMask >> 1];
- b = (Byte)(dest >> (24 - index * 8));
+ index = kMaskToBitNumber[prevMask] * 8;
+ b = (Byte)(dest >> (24 - index));
if (!Test86MSByte(b))
break;
- src = dest ^ ((1 << (32 - index * 8)) - 1);
+ src = dest ^ ((1 << (32 - index)) - 1);
}
- buffer[bufferPos + 4] = (Byte)(~(((dest >> 24) & 1) - 1));
- buffer[bufferPos + 3] = (Byte)(dest >> 16);
- buffer[bufferPos + 2] = (Byte)(dest >> 8);
- buffer[bufferPos + 1] = (Byte)dest;
+ p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
+ p[3] = (Byte)(dest >> 16);
+ p[2] = (Byte)(dest >> 8);
+ p[1] = (Byte)dest;
bufferPos += 5;
- *prevMask = 0;
}
else
{
+ prevMask = ((prevMask << 1) & 0x7) | 1;
bufferPos++;
- *prevMask |= 1;
- if (Test86MSByte(b))
- *prevMask |= 0x10;
}
}
+ prevPosT = bufferPos - prevPosT;
+ *prevMaskMix = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
return bufferPos;
}
diff --git a/C/Compress/Branch/BranchX86.h b/C/Compress/Branch/BranchX86.h
index 25c1ae51..5dfd02a7 100755
--- a/C/Compress/Branch/BranchX86.h
+++ b/C/Compress/Branch/BranchX86.h
@@ -5,9 +5,8 @@
#include "BranchTypes.h"
-#define x86_Convert_Init(prevMask, prevPos) { prevMask = 0; prevPos = (UInt32)(-5); }
+#define x86_Convert_Init(state) { state = 0; }
-UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos,
- UInt32 *prevMask, UInt32 *prevPos, int encoding);
+SizeT x86_Convert(Byte *buffer, SizeT endPos, UInt32 nowPos, UInt32 *state, int encoding);
#endif
diff --git a/C/Compress/Branch/BranchX86_2.c b/C/Compress/Branch/BranchX86_2.c
new file mode 100755
index 00000000..241789a5
--- /dev/null
+++ b/C/Compress/Branch/BranchX86_2.c
@@ -0,0 +1,135 @@
+// BranchX86_2.c
+
+#include "BranchX86_2.h"
+
+#include "../../Alloc.h"
+
+#ifdef _LZMA_PROB32
+#define CProb UInt32
+#else
+#define CProb UInt16
+#endif
+
+#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80)
+#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1))
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_READ_BYTE (*Buffer++)
+
+#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \
+ { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }}
+
+#define RC_TEST { if (Buffer == BufferLim) return BCJ2_RESULT_DATA_ERROR; }
+
+#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2
+
+#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; }
+
+#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound)
+#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits;
+#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits;
+// #define UpdateBit0(p) Range = bound; *(p) = (CProb)(*(p) + ((kBitModelTotal - *(p)) >> kNumMoveBits));
+// #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) = (CProb)(*(p) - (*(p) >> kNumMoveBits));
+
+int x86_2_Decode(
+ const Byte *buf0, SizeT size0,
+ const Byte *buf1, SizeT size1,
+ const Byte *buf2, SizeT size2,
+ const Byte *buf3, SizeT size3,
+ Byte *outBuf, SizeT outSize)
+{
+ CProb p[256 + 2];
+ SizeT inPos = 0, outPos = 0;
+
+ const Byte *Buffer, *BufferLim;
+ UInt32 Range, Code;
+ Byte prevByte = 0;
+
+ unsigned int i;
+ for (i = 0; i < sizeof(p) / sizeof(p[0]); i++)
+ p[i] = kBitModelTotal >> 1;
+ RC_INIT(buf3, size3);
+
+ if (outSize == 0)
+ return BCJ2_RESULT_OK;
+
+ for (;;)
+ {
+ Byte b;
+ CProb *prob;
+ UInt32 bound;
+
+ SizeT limit = size0 - inPos;
+ if (outSize - outPos < limit)
+ limit = outSize - outPos;
+ while (limit != 0)
+ {
+ Byte b = buf0[inPos];
+ outBuf[outPos++] = b;
+ if (IsJ(prevByte, b))
+ break;
+ inPos++;
+ prevByte = b;
+ limit--;
+ }
+
+ if (limit == 0 || outPos == outSize)
+ break;
+
+ b = buf0[inPos++];
+
+ if (b == 0xE8)
+ prob = p + prevByte;
+ else if (b == 0xE9)
+ prob = p + 256;
+ else
+ prob = p + 257;
+
+ IfBit0(prob)
+ {
+ UpdateBit0(prob)
+ prevByte = b;
+ }
+ else
+ {
+ UInt32 dest;
+ const Byte *v;
+ UpdateBit1(prob)
+ if (b == 0xE8)
+ {
+ v = buf1;
+ if (size1 < 4)
+ return BCJ2_RESULT_DATA_ERROR;
+ buf1 += 4;
+ size1 -= 4;
+ }
+ else
+ {
+ v = buf2;
+ if (size2 < 4)
+ return BCJ2_RESULT_DATA_ERROR;
+ buf2 += 4;
+ size2 -= 4;
+ }
+ dest = (((UInt32)v[0] << 24) | ((UInt32)v[1] << 16) |
+ ((UInt32)v[2] << 8) | ((UInt32)v[3])) - ((UInt32)outPos + 4);
+ outBuf[outPos++] = (Byte)dest;
+ if (outPos == outSize)
+ break;
+ outBuf[outPos++] = (Byte)(dest >> 8);
+ if (outPos == outSize)
+ break;
+ outBuf[outPos++] = (Byte)(dest >> 16);
+ if (outPos == outSize)
+ break;
+ outBuf[outPos++] = prevByte = (Byte)(dest >> 24);
+ }
+ }
+ return (outPos == outSize) ? BCJ2_RESULT_OK : BCJ2_RESULT_DATA_ERROR;
+}
diff --git a/C/Compress/Branch/BranchX86_2.h b/C/Compress/Branch/BranchX86_2.h
new file mode 100755
index 00000000..4d861fa3
--- /dev/null
+++ b/C/Compress/Branch/BranchX86_2.h
@@ -0,0 +1,28 @@
+// BranchX86_2.h
+
+#ifndef __BRANCHX86_2_H
+#define __BRANCHX86_2_H
+
+#include "BranchTypes.h"
+
+#define BCJ2_RESULT_OK 0
+#define BCJ2_RESULT_DATA_ERROR 1
+
+/*
+Conditions:
+ outSize <= FullOutputSize,
+ where FullOutputSize is full size of output stream of x86_2 filter.
+
+If buf0 overlaps outBuf, there are two required conditions:
+ 1) (buf0 >= outBuf)
+ 2) (buf0 + size0 >= outBuf + FullOutputSize).
+*/
+
+int x86_2_Decode(
+ const Byte *buf0, SizeT size0,
+ const Byte *buf1, SizeT size1,
+ const Byte *buf2, SizeT size2,
+ const Byte *buf3, SizeT size3,
+ Byte *outBuf, SizeT outSize);
+
+#endif