⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lzmaif.c

📁 lzma的压缩算法再嵌入式系统上的实现
💻 C
字号:
/*-----------------------------------------------------------------------------
 文件名  : LzmaIf.c
 作者    : james
 版本    :
 完成日期: 2004-07-15
 文件描述: LZMA压缩算法的解压缩接口的源文件.
 备注    :
 函数列表: 主要函数列表,每条记录应包括函数名及功能简要说明
           (1):
           (2):
           (3):
           ......

 提供给外部的接口: 本文件提供给外部的接口
           (1):
           (2):

 需要外部提供的接口: 本文件需要外部提供的接口
           (1):
           (2):

 修改历史:
        1. 修改者   :
           时间     :
           版本     :
           修改原因 :
        2. ...
-----------------------------------------------------------------------------*/
#if defined(_MSC_VER)
#define MAKE_INCLUDE_COMPRESS_TYPE_LZMA
#endif

#ifdef MAKE_INCLUDE_COMPRESS_TYPE_LZMA

/*================================头文件引用=================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "LzmaDecode.h"



/*===============================外部变量引用================================*/

/*===============================全局变量定义================================*/

/*===============================外部函数引用================================*/


/* 打印输出函数 */
extern unsigned long Drv_Print(const char *pStr, ...);
#define LZMA_Print          Drv_Print

#ifndef MAKE_BOOTROM
/* 清狗的回调函数 */
typedef void (* Drv_Func)(void);
extern Drv_Func funcgDrvFeedSoftWatchdogHook;
#endif


#ifdef _LZMA_IN_CB
/* 向上对齐 */
#define ALIGN_UP(addr,align)       ( ((unsigned int)(addr) + (unsigned int)((align) - 1)) & ~(unsigned int)((align) - 1) )

#define MAX_DECOMPRESS_READ_COUNT  10

typedef struct _CBuffer
{
  ILzmaInCallback InCallback;
  unsigned char *Buffer;
  unsigned int Size;
  unsigned int PerSize;
  unsigned int PerCount;
} CBuffer;

int LzmaReadCompressed(void *object, unsigned char **buffer, unsigned int *size)
{

    CBuffer *bo = (CBuffer *)object;

    #ifdef MAKE_BOOTROM
    /* 输出解压缩的百分比 */
    if( bo->PerCount != 0 )
    {
        LZMA_Print("%ld%%...", bo->PerCount * 100 / MAX_DECOMPRESS_READ_COUNT );
    }
    #else
    /* 清狗 */
    if( funcgDrvFeedSoftWatchdogHook != NULL )
    {
        funcgDrvFeedSoftWatchdogHook();
    }
    Drv_FeedHardWatchDog();
    #endif

    if( bo->PerCount == ( MAX_DECOMPRESS_READ_COUNT - 1 ) )
    {
        *size   = bo->Size - bo->PerSize * bo->PerCount;
    }
    else if ( bo->PerCount < ( MAX_DECOMPRESS_READ_COUNT - 1 ) )
    {
        *size   = bo->PerSize;
    }
    else
    {
        LZMA_Print("\r\n  LzmaReadCompressed() : Read compressd mem fail !");
        return LZMA_RESULT_NOT_ENOUGH_MEM;
    }

    *buffer     = bo->Buffer + bo->PerSize * bo->PerCount;


    bo->PerCount ++;

    return LZMA_RESULT_OK;

}
#endif


