tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Lzma86Enc.c (2712B)


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