Subversion Repositories Games.Chess Giants

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
99 pmbaty 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
 
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
}