1-- Legal licensing note: 2 3-- Copyright (c) 1999 .. 2018 Gautier de Montmollin 4-- SWITZERLAND 5 6-- Permission is hereby granted, free of charge, to any person obtaining a copy 7-- of this software and associated documentation files (the "Software"), to deal 8-- in the Software without restriction, including without limitation the rights 9-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10-- copies of the Software, and to permit persons to whom the Software is 11-- furnished to do so, subject to the following conditions: 12 13-- The above copyright notice and this permission notice shall be included in 14-- all copies or substantial portions of the Software. 15 16-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22-- THE SOFTWARE. 23 24-- NB: this is the MIT License, as found on the site 25-- http://www.opensource.org/licenses/mit-license.php 26 27with Interfaces; 28with Ada.Text_IO; 29with Ada.Unchecked_Deallocation; 30 31package body UnZip.Decompress.Huffman is 32 33 -- Note from Pascal source: 34 -- C code by info-zip group, translated to pascal by Christian Ghisler 35 -- based on unz51g.zip 36 37 -- Free huffman tables starting with table where t points to 38 39 procedure HufT_free ( tl: in out p_Table_list ) is 40 41 procedure Dispose is new 42 Ada.Unchecked_Deallocation( HufT_table, p_HufT_table ); 43 procedure Dispose is new 44 Ada.Unchecked_Deallocation( Table_list, p_Table_list ); 45 46 current: p_Table_list; 47 tcount : Natural:= 0; -- just a stat. Idea: replace table_list with an array 48 49 begin 50 if full_trace then 51 Ada.Text_IO.Put("[HufT_Free... "); 52 end if; 53 while tl /= null loop 54 Dispose( tl.table ); -- destroy the Huffman table 55 current:= tl; 56 tl := tl.next; 57 Dispose( current ); -- destroy the current node 58 if full_trace then 59 tcount:= tcount+1; 60 end if; 61 end loop; 62 if full_trace then 63 Ada.Text_IO.Put_Line( Integer'Image(tcount)& " tables]" ); 64 end if; 65 end HufT_free; 66 67 -- Build huffman table from code lengths given by array b 68 69 procedure HufT_build ( b : Length_array; 70 s : Integer; 71 d, e : Length_array; 72 tl : out p_Table_list; 73 m : in out Integer; 74 huft_incomplete : out Boolean) 75 is 76 use Interfaces; 77 78 b_max : constant:= 16; 79 b_maxp1: constant:= b_max + 1; 80 81 -- bit length count table 82 count : array( 0 .. b_maxp1 ) of Integer:= (others=> 0); 83 84 f : Integer; -- i repeats in table every f entries 85 g : Integer; -- max. code length 86 i, -- counter, current code 87 j : Integer; -- counter 88 kcc : Integer; -- number of bits in current code 89 90 c_idx, v_idx: Natural; -- array indices 91 92 current_table_ptr : p_HufT_table:= null; 93 current_node_ptr : p_Table_list:= null; -- curr. node for the curr. table 94 new_node_ptr : p_Table_list; -- new node for the new table 95 96 new_entry: HufT; -- table entry for structure assignment 97 98 u : array( 0..b_max ) of p_HufT_table; -- table stack 99 100 n_max : constant:= 288; 101 -- values in order of bit length 102 v : array( 0..n_max ) of Integer:= (others=> 0); 103 el_v, el_v_m_s: Integer; 104 105 w : Natural:= 0; -- bits before this table 106 107 offset, code_stack : array( 0..b_maxp1 ) of Integer; 108 109 table_level : Integer:= -1; 110 bits : array( Integer'(-1)..b_maxp1 ) of Integer; 111 -- ^bits(table_level) = # bits in table of level table_level 112 113 y : Integer; -- number of dummy codes added 114 z : Natural:= 0; -- number of entries in current table 115 el : Integer; -- length of eob code=code 256 116 117 no_copy_length_array: constant Boolean:= d'Length=0 or e'Length=0; 118 119 begin 120 if full_trace then 121 Ada.Text_IO.Put("[HufT_Build..."); 122 end if; 123 tl:= null; 124 125 if b'Length > 256 then -- set length of EOB code, if any 126 el := b(256); 127 else 128 el := b_max; 129 end if; 130 131 -- Generate counts for each bit length 132 133 for k in b'Range loop 134 if b(k) > b_max then 135 -- m := 0; -- GNAT 2005 doesn't like it (warning). 136 raise huft_error; 137 end if; 138 count( b(k) ):= count( b(k) ) + 1; 139 end loop; 140 141 if count(0) = b'Length then 142 m := 0; 143 huft_incomplete:= False; -- spotted by Tucker Taft, 19-Aug-2004 144 return; -- complete 145 end if; 146 147 -- Find minimum and maximum length, bound m by those 148 149 j := 1; 150 while j <= b_max and then count(j) = 0 loop 151 j:= j + 1; 152 end loop; 153 kcc := j; 154 if m < j then 155 m := j; 156 end if; 157 i := b_max; 158 while i > 0 and then count(i) = 0 loop 159 i:= i - 1; 160 end loop; 161 g := i; 162 if m > i then 163 m := i; 164 end if; 165 166 -- Adjust last length count to fill out codes, if needed 167 168 y := Integer( Shift_Left(Unsigned_32'(1), j) ); -- y:= 2 ** j; 169 while j < i loop 170 y := y - count(j); 171 if y < 0 then 172 raise huft_error; 173 end if; 174 y:= y * 2; 175 j:= j + 1; 176 end loop; 177 178 y:= y - count(i); 179 if y < 0 then 180 raise huft_error; 181 end if; 182 count(i):= count(i) + y; 183 184 -- Generate starting offsets into the value table for each length 185 186 offset(1) := 0; 187 j:= 0; 188 for idx in 2..i loop 189 j:= j + count( idx-1 ); 190 offset( idx ) := j; 191 end loop; 192 193 -- Make table of values in order of bit length 194 195 for idx in b'Range loop 196 j := b(idx); 197 if j /= 0 then 198 v( offset(j) ) := idx-b'First; 199 offset(j):= offset(j) + 1; 200 end if; 201 end loop; 202 203 -- Generate huffman codes and for each, make the table entries 204 205 code_stack(0) := 0; 206 i := 0; 207 v_idx:= v'First; 208 bits(-1) := 0; 209 210 -- go through the bit lengths (kcc already is bits in shortest code) 211 for k in kcc .. g loop 212 213 for am1 in reverse 0 .. count(k)-1 loop -- a counts codes of length k 214 215 -- here i is the huffman code of length k bits for value v(v_idx) 216 while k > w + bits(table_level) loop 217 218 w:= w + bits(table_level); -- Length of tables to this position 219 table_level:= table_level+ 1; 220 z:= g - w; -- Compute min size table <= m bits 221 if z > m then 222 z := m; 223 end if; 224 j := k - w; 225 f := Integer(Shift_Left(Unsigned_32'(1), j)); -- f:= 2 ** j; 226 if f > am1 + 2 then -- Try a k-w bit table 227 f:= f - (am1 + 2); 228 c_idx:= k; 229 loop -- Try smaller tables up to z bits 230 j:= j + 1; 231 exit when j >= z; 232 f := f * 2; 233 c_idx:= c_idx + 1; 234 exit when f - count(c_idx) <= 0; 235 f:= f - count(c_idx); 236 end loop; 237 end if; 238 239 if w + j > el and then w < el then 240 j:= el - w; -- Make EOB code end at table 241 end if; 242 if w = 0 then 243 j := m; -- Fix: main table always m bits! 244 end if; 245 z:= Integer(Shift_Left(Unsigned_32'(1), j)); -- z:= 2 ** j; 246 bits(table_level) := j; 247 248 -- Allocate and link new table 249 250 begin 251 current_table_ptr := new HufT_table ( 0..z ); 252 new_node_ptr := new Table_list'( current_table_ptr, null ); 253 exception 254 when Storage_Error => 255 raise huft_out_of_memory; 256 end; 257 258 if current_node_ptr = null then -- first table 259 tl:= new_node_ptr; 260 else 261 current_node_ptr.next:= new_node_ptr; -- not my first... 262 end if; 263 264 current_node_ptr:= new_node_ptr; -- always non-Null from there 265 266 u( table_level ):= current_table_ptr; 267 268 -- Connect to last table, if there is one 269 270 if table_level > 0 then 271 code_stack(table_level) := i; 272 new_entry.bits := bits(table_level-1); 273 new_entry.extra_bits := 16 + j; 274 new_entry.next_table := current_table_ptr; 275 276 j := Integer( 277 Shift_Right( Unsigned_32(i) and 278 (Shift_Left(Unsigned_32'(1), w) - 1 ), 279 w - bits(table_level-1) ) 280 ); 281 282 -- Test against bad input! 283 284 if j > u( table_level - 1 )'Last then 285 raise huft_error; 286 end if; 287 u( table_level - 1 ) (j) := new_entry; 288 end if; 289 290 end loop; 291 292 -- Set up table entry in new_entry 293 294 new_entry.bits := k - w; 295 new_entry.next_table:= null; -- Unused 296 297 if v_idx >= b'Length then 298 new_entry.extra_bits := invalid; 299 else 300 el_v:= v(v_idx); 301 el_v_m_s:= el_v - s; 302 if el_v_m_s < 0 then -- Simple code, raw value 303 if el_v < 256 then 304 new_entry.extra_bits:= 16; 305 else 306 new_entry.extra_bits:= 15; 307 end if; 308 new_entry.n := el_v; 309 else -- Non-simple -> lookup in lists 310 if no_copy_length_array then 311 raise huft_error; 312 end if; 313 new_entry.extra_bits := e( el_v_m_s ); 314 new_entry.n := d( el_v_m_s ); 315 end if; 316 v_idx:= v_idx + 1; 317 end if; 318 319 -- fill code-like entries with new_entry 320 f := Integer( Shift_Left( Unsigned_32'(1) , k - w )); 321 -- i.e. f := 2 ** (k-w); 322 j := Integer( Shift_Right( Unsigned_32(i), w ) ); 323 while j < z loop 324 current_table_ptr(j) := new_entry; 325 j:= j + f; 326 end loop; 327 328 -- backwards increment the k-bit code i 329 j := Integer( Shift_Left( Unsigned_32'(1) , k - 1 )); 330 -- i.e.: j:= 2 ** (k-1) 331 while ( Unsigned_32(i) and Unsigned_32(j) ) /= 0 loop 332 i := Integer( Unsigned_32(i) xor Unsigned_32(j) ); 333 j := j / 2; 334 end loop; 335 i := Integer( Unsigned_32(i) xor Unsigned_32(j) ); 336 337 -- backup over finished tables 338 while 339 Integer(Unsigned_32(i) and (Shift_Left(1, w)-1)) /= 340 code_stack(table_level) 341 loop 342 table_level:= table_level - 1; 343 w:= w - bits(table_level); -- Size of previous table! 344 end loop; 345 346 end loop; -- am1 347 end loop; -- k 348 349 if full_trace then 350 Ada.Text_IO.Put_Line("finished]"); 351 end if; 352 353 huft_incomplete:= y /= 0 and g /= 1; 354 355 exception 356 when others => 357 HufT_free( tl ); 358 raise; 359 end HufT_build; 360 361end UnZip.Decompress.Huffman; 362