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