Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
  2. 2015-08-01 : Igor Pavlov : Public domain */
  3.  
  4. #include "Precomp.h"
  5.  
  6. #include "Bcj2.h"
  7. #include "CpuArch.h"
  8.  
  9. #define CProb UInt16
  10.  
  11. #define kTopValue ((UInt32)1 << 24)
  12. #define kNumModelBits 11
  13. #define kBitModelTotal (1 << kNumModelBits)
  14. #define kNumMoveBits 5
  15.  
  16. #define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)
  17. #define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
  18. #define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
  19.  
  20. void Bcj2Dec_Init(CBcj2Dec *p)
  21. {
  22.   unsigned i;
  23.  
  24.   p->state = BCJ2_DEC_STATE_OK;
  25.   p->ip = 0;
  26.   p->temp[3] = 0;
  27.   p->range = 0;
  28.   p->code = 0;
  29.   for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
  30.     p->probs[i] = kBitModelTotal >> 1;
  31. }
  32.  
  33. SRes Bcj2Dec_Decode(CBcj2Dec *p)
  34. {
  35.   if (p->range <= 5)
  36.   {
  37.     p->state = BCJ2_DEC_STATE_OK;
  38.     for (; p->range != 5; p->range++)
  39.     {
  40.       if (p->range == 1 && p->code != 0)
  41.         return SZ_ERROR_DATA;
  42.      
  43.       if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
  44.       {
  45.         p->state = BCJ2_STREAM_RC;
  46.         return SZ_OK;
  47.       }
  48.  
  49.       p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
  50.     }
  51.    
  52.     if (p->code == 0xFFFFFFFF)
  53.       return SZ_ERROR_DATA;
  54.    
  55.     p->range = 0xFFFFFFFF;
  56.   }
  57.   else if (p->state >= BCJ2_DEC_STATE_ORIG_0)
  58.   {
  59.     while (p->state <= BCJ2_DEC_STATE_ORIG_3)
  60.     {
  61.       Byte *dest = p->dest;
  62.       if (dest == p->destLim)
  63.         return SZ_OK;
  64.       *dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0];
  65.       p->dest = dest + 1;
  66.     }
  67.   }
  68.  
  69.   /*
  70.   if (BCJ2_IS_32BIT_STREAM(p->state))
  71.   {
  72.     const Byte *cur = p->bufs[p->state];
  73.     if (cur == p->lims[p->state])
  74.       return SZ_OK;
  75.     p->bufs[p->state] = cur + 4;
  76.    
  77.     {
  78.       UInt32 val;
  79.       Byte *dest;
  80.       SizeT rem;
  81.      
  82.       p->ip += 4;
  83.       val = GetBe32(cur) - p->ip;
  84.       dest = p->dest;
  85.       rem = p->destLim - dest;
  86.       if (rem < 4)
  87.       {
  88.         SizeT i;
  89.         SetUi32(p->temp, val);
  90.         for (i = 0; i < rem; i++)
  91.           dest[i] = p->temp[i];
  92.         p->dest = dest + rem;
  93.         p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
  94.         return SZ_OK;
  95.       }
  96.       SetUi32(dest, val);
  97.       p->temp[3] = (Byte)(val >> 24);
  98.       p->dest = dest + 4;
  99.       p->state = BCJ2_DEC_STATE_OK;
  100.     }
  101.   }
  102.   */
  103.  
  104.   for (;;)
  105.   {
  106.     if (BCJ2_IS_32BIT_STREAM(p->state))
  107.       p->state = BCJ2_DEC_STATE_OK;
  108.     else
  109.     {
  110.       if (p->range < kTopValue)
  111.       {
  112.         if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
  113.         {
  114.           p->state = BCJ2_STREAM_RC;
  115.           return SZ_OK;
  116.         }
  117.         p->range <<= 8;
  118.         p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
  119.       }
  120.  
  121.       {
  122.         const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
  123.         const Byte *srcLim;
  124.         Byte *dest;
  125.         SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
  126.        
  127.         if (num == 0)
  128.         {
  129.           p->state = BCJ2_STREAM_MAIN;
  130.           return SZ_OK;
  131.         }
  132.        
  133.         dest = p->dest;
  134.         if (num > (SizeT)(p->destLim - dest))
  135.         {
  136.           num = p->destLim - dest;
  137.           if (num == 0)
  138.           {
  139.             p->state = BCJ2_DEC_STATE_ORIG;
  140.             return SZ_OK;
  141.           }
  142.         }
  143.        
  144.         srcLim = src + num;
  145.  
  146.         if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
  147.           *dest = src[0];
  148.         else for (;;)
  149.         {
  150.           Byte b = *src;
  151.           *dest = b;
  152.           if (b != 0x0F)
  153.           {
  154.             if ((b & 0xFE) == 0xE8)
  155.               break;
  156.             dest++;
  157.             if (++src != srcLim)
  158.               continue;
  159.             break;
  160.           }
  161.           dest++;
  162.           if (++src == srcLim)
  163.             break;
  164.           if ((*src & 0xF0) != 0x80)
  165.             continue;
  166.           *dest = *src;
  167.           break;
  168.         }
  169.        
  170.         num = src - p->bufs[BCJ2_STREAM_MAIN];
  171.        
  172.         if (src == srcLim)
  173.         {
  174.           p->temp[3] = src[-1];
  175.           p->bufs[BCJ2_STREAM_MAIN] = src;
  176.           p->ip += (UInt32)num;
  177.           p->dest += num;
  178.           p->state =
  179.             p->bufs[BCJ2_STREAM_MAIN] ==
  180.             p->lims[BCJ2_STREAM_MAIN] ?
  181.               (unsigned)BCJ2_STREAM_MAIN :
  182.               (unsigned)BCJ2_DEC_STATE_ORIG;
  183.           return SZ_OK;
  184.         }
  185.        
  186.         {
  187.           UInt32 bound, ttt;
  188.           CProb *prob;
  189.           Byte b = src[0];
  190.           Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
  191.          
  192.           p->temp[3] = b;
  193.           p->bufs[BCJ2_STREAM_MAIN] = src + 1;
  194.           num++;
  195.           p->ip += (UInt32)num;
  196.           p->dest += num;
  197.          
  198.           prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
  199.          
  200.           _IF_BIT_0
  201.           {
  202.             _UPDATE_0
  203.             continue;
  204.           }
  205.           _UPDATE_1
  206.            
  207.         }
  208.       }
  209.     }
  210.  
  211.     {
  212.       UInt32 val;
  213.       unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
  214.       const Byte *cur = p->bufs[cj];
  215.       Byte *dest;
  216.       SizeT rem;
  217.      
  218.       if (cur == p->lims[cj])
  219.       {
  220.         p->state = cj;
  221.         break;
  222.       }
  223.      
  224.       val = GetBe32(cur);
  225.       p->bufs[cj] = cur + 4;
  226.  
  227.       p->ip += 4;
  228.       val -= p->ip;
  229.       dest = p->dest;
  230.       rem = p->destLim - dest;
  231.      
  232.       if (rem < 4)
  233.       {
  234.         SizeT i;
  235.         SetUi32(p->temp, val);
  236.         for (i = 0; i < rem; i++)
  237.           dest[i] = p->temp[i];
  238.         p->dest = dest + rem;
  239.         p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
  240.         break;
  241.       }
  242.      
  243.       SetUi32(dest, val);
  244.       p->temp[3] = (Byte)(val >> 24);
  245.       p->dest = dest + 4;
  246.     }
  247.   }
  248.  
  249.   if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])
  250.   {
  251.     p->range <<= 8;
  252.     p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
  253.   }
  254.  
  255.   return SZ_OK;
  256. }
  257.