diff --git a/Sources/BZip2/BZip2.swift b/Sources/BZip2/BZip2.swift index cf921553..8d991fe6 100644 --- a/Sources/BZip2/BZip2.swift +++ b/Sources/BZip2/BZip2.swift @@ -147,7 +147,7 @@ public class BZip2: DecompressionAlgorithm { } } let codes = Code.huffmanCodes(from: lengths) - let table = DecodingTree(codes: codes.codes, maxBits: codes.maxBits, bitReader) + let table = DecodingTree(codes, bitReader) tables.append(table) } diff --git a/Sources/Common/CodingTree/Code.swift b/Sources/Common/CodingTree/Code.swift index fcbe7999..f580cf9b 100644 --- a/Sources/Common/CodingTree/Code.swift +++ b/Sources/Common/CodingTree/Code.swift @@ -5,6 +5,8 @@ import Foundation +typealias HuffmanCodes = (codes: [Code], maxBits: Int) + struct Code { /// Number of bits used for `code`. @@ -13,7 +15,7 @@ struct Code { let symbol: Int /// `lengths` don't have to be sorted, but there must not be any 0 code lengths. - static func huffmanCodes(from lengths: [CodeLength]) -> (codes: [Code], maxBits: Int) { + static func huffmanCodes(from lengths: [CodeLength]) -> HuffmanCodes { // Sort `lengths` array to calculate canonical Huffman code. let sortedLengths = lengths.sorted() diff --git a/Sources/Common/CodingTree/DecodingTree.swift b/Sources/Common/CodingTree/DecodingTree.swift index 8149f3e9..65e1e615 100644 --- a/Sources/Common/CodingTree/DecodingTree.swift +++ b/Sources/Common/CodingTree/DecodingTree.swift @@ -13,14 +13,14 @@ final class DecodingTree { private let tree: [Int] private let leafCount: Int - init(codes: [Code], maxBits: Int, _ bitReader: BitReader) { + init(_ huffmanCodes: HuffmanCodes, _ bitReader: BitReader) { self.bitReader = bitReader // Calculate maximum amount of leaves in a tree. - self.leafCount = 1 << (maxBits + 1) + self.leafCount = 1 << (huffmanCodes.maxBits + 1) var tree = Array(repeating: -1, count: leafCount) - for code in codes { + for code in huffmanCodes.codes { // Put code in its place in the tree. var treeCode = code.code var index = 0 diff --git a/Sources/Deflate/Deflate+Compress.swift b/Sources/Deflate/Deflate+Compress.swift index 1bb39043..b665d115 100644 --- a/Sources/Deflate/Deflate+Compress.swift +++ b/Sources/Deflate/Deflate+Compress.swift @@ -106,9 +106,9 @@ extension Deflate: CompressionAlgorithm { // Constructing Huffman trees for the case of block with preset alphabets. // In this case codes for literals and distances are fixed. /// Huffman tree for literal and length symbols/codes. - let mainLiterals = EncodingTree(codes: Constants.staticHuffmanLiteralCodes, bitWriter, reverseCodes: true) + let mainLiterals = EncodingTree(codes: Constants.staticHuffmanLiteralCodes.codes, bitWriter, reverseCodes: true) /// Huffman tree for backward distance symbols/codes. - let mainDistances = EncodingTree(codes: Constants.staticHuffmanDistanceCodes, bitWriter, reverseCodes: true) + let mainDistances = EncodingTree(codes: Constants.staticHuffmanDistanceCodes.codes, bitWriter, reverseCodes: true) for code in bldCodes { switch code { diff --git a/Sources/Deflate/Deflate+Constants.swift b/Sources/Deflate/Deflate+Constants.swift index ca7a2cea..eb30d3f3 100644 --- a/Sources/Deflate/Deflate+Constants.swift +++ b/Sources/Deflate/Deflate+Constants.swift @@ -10,8 +10,8 @@ extension Deflate { struct Constants { // Precomputed codes for the static Huffman literal and distance trees. - static let staticHuffmanLiteralCodes = - [Code(bits: 7, code: 0, symbol: 256), Code(bits: 7, code: 64, symbol: 257), + static let staticHuffmanLiteralCodes: HuffmanCodes = + ([Code(bits: 7, code: 0, symbol: 256), Code(bits: 7, code: 64, symbol: 257), Code(bits: 7, code: 32, symbol: 258), Code(bits: 7, code: 96, symbol: 259), Code(bits: 7, code: 16, symbol: 260), Code(bits: 7, code: 80, symbol: 261), Code(bits: 7, code: 48, symbol: 262), Code(bits: 7, code: 112, symbol: 263), @@ -154,10 +154,10 @@ extension Deflate { Code(bits: 9, code: 63, symbol: 248), Code(bits: 9, code: 319, symbol: 249), Code(bits: 9, code: 191, symbol: 250), Code(bits: 9, code: 447, symbol: 251), Code(bits: 9, code: 127, symbol: 252), Code(bits: 9, code: 383, symbol: 253), - Code(bits: 9, code: 255, symbol: 254), Code(bits: 9, code: 511, symbol: 255)] + Code(bits: 9, code: 255, symbol: 254), Code(bits: 9, code: 511, symbol: 255)], 9) - static let staticHuffmanDistanceCodes = - [Code(bits: 5, code: 0, symbol: 0), Code(bits: 5, code: 16, symbol: 1), + static let staticHuffmanDistanceCodes: HuffmanCodes = + ([Code(bits: 5, code: 0, symbol: 0), Code(bits: 5, code: 16, symbol: 1), Code(bits: 5, code: 8, symbol: 2), Code(bits: 5, code: 24, symbol: 3), Code(bits: 5, code: 4, symbol: 4), Code(bits: 5, code: 20, symbol: 5), Code(bits: 5, code: 12, symbol: 6), Code(bits: 5, code: 28, symbol: 7), @@ -172,7 +172,7 @@ extension Deflate { Code(bits: 5, code: 3, symbol: 24), Code(bits: 5, code: 19, symbol: 25), Code(bits: 5, code: 11, symbol: 26), Code(bits: 5, code: 27, symbol: 27), Code(bits: 5, code: 7, symbol: 28), Code(bits: 5, code: 23, symbol: 29), - Code(bits: 5, code: 15, symbol: 30), Code(bits: 5, code: 31, symbol: 31)] + Code(bits: 5, code: 15, symbol: 30), Code(bits: 5, code: 31, symbol: 31)], 5) static let codeLengthOrders: [Int] = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15] diff --git a/Sources/Deflate/Deflate.swift b/Sources/Deflate/Deflate.swift index c49a3504..60c2970a 100644 --- a/Sources/Deflate/Deflate.swift +++ b/Sources/Deflate/Deflate.swift @@ -77,8 +77,8 @@ public class Deflate: DecompressionAlgorithm { if blockType == 1 { // Static Huffman // In this case codes for literals and distances are fixed. // Initialize trees from bootstraps. - mainLiterals = DecodingTree(codes: Constants.staticHuffmanLiteralCodes, maxBits: 9, bitReader) - mainDistances = DecodingTree(codes: Constants.staticHuffmanDistanceCodes, maxBits: 5, bitReader) + mainLiterals = DecodingTree(Constants.staticHuffmanLiteralCodes, bitReader) + mainDistances = DecodingTree(Constants.staticHuffmanDistanceCodes, bitReader) } else { // Dynamic Huffman // In this case there are Huffman codes for two alphabets in data right after block header. // Each code defined by a sequence of code lengths (which are compressed themselves with Huffman). @@ -102,8 +102,7 @@ public class Deflate: DecompressionAlgorithm { } let dynamicCodes = Code.huffmanCodes(from: Deflate.lengths(from: orderedCodeLengths)) /// Huffman tree for code lengths. Each code in the main alphabets is coded with this tree. - let dynamicCodeTree = DecodingTree(codes: dynamicCodes.codes, maxBits: dynamicCodes.maxBits, - bitReader) + let dynamicCodeTree = DecodingTree(dynamicCodes, bitReader) // Now we need to read codes (code lengths) for two main alphabets (trees). var codeLengths: [Int] = [] @@ -154,10 +153,10 @@ public class Deflate: DecompressionAlgorithm { // We have read codeLengths for both trees at once. // Now we need to split them and make corresponding trees. let literalCodes = Code.huffmanCodes(from: Deflate.lengths(from: Array(codeLengths[0..