411 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			411 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * Usefuls routines based on the LzmaTest.c file from LZMA SDK 4.65
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright (C) 2007-2009 Industrie Dial Face S.p.A.
							 | 
						||
| 
								 | 
							
								 * Luigi 'Comio' Mantellini (luigi.mantellini@idf-hit.com)
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Copyright (C) 1999-2005 Igor Pavlov
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * SPDX-License-Identifier:    GPL-2.0+
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * LZMA_Alone stream format:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * uchar   Properties[5]
							 | 
						||
| 
								 | 
							
								 * uint64  Uncompressed size
							 | 
						||
| 
								 | 
							
								 * uchar   data[*]
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define LZMA_PROPERTIES_OFFSET 0
							 | 
						||
| 
								 | 
							
								#define LZMA_SIZE_OFFSET       LZMA_PROPS_SIZE
							 | 
						||
| 
								 | 
							
								#define LZMA_DATA_OFFSET       LZMA_SIZE_OFFSET+sizeof(uint64_t)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "os_types.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "LzmaTools.h"
							 | 
						||
| 
								 | 
							
								#include "LzmaDec.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <string.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "7zAlloc.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "flash.h"
							 | 
						||
| 
								 | 
							
								#include "ahb.h"
							 | 
						||
| 
								 | 
							
								#include "iot_mtd.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define min(a, b) (((a) < (b)) ? (a) : (b))
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* LZMA decoder need 1M size buffer */
							 | 
						||
| 
								 | 
							
								#define BUF_SZ (64 * 1024 + 32 * 1024)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static unsigned char *heap_buf = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void *SzAlloc(void *p, size_t size) { return buffer_alloc_malloc(size); }
							 | 
						||
