Home | History | Annotate | Download | only in C
      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
    147