压缩算法_quicklz使用

1 quicklz

  quicklz是单片机上一个常见的压缩算法,具体原理没有文档和hash表的相关基础我就不去深究了;

  只需要将fileSrc.txt放在桌面,代码可以使用vscode的mingw直接编译;

2 quicklz源码

  quicklz源码就一个c文件一个h文件,标准库要求就一个<string.h>;移植起来比较简单,直接包含头文件即可;

  https://gitee.com/RT-Thread-Mirror/quicklz

fileSrc.txt
/***Put this file on Desktop as srcFile for quicklz compress;***/

// attention
//1 compress buff no more than 2048 size;
//2 because compressed transmit buff need to read qlz algrorithm parameter together for decompress,
//   and parameter will count into decompressed buff;
//   may lead to some mistake decompress;

4 quicklz 函数接口

/***main.c**************************************************************************************************/
//vscode直接使用mingw编译的时候没法包含多个c文件编译,需要配置vscode编译路径,不想配先放着;
//所以quicklz.c代码需要放到main函数所在c文件中,不然会查找不到;


#include <stdio.h>  
#include <stdlib.h> 
#include "quicklz.h"


#define PATH_FILE_SRC    "C:/Users/WINDOWS/Desktop/fileSrc.txt"
#define PATH_FILE_CPS    "C:/Users/WINDOWS/Desktop/fileCompress.qlz"
#define PATH_FILE_DST    "C:/Users/WINDOWS/Desktop/fileDst.txt"


int qlzCompress(void)
{
	printf("qlzCompress() \n");
	
	FILE *fsrcFile;
	FILE *fcpsFile;
    unsigned char psrcTrans[2048] ={0};      
    unsigned char pdstTrans[2048] ={0};     
	size_t srcFileLen, cpsFileLen; 
	qlz_state_compress state_compress;
    
	//fsrcFile handle;
    fsrcFile = fopen(PATH_FILE_SRC, "r");

	//fsrcFile length;
    fseek(fsrcFile, 0, SEEK_END);
    srcFileLen = ftell(fsrcFile);
	
	//read fsrcFile >> psrcTrans;
	printf("srcFileLen:(d)%08d  \n",srcFileLen);
	fseek(fsrcFile, 0, SEEK_SET);
    fread(psrcTrans, sizeof(char), srcFileLen, fsrcFile);
	//for(int i =0; i<srcFileLen;i++)  printf("%c",psrcTrans[i]); printf("\n");

	//fcpsFile handle;
	fcpsFile = fopen(PATH_FILE_CPS, "w");

	//compress psrcTrans >> pdstTrans;
    cpsFileLen = qlz_compress(psrcTrans, pdstTrans, srcFileLen, &state_compress);
	
	printf("cpsFileLen:(d)%08d  \n",cpsFileLen);
    fwrite(pdstTrans, sizeof(char), cpsFileLen, fcpsFile);

    fclose(fsrcFile);
    fclose(fcpsFile);
    return 0;
}



int qlzDecompress(void)
{
   printf("qlzDecompress()  \n");
   
   FILE *fcpsFile;
   FILE *fdstFile;
   unsigned char *pcpsTrans;
   unsigned char *pdstTrans;
   qlz_state_decompress state_decompress;
   unsigned int cpsFileLen;
   unsigned int decpsFileLen;

   //fcpsFile handle;
   fcpsFile = fopen(PATH_FILE_CPS, "r");

   //fcpsFile length;
   fseek(fcpsFile, 0, SEEK_END);
   cpsFileLen = ftell(fcpsFile);

   //pcpsTrans buff
   pcpsTrans = (unsigned char *)malloc(cpsFileLen);
   if(pcpsTrans==NULL){
   	   printf("malloc cps buff fail.  \n");
	   return -2;
   }

   //read fcpsFile >> pcpsTrans;
   printf("cpsFileLen:(d)%08d \n",cpsFileLen);
   fseek(fcpsFile, 0, SEEK_SET);
   fread(pcpsTrans, sizeof(char), cpsFileLen, fcpsFile);
   //for(int i =0;i< cpsFileLen;i++)  printf("%02x ",pcpsTrans[i]); printf("\n");

   //pdstTrans length;
   decpsFileLen = qlz_size_decompressed(pcpsTrans);
   pdstTrans = (unsigned char *)malloc(decpsFileLen);
   if(pdstTrans ==NULL){
   	  printf("malloc pdstTrans fail. \n");
	  return -3;
   }

   //bcz pcpsTrans read some more qlz para,
   //so after decompress will have some more space empty in fileDst.txt? bug leave;
   printf("decpsFileLen:(d)%08d \n",decpsFileLen);
   decpsFileLen = qlz_decompress(pcpsTrans, pdstTrans, &state_decompress); 

   fdstFile = fopen(PATH_FILE_DST, "w");
   fwrite(pdstTrans, sizeof(char), decpsFileLen, fdstFile);
   
   fclose(fcpsFile);
   fclose(fdstFile);
   free(pcpsTrans);
   free(pdstTrans);
   return 0;
}


