all repos — mgba @ 341ebd04356360cfff3e217bf7a419e43b534ef1

mGBA Game Boy Advance Emulator

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

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