Subversion Repositories Games.Chess Giants

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
  2. 2008-08-05
  3. Igor Pavlov
  4. Public domain */
  5.  
  6. #include <string.h>
  7.  
  8. #include "Lzma86Enc.h"
  9.  
  10. #include "Alloc.h"
  11. #include "Bra.h"
  12. #include "LzmaEnc.h"
  13.  
  14. #define SZE_OUT_OVERFLOW SZE_DATA_ERROR
  15.  
  16. static void *SzAlloc(void *p, size_t size) { return MyAlloc(size); }
  17. static void SzFree(void *p, void *address) { MyFree(address); }
  18. static ISzAlloc g_Alloc = { SzAlloc, SzFree };
  19.  
  20. #define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE)
  21. #define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
  22.  
  23. int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
  24.     int level, UInt32 dictSize, int filterMode)
  25. {
  26.   size_t outSize2 = *destLen;
  27.   Byte *filteredStream;
  28.   Bool useFilter;
  29.   int mainResult = SZ_ERROR_OUTPUT_EOF;
  30.   CLzmaEncProps props;
  31.   LzmaEncProps_Init(&props);
  32.   props.level = level;
  33.   props.dictSize = dictSize;
  34.  
  35.   *destLen = 0;
  36.   if (outSize2 < LZMA86_HEADER_SIZE)
  37.     return SZ_ERROR_OUTPUT_EOF;
  38.  
  39.   {
  40.     int i;
  41.     UInt64 t = srcLen;
  42.     for (i = 0; i < 8; i++, t >>= 8)
  43.       dest[LZMA86_SIZE_OFFSET + i] = (Byte)t;
  44.   }
  45.  
  46.   filteredStream = 0;
  47.   useFilter = (filterMode != SZ_FILTER_NO);
  48.   if (useFilter)
  49.   {
  50.     if (srcLen != 0)
  51.     {
  52.       filteredStream = (Byte *)MyAlloc(srcLen);
  53.       if (filteredStream == 0)
  54.         return SZ_ERROR_MEM;
  55.       memcpy(filteredStream, src, srcLen);
  56.     }
  57.     {
  58.       UInt32 x86State;
  59.       x86_Convert_Init(x86State);
  60.       x86_Convert(filteredStream, srcLen, 0, &x86State, 1);
  61.     }
  62.   }
  63.  
  64.   {
  65.     size_t minSize = 0;
  66.     Bool bestIsFiltered = False;
  67.  
  68.     /* passes for SZ_FILTER_AUTO:
  69.         0 - BCJ + LZMA
  70.         1 - LZMA
  71.         2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
  72.     */
  73.     int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
  74.  
  75.     int i;
  76.     for (i = 0; i < numPasses; i++)
  77.     {
  78.       size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;
  79.       size_t outPropsSize = 5;
  80.       SRes curRes;
  81.       Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);
  82.       if (curModeIsFiltered && !bestIsFiltered)
  83.         break;
  84.       if (useFilter && i == 0)
  85.         curModeIsFiltered = True;
  86.  
  87.       curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,
  88.           curModeIsFiltered ? filteredStream : src, srcLen,
  89.           &props, dest + 1, &outPropsSize, 0,
  90.           NULL, &g_Alloc, &g_Alloc);
  91.  
  92.       if (curRes != SZ_ERROR_OUTPUT_EOF)
  93.       {
  94.         if (curRes != SZ_OK)
  95.         {
  96.           mainResult = curRes;
  97.           break;
  98.         }
  99.         if (outSizeProcessed <= minSize || mainResult != SZ_OK)
  100.         {
  101.           minSize = outSizeProcessed;
  102.           bestIsFiltered = curModeIsFiltered;
  103.           mainResult = SZ_OK;
  104.         }
  105.       }
  106.     }
  107.     dest[0] = (unsigned char) (bestIsFiltered ? 1 : 0); /*MAB: Cast to silence compiler */
  108.     *destLen = LZMA86_HEADER_SIZE + minSize;
  109.   }
  110.   if (useFilter)
  111.     MyFree(filteredStream);
  112.   return mainResult;
  113. }
  114.