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;
							 | 
						||
| 
								 | 
							
								}
							 |