107 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			107 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
 | ||
|  | 2016-05-16 : Igor Pavlov : Public domain */ | ||
|  | 
 | ||
|  | #include "Precomp.h"
 | ||
|  | 
 | ||
|  | #include <string.h>
 | ||
|  | 
 | ||
|  | #include "Lzma86.h"
 | ||
|  | 
 | ||
|  | #include "Alloc.h"
 | ||
|  | #include "Bra.h"
 | ||
|  | #include "LzmaEnc.h"
 | ||
|  | 
 | ||
|  | #define SZE_OUT_OVERFLOW SZE_DATA_ERROR
 | ||
|  | 
 | ||
|  | int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, | ||
|  |     int level, UInt32 dictSize, int filterMode) | ||
|  | { | ||
|  |   size_t outSize2 = *destLen; | ||
|  |   Byte *filteredStream; | ||
|  |   Bool useFilter; | ||
|  |   int mainResult = SZ_ERROR_OUTPUT_EOF; | ||
|  |   CLzmaEncProps props; | ||
|  |   LzmaEncProps_Init(&props); | ||
|  |   props.level = level; | ||
|  |   props.dictSize = dictSize; | ||
|  |    | ||
|  |   *destLen = 0; | ||
|  |   if (outSize2 < LZMA86_HEADER_SIZE) | ||
|  |     return SZ_ERROR_OUTPUT_EOF; | ||
|  | 
 | ||
|  |   { | ||
|  |     int i; | ||
|  |     UInt64 t = srcLen; | ||
|  |     for (i = 0; i < 8; i++, t >>= 8) | ||
|  |       dest[LZMA86_SIZE_OFFSET + i] = (Byte)t; | ||
|  |   } | ||
|  | 
 | ||
|  |   filteredStream = 0; | ||
|  |   useFilter = (filterMode != SZ_FILTER_NO); | ||
|  |   if (useFilter) | ||
|  |   { | ||
|  |     if (srcLen != 0) | ||
|  |     { | ||
|  |       filteredStream = (Byte *)MyAlloc(srcLen); | ||
|  |       if (filteredStream == 0) | ||
|  |         return SZ_ERROR_MEM; | ||
|  |       memcpy(filteredStream, src, srcLen); | ||
|  |     } | ||
|  |     { | ||
|  |       UInt32 x86State; | ||
|  |       x86_Convert_Init(x86State); | ||
|  |       x86_Convert(filteredStream, srcLen, 0, &x86State, 1); | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   { | ||
|  |     size_t minSize = 0; | ||
|  |     Bool bestIsFiltered = False; | ||
|  | 
 | ||
|  |     /* passes for SZ_FILTER_AUTO:
 | ||
|  |         0 - BCJ + LZMA | ||
|  |         1 - LZMA | ||
|  |         2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better. | ||
|  |     */ | ||
|  |     int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1; | ||
|  | 
 | ||
|  |     int i; | ||
|  |     for (i = 0; i < numPasses; i++) | ||
|  |     { | ||
|  |       size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE; | ||
|  |       size_t outPropsSize = 5; | ||
|  |       SRes curRes; | ||
|  |       Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1); | ||
|  |       if (curModeIsFiltered && !bestIsFiltered) | ||
|  |         break; | ||
|  |       if (useFilter && i == 0) | ||
|  |         curModeIsFiltered = True; | ||
|  |        | ||
|  |       curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed, | ||
|  |           curModeIsFiltered ? filteredStream : src, srcLen, | ||
|  |           &props, dest + 1, &outPropsSize, 0, | ||
|  |           NULL, &g_Alloc, &g_Alloc); | ||
|  |        | ||
|  |       if (curRes != SZ_ERROR_OUTPUT_EOF) | ||
|  |       { | ||
|  |         if (curRes != SZ_OK) | ||
|  |         { | ||
|  |           mainResult = curRes; | ||
|  |           break; | ||
|  |         } | ||
|  |         if (outSizeProcessed <= minSize || mainResult != SZ_OK) | ||
|  |         { | ||
|  |           minSize = outSizeProcessed; | ||
|  |           bestIsFiltered = curModeIsFiltered; | ||
|  |           mainResult = SZ_OK; | ||
|  |         } | ||
|  |       } | ||
|  |     } | ||
|  |     dest[0] = (Byte)(bestIsFiltered ? 1 : 0); | ||
|  |     *destLen = LZMA86_HEADER_SIZE + minSize; | ||
|  |   } | ||
|  |   if (useFilter) | ||
|  |     MyFree(filteredStream); | ||
|  |   return mainResult; | ||
|  | } |