Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5728 serge 1
/* Bcj2.h -- BCJ2 Converter for x86 code
2
2014-11-10 : Igor Pavlov : Public domain */
3
 
4
#ifndef __BCJ2_H
5
#define __BCJ2_H
6
 
7
#include "7zTypes.h"
8
 
9
EXTERN_C_BEGIN
10
 
11
#define BCJ2_NUM_STREAMS 4
12
 
13
enum
14
{
15
  BCJ2_STREAM_MAIN,
16
  BCJ2_STREAM_CALL,
17
  BCJ2_STREAM_JUMP,
18
  BCJ2_STREAM_RC
19
};
20
 
21
enum
22
{
23
  BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS,
24
  BCJ2_DEC_STATE_ORIG_1,
25
  BCJ2_DEC_STATE_ORIG_2,
26
  BCJ2_DEC_STATE_ORIG_3,
27
 
28
  BCJ2_DEC_STATE_ORIG,
29
  BCJ2_DEC_STATE_OK
30
};
31
 
32
enum
33
{
34
  BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS,
35
  BCJ2_ENC_STATE_OK
36
};
37
 
38
 
39
#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP)
40
 
41
/*
42
CBcj2Dec / CBcj2Enc
43
bufs sizes:
44
  BUF_SIZE(n) = lims[n] - bufs[n]
45
bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4:
46
    (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0
47
    (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0
48
*/
49
 
50
/*
51
CBcj2Dec:
52
dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions:
53
  bufs[BCJ2_STREAM_MAIN] >= dest &&
54
  bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv +
55
        BUF_SIZE(BCJ2_STREAM_CALL) +
56
        BUF_SIZE(BCJ2_STREAM_JUMP)
57
     tempReserv = 0 : for first call of Bcj2Dec_Decode
58
     tempReserv = 4 : for any other calls of Bcj2Dec_Decode
59
  overlap with offset = 1 is not allowed
60
*/
61
 
62
typedef struct
63
{
64
  const Byte *bufs[BCJ2_NUM_STREAMS];
65
  const Byte *lims[BCJ2_NUM_STREAMS];
66
  Byte *dest;
67
  const Byte *destLim;
68
 
69
  unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */
70
 
71
  UInt32 ip;
72
  Byte temp[4];
73
  UInt32 range;
74
  UInt32 code;
75
  UInt16 probs[2 + 256];
76
} CBcj2Dec;
77
 
78
void Bcj2Dec_Init(CBcj2Dec *p);
79
 
80
/* Returns: SZ_OK or SZ_ERROR_DATA */
81
SRes Bcj2Dec_Decode(CBcj2Dec *p);
82
 
83
#define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0)
84
 
85
 
86
 
87
typedef enum
88
{
89
  BCJ2_ENC_FINISH_MODE_CONTINUE,
90
  BCJ2_ENC_FINISH_MODE_END_BLOCK,
91
  BCJ2_ENC_FINISH_MODE_END_STREAM
92
} EBcj2Enc_FinishMode;
93
 
94
typedef struct
95
{
96
  Byte *bufs[BCJ2_NUM_STREAMS];
97
  const Byte *lims[BCJ2_NUM_STREAMS];
98
  const Byte *src;
99
  const Byte *srcLim;
100
 
101
  unsigned state;
102
  EBcj2Enc_FinishMode finishMode;
103
 
104
  Byte prevByte;
105
 
106
  Byte cache;
107
  UInt32 range;
108
  UInt64 low;
109
  UInt64 cacheSize;
110
 
111
  UInt32 ip;
112
 
113
  /* 32-bit ralative offset in JUMP/CALL commands is
114
       - (mod 4 GB)   in 32-bit mode
115
       - signed Int32 in 64-bit mode
116
     We use (mod 4 GB) check for fileSize.
117
     Use fileSize up to 2 GB, if you want to support 32-bit and 64-bit code conversion. */
118
  UInt32 fileIp;
119
  UInt32 fileSize;    /* (fileSize <= ((UInt32)1 << 31)), 0 means no_limit */
120
  UInt32 relatLimit;  /* (relatLimit <= ((UInt32)1 << 31)), 0 means desable_conversion */
121
 
122
  UInt32 tempTarget;
123
  unsigned tempPos;
124
  Byte temp[4 * 2];
125
 
126
  unsigned flushPos;
127
 
128
  UInt16 probs[2 + 256];
129
} CBcj2Enc;
130
 
131
void Bcj2Enc_Init(CBcj2Enc *p);
132
void Bcj2Enc_Encode(CBcj2Enc *p);
133
 
134
#define Bcj2Enc_Get_InputData_Size(p) ((SizeT)((p)->srcLim - (p)->src) + (p)->tempPos)
135
#define Bcj2Enc_IsFinished(p) ((p)->flushPos == 5)
136
 
137
 
138
#define BCJ2_RELAT_LIMIT_NUM_BITS 26
139
#define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS)
140
 
141
/* limit for CBcj2Enc::fileSize variable */
142
#define BCJ2_FileSize_MAX ((UInt32)1 << 31)
143
 
144
EXTERN_C_END
145
 
146
#endif