diff --git a/SWCompression.xcodeproj/project.pbxproj b/SWCompression.xcodeproj/project.pbxproj index 119c7ee5..93274e71 100644 --- a/SWCompression.xcodeproj/project.pbxproj +++ b/SWCompression.xcodeproj/project.pbxproj @@ -147,6 +147,10 @@ 0681B3E11E44F674001A9D79 /* BitWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0681B3DD1E44F674001A9D79 /* BitWriter.swift */; }; 0685E6241F123F0D008655AA /* test_zip_bzip2.zip in Resources */ = {isa = PBXBuildFile; fileRef = 0685E6231F123F0D008655AA /* test_zip_bzip2.zip */; }; 068B36791ED0AC050016269E /* full_test.tar in Resources */ = {isa = PBXBuildFile; fileRef = 068B36781ED0AC050016269E /* full_test.tar */; }; + 06912BD21F5C8F3D0070BB60 /* Deflate+Lengths.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06912BD11F5C8F3D0070BB60 /* Deflate+Lengths.swift */; }; + 06912BD31F5C8F3D0070BB60 /* Deflate+Lengths.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06912BD11F5C8F3D0070BB60 /* Deflate+Lengths.swift */; }; + 06912BD41F5C8F3D0070BB60 /* Deflate+Lengths.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06912BD11F5C8F3D0070BB60 /* Deflate+Lengths.swift */; }; + 06912BD51F5C8F3D0070BB60 /* Deflate+Lengths.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06912BD11F5C8F3D0070BB60 /* Deflate+Lengths.swift */; }; 0691B9401EBE3E100037EE58 /* test.tar in Resources */ = {isa = PBXBuildFile; fileRef = 0691B93F1EBE3E100037EE58 /* test.tar */; }; 0693DF521F2E499F00602300 /* test_empty_dir.7z in Resources */ = {isa = PBXBuildFile; fileRef = 0693DF501F2E499F00602300 /* test_empty_dir.7z */; }; 0693DF531F2E499F00602300 /* test_empty_file.7z in Resources */ = {isa = PBXBuildFile; fileRef = 0693DF511F2E499F00602300 /* test_empty_file.7z */; }; @@ -398,6 +402,7 @@ 0681B3DD1E44F674001A9D79 /* BitWriter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BitWriter.swift; path = Sources/BitWriter.swift; sourceTree = SOURCE_ROOT; }; 0685E6231F123F0D008655AA /* test_zip_bzip2.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = test_zip_bzip2.zip; sourceTree = ""; }; 068B36781ED0AC050016269E /* full_test.tar */ = {isa = PBXFileReference; lastKnownFileType = archive.tar; path = full_test.tar; sourceTree = ""; }; + 06912BD11F5C8F3D0070BB60 /* Deflate+Lengths.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Deflate+Lengths.swift"; sourceTree = ""; }; 0691B93F1EBE3E100037EE58 /* test.tar */ = {isa = PBXFileReference; lastKnownFileType = archive.tar; path = test.tar; sourceTree = ""; }; 0693DF501F2E499F00602300 /* test_empty_dir.7z */ = {isa = PBXFileReference; lastKnownFileType = file; path = test_empty_dir.7z; sourceTree = ""; }; 0693DF511F2E499F00602300 /* test_empty_file.7z */ = {isa = PBXFileReference; lastKnownFileType = file; path = test_empty_file.7z; sourceTree = ""; }; @@ -882,6 +887,7 @@ 061FCE251DBCC4BE0052F7BE /* Deflate.swift */, 06CDFCA71F111D9700292758 /* DeflateError.swift */, 06CDFC9D1F111D2600292758 /* DeflateCompression.swift */, + 06912BD11F5C8F3D0070BB60 /* Deflate+Lengths.swift */, ); name = Deflate; sourceTree = ""; @@ -1238,6 +1244,7 @@ 0681B3DF1E44F674001A9D79 /* BitWriter.swift in Sources */, 061C063E1F0E8AB700832F0C /* ZipError.swift in Sources */, 069D0FE71E0D6C6400D8AA87 /* LZMADecoder.swift in Sources */, + 06912BD31F5C8F3D0070BB60 /* Deflate+Lengths.swift in Sources */, 06A9606B1F1E7E0D0078E6D1 /* 7zSubstreamInfo.swift in Sources */, 06FED40D1DD7717E0013DFB2 /* BZip2.swift in Sources */, 06A960611F1E7DE20078E6D1 /* 7zFileInfo.swift in Sources */, @@ -1298,6 +1305,7 @@ 0681B3E01E44F674001A9D79 /* BitWriter.swift in Sources */, 061C063F1F0E8AB700832F0C /* ZipError.swift in Sources */, 069D0FE81E0D6C6400D8AA87 /* LZMADecoder.swift in Sources */, + 06912BD41F5C8F3D0070BB60 /* Deflate+Lengths.swift in Sources */, 06A9606C1F1E7E0D0078E6D1 /* 7zSubstreamInfo.swift in Sources */, 065569711DC65C2B00A47E66 /* Deflate.swift in Sources */, 06A960621F1E7DE20078E6D1 /* 7zFileInfo.swift in Sources */, @@ -1358,6 +1366,7 @@ 0681B3E11E44F674001A9D79 /* BitWriter.swift in Sources */, 061C06401F0E8AB700832F0C /* ZipError.swift in Sources */, 069D0FE91E0D6C6400D8AA87 /* LZMADecoder.swift in Sources */, + 06912BD51F5C8F3D0070BB60 /* Deflate+Lengths.swift in Sources */, 06A9606D1F1E7E0D0078E6D1 /* 7zSubstreamInfo.swift in Sources */, 06FED40F1DD7717E0013DFB2 /* BZip2.swift in Sources */, 06A960631F1E7DE20078E6D1 /* 7zFileInfo.swift in Sources */, @@ -1418,6 +1427,7 @@ 0681B3DE1E44F674001A9D79 /* BitWriter.swift in Sources */, 061C063D1F0E8AB700832F0C /* ZipError.swift in Sources */, 069D0FE61E0D6C6400D8AA87 /* LZMADecoder.swift in Sources */, + 06912BD21F5C8F3D0070BB60 /* Deflate+Lengths.swift in Sources */, 06A9606A1F1E7E0D0078E6D1 /* 7zSubstreamInfo.swift in Sources */, 06A3933B1DE0709300182E12 /* Deflate.swift in Sources */, 06A960601F1E7DE20078E6D1 /* 7zFileInfo.swift in Sources */, diff --git a/Sources/Deflate+Lengths.swift b/Sources/Deflate+Lengths.swift new file mode 100644 index 00000000..cad58dc6 --- /dev/null +++ b/Sources/Deflate+Lengths.swift @@ -0,0 +1,39 @@ +// Copyright (c) 2017 Timofey Solomko +// Licensed under MIT License +// +// See LICENSE for license information + +import Foundation + +// Deflate specific functions for generation of HuffmanLength arrays from different inputs. +extension Deflate { + + static func lengths(from bootStrap: [(symbol: Int, codeLength: Int)]) -> [HuffmanLength] { + // Fills the 'lengths' array with pairs of (symbol, codeLength) from a 'bootstrap'. + var lengths = [HuffmanLength]() + var start = bootStrap[0].symbol + var bits = bootStrap[0].codeLength + for pair in bootStrap[1.. 0 { + for i in start.. [HuffmanLength] { + var lengths = [HuffmanLength]() + for (i, codeLength) in orderedCodeLengths.enumerated() where codeLength > 0 { + lengths.append(HuffmanLength(symbol: i, codeLength: codeLength)) + } + return lengths + } + +} diff --git a/Sources/Deflate.swift b/Sources/Deflate.swift index 012acfba..572a138d 100644 --- a/Sources/Deflate.swift +++ b/Sources/Deflate.swift @@ -10,8 +10,8 @@ public class Deflate: DecompressionAlgorithm { struct Constants { // Bootstraps for Static Huffman trees (first element in tuple is code, second is number of bits). - static let staticHuffmanBootstrap = HuffmanLength.lengths(from: [(0, 8), (144, 9), (256, 7), (280, 8), (288, -1)]) - static let staticHuffmanDistancesBootstrap = HuffmanLength.lengths(from: [(0, 5), (32, -1)]) + static let staticHuffmanBootstrap = Deflate.lengths(from: [(0, 8), (144, 9), (256, 7), (280, 8), (288, -1)]) + static let staticHuffmanDistancesBootstrap = Deflate.lengths(from: [(0, 5), (32, -1)]) static let codeLengthOrders: [Int] = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15] @@ -122,7 +122,7 @@ public class Deflate: DecompressionAlgorithm { lengthsForOrder[Constants.codeLengthOrders[i]] = bitReader.intFromBits(count: 3) } /// Huffman tree for code lengths. Each code in the main alphabets is coded with this tree. - let dynamicCodes = DecodingHuffmanTree(lengths: HuffmanLength.lengths(from: lengthsForOrder), bitReader) + let dynamicCodes = DecodingHuffmanTree(lengths: Deflate.lengths(from: lengthsForOrder), bitReader) // Now we need to read codes (code lengths) for two main alphabets (trees). var codeLengths: [Int] = [] @@ -164,9 +164,9 @@ public class Deflate: DecompressionAlgorithm { // We have read codeLengths for both trees at once. // Now we need to split them and make corresponding trees. mainLiterals = DecodingHuffmanTree(lengths: - HuffmanLength.lengths(from: Array(codeLengths[0.. [HuffmanLength] { - // Fills the 'lengths' array with pairs of (symbol, codeLength) from a 'bootstrap'. - var lengths = [HuffmanLength]() - var start = bootStrap[0].symbol - var bits = bootStrap[0].codeLength - for pair in bootStrap[1.. 0 { - for i in start.. [HuffmanLength] { - var lengths = [HuffmanLength]() - for (i, codeLength) in orderedCodeLengths.enumerated() where codeLength > 0 { - lengths.append(HuffmanLength(symbol: i, codeLength: codeLength)) - } - return lengths - } - } extension HuffmanLength: Comparable {