mirror of
https://github.com/tsolomko/SWCompression.git
synced 2026-06-23 14:56:41 +00:00
e32887084c
This seems to have a positive impact on the performance of Deflate and BZip2 decompression and compression. It is unclear to me why these two were declared as classes in the first place.
62 lines
1.8 KiB
Swift
62 lines
1.8 KiB
Swift
// Copyright (c) 2026 Timofey Solomko
|
|
// Licensed under MIT License
|
|
//
|
|
// See LICENSE for license information
|
|
|
|
import BitByteData
|
|
|
|
fileprivate struct CodingIndex {
|
|
|
|
let treeCode: Int
|
|
let bitSize: Int
|
|
|
|
}
|
|
|
|
struct EncodingTree {
|
|
|
|
private let bitWriter: BitWriter
|
|
|
|
private let codingIndices: [CodingIndex]
|
|
|
|
init(_ codes: [Code], _ bitWriter: BitWriter, reverseCodes: Bool = false) {
|
|
self.bitWriter = bitWriter
|
|
|
|
var codingIndices = Array(repeating: CodingIndex(treeCode: -1, bitSize: -1), count: codes.count)
|
|
|
|
for code in codes {
|
|
// Codes have already been reversed.
|
|
// TODO: This assumption may be only correct for Huffman codes.
|
|
let treeCode = reverseCodes ? code.code : code.code.reversed(bits: code.bits)
|
|
codingIndices[code.symbol] = CodingIndex(treeCode: treeCode, bitSize: code.bits)
|
|
}
|
|
self.codingIndices = codingIndices
|
|
}
|
|
|
|
func code(symbol: Int) {
|
|
guard symbol < self.codingIndices.count
|
|
else { fatalError("Symbol is not found.") }
|
|
|
|
let codingIndex = self.codingIndices[symbol]
|
|
|
|
guard codingIndex.treeCode > -1
|
|
else { fatalError("Symbol is not found.") }
|
|
|
|
self.bitWriter.write(number: codingIndex.treeCode, bitsCount: codingIndex.bitSize)
|
|
}
|
|
|
|
func bitSize(for stats: [Int]) -> Int {
|
|
var totalSize = 0
|
|
for (symbol, count) in stats.enumerated() where count > 0 {
|
|
guard symbol < self.codingIndices.count
|
|
else { fatalError("Symbol is not found.") }
|
|
let codingIndex = self.codingIndices[symbol]
|
|
guard codingIndex.treeCode > -1
|
|
else { fatalError("Symbol is not found.") }
|
|
|
|
totalSize += count * codingIndex.bitSize
|
|
}
|
|
return totalSize
|
|
}
|
|
|
|
}
|