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_ci443370b324cSopenharmony_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