参考文档 / ZLIB × LEAN
trees.c.lean
此页源文件快照 ·
d4c02498f628ca78 · 对应提交的原文 ↗本页保留 Lean 源码及行号。点击行号可定位语句,点击 import 中的模块名可查看依赖。
1import ZlibF.Runtime.Alloc
2import ZlibF.Runtime.Tables
3
4/-!
5# trees.c — faithful translation (draft)
6
7Source: `zlib/trees.c` and `zlib/trees.h`, default build (LP64; `ZLIB_DEBUG`, `GEN_TREES_H`, `LIT_MEM`,
8`NO_INIT_GLOBAL_POINTERS`, `FORCE_STATIC`, `FORCE_STORED` undefined; `STDC` defined, so the tables come from
9`trees.h`). Translated statement by statement. Macros are expanded in source order: `put_byte`, `put_short`,
10`send_bits`, `send_code`, `pqremove`, `smaller`, `d_code`.
11
12Conventions of this file:
13
14* `deflate_state *s` is `DeflateStatePtr`. A scalar field is read with `rd s` (a load of the whole record) and
15 written with `md s` (a load, a record update and a store). An array field decays to a pointer: `pLtree s`
16 (`s->dyn_ltree`), `pDtree`, `pBltree`, `pHeap`, `pDepth`, `pBlCount`.
17* `int` is `Int32` with checked arithmetic (`iadd`, `isub`, `shl1`, ...): an overflow is `Fault.ub`.
18 `unsigned`, `ush`, `uch`, `ulg` wrap.
19* `Assert` and `Trace*` are compiled out (no `ZLIB_DEBUG`); `tr_static_init` is an empty function.
20* The static tables of `trees.h` and `trees.c` are `*_tab` constants below, installed in the heap by
21 `install_trees` (they are `Statics` fields; a store through them is a fault).
22* `ct_data`: `Freq`/`Code` is `fc`, `Dad`/`Len` is `dl`.
23* Local `ush next_code[MAX_BITS+1]` of `gen_codes` is a Lean `Array UInt16`; its element 0 is never read
24 (`len == 0` is skipped) and an index outside it is a fault.
25-/
26
27namespace Zlib.Trees
28open C
29
30/-! ## Constants -/
31
32def MAX_BL_BITS : Int32 := 7
33def END_BLOCK : Int32 := 256
34def REP_3_6 : Int32 := 16
35def REPZ_3_10 : Int32 := 17
36def REPZ_11_138 : Int32 := 18
37
38/-- `extra_lbits[LENGTH_CODES]` (trees.c). -/
39def extra_lbits_tab : Array Int32 := #[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0]
40/-- `extra_dbits[D_CODES]` (trees.c). -/
41def extra_dbits_tab : Array Int32 := #[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]
42/-- `extra_blbits[BL_CODES]` (trees.c). -/
43def extra_blbits_tab : Array Int32 := #[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7]
44/-- `local const uch bl_order[BL_CODES]` (trees.c). -/
45def bl_order : Array UInt8 := #[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]
46
47/-! ## Tables of `trees.h` (verbatim) -/
48
49/-- `static_ltree`: `trees.h`, verbatim (288 entries; `fc` = `Code`, `dl` = `Len`). -/
50def static_ltree_tab : Array CtData := #[
51 ⟨12, 8⟩, ⟨140, 8⟩, ⟨76, 8⟩, ⟨204, 8⟩, ⟨44, 8⟩, ⟨172, 8⟩,
52 ⟨108, 8⟩, ⟨236, 8⟩, ⟨28, 8⟩, ⟨156, 8⟩, ⟨92, 8⟩, ⟨220, 8⟩,
53 ⟨60, 8⟩, ⟨188, 8⟩, ⟨124, 8⟩, ⟨252, 8⟩, ⟨2, 8⟩, ⟨130, 8⟩,
54 ⟨66, 8⟩, ⟨194, 8⟩, ⟨34, 8⟩, ⟨162, 8⟩, ⟨98, 8⟩, ⟨226, 8⟩,
55 ⟨18, 8⟩, ⟨146, 8⟩, ⟨82, 8⟩, ⟨210, 8⟩, ⟨50, 8⟩, ⟨178, 8⟩,
56 ⟨114, 8⟩, ⟨242, 8⟩, ⟨10, 8⟩, ⟨138, 8⟩, ⟨74, 8⟩, ⟨202, 8⟩,
57 ⟨42, 8⟩, ⟨170, 8⟩, ⟨106, 8⟩, ⟨234, 8⟩, ⟨26, 8⟩, ⟨154, 8⟩,
58 ⟨90, 8⟩, ⟨218, 8⟩, ⟨58, 8⟩, ⟨186, 8⟩, ⟨122, 8⟩, ⟨250, 8⟩,
59 ⟨6, 8⟩, ⟨134, 8⟩, ⟨70, 8⟩, ⟨198, 8⟩, ⟨38, 8⟩, ⟨166, 8⟩,
60 ⟨102, 8⟩, ⟨230, 8⟩, ⟨22, 8⟩, ⟨150, 8⟩, ⟨86, 8⟩, ⟨214, 8⟩,
61 ⟨54, 8⟩, ⟨182, 8⟩, ⟨118, 8⟩, ⟨246, 8⟩, ⟨14, 8⟩, ⟨142, 8⟩,
62 ⟨78, 8⟩, ⟨206, 8⟩, ⟨46, 8⟩, ⟨174, 8⟩, ⟨110, 8⟩, ⟨238, 8⟩,
63 ⟨30, 8⟩, ⟨158, 8⟩, ⟨94, 8⟩, ⟨222, 8⟩, ⟨62, 8⟩, ⟨190, 8⟩,
64 ⟨126, 8⟩, ⟨254, 8⟩, ⟨1, 8⟩, ⟨129, 8⟩, ⟨65, 8⟩, ⟨193, 8⟩,
65 ⟨33, 8⟩, ⟨161, 8⟩, ⟨97, 8⟩, ⟨225, 8⟩, ⟨17, 8⟩, ⟨145, 8⟩,
66 ⟨81, 8⟩, ⟨209, 8⟩, ⟨49, 8⟩, ⟨177, 8⟩, ⟨113, 8⟩, ⟨241, 8⟩,
67 ⟨9, 8⟩, ⟨137, 8⟩, ⟨73, 8⟩, ⟨201, 8⟩, ⟨41, 8⟩, ⟨169, 8⟩,
68 ⟨105, 8⟩, ⟨233, 8⟩, ⟨25, 8⟩, ⟨153, 8⟩, ⟨89, 8⟩, ⟨217, 8⟩,
69 ⟨57, 8⟩, ⟨185, 8⟩, ⟨121, 8⟩, ⟨249, 8⟩, ⟨5, 8⟩, ⟨133, 8⟩,
70 ⟨69, 8⟩, ⟨197, 8⟩, ⟨37, 8⟩, ⟨165, 8⟩, ⟨101, 8⟩, ⟨229, 8⟩,
71 ⟨21, 8⟩, ⟨149, 8⟩, ⟨85, 8⟩, ⟨213, 8⟩, ⟨53, 8⟩, ⟨181, 8⟩,
72 ⟨117, 8⟩, ⟨245, 8⟩, ⟨13, 8⟩, ⟨141, 8⟩, ⟨77, 8⟩, ⟨205, 8⟩,
73 ⟨45, 8⟩, ⟨173, 8⟩, ⟨109, 8⟩, ⟨237, 8⟩, ⟨29, 8⟩, ⟨157, 8⟩,
74 ⟨93, 8⟩, ⟨221, 8⟩, ⟨61, 8⟩, ⟨189, 8⟩, ⟨125, 8⟩, ⟨253, 8⟩,
75 ⟨19, 9⟩, ⟨275, 9⟩, ⟨147, 9⟩, ⟨403, 9⟩, ⟨83, 9⟩, ⟨339, 9⟩,
76 ⟨211, 9⟩, ⟨467, 9⟩, ⟨51, 9⟩, ⟨307, 9⟩, ⟨179, 9⟩, ⟨435, 9⟩,
77 ⟨115, 9⟩, ⟨371, 9⟩, ⟨243, 9⟩, ⟨499, 9⟩, ⟨11, 9⟩, ⟨267, 9⟩,
78 ⟨139, 9⟩, ⟨395, 9⟩, ⟨75, 9⟩, ⟨331, 9⟩, ⟨203, 9⟩, ⟨459, 9⟩,
79 ⟨43, 9⟩, ⟨299, 9⟩, ⟨171, 9⟩, ⟨427, 9⟩, ⟨107, 9⟩, ⟨363, 9⟩,
80 ⟨235, 9⟩, ⟨491, 9⟩, ⟨27, 9⟩, ⟨283, 9⟩, ⟨155, 9⟩, ⟨411, 9⟩,
81 ⟨91, 9⟩, ⟨347, 9⟩, ⟨219, 9⟩, ⟨475, 9⟩, ⟨59, 9⟩, ⟨315, 9⟩,
82 ⟨187, 9⟩, ⟨443, 9⟩, ⟨123, 9⟩, ⟨379, 9⟩, ⟨251, 9⟩, ⟨507, 9⟩,
83 ⟨7, 9⟩, ⟨263, 9⟩, ⟨135, 9⟩, ⟨391, 9⟩, ⟨71, 9⟩, ⟨327, 9⟩,
84 ⟨199, 9⟩, ⟨455, 9⟩, ⟨39, 9⟩, ⟨295, 9⟩, ⟨167, 9⟩, ⟨423, 9⟩,
85 ⟨103, 9⟩, ⟨359, 9⟩, ⟨231, 9⟩, ⟨487, 9⟩, ⟨23, 9⟩, ⟨279, 9⟩,
86 ⟨151, 9⟩, ⟨407, 9⟩, ⟨87, 9⟩, ⟨343, 9⟩, ⟨215, 9⟩, ⟨471, 9⟩,
87 ⟨55, 9⟩, ⟨311, 9⟩, ⟨183, 9⟩, ⟨439, 9⟩, ⟨119, 9⟩, ⟨375, 9⟩,
88 ⟨247, 9⟩, ⟨503, 9⟩, ⟨15, 9⟩, ⟨271, 9⟩, ⟨143, 9⟩, ⟨399, 9⟩,
89 ⟨79, 9⟩, ⟨335, 9⟩, ⟨207, 9⟩, ⟨463, 9⟩, ⟨47, 9⟩, ⟨303, 9⟩,
90 ⟨175, 9⟩, ⟨431, 9⟩, ⟨111, 9⟩, ⟨367, 9⟩, ⟨239, 9⟩, ⟨495, 9⟩,
91 ⟨31, 9⟩, ⟨287, 9⟩, ⟨159, 9⟩, ⟨415, 9⟩, ⟨95, 9⟩, ⟨351, 9⟩,
92 ⟨223, 9⟩, ⟨479, 9⟩, ⟨63, 9⟩, ⟨319, 9⟩, ⟨191, 9⟩, ⟨447, 9⟩,
93 ⟨127, 9⟩, ⟨383, 9⟩, ⟨255, 9⟩, ⟨511, 9⟩, ⟨0, 7⟩, ⟨64, 7⟩,
94 ⟨32, 7⟩, ⟨96, 7⟩, ⟨16, 7⟩, ⟨80, 7⟩, ⟨48, 7⟩, ⟨112, 7⟩,
95 ⟨8, 7⟩, ⟨72, 7⟩, ⟨40, 7⟩, ⟨104, 7⟩, ⟨24, 7⟩, ⟨88, 7⟩,
96 ⟨56, 7⟩, ⟨120, 7⟩, ⟨4, 7⟩, ⟨68, 7⟩, ⟨36, 7⟩, ⟨100, 7⟩,
97 ⟨20, 7⟩, ⟨84, 7⟩, ⟨52, 7⟩, ⟨116, 7⟩, ⟨3, 8⟩, ⟨131, 8⟩,
98 ⟨67, 8⟩, ⟨195, 8⟩, ⟨35, 8⟩, ⟨163, 8⟩, ⟨99, 8⟩, ⟨227, 8⟩
99]
100
101/-- `static_dtree`: `trees.h`, verbatim (30 entries; `fc` = `Code`, `dl` = `Len`). -/
102def static_dtree_tab : Array CtData := #[
103 ⟨0, 5⟩, ⟨16, 5⟩, ⟨8, 5⟩, ⟨24, 5⟩, ⟨4, 5⟩, ⟨20, 5⟩,
104 ⟨12, 5⟩, ⟨28, 5⟩, ⟨2, 5⟩, ⟨18, 5⟩, ⟨10, 5⟩, ⟨26, 5⟩,
105 ⟨6, 5⟩, ⟨22, 5⟩, ⟨14, 5⟩, ⟨30, 5⟩, ⟨1, 5⟩, ⟨17, 5⟩,
106 ⟨9, 5⟩, ⟨25, 5⟩, ⟨5, 5⟩, ⟨21, 5⟩, ⟨13, 5⟩, ⟨29, 5⟩,
107 ⟨3, 5⟩, ⟨19, 5⟩, ⟨11, 5⟩, ⟨27, 5⟩, ⟨7, 5⟩, ⟨23, 5⟩
108]
109
110/-- `_dist_code`: `trees.h`, verbatim (512 entries). -/
111def dist_code_tab : Array UInt8 := #[
112 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
113 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
114 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
115 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
116 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
117 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
118 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
119 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
120 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
121 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
122 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
123 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
124 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
125 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
126 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
127 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
128 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
129 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
130 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
131 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
132 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
133 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
134 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
135 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
136 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
137 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
138]
139
140/-- `_length_code`: `trees.h`, verbatim (256 entries). -/
141def length_code_tab : Array UInt8 := #[
142 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
143 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
144 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
145 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
146 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
147 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
148 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
149 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
150 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
151 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
152 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
153 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
154 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
155]
156
157/-- `base_length`: `trees.h`, verbatim (29 entries). -/
158def base_length_tab : Array Int32 := #[
159 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
160 64, 80, 96, 112, 128, 160, 192, 224, 0
161]
162
163/-- `base_dist`: `trees.h`, verbatim (30 entries). -/
164def base_dist_tab : Array Int32 := #[
165 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
166 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
167]
168
169/-- The static tables and descriptors of `trees.c`, installed in the `Statics` of a heap:
170`static_l_desc = {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}`,
171`static_d_desc = {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}`,
172`static_bl_desc = {NULL, extra_blbits, 0, BL_CODES, MAX_BL_BITS}`. -/
173def trees_statics (st : Statics) : Statics :=
174 { st with
175 dist_code := dist_code_tab
176 length_code := length_code_tab
177 base_dist := base_dist_tab
178 base_length := base_length_tab
179 static_dtree := static_dtree_tab
180 static_ltree := static_ltree_tab
181 extra_lbits := extra_lbits_tab
182 extra_dbits := extra_dbits_tab
183 extra_blbits := extra_blbits_tab
184 static_l_desc := { static_tree := .ref .st_static_ltree 0, extra_bits := .ref .st_extra_lbits 0,
185 extra_base := LITERALS + 1, elems := L_CODES, max_length := MAX_BITS }
186 static_d_desc := { static_tree := .ref .st_static_dtree 0, extra_bits := .ref .st_extra_dbits 0,
187 extra_base := 0, elems := D_CODES, max_length := MAX_BITS }
188 static_bl_desc := { static_tree := .null, extra_bits := .ref .st_extra_blbits 0,
189 extra_base := 0, elems := BL_CODES, max_length := MAX_BL_BITS } }
190
191/-- The heap with the static data of `trees.c` and `trees.h` in place. -/
192def install_trees (h : Heap) : Heap := { h with static := trees_statics h.static }
193
194/-! ## Helpers (not C functions): checked `int` arithmetic, record and array access -/
195
196/-- A checked `int` result. -/
197def ck (x : Int) : M Int32 :=
198 if -2147483648 ≤ x ∧ x ≤ 2147483647 then pure (Int32.ofInt x) else ub "signed integer overflow"
199def iadd (a b : Int32) : M Int32 := ck (a.toInt + b.toInt)
200def isub (a b : Int32) : M Int32 := ck (a.toInt - b.toInt)
201/-- `x << 1` for an `int`: undefined for a negative `x` or if the result does not fit. -/
202def shl1 (x : Int32) : M Int32 := if x.toInt < 0 then ub "left shift of a negative value" else ck (x.toInt * 2)
203/-- `ush` to `int`. -/
204def u16i (x : UInt16) : Int32 := Int32.ofInt x.toNat
205/-- `uch` to `int`. -/
206def u8i (x : UInt8) : Int32 := Int32.ofInt x.toNat
207/-- `int` to `unsigned` (modulo 2^32). -/
208def i2u (x : Int32) : UInt32 := UInt32.ofNat (x.toInt % 4294967296).toNat
209/-- `unsigned` to `int` (modulo 2^32, as gcc). -/
210def u2i (x : UInt32) : Int32 := Int32.ofInt (if x.toNat ≥ 2147483648 then (x.toNat : Int) - 4294967296 else x.toNat)
211/-- `int` to `unsigned long` (sign extension, modulo 2^64). -/
212def i2ul (x : Int32) : UInt64 := UInt64.ofNat (x.toInt % 18446744073709551616).toNat
213/-- `(ush)x` for an `int`. -/
214def i2us (x : Int32) : UInt16 := UInt16.ofNat (x.toInt % 65536).toNat
215
216/-- `for (init; cond; step) body` over the locals `σ`; `continue` is the end of `body`. -/
217def cfor {σ : Type} (cond : σ → M Bool) (step : σ → M σ) (body : σ → M σ) (s : σ) : M σ :=
218 cwhile (fun s => do pure (← cond s, s)) (fun s => do step (← body s)) s
219
220/-- `s` is a live deflate state; its block number. -/
221def sid (s : DeflateStatePtr) : M Nat := do
222 let _ ← ldDeflateState s
223 match s with
224 | some (.tab i) => pure i
225 | none => ub "null dereference (deflate_state)"
226
227/-- `s->f` for a scalar field: the whole record. -/
228def rd (s : DeflateStatePtr) : M DeflateState := ldDeflateState s
229/-- `s->f = v`, as a load, a record update and a store. -/
230def md (s : DeflateStatePtr) (f : DeflateState → DeflateState) : M Unit := do
231 stDeflateState s (f (← ldDeflateState s))
232
233/-- `s->dyn_ltree` -/
234def pLtree (s : DeflateStatePtr) : M CtDataPtr := do pure (.ref (.dstate_dyn_ltree (← sid s)) 0)
235/-- `s->dyn_dtree` -/
236def pDtree (s : DeflateStatePtr) : M CtDataPtr := do pure (.ref (.dstate_dyn_dtree (← sid s)) 0)
237/-- `s->bl_tree` -/
238def pBltree (s : DeflateStatePtr) : M CtDataPtr := do pure (.ref (.dstate_bl_tree (← sid s)) 0)
239/-- `s->heap` -/
240def pHeap (s : DeflateStatePtr) : M IPtr := do pure (.ref (.dstate_heap (← sid s)) 0)
241/-- `s->depth` -/
242def pDepth (s : DeflateStatePtr) : M BPtr := do pure (.ref (.dstate_depth (← sid s)) 0)
243/-- `s->bl_count` -/
244def pBlCount (s : DeflateStatePtr) : M WPtr := do pure (.ref (.dstate_bl_count (← sid s)) 0)
245/-- `&s->l_desc`, `&s->d_desc`, `&s->bl_desc` -/
246def pLdesc (s : DeflateStatePtr) : M TreeDescPtr := do pure (some (.in_dstate_l_desc (← sid s)))
247def pDdesc (s : DeflateStatePtr) : M TreeDescPtr := do pure (some (.in_dstate_d_desc (← sid s)))
248def pBldesc (s : DeflateStatePtr) : M TreeDescPtr := do pure (some (.in_dstate_bl_desc (← sid s)))
249
250/-- `p[i] = v` -/
251def setAt {R T : Type} [Space Heap R T] (p : Ptr R) (i : Int) (v : T) : M Unit := do
252 Ptr.store (← Ptr.add p i) v
253/-- `s->heap[i]` -/
254def heapAt (s : DeflateStatePtr) (i : Int32) : M Int32 := do Ptr.index (← pHeap s) i.toInt
255/-- `s->heap[i] = v` -/
256def heapSet (s : DeflateStatePtr) (i : Int32) (v : Int32) : M Unit := do setAt (← pHeap s) i.toInt v
257
258/-- `tree[i].Freq` / `.Code` -/
259def getFc (tree : CtDataPtr) (i : Int) : M UInt16 := do pure (← Ptr.index tree i).fc
260/-- `tree[i].Dad` / `.Len` -/
261def getDl (tree : CtDataPtr) (i : Int) : M UInt16 := do pure (← Ptr.index tree i).dl
262/-- `tree[i].Freq = v` -/
263def setFc (tree : CtDataPtr) (i : Int) (v : UInt16) : M Unit := do
264 let p ← Ptr.add tree i
265 let e ← Ptr.load p
266 Ptr.store p { e with fc := v }
267/-- `tree[i].Len = v` -/
268def setDl (tree : CtDataPtr) (i : Int) (v : UInt16) : M Unit := do
269 let p ← Ptr.add tree i
270 let e ← Ptr.load p
271 Ptr.store p { e with dl := v }
272
273/-- `bl_order[i]` (a static array; an index outside it is undefined). -/
274def blOrder (i : Int) : M UInt8 :=
275 if 0 ≤ i ∧ i < 19 then pure bl_order[i.toNat]! else ub "bl_order index outside its array"
276
277/-! ## Macros of `deflate.h` and `trees.c` -/
278
279/-- `put_byte(s, c)`: `{s->pending_buf[s->pending++] = (Bytef)(c);}` -/
280def put_byte (s : DeflateStatePtr) (c : UInt8) : M Unit := do
281 let d ← rd s
282 let p ← Ptr.add d.pending_buf (d.pending.toNat : Int)
283 store8 p c
284 md s fun d => { d with pending := d.pending + 1 }
285
286/-- `put_short(s, w)`: `{ put_byte(s, (uch)((w) & 0xff)); put_byte(s, (uch)((ush)(w) >> 8)); }` -/
287def put_short (s : DeflateStatePtr) (w : UInt16) : M Unit := do
288 put_byte s (w &&& 0xff).toUInt8
289 put_byte s (w >>> 8).toUInt8
290
291/-- `(ush)val << s->bi_valid` (an `int` shift: the count must be in `0..31` and the result must fit). -/
292def shlUs (val : Int32) (c : Int32) : M Nat :=
293 if c.toInt < 0 ∨ 31 < c.toInt then ub "invalid shift count"
294 else if (i2us val).toNat * 2 ^ c.toInt.toNat ≥ 2147483648 then ub "signed overflow in left shift"
295 else pure ((i2us val).toNat * 2 ^ c.toInt.toNat)
296
297/-- `(ush)val >> c` -/
298def shrUs (val : Int32) (c : Int32) : M UInt16 :=
299 if c.toInt < 0 ∨ 31 < c.toInt then ub "invalid shift count"
300 else pure (UInt16.ofNat ((i2us val).toNat >>> c.toInt.toNat))
301
302/-- `send_bits(s, value, length)` (the macro of `trees.c`, `Buf_size` = 16). -/
303def send_bits (s : DeflateStatePtr) (value : Int32) (length : Int32) : M Unit := do
304 -- int len = length;
305 let len := length
306 let d ← rd s
307 if d.bi_valid > (← isub Buf_size len) then
308 -- int val = (int)value;
309 let val := value
310 -- s->bi_buf |= (ush)val << s->bi_valid;
311 let sh ← shlUs val d.bi_valid
312 md s fun d => { d with bi_buf := UInt16.ofNat (d.bi_buf.toNat ||| sh) }
313 -- put_short(s, s->bi_buf);
314 put_short s (← rd s).bi_buf
315 -- s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);
316 let c ← isub Buf_size (← rd s).bi_valid
317 let r ← shrUs val c
318 md s fun d => { d with bi_buf := r }
319 -- s->bi_valid += len - Buf_size;
320 let t ← isub len Buf_size
321 let nv ← iadd (← rd s).bi_valid t
322 md s fun d => { d with bi_valid := nv }
323 else
324 -- s->bi_buf |= (ush)(value) << s->bi_valid;
325 let sh ← shlUs value d.bi_valid
326 md s fun d => { d with bi_buf := UInt16.ofNat (d.bi_buf.toNat ||| sh) }
327 -- s->bi_valid += len;
328 let nv ← iadd (← rd s).bi_valid len
329 md s fun d => { d with bi_valid := nv }
330
331/-- `send_code(s, c, tree)`: `send_bits(s, tree[c].Code, tree[c].Len)`. -/
332def send_code (s : DeflateStatePtr) (c : Int) (tree : CtDataPtr) : M Unit := do
333 let len := u16i (← getDl tree c)
334 let code := u16i (← getFc tree c)
335 send_bits s code len
336
337/-- `d_code(dist)`: `((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])`, `dist` unsigned. -/
338def d_code (dist : UInt32) : M UInt8 :=
339 if dist < 256 then Ptr.index (.ref .st_dist_code 0 : BPtr) (dist.toNat : Int)
340 else Ptr.index (.ref .st_dist_code 0 : BPtr) (((256 : UInt32) + (dist >>> 7)).toNat : Int)
341
342/-- `smaller(tree, n, m, depth)` -/
343def smaller (tree : CtDataPtr) (n m : Int32) (depth : BPtr) : M Bool := do
344 let fn ← getFc tree n.toInt
345 let fm ← getFc tree m.toInt
346 if fn < fm then return true
347 if fn == fm then
348 let dn ← Ptr.index depth n.toInt
349 let dm ← Ptr.index depth m.toInt
350 return decide (dn ≤ dm)
351 return false
352
353/-! ## Functions -/
354
355/-- `local unsigned bi_reverse(unsigned code, int len)` -/
356def bi_reverse (code : UInt32) (len : Int32) : M UInt32 := do
357 -- unsigned res = 0;
358 -- do { res |= code & 1; code >>= 1, res <<= 1; } while (--len > 0);
359 let (_, res, _) ← cdoWhile (σ := UInt32 × UInt32 × Int32)
360 (fun (code, res, len) => do
361 let res := res ||| (code &&& 1)
362 pure (code >>> 1, res <<< 1, len))
363 (fun (code, res, len) => do
364 let len ← isub len 1
365 pure (decide (len.toInt > 0), (code, res, len)))
366 (code, 0, len)
367 return res >>> 1
368
369/-- `local void bi_flush(deflate_state *s)` -/
370def bi_flush (s : DeflateStatePtr) : M Unit := do
371 let d ← rd s
372 if d.bi_valid == 16 then
373 put_short s (← rd s).bi_buf
374 md s fun d => { d with bi_buf := 0 }
375 md s fun d => { d with bi_valid := 0 }
376 else if d.bi_valid ≥ 8 then
377 put_byte s (← rd s).bi_buf.toUInt8
378 md s fun d => { d with bi_buf := d.bi_buf >>> 8 }
379 let nv ← isub (← rd s).bi_valid 8
380 md s fun d => { d with bi_valid := nv }
381
382/-- `local void bi_windup(deflate_state *s)` -/
383def bi_windup (s : DeflateStatePtr) : M Unit := do
384 let d ← rd s
385 if d.bi_valid > 8 then
386 put_short s (← rd s).bi_buf
387 else if d.bi_valid > 0 then
388 put_byte s (← rd s).bi_buf.toUInt8
389 -- s->bi_used = ((s->bi_valid - 1) & 7) + 1;
390 let t ← isub (← rd s).bi_valid 1
391 let u ← iadd (t &&& 7) 1
392 md s fun d => { d with bi_used := u }
393 md s fun d => { d with bi_buf := 0 }
394 md s fun d => { d with bi_valid := 0 }
395
396/-- `local void gen_codes(ct_data *tree, int max_code, ushf *bl_count)` -/
397def gen_codes (tree : CtDataPtr) (max_code : Int32) (bl_count : WPtr) : M Unit := do
398 -- ush next_code[MAX_BITS+1]; unsigned code = 0;
399 let next_code0 : Array UInt16 := Array.replicate 16 0
400 -- for (bits = 1; bits <= MAX_BITS; bits++) { code = (code + bl_count[bits - 1]) << 1; next_code[bits] = (ush)code; }
401 let (_, _, next_code) ← cfor (σ := Int32 × UInt32 × Array UInt16)
402 (fun (bits, _, _) => pure (decide (bits.toInt ≤ MAX_BITS.toInt)))
403 (fun (bits, code, nc) => do pure (← iadd bits 1, code, nc))
404 (fun (bits, code, nc) => do
405 let b ← Ptr.index bl_count (← isub bits 1).toInt
406 let code := (code + b.toUInt32) <<< 1
407 if bits.toInt < 0 ∨ nc.size ≤ bits.toInt.toNat then ub "next_code index outside its array"
408 pure (bits, code, nc.set! bits.toInt.toNat code.toUInt16))
409 (1, 0, next_code0)
410 -- for (n = 0; n <= max_code; n++) { int len = tree[n].Len; if (len == 0) continue;
411 -- tree[n].Code = (ush)bi_reverse(next_code[len]++, len); }
412 let _ ← cfor (σ := Int32 × Array UInt16)
413 (fun (n, _) => pure (decide (n.toInt ≤ max_code.toInt)))
414 (fun (n, nc) => do pure (← iadd n 1, nc))
415 (fun (n, nc) => do
416 let len := u16i (← getDl tree n.toInt)
417 if len == 0 then return (n, nc)
418 let li := len.toInt.toNat
419 if nc.size ≤ li then ub "next_code index outside its array"
420 let old := nc[li]!
421 let nc := nc.set! li (old + 1)
422 let r ← bi_reverse old.toUInt32 len
423 setFc tree n.toInt r.toUInt16
424 pure (n, nc))
425 (0, next_code)
426
427/-- `local void tr_static_init(void)`: the body is inside `#if defined(GEN_TREES_H) || !defined(STDC)`, which is
428false in the default build, so the function is empty. -/
429def tr_static_init : M Unit := pure ()
430
431/-- `local void init_block(deflate_state *s)` -/
432def init_block (s : DeflateStatePtr) : M Unit := do
433 -- for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
434 let _ ← cfor (σ := Int32) (fun n => pure (decide (n.toInt < L_CODES.toInt))) (fun n => iadd n 1)
435 (fun n => do setFc (← pLtree s) n.toInt 0; pure n) 0
436 let _ ← cfor (σ := Int32) (fun n => pure (decide (n.toInt < D_CODES.toInt))) (fun n => iadd n 1)
437 (fun n => do setFc (← pDtree s) n.toInt 0; pure n) 0
438 let _ ← cfor (σ := Int32) (fun n => pure (decide (n.toInt < BL_CODES.toInt))) (fun n => iadd n 1)
439 (fun n => do setFc (← pBltree s) n.toInt 0; pure n) 0
440 -- s->dyn_ltree[END_BLOCK].Freq = 1;
441 setFc (← pLtree s) END_BLOCK.toInt 1
442 -- s->opt_len = s->static_len = 0L;
443 md s fun d => { d with static_len := 0 }
444 md s fun d => { d with opt_len := 0 }
445 -- s->sym_next = s->matches = 0;
446 md s fun d => { d with «matches» := 0 }
447 md s fun d => { d with sym_next := 0 }
448
449/-- `void ZLIB_INTERNAL _tr_init(deflate_state *s)` -/
450def «_tr_init» (s : DeflateStatePtr) : M Unit := do
451 tr_static_init
452 let id ← sid s
453 md s fun d => { d with l_desc := { d.l_desc with dyn_tree := .ref (.dstate_dyn_ltree id) 0 } }
454 md s fun d => { d with l_desc := { d.l_desc with stat_desc := some .st_static_l_desc } }
455 md s fun d => { d with d_desc := { d.d_desc with dyn_tree := .ref (.dstate_dyn_dtree id) 0 } }
456 md s fun d => { d with d_desc := { d.d_desc with stat_desc := some .st_static_d_desc } }
457 md s fun d => { d with bl_desc := { d.bl_desc with dyn_tree := .ref (.dstate_bl_tree id) 0 } }
458 md s fun d => { d with bl_desc := { d.bl_desc with stat_desc := some .st_static_bl_desc } }
459 md s fun d => { d with bi_buf := 0 }
460 md s fun d => { d with bi_valid := 0 }
461 md s fun d => { d with bi_used := 0 }
462 -- Initialize the first block of the first file:
463 init_block s
464
465/-- `local void pqdownheap(deflate_state *s, ct_data *tree, int k)` -/
466def pqdownheap (s : DeflateStatePtr) (tree : CtDataPtr) (k : Int32) : M Unit := do
467 -- int v = s->heap[k]; int j = k << 1;
468 let v ← heapAt s k
469 let j ← shl1 k
470 -- while (j <= s->heap_len) { ... } (the flag is the `break`)
471 let (k, _, _) ← cwhile (σ := Int32 × Int32 × Bool)
472 (fun (k, j, brk) => do
473 if brk then return (false, (k, j, brk))
474 pure (decide (j.toInt ≤ (← rd s).heap_len.toInt), (k, j, brk)))
475 (fun (k, j, _) => do
476 let mut jj := j
477 -- if (j < s->heap_len && smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) j++;
478 if jj.toInt < (← rd s).heap_len.toInt then
479 let a ← heapAt s (← iadd jj 1)
480 let b ← heapAt s jj
481 if ← smaller tree a b (← pDepth s) then jj ← iadd jj 1
482 -- if (smaller(tree, v, s->heap[j], s->depth)) break;
483 let hj ← heapAt s jj
484 if ← smaller tree v hj (← pDepth s) then return (k, jj, true)
485 -- s->heap[k] = s->heap[j]; k = j;
486 heapSet s k hj
487 -- j <<= 1;
488 let j2 ← shl1 jj
489 return (jj, j2, false))
490 (k, j, false)
491 -- s->heap[k] = v;
492 heapSet s k v
493
494/-- `pqremove(s, tree, top)`: `{ top = s->heap[SMALLEST]; s->heap[SMALLEST] = s->heap[s->heap_len--];
495pqdownheap(s, tree, SMALLEST); }`; returns `top`. -/
496def pqremove (s : DeflateStatePtr) (tree : CtDataPtr) : M Int32 := do
497 let top ← heapAt s 1
498 -- s->heap[SMALLEST] = s->heap[s->heap_len--];
499 let hl := (← rd s).heap_len
500 let v ← heapAt s hl
501 let hl' ← isub hl 1
502 md s fun d => { d with heap_len := hl' }
503 heapSet s 1 v
504 pqdownheap s tree 1
505 return top
506
507/-- `local void gen_bitlen(deflate_state *s, tree_desc *desc)` -/
508def gen_bitlen (s : DeflateStatePtr) (desc : TreeDescPtr) : M Unit := do
509 let dd ← ldTreeDesc desc
510 let tree := dd.dyn_tree
511 let max_code := dd.max_code
512 let sd ← ldStaticTreeDesc dd.stat_desc
513 let stree := sd.static_tree
514 let extra := sd.extra_bits
515 let base := sd.extra_base
516 let max_length := sd.max_length
517 -- for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
518 let _ ← cfor (σ := Int32) (fun b => pure (decide (b.toInt ≤ MAX_BITS.toInt))) (fun b => iadd b 1)
519 (fun b => do setAt (← pBlCount s) b.toInt 0; pure b) 0
520 -- tree[s->heap[s->heap_max]].Len = 0;
521 setDl tree (← heapAt s (← rd s).heap_max).toInt 0
522 -- for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { ... } state (h, overflow)
523 let h0 ← iadd (← rd s).heap_max 1
524 let (h, overflow) ← cfor (σ := Int32 × Int32)
525 (fun (h, _) => pure (decide (h.toInt < HEAP_SIZE.toInt)))
526 (fun (h, o) => do pure (← iadd h 1, o))
527 (fun (h, overflow) => do
528 let n ← heapAt s h
529 -- bits = tree[tree[n].Dad].Len + 1;
530 let mut bits ← iadd (u16i (← getDl tree (u16i (← getDl tree n.toInt)).toInt)) 1
531 let mut overflow := overflow
532 -- if (bits > max_length) bits = max_length, overflow++;
533 if bits.toInt > max_length.toInt then
534 bits := max_length
535 overflow ← iadd overflow 1
536 -- tree[n].Len = (ush)bits;
537 setDl tree n.toInt (i2us bits)
538 -- if (n > max_code) continue;
539 if n.toInt > max_code.toInt then return (h, overflow)
540 -- s->bl_count[bits]++;
541 let bc ← pBlCount s
542 setAt bc bits.toInt ((← Ptr.index bc bits.toInt) + 1)
543 -- xbits = 0; if (n >= base) xbits = extra[n - base];
544 let mut xbits : Int32 := 0
545 if n.toInt ≥ base.toInt then xbits ← Ptr.index extra (← isub n base).toInt
546 -- f = tree[n].Freq;
547 let f ← getFc tree n.toInt
548 -- s->opt_len += (ulg)f * (unsigned)(bits + xbits);
549 let t ← iadd bits xbits
550 md s fun d => { d with opt_len := d.opt_len + f.toUInt64 * (i2u t).toUInt64 }
551 -- if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits);
552 if stree != .null then
553 let t2 ← iadd (u16i (← getDl stree n.toInt)) xbits
554 md s fun d => { d with static_len := d.static_len + f.toUInt64 * (i2u t2).toUInt64 }
555 return (h, overflow))
556 (h0, 0)
557 -- if (overflow == 0) return;
558 if overflow == 0 then return
559 -- do { bits = max_length-1; while (bl_count[bits]==0) bits--; ... overflow -= 2; } while (overflow > 0);
560 let _ ← cdoWhile (σ := Int32)
561 (fun overflow => do
562 let bits ← isub max_length 1
563 let bc ← pBlCount s
564 let bits ← cwhile (σ := Int32)
565 (fun b => do pure (decide ((← Ptr.index bc b.toInt) == 0), b))
566 (fun b => isub b 1) bits
567 setAt bc bits.toInt ((← Ptr.index bc bits.toInt) - 1)
568 let b1 ← iadd bits 1
569 setAt bc b1.toInt ((← Ptr.index bc b1.toInt) + 2)
570 setAt bc max_length.toInt ((← Ptr.index bc max_length.toInt) - 1)
571 isub overflow 2)
572 (fun overflow => pure (decide (overflow.toInt > 0), overflow))
573 overflow
574 -- for (bits = max_length; bits != 0; bits--) { n = s->bl_count[bits]; while (n != 0) { ... } }
575 let _ ← cfor (σ := Int32 × Int32)
576 (fun (bits, _) => pure (bits != 0))
577 (fun (bits, h) => do pure (← isub bits 1, h))
578 (fun (bits, h) => do
579 let n0 := u16i (← Ptr.index (← pBlCount s) bits.toInt)
580 let (_, h) ← cwhile (σ := Int32 × Int32)
581 (fun (n, h) => pure (n != 0, (n, h)))
582 (fun (n, h) => do
583 -- m = s->heap[--h];
584 let h ← isub h 1
585 let m ← heapAt s h
586 -- if (m > max_code) continue;
587 if m.toInt > max_code.toInt then return (n, h)
588 -- if ((unsigned) tree[m].Len != (unsigned) bits) {...}
589 let lm ← getDl tree m.toInt
590 if lm.toUInt32 != i2u bits then
591 -- s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq;
592 let fm ← getFc tree m.toInt
593 md s fun d => { d with opt_len := d.opt_len + (i2ul bits - lm.toUInt64) * fm.toUInt64 }
594 setDl tree m.toInt (i2us bits)
595 -- n--;
596 pure (← isub n 1, h))
597 (n0, h)
598 pure (bits, h))
599 (max_length, h)
600
601/-- `local void build_tree(deflate_state *s, tree_desc *desc)` -/
602def build_tree (s : DeflateStatePtr) (desc : TreeDescPtr) : M Unit := do
603 let dd ← ldTreeDesc desc
604 let tree := dd.dyn_tree
605 let sd ← ldStaticTreeDesc dd.stat_desc
606 let stree := sd.static_tree
607 let elems := sd.elems
608 -- int max_code = -1;
609 -- s->heap_len = 0, s->heap_max = HEAP_SIZE;
610 md s fun d => { d with heap_len := 0 }
611 md s fun d => { d with heap_max := HEAP_SIZE }
612 -- for (n = 0; n < elems; n++) { if (tree[n].Freq != 0) {...} else tree[n].Len = 0; }
613 let max_code ← cfor (σ := Int32 × Int32)
614 (fun (n, _) => pure (decide (n.toInt < elems.toInt)))
615 (fun (n, mc) => do pure (← iadd n 1, mc))
616 (fun (n, mc) => do
617 if (← getFc tree n.toInt) != 0 then
618 -- s->heap[++(s->heap_len)] = max_code = n;
619 let hl ← iadd (← rd s).heap_len 1
620 md s fun d => { d with heap_len := hl }
621 heapSet s hl n
622 -- s->depth[n] = 0;
623 setAt (← pDepth s) n.toInt 0
624 pure (n, n)
625 else
626 setDl tree n.toInt 0
627 pure (n, mc))
628 (0, -1)
629 let mut max_code := max_code.2
630 -- while (s->heap_len < 2) { ... }
631 let mc ← cwhile (σ := Int32)
632 (fun mc => do pure (decide ((← rd s).heap_len.toInt < 2), mc))
633 (fun mc => do
634 -- node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
635 let mut mc := mc
636 let mut val : Int32 := 0
637 if mc.toInt < 2 then
638 mc ← iadd mc 1
639 val := mc
640 let hl ← iadd (← rd s).heap_len 1
641 md s fun d => { d with heap_len := hl }
642 heapSet s hl val
643 let node := val
644 -- tree[node].Freq = 1; s->depth[node] = 0;
645 setFc tree node.toInt 1
646 setAt (← pDepth s) node.toInt 0
647 -- s->opt_len--; if (stree) s->static_len -= stree[node].Len;
648 md s fun d => { d with opt_len := d.opt_len - 1 }
649 if stree != .null then
650 let l ← getDl stree node.toInt
651 md s fun d => { d with static_len := d.static_len - l.toUInt64 }
652 pure mc)
653 max_code
654 max_code := mc
655 -- desc->max_code = max_code;
656 stTreeDesc desc { (← ldTreeDesc desc) with max_code := max_code }
657 -- for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
658 let _ ← cfor (σ := Int32) (fun n => pure (decide (n.toInt ≥ 1))) (fun n => isub n 1)
659 (fun n => do pqdownheap s tree n; pure n) ((← rd s).heap_len / 2)
660 -- node = elems;
661 -- do { ... } while (s->heap_len >= 2);
662 let _ ← cdoWhile (σ := Int32)
663 (fun node => do
664 -- pqremove(s, tree, n); m = s->heap[SMALLEST];
665 let n ← pqremove s tree
666 let m ← heapAt s 1
667 -- s->heap[--(s->heap_max)] = n; s->heap[--(s->heap_max)] = m;
668 let hm ← isub (← rd s).heap_max 1
669 md s fun d => { d with heap_max := hm }
670 heapSet s hm n
671 let hm ← isub (← rd s).heap_max 1
672 md s fun d => { d with heap_max := hm }
673 heapSet s hm m
674 -- tree[node].Freq = tree[n].Freq + tree[m].Freq;
675 let fn ← getFc tree n.toInt
676 let fm ← getFc tree m.toInt
677 setFc tree node.toInt (fn + fm)
678 -- s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? s->depth[n] : s->depth[m]) + 1);
679 let dp ← pDepth s
680 let dn ← Ptr.index dp n.toInt
681 let dm ← Ptr.index dp m.toInt
682 let mx ← if dn ≥ dm then Ptr.index dp n.toInt else Ptr.index dp m.toInt
683 setAt dp node.toInt (mx + 1)
684 -- tree[n].Dad = tree[m].Dad = (ush)node;
685 setDl tree m.toInt (i2us node)
686 setDl tree n.toInt (i2us node)
687 -- s->heap[SMALLEST] = node++;
688 heapSet s 1 node
689 let node' ← iadd node 1
690 pqdownheap s tree 1
691 pure node')
692 (fun node => do pure (decide ((← rd s).heap_len.toInt ≥ 2), node))
693 elems
694 -- s->heap[--(s->heap_max)] = s->heap[SMALLEST];
695 let top ← heapAt s 1
696 let hm ← isub (← rd s).heap_max 1
697 md s fun d => { d with heap_max := hm }
698 heapSet s hm top
699 -- gen_bitlen(s, (tree_desc *)desc);
700 gen_bitlen s desc
701 -- gen_codes ((ct_data *)tree, max_code, s->bl_count);
702 gen_codes tree max_code (← pBlCount s)
703
704/-- `local void scan_tree(deflate_state *s, ct_data *tree, int max_code)` -/
705def scan_tree (s : DeflateStatePtr) (tree : CtDataPtr) (max_code : Int32) : M Unit := do
706 -- locals: n, prevlen, curlen, nextlen, count, max_count, min_count
707 let nextlen0 := u16i (← getDl tree 0)
708 let (mx0, mn0) : Int32 × Int32 := if nextlen0 == 0 then (138, 3) else (7, 4)
709 -- tree[max_code + 1].Len = (ush)0xffff;
710 setDl tree (← iadd max_code 1).toInt 0xffff
711 let _ ← cfor (σ := Int32 × Int32 × Int32 × Int32 × Int32 × Int32 × Int32)
712 (fun (n, _) => pure (decide (n.toInt ≤ max_code.toInt)))
713 (fun (n, r) => do pure (← iadd n 1, r))
714 (fun (n, prevlen, nextlen, count, max_count, min_count, _) => do
715 -- curlen = nextlen; nextlen = tree[n + 1].Len;
716 let curlen := nextlen
717 let nextlen := u16i (← getDl tree (← iadd n 1).toInt)
718 -- if (++count < max_count && curlen == nextlen) continue;
719 let count ← iadd count 1
720 if count.toInt < max_count.toInt ∧ curlen == nextlen then
721 return (n, prevlen, nextlen, count, max_count, min_count, 0)
722 let blt ← pBltree s
723 if count.toInt < min_count.toInt then
724 -- s->bl_tree[curlen].Freq += (ush)count;
725 setFc blt curlen.toInt ((← getFc blt curlen.toInt) + i2us count)
726 else if curlen != 0 then
727 -- if (curlen != prevlen) s->bl_tree[curlen].Freq++;
728 if curlen != prevlen then setFc blt curlen.toInt ((← getFc blt curlen.toInt) + 1)
729 setFc blt REP_3_6.toInt ((← getFc blt REP_3_6.toInt) + 1)
730 else if count.toInt ≤ 10 then
731 setFc blt REPZ_3_10.toInt ((← getFc blt REPZ_3_10.toInt) + 1)
732 else
733 setFc blt REPZ_11_138.toInt ((← getFc blt REPZ_11_138.toInt) + 1)
734 -- count = 0; prevlen = curlen;
735 let count : Int32 := 0
736 let prevlen := curlen
737 let (max_count, min_count) : Int32 × Int32 :=
738 if nextlen == 0 then (138, 3) else if curlen == nextlen then (6, 3) else (7, 4)
739 return (n, prevlen, nextlen, count, max_count, min_count, 0))
740 (0, -1, nextlen0, 0, mx0, mn0, 0)
741
742/-- `local void send_tree(deflate_state *s, ct_data *tree, int max_code)` -/
743def send_tree (s : DeflateStatePtr) (tree : CtDataPtr) (max_code : Int32) : M Unit := do
744 let nextlen0 := u16i (← getDl tree 0)
745 -- /* tree[max_code + 1].Len = -1; */ /* guard already set */
746 let (mx0, mn0) : Int32 × Int32 := if nextlen0 == 0 then (138, 3) else (7, 4)
747 let _ ← cfor (σ := Int32 × Int32 × Int32 × Int32 × Int32 × Int32 × Int32)
748 (fun (n, _) => pure (decide (n.toInt ≤ max_code.toInt)))
749 (fun (n, r) => do pure (← iadd n 1, r))
750 (fun (n, prevlen, nextlen, count, max_count, min_count, _) => do
751 let curlen := nextlen
752 let nextlen := u16i (← getDl tree (← iadd n 1).toInt)
753 let mut count ← iadd count 1
754 if count.toInt < max_count.toInt ∧ curlen == nextlen then
755 return (n, prevlen, nextlen, count, max_count, min_count, 0)
756 if count.toInt < min_count.toInt then
757 -- do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
758 count ← cdoWhile (σ := Int32)
759 (fun c => do send_code s curlen.toInt (← pBltree s); pure c)
760 (fun c => do let c ← isub c 1; pure (c != 0, c))
761 count
762 else if curlen != 0 then
763 if curlen != prevlen then
764 send_code s curlen.toInt (← pBltree s)
765 count ← isub count 1
766 send_code s REP_3_6.toInt (← pBltree s)
767 send_bits s (← isub count 3) 2
768 else if count.toInt ≤ 10 then
769 send_code s REPZ_3_10.toInt (← pBltree s)
770 send_bits s (← isub count 3) 3
771 else
772 send_code s REPZ_11_138.toInt (← pBltree s)
773 send_bits s (← isub count 11) 7
774 -- count = 0; prevlen = curlen;
775 count := 0
776 let prevlen := curlen
777 let (max_count, min_count) : Int32 × Int32 :=
778 if nextlen == 0 then (138, 3) else if curlen == nextlen then (6, 3) else (7, 4)
779 return (n, prevlen, nextlen, count, max_count, min_count, 0))
780 (0, -1, nextlen0, 0, mx0, mn0, 0)
781
782/-- `local int build_bl_tree(deflate_state *s)` -/
783def build_bl_tree (s : DeflateStatePtr) : M Int32 := do
784 -- scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
785 scan_tree s (← pLtree s) (← rd s).l_desc.max_code
786 scan_tree s (← pDtree s) (← rd s).d_desc.max_code
787 -- build_tree(s, (tree_desc *)(&(s->bl_desc)));
788 build_tree s (← pBldesc s)
789 -- for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { if (...Len != 0) break; }
790 let (mb, _) ← cwhile (σ := Int32 × Bool)
791 (fun (mb, brk) => pure (!brk && decide (mb.toInt ≥ 3), (mb, brk)))
792 (fun (mb, _) => do
793 if (← getDl (← pBltree s) (u8i (← blOrder mb.toInt)).toInt) != 0 then return (mb, true)
794 pure (← isub mb 1, false))
795 (BL_CODES - 1, false)
796 -- s->opt_len += 3*((ulg)max_blindex + 1) + 5 + 5 + 4;
797 md s fun d => { d with opt_len := d.opt_len + (3 * (i2ul mb + 1) + 5 + 5 + 4) }
798 return mb
799
800/-- `local void send_all_trees(deflate_state *s, int lcodes, int dcodes, int blcodes)` -/
801def send_all_trees (s : DeflateStatePtr) (lcodes dcodes blcodes : Int32) : M Unit := do
802 send_bits s (← isub lcodes 257) 5
803 send_bits s (← isub dcodes 1) 5
804 send_bits s (← isub blcodes 4) 4
805 -- for (rank = 0; rank < blcodes; rank++) send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
806 let _ ← cfor (σ := Int32) (fun r => pure (decide (r.toInt < blcodes.toInt))) (fun r => iadd r 1)
807 (fun r => do
808 let l ← getDl (← pBltree s) (u8i (← blOrder r.toInt)).toInt
809 send_bits s (u16i l) 3
810 pure r) 0
811 send_tree s (← pLtree s) (← isub lcodes 1)
812 send_tree s (← pDtree s) (← isub dcodes 1)
813
814/-- `void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, ulg stored_len, int last)` -/
815def «_tr_stored_block» (s : DeflateStatePtr) (buf : BPtr) (stored_len : UInt64) (last : Int32) : M Unit := do
816 -- send_bits(s, (STORED_BLOCK<<1) + last, 3);
817 send_bits s (← iadd (STORED_BLOCK <<< 1) last) 3
818 bi_windup s
819 put_short s stored_len.toUInt16
820 put_short s (~~~stored_len).toUInt16
821 -- if (stored_len) zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len);
822 if stored_len != 0 then
823 let d ← rd s
824 let dst ← Ptr.add d.pending_buf (d.pending.toNat : Int)
825 memcpyB dst buf stored_len.toNat
826 md s fun d => { d with pending := d.pending + stored_len }
827
828/-- `void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s)` -/
829def «_tr_flush_bits» (s : DeflateStatePtr) : M Unit := bi_flush s
830
831/-- `void ZLIB_INTERNAL _tr_align(deflate_state *s)` -/
832def «_tr_align» (s : DeflateStatePtr) : M Unit := do
833 send_bits s (STATIC_TREES <<< 1) 3
834 send_code s END_BLOCK.toInt (.ref .st_static_ltree 0)
835 bi_flush s
836
837/-- `local void compress_block(deflate_state *s, const ct_data *ltree, const ct_data *dtree)` -/
838def compress_block (s : DeflateStatePtr) (ltree dtree : CtDataPtr) : M Unit := do
839 let lcp : BPtr := .ref .st_length_code 0
840 -- if (s->sym_next != 0) do { ... } while (sx < s->sym_next);
841 if (← rd s).sym_next != 0 then
842 let _ ← cdoWhile (σ := UInt32)
843 (fun sx => do
844 -- dist = s->sym_buf[sx++] & 0xff;
845 let sb := (← rd s).sym_buf
846 let b0 ← Ptr.index sb sx.toNat
847 let sx := sx + 1
848 let dist : UInt32 := b0.toUInt32 &&& 0xff
849 -- dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
850 let b1 ← Ptr.index sb sx.toNat
851 let sx := sx + 1
852 let dist := dist + ((b1.toUInt32 &&& 0xff) <<< 8)
853 -- lc = s->sym_buf[sx++];
854 let b2 ← Ptr.index sb sx.toNat
855 let sx := sx + 1
856 let lc := u8i b2
857 if dist == 0 then
858 send_code s lc.toInt ltree
859 else
860 -- code = _length_code[lc];
861 let code := (← Ptr.index lcp lc.toInt).toUInt32
862 -- send_code(s, code + LITERALS + 1, ltree);
863 send_code s (code + (i2u LITERALS) + 1).toNat ltree
864 -- extra = extra_lbits[code];
865 let extra ← Ptr.index (.ref .st_extra_lbits 0 : IPtr) code.toNat
866 let mut lc := lc
867 if extra != 0 then
868 lc ← isub lc (← Ptr.index (.ref .st_base_length 0 : IPtr) code.toNat)
869 send_bits s lc extra
870 -- dist--; code = d_code(dist);
871 let dist := dist - 1
872 let code := (← d_code dist).toUInt32
873 send_code s code.toNat dtree
874 let extra ← Ptr.index (.ref .st_extra_dbits 0 : IPtr) code.toNat
875 if extra != 0 then
876 let dist := dist - (i2u (← Ptr.index (.ref .st_base_dist 0 : IPtr) code.toNat))
877 send_bits s (u2i dist) extra
878 pure sx)
879 (fun sx => do pure (decide (sx < (← rd s).sym_next), sx))
880 0
881 -- send_code(s, END_BLOCK, ltree);
882 send_code s END_BLOCK.toInt ltree
883
884/-- `local int detect_data_type(deflate_state *s)` -/
885def detect_data_type (s : DeflateStatePtr) : M Int32 := do
886 -- unsigned long block_mask = 0xf3ffc07fUL;
887 -- for (n = 0; n <= 31; n++, block_mask >>= 1) if ((block_mask & 1) && ...Freq != 0) return Z_BINARY;
888 let (_, _, r) ← cwhile (σ := Int32 × UInt64 × Option Int32)
889 (fun (n, bm, r) => pure (r.isNone && decide (n.toInt ≤ 31), (n, bm, r)))
890 (fun (n, bm, _) => do
891 if (bm &&& 1) != 0 ∧ (← getFc (← pLtree s) n.toInt) != 0 then return (n, bm, some Z_BINARY)
892 pure (← iadd n 1, bm >>> 1, none))
893 (0, 0xf3ffc07f, none)
894 if let some v := r then return v
895 -- if (dyn_ltree[9].Freq != 0 || dyn_ltree[10].Freq != 0 || dyn_ltree[13].Freq != 0) return Z_TEXT;
896 if (← getFc (← pLtree s) 9) != 0 ∨ (← getFc (← pLtree s) 10) != 0 ∨ (← getFc (← pLtree s) 13) != 0 then
897 return Z_TEXT
898 -- for (n = 32; n < LITERALS; n++) if (s->dyn_ltree[n].Freq != 0) return Z_TEXT;
899 let (_, r) ← cwhile (σ := Int32 × Option Int32)
900 (fun (n, r) => pure (r.isNone && decide (n.toInt < LITERALS.toInt), (n, r)))
901 (fun (n, _) => do
902 if (← getFc (← pLtree s) n.toInt) != 0 then return (n, some Z_TEXT)
903 pure (← iadd n 1, none))
904 (32, none)
905 if let some v := r then return v
906 return Z_BINARY
907
908/-- `void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, ulg stored_len, int last)` -/
909def «_tr_flush_block» (s : DeflateStatePtr) (buf : BPtr) (stored_len : UInt64) (last : Int32) : M Unit := do
910 -- int max_blindex = 0;
911 let mut max_blindex : Int32 := 0
912 let mut opt_lenb : UInt64 := 0
913 let mut static_lenb : UInt64 := 0
914 if (← rd s).level.toInt > 0 then
915 -- if (s->strm->data_type == Z_UNKNOWN) s->strm->data_type = detect_data_type(s);
916 let strm := (← rd s).strm
917 if (← ldZStream strm).data_type == Z_UNKNOWN then
918 let t ← detect_data_type s
919 stZStream strm { (← ldZStream strm) with data_type := t }
920 build_tree s (← pLdesc s)
921 build_tree s (← pDdesc s)
922 max_blindex ← build_bl_tree s
923 -- opt_lenb = (s->opt_len + 3 + 7) >> 3; static_lenb = (s->static_len + 3 + 7) >> 3;
924 opt_lenb := ((← rd s).opt_len + 3 + 7) >>> 3
925 static_lenb := ((← rd s).static_len + 3 + 7) >>> 3
926 -- if (static_lenb <= opt_lenb || s->strategy == Z_FIXED) opt_lenb = static_lenb;
927 if static_lenb ≤ opt_lenb ∨ (← rd s).strategy == Z_FIXED then opt_lenb := static_lenb
928 else
929 -- opt_lenb = static_lenb = stored_len + 5;
930 opt_lenb := stored_len + 5
931 static_lenb := stored_len + 5
932 if stored_len + 4 ≤ opt_lenb ∧ buf != .null then
933 «_tr_stored_block» s buf stored_len last
934 else if static_lenb == opt_lenb then
935 send_bits s (← iadd (STATIC_TREES <<< 1) last) 3
936 compress_block s (.ref .st_static_ltree 0) (.ref .st_static_dtree 0)
937 else
938 send_bits s (← iadd (DYN_TREES <<< 1) last) 3
939 send_all_trees s (← iadd (← rd s).l_desc.max_code 1) (← iadd (← rd s).d_desc.max_code 1)
940 (← iadd max_blindex 1)
941 compress_block s (← pLtree s) (← pDtree s)
942 init_block s
943 -- if (last) bi_windup(s);
944 if last != 0 then bi_windup s
945
946/-- `int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc)` -/
947def «_tr_tally» (s : DeflateStatePtr) (dist lc : UInt32) : M Int32 := do
948 -- s->sym_buf[s->sym_next++] = (uch)dist; (uch)(dist >> 8); (uch)lc;
949 let put (v : UInt8) : M Unit := do
950 let d ← rd s
951 setAt d.sym_buf d.sym_next.toNat v
952 md s fun d => { d with sym_next := d.sym_next + 1 }
953 put dist.toUInt8
954 put (dist >>> 8).toUInt8
955 put lc.toUInt8
956 if dist == 0 then
957 -- s->dyn_ltree[lc].Freq++;
958 let lt ← pLtree s
959 setFc lt lc.toNat ((← getFc lt lc.toNat) + 1)
960 else
961 md s fun d => { d with «matches» := d.«matches» + 1 }
962 let dist := dist - 1
963 -- s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++;
964 let lcode ← Ptr.index (.ref .st_length_code 0 : BPtr) lc.toNat
965 let idx := (u8i lcode).toInt + LITERALS.toInt + 1
966 let lt ← pLtree s
967 setFc lt idx ((← getFc lt idx) + 1)
968 -- s->dyn_dtree[d_code(dist)].Freq++;
969 let dc ← d_code dist
970 let dt ← pDtree s
971 setFc dt dc.toNat ((← getFc dt dc.toNat) + 1)
972 -- return (s->sym_next == s->sym_end);
973 let d ← rd s
974 return (if d.sym_next == d.sym_end then 1 else 0)
975
976end Zlib.Trees