/*-----------------------------------------------------------------------------
 函数名称    : LZMA_Decompress();
 功能        : LZMA压缩算法的解压缩接口;
 输入参数    : pDst,        解压缩的目的内存的地址;
               pulDstLen,   解压缩的目的内存的长度;
               pSrc,        解压缩的源内存的地址;
               ulSrcLen,    解压缩的源内存的长度;
 输出参数    : *pulDstLen,  如果解压缩成功, 实际解压后的长度;
 返回值      : 0,           成功;
               其他,        失败.
 函数调用说明:
 典型使用示例:
-----------------------------------------------------------------------------*/
unsigned long LZMA_Decompress( void *pDst, unsigned long *pulDstLen, void *pSrc, unsigned long ulSrcLen )
{
  unsigned int compressedSize, outSize, outSizeProcessed, lzmaInternalSize;
  void *inStream, *outStream, *lzmaInternalData;
  unsigned char properties[5];
  unsigned char prop0;
  int ii;
  int lc, lp, pb;
  int res;
  #ifdef _LZMA_IN_CB
  CBuffer bo;
  #endif
  unsigned char *pCharSrc = pSrc;

  if( ( NULL == pDst ) || ( NULL == pulDstLen ) || ( NULL == pSrc ) )
  {
    LZMA_Print("\r\n  LZMA_Decompress() : Input prt is null");
    return 1;
  }

  if( ( 0 == *pulDstLen ) || ( 0 == ulSrcLen ) )
  {
    LZMA_Print("\r\n  LZMA_Decompress() : Input mem len is zero");
    return 1;
  }

  memcpy(properties, pSrc, sizeof(properties) );
  pCharSrc += sizeof(properties);

  outSize = 0;
  for (ii = 0; ii < 4; ii++)
  {
    unsigned char b;
    b = *pCharSrc;
    pCharSrc ++;
    outSize += (unsigned int)(b) << (ii * 8);
  }

  if (outSize == 0xFFFFFFFF)
  {
    LZMA_Print("\r\n  LZMA_Decompress() : stream version is not supported");
    return 1;
  }

  for (ii = 0; ii < 4; ii++)
  {
    unsigned char b;
    b = *pCharSrc;
    pCharSrc ++;
    if (b != 0)
    {
      LZMA_Print("\r\n  LZMA_Decompress() :  too long file");
      return 1;
    }
  }

  compressedSize = ulSrcLen - 13;
  inStream = pCharSrc;

  prop0 = properties[0];
  if (prop0 >= (9*5*5))
  {
    LZMA_Print("\r\n  LZMA_Decompress() : Properties error");
    return 1;
  }
  for (pb = 0; prop0 >= (9 * 5);
    pb++, prop0 -= (9 * 5));
  for (lp = 0; prop0 >= 9;
    lp++, prop0 -= 9);
  lc = prop0;

  lzmaInternalSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb);

  #ifdef _LZMA_OUT_READ
  lzmaInternalSize += 100;
  #endif

  outStream = pDst;
  if (outSize >= *pulDstLen)
  {
    LZMA_Print("\r\n  LZMA_Decompress() : outSize is not enough. outSize(0x%lx) >= *pulDstLen(0x%lx) ", outSize, *pulDstLen);
    return 1;
  }


  lzmaInternalData = malloc(lzmaInternalSize);

  if (outStream == 0 || lzmaInternalData == 0)
  {
    LZMA_Print("\r\n  LZMA_Decompress() : can't allocate lzmaInternalData ! lzmaInternalSize = 0x%lx", lzmaInternalSize );
    return 1;
  }

  #ifdef _LZMA_IN_CB
  bo.InCallback.Read = LzmaReadCompressed;
  bo.Buffer = (unsigned char *)inStream;
  bo.Size = compressedSize;
  bo.PerCount = 0;
  bo.PerSize = ALIGN_UP( compressedSize / MAX_DECOMPRESS_READ_COUNT, 0x10 );
  #endif

  #ifdef _LZMA_OUT_READ
  {
    UInt32 nowPos;
    unsigned char *dictionary;
    UInt32 dictionarySize = 0;
    int i;
    for (i = 0; i < 4; i++)
      dictionarySize += (UInt32)(properties[1 + i]) << (i * 8);
    dictionary = malloc(dictionarySize);
    if (dictionary == 0)
    {
      LZMA_Print("\r\n  LZMA_Decompress() : can't allocate dictionary. dictionarySize = 0x%lx", dictionarySize);
      return 1;
    }
    LzmaDecoderInit((unsigned char *)lzmaInternalData, lzmaInternalSize,
        lc, lp, pb,
        dictionary, dictionarySize,
        #ifdef _LZMA_IN_CB
        &bo.InCallback
        #else
        (unsigned char *)inStream, compressedSize
        #endif
        );
    for (nowPos = 0; nowPos < outSize;)
    {
      UInt32 blockSize = outSize - nowPos;
      UInt32 kBlockSize = 0x10000;
      if (blockSize > kBlockSize)
        blockSize = kBlockSize;
      res = LzmaDecode((unsigned char *)lzmaInternalData,
      ((unsigned char *)outStream) + nowPos, blockSize, &outSizeProcessed);
      if (res != 0)
      {
        LZMA_Print("\r\n  LZMA_Decompress() : error = %d\n", res);
        return 1;
      }
      if (outSizeProcessed == 0)
      {
        outSize = nowPos;
        break;
      }
      nowPos += outSizeProcessed;
    }
    free(dictionary);
  }

  #else
  res = LzmaDecode((unsigned char *)lzmaInternalData, lzmaInternalSize,
      lc, lp, pb,
      #ifdef _LZMA_IN_CB
      &bo.InCallback,
      #else
      (unsigned char *)inStream, compressedSize,
      #endif
      (unsigned char *)outStream, outSize, &outSizeProcessed);
  outSize = outSizeProcessed;
  #endif

  if (res != 0)
  {
    LZMA_Print("\r\n  LZMA_Decompress() : error = %d\n", res);
    return 1;
  }

  free(lzmaInternalData);

  *pulDstLen = outSize;

  return 0;

}


#endif /* MAKE_INCLUDE_COMPRESS_TYPE_LZMA */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -