1370b324cSopenharmony_ci/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder 2370b324cSopenharmony_ci2023-03-03 : Igor Pavlov : Public domain */ 3370b324cSopenharmony_ci 4370b324cSopenharmony_ci#include "Precomp.h" 5370b324cSopenharmony_ci 6370b324cSopenharmony_ci#include <string.h> 7370b324cSopenharmony_ci 8370b324cSopenharmony_ci#include "Lzma86.h" 9370b324cSopenharmony_ci 10370b324cSopenharmony_ci#include "Alloc.h" 11370b324cSopenharmony_ci#include "Bra.h" 12370b324cSopenharmony_ci#include "LzmaEnc.h" 13370b324cSopenharmony_ci 14370b324cSopenharmony_ciint Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, 15370b324cSopenharmony_ci int level, UInt32 dictSize, int filterMode) 16370b324cSopenharmony_ci{ 17370b324cSopenharmony_ci size_t outSize2 = *destLen; 18370b324cSopenharmony_ci Byte *filteredStream; 19370b324cSopenharmony_ci BoolInt useFilter; 20370b324cSopenharmony_ci int mainResult = SZ_ERROR_OUTPUT_EOF; 21370b324cSopenharmony_ci CLzmaEncProps props; 22370b324cSopenharmony_ci LzmaEncProps_Init(&props); 23370b324cSopenharmony_ci props.level = level; 24370b324cSopenharmony_ci props.dictSize = dictSize; 25370b324cSopenharmony_ci 26370b324cSopenharmony_ci *destLen = 0; 27370b324cSopenharmony_ci if (outSize2 < LZMA86_HEADER_SIZE) 28370b324cSopenharmony_ci return SZ_ERROR_OUTPUT_EOF; 29370b324cSopenharmony_ci 30370b324cSopenharmony_ci { 31370b324cSopenharmony_ci int i; 32370b324cSopenharmony_ci UInt64 t = srcLen; 33370b324cSopenharmony_ci for (i = 0; i < 8; i++, t >>= 8) 34370b324cSopenharmony_ci dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; 35370b324cSopenharmony_ci } 36370b324cSopenharmony_ci 37370b324cSopenharmony_ci filteredStream = 0; 38370b324cSopenharmony_ci useFilter = (filterMode != SZ_FILTER_NO); 39370b324cSopenharmony_ci if (useFilter) 40370b324cSopenharmony_ci { 41370b324cSopenharmony_ci if (srcLen != 0) 42370b324cSopenharmony_ci { 43370b324cSopenharmony_ci filteredStream = (Byte *)MyAlloc(srcLen); 44370b324cSopenharmony_ci if (filteredStream == 0) 45370b324cSopenharmony_ci return SZ_ERROR_MEM; 46370b324cSopenharmony_ci memcpy(filteredStream, src, srcLen); 47370b324cSopenharmony_ci } 48370b324cSopenharmony_ci { 49370b324cSopenharmony_ci UInt32 x86State = Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL; 50370b324cSopenharmony_ci z7_BranchConvSt_X86_Enc(filteredStream, srcLen, 0, &x86State); 51370b324cSopenharmony_ci } 52370b324cSopenharmony_ci } 53370b324cSopenharmony_ci 54370b324cSopenharmony_ci { 55370b324cSopenharmony_ci size_t minSize = 0; 56370b324cSopenharmony_ci BoolInt bestIsFiltered = False; 57370b324cSopenharmony_ci 58370b324cSopenharmony_ci /* passes for SZ_FILTER_AUTO: 59370b324cSopenharmony_ci 0 - BCJ + LZMA 60370b324cSopenharmony_ci 1 - LZMA 61370b324cSopenharmony_ci 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. 62370b324cSopenharmony_ci */ 63370b324cSopenharmony_ci int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; 64370b324cSopenharmony_ci 65370b324cSopenharmony_ci int i; 66370b324cSopenharmony_ci for (i = 0; i < numPasses; i++) 67370b324cSopenharmony_ci { 68370b324cSopenharmony_ci size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; 69370b324cSopenharmony_ci size_t outPropsSize = 5; 70370b324cSopenharmony_ci SRes curRes; 71370b324cSopenharmony_ci BoolInt curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); 72370b324cSopenharmony_ci if (curModeIsFiltered && !bestIsFiltered) 73370b324cSopenharmony_ci break; 74370b324cSopenharmony_ci if (useFilter && i == 0) 75370b324cSopenharmony_ci curModeIsFiltered = True; 76370b324cSopenharmony_ci 77370b324cSopenharmony_ci curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, 78370b324cSopenharmony_ci curModeIsFiltered ? filteredStream : src, srcLen, 79370b324cSopenharmony_ci &props, dest + 1, &outPropsSize, 0, 80370b324cSopenharmony_ci NULL, &g_Alloc, &g_Alloc); 81370b324cSopenharmony_ci 82370b324cSopenharmony_ci if (curRes != SZ_ERROR_OUTPUT_EOF) 83370b324cSopenharmony_ci { 84370b324cSopenharmony_ci if (curRes != SZ_OK) 85370b324cSopenharmony_ci { 86370b324cSopenharmony_ci mainResult = curRes; 87370b324cSopenharmony_ci break; 88370b324cSopenharmony_ci } 89370b324cSopenharmony_ci if (outSizeProcessed <= minSize || mainResult != SZ_OK) 90370b324cSopenharmony_ci { 91370b324cSopenharmony_ci minSize = outSizeProcessed; 92370b324cSopenharmony_ci bestIsFiltered = curModeIsFiltered; 93370b324cSopenharmony_ci mainResult = SZ_OK; 94370b324cSopenharmony_ci } 95370b324cSopenharmony_ci } 96370b324cSopenharmony_ci } 97370b324cSopenharmony_ci dest[0] = (Byte)(bestIsFiltered ? 1 : 0); 98370b324cSopenharmony_ci *destLen = LZMA86_HEADER_SIZE + minSize; 99370b324cSopenharmony_ci } 100370b324cSopenharmony_ci if (useFilter) 101370b324cSopenharmony_ci MyFree(filteredStream); 102370b324cSopenharmony_ci return mainResult; 103370b324cSopenharmony_ci} 104