// // HuffmanTable.swift // SWCompression // // Created by Timofey Solomko on 24.10.16. // Copyright © 2016 Timofey Solomko. All rights reserved. // import Foundation class HuffmanTable: CustomStringConvertible { struct Constants { static let codeLengthOrders: [Int] = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15] /// - Warning: Substract 257 from index! static let lengthBase: [Int] = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258] static let distanceBase: [Int] = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577] } var lengths: [HuffmanLength] var description: String { return self.lengths.reduce("HuffmanTable:\n") { $0.appending("\($1)\n") } } init(bootstrap: [Array]) { // Fills the 'lengths' array with numerous HuffmanLengths from a 'bootstrap' var newLengths: [HuffmanLength] = [] var start = bootstrap[0][0] var bits = bootstrap[0][1] for pair in bootstrap[1.. 0 { newLengths.append(contentsOf: (start.. Int { // Auxiliarly subfunction, which computes reversed order of bits in a number // This is some weird magic var a = 1 << 0 var b = 1 << (bits - 1) var z = 0 for i in stride(from: bits - 1, to: -1, by: -2) { z |= (symbol >> i) & a z |= (symbol << i) & b a <<= 1 b >>= 1 } return z } // Calculates symbol and reversedSymbol properties for each length in 'lengths' array // This is done with the help of some weird magic var loopBits = -1 var symbol = -1 for index in 0.. HuffmanLength? { var cachedLength = -1 var cached: Int = -1 for length in self.lengths { let lbits = length.bits if cachedLength != lbits { cached = convertToInt(uint8Array: Array(bitArray[0..