This commit is contained in:
Igor Pavlov
2005-05-30 00:00:00 +00:00
committed by Kornel Lesiński
parent 8c1b5c7b7e
commit 3c510ba80b
926 changed files with 40559 additions and 23519 deletions

View File

@@ -3,67 +3,14 @@
#include "StdAfx.h"
#include "ARM.h"
#include "Windows/Defs.h"
#include "BranchARM.c"
static HRESULT BC_ARM_Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
UInt32 CBC_ARM_Encoder::SubFilter(Byte *data, UInt32 size)
{
UINT32 nowPos = 0;
UINT64 nowPos64 = 0;
UINT32 bufferPos = 0;
while(true)
{
UINT32 processedSize;
UINT32 size = kBufferSize - bufferPos;
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
UINT32 endPos = bufferPos + processedSize;
if (endPos < 4)
{
if (endPos > 0)
{
RINOK(outStream->Write(buffer, endPos, &processedSize));
if (endPos != processedSize)
return E_FAIL;
}
return S_OK;
}
for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 4)
{
if (buffer[bufferPos + 3] == 0xeb)
{
UINT32 src =
(buffer[bufferPos + 2] << 16) |
(buffer[bufferPos + 1] << 8) |
(buffer[bufferPos + 0]);
src <<= 2;
UINT32 dest;
if (encoding)
dest = nowPos + bufferPos + 8 + src;
else
dest = src - (nowPos + bufferPos + 8);
dest >>= 2;
buffer[bufferPos + 2] = (dest >> 16);
buffer[bufferPos + 1] = (dest >> 8);
buffer[bufferPos + 0] = dest;
}
}
nowPos += bufferPos;
nowPos64 += bufferPos;
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
if (bufferPos != processedSize)
return E_FAIL;
if (progress != NULL)
{
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
}
UINT32 i = 0;
while(bufferPos < endPos)
buffer[i++] = buffer[bufferPos++];
bufferPos = i;
}
return ::ARM_Convert(data, size, _bufferPos, 1);
}
MyClassImp(BC_ARM)
UInt32 CBC_ARM_Decoder::SubFilter(Byte *data, UInt32 size)
{
return ::ARM_Convert(data, size, _bufferPos, 0);
}

View File

@@ -1,12 +1,10 @@
// ARM.h
#pragma once
#ifndef __ARM_H
#define __ARM_H
#include "Coder.h"
#include "BranchCoder.h"
MyClass(BC_ARM, 0x05, 1)
MyClassA(BC_ARM, 0x05, 1)
#endif

View File

@@ -3,74 +3,14 @@
#include "StdAfx.h"
#include "ARMThumb.h"
#include "Windows/Defs.h"
#include "BranchARMThumb.c"
static HRESULT BC_ARMThumb_Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
UInt32 CBC_ARMThumb_Encoder::SubFilter(Byte *data, UInt32 size)
{
UINT32 nowPos = 0;
UINT64 nowPos64 = 0;
UINT32 bufferPos = 0;
while(true)
{
UINT32 processedSize;
UINT32 size = kBufferSize - bufferPos;
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
UINT32 endPos = bufferPos + processedSize;
if (endPos < 4)
{
if (endPos > 0)
{
RINOK(outStream->Write(buffer, endPos, &processedSize));
if (endPos != processedSize)
return E_FAIL;
}
return S_OK;
}
for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 2)
{
if ((buffer[bufferPos + 1] & 0xF8) == 0xF0 &&
(buffer[bufferPos + 3] & 0xF8) == 0xF8)
{
UINT32 src =
((buffer[bufferPos + 1] & 0x7) << 19) |
(buffer[bufferPos + 0] << 11) |
((buffer[bufferPos + 3] & 0x7) << 8) |
(buffer[bufferPos + 2]);
src <<= 1;
UINT32 dest;
if (encoding)
dest = nowPos + bufferPos + 4 + src;
else
dest = src - (nowPos + bufferPos + 4);
dest >>= 1;
buffer[bufferPos + 1] = 0xF0 | ((dest >> 19) & 0x7);
buffer[bufferPos + 0] = (dest >> 11);
buffer[bufferPos + 3] = 0xF8 | ((dest >> 8) & 0x7);
buffer[bufferPos + 2] = (dest);
bufferPos += 2;
}
}
nowPos += bufferPos;
nowPos64 += bufferPos;
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
if (bufferPos != processedSize)
return E_FAIL;
if (progress != NULL)
{
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
}
UINT32 i = 0;
while(bufferPos < endPos)
buffer[i++] = buffer[bufferPos++];
bufferPos = i;
}
return ::ARMThumb_Convert(data, size, _bufferPos, 1);
}
MyClassImp(BC_ARMThumb)
UInt32 CBC_ARMThumb_Decoder::SubFilter(Byte *data, UInt32 size)
{
return ::ARMThumb_Convert(data, size, _bufferPos, 0);
}

View File

@@ -1,12 +1,10 @@
// ARMThumb.h
#pragma once
#ifndef __ARMTHUMB_H
#define __ARMTHUMB_H
#include "Coder.h"
#include "BranchCoder.h"
MyClass(BC_ARMThumb, 0x07, 1)
MyClassA(BC_ARMThumb, 0x07, 1)
#endif

View File

@@ -1,75 +0,0 @@
// Alpha.cpp
#include "StdAfx.h"
#include "Alpha.h"
#include "Windows/Defs.h"
static HRESULT BC_Alpha_Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
{
UINT32 nowPos = 0;
UINT64 nowPos64 = 0;
UINT32 bufferPos = 0;
while(true)
{
UINT32 processedSize;
UINT32 size = kBufferSize - bufferPos;
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
UINT32 endPos = bufferPos + processedSize;
if (endPos < 4)
{
if (endPos > 0)
{
RINOK(outStream->Write(buffer, endPos, &processedSize));
if (endPos != processedSize)
return E_FAIL;
}
return S_OK;
}
for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 4)
{
// if (buffer[bufferPos + 3] == 0xc3 && (buffer[bufferPos + 2] >> 5) == 7) // its jump
// if (buffer[bufferPos + 3] == 0xd3 && (buffer[bufferPos + 2] >> 5) == 2)
// if (buffer[bufferPos + 3] == 0xd3)
if ((buffer[bufferPos + 3] >> 2) == 0x34)
{
UINT32 src =
((buffer[bufferPos + 2] & 0x1F) << 16) |
(buffer[bufferPos + 1] << 8) |
(buffer[bufferPos + 0]);
src <<= 2;
UINT32 dest;
if (encoding)
dest = (nowPos + bufferPos + 4) + src;
else
dest = src - (nowPos + bufferPos + 4);
dest >>= 2;
dest &= 0x1FFFFF;
buffer[bufferPos + 2] &= (~0x1F);
buffer[bufferPos + 2] |= (dest >> 16);
buffer[bufferPos + 1] = (dest >> 8);
buffer[bufferPos + 0] = dest;
}
}
nowPos += bufferPos;
nowPos64 += bufferPos;
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
if (bufferPos != processedSize)
return E_FAIL;
if (progress != NULL)
{
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
}
UINT32 i = 0;
while(bufferPos < endPos)
buffer[i++] = buffer[bufferPos++];
bufferPos = i;
}
}
MyClassImp(BC_Alpha)

View File

@@ -1,12 +0,0 @@
// Alpha.h
#pragma once
#ifndef __ALPHA_H
#define __ALPHA_H
#include "Coder.h"
MyClass(BC_Alpha, 0x03, 1)
#endif

View File

