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