mirror of
https://github.com/ZDoom/Raze.git
synced 2024-12-01 08:31:30 +00:00
718112a8fe
Currently none of these is being used, but eventually they will, once more code gets ported over. So it's better to have them right away and avoid editing the project file too much, only to revert that later.
146 lines
3.1 KiB
C
146 lines
3.1 KiB
C
/* Bcj2.h -- BCJ2 Converter for x86 code
|
|
2014-11-10 : Igor Pavlov : Public domain */
|
|
|
|
#ifndef __BCJ2_H
|
|
#define __BCJ2_H
|
|
|
|
#include "7zTypes.h"
|
|
|
|
EXTERN_C_BEGIN
|
|
|
|
#define BCJ2_NUM_STREAMS 4
|
|
|
|
enum
|
|
{
|
|
BCJ2_STREAM_MAIN,
|
|
BCJ2_STREAM_CALL,
|
|
BCJ2_STREAM_JUMP,
|
|
BCJ2_STREAM_RC
|
|
};
|
|
|
|
enum
|
|
{
|
|
BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS,
|
|
BCJ2_DEC_STATE_ORIG_1,
|
|
BCJ2_DEC_STATE_ORIG_2,
|
|
BCJ2_DEC_STATE_ORIG_3,
|
|
|
|
BCJ2_DEC_STATE_ORIG,
|
|
BCJ2_DEC_STATE_OK
|
|
};
|
|
|
|
enum
|
|
{
|
|
BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS,
|
|
BCJ2_ENC_STATE_OK
|
|
};
|
|
|
|
|
|
#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP)
|
|
|
|
/*
|
|
CBcj2Dec / CBcj2Enc
|
|
bufs sizes:
|
|
BUF_SIZE(n) = lims[n] - bufs[n]
|
|
bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4:
|
|
(BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0
|
|
(BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0
|
|
*/
|
|
|
|
/*
|
|
CBcj2Dec:
|
|
dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions:
|
|
bufs[BCJ2_STREAM_MAIN] >= dest &&
|
|
bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv +
|
|
BUF_SIZE(BCJ2_STREAM_CALL) +
|
|
BUF_SIZE(BCJ2_STREAM_JUMP)
|
|
tempReserv = 0 : for first call of Bcj2Dec_Decode
|
|
tempReserv = 4 : for any other calls of Bcj2Dec_Decode
|
|
overlap with offset = 1 is not allowed
|
|
*/
|
|
|
|
typedef struct
|
|
{
|
|
const Byte *bufs[BCJ2_NUM_STREAMS];
|
|
const Byte *lims[BCJ2_NUM_STREAMS];
|
|
Byte *dest;
|
|
const Byte *destLim;
|
|
|
|
unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */
|
|
|
|
UInt32 ip;
|
|
Byte temp[4];
|
|
UInt32 range;
|
|
UInt32 code;
|
|
UInt16 probs[2 + 256];
|
|
} CBcj2Dec;
|
|
|
|
void Bcj2Dec_Init(CBcj2Dec *p);
|
|
|
|
/* Returns: SZ_OK or SZ_ERROR_DATA */
|
|
SRes Bcj2Dec_Decode(CBcj2Dec *p);
|
|
|
|
#define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0)
|
|
|
|
|
|
|
|
typedef enum
|
|
{
|
|
BCJ2_ENC_FINISH_MODE_CONTINUE,
|
|
BCJ2_ENC_FINISH_MODE_END_BLOCK,
|
|
BCJ2_ENC_FINISH_MODE_END_STREAM
|
|
} EBcj2Enc_FinishMode;
|
|
|
|
typedef struct
|
|
{
|
|
Byte *bufs[BCJ2_NUM_STREAMS];
|
|
const Byte *lims[BCJ2_NUM_STREAMS];
|
|
const Byte *src;
|
|
const Byte *srcLim;
|
|
|
|
unsigned state;
|
|
EBcj2Enc_FinishMode finishMode;
|
|
|
|
Byte prevByte;
|
|
|
|
Byte cache;
|
|
UInt32 range;
|
|
UInt64 low;
|
|
UInt64 cacheSize;
|
|
|
|
UInt32 ip;
|
|
|
|
/* 32-bit ralative offset in JUMP/CALL commands is
|
|
- (mod 4 GB) in 32-bit mode
|
|
- signed Int32 in 64-bit mode
|
|
We use (mod 4 GB) check for fileSize.
|
|
Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */
|
|
UInt32 fileIp;
|
|
UInt32 fileSize; /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */
|
|
UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conversion */
|
|
|
|
UInt32 tempTarget;
|
|
unsigned tempPos;
|
|
Byte temp[4 * 2];
|
|
|
|
unsigned flushPos;
|
|
|
|
UInt16 probs[2 + 256];
|
|
} CBcj2Enc;
|
|
|
|
void Bcj2Enc_Init(CBcj2Enc *p);
|
|
void Bcj2Enc_Encode(CBcj2Enc *p);
|
|
|
|
#define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos)
|
|
#define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5)
|
|
|
|
|
|
#define BCJ2_RELAT_LIMIT_NUM_BITS 26
|
|
#define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS)
|
|
|
|
/* limit for CBcj2Enc::fileSize variable */
|
|
#define BCJ2_FileSize_MAX ((UInt32)1 << 31)
|
|
|
|
EXTERN_C_END
|
|
|
|
#endif
|