@@ -123,24 +123,6 @@ SOURCE=.\StdAfx.h
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\Alpha.cpp
!IF "$(CFG)" == "Branch - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Branch - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\Alpha.h
# End Source File
# Begin Source File
SOURCE=.\ARM.cpp
!IF "$(CFG)" == "Branch - Win32 Release"
@@ -177,7 +159,15 @@ SOURCE=.\ARMThumb.h
# End Source File
# Begin Source File
SOURCE=.\Coder.h
SOURCE=.\BranchCoder.cpp
# End Source File
# Begin Source File
SOURCE=.\BranchCoder.h
# End Source File
# Begin Source File
SOURCE=.\BranchX86.h
# End Source File
# Begin Source File
@@ -199,24 +189,6 @@ SOURCE=.\IA64.h
# End Source File
# Begin Source File
SOURCE=.\M68.cpp
!IF "$(CFG)" == "Branch - Win32 Release"
# ADD CPP /O2
# SUBTRACT CPP /YX /Yc /Yu
!ELSEIF "$(CFG)" == "Branch - Win32 Debug"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\M68.h
# End Source File
# Begin Source File
SOURCE=.\PPC.cpp
!IF "$(CFG)" == "Branch - Win32 Release"
@@ -235,6 +207,14 @@ SOURCE=.\PPC.h
# End Source File
# Begin Source File
SOURCE=.\SPARC.cpp
# End Source File
# Begin Source File
SOURCE=.\SPARC.h
# End Source File
# Begin Source File
SOURCE=.\x86.cpp
!IF "$(CFG)" == "Branch - Win32 Release"
@@ -305,6 +285,14 @@ SOURCE=..\RangeCoder\RangeCoderBit.h
# Begin Group "Common"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\..\Common\Alloc.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\Common\Alloc.h
# End Source File
# End Group
# End Target
# End Project

View File

@@ -0,0 +1,26 @@
// BranchARM.c
#include "BranchARM.h"
UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
{
UInt32 i;
for (i = 0; i + 4 <= size; i += 4)
{
if (data[i + 3] == 0xEB)
{
UInt32 src = (data[i + 2] << 16) | (data[i + 1] << 8) | (data[i + 0]);
src <<= 2;
UInt32 dest;
if (encoding)
dest = nowPos + i + 8 + src;
else
dest = src - (nowPos + i + 8);
dest >>= 2;
data[i + 2] = (dest >> 16);
data[i + 1] = (dest >> 8);
data[i + 0] = dest;
}
}
return i;
}

View File

@@ -0,0 +1,10 @@
// BranchARM.h
#ifndef __BRANCH_ARM_H
#define __BRANCH_ARM_H
#include "Common/Types.h"
UInt32 ARM_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
#endif

View File

@@ -0,0 +1,35 @@
// BranchARMThumb.c
#include "BranchARMThumb.h"
UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
{
UInt32 i;
for (i = 0; i + 4 <= size; i += 2)
{
if ((data[i + 1] & 0xF8) == 0xF0 &&
(data[i + 3] & 0xF8) == 0xF8)
{
UInt32 src =
((data[i + 1] & 0x7) << 19) |
(data[i + 0] << 11) |
((data[i + 3] & 0x7) << 8) |
(data[i + 2]);
src <<= 1;
UInt32 dest;
if (encoding)
dest = nowPos + i + 4 + src;
else
dest = src - (nowPos + i + 4);
dest >>= 1;
data[i + 1] = 0xF0 | ((dest >> 19) & 0x7);
data[i + 0] = (dest >> 11);
data[i + 3] = 0xF8 | ((dest >> 8) & 0x7);
data[i + 2] = (dest);
i += 2;
}
}
return i;
}

View File

@@ -0,0 +1,10 @@
// BranchARMThumb.h
#ifndef __BRANCH_ARM_THUMB_H
#define __BRANCH_ARM_THUMB_H
#include "Common/Types.h"
UInt32 ARMThumb_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
#endif

View File

@@ -0,0 +1,18 @@
// BranchCoder.cpp
#include "StdAfx.h"
#include "BranchCoder.h"
STDMETHODIMP CBranchConverter::Init()
{
_bufferPos = 0;
SubInit();
return S_OK;
}
STDMETHODIMP_(UInt32) CBranchConverter::Filter(Byte *data, UInt32 size)
{
UInt32 processedSize = SubFilter(data, size);
_bufferPos += processedSize;
return processedSize;
}

View File