| 
								 | 
							
								static void SzFree(void *p, void *address) { buffer_alloc_free(address); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct dataStream
							 | 
						||
| 
								 | 
							
								 {
							 | 
						||
| 
								 | 
							
								    const unsigned char * inData;
							 | 
						||
| 
								 | 
							
								    size_t inLen;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    unsigned char * outData;
							 | 
						||
| 
								 | 
							
								    size_t outLen;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct dataStream ds;
							 | 
						||
| 
								 | 
							
								static uint32_t start_addr = 0, end_addr = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static void flash_erase_blocks(uint32_t addr, uint32_t size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    flash_write_param_t param = {
							 | 
						||
| 
								 | 
							
								        .sw_mode = MOD_SW_MODE_DIS,
							 | 
						||
| 
								 | 
							
								        .erase_mode = MODE_ERASE_BLOCK64
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    start_addr = (addr + BLOCK_ERASE_64K_MASK) & (~BLOCK_ERASE_64K_MASK);
							 | 
						||
| 
								 | 
							
								    end_addr = (addr + size) & (~BLOCK_ERASE_64K_MASK);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* disable cache space */
							 | 
						||
| 
								 | 
							
								    ahb_cache_space_dis_for_flash_write();
							 | 
						||
| 
								 | 
							
								    for (uint32_t erase_addr = start_addr; erase_addr < end_addr;
							 | 
						||
| 
								 | 
							
								        erase_addr += BLOCK_ERASE_64K_SIZE) {
							 | 
						||
| 
								 | 
							
								        flash_erase(erase_addr, ¶m);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    /* enable cache space again */
							 | 
						||
| 
								 | 
							
								    ahb_cache_space_ena_for_flash_write();
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static int
							 | 
						||
| 
								 | 
							
								inputCallback(void *ctx, void *buf, size_t * size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    size_t rd = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    rd = (ds.inLen < *size) ? ds.inLen : *size;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (rd > 0) {
							 | 
						||
| 
								 | 
							
								        memcpy(buf, (void *) ds.inData, rd);
							 | 
						||
| 
								 | 
							
								        ds.inData += rd;
							 | 
						||
| 
								 | 
							
								        ds.inLen -= rd;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    *size = rd;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static size_t
							 | 
						||
| 
								 | 
							
								outputCallback(void *ctx, const void *buf, size_t size)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    flash_write_param_t param = {0};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*write to the FW addr in flash*/
							 | 
						||
| 
								 | 
							
								    param.read_mode = MOD_SFC_READ_QUAD_IO_FAST;
							 | 
						||
| 
								 | 
							
								    param.write_mode = MOD_SFC_PROG_STAND;
							 | 
						||
| 
								 | 
							
								    param.is_erase = 1;
							 | 
						||
| 
								 | 
							
								    param.sw_mode = MOD_SW_MODE_DIS;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* disable cache space */
							 | 
						||
| 
								 | 
							
								    ahb_cache_space_dis_for_flash_write();
							 | 
						||
| 
								 | 
							
								    if ((start_addr <= (uint32_t)(ds.outData + ds.outLen)) &&
							 | 
						||
| 
								 | 
							
								        ((uint32_t)(ds.outData + ds.outLen + size) <= end_addr)) {
							 | 
						||
| 
								 | 
							
								        param.is_erase = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    flash_write(buf, (uint32_t)(ds.outData + ds.outLen), (uint32_t)size, ¶m);
							 | 
						||
| 
								 | 
							
								    /* enable cache space again */
							 | 
						||
| 
								 | 
							
								    ahb_cache_space_ena_for_flash_write();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ds.outLen += (uint32_t)size;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return size;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define IN_BUF_SIZE (1 << 14)
							 | 
						||
| 
								 | 
							
								#define OUT_BUF_SIZE (1 << 14)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Byte *inBuf = NULL;
							 | 
						||
| 
								 | 
							
								Byte *outBuf = NULL;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static SRes Decode2(CLzmaDec *state, ISeqOutStream *outStream, ISeqInStream *inStream,
							 | 
						||
| 
								 | 
							
								    UInt64 unpackSize)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								  int thereIsSize = (unpackSize != (UInt64)(Int64)-1);
							 | 
						||
| 
								 | 
							
								  size_t inPos = 0, inSize = 0, outPos = 0;
							 | 
						||
| 
								 | 
							
								  LzmaDec_Init(state);
							 | 
						||
| 
								 | 
							
								  for (;;)
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    if (inPos == inSize)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      inSize = IN_BUF_SIZE;
							 | 
						||
| 
								 | 
							
								      RINOK(inStream->Read(inStream, inBuf, &inSize));
							 | 
						||
| 
								 | 
							
								      inPos = 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      SRes res;
							 | 
						||
| 
								 | 
							
								      SizeT inProcessed = inSize - inPos;
							 | 
						||
| 
								 | 
							
								      SizeT outProcessed = OUT_BUF_SIZE - outPos;
							 | 
						||
| 
								 | 
							
								      ELzmaFinishMode finishMode = LZMA_FINISH_ANY;
							 | 
						||
| 
								 | 
							
								      ELzmaStatus status;
							 | 
						||
| 
								 | 
							
								      if (thereIsSize && outProcessed > unpackSize)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        outProcessed = (SizeT)unpackSize;
							 | 
						||
| 
								 | 
							
								        finishMode = LZMA_FINISH_END;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      res = LzmaDec_DecodeToBuf(state, outBuf + outPos, &outProcessed,
							 | 
						||
| 
								 | 
							
								        inBuf + inPos, &inProcessed, finishMode, &status);
							 | 
						||
| 
								 | 
							
								      inPos += inProcessed;
							 | 
						||
| 
								 | 
							
								      outPos += outProcessed;
							 | 
						||
| 
								 | 
							
								      unpackSize -= outProcessed;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (outStream)
							 | 
						||
| 
								 | 
							
								        if (outStream->Write(outStream, outBuf, outPos) != outPos)
							 | 
						||
| 
								 | 
							
								          return SZ_ERROR_WRITE;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      outPos = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (res != SZ_OK || (thereIsSize && unpackSize == 0))
							 | 
						||
| 
								 | 
							
								        return res;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (inProcessed == 0 && outProcessed == 0)
							 | 
						||
| 
								 | 
							
								      {
							 | 
						||
| 
								 | 
							
								        if (thereIsSize || status != LZMA_STATUS_FINISHED_WITH_MARK)
							 | 
						||
| 
								 | 
							
								          return SZ_ERROR_DATA;
							 | 
						||
| 
								 | 
							
								        return res;
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int BufferDecode(uint8_t *dst,  uint32_t *dstLen, uint8_t *src, uint32_t srcLen,
							 | 
						||
| 
								 | 
							
								    uint8_t *buf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    ISeqOutStream outStream;
							 | 
						||
| 
								 | 
							
								    ISeqInStream inStream;
							 | 
						||
| 
								 | 
							
								    ISzAlloc g_Alloc;
							 | 
						||
| 
								 | 
							
								    UInt64 unpackSize;
							 | 
						||
| 
								 | 
							
								    int i;
							 | 
						||
| 
								 | 
							
								    size_t header_size;
							 | 
						||
| 
								 | 
							
								    SRes res = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CLzmaDec state;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    outStream.Write= outputCallback;
							 | 
						||
| 
								 | 
							
								    inStream.Read = inputCallback;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ds.inData = src;
							 | 
						||
| 
								 | 
							
								    ds.inLen = srcLen;
							 | 
						||
| 
								 | 
							
								    ds.outData = dst;
							 | 
						||
| 
								 | 
							
								    ds.outLen = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */
							 | 
						||
| 
								 | 
							
								    unsigned char header[LZMA_PROPS_SIZE + 8];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Read and parse header */
							 | 
						||
| 
								 | 
							
								    header_size = sizeof(header);
							 | 
						||
| 
								 | 
							
								    inStream.Read(&inStream, header, &header_size);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    unpackSize = 0;
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < 8; i++)
							 | 
						||
| 
								 | 
							
								    unpackSize += (UInt64)header[LZMA_PROPS_SIZE + i] << (i * 8);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    heap_buf = (unsigned char*)buf;
							 | 
						||
| 
								 | 
							
								    memory_buffer_alloc_init(heap_buf, BUF_SZ);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    g_Alloc.Alloc = SzAlloc;
							 | 
						||
| 
								 | 
							
								    g_Alloc.Free = SzFree;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    LzmaDec_Construct(&state);
							 | 
						||
| 
								 | 
							
								    LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    inBuf  = g_Alloc.Alloc(NULL, IN_BUF_SIZE);
							 | 
						||
| 
								 | 
							
								    outBuf = g_Alloc.Alloc(NULL, OUT_BUF_SIZE);
							 | 
						||
| 
								 | 
							
								    if (!inBuf || !outBuf) {
							 | 
						||
| 
								 | 
							
								        if (inBuf) {
							 | 
						||
| 
								 | 
							
								            g_Alloc.Free(NULL, inBuf);
							 | 
						||
| 
								 | 
							
								            inBuf  = NULL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (outBuf) {
							 | 
						||
| 
								 | 
							
								            g_Alloc.Free(NULL, outBuf);
							 | 
						||
| 
								 | 
							
								            outBuf  = NULL;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return SZ_ERROR_MEM;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    flash_erase_blocks((uint32_t)dst, (uint32_t)unpackSize);
							 | 
						||
| 
								 | 
							
								    res = Decode2(&state, &outStream, &inStream, unpackSize);
							 | 
						||
| 
								 | 
							
								    g_Alloc.Free(NULL, inBuf);
							 | 
						||
| 
								 | 
							
								    inBuf  = NULL;
							 | 
						||
| 
								 | 
							
								    g_Alloc.Free(NULL, outBuf);
							 | 
						||
| 
								 | 
							
								    outBuf = NULL;
							 | 
						||
| 
								 | 
							
								    LzmaDec_Free(&state, &g_Alloc);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    *dstLen = ds.outLen;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return res;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int lzmaBuffToBuffDecompress (unsigned char *outStream, uint32_t *uncompressedSize,
							 | 
						||
| 
								 | 
							
								                  unsigned char *inStream,  uint32_t  length, uint8_t *buf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								#if RUN_IN_PSRAM
							 | 
						||
| 
								 | 
							
								    int res = SZ_ERROR_DATA;
							 | 
						||
| 
								 | 
							
								    int i;
							 | 
						||
| 
								 | 
							
								    ISzAlloc g_Alloc;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    SizeT outSizeFull = 0xFFFFFFFF; /* 4GBytes limit */
							 | 
						||
| 
								 | 
							
								    SizeT outProcessed;
							 | 
						||
| 
								 | 
							
								    SizeT outSize;
							 | 
						||
| 
								 | 
							
								    SizeT outSizeHigh;
							 | 
						||
| 
								 | 
							
								    ELzmaStatus state;
							 | 
						||
| 
								 | 
							
								    SizeT compressedSize = (SizeT)(length - LZMA_PROPS_SIZE);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    memset(&state, 0, sizeof(state));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    outSize = 0;
							 | 
						||
| 
								 | 
							
								    outSizeHigh = 0;
							 | 
						||
| 
								 | 
							
								    /* Read the uncompressed size */
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < 8; i++) {
							 | 
						||
| 
								 | 
							
								        unsigned char b = inStream[LZMA_SIZE_OFFSET + i];
							 | 
						||
| 
								 | 
							
								            if (i < 4) {
							 | 
						||
| 
								 | 
							
								                outSize     += (UInt32)(b) << (i * 8);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								                outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    outSizeFull = (SizeT)outSize;
							 | 
						||
| 
								 | 
							
								    if (sizeof(SizeT) >= 8) {
							 | 
						||
| 
								 | 
							
								        /*
							 | 
						||
| 
								 | 
							
								         * SizeT is a 64 bit uint => We can manage files larger than 4GB!
							 | 
						||
| 
								 | 
							
								         *
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								            outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
							 | 
						||
| 
								 | 
							
								    } else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize) {
							 | 
						||
| 
								 | 
							
								        /*
							 | 
						||
| 
								 | 
							
								         * SizeT is a 32 bit uint => We cannot manage files larger than
							 | 
						||
| 
								 | 
							
								         * 4GB!  Assume however that all 0xf values is "unknown size" and
							 | 
						||
| 
								 | 
							
								         * not actually a file of 2^64 bits.
							 | 
						||
| 
								 | 
							
								         *
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        if (outSizeHigh != (SizeT)-1 || outSize != (SizeT)-1) {
							 | 
						||
| 
								 | 
							
								            return SZ_ERROR_DATA;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    heap_buf = (unsigned char*)buf;
							 | 
						||
| 
								 | 
							
								    memory_buffer_alloc_init(heap_buf, BUF_SZ);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    g_Alloc.Alloc = SzAlloc;
							 | 
						||
| 
								 | 
							
								    g_Alloc.Free = SzFree;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Short-circuit early if we know the buffer can't hold the results. */
							 | 
						||
| 
								 | 
							
								    if (outSizeFull != (SizeT)-1 && *uncompressedSize < outSizeFull)
							 | 
						||
| 
								 | 
							
								        return SZ_ERROR_OUTPUT_EOF;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Decompress */
							 | 
						||
| 
								 | 
							
								    outProcessed = min(outSizeFull, *uncompressedSize);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    res = LzmaDecode(
							 | 
						||
| 
								 | 
							
								        outStream, &outProcessed,
							 | 
						||
| 
								 | 
							
								        inStream + LZMA_DATA_OFFSET, &compressedSize,
							 | 
						||
| 
								 | 
							
								        inStream, LZMA_PROPS_SIZE, LZMA_FINISH_END, &state, &g_Alloc);
							 | 
						||
| 
								 | 
							
								    *uncompressedSize = outProcessed;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (res != SZ_OK)  {
							 | 
						||
| 
								 | 
							
								        return res;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return res;
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    return BufferDecode(outStream, uncompressedSize, inStream, length, buf);
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int lzmaBuffToBuffDecompress2Ram(unsigned char * outStream,
							 | 
						||
| 
								 | 
							
								  uint32_t * uncompressedSize, unsigned char * inStream, uint32_t length, uint8_t *buf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    int res = SZ_ERROR_DATA;
							 | 
						||
| 
								 | 
							
								    int i;
							 | 
						||
| 
								 | 
							
								    ISzAlloc g_Alloc;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    SizeT outSizeFull = 0xFFFFFFFF; /* 4GBytes limit */
							 | 
						||
| 
								 | 
							
								    SizeT outProcessed;
							 | 
						||
| 
								 | 
							
								    SizeT outSize;
							 | 
						||
| 
								 | 
							
								    SizeT outSizeHigh;
							 | 
						||
| 
								 | 
							
								    ELzmaStatus state;
							 | 
						||
| 
								 | 
							
								    SizeT compressedSize = (SizeT)(length - LZMA_PROPS_SIZE);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    memset(&state, 0, sizeof(state));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    outSize = 0;
							 | 
						||
| 
								 | 
							
								    outSizeHigh = 0;
							 | 
						||
| 
								 | 
							
								    /* Read the uncompressed size */
							 | 
						||
| 
								 | 
							
								    for (i = 0; i < 8; i++) {
							 | 
						||
| 
								 | 
							
								        unsigned char b = inStream[LZMA_SIZE_OFFSET + i];
							 | 
						||
| 
								 | 
							
								            if (i < 4) {
							 | 
						||
| 
								 | 
							
								                outSize     += (UInt32)(b) << (i * 8);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								                outSizeHigh += (UInt32)(b) << ((i - 4) * 8);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    outSizeFull = (SizeT)outSize;
							 | 
						||
| 
								 | 
							
								    if (sizeof(SizeT) >= 8) {
							 | 
						||
| 
								 | 
							
								        /*
							 | 
						||
| 
								 | 
							
								         * SizeT is a 64 bit uint => We can manage files larger than 4GB!
							 | 
						||
| 
								 | 
							
								         *
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								            outSizeFull |= (((SizeT)outSizeHigh << 16) << 16);
							 | 
						||
| 
								 | 
							
								    } else if (outSizeHigh != 0 || (UInt32)(SizeT)outSize != outSize) {
							 | 
						||
| 
								 | 
							
								        /*
							 | 
						||
| 
								 | 
							
								         * SizeT is a 32 bit uint => We cannot manage files larger than
							 | 
						||
| 
								 | 
							
								         * 4GB!  Assume however that all 0xf values is "unknown size" and
							 | 
						||
| 
								 | 
							
								         * not actually a file of 2^64 bits.
							 | 
						||
| 
								 | 
							
								         *
							 | 
						||
| 
								 | 
							
								         */
							 | 
						||
| 
								 | 
							
								        if (outSizeHigh != (SizeT)-1 || outSize != (SizeT)-1) {
							 | 
						||
| 
								 | 
							
								            return SZ_ERROR_DATA;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    heap_buf = (unsigned char*)buf;
							 | 
						||
| 
								 | 
							
								    memory_buffer_alloc_init(heap_buf, BUF_SZ);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    g_Alloc.Alloc = SzAlloc;
							 | 
						||
| 
								 | 
							
								    g_Alloc.Free = SzFree;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Short-circuit early if we know the buffer can't hold the results. */
							 | 
						||
| 
								 | 
							
								    if (outSizeFull != (SizeT)-1 && *uncompressedSize < outSizeFull)
							 | 
						||
| 
								 | 
							
								        return SZ_ERROR_OUTPUT_EOF;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* Decompress */
							 | 
						||
| 
								 | 
							
								    outProcessed = min(outSizeFull, *uncompressedSize);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    res = LzmaDecode(
							 | 
						||
| 
								 | 
							
								        outStream, &outProcessed,
							 | 
						||
| 
								 | 
							
								        inStream + LZMA_DATA_OFFSET, &compressedSize,
							 | 
						||
| 
								 | 
							
								        inStream, LZMA_PROPS_SIZE, LZMA_FINISH_END, &state, &g_Alloc);
							 | 
						||
| 
								 | 
							
								    *uncompressedSize = outProcessed;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (res != SZ_OK)  {
							 | 
						||
| 
								 | 
							
								        return res;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return res;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int lzmaBuffToBuffDecompress2Flash(unsigned char * outStream,
							 | 
						||
| 
								 | 
							
								    uint32_t * uncompressedSize, unsigned char * inStream, uint32_t length, uint8_t *buf)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return BufferDecode(outStream, uncompressedSize, inStream, length, buf);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 |