Added new function to BitToByteWriter which writes a number with specified amount of bits.

This commit is contained in:
Timofey Solomko
2017-02-08 19:34:07 +03:00
parent 0db34d6820
commit b1100a7594
2 changed files with 20 additions and 25 deletions
+12
View File
@@ -78,6 +78,18 @@ final class BitToByteWriter {
}
}
func write(number: Int, bitsCount: Int) {
var mask = 1
for _ in 0..<bitsCount {
if number & mask > 0 {
self.write(bit: 1)
} else {
self.write(bit: 0)
}
mask <<= 1
}
}
func finish() {
self.buffer.append(self.currentByte)
self.currentByte = 0
+8 -25
View File
@@ -233,22 +233,23 @@ public final class Deflate: DecompressionAlgorithm {
public static func compress(data: Data) throws -> Data {
let bytes = data.toArray(type: UInt8.self)
let bldCodes = Deflate.lengthEncode(bytes)
let huffmanEncodedBytes = Deflate.huffmanEncode(bldCodes)
let huffmanEncodedBytes = Deflate.encodeHuffmanBlock(bldCodes)
return Data(bytes: huffmanEncodedBytes)
}
private static func huffmanEncode(_ bldCodes: [BLDCode]) -> [UInt8] {
/// Empty DWP object for creating Huffman trees.
var pointerData = DataWithPointer(data: Data(), bitOrder: .reversed)
private static func encodeHuffmanBlock(_ bldCodes: [BLDCode]) -> [UInt8] {
let bitWriter = BitToByteWriter(bitOrder: .reversed)
// Write block header.
// Note: For now it is only static huffman blocks.
// Note: Only one block is supported for now.
bitWriter.write(bit: 1)
bitWriter.write(bits: [1, 0])
/// Empty DWP object for creating Huffman trees.
var pointerData = DataWithPointer(data: Data(), bitOrder: .reversed)
// Constructing Huffman trees for the case of block with preset alphabets.
// In this case codes for literals and distances are fixed.
// Bootstraps for trees (first element in pair is code, second is number of bits).
@@ -272,16 +273,7 @@ public final class Deflate: DecompressionAlgorithm {
// TODO: Add check for empty returned array.
bitWriter.write(bits: mainLiterals.code(symbol: lengthSymbol))
var mask = 1
for _ in 0..<extraLengthBitsCount {
if lengthExtra & mask > 0 {
bitWriter.write(bit: 1)
} else {
bitWriter.write(bit: 0)
}
mask <<= 1
}
bitWriter.write(number: lengthExtra, bitsCount: extraLengthBitsCount)
let distanceSymbol = ((HuffmanTree.Constants.distanceBase.index { $0 > distance }) ?? 30) - 1
let distanceExtra = distance - HuffmanTree.Constants.distanceBase[distanceSymbol]
@@ -290,16 +282,7 @@ public final class Deflate: DecompressionAlgorithm {
// TODO: Add check for empty returned array.
bitWriter.write(bits: mainDistances.code(symbol: distanceSymbol))
mask = 1
for _ in 0..<extraDistanceBitsCount {
if distanceExtra & mask > 0 {
bitWriter.write(bit: 1)
} else {
bitWriter.write(bit: 0)
}
mask <<= 1
}
bitWriter.write(number: distanceExtra, bitsCount: extraDistanceBitsCount)
}
}