int main()
{
    printf("hello  \n");
	//文件压缩完之后会多出部分qlz的参数,分配内存时需要考虑;
	//因为解压时是通过读取文件长度来解压的,所以解压后结尾部分会把这部分多出的也解压了;qlz本身小bug??

	//这个bug的解决办法是在使用数据的时候只读取解压长度的数据,丢弃掉多余字节;
	//所以在使用数据的时候,需要通过解压前数据长度来使用;
	//上面的接口函数只是压缩解压,不涉及数据处理使用;
	
	//qlz解压最大不超过4096,需要考虑;
	//函数内数组不要超出栈空间大小;
	
    qlzCompress();
    qlzDecompress();
    return 0;
}

5 文件操作读写模式

  

  前两列判断fopen的操作;后两列判断如果可以执行当前函数操作的话pfile的文件偏移位置;

  需要注意的是图中斜杆部分读写无此操作,但执行不会报错,导致不容易发现bug,

  通过判断fopen、fread、fwrite返回值来判断文件操作是否成功失败,可以提高代码的健壮性和稳定性;

6 小结

  这个接口主要还有三个地方需要优化的;

  一是vscode编辑器配置多个c文件编译的问题,但是我懒的配置了,先放着吧;

  二是解压成源文件之后,解压出来的文件结尾虽然没有数据丢失但是会有部分空格多余,需要丢弃,先放着吧;

  三是读写接口可以优化,加上返回值判断,也放着把;

### QuickLZ Compression Algorithm Version for Microcontrollers For applications targeting microcontrollers, the implementation of the QuickLZ compression algorithm must be optimized to fit within limited resources such as memory and processing power. The core idea behind QuickLZ is its speed advantage over other algorithms at the cost of a slightly lower compression ratio[^2]. The original QuickLZ library supports various platforms but may require modifications or specific configurations when porting to resource-constrained environments like those found in embedded systems. #### Key Considerations for Microcontroller Implementation To adapt QuickLZ for use on microcontrollers: - **Resource Optimization**: Minimize RAM usage by adjusting buffer sizes according to available system resources. - **Simplified Codebase**: Remove unnecessary features that do not contribute directly to compression/decompression functionality. - **Portability Enhancements**: Ensure compatibility with different architectures through conditional compilation directives. An example initialization snippet tailored towards microcontroller constraints might look similar to this C code block: ```c #include "quicklz.h" // Initialize state structures used during compression operations qlz_state_compress compress_state; memset(&compress_state, 0, sizeof(compress_state)); // Similarly initialize decompression states if needed... ``` This setup ensures proper allocation and zero-initialization of required internal buffers before performing any actual data manipulation tasks using QuickLZ functions. --related questions-- 1. What are some common challenges faced while implementing compression libraries on microcontrollers? 2. How does QuickLZ compare against LZ4 regarding performance metrics suitable for embedded devices? 3. Can you provide an overview of how to optimize QuickLZ specifically for low-power consumption scenarios typical in IoT deployments? 4. Are there pre-existing ports of QuickLZ designed explicitly for popular microcontroller families (e.g., AVR, ARM Cortex-M)? 5. In what ways can one measure the effectiveness of compressed data storage solutions implemented on constrained hardware platforms?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值