| ... | ... | @@ -3,7 +3,7 @@ const assert = std.debug.assert; |
| 3 | 3 | const testing = std.testing; |
| 4 | 4 | |
| 5 | 5 | const hfd = @import("huffman_decoder.zig"); |
| 6 | | const BitReader = @import("bit_reader.zig").BitReader64; |
| 6 | const BitReader = @import("bit_reader.zig").BitReader; |
| 7 | 7 | const CircularBuffer = @import("CircularBuffer.zig"); |
| 8 | 8 | const Container = @import("container.zig").Container; |
| 9 | 9 | const Token = @import("Token.zig"); |
| ... | ... | @@ -17,8 +17,16 @@ pub fn decompress(comptime container: Container, reader: anytype, writer: anytyp |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | 19 | /// Inflate decompressor for the reader type. |
| 20 | | pub fn decompressor(comptime container: Container, reader: anytype) Inflate(container, @TypeOf(reader)) { |
| 21 | | return Inflate(container, @TypeOf(reader)).init(reader); |
| 20 | pub fn decompressor(comptime container: Container, reader: anytype) Decompressor(container, @TypeOf(reader)) { |
| 21 | return Decompressor(container, @TypeOf(reader)).init(reader); |
| 22 | } |
| 23 | |
| 24 | pub fn Decompressor(comptime container: Container, comptime ReaderType: type) type { |
| 25 | // zlib has 4 bytes footer, lookahead of 4 bytes ensures that we will not overshoot. |
| 26 | // gzip has 8 bytes footer so we will not overshoot even with 8 bytes of lookahead. |
| 27 | // For raw deflate there is always possibility of overshot so we use 8 bytes lookahead. |
| 28 | const lookahead: type = if (container == .zlib) u32 else u64; |
| 29 | return Inflate(container, lookahead, ReaderType); |
| 22 | 30 | } |
| 23 | 31 | |
| 24 | 32 | /// Inflate decompresses deflate bit stream. Reads compressed data from reader |
| ... | ... | @@ -40,9 +48,12 @@ pub fn decompressor(comptime container: Container, reader: anytype) Inflate(cont |
| 40 | 48 | /// * 64K for history (CircularBuffer) |
| 41 | 49 | /// * ~10K huffman decoders (Literal and DistanceDecoder) |
| 42 | 50 | /// |
| 43 | | pub fn Inflate(comptime container: Container, comptime ReaderType: type) type { |
| 51 | pub fn Inflate(comptime container: Container, comptime LookaheadType: type, comptime ReaderType: type) type { |
| 52 | assert(LookaheadType == u32 or LookaheadType == u64); |
| 53 | const BitReaderType = BitReader(LookaheadType, ReaderType); |
| 54 | |
| 44 | 55 | return struct { |
| 45 | | const BitReaderType = BitReader(ReaderType); |
| 56 | //const BitReaderType = BitReader(ReaderType); |
| 46 | 57 | const F = BitReaderType.flag; |
| 47 | 58 | |
| 48 | 59 | bits: BitReaderType = .{}, |
| ... | ... | @@ -219,9 +230,14 @@ pub fn Inflate(comptime container: Container, comptime ReaderType: type) type { |
| 219 | 230 | switch (sym.kind) { |
| 220 | 231 | .literal => self.hist.write(sym.symbol), |
| 221 | 232 | .match => { // Decode match backreference <length, distance> |
| 222 | | try self.bits.fill(5 + 15 + 13); // so we can use buffered reads |
| 233 | // fill so we can use buffered reads |
| 234 | if (LookaheadType == u32) |
| 235 | try self.bits.fill(5 + 15) |
| 236 | else |
| 237 | try self.bits.fill(5 + 15 + 13); |
| 223 | 238 | const length = try self.decodeLength(sym.symbol); |
| 224 | 239 | const dsm = try self.decodeSymbol(&self.dst_dec); |
| 240 | if (LookaheadType == u32) try self.bits.fill(13); |
| 225 | 241 | const distance = try self.decodeDistance(dsm.symbol); |
| 226 | 242 | try self.hist.writeMatch(length, distance); |
| 227 | 243 | }, |