@@ -0,0 +1,54 @@
// BranchCoder.h
#ifndef __BRANCH_CODER_H
#define __BRANCH_CODER_H
#include "Common/MyCom.h"
#include "Common/Types.h"
#include "Common/Alloc.h"
#include "../../ICoder.h"
class CBranchConverter:
public ICompressFilter,
public CMyUnknownImp
{
protected:
UInt32 _bufferPos;
virtual void SubInit() {}
virtual UInt32 SubFilter(Byte *data, UInt32 size) = 0;
public:
MY_UNKNOWN_IMP;
STDMETHOD(Init)();
STDMETHOD_(UInt32, Filter)(Byte *data, UInt32 size);
};
#define MyClassEncoderA(Name) class C ## Name: public CBranchConverter \
{ public: UInt32 SubFilter(Byte *data, UInt32 size); };
#define MyClassDecoderA(Name) class C ## Name: public CBranchConverter \
{ public: UInt32 SubFilter(Byte *data, UInt32 size); };
#define MyClassEncoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
{ public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
#define MyClassDecoderB(Name, ADD_ITEMS, ADD_INIT) class C ## Name: public CBranchConverter, public ADD_ITEMS \
{ public: UInt32 SubFilter(Byte *data, UInt32 size); ADD_INIT};
#define MyClass2b(Name, id, subId, encodingId) \
DEFINE_GUID(CLSID_CCompressConvert ## Name, \
0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00);
#define MyClassA(Name, id, subId) \
MyClass2b(Name ## _Encoder, id, subId, 0x01) \
MyClassEncoderA(Name ## _Encoder) \
MyClass2b(Name ## _Decoder, id, subId, 0x00) \
MyClassDecoderA(Name ## _Decoder)
#define MyClassB(Name, id, subId, ADD_ITEMS, ADD_INIT) \
MyClass2b(Name ## _Encoder, id, subId, 0x01) \
MyClassEncoderB(Name ## _Encoder, ADD_ITEMS, ADD_INIT) \
MyClass2b(Name ## _Decoder, id, subId, 0x00) \
MyClassDecoderB(Name ## _Decoder, ADD_ITEMS, ADD_INIT)
#endif

View File

@@ -0,0 +1,65 @@
// BranchIA64.c
#include "BranchIA64.h"
const Byte kBranchTable[32] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
4, 4, 6, 6, 0, 0, 7, 7,
4, 4, 0, 0, 4, 4, 0, 0
};
UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
{
UInt32 i;
for (i = 0; i + 16 <= size; i += 16)
{
UInt32 instrTemplate = data[i] & 0x1F;
UInt32 mask = kBranchTable[instrTemplate];
UInt32 bitPos = 5;
for (int slot = 0; slot < 3; slot++, bitPos += 41)
{
if (((mask >> slot) & 1) == 0)
continue;
UInt32 bytePos = (bitPos >> 3);
UInt32 bitRes = bitPos & 0x7;
// UInt64 instruction = *(UInt64 *)(data + i + bytePos);
UInt64 instruction = 0;
int j;
for (j = 0; j < 6; j++)
instruction += (UInt64)(data[i + j + bytePos]) << (8 * j);
UInt64 instNorm = instruction >> bitRes;
if (((instNorm >> 37) & 0xF) == 0x5
&& ((instNorm >> 9) & 0x7) == 0
// && (instNorm & 0x3F)== 0
)
{
UInt32 src = UInt32((instNorm >> 13) & 0xFFFFF);
src |= ((instNorm >> 36) & 1) << 20;
src <<= 4;
UInt32 dest;
if (encoding)
dest = nowPos + i + src;
else
dest = src - (nowPos + i);
dest >>= 4;
instNorm &= ~(UInt64(0x8FFFFF) << 13);
instNorm |= (UInt64(dest & 0xFFFFF) << 13);
instNorm |= (UInt64(dest & 0x100000) << (36 - 20));
instruction &= (1 << bitRes) - 1;
instruction |= (instNorm << bitRes);
// *(UInt64 *)(data + i + bytePos) = instruction;
for (j = 0; j < 6; j++)
data[i + j + bytePos] = Byte(instruction >> (8 * j));
}
}
}
return i;
}

View File

@@ -0,0 +1,10 @@
// BranchIA64.h
#ifndef __BRANCH_IA64_H
#define __BRANCH_IA64_H
#include "Common/Types.h"
UInt32 IA64_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
#endif

View File

@@ -0,0 +1,36 @@
// BranchPPC.c
#include "BranchPPC.h"
UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
{
UInt32 i;
for (i = 0; i + 4 <= size; i += 4)
{
// PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link)
if ((data[i] >> 2) == 0x12 &&
(
(data[i + 3] & 3) == 1
// || (data[i+3] & 3) == 3
)
)
{
UInt32 src = ((data[i + 0] & 3) << 24) |
(data[i + 1] << 16) |
(data[i + 2] << 8) |
(data[i + 3] & (~3));
UInt32 dest;
if (encoding)
dest = nowPos + i + src;
else
dest = src - (nowPos + i);
data[i + 0] = 0x48 | ((dest >> 24) & 0x3);
data[i + 1] = (dest >> 16);
data[i + 2] = (dest >> 8);
data[i + 3] &= 0x3;
data[i + 3] |= dest;
}
}
return i;
}

View File

@@ -0,0 +1,10 @@
// BranchPPC.h
#ifndef __BRANCH_PPC_H
#define __BRANCH_PPC_H
#include "Common/Types.h"
UInt32 PPC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
#endif

View File

@@ -0,0 +1,36 @@
// BranchSPARC.c
#include "BranchSPARC.h"
UInt32 SPARC_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding)
{
UInt32 i;
for (i = 0; i + 4 <= size; i += 4)
{
if (data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00 ||
data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)
{
UInt32 src =
((UInt32)data[i + 0] << 24) |
((UInt32)data[i + 1] << 16) |
((UInt32)data[i + 2] << 8) |
((UInt32)data[i + 3]);
src <<= 2;
UInt32 dest;
if (encoding)
dest = nowPos + i + src;
else
dest = src - (nowPos + i);
dest >>= 2;
dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
data[i + 0] = (Byte)(dest >> 24);
data[i + 1] = (Byte)(dest >> 16);
data[i + 2] = (Byte)(dest >> 8);
data[i + 3] = (Byte)dest;
}
}
return i;
}

View File

@@ -0,0 +1,10 @@
// BranchSPARC.h
#ifndef __BRANCH_SPARC_H
#define __BRANCH_SPARC_H
#include "Common/Types.h"
UInt32 SPARC_B_Convert(Byte *data, UInt32 size, UInt32 nowPos, int encoding);
#endif

101
7zip/Compress/Branch/BranchX86.c Executable file
View File

@@ -0,0 +1,101 @@
/* BranchX86.c */
#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 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)
{
UInt32 bufferPos = 0;
UInt32 limit;
if (endPos < 5)
return 0;
if (nowPos - *prevPos > 5)
*prevPos = nowPos - 5;
limit = endPos - 5;
while(bufferPos <= limit)
{
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;
else
{
UInt32 i;
for (i = 0; i < offset; i++)
{
*prevMask &= 0x77;
*prevMask <<= 1;
}
}
b = buffer[bufferPos + 4];
if (Test86MSByte(b) && kMaskToAllowedStatus[(*prevMask >> 1) & 0x7] &&
(*prevMask >> 1) < 0x10)
{
UInt32 src =
((UInt32)(b) << 24) |
((UInt32)(buffer[bufferPos + 3]) << 16) |
((UInt32)(buffer[bufferPos + 2]) << 8) |
(buffer[bufferPos + 1]);
UInt32 dest;
while(1)
{
UInt32 index;
if (encoding)
dest = (nowPos + bufferPos + 5) + src;
else
dest = src - (nowPos + bufferPos + 5);
if (*prevMask == 0)
break;
index = kMaskToBitNumber[*prevMask >> 1];
b = (Byte)(dest >> (24 - index * 8));
if (!Test86MSByte(b))
break;
src = dest ^ ((1 << (32 - index * 8)) - 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;
bufferPos += 5;
*prevMask = 0;
}
else
{
bufferPos++;
*prevMask |= 1;
if (Test86MSByte(b))
*prevMask |= 0x10;
}
}
return bufferPos;
}

View File

@@ -0,0 +1,19 @@
/* BranchX86.h */
#ifndef __BRANCHX86_H
#define __BRANCHX86_H
#ifndef UInt32
#define UInt32 unsigned int
#endif
#ifndef Byte
#define Byte unsigned char
#endif
#define x86_Convert_Init(prevMask, prevPos) { prevMask = 0; prevPos = (UInt32)(-5); }
UInt32 x86_Convert(Byte *buffer, UInt32 endPos, UInt32 nowPos,
UInt32 *prevMask, UInt32 *prevPos, int encoding);
#endif

View File

@@ -1,66 +0,0 @@
// Branch/Coder.h
#pragma once
#ifndef __CallPowerPC_CODER_H
#define __CallPowerPC_CODER_H
#include "Common/MyCom.h"
#include "Common/Types.h"
#include "../../ICoder.h"
const int kBufferSize = 1 << 17;
class CDataBuffer
{
protected:
BYTE *_buffer;
public:
CDataBuffer()
{ _buffer = new BYTE[kBufferSize]; }
~CDataBuffer()
{ delete []_buffer; }
};
#define MyClass3(Name) \
class C ## Name: \
public ICompressCoder, \
public CDataBuffer, \
public CMyUnknownImp \
{ \
public: \
MY_UNKNOWN_IMP \
STDMETHOD(Code)(ISequentialInStream *inStream, \
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, \
ICompressProgressInfo *progress); \
};
// {23170F69-40C1-278B-0303-010100000100}
#define MyClass2(Name, id, subId, encodingId) \
DEFINE_GUID(CLSID_CCompressConvert ## Name, \
0x23170F69, 0x40C1, 0x278B, 0x03, 0x03, id, subId, 0x00, 0x00, encodingId, 0x00); \
MyClass3(Name) \
#define MyClass(Name, id, subId) \
MyClass2(Name ## _Encoder, id, subId, 0x01) \
MyClass2(Name ## _Decoder, id, subId, 0x00)
#define MyClassImp(Name) \
STDMETHODIMP C ## Name ## _Encoder::Code(ISequentialInStream *inStream, \
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, \
ICompressProgressInfo *progress) \
{ \
return Name ## _Code(inStream, outStream, inSize, outSize, \
progress, _buffer, true); \
} \
STDMETHODIMP C ## Name ## _Decoder::Code(ISequentialInStream *inStream, \
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize, \
ICompressProgressInfo *progress) \
{ \
return Name ## _Code(inStream, outStream, inSize, outSize, \
progress, _buffer, false); \
}
#endif

View File

@@ -2,52 +2,28 @@
#include "StdAfx.h"
#define INITGUID
#include "Common/MyInitGuid.h"
#include "Common/ComTry.h"
#include "Coder.h"
#include "x86.h"
#include "PPC.h"
#include "Alpha.h"
#include "IA64.h"
#include "ARM.h"
#include "ARMThumb.h"
#include "M68.h"
#include "x86_2.h"
#include "SPARC.h"
#include "../../ICoder.h"
#define MY_CreateClass(n) \
#define MY_CreateClass0(n) \
if (*clsid == CLSID_CCompressConvert ## n ## _Encoder) { \
if (!correctInterface) \
return E_NOINTERFACE; \
coder = (ICompressCoder *)new C ## n ## _Encoder(); \
filter = (ICompressFilter *)new C ## n ## _Encoder(); \
} else if (*clsid == CLSID_CCompressConvert ## n ## _Decoder){ \
if (!correctInterface) \
return E_NOINTERFACE; \
coder = (ICompressCoder *)new C ## n ## _Decoder(); \
filter = (ICompressFilter *)new C ## n ## _Decoder(); \
}
/*
#define MyOBJECT_ENTRY(Name) \
OBJECT_ENTRY(CLSID_CCompressConvert ## Name ## _Encoder, C ## Name ## _Encoder) \
OBJECT_ENTRY(CLSID_CCompressConvert ## Name ## _Decoder, C ## Name ## _Decoder) \
BEGIN_OBJECT_MAP(ObjectMap)
MyOBJECT_ENTRY(BCJ_x86)
MyOBJECT_ENTRY(BCJ2_x86)
MyOBJECT_ENTRY(BC_PPC_B)
MyOBJECT_ENTRY(BC_Alpha)
MyOBJECT_ENTRY(BC_IA64)
MyOBJECT_ENTRY(BC_ARM)
MyOBJECT_ENTRY(BC_ARMThumb)
MyOBJECT_ENTRY(BC_M68_B)
END_OBJECT_MAP()
*/
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
@@ -61,22 +37,19 @@ STDAPI CreateObject(
{
COM_TRY_BEGIN
*outObject = 0;
int correctInterface = (*interfaceID == IID_ICompressCoder);
CMyComPtr<ICompressCoder> coder;
MY_CreateClass(BCJ_x86)
int correctInterface = (*interfaceID == IID_ICompressFilter);
CMyComPtr<ICompressFilter> filter;
MY_CreateClass0(BCJ_x86)
else
MY_CreateClass(BC_PPC_B)
MY_CreateClass0(BC_ARM)
else
MY_CreateClass(BC_Alpha)
MY_CreateClass0(BC_PPC_B)
else
MY_CreateClass(BC_IA64)
MY_CreateClass0(BC_IA64)
else
MY_CreateClass(BC_ARM)
MY_CreateClass0(BC_ARMThumb)
else
MY_CreateClass(BC_ARMThumb)
else
MY_CreateClass(BC_M68_B)
MY_CreateClass0(BC_SPARC)
else
{
CMyComPtr<ICompressCoder2> coder2;
@@ -98,8 +71,9 @@ STDAPI CreateObject(
*outObject = coder2.Detach();
return S_OK;
}
*outObject = coder.Detach();
*outObject = filter.Detach();
return S_OK;
COM_TRY_END
}
@@ -123,11 +97,12 @@ static CBranchMethodItem g_Methods[] =
METHOD_ITEM(BCJ_x86, 0x01, 0x03, L"BCJ", 1),
METHOD_ITEM(BCJ2_x86, 0x01, 0x1B, L"BCJ2", 4),
METHOD_ITEM(BC_PPC_B, 0x02, 0x05, L"BC_PPC_B", 1),
METHOD_ITEM(BC_Alpha, 0x03, 1, L"BC_Alpha", 1),
// METHOD_ITEM(BC_Alpha, 0x03, 1, L"BC_Alpha", 1),
METHOD_ITEM(BC_IA64, 0x04, 1, L"BC_IA64", 1),
METHOD_ITEM(BC_ARM, 0x05, 1, L"BC_ARM", 1),
METHOD_ITEM(BC_M68_B, 0x06, 5, L"BC_M68_B", 1),
METHOD_ITEM(BC_ARMThumb, 0x07, 1, L"BC_ARMThumb", 1)
// METHOD_ITEM(BC_M68_B, 0x06, 5, L"BC_M68_B", 1),
METHOD_ITEM(BC_ARMThumb, 0x07, 1, L"BC_ARMThumb", 1),
METHOD_ITEM(BC_SPARC, 0x08, 0x05, L"BC_SPARC", 1)
};
STDAPI GetNumberOfMethods(UINT32 *numMethods)
@@ -175,4 +150,3 @@ STDAPI GetMethodProperty(UINT32 index, PROPID propID, PROPVARIANT *value)
}
return S_OK;
}

View File

@@ -3,101 +3,14 @@
#include "StdAfx.h"
#include "IA64.h"
#include "Windows/Defs.h"
#include "BranchIA64.c"
const BYTE kBranchTable[32] =
{
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
4, 4, 6, 6, 0, 0, 7, 7,
4, 4, 0, 0, 4, 4, 0, 0
};
static HRESULT BC_IA64_Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
UInt32 CBC_IA64_Encoder::SubFilter(Byte *data, UInt32 size)
{
UINT32 nowPos = 0;
UINT64 nowPos64 = 0;
UINT32 bufferPos = 0;
while(true)
{
UINT32 processedSize;
UINT32 size = kBufferSize - bufferPos;
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
UINT32 endPos = bufferPos + processedSize;
if (endPos < 16)
{
if (endPos > 0)
{
RINOK(outStream->Write(buffer, endPos, &processedSize));
if (endPos != processedSize)
return E_FAIL;
}
return S_OK;
}
for (bufferPos = 0; bufferPos <= endPos - 16; bufferPos += 16)
{
UINT32 instrTemplate = buffer[bufferPos] & 0x1F;
// ofs << hex << setw(4) << instrTemplate << endl;
UINT32 mask = kBranchTable[instrTemplate];
UINT32 bitPos = 5;
for (int slot = 0; slot < 3; slot++, bitPos += 41)
{
if (((mask >> slot) & 1) == 0)
continue;
UINT32 bytePos = (bitPos >> 3);
UINT32 bitRes = bitPos & 0x7;
UINT64 instruction = *(UINT64 *)(buffer + bufferPos + bytePos);
UINT64 instNorm = instruction >> bitRes;
if (((instNorm >> 37) & 0xF) == 0x5
&& ((instNorm >> 9) & 0x7) == 0
// && (instNorm & 0x3F)== 0
)
{
UINT32 src = UINT32((instNorm >> 13) & 0xFFFFF);
src |= ((instNorm >> 36) & 1) << 20;
src <<= 4;
UINT32 dest;
if (encoding)
dest = nowPos + bufferPos + src;
else
dest = src - (nowPos + bufferPos);
dest >>= 4;
UINT64 instNorm2 = instNorm;
instNorm &= ~(UINT64(0x8FFFFF) << 13);
instNorm |= (UINT64(dest & 0xFFFFF) << 13);
instNorm |= (UINT64(dest & 0x100000) << (36 - 20));
instruction &= (1 << bitRes) - 1;
instruction |= (instNorm << bitRes);
*(UINT64 *)(buffer + bufferPos + bytePos) = instruction;
}
}
}
nowPos += bufferPos;
nowPos64 += bufferPos;
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
if (bufferPos != processedSize)
return E_FAIL;
if (progress != NULL)
{
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
}
UINT32 i = 0;
while(bufferPos < endPos)
buffer[i++] = buffer[bufferPos++];
bufferPos = i;
}
return ::IA64_Convert(data, size, _bufferPos, 1);
}
MyClassImp(BC_IA64)
UInt32 CBC_IA64_Decoder::SubFilter(Byte *data, UInt32 size)
{
return ::IA64_Convert(data, size, _bufferPos, 0);
}

View File

@@ -1,14 +1,10 @@
// IA64.h
#pragma once
#ifndef __IA64_H
#define __IA64_H
#include "Coder.h"
#include "BranchCoder.h"
MyClass(BC_IA64, 0x04, 1)
// MyClass(IA64_Parse, 0x08, 1)
MyClassA(BC_IA64, 0x04, 1)
#endif

View File

@@ -1,69 +0,0 @@
// M68.cpp
#include "StdAfx.h"
#include "M68.h"
#include "Windows/Defs.h"
static HRESULT BC_M68_B_Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
{
UINT32 nowPos = 0;
UINT64 nowPos64 = 0;
UINT32 bufferPos = 0;
while(true)
{
UINT32 processedSize;
UINT32 size = kBufferSize - bufferPos;
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
UINT32 endPos = bufferPos + processedSize;
if (endPos < 4)
{
if (endPos > 0)
{
RINOK(outStream->Write(buffer, endPos, &processedSize));
if (endPos != processedSize)
return E_FAIL;
}
return S_OK;
}
for (bufferPos = 0; bufferPos <= endPos - 4;)
{
if (buffer[bufferPos] == 0x61 && buffer[bufferPos + 1] == 0x00)
{
UINT32 src =
(buffer[bufferPos + 2] << 8) |
(buffer[bufferPos + 3]);
UINT32 dest;
if (encoding)
dest = nowPos + bufferPos + 2 + src;
else
dest = src - (nowPos + bufferPos + 2);
buffer[bufferPos + 2] = (dest >> 8);
buffer[bufferPos + 3] = dest;
bufferPos += 4;
}
else
bufferPos += 2;
}
nowPos += bufferPos;
nowPos64 += bufferPos;
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
if (bufferPos != processedSize)
return E_FAIL;
if (progress != NULL)
{
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
}
UINT32 i = 0;
while(bufferPos < endPos)
buffer[i++] = buffer[bufferPos++];
bufferPos = i;
}
}
MyClassImp(BC_M68_B)

View File

@@ -1,12 +0,0 @@
// M68.h
#pragma once
#ifndef __M68_H
#define __M68_H
#include "Coder.h"
MyClass(BC_M68_B, 0x06, 5)
#endif

View File

@@ -4,73 +4,14 @@
#include "PPC.h"
#include "Windows/Defs.h"
#include "BranchPPC.c"
static HRESULT BC_PPC_B_Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
UInt32 CBC_PPC_B_Encoder::SubFilter(Byte *data, UInt32 size)
{
UINT32 nowPos = 0;
UINT64 nowPos64 = 0;
UINT32 bufferPos = 0;
while(true)
{
UINT32 processedSize;
UINT32 size = kBufferSize - bufferPos;
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
UINT32 endPos = bufferPos + processedSize;
if (endPos < 4)
{
if (endPos > 0)
{
RINOK(outStream->Write(buffer, endPos, &processedSize));
if (endPos != processedSize)
return E_FAIL;
}
return S_OK;
}
for (bufferPos = 0; bufferPos <= endPos - 4; bufferPos += 4)
{
// PowerPC branch 6(48) 24(Offset) 1(Abs) 1(Link)
if ((buffer[bufferPos] >> 2) == 0x12 &&
(
(buffer[bufferPos + 3] & 3) == 1
// || (buffer[bufferPos+3] & 3) == 3
)
)
{
UINT32 src = ((buffer[bufferPos + 0] & 3) << 24) |
(buffer[bufferPos + 1] << 16) |
(buffer[bufferPos + 2] << 8) |
(buffer[bufferPos + 3] & (~3));
UINT32 dest;
if (encoding)
dest = nowPos + bufferPos + src;
else
dest = src - (nowPos + bufferPos);
buffer[bufferPos + 0] = 0x48 | ((dest >> 24) & 0x3);
buffer[bufferPos + 1] = (dest >> 16);
buffer[bufferPos + 2] = (dest >> 8);
buffer[bufferPos + 3] &= 0x3;
buffer[bufferPos + 3] |= dest;
}
}
nowPos += bufferPos;
nowPos64 += bufferPos;
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
if (bufferPos != processedSize)
return E_FAIL;
if (progress != NULL)
{
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
}
UINT32 i = 0;
while(bufferPos < endPos)
buffer[i++] = buffer[bufferPos++];
bufferPos = i;
}
return ::PPC_B_Convert(data, size, _bufferPos, 1);
}
MyClassImp(BC_PPC_B)
UInt32 CBC_PPC_B_Decoder::SubFilter(Byte *data, UInt32 size)
{
return ::PPC_B_Convert(data, size, _bufferPos, 0);
}

View File

@@ -1,12 +1,10 @@
// PPC.h
#pragma once
#ifndef __PPC_H
#define __PPC_H
#include "Coder.h"
#include "BranchCoder.h"
MyClass(BC_PPC_B, 0x02, 5)
MyClassA(BC_PPC_B, 0x02, 5)
#endif

17
7zip/Compress/Branch/SPARC.cpp Executable file
View File

@@ -0,0 +1,17 @@
// SPARC.cpp
#include "StdAfx.h"
#include "SPARC.h"
#include "Windows/Defs.h"
#include "BranchSPARC.c"
UInt32 CBC_SPARC_Encoder::SubFilter(Byte *data, UInt32 size)
{
return ::SPARC_Convert(data, size, _bufferPos, 1);
}
UInt32 CBC_SPARC_Decoder::SubFilter(Byte *data, UInt32 size)
{
return ::SPARC_Convert(data, size, _bufferPos, 0);
}

10
7zip/Compress/Branch/SPARC.h Executable file
View File

@@ -0,0 +1,10 @@
// SPARC.h
#ifndef __SPARC_H
#define __SPARC_H
#include "BranchCoder.h"
MyClassA(BC_SPARC, 0x08, 5)
#endif

View File

@@ -1,3 +1,3 @@
// StdAfx.cpp
#include "stdafx.h"
#include "StdAfx.h"

View File

@@ -1,8 +1,8 @@
// stdafx.h
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include <windows.h>
#include "../../../Common/MyWindows.h"
#endif
#endif

View File

@@ -66,8 +66,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 3,9,2,0
PRODUCTVERSION 3,9,2,0
FILEVERSION 4,17,0,0
PRODUCTVERSION 4,17,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -84,15 +84,15 @@ BEGIN
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "Igor Pavlov\0"
VALUE "FileDescription", "Branch converter\0"
VALUE "FileVersion", "3, 9, 2, 0\0"
VALUE "FileDescription", "Branch filter\0"
VALUE "FileVersion", "4, 17, 0, 0\0"
VALUE "InternalName", "Branch\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2003 Igor Pavlov\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2005 Igor Pavlov\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "Branch.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "7-Zip\0"
VALUE "ProductVersion", "3, 9, 2, 0\0"
VALUE "ProductVersion", "4, 17, 0, 0\0"
VALUE "SpecialBuild", "\0"
END
END

View File

@@ -1,124 +1,18 @@
// x86.h
// x86.cpp
#include "StdAfx.h"
#include "x86.h"
#include "Windows/Defs.h"
static bool inline Test86MSByte(BYTE b)
#include "BranchX86.c"
UInt32 CBCJ_x86_Encoder::SubFilter(Byte *data, UInt32 size)
{
return (b == 0 || b == 0xFF);
return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 1);
}
const bool kMaskToAllowedStatus[8] = {true, true, true, false, true, false, false, false};
const BYTE kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
static HRESULT BCJ_x86_Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream, const UINT64 *inSize, const UINT64 *outSize,
ICompressProgressInfo *progress, BYTE *buffer, bool encoding)
UInt32 CBCJ_x86_Decoder::SubFilter(Byte *data, UInt32 size)
{
UINT64 nowPos64 = 0;
UINT32 nowPos = 0;
UINT32 bufferPos = 0;
UINT32 prevMask = 0;
UINT32 prevPos = (- 5);
while(true)
{
UINT32 processedSize;
UINT32 size = kBufferSize - bufferPos;
RINOK(inStream->Read(buffer + bufferPos, size, &processedSize));
UINT32 endPos = bufferPos + processedSize;
if (endPos < 5)
{
if (endPos > 0)
{
RINOK(outStream->Write(buffer, endPos, &processedSize));
if (endPos != processedSize)
return E_FAIL;
}
return S_OK;
}
bufferPos = 0;
if (nowPos - prevPos > 5)
prevPos = nowPos - 5;
UINT32 limit = endPos - 5;
while(bufferPos <= limit)
{
if (buffer[bufferPos] != 0xE8 && buffer[bufferPos] != 0xE9)
{
bufferPos++;
continue;
}
UINT32 offset = (nowPos + bufferPos - prevPos);
prevPos = (nowPos + bufferPos);
if (offset > 5)
prevMask = 0;
else
{
for (UINT32 i = 0; i < offset; i++)
{
prevMask &= 0x77;
prevMask <<= 1;
}
}
BYTE &nextByte = buffer[bufferPos + 4];
if (Test86MSByte(nextByte) && kMaskToAllowedStatus[(prevMask >> 1) & 0x7] &&
(prevMask >> 1) < 0x10)
{
UINT32 src =
(UINT32(nextByte) << 24) |
(UINT32(buffer[bufferPos + 3]) << 16) |
(UINT32(buffer[bufferPos + 2]) << 8) |
(buffer[bufferPos + 1]);
UINT32 dest;
while(true)
{
if (encoding)
dest = (nowPos + bufferPos + 5) + src;
else
dest = src - (nowPos + bufferPos + 5);
if (prevMask == 0)
break;
UINT32 index = kMaskToBitNumber[prevMask >> 1];
if (!Test86MSByte(dest >> (24 - index * 8)))
break;
src = dest ^ ((1 << (32 - index * 8)) - 1);
// src = dest;
}
nextByte = ~(((dest >> 24) & 1) - 1);
buffer[bufferPos + 3] = (dest >> 16);
buffer[bufferPos + 2] = (dest >> 8);
buffer[bufferPos + 1] = dest;
bufferPos += 5;
prevMask = 0;
}
else
{
bufferPos++;
prevMask |= 1;
if (Test86MSByte(nextByte))
prevMask |= 0x10;
}
}
nowPos += bufferPos;
nowPos64 += bufferPos;
RINOK(outStream->Write(buffer, bufferPos, &processedSize));
if (bufferPos != processedSize)
return E_FAIL;
if (progress != NULL)
{
RINOK(progress->SetRatioInfo(&nowPos64, &nowPos64));
}
UINT32 i = 0;
while(bufferPos < endPos)
buffer[i++] = buffer[bufferPos++];
bufferPos = i;
}
return ::x86_Convert(data, size, _bufferPos, &_prevMask, &_prevPos, 0);
}
MyClassImp(BCJ_x86)

View File

@@ -1,13 +1,19 @@
// x86.h
#pragma once
#ifndef __X86_H
#define __X86_H
#include "Coder.h"
#include "BranchCoder.h"
#include "BranchX86.h"
MyClass(BCJ_x86, 0x01, 3)
// MyClass(x86_J, 0x01, 2)
struct CBranch86
{
UInt32 _prevMask;
UInt32 _prevPos;
void x86Init() { x86_Convert_Init(_prevMask, _prevPos); }
};
MyClassB(BCJ_x86, 0x01, 3, CBranch86 ,
virtual void SubInit() { x86Init(); })
#endif

View File

@@ -3,27 +3,46 @@
#include "StdAfx.h"
#include "x86_2.h"
#include "Windows/Defs.h"
#include "../../ICoder.h"
#include "../../../Common/Alloc.h"
inline UINT32 Swap4(UINT32 value)
{
return (value << 24) | (value >> 24) |
( (value >> 8) & 0xFF00) | ( (value << 8) & 0xFF0000);
}
static const int kBufferSize = 1 << 17;
inline bool IsJcc(BYTE b0, BYTE b1)
inline bool IsJcc(Byte b0, Byte b1)
{
return (b0 == 0x0F && (b1 & 0xF0) == 0x80);
}
#ifndef EXTRACT_ONLY
static bool inline Test86MSByte(BYTE b)
static bool inline Test86MSByte(Byte b)
{
return (b == 0 || b == 0xFF);
}
bool CBCJ2_x86_Encoder::Create()
{
if (!_mainStream.Create(1 << 16))
return false;
if (!_callStream.Create(1 << 20))
return false;
if (!_jumpStream.Create(1 << 20))
return false;
if (!_rangeEncoder.Create(1 << 20))
return false;
if (_buffer == 0)
{
_buffer = (Byte *)BigAlloc(kBufferSize);
if (_buffer == 0)
return false;
}
return true;
}
CBCJ2_x86_Encoder::~CBCJ2_x86_Encoder()
{
BigFree(_buffer);
}
HRESULT CBCJ2_x86_Encoder::Flush()
{
RINOK(_mainStream.Flush());
@@ -33,21 +52,24 @@ HRESULT CBCJ2_x86_Encoder::Flush()
return _rangeEncoder.FlushStream();
}
const UINT32 kDefaultLimit = (1 << 24);
const UInt32 kDefaultLimit = (1 << 24);
HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
const UINT64 **inSizes,
UINT32 numInStreams,
const UInt64 **inSizes,
UInt32 numInStreams,
ISequentialOutStream **outStreams,
const UINT64 **outSizes,
UINT32 numOutStreams,
const UInt64 **outSizes,
UInt32 numOutStreams,
ICompressProgressInfo *progress)
{
if (numInStreams != 1 || numOutStreams != 4)
return E_INVALIDARG;
if (!Create())
return E_OUTOFMEMORY;
bool sizeIsDefined = false;
UINT64 inSize;
UInt64 inSize;
if (inSizes != NULL)
if (inSizes[0] != NULL)
{
@@ -56,48 +78,50 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
sizeIsDefined = true;
}
ISequentialInStream *inStream = inStreams[0];
_mainStream.Init(outStreams[0]);
_callStream.Init(outStreams[1]);
_jumpStream.Init(outStreams[2]);
_rangeEncoder.Init(outStreams[3]);
_mainStream.SetStream(outStreams[0]);
_mainStream.Init();
_callStream.SetStream(outStreams[1]);
_callStream.Init();
_jumpStream.SetStream(outStreams[2]);
_jumpStream.Init();
_rangeEncoder.SetStream(outStreams[3]);
_rangeEncoder.Init();
for (int i = 0; i < 256; i++)
_statusE8Encoder[i].Init();
_statusE9Encoder.Init();
_statusJccEncoder.Init();
// CCoderReleaser releaser(this);
CCoderReleaser releaser(this);
CMyComPtr<ICompressGetSubStreamSize> getSubStreamSize;
{
inStream->QueryInterface(IID_ICompressGetSubStreamSize, (void **)&getSubStreamSize);
}
UInt32 nowPos = 0;
UInt64 nowPos64 = 0;
UInt32 bufferPos = 0;
UInt32 processedSize;
UINT32 nowPos = 0;
UINT64 nowPos64 = 0;
UINT32 bufferPos = 0;
UINT32 processedSize;
Byte prevByte = 0;
BYTE prevByte = 0;
UINT64 subStreamIndex = 0;
UINT64 subStreamStartPos = 0;
UINT64 subStreamEndPos = 0;
UInt64 subStreamIndex = 0;
UInt64 subStreamStartPos = 0;
UInt64 subStreamEndPos = 0;
while(true)
{
UINT32 size = kBufferSize - bufferPos;
UInt32 size = kBufferSize - bufferPos;
RINOK(inStream->Read(_buffer + bufferPos, size, &processedSize));
UINT32 endPos = bufferPos + processedSize;
UInt32 endPos = bufferPos + processedSize;
if (endPos < 5)
{
// change it
for (bufferPos = 0; bufferPos < endPos; bufferPos++)
{
BYTE b = _buffer[bufferPos];
Byte b = _buffer[bufferPos];
_mainStream.WriteByte(b);
if (b == 0xE8)
_statusE8Encoder[prevByte].Encode(&_rangeEncoder, 0);
@@ -112,10 +136,10 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
bufferPos = 0;
UINT32 limit = endPos - 5;
UInt32 limit = endPos - 5;
while(bufferPos <= limit)
{
BYTE b = _buffer[bufferPos];
Byte b = _buffer[bufferPos];
_mainStream.WriteByte(b);
if (b != 0xE8 && b != 0xE9 && !IsJcc(prevByte, b))
{
@@ -123,21 +147,21 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
prevByte = b;
continue;
}
BYTE nextByte = _buffer[bufferPos + 4];
UINT32 src =
(UINT32(nextByte) << 24) |
(UINT32(_buffer[bufferPos + 3]) << 16) |
(UINT32(_buffer[bufferPos + 2]) << 8) |
Byte nextByte = _buffer[bufferPos + 4];
UInt32 src =
(UInt32(nextByte) << 24) |
(UInt32(_buffer[bufferPos + 3]) << 16) |
(UInt32(_buffer[bufferPos + 2]) << 8) |
(_buffer[bufferPos + 1]);
UINT32 dest = (nowPos + bufferPos + 5) + src;
UInt32 dest = (nowPos + bufferPos + 5) + src;
// if (Test86MSByte(nextByte))
bool convert;
if (getSubStreamSize != NULL)
{
UINT64 currentPos = (nowPos64 + bufferPos);
UInt64 currentPos = (nowPos64 + bufferPos);
while (subStreamEndPos < currentPos)
{
UINT64 subStreamSize;
UInt64 subStreamSize;
HRESULT result = getSubStreamSize->GetSubStreamSize(subStreamIndex, &subStreamSize);
if (result == S_OK)
{
@@ -165,7 +189,7 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
convert = Test86MSByte(nextByte);
else
{
UINT64 dest64 = (currentPos + 5) + INT64(INT32(src));
UInt64 dest64 = (currentPos + 5) + Int64(Int32(src));
convert = (dest64 >= subStreamStartPos && dest64 < subStreamEndPos);
}
}
@@ -182,13 +206,21 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
else
_statusJccEncoder.Encode(&_rangeEncoder, 1);
dest = Swap4(dest);
bufferPos += 5;
if (b == 0xE8)
_callStream.WriteBytes(&dest, sizeof(dest));
{
_callStream.WriteByte((Byte)(dest >> 24));
_callStream.WriteByte((Byte)(dest >> 16));
_callStream.WriteByte((Byte)(dest >> 8));
_callStream.WriteByte((Byte)(dest));
}
else
_jumpStream.WriteBytes(&dest, sizeof(dest));
{
_jumpStream.WriteByte((Byte)(dest >> 24));
_jumpStream.WriteByte((Byte)(dest >> 16));
_jumpStream.WriteByte((Byte)(dest >> 8));
_jumpStream.WriteByte((Byte)(dest));
}
prevByte = nextByte;
}
else
@@ -211,8 +243,7 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
RINOK(progress->SetRatioInfo(&nowPos64, NULL));
}
UINT32 i = 0;
UInt32 i = 0;
while(bufferPos < endPos)
_buffer[i++] = _buffer[bufferPos++];
bufferPos = i;
@@ -220,11 +251,11 @@ HRESULT CBCJ2_x86_Encoder::CodeReal(ISequentialInStream **inStreams,
}
STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams,
const UINT64 **inSizes,
UINT32 numInStreams,
const UInt64 **inSizes,
UInt32 numInStreams,
ISequentialOutStream **outStreams,
const UINT64 **outSizes,
UINT32 numOutStreams,
const UInt64 **outSizes,
UInt32 numOutStreams,
ICompressProgressInfo *progress)
{
try
@@ -239,41 +270,58 @@ STDMETHODIMP CBCJ2_x86_Encoder::Code(ISequentialInStream **inStreams,
#endif
HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
const UINT64 **inSizes,
UINT32 numInStreams,
const UInt64 **inSizes,
UInt32 numInStreams,
ISequentialOutStream **outStreams,
const UINT64 **outSizes,
UINT32 numOutStreams,
const UInt64 **outSizes,
UInt32 numOutStreams,
ICompressProgressInfo *progress)
{
if (numInStreams != 4 || numOutStreams != 1)
return E_INVALIDARG;
_mainInStream.Init(inStreams[0]);
_callStream.Init(inStreams[1]);
_jumpStream.Init(inStreams[2]);
_rangeDecoder.Init(inStreams[3]);
if (!_mainInStream.Create(1 << 16))
return E_OUTOFMEMORY;
if (!_callStream.Create(1 << 20))
return E_OUTOFMEMORY;
if (!_jumpStream.Create(1 << 16))
return E_OUTOFMEMORY;
if (!_rangeDecoder.Create(1 << 20))
return E_OUTOFMEMORY;
if (!_outStream.Create(1 << 16))
return E_OUTOFMEMORY;
_mainInStream.SetStream(inStreams[0]);
_callStream.SetStream(inStreams[1]);
_jumpStream.SetStream(inStreams[2]);
_rangeDecoder.SetStream(inStreams[3]);
_outStream.SetStream(outStreams[0]);
_mainInStream.Init();
_callStream.Init();
_jumpStream.Init();
_rangeDecoder.Init();
_outStream.Init();
for (int i = 0; i < 256; i++)
_statusE8Decoder[i].Init();
_statusE9Decoder.Init();
_statusJccDecoder.Init();
_outStream.Init(outStreams[0]);
CCoderReleaser releaser(this);
// CCoderReleaser releaser(this);
BYTE prevByte = 0;
UINT32 processedBytes = 0;
Byte prevByte = 0;
UInt32 processedBytes = 0;
while(true)
{
if (processedBytes > (1 << 20) && progress != NULL)
{
UINT64 nowPos64 = _outStream.GetProcessedSize();
UInt64 nowPos64 = _outStream.GetProcessedSize();
RINOK(progress->SetRatioInfo(NULL, &nowPos64));
processedBytes = 0;
}
processedBytes++;
BYTE b;
Byte b;
if (!_mainInStream.ReadByte(b))
return Flush();
_outStream.WriteByte(b);
@@ -291,20 +339,44 @@ HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
status = (_statusJccDecoder.Decode(&_rangeDecoder) == 1);
if (status)
{
UINT32 src;
UInt32 src;
if (b == 0xE8)
{
if (!_callStream.ReadBytes(&src, sizeof(src)))
Byte b0;
if(!_callStream.ReadByte(b0))
return S_FALSE;
src = ((UInt32)b0) << 24;
if(!_callStream.ReadByte(b0))
return S_FALSE;
src |= ((UInt32)b0) << 16;
if(!_callStream.ReadByte(b0))
return S_FALSE;
src |= ((UInt32)b0) << 8;
if(!_callStream.ReadByte(b0))
return S_FALSE;
src |= ((UInt32)b0);
}
else
{
if (!_jumpStream.ReadBytes(&src, sizeof(src)))
Byte b0;
if(!_jumpStream.ReadByte(b0))
return S_FALSE;
src = ((UInt32)b0) << 24;
if(!_jumpStream.ReadByte(b0))
return S_FALSE;
src |= ((UInt32)b0) << 16;
if(!_jumpStream.ReadByte(b0))
return S_FALSE;
src |= ((UInt32)b0) << 8;
if(!_jumpStream.ReadByte(b0))
return S_FALSE;
src |= ((UInt32)b0);
}
src = Swap4(src);
UINT32 dest = src - (UINT32(_outStream.GetProcessedSize()) + 4) ;
_outStream.WriteBytes(&dest, sizeof(dest));
UInt32 dest = src - (UInt32(_outStream.GetProcessedSize()) + 4) ;
_outStream.WriteByte((Byte)(dest));
_outStream.WriteByte((Byte)(dest >> 8));
_outStream.WriteByte((Byte)(dest >> 16));
_outStream.WriteByte((Byte)(dest >> 24));
prevByte = (dest >> 24);
processedBytes += 4;
}
@@ -314,11 +386,11 @@ HRESULT CBCJ2_x86_Decoder::CodeReal(ISequentialInStream **inStreams,
}
STDMETHODIMP CBCJ2_x86_Decoder::Code(ISequentialInStream **inStreams,
const UINT64 **inSizes,
UINT32 numInStreams,
const UInt64 **inSizes,
UInt32 numInStreams,
ISequentialOutStream **outStreams,
const UINT64 **outSizes,
UINT32 numOutStreams,
const UInt64 **outSizes,
UInt32 numOutStreams,
ICompressProgressInfo *progress)
{
try

View File

@@ -1,14 +1,11 @@
// x86_2.h
#pragma once
#ifndef __BRANCH_X86_2_H
#define __BRANCH_X86_2_H
#ifndef __X86_2_H
#define __X86_2_H
#include "Common/MyCom.h"
#include "Coder.h"
#include "../../../Common/MyCom.h"
#include "../RangeCoder/RangeCoderBit.h"
// #include "../../Common/InBuffer.h"
#include "../../ICoder.h"
// {23170F69-40C1-278B-0303-010100000100}
#define MyClass2_a(Name, id, subId, encodingId) \
@@ -27,11 +24,13 @@ const int kNumMoveBits = 5;
class CBCJ2_x86_Encoder:
public ICompressCoder2,
public CDataBuffer,
public CMyUnknownImp
{
Byte *_buffer;
public:
CBCJ2_x86_Encoder(): _mainStream(1 << 16) {}
CBCJ2_x86_Encoder(): _buffer(0) {};
~CBCJ2_x86_Encoder();
bool Create();
COutBuffer _mainStream;
COutBuffer _callStream;
@@ -42,7 +41,6 @@ public:
NCompress::NRangeCoder::CBitEncoder<kNumMoveBits> _statusJccEncoder;
HRESULT Flush();
/*
void ReleaseStreams()
{
_mainStream.ReleaseStream();
@@ -55,32 +53,27 @@ public:
{
CBCJ2_x86_Encoder *_coder;
public:
CCoderReleaser(CBCJ2_x86_Encoder *aCoder): _coder(aCoder) {}
~CCoderReleaser()
{
_coder->ReleaseStreams();
}
CCoderReleaser(CBCJ2_x86_Encoder *coder): _coder(coder) {}
~CCoderReleaser() { _coder->ReleaseStreams(); }
};
friend class CCoderReleaser;
*/
public:
MY_UNKNOWN_IMP
HRESULT CodeReal(ISequentialInStream **inStreams,
const UINT64 **inSizes,
UINT32 numInStreams,
const UInt64 **inSizes,
UInt32 numInStreams,
ISequentialOutStream **outStreams,
const UINT64 **outSizes,
UINT32 numOutStreams,
const UInt64 **outSizes,
UInt32 numOutStreams,
ICompressProgressInfo *progress);
STDMETHOD(Code)(ISequentialInStream **inStreams,
const UINT64 **inSizes,
UINT32 numInStreams,
const UInt64 **inSizes,
UInt32 numInStreams,
ISequentialOutStream **outStreams,
const UINT64 **outSizes,
UINT32 numOutStreams,
const UInt64 **outSizes,
UInt32 numOutStreams,
ICompressProgressInfo *progress);
};
@@ -91,8 +84,6 @@ class CBCJ2_x86_Decoder:
public CMyUnknownImp
{
public:
CBCJ2_x86_Decoder(): _outStream(1 << 16), _mainInStream(1 << 16) {}
CInBuffer _mainInStream;
CInBuffer _callStream;
CInBuffer _jumpStream;
@@ -103,7 +94,6 @@ public:
COutBuffer _outStream;
/*
void ReleaseStreams()
{
_mainInStream.ReleaseStream();
@@ -112,35 +102,31 @@ public:
_rangeDecoder.ReleaseStream();
_outStream.ReleaseStream();
}
*/
HRESULT Flush() { return _outStream.Flush(); }
/*
class CCoderReleaser
{
CBCJ2_x86_Decoder *_coder;
public:
CCoderReleaser(CBCJ2_x86_Decoder *aCoder): _coder(aCoder) {}
CCoderReleaser(CBCJ2_x86_Decoder *coder): _coder(coder) {}
~CCoderReleaser() { _coder->ReleaseStreams(); }
};
friend class CCoderReleaser;
*/
public:
MY_UNKNOWN_IMP
HRESULT CodeReal(ISequentialInStream **inStreams,
const UINT64 **inSizes,
UINT32 numInStreams,
const UInt64 **inSizes,
UInt32 numInStreams,
ISequentialOutStream **outStreams,
const UINT64 **outSizes,
UINT32 numOutStreams,
const UInt64 **outSizes,
UInt32 numOutStreams,
ICompressProgressInfo *progress);
STDMETHOD(Code)(ISequentialInStream **inStreams,
const UINT64 **inSizes,
UINT32 numInStreams,
const UInt64 **inSizes,
UInt32 numInStreams,
ISequentialOutStream **outStreams,
const UINT64 **outSizes,
UINT32 numOutStreams,
const UInt64 **outSizes,
UInt32 numOutStreams,
ICompressProgressInfo *progress);
};