├── .gitignore ├── LICENSE ├── README.TXT ├── README.md ├── README_ZH.md ├── SConscript ├── doc └── image │ └── fastlz.jpg ├── fastlz.c ├── fastlz.h └── fastlz_sample.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Object files 5 | *.o 6 | *.ko 7 | *.obj 8 | *.elf 9 | 10 | # Linker output 11 | *.ilk 12 | *.map 13 | *.exp 14 | 15 | # Precompiled Headers 16 | *.gch 17 | *.pch 18 | 19 | # Libraries 20 | *.lib 21 | *.a 22 | *.la 23 | *.lo 24 | 25 | # Shared objects (inc. Windows DLLs) 26 | *.dll 27 | *.so 28 | *.so.* 29 | *.dylib 30 | 31 | # Executables 32 | *.exe 33 | *.out 34 | *.app 35 | *.i*86 36 | *.x86_64 37 | *.hex 38 | 39 | # Debug files 40 | *.dSYM/ 41 | *.su 42 | *.idb 43 | *.pdb 44 | 45 | # Kernel Module Compile Results 46 | *.mod* 47 | *.cmd 48 | .tmp_versions/ 49 | modules.order 50 | Module.symvers 51 | Mkfile.old 52 | dkms.conf 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | FastLZ - lightning-fast lossless compression library 2 | 3 | Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) 4 | Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) 5 | Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | 25 | -------------------------------------------------------------------------------- /README.TXT: -------------------------------------------------------------------------------- 1 | FastLZ - lightning-fast lossless compression library 2 | 3 | Author: Ariya Hidayat 4 | Official website: http://www.fastlz.org 5 | 6 | FastLZ is distributed using the MIT license, see file LICENSE 7 | for details. 8 | 9 | FastLZ consists of two files: fastlz.h and fastlz.c. Just add these 10 | files to your project in order to use FastLZ. For information on 11 | compression and decompression routines, see fastlz.h. 12 | 13 | A simple file compressor called 6pack is included as an example 14 | on how to use FastLZ. The corresponding decompressor is 6unpack. 15 | 16 | To compile using GCC: 17 | 18 | gcc -o 6pack 6pack.c fastlz.c 19 | gcc -o 6unpack 6unpack.c fastlz.c 20 | 21 | To compile using MinGW: 22 | 23 | mingw32-gcc -o 6pack 6pack.c fastlz.c 24 | mingw32-gcc -o 6unpack 6unpack.c fastlz.c 25 | 26 | To compile using Microsoft Visual C++: 27 | 28 | cl 6pack.c fastlz.c 29 | cl 6unpack.c fastlz.c 30 | 31 | To compile using Borland C++: 32 | 33 | bcc32 6pack.c fastlz.c 34 | bcc32 6unpack.c fastlz.c 35 | 36 | To compile using OpenWatcom C/C++: 37 | 38 | cl386 6pack.c fastlz.c 39 | cl386 6unpack.c fastlz.c 40 | 41 | To compile using Intel C++ compiler for Windows: 42 | 43 | icl 6pack.c fastlz.c 44 | icl 6unpack.c fastlz.c 45 | 46 | To compile using Intel C++ compiler for Linux: 47 | 48 | icc -o 6pack 6pack.c fastlz.c 49 | icc -o 6unpack 6unpack.c fastlz.c 50 | 51 | To compile 6pack using LCC-Win32: 52 | 53 | lc 6pack.c fastlz.c 54 | lc 6unpack.c fastlz.c 55 | 56 | To compile 6pack using Pelles C: 57 | 58 | pocc 6pack.c 59 | pocc 6unpack.c 60 | pocc fastlz.c 61 | polink 6pack.obj fastlz.obj 62 | polink 6unpack.obj fastlz.obj 63 | 64 | For speed optimization, always use proper compile flags for optimization options. 65 | Typical compiler flags are given below: 66 | 67 | * GCC (pre 4.2): -march=pentium -O3 -fomit-frame-pointer -mtune=pentium 68 | * GCC 4.2 or later: -march=pentium -O3 -fomit-frame-pointer -mtune=generic 69 | * Digital Mars C/C++: -o+all -5 70 | * Intel C++ (Windows): /O3 /Qipo 71 | * Intel C++ (Linux): -O2 -march=pentium -mtune=pentium 72 | * Borland C++: -O2 -5 73 | * LCC-Win32: -O 74 | * Pelles C: /O2 75 | 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FastLZ 2 | 3 | [中文页](README_ZH.md) | English 4 | 5 | ## 1 Introduction 6 | 7 | FastLZ is a fast and lossless compression library that contains only two files, is simple to use and easy to integrate. This [FastLZ](https://github.com/RT-Thread-packages/fastlz) library is a port of RT-thread to the official [FastLZ](http://fastlz.org/download.htm) C library. For more information about fastlz, please refer to [http://fastlz.org/index.html](http://fastlz.org/index.html). 8 | 9 | ## 2. How to obtain 10 | 11 | - Use menuconfig 12 | ``` 13 | RT-Thread online packages ---> 14 | miscellaneous packages ---> 15 | [*] Fastlz: A portable real-time compression library 16 | ``` 17 | 18 | ## 3. Example introduction 19 | 20 | ### 3.1 Get examples 21 | 22 | - Configure the enable sample option `Enable using fastlz sample`; 23 | - Configure the compression level option, set to level 1 (there are two levels 1 or 2, level 1 has the fastest compression speed, and level 2 has a large compression ratio); 24 | - The configuration package version is selected as the latest version `latest_version`. 25 | 26 | ![](./doc/image/fastlz.jpg) 27 | 28 | ### 3.2 Run example 29 | This example is a simple file compression and decompression routine, which depends on the file system. The commands used are two `-c` and `-d`. The `-c` command compresses one file to another, ` The -d` command decompresses a file to another file. 30 | How to use: 31 | msh cmd compression: `fastlz_test -c /file.bin /file.cmprs.bin` 32 | msh cmd decompression: `fastlz_test -d /file.cmprs.bin /file_dcmprs.bin` 33 | 34 | ``` 35 | msh />fastlz_test -c /file.bin /file.cmprs.bin 36 | [fastlz]compress start: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> 37 | [fastlz]compressed 469848 bytes into 363495 bytes, compression ratio is 77%! 38 | msh /> 39 | msh />fastlz_test -d /file.cmprs.bin /file_dcmprs.bin 40 | [fastlz]decompress start: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>>>>>> 41 | [fastlz]decompressed 363495 bytes into 469848 bytes! 42 | ``` 43 | 44 | ## 4. Matters needing attention 45 | 46 | ### 4.1 Differences from the official source code 47 | 48 | The FastLZ source code uses static memory allocation. A 32Kbytes buffer is preset, which occupies too much stack resources. The source code is modified and dynamic memory allocation is used to replace the original static memory allocation. 49 | 50 | Make the following changes to the source code `fastlz.c`, you need to pay attention when porting the official code: 51 | 52 | 1. Add dynamic memory allocation definition 53 | ```C 54 | #include 55 | 56 | #define malloc rt_malloc 57 | #define free rt_free 58 | ``` 59 | 60 | 2. Use `malloc` to allocate memory for `htab` 61 | ```C 62 | const flzuint8* htab[HASH_SIZE]; 63 | ``` 64 | Replace with 65 | ```C 66 | const flzuint8** htab = (const flzuint8**)malloc(sizeof(flzuint8*) * HASH_SIZE); 67 | ``` 68 | 69 | 3. Use `free` to release memory before `return` 70 | 71 | ## 5. Reference materials 72 | 73 | - FastLZ official website: [http://fastlz.org/index.html](http://fastlz.org/support.htm) 74 | -------------------------------------------------------------------------------- /README_ZH.md: -------------------------------------------------------------------------------- 1 | # FastLZ 2 | 3 | 中文页 | [English](README.md) 4 | 5 | ## 1、介绍 6 | 7 | FastLZ 是一个快速无损压缩库, 仅包含两个文件, 使用简单, 易于集成。 这个 [FastLZ](https://github.com/RT-Thread-packages/fastlz) 库是 RT-thread 针对官方[FastLZ](http://fastlz.org/download.htm)的C库的移植, 有关 fastlz 的更多信息,请参阅[http://fastlz.org/index.html](http://fastlz.org/index.html) 。 8 | 9 | ## 2、获取方式 10 | 11 | - 使用 menuconfig 12 | ``` 13 | RT-Thread online packages ---> 14 | miscellaneous packages ---> 15 | [*] Fastlz: A portable real-time compression library 16 | ``` 17 | 18 | ## 3、示例介绍 19 | 20 | ### 3.1 获取示例 21 | 22 | - 配置使能示例选项 `Enable using fastlz sample`; 23 | - 配置压缩等级选项,配置为level 1(有两种等级 1 or 2,level 1 压缩速度最快, level 2 压缩比大); 24 | - 配置包版本选为最新版 `latest_version` . 25 | 26 | ![](./doc/image/fastlz.jpg) 27 | 28 | ### 3.2 运行示例 29 | 该示例为一个简单的文件压缩和解压的例程,需要依赖文件系统,用到的命令有两个` -c`和 `-d`, `-c`命令压缩一个文件到另一个文件,`-d`命令解压一个文件到另一个文件。 30 | 使用方式: 31 | msh cmd 压缩: `fastlz_test -c /file.bin /file.cmprs.bin` 32 | msh cmd 解压: `fastlz_test -d /file.cmprs.bin /file_dcmprs.bin` 33 | 34 | msh />fastlz_test -c /file.bin /file.cmprs.bin 35 | [fastlz]compress start : >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 36 | [fastlz]compressed 469848 bytes into 363495 bytes , compression ratio is 77%! 37 | msh /> 38 | msh />fastlz_test -d /file.cmprs.bin /file_dcmprs.bin 39 | [fastlz]decompress start : >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 40 | [fastlz]decompressed 363495 bytes into 469848 bytes ! 41 | 42 | ## 4、注意事项 43 | 44 | ### 4.1 与官方源码差异 45 | 46 | FastLZ 源码中使用了静态内存分配,预置了一个 32Kbytes 大小的 buffer,占用堆栈资源过大,修改了源码,使用动态内存分配替换原有的静态内存分配。 47 | 48 | 对源码 `fastlz.c` 进行如下变动,移植官方代码的时候需要注意: 49 | 50 | 1. 添加动态内存分配定义 51 | ```C 52 | #include 53 | 54 | #define malloc rt_malloc 55 | #define free rt_free 56 | ``` 57 | 58 | 2. 使用 `malloc` 为 `htab` 分配内存 59 | ```C 60 | const flzuint8* htab[HASH_SIZE]; 61 | ``` 62 | 替换为 63 | ```C 64 | const flzuint8** htab = (const flzuint8**)malloc(sizeof(flzuint8*) * HASH_SIZE); 65 | ``` 66 | 67 | 3. 在 `return` 前使用 `free` 释放内存 68 | 69 | ## 5、参考资料 70 | 71 | - FastLZ 官方网站:[http://fastlz.org/index.html](http://fastlz.org/support.htm) 72 | 73 | -------------------------------------------------------------------------------- /SConscript: -------------------------------------------------------------------------------- 1 | # RT-Thread building script for component 2 | 3 | from building import * 4 | 5 | cwd = GetCurrentDir() 6 | src = Glob('fastlz.c') 7 | CPPPATH = [cwd] 8 | 9 | if GetDepend('FASTLZ_USING_SAMPLE'): 10 | src += Glob('fastlz_sample.c') 11 | 12 | group = DefineGroup('fastlz', src, depend = ['PKG_USING_FASTLZ'], CPPPATH = CPPPATH) 13 | 14 | Return('group') 15 | -------------------------------------------------------------------------------- /doc/image/fastlz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RT-Thread-packages/fastlz/3bdb478afc60d6b4abee74a7b0ed6062c6ccc6ad/doc/image/fastlz.jpg -------------------------------------------------------------------------------- /fastlz.c: -------------------------------------------------------------------------------- 1 | /* 2 | FastLZ - lightning-fast lossless compression library 3 | 4 | Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) 5 | Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) 6 | Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | */ 26 | 27 | #if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #ifdef RT_USING_HEAP 34 | #define malloc rt_malloc 35 | #define free rt_free 36 | #endif 37 | 38 | /* 39 | * Always check for bound when decompressing. 40 | * Generally it is best to leave it defined. 41 | */ 42 | #define FASTLZ_SAFE 43 | 44 | /* 45 | * Give hints to the compiler for branch prediction optimization. 46 | */ 47 | #if defined(__GNUC__) && (__GNUC__ > 2) 48 | #define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1)) 49 | #define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0)) 50 | #else 51 | #define FASTLZ_EXPECT_CONDITIONAL(c) (c) 52 | #define FASTLZ_UNEXPECT_CONDITIONAL(c) (c) 53 | #endif 54 | 55 | /* 56 | * Use inlined functions for supported systems. 57 | */ 58 | #if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C) 59 | #define FASTLZ_INLINE inline 60 | #elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__) 61 | #define FASTLZ_INLINE __inline 62 | #else 63 | #define FASTLZ_INLINE 64 | #endif 65 | 66 | /* 67 | * Prevent accessing more than 8-bit at once, except on x86 architectures. 68 | */ 69 | #if !defined(FASTLZ_STRICT_ALIGN) 70 | #define FASTLZ_STRICT_ALIGN 71 | #if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */ 72 | #undef FASTLZ_STRICT_ALIGN 73 | #elif defined(__i486__) || defined(__i586__) || defined(__i686__) /* GNU C */ 74 | #undef FASTLZ_STRICT_ALIGN 75 | #elif defined(_M_IX86) /* Intel, MSVC */ 76 | #undef FASTLZ_STRICT_ALIGN 77 | #elif defined(__386) 78 | #undef FASTLZ_STRICT_ALIGN 79 | #elif defined(_X86_) /* MinGW */ 80 | #undef FASTLZ_STRICT_ALIGN 81 | #elif defined(__I86__) /* Digital Mars */ 82 | #undef FASTLZ_STRICT_ALIGN 83 | #endif 84 | #endif 85 | 86 | /* 87 | * FIXME: use preprocessor magic to set this on different platforms! 88 | */ 89 | typedef unsigned char flzuint8; 90 | typedef unsigned short flzuint16; 91 | typedef unsigned int flzuint32; 92 | 93 | /* prototypes */ 94 | int fastlz_compress(const void* input, int length, void* output); 95 | int fastlz_compress_level(int level, const void* input, int length, void* output); 96 | int fastlz_decompress(const void* input, int length, void* output, int maxout); 97 | 98 | #define MAX_COPY 32 99 | #define MAX_LEN 264 /* 256 + 8 */ 100 | #define MAX_DISTANCE 8192 101 | 102 | #if !defined(FASTLZ_STRICT_ALIGN) 103 | #define FASTLZ_READU16(p) *((const flzuint16*)(p)) 104 | #else 105 | #define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8) 106 | #endif 107 | 108 | #define HASH_LOG 13 109 | #define HASH_SIZE (1<< HASH_LOG) 110 | #define HASH_MASK (HASH_SIZE-1) 111 | #define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; } 112 | 113 | #undef FASTLZ_LEVEL 114 | #define FASTLZ_LEVEL 1 115 | 116 | #undef FASTLZ_COMPRESSOR 117 | #undef FASTLZ_DECOMPRESSOR 118 | #define FASTLZ_COMPRESSOR fastlz1_compress 119 | #define FASTLZ_DECOMPRESSOR fastlz1_decompress 120 | static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output); 121 | static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout); 122 | #include "fastlz.c" 123 | 124 | #undef FASTLZ_LEVEL 125 | #define FASTLZ_LEVEL 2 126 | 127 | #undef MAX_DISTANCE 128 | #define MAX_DISTANCE 8191 129 | #define MAX_FARDISTANCE (65535+MAX_DISTANCE-1) 130 | 131 | #undef FASTLZ_COMPRESSOR 132 | #undef FASTLZ_DECOMPRESSOR 133 | #define FASTLZ_COMPRESSOR fastlz2_compress 134 | #define FASTLZ_DECOMPRESSOR fastlz2_decompress 135 | static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output); 136 | static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout); 137 | #include "fastlz.c" 138 | 139 | int fastlz_compress(const void* input, int length, void* output) 140 | { 141 | /* for short block, choose fastlz1 */ 142 | if(length < 65536) 143 | return fastlz1_compress(input, length, output); 144 | 145 | /* else... */ 146 | return fastlz2_compress(input, length, output); 147 | } 148 | 149 | int fastlz_decompress(const void* input, int length, void* output, int maxout) 150 | { 151 | /* magic identifier for compression level */ 152 | int level = ((*(const flzuint8*)input) >> 5) + 1; 153 | 154 | if(level == 1) 155 | return fastlz1_decompress(input, length, output, maxout); 156 | if(level == 2) 157 | return fastlz2_decompress(input, length, output, maxout); 158 | 159 | /* unknown level, trigger error */ 160 | return 0; 161 | } 162 | 163 | int fastlz_compress_level(int level, const void* input, int length, void* output) 164 | { 165 | if(level == 1) 166 | return fastlz1_compress(input, length, output); 167 | if(level == 2) 168 | return fastlz2_compress(input, length, output); 169 | 170 | return 0; 171 | } 172 | 173 | #else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */ 174 | 175 | static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output) 176 | { 177 | const flzuint8* ip = (const flzuint8*) input; 178 | const flzuint8* ip_bound = ip + length - 2; 179 | const flzuint8* ip_limit = ip + length - 12; 180 | flzuint8* op = (flzuint8*) output; 181 | 182 | const flzuint8** hslot; 183 | flzuint32 hval; 184 | 185 | flzuint32 copy; 186 | 187 | const flzuint8** htab = (const flzuint8**)malloc(sizeof(flzuint8*) * HASH_SIZE); 188 | if (htab == NULL) 189 | { 190 | return -1; 191 | } 192 | 193 | /* sanity check */ 194 | if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4)) 195 | { 196 | if(length) 197 | { 198 | /* create literal copy only */ 199 | *op++ = length-1; 200 | ip_bound++; 201 | while(ip <= ip_bound) 202 | *op++ = *ip++; 203 | free(htab); 204 | return length+1; 205 | } 206 | else 207 | { 208 | free(htab); 209 | return 0; 210 | } 211 | } 212 | 213 | /* initializes hash table */ 214 | for (hslot = htab; hslot < htab + HASH_SIZE; hslot++) 215 | *hslot = ip; 216 | 217 | /* we start with literal copy */ 218 | copy = 2; 219 | *op++ = MAX_COPY-1; 220 | *op++ = *ip++; 221 | *op++ = *ip++; 222 | 223 | /* main loop */ 224 | while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit)) 225 | { 226 | const flzuint8* ref; 227 | flzuint32 distance; 228 | 229 | /* minimum match length */ 230 | flzuint32 len = 3; 231 | 232 | /* comparison starting-point */ 233 | const flzuint8* anchor = ip; 234 | 235 | /* check for a run */ 236 | #if FASTLZ_LEVEL==2 237 | if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1)) 238 | { 239 | distance = 1; 240 | ip += 3; 241 | ref = anchor - 1 + 3; 242 | goto match; 243 | } 244 | #endif 245 | 246 | /* find potential match */ 247 | HASH_FUNCTION(hval,ip); 248 | hslot = htab + hval; 249 | ref = htab[hval]; 250 | 251 | /* calculate distance to the match */ 252 | distance = anchor - ref; 253 | 254 | /* update hash table */ 255 | *hslot = anchor; 256 | 257 | /* is this a match? check the first 3 bytes */ 258 | if(distance==0 || 259 | #if FASTLZ_LEVEL==1 260 | (distance >= MAX_DISTANCE) || 261 | #else 262 | (distance >= MAX_FARDISTANCE) || 263 | #endif 264 | *ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++) 265 | goto literal; 266 | 267 | #if FASTLZ_LEVEL==2 268 | /* far, needs at least 5-byte match */ 269 | if(distance >= MAX_DISTANCE) 270 | { 271 | if(*ip++ != *ref++ || *ip++!= *ref++) 272 | goto literal; 273 | len += 2; 274 | } 275 | 276 | match: 277 | #endif 278 | 279 | /* last matched byte */ 280 | ip = anchor + len; 281 | 282 | /* distance is biased */ 283 | distance--; 284 | 285 | if(!distance) 286 | { 287 | /* zero distance means a run */ 288 | flzuint8 x = ip[-1]; 289 | while(ip < ip_bound) 290 | if(*ref++ != x) break; else ip++; 291 | } 292 | else 293 | for(;;) 294 | { 295 | /* safe because the outer check against ip limit */ 296 | if(*ref++ != *ip++) break; 297 | if(*ref++ != *ip++) break; 298 | if(*ref++ != *ip++) break; 299 | if(*ref++ != *ip++) break; 300 | if(*ref++ != *ip++) break; 301 | if(*ref++ != *ip++) break; 302 | if(*ref++ != *ip++) break; 303 | if(*ref++ != *ip++) break; 304 | while(ip < ip_bound) 305 | if(*ref++ != *ip++) break; 306 | break; 307 | } 308 | 309 | /* if we have copied something, adjust the copy count */ 310 | if(copy) 311 | /* copy is biased, '0' means 1 byte copy */ 312 | *(op-copy-1) = copy-1; 313 | else 314 | /* back, to overwrite the copy count */ 315 | op--; 316 | 317 | /* reset literal counter */ 318 | copy = 0; 319 | 320 | /* length is biased, '1' means a match of 3 bytes */ 321 | ip -= 3; 322 | len = ip - anchor; 323 | 324 | /* encode the match */ 325 | #if FASTLZ_LEVEL==2 326 | if(distance < MAX_DISTANCE) 327 | { 328 | if(len < 7) 329 | { 330 | *op++ = (len << 5) + (distance >> 8); 331 | *op++ = (distance & 255); 332 | } 333 | else 334 | { 335 | *op++ = (7 << 5) + (distance >> 8); 336 | for(len-=7; len >= 255; len-= 255) 337 | *op++ = 255; 338 | *op++ = len; 339 | *op++ = (distance & 255); 340 | } 341 | } 342 | else 343 | { 344 | /* far away, but not yet in the another galaxy... */ 345 | if(len < 7) 346 | { 347 | distance -= MAX_DISTANCE; 348 | *op++ = (len << 5) + 31; 349 | *op++ = 255; 350 | *op++ = distance >> 8; 351 | *op++ = distance & 255; 352 | } 353 | else 354 | { 355 | distance -= MAX_DISTANCE; 356 | *op++ = (7 << 5) + 31; 357 | for(len-=7; len >= 255; len-= 255) 358 | *op++ = 255; 359 | *op++ = len; 360 | *op++ = 255; 361 | *op++ = distance >> 8; 362 | *op++ = distance & 255; 363 | } 364 | } 365 | #else 366 | 367 | if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2)) 368 | while(len > MAX_LEN-2) 369 | { 370 | *op++ = (7 << 5) + (distance >> 8); 371 | *op++ = MAX_LEN - 2 - 7 -2; 372 | *op++ = (distance & 255); 373 | len -= MAX_LEN-2; 374 | } 375 | 376 | if(len < 7) 377 | { 378 | *op++ = (len << 5) + (distance >> 8); 379 | *op++ = (distance & 255); 380 | } 381 | else 382 | { 383 | *op++ = (7 << 5) + (distance >> 8); 384 | *op++ = len - 7; 385 | *op++ = (distance & 255); 386 | } 387 | #endif 388 | 389 | /* update the hash at match boundary */ 390 | HASH_FUNCTION(hval,ip); 391 | htab[hval] = ip++; 392 | HASH_FUNCTION(hval,ip); 393 | htab[hval] = ip++; 394 | 395 | /* assuming literal copy */ 396 | *op++ = MAX_COPY-1; 397 | 398 | continue; 399 | 400 | literal: 401 | *op++ = *anchor++; 402 | ip = anchor; 403 | copy++; 404 | if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY)) 405 | { 406 | copy = 0; 407 | *op++ = MAX_COPY-1; 408 | } 409 | } 410 | 411 | /* left-over as literal copy */ 412 | ip_bound++; 413 | while(ip <= ip_bound) 414 | { 415 | *op++ = *ip++; 416 | copy++; 417 | if(copy == MAX_COPY) 418 | { 419 | copy = 0; 420 | *op++ = MAX_COPY-1; 421 | } 422 | } 423 | 424 | /* if we have copied something, adjust the copy length */ 425 | if(copy) 426 | *(op-copy-1) = copy-1; 427 | else 428 | op--; 429 | 430 | #if FASTLZ_LEVEL==2 431 | /* marker for fastlz2 */ 432 | *(flzuint8*)output |= (1 << 5); 433 | #endif 434 | 435 | free(htab); 436 | 437 | return op - (flzuint8*)output; 438 | } 439 | 440 | static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout) 441 | { 442 | const flzuint8* ip = (const flzuint8*) input; 443 | const flzuint8* ip_limit = ip + length; 444 | flzuint8* op = (flzuint8*) output; 445 | flzuint8* op_limit = op + maxout; 446 | flzuint32 ctrl = (*ip++) & 31; 447 | int loop = 1; 448 | 449 | do 450 | { 451 | const flzuint8* ref = op; 452 | flzuint32 len = ctrl >> 5; 453 | flzuint32 ofs = (ctrl & 31) << 8; 454 | 455 | if(ctrl >= 32) 456 | { 457 | #if FASTLZ_LEVEL==2 458 | flzuint8 code; 459 | #endif 460 | len--; 461 | ref -= ofs; 462 | if (len == 7-1) 463 | #if FASTLZ_LEVEL==1 464 | len += *ip++; 465 | ref -= *ip++; 466 | #else 467 | do 468 | { 469 | code = *ip++; 470 | len += code; 471 | } while (code==255); 472 | code = *ip++; 473 | ref -= code; 474 | 475 | /* match from 16-bit distance */ 476 | if(FASTLZ_UNEXPECT_CONDITIONAL(code==255)) 477 | if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8))) 478 | { 479 | ofs = (*ip++) << 8; 480 | ofs += *ip++; 481 | ref = op - ofs - MAX_DISTANCE; 482 | } 483 | #endif 484 | 485 | #ifdef FASTLZ_SAFE 486 | if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit)) 487 | return 0; 488 | 489 | if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output)) 490 | return 0; 491 | #endif 492 | 493 | if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit)) 494 | ctrl = *ip++; 495 | else 496 | loop = 0; 497 | 498 | if(ref == op) 499 | { 500 | /* optimize copy for a run */ 501 | flzuint8 b = ref[-1]; 502 | *op++ = b; 503 | *op++ = b; 504 | *op++ = b; 505 | for(; len; --len) 506 | *op++ = b; 507 | } 508 | else 509 | { 510 | #if !defined(FASTLZ_STRICT_ALIGN) 511 | const flzuint16* p; 512 | flzuint16* q; 513 | #endif 514 | /* copy from reference */ 515 | ref--; 516 | *op++ = *ref++; 517 | *op++ = *ref++; 518 | *op++ = *ref++; 519 | 520 | #if !defined(FASTLZ_STRICT_ALIGN) 521 | /* copy a byte, so that now it's word aligned */ 522 | if(len & 1) 523 | { 524 | *op++ = *ref++; 525 | len--; 526 | } 527 | 528 | /* copy 16-bit at once */ 529 | q = (flzuint16*) op; 530 | op += len; 531 | p = (const flzuint16*) ref; 532 | for(len>>=1; len > 4; len-=4) 533 | { 534 | *q++ = *p++; 535 | *q++ = *p++; 536 | *q++ = *p++; 537 | *q++ = *p++; 538 | } 539 | for(; len; --len) 540 | *q++ = *p++; 541 | #else 542 | for(; len; --len) 543 | *op++ = *ref++; 544 | #endif 545 | } 546 | } 547 | else 548 | { 549 | ctrl++; 550 | #ifdef FASTLZ_SAFE 551 | if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit)) 552 | return 0; 553 | if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit)) 554 | return 0; 555 | #endif 556 | 557 | *op++ = *ip++; 558 | for(--ctrl; ctrl; ctrl--) 559 | *op++ = *ip++; 560 | 561 | loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit); 562 | if(loop) 563 | ctrl = *ip++; 564 | } 565 | } 566 | while(FASTLZ_EXPECT_CONDITIONAL(loop)); 567 | 568 | return op - (flzuint8*)output; 569 | } 570 | 571 | #endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */ 572 | -------------------------------------------------------------------------------- /fastlz.h: -------------------------------------------------------------------------------- 1 | /* 2 | FastLZ - lightning-fast lossless compression library 3 | 4 | Copyright (C) 2007 Ariya Hidayat (ariya@kde.org) 5 | Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) 6 | Copyright (C) 2005 Ariya Hidayat (ariya@kde.org) 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | */ 26 | 27 | #ifndef FASTLZ_H 28 | #define FASTLZ_H 29 | 30 | #define FASTLZ_VERSION 0x000100 31 | 32 | #define FASTLZ_VERSION_MAJOR 0 33 | #define FASTLZ_VERSION_MINOR 0 34 | #define FASTLZ_VERSION_REVISION 0 35 | 36 | #define FASTLZ_VERSION_STRING "0.1.0" 37 | 38 | /* The output buffer must be at least 5% larger than the input buffer and can not be smaller than 66 bytes. */ 39 | #define FASTLZ_BUFFER_PADDING(x) (66 + (x) * 5 / 100) 40 | 41 | #if defined (__cplusplus) 42 | extern "C" { 43 | #endif 44 | 45 | /** 46 | Compress a block of data in the input buffer and returns the size of 47 | compressed block. The size of input buffer is specified by length. The 48 | minimum input buffer size is 16. 49 | 50 | The output buffer must be at least 5% larger than the input buffer 51 | and can not be smaller than 66 bytes. 52 | 53 | If the input is not compressible, the return value might be larger than 54 | length (input buffer size). 55 | 56 | The input buffer and the output buffer can not overlap. 57 | */ 58 | 59 | int fastlz_compress(const void* input, int length, void* output); 60 | 61 | /** 62 | Decompress a block of compressed data and returns the size of the 63 | decompressed block. If error occurs, e.g. the compressed data is 64 | corrupted or the output buffer is not large enough, then 0 (zero) 65 | will be returned instead. 66 | 67 | The input buffer and the output buffer can not overlap. 68 | 69 | Decompression is memory safe and guaranteed not to write the output buffer 70 | more than what is specified in maxout. 71 | */ 72 | 73 | int fastlz_decompress(const void* input, int length, void* output, int maxout); 74 | 75 | /** 76 | Compress a block of data in the input buffer and returns the size of 77 | compressed block. The size of input buffer is specified by length. The 78 | minimum input buffer size is 16. 79 | 80 | The output buffer must be at least 5% larger than the input buffer 81 | and can not be smaller than 66 bytes. 82 | 83 | If the input is not compressible, the return value might be larger than 84 | length (input buffer size). 85 | 86 | The input buffer and the output buffer can not overlap. 87 | 88 | Compression level can be specified in parameter level. At the moment, 89 | only level 1 and level 2 are supported. 90 | Level 1 is the fastest compression and generally useful for short data. 91 | Level 2 is slightly slower but it gives better compression ratio. 92 | 93 | Note that the compressed data, regardless of the level, can always be 94 | decompressed using the function fastlz_decompress above. 95 | */ 96 | 97 | int fastlz_compress_level(int level, const void* input, int length, void* output); 98 | 99 | #if defined (__cplusplus) 100 | } 101 | #endif 102 | 103 | #endif /* FASTLZ_H */ 104 | -------------------------------------------------------------------------------- /fastlz_sample.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File : fastlz_sample.c 3 | * this example is a very simple test program for the fastlz library, 4 | * using non-stream compress and decompress. If you want to use stream compress, 5 | * you need at least 100K of ROM for history buffer(not recommend), or you can custom 6 | * header to storage the compress block size, and carry out stream compress by non-stream. 7 | * 8 | * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team 9 | * 10 | * This program is free software; you can redistribute it and/or modify 11 | * it under the terms of the GNU General Public License as published by 12 | * the Free Software Foundation; either version 2 of the License, or 13 | * (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU General Public License along 21 | * with this program; if not, write to the Free Software Foundation, Inc., 22 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 23 | * 24 | * Change Logs: 25 | * Date Author Notes 26 | * 2018-02-05 chenyong first version 27 | * 2018-02-11 Murphy Adapted fastlz 28 | */ 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | #include 37 | 38 | #include "fastlz.h" 39 | 40 | #define malloc rt_malloc 41 | #define free rt_free 42 | 43 | #define BLOCK_HEADER_SIZE 4 44 | 45 | #define COMPRESS_BUFFER_SIZE 4096 46 | #define DCOMPRESS_BUFFER_SIZE 4096 47 | 48 | /* The output buffer must be at least 5% larger than the input buffer and can not be smaller than 66 bytes */ 49 | #define BUFFER_PADDING FASTLZ_BUFFER_PADDING(COMPRESS_BUFFER_SIZE) 50 | 51 | /* compress level: 1 or 2 */ 52 | #define FASTLZ_COMPRESS_LEVEL FASTLZ_SAMPLE_COMPRESSION_LEVEL 53 | 54 | static int fastlz_compress_file(int fd_in, int fd_out) 55 | { 56 | /* Start to compress file */ 57 | rt_uint8_t *cmprs_buffer = RT_NULL, *buffer = RT_NULL; 58 | rt_uint8_t buffer_hdr[BLOCK_HEADER_SIZE] = { 0 }; 59 | int cmprs_size = 0, block_size = 0, totle_cmprs_size = 0; 60 | size_t file_size = 0, i = 0; 61 | int ret = 0; 62 | 63 | file_size = lseek(fd_in, 0, SEEK_END); 64 | lseek(fd_in, 0, SEEK_SET); 65 | 66 | cmprs_buffer = (rt_uint8_t *) malloc(COMPRESS_BUFFER_SIZE + BUFFER_PADDING); 67 | buffer = (rt_uint8_t *) malloc(COMPRESS_BUFFER_SIZE); 68 | if (!cmprs_buffer || !buffer) 69 | { 70 | rt_kprintf("[fastlz] No memory for cmprs_buffer or buffer!\n"); 71 | ret = -1; 72 | goto _exit; 73 | } 74 | 75 | rt_kprintf("[fastlz]compress start : "); 76 | for (i = 0; i < file_size; i += COMPRESS_BUFFER_SIZE) 77 | { 78 | if ((file_size - i) < COMPRESS_BUFFER_SIZE) 79 | { 80 | block_size = file_size - i; 81 | } 82 | else 83 | { 84 | block_size = COMPRESS_BUFFER_SIZE; 85 | } 86 | 87 | memset(buffer, 0x00, COMPRESS_BUFFER_SIZE); 88 | memset(cmprs_buffer, 0x00, COMPRESS_BUFFER_SIZE + BUFFER_PADDING); 89 | 90 | read(fd_in, buffer, block_size); 91 | 92 | /* The destination buffer must be at least size + 400 bytes large because incompressible data may increase in size. */ 93 | cmprs_size = fastlz_compress_level(FASTLZ_COMPRESS_LEVEL, buffer, block_size, (char *) cmprs_buffer); 94 | if (cmprs_size < 0) 95 | { 96 | ret = -1; 97 | goto _exit; 98 | } 99 | 100 | /* Store compress block size to the block header (4 byte). */ 101 | buffer_hdr[3] = cmprs_size % (1 << 8); 102 | buffer_hdr[2] = (cmprs_size % (1 << 16)) / (1 << 8); 103 | buffer_hdr[1] = (cmprs_size % (1 << 24)) / (1 << 16); 104 | buffer_hdr[0] = cmprs_size / (1 << 24); 105 | 106 | write(fd_out, buffer_hdr, BLOCK_HEADER_SIZE); 107 | write(fd_out, cmprs_buffer, cmprs_size); 108 | 109 | totle_cmprs_size += cmprs_size + BLOCK_HEADER_SIZE; 110 | rt_kprintf(">"); 111 | } 112 | 113 | rt_kprintf("\n"); 114 | rt_kprintf("[fastlz]compressed %d bytes into %d bytes , compression ratio is %d%!\n", file_size, totle_cmprs_size, 115 | (totle_cmprs_size * 100) / file_size); 116 | _exit: 117 | if (cmprs_buffer) 118 | { 119 | free(cmprs_buffer); 120 | } 121 | 122 | if (buffer) 123 | { 124 | free(buffer); 125 | } 126 | 127 | return ret; 128 | } 129 | 130 | 131 | static int fastlz_decompress_file(int fd_in, int fd_out) 132 | { 133 | /* Start to decompress file */ 134 | rt_uint8_t *dcmprs_buffer = RT_NULL, *buffer = RT_NULL; 135 | rt_uint8_t buffer_hdr[BLOCK_HEADER_SIZE] = { 0 }; 136 | size_t dcmprs_size = 0, block_size = 0, total_dcmprs_size = 0; 137 | size_t file_size = 0, i = 0; 138 | int ret = 0; 139 | 140 | file_size = lseek(fd_in, 0, SEEK_END); 141 | lseek(fd_in, 0, SEEK_SET); 142 | 143 | if (file_size <= BLOCK_HEADER_SIZE) 144 | { 145 | rt_kprintf("[fastlz] decomprssion file size : %d error!\n", file_size); 146 | ret = -1; 147 | goto _dcmprs_exit; 148 | } 149 | 150 | dcmprs_buffer = (rt_uint8_t *) malloc(DCOMPRESS_BUFFER_SIZE); 151 | buffer = (rt_uint8_t *) malloc(DCOMPRESS_BUFFER_SIZE + BUFFER_PADDING); 152 | if (!dcmprs_buffer || !buffer) 153 | { 154 | rt_kprintf("[fastlz] No memory for dcmprs_buffer or buffer!\n"); 155 | ret = -1; 156 | goto _dcmprs_exit; 157 | } 158 | 159 | rt_kprintf("[fastlz]decompress start : "); 160 | for (i = 0; i < file_size; i += BLOCK_HEADER_SIZE + block_size) 161 | { 162 | /* Get the decompress block size from the block header. */ 163 | read(fd_in, buffer_hdr, BLOCK_HEADER_SIZE); 164 | block_size = buffer_hdr[0] * (1 << 24) + buffer_hdr[1] * (1 << 16) + buffer_hdr[2] * (1 << 8) + buffer_hdr[3]; 165 | 166 | memset(buffer, 0x00, COMPRESS_BUFFER_SIZE + BUFFER_PADDING); 167 | memset(dcmprs_buffer, 0x00, DCOMPRESS_BUFFER_SIZE); 168 | 169 | read(fd_in, buffer, block_size); 170 | 171 | dcmprs_size = fastlz_decompress((const void *) buffer, block_size, dcmprs_buffer, DCOMPRESS_BUFFER_SIZE); 172 | write(fd_out, dcmprs_buffer, dcmprs_size); 173 | 174 | total_dcmprs_size += dcmprs_size; 175 | rt_kprintf(">"); 176 | } 177 | rt_kprintf("\n"); 178 | rt_kprintf("decompressed %d bytes into %d bytes !\n", file_size, total_dcmprs_size); 179 | 180 | _dcmprs_exit: 181 | if (dcmprs_buffer) 182 | { 183 | free(dcmprs_buffer); 184 | } 185 | 186 | if(buffer) 187 | { 188 | free(buffer); 189 | } 190 | 191 | return ret; 192 | } 193 | 194 | int fastlz_test(int argc, char ** argv) 195 | { 196 | int fd_in = -1 , fd_out = -1; 197 | int ret = 0; 198 | 199 | if (argc != 4) 200 | { 201 | rt_kprintf("Usage:\n"); 202 | rt_kprintf("fastlz_test -c [file] [cmprs_file] -compress \"file\" to \"cmprs_file\" \n"); 203 | rt_kprintf("fastlz_test -d [cmprs_file] [dcmprs_file] -dcompress \"cmprs_file\" to \"dcmprs_file\" \n"); 204 | 205 | ret = -1; 206 | goto _exit; 207 | } 208 | 209 | fd_in = open(argv[2], O_RDONLY, 0); 210 | if (fd_in < 0) 211 | { 212 | rt_kprintf("[fastlz] open the input file : %s error!\n", argv[2]); 213 | ret = -1; 214 | goto _exit; 215 | } 216 | 217 | fd_out = open(argv[3], O_WRONLY | O_CREAT | O_TRUNC, 0); 218 | if (fd_out < 0) 219 | { 220 | rt_kprintf("[fastlz] open the output file : %s error!\n", argv[3]); 221 | ret = -1; 222 | goto _exit; 223 | } 224 | 225 | if(memcmp("-c", argv[1], strlen(argv[1])) == 0) 226 | { 227 | 228 | if(fastlz_compress_file(fd_in, fd_out) < 0) 229 | { 230 | rt_kprintf("[fastlz] fastlz compress file error!\n"); 231 | } 232 | 233 | } 234 | else if(memcmp("-d", argv[1], strlen(argv[1])) == 0) 235 | { 236 | 237 | if(fastlz_decompress_file(fd_in, fd_out) < 0) 238 | { 239 | rt_kprintf("[fastlz] fastlz decompress file error!\n"); 240 | } 241 | } 242 | else 243 | { 244 | rt_kprintf("Usage:\n"); 245 | rt_kprintf("fastlz_test -c [file] [cmprs_file] -compress \"file\" to \"cmprs_file\" \n"); 246 | rt_kprintf("fastlz_test -d [cmprs_file] [dcmprs_file] -dcompress \"cmprs_file\" to \"dcmprs_file\" \n"); 247 | 248 | ret = -1; 249 | goto _exit; 250 | } 251 | 252 | _exit: 253 | if(fd_in >= 0) 254 | { 255 | close(fd_in); 256 | } 257 | 258 | if(fd_out >= 0) 259 | { 260 | close(fd_out); 261 | } 262 | 263 | return ret; 264 | } 265 | 266 | #ifdef RT_USING_FINSH 267 | #ifdef FINSH_USING_MSH 268 | 269 | #include 270 | 271 | MSH_CMD_EXPORT(fastlz_test, fastlz compress and decompress test); 272 | #endif 273 | #endif 274 | --------------------------------------------------------------------------------