1370b324cSopenharmony_ci# third_party_lzma 2370b324cSopenharmony_ci 3370b324cSopenharmony_ci## 介绍 4370b324cSopenharmony_ci 5370b324cSopenharmony_ciLZMA 是著名的LZ77压缩算法的改良版本, 最大化地提高了压缩比率, 保持了高压缩速度和解压缩时较低的内存需要。 6370b324cSopenharmony_ci 7370b324cSopenharmony_ciLZMA2 基于 LZMA, 在压缩过程中提供了更好的多线程支持, 和其他改进优化。 8370b324cSopenharmony_ci 9370b324cSopenharmony_ci7z 是一种数据压缩和文件档案的格式, 是7zip软件的主要文件格式 [**7z官网**](https://www.7-zip.org)。 10370b324cSopenharmony_ci7z 格式支持不同的压缩方式: LZMA, LZMA2 和其他, 同时也支持基于AES-256的对称加密。 11370b324cSopenharmony_ci 12370b324cSopenharmony_ciXZ 是一种使用LZMA2数据压缩的文件格式, XZ格式带有额外的特性: SHA/CRC数据校验, 用于提升压缩比率的filters, 拆分blocks和streams。 13370b324cSopenharmony_ci 14370b324cSopenharmony_ci## 软件架构 15370b324cSopenharmony_ci 16370b324cSopenharmony_ci软件架构说明 17370b324cSopenharmony_ci 18370b324cSopenharmony_ci| format/algorithm | C | C++ | C# | Java | 19370b324cSopenharmony_ci| :------ | :---------| :----- | :----- | :----- | 20370b324cSopenharmony_ci| LZMA 压缩和解压缩 | ✓ | ✓ | ✓ | ✓ | 21370b324cSopenharmony_ci| LZMA2 压缩和解压缩 | ✓ | ✓ | | | 22370b324cSopenharmony_ci| XZ 压缩和解压缩 | ✓ | ✓ | | | 23370b324cSopenharmony_ci| 7Z 解压缩 | ✓ | ✓ | | | 24370b324cSopenharmony_ci| 7Z 压缩 | | ✓ | | | 25370b324cSopenharmony_ci| small SFXs for installers (7z decompression) | ✓ | | | | 26370b324cSopenharmony_ci| SFXs and SFXs for installers (7z decompression) | | ✓ | | | 27370b324cSopenharmony_ci 28370b324cSopenharmony_ci--- 29370b324cSopenharmony_ci 30370b324cSopenharmony_ci```bash 31370b324cSopenharmony_ci/third_party/lzma 32370b324cSopenharmony_ci├── Asm # asm files (optimized code for CRC calculation and Intel-AES encryption) 33370b324cSopenharmony_ci│ ├── arm 34370b324cSopenharmony_ci│ ├── arm64 35370b324cSopenharmony_ci│ └── x86 36370b324cSopenharmony_ci├── C # C files (compression / decompression and other) 37370b324cSopenharmony_ci│ └── Util 38370b324cSopenharmony_ci│ ├── 7z # 7z decoder program (decoding 7z files) 39370b324cSopenharmony_ci│ ├── Lzma # LZMA program (file->file LZMA encoder/decoder) 40370b324cSopenharmony_ci│ ├── LzmaLib # LZMA library (.DLL for Windows) 41370b324cSopenharmony_ci│ └── SfxSetup # small SFX module for installers 42370b324cSopenharmony_ci├── CPP 43370b324cSopenharmony_ci│ ├── Common # common files for C++ projects 44370b324cSopenharmony_ci│ ├── Windows # common files for Windows related code 45370b324cSopenharmony_ci│ └── 7zip # files related to 7-Zip 46370b324cSopenharmony_ci│ ├── Archive # files related to archiving 47370b324cSopenharmony_ci│ │ ├── Common # common files for archive handling 48370b324cSopenharmony_ci│ │ └── 7z # 7z C++ Encoder/Decoder 49370b324cSopenharmony_ci│ ├── Bundles # Modules that are bundles of other modules (files) 50370b324cSopenharmony_ci│ │ ├── Alone7z # 7zr.exe: Standalone 7-Zip console program (reduced version) 51370b324cSopenharmony_ci│ │ ├── Format7zExtractR # 7zxr.dll: Reduced version of 7z DLL: extracting from 7z/LZMA/BCJ/BCJ2. 52370b324cSopenharmony_ci│ │ ├── Format7zR # 7zr.dll: Reduced version of 7z DLL: extracting/compressing to 7z/LZMA/BCJ/BCJ2 53370b324cSopenharmony_ci│ │ ├── LzmaCon # lzma.exe: LZMA compression/decompression 54370b324cSopenharmony_ci│ │ ├── LzmaSpec # example code for LZMA Specification 55370b324cSopenharmony_ci│ │ ├── SFXCon # 7zCon.sfx: Console 7z SFX module 56370b324cSopenharmony_ci│ │ ├── SFXSetup # 7zS.sfx: 7z SFX module for installers 57370b324cSopenharmony_ci│ │ └── SFXWin # 7z.sfx: GUI 7z SFX module 58370b324cSopenharmony_ci│ ├── Common # common files for 7-Zip 59370b324cSopenharmony_ci│ ├── Compress # files for compression/decompression 60370b324cSopenharmony_ci│ ├── Crypto # files for encryption / decompression 61370b324cSopenharmony_ci│ └── UI # User Interface files 62370b324cSopenharmony_ci│ ├── Client7z # Test application for 7za.dll, 7zr.dll, 7zxr.dll 63370b324cSopenharmony_ci│ ├── Common # Common UI files 64370b324cSopenharmony_ci│ ├── Console # Code for console program (7z.exe) 65370b324cSopenharmony_ci│ ├── Explorer # Some code from 7-Zip Shell extension 66370b324cSopenharmony_ci│ ├── FileManager # Some GUI code from 7-Zip File Manager 67370b324cSopenharmony_ci│ └── GUI # Some GUI code from 7-Zip 68370b324cSopenharmony_ci├── CS 69370b324cSopenharmony_ci│ └── 7zip 70370b324cSopenharmony_ci│ ├── Common # some common files for 7-Zip 71370b324cSopenharmony_ci│ └── Compress # files related to compression/decompression 72370b324cSopenharmony_ci│ ├── LZ # files related to LZ (Lempel-Ziv) compression algorithm 73370b324cSopenharmony_ci│ ├── LZMA # LZMA compression/decompression 74370b324cSopenharmony_ci│ ├── LzmaAlone # file->file LZMA compression/decompression 75370b324cSopenharmony_ci│ └── RangeCoder # Range Coder (special code of compression/decompression) 76370b324cSopenharmony_ci├── DOC 77370b324cSopenharmony_ci│ ├── 7zC.txt # 7z ANSI-C Decoder description 78370b324cSopenharmony_ci│ ├── 7zFormat.txt # 7z Format description 79370b324cSopenharmony_ci│ ├── installer.txt # information about 7-Zip for installers 80370b324cSopenharmony_ci│ ├── lzma-history.txt # history of LZMA SDK 81370b324cSopenharmony_ci│ ├── lzma-sdk.txt # LZMA SDK description 82370b324cSopenharmony_ci│ ├── lzma-specification.txt # Specification of LZMA 83370b324cSopenharmony_ci│ ├── lzma.txt # LZMA compression description 84370b324cSopenharmony_ci│ └── Methods.txt # Compression method IDs for .7z 85370b324cSopenharmony_ci└── Java 86370b324cSopenharmony_ci └── SevenZip 87370b324cSopenharmony_ci └── Compression # files related to compression/decompression 88370b324cSopenharmony_ci ├── LZ # files related to LZ (Lempel-Ziv) compression algorithm 89370b324cSopenharmony_ci ├── LZMA # LZMA compression/decompression 90370b324cSopenharmony_ci └── RangeCoder # Range Coder (special code of compression/decompression) 91370b324cSopenharmony_ci``` 92370b324cSopenharmony_ci 93370b324cSopenharmony_ci## 证书 94370b324cSopenharmony_ci 95370b324cSopenharmony_ciLZMA SDK is written and placed in the public domain by Igor Pavlov. 96370b324cSopenharmony_ci 97370b324cSopenharmony_ciSome code in LZMA SDK is based on public domain code from another developers: 98370b324cSopenharmony_ci 99370b324cSopenharmony_ci 1) PPMd var.H (2001): Dmitry Shkarin 100370b324cSopenharmony_ci 101370b324cSopenharmony_ci 2) SHA-256: Wei Dai (Crypto++ library) 102370b324cSopenharmony_ci 103370b324cSopenharmony_ciAnyone is free to copy, modify, publish, use, compile, sell, or distribute the 104370b324cSopenharmony_cioriginal LZMA SDK code, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. 105370b324cSopenharmony_ci 106370b324cSopenharmony_ciLZMA SDK code is compatible with open source licenses, for example, you can include it to GNU GPL or GNU LGPL code. 107370b324cSopenharmony_ci 108370b324cSopenharmony_ci## 编译构建 109370b324cSopenharmony_ci 110370b324cSopenharmony_ci### ***UNIX/Linux*** 111370b324cSopenharmony_ci 112370b324cSopenharmony_ci使用gcc和clang编译7-zip有多种选项,同时7-zip代码中两部分重要的代码: C和汇编。如果与汇编代码一起编译版本,会得到更快的7-zip二进制。7-zip的汇编代码遵循不同平台的语法。 113370b324cSopenharmony_ci 114370b324cSopenharmony_ci#### *arm64* 115370b324cSopenharmony_ci 116370b324cSopenharmony_cigcc和clang arm64版本支持arm64汇编代码语法。 117370b324cSopenharmony_ci 118370b324cSopenharmony_ci#### *x86 and x86_64(AMD64)* 119370b324cSopenharmony_ci 120370b324cSopenharmony_ciAsmc Macro Assembler 和 JWasm 在Linux 系统上都支持MASM语法,但JWasm 不支持一些7-zip中使用的cpu指令。 121370b324cSopenharmony_ci如果你想编译更快的7zip,必须在Linux上安装Asmc Macro Assembler [https://github.com/nidud/asmc](https://github.com/nidud/asmc) 122370b324cSopenharmony_ci 123370b324cSopenharmony_ci### ***构建命令*** 124370b324cSopenharmony_ci 125370b324cSopenharmony_ci目录中有两个主要文件用于编译 126370b324cSopenharmony_ci makefile - 使用nmake命令编译Windows版本的7zip 127370b324cSopenharmony_ci makefile.gcc - 使用make命令编译Linux/macOs版本的7zip 128370b324cSopenharmony_ci 129370b324cSopenharmony_ci首先切换到包含 `makefile.gcc`的目录下: 130370b324cSopenharmony_ci 131370b324cSopenharmony_ci```bash 132370b324cSopenharmony_ci cd CPP/7zip/Bundles/Alone7z 133370b324cSopenharmony_ci``` 134370b324cSopenharmony_ci 135370b324cSopenharmony_ci```bash 136370b324cSopenharmony_ci make -j -f makefile.gcc 137370b324cSopenharmony_ci``` 138370b324cSopenharmony_ci 139370b324cSopenharmony_ci另外在"CPP/7zip/"目录下的"*.mak"文件也可以与优化的代码同时编译,并且带有优化选项。比如: 140370b324cSopenharmony_ci 141370b324cSopenharmony_ci```bash 142370b324cSopenharmony_ci cd CPP/7zip/Bundles/Alone7z 143370b324cSopenharmony_ci make -j -f ../../cmpl_gcc.mak 144370b324cSopenharmony_ci``` 145370b324cSopenharmony_ci 146370b324cSopenharmony_ci## **接口使用说明** 147370b324cSopenharmony_ci 148370b324cSopenharmony_ci这部分描述了C语言实现的LZMA编码和解码函数 149370b324cSopenharmony_ci 150370b324cSopenharmony_ci注意: 你也可以阅读参考 LZMA Specification (lzma-specification.txt from LZMA SDK) 151370b324cSopenharmony_ci 152370b324cSopenharmony_ci你也可以查看使用LZMA编码和解码的案例: 153370b324cSopenharmony_ci ***C/Util/Lzma/LzmaUtil.c*** 154370b324cSopenharmony_ci 155370b324cSopenharmony_ci### ***LZMA 压缩的文件格式*** 156370b324cSopenharmony_ci 157370b324cSopenharmony_ci```bash 158370b324cSopenharmony_ciOffset Size Description 159370b324cSopenharmony_ci 0 1 Special LZMA properties (lc,lp, pb in encoded form) 160370b324cSopenharmony_ci 1 4 Dictionary size (little endian) 161370b324cSopenharmony_ci 5 8 Uncompressed size (little endian). -1 means unknown size 162370b324cSopenharmony_ci 13 Compressed data 163370b324cSopenharmony_ci``` 164370b324cSopenharmony_ci 165370b324cSopenharmony_ciANSI-C(American National Standards Institue) LZMA Decoder 166370b324cSopenharmony_ci请注意ANSI-C的接口在LZMA SDK 4.58版本发生了变更,如果你想使用旧的接口,你可以从sourceforge.net 网站下载之前的LZMA SDK版本。 167370b324cSopenharmony_ci 168370b324cSopenharmony_ci使用 ANSI-C LZMA Decoder需要使用到以下文件: 169370b324cSopenharmony_ci 170370b324cSopenharmony_ci```bash 171370b324cSopenharmony_ci LzmaDec.h 172370b324cSopenharmony_ci LzmaDec.c 173370b324cSopenharmony_ci 7zTypes.h 174370b324cSopenharmony_ci Precomp.h 175370b324cSopenharmony_ci Compiler.h 176370b324cSopenharmony_ci``` 177370b324cSopenharmony_ci 178370b324cSopenharmony_ci参考案例: C/Util/Lzma/LzmaUtil.c 179370b324cSopenharmony_ci 180370b324cSopenharmony_ciLZMA decoding的内存要求 181370b324cSopenharmony_ci 182370b324cSopenharmony_ci1. LZMA decoding函数局部变量的栈内存不超过200-400字节 183370b324cSopenharmony_ci 184370b324cSopenharmony_ci2. LZMA Decoder使用字典缓冲区和内部state结构 185370b324cSopenharmony_ci 186370b324cSopenharmony_ci3. 内部state结构size消耗state_size = (4 + (1.5 << (lc + lp))) KB by default (lc=3, lp=0), state_size = 16 KB. 187370b324cSopenharmony_ci 188370b324cSopenharmony_ci### ***如何解压缩*** 189370b324cSopenharmony_ci 190370b324cSopenharmony_ciLZMA Decoder (ANSI-C version) 支持以下两种接口: 191370b324cSopenharmony_ci 192370b324cSopenharmony_ci**1)** 单次调用: LzmaDecode 193370b324cSopenharmony_ci 194370b324cSopenharmony_ci**2)** 多次调用:LzmaDec_DecodeToBuf(类似于zlib接口) 195370b324cSopenharmony_ci 196370b324cSopenharmony_ci**你必须自己定义内存分配器:** 197370b324cSopenharmony_ci 198370b324cSopenharmony_ciExample: 199370b324cSopenharmony_ci 200370b324cSopenharmony_ci```c 201370b324cSopenharmony_civoid *SzAlloc(void *p, size_t size) { p = p; return malloc(size); } 202370b324cSopenharmony_civoid SzFree(void *p, void *address) { p = p; free(address); } 203370b324cSopenharmony_ciISzAlloc alloc = { SzAlloc, SzFree }; 204370b324cSopenharmony_ci``` 205370b324cSopenharmony_ci 206370b324cSopenharmony_ciYou can use p = p; operator to disable compiler warnings. 207370b324cSopenharmony_ci 208370b324cSopenharmony_ci#### ***单次调用*** 209370b324cSopenharmony_ci 210370b324cSopenharmony_ci1. 使用场景: RAM->RAM decompressing 211370b324cSopenharmony_ci2. 编译文件: LzmaDec.h + LzmaDec.c + 7zTypes.h 212370b324cSopenharmony_ci3. 编译宏: 不需要 213370b324cSopenharmony_ci4. 内存需要: 214370b324cSopenharmony_ci 215370b324cSopenharmony_ci- Input buffer: compressed size 216370b324cSopenharmony_ci- Output buffer: uncompressed size 217370b324cSopenharmony_ci- LZMA Internal Structures: state_size (16 KB for default settings) 218370b324cSopenharmony_ci 219370b324cSopenharmony_ci**Interface:** 220370b324cSopenharmony_ci 221370b324cSopenharmony_ci```c 222370b324cSopenharmony_ci int LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 223370b324cSopenharmony_ci const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode, 224370b324cSopenharmony_ci ELzmaStatus *status, ISzAlloc *alloc); 225370b324cSopenharmony_ci In: 226370b324cSopenharmony_ci dest - output data 227370b324cSopenharmony_ci destLen - output data size 228370b324cSopenharmony_ci src - input data 229370b324cSopenharmony_ci srcLen - input data size 230370b324cSopenharmony_ci propData - LZMA properties (5 bytes) 231370b324cSopenharmony_ci propSize - size of propData buffer (5 bytes) 232370b324cSopenharmony_ci finishMode - It has meaning only if the decoding reaches output limit (*destLen). 233370b324cSopenharmony_ci LZMA_FINISH_ANY - Decode just destLen bytes. 234370b324cSopenharmony_ci LZMA_FINISH_END - Stream must be finished after (*destLen). 235370b324cSopenharmony_ci You can use LZMA_FINISH_END, when you know that 236370b324cSopenharmony_ci current output buffer covers last bytes of stream. 237370b324cSopenharmony_ci alloc - Memory allocator. 238370b324cSopenharmony_ci 239370b324cSopenharmony_ci Out: 240370b324cSopenharmony_ci destLen - processed output size 241370b324cSopenharmony_ci srcLen - processed input size 242370b324cSopenharmony_ci 243370b324cSopenharmony_ci Output: 244370b324cSopenharmony_ci SZ_OK 245370b324cSopenharmony_ci status: 246370b324cSopenharmony_ci LZMA_STATUS_FINISHED_WITH_MARK 247370b324cSopenharmony_ci LZMA_STATUS_NOT_FINISHED 248370b324cSopenharmony_ci LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK 249370b324cSopenharmony_ci SZ_ERROR_DATA - Data error 250370b324cSopenharmony_ci SZ_ERROR_MEM - Memory allocation error 251370b324cSopenharmony_ci SZ_ERROR_UNSUPPORTED - Unsupported properties 252370b324cSopenharmony_ci SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). 253370b324cSopenharmony_ci``` 254370b324cSopenharmony_ci 255370b324cSopenharmony_ci如果LZMA decoder 在输出缓冲区上限前到达并看到了end_marker, 返回OK,同时输出的destLen的值会比输出缓冲区的上限小。 256370b324cSopenharmony_ci 257370b324cSopenharmony_ci你可以在完全解压缩后使用多重检查数据的完整性: 258370b324cSopenharmony_ci 259370b324cSopenharmony_ci 1. 检查返回值和status变量 260370b324cSopenharmony_ci 2. 如果你已知未压缩的数据大小,检查 output(destLen) = uncompressedSize 261370b324cSopenharmony_ci 3. 如果你已知压缩后的数据大小,检查 output(srcLen) = compressedSize 262370b324cSopenharmony_ci 263370b324cSopenharmony_ci#### ***根据状态多次调用 (类似于zlib接口)*** 264370b324cSopenharmony_ci 265370b324cSopenharmony_ci1. 使用场景: file->file decompressing 266370b324cSopenharmony_ci2. 编译文件: LzmaDec.h + LzmaDec.c + 7zTypes.h 267370b324cSopenharmony_ci3. 内存要求: 268370b324cSopenharmony_ci 269370b324cSopenharmony_ci- Buffer for input stream: any size (for example, 16 KB) 270370b324cSopenharmony_ci- Buffer for output stream: any size (for example, 16 KB) 271370b324cSopenharmony_ci- LZMA Internal Structures: state_size (16 KB for default settings) 272370b324cSopenharmony_ci- LZMA dictionary (字典大小编码在LZMA properties header中) 273370b324cSopenharmony_ci 274370b324cSopenharmony_ci使用流程: 275370b324cSopenharmony_ci 276370b324cSopenharmony_ci**1)** 读取 LZMA properties (5 bytes) and uncompressed size (8 bytes, 小端序) 到 header: 277370b324cSopenharmony_ci 278370b324cSopenharmony_ci```c 279370b324cSopenharmony_ci unsigned char header[LZMA_PROPS_SIZE + 8]; 280370b324cSopenharmony_ci ReadFile(inFile, header, sizeof(header) 281370b324cSopenharmony_ci``` 282370b324cSopenharmony_ci 283370b324cSopenharmony_ci**2)** 使用"LZMA properties"分配创建 CLzmaDec(state + dictionary) 284370b324cSopenharmony_ci 285370b324cSopenharmony_ci```c 286370b324cSopenharmony_ci CLzmaDec state; 287370b324cSopenharmony_ci LzmaDec_Constr(&state); 288370b324cSopenharmony_ci res = LzmaDec_Allocate(&state, header, LZMA_PROPS_SIZE, &g_Alloc); 289370b324cSopenharmony_ci if (res != SZ_OK) 290370b324cSopenharmony_ci return res; 291370b324cSopenharmony_ci``` 292370b324cSopenharmony_ci 293370b324cSopenharmony_ci**3)** 初始化LzmaDec,在循环中调用LzmaDec_DecodeToBuf 294370b324cSopenharmony_ci 295370b324cSopenharmony_ci```c 296370b324cSopenharmony_ci LzmaDec_Init(&state); 297370b324cSopenharmony_ci for (;;) 298370b324cSopenharmony_ci { 299370b324cSopenharmony_ci ... 300370b324cSopenharmony_ci int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, 301370b324cSopenharmony_ci const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode); 302370b324cSopenharmony_ci ... 303370b324cSopenharmony_ci } 304370b324cSopenharmony_ci``` 305370b324cSopenharmony_ci 306370b324cSopenharmony_ci**4)** 释放所有分配的结构 307370b324cSopenharmony_ci 308370b324cSopenharmony_ci```c 309370b324cSopenharmony_ci LzmaDec_Free(&state, &g_Alloc); 310370b324cSopenharmony_ci``` 311370b324cSopenharmony_ci 312370b324cSopenharmony_ciLook example code: 313370b324cSopenharmony_ci C/Util/Lzma/LzmaUtil.c 314370b324cSopenharmony_ci 315370b324cSopenharmony_ci### ***如何压缩数据*** 316370b324cSopenharmony_ci 317370b324cSopenharmony_ci1 编译文件: 318370b324cSopenharmony_ci 319370b324cSopenharmony_ci```bash 320370b324cSopenharmony_ci 7zTypes.h 321370b324cSopenharmony_ci Threads.h 322370b324cSopenharmony_ci LzmaEnc.h 323370b324cSopenharmony_ci LzmaEnc.c 324370b324cSopenharmony_ci LzFind.h 325370b324cSopenharmony_ci LzFind.c 326370b324cSopenharmony_ci LzFindMt.h 327370b324cSopenharmony_ci LzFindMt.c 328370b324cSopenharmony_ci LzHash.h 329370b324cSopenharmony_ci``` 330370b324cSopenharmony_ci 331370b324cSopenharmony_ci2 内存需要: 332370b324cSopenharmony_ci 333370b324cSopenharmony_ci- (dictSize * 11.5 + 6 MB) + state_size 334370b324cSopenharmony_ci 335370b324cSopenharmony_ciLzma Encoder 可使用两种内存分配器: 336370b324cSopenharmony_ci 337370b324cSopenharmony_ci- alloc - for small arrays. 338370b324cSopenharmony_ci- allocBig - for big arrays. 339370b324cSopenharmony_ci 340370b324cSopenharmony_ci例如,你可以在allocBig分配器中使用大RAM页(2 MB)来获得更快的压缩速度。需要注意的是Windows对于大RAM页的实现较差。alloc和allocBig也可以使用相同的分配器。 341370b324cSopenharmony_ci 342370b324cSopenharmony_ci#### ***带有回调的单次压缩*** 343370b324cSopenharmony_ci 344370b324cSopenharmony_ciLook example code: 345370b324cSopenharmony_ci C/Util/Lzma/LzmaUtil.c 346370b324cSopenharmony_ci 347370b324cSopenharmony_ci使用场景: file->file compressing 348370b324cSopenharmony_ci 349370b324cSopenharmony_ci**1)** 你必须实现接口的回调函数 350370b324cSopenharmony_ci 351370b324cSopenharmony_ci```c 352370b324cSopenharmony_ciISeqInStream 353370b324cSopenharmony_ciISeqOutStream 354370b324cSopenharmony_ciICompressProgress 355370b324cSopenharmony_ciISzAlloc 356370b324cSopenharmony_ci 357370b324cSopenharmony_cistatic void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } 358370b324cSopenharmony_cistatic void SzFree(void *p, void *address) { p = p; MyFree(address); } 359370b324cSopenharmony_cistatic ISzAlloc g_Alloc = { SzAlloc, SzFree }; 360370b324cSopenharmony_ci 361370b324cSopenharmony_ci CFileSeqInStream inStream; 362370b324cSopenharmony_ci CFileSeqOutStream outStream; 363370b324cSopenharmony_ci 364370b324cSopenharmony_ci inStream.funcTable.Read = MyRead; 365370b324cSopenharmony_ci inStream.file = inFile; 366370b324cSopenharmony_ci outStream.funcTable.Write = MyWrite; 367370b324cSopenharmony_ci outStream.file = outFile; 368370b324cSopenharmony_ci``` 369370b324cSopenharmony_ci 370370b324cSopenharmony_ci**2)** 创建CLzmaEncHandle对象 371370b324cSopenharmony_ci 372370b324cSopenharmony_ci```c 373370b324cSopenharmony_ci CLzmaEncHandle enc; 374370b324cSopenharmony_ci 375370b324cSopenharmony_ci enc = LzmaEnc_Create(&g_Alloc); 376370b324cSopenharmony_ci if (enc == 0) 377370b324cSopenharmony_ci return SZ_ERROR_MEM; 378370b324cSopenharmony_ci``` 379370b324cSopenharmony_ci 380370b324cSopenharmony_ci**3)** 初始化CLzmaEncProps属性 381370b324cSopenharmony_ci 382370b324cSopenharmony_ci```c 383370b324cSopenharmony_ci LzmaEncProps_Init(&props); 384370b324cSopenharmony_ci``` 385370b324cSopenharmony_ci 386370b324cSopenharmony_ci之后你可以改变这个结构里的一些属性 387370b324cSopenharmony_ci 388370b324cSopenharmony_ci**4)** 把上一个步骤设置的属性设置给LZMA Encoder 389370b324cSopenharmony_ci 390370b324cSopenharmony_ci```c 391370b324cSopenharmony_ci res = LzmaEnc_SetProps(enc, &props); 392370b324cSopenharmony_ci``` 393370b324cSopenharmony_ci 394370b324cSopenharmony_ci**5)** 将编码的属性写入header 395370b324cSopenharmony_ci 396370b324cSopenharmony_ci```c 397370b324cSopenharmony_ci Byte header[LZMA_PROPS_SIZE + 8]; 398370b324cSopenharmony_ci size_t headerSize = LZMA_PROPS_SIZE; 399370b324cSopenharmony_ci UInt64 fileSize; 400370b324cSopenharmony_ci int i; 401370b324cSopenharmony_ci 402370b324cSopenharmony_ci res = LzmaEnc_WriteProperties(enc, header, &headerSize); 403370b324cSopenharmony_ci fileSize = MyGetFileLength(inFile); 404370b324cSopenharmony_ci for (i = 0; i < 8; i++) 405370b324cSopenharmony_ci header[headerSize++] = (Byte)(fileSize >> (8 * i)); 406370b324cSopenharmony_ci MyWriteFileAndCheck(outFile, header, headerSize) 407370b324cSopenharmony_ci``` 408370b324cSopenharmony_ci 409370b324cSopenharmony_ci**6)** 调用编码函数 410370b324cSopenharmony_ci 411370b324cSopenharmony_ci```c 412370b324cSopenharmony_ci res = LzmaEnc_Encode(enc, &outStream.funcTable, &inStream.funcTable, 413370b324cSopenharmony_ci NULL, &g_Alloc, &g_Alloc); 414370b324cSopenharmony_ci``` 415370b324cSopenharmony_ci 416370b324cSopenharmony_ci**7)** 删除LZMA Encoder对象 417370b324cSopenharmony_ci 418370b324cSopenharmony_ci```c 419370b324cSopenharmony_ci LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc); 420370b324cSopenharmony_ci``` 421370b324cSopenharmony_ci 422370b324cSopenharmony_ci如果回调函数返回某些错误码,LzmaEnc_Encode 也会返回该错误码或者返回类似于SZ_ERROR_READ, SZ_ERROR_WRITE or SZ_ERROR_PROGRESS。 423370b324cSopenharmony_ci 424370b324cSopenharmony_ci--- 425370b324cSopenharmony_ci 426370b324cSopenharmony_ci#### ***单次调用 RAM->RAM 压缩*** 427370b324cSopenharmony_ci 428370b324cSopenharmony_ci单次调用,RAM->RAM 压缩与设置回调的方式压缩类似, 但你需要提供指向buffers的指针而不是指向回调函数的指针。 429370b324cSopenharmony_ci 430370b324cSopenharmony_ci```c 431370b324cSopenharmony_ciSRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, 432370b324cSopenharmony_ci const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, 433370b324cSopenharmony_ci ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); 434370b324cSopenharmony_ciReturn code: 435370b324cSopenharmony_ci SZ_OK - OK 436370b324cSopenharmony_ci SZ_ERROR_MEM - Memory allocation error 437370b324cSopenharmony_ci SZ_ERROR_PARAM - Incorrect paramater 438370b324cSopenharmony_ci SZ_ERROR_OUTPUT_EOF - output buffer overflow 439370b324cSopenharmony_ci SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) 440370b324cSopenharmony_ci``` 441370b324cSopenharmony_ci 442370b324cSopenharmony_ci宏 443370b324cSopenharmony_ci 444370b324cSopenharmony_ci```c 445370b324cSopenharmony_ci_LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code. 446370b324cSopenharmony_ci_LZMA_PROB32 - It can increase the speed on some 32-bit CPUs, but memory usage for 447370b324cSopenharmony_ci - some structures will be doubled in that case. 448370b324cSopenharmony_ci_LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is 32-bit. 449370b324cSopenharmony_ci_LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type. 450370b324cSopenharmony_ci_7ZIP_PPMD_SUPPPORT - Define it if you don't want to support PPMD method in AMSI-C .7z decoder. 451370b324cSopenharmony_ci``` 452370b324cSopenharmony_ci 453370b324cSopenharmony_ciC++版本的 LZMA Encoder/Decoder 454370b324cSopenharmony_ci 455370b324cSopenharmony_ciC++版本的 LZMA 代码使用COM-LIKE接口。如果你想使用,可以了解下COM(Component Object Model)/OLE(Object Linking and Embedding)/DDE(Dynamic Data Exchange)的基础。 456370b324cSopenharmony_ci 457370b324cSopenharmony_ciC++版本的 LZMA 代码部门仅仅只是将ANSI-C代码包装了. 458370b324cSopenharmony_ci 459370b324cSopenharmony_ci注意: 460370b324cSopenharmony_ci如果你使用7zip目录下的C++代码,你必须检查你正确地使用new 运算符 461370b324cSopenharmony_ciMSVC 6.0 编译7-zip时,不会抛出 new 运算符的异常。所以7zip在 CPP\Common\NewHandler.cpp 重新定义了new operator 462370b324cSopenharmony_ci 463370b324cSopenharmony_ci```cpp 464370b324cSopenharmony_cioperator new(size_t size) 465370b324cSopenharmony_ci{ 466370b324cSopenharmony_ci void *p = ::malloc(size); 467370b324cSopenharmony_ci if (p == 0) 468370b324cSopenharmony_ci throw CNewException(); 469370b324cSopenharmony_ci return p; 470370b324cSopenharmony_ci} 471370b324cSopenharmony_ci``` 472370b324cSopenharmony_ci 473370b324cSopenharmony_ci如果你使用的MSCV版本支持new运算符的异常抛出,你在编译7zip时可以忽略"NewHandler.cpp"。 474370b324cSopenharmony_ci所以使用标准的异常。实际上7zip的部分代码捕获的任何异常都会转换为HRESULT码。如果你调用7zip的COM interface 就不需要捕获CNewException. 475370b324cSopenharmony_ci 476370b324cSopenharmony_ci### ***接口案例:*** 477370b324cSopenharmony_ci 478370b324cSopenharmony_ciLook example code : C/Util/Lzma/LzmaUtil.c 479370b324cSopenharmony_ci 480370b324cSopenharmony_ci```bash 481370b324cSopenharmony_ci cd C/Util/Lzma 482370b324cSopenharmony_ci make -j -f makefile.gcc 483370b324cSopenharmony_ci output: ./_o/7lzma 484370b324cSopenharmony_ci``` 485370b324cSopenharmony_ci 486370b324cSopenharmony_ci```bash 487370b324cSopenharmony_ci LZMA-C 22.01 (x64) : Igor Pavlov : Public domain : 2022-07-15 488370b324cSopenharmony_ci 489370b324cSopenharmony_ci Usage: lzma <e|d> inputFile outputFile 490370b324cSopenharmony_ci e: encode file 491370b324cSopenharmony_ci d: decode file 492370b324cSopenharmony_ci``` 493370b324cSopenharmony_ci 494370b324cSopenharmony_ci## 参与贡献 495370b324cSopenharmony_ci 496370b324cSopenharmony_ci[https://sourceforge.net/p/sevenzip/_list/tickets](https://sourceforge.net/p/sevenzip/_list/tickets) 497370b324cSopenharmony_ci 498370b324cSopenharmony_ci## 相关仓 499370b324cSopenharmony_ci 500370b324cSopenharmony_ci[**developtools\hiperf**](https://gitee.com/openharmony/developtools_hiperf) 501