all repos — mgba @ b2d406a411b31acce5bbf0246af32a80c22ca834

mGBA Game Boy Advance Emulator

src/third-party/lzma/Lzma86Enc.c (view raw)

  1/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
  22018-07-04 : 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
 16int 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  BoolInt 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    BoolInt 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      BoolInt 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}