| ... | @@ -139,11 +139,8 @@ fn dynamicCodeLength(self: *Decompress, code: u16, lens: []u4, pos: usize) !usiz | ... | @@ -139,11 +139,8 @@ fn dynamicCodeLength(self: *Decompress, code: u16, lens: []u4, pos: usize) !usiz |
| 139 | } | 139 | } |
| 140 | } | 140 | } |
| 141 | | 141 | |
| 142 | // Peek 15 bits from bits reader (maximum code len is 15 bits). Use | | |
| 143 | // decoder to find symbol for that code. We then know how many bits is | | |
| 144 | // used. Shift bit reader for that much bits, those bits are used. And | | |
| 145 | // return symbol. | | |
| 146 | fn decodeSymbol(self: *Decompress, decoder: anytype) !Symbol { | 142 | fn decodeSymbol(self: *Decompress, decoder: anytype) !Symbol { |
| | 143 | // Maximum code len is 15 bits. |
| 147 | const sym = try decoder.find(@bitReverse(try self.peekBits(u15))); | 144 | const sym = try decoder.find(@bitReverse(try self.peekBits(u15))); |
| 148 | try self.tossBits(sym.code_bits); | 145 | try self.tossBits(sym.code_bits); |
| 149 | return sym; | 146 | return sym; |
| ... | @@ -451,31 +448,30 @@ fn peekBitsEnding(d: *Decompress, comptime U: type) !U { | ... | @@ -451,31 +448,30 @@ fn peekBitsEnding(d: *Decompress, comptime U: type) !U { |
| 451 | const remaining_bits = d.remaining_bits; | 448 | const remaining_bits = d.remaining_bits; |
| 452 | const next_bits = d.next_bits; | 449 | const next_bits = d.next_bits; |
| 453 | const in = d.input; | 450 | const in = d.input; |
| 454 | var u: U = 0; | 451 | var u: usize = 0; |
| 455 | var remaining_needed_bits = @bitSizeOf(U) - remaining_bits; | 452 | var remaining_needed_bits = @bitSizeOf(U) - remaining_bits; |
| 456 | var peek_len: usize = 0; | 453 | var i: usize = 0; |
| 457 | while (@bitSizeOf(U) >= 8 and remaining_needed_bits >= 8) { | 454 | while (remaining_needed_bits >= 8) { |
| 458 | peek_len += 1; | 455 | const byte = try specialPeek(in, next_bits, i); |
| 459 | const byte = try specialPeek(in, next_bits, peek_len); | 456 | u |= @as(usize, byte) << @intCast(i * 8); |
| 460 | u = (u << 8) | byte; | | |
| 461 | remaining_needed_bits -= 8; | 457 | remaining_needed_bits -= 8; |
| | 458 | i += 1; |
| 462 | } | 459 | } |
| 463 | if (remaining_needed_bits != 0) { | 460 | if (remaining_needed_bits != 0) { |
| 464 | peek_len += 1; | 461 | const byte = try specialPeek(in, next_bits, i); |
| 465 | const byte = try specialPeek(in, next_bits, peek_len); | 462 | u |= @as(usize, byte) << @intCast((i * 8) + remaining_needed_bits); |
| 466 | u = @intCast((@as(usize, u) << remaining_needed_bits) | (byte & ((@as(usize, 1) << remaining_needed_bits) - 1))); | | |
| 467 | } | 463 | } |
| 468 | return @intCast((@as(usize, u) << remaining_bits) | next_bits); | 464 | return @truncate((u << remaining_bits) | next_bits); |
| 469 | } | 465 | } |
| 470 | | 466 | |
| 471 | /// If there is any unconsumed data, handles EndOfStream by pretending there | 467 | /// If there is any unconsumed data, handles EndOfStream by pretending there |
| 472 | /// are zeroes afterwards. | 468 | /// are zeroes afterwards. |
| 473 | fn specialPeek(in: *Reader, next_bits: usize, n: usize) Reader.Error!u8 { | 469 | fn specialPeek(in: *Reader, next_bits: usize, i: usize) Reader.Error!u8 { |
| 474 | const peeked = in.peek(n) catch |err| switch (err) { | 470 | const peeked = in.peek(i + 1) catch |err| switch (err) { |
| 475 | error.ReadFailed => return error.ReadFailed, | 471 | error.ReadFailed => return error.ReadFailed, |
| 476 | error.EndOfStream => if (next_bits == 0 and n == 0) return error.EndOfStream else return 0, | 472 | error.EndOfStream => if (next_bits == 0 and i == 0) return error.EndOfStream else return 0, |
| 477 | }; | 473 | }; |
| 478 | return peeked[n - 1]; | 474 | return peeked[i]; |
| 479 | } | 475 | } |
| 480 | | 476 | |
| 481 | fn tossBits(d: *Decompress, n: u6) !void { | 477 | fn tossBits(d: *Decompress, n: u6) !void { |
| ... | @@ -507,11 +503,14 @@ fn tossBitsEnding(d: *Decompress, n: u6) !void { | ... | @@ -507,11 +503,14 @@ fn tossBitsEnding(d: *Decompress, n: u6) !void { |
| 507 | if (remaining_needed_bits == 0) { | 503 | if (remaining_needed_bits == 0) { |
| 508 | d.next_bits = 0; | 504 | d.next_bits = 0; |
| 509 | d.remaining_bits = 0; | 505 | d.remaining_bits = 0; |
| 510 | } else { | 506 | return; |
| 511 | const byte = try in.takeByte(); | | |
| 512 | d.next_bits = @as(usize, byte) >> remaining_needed_bits; | | |
| 513 | d.remaining_bits = @intCast(8 - remaining_needed_bits); | | |
| 514 | } | 507 | } |
| | 508 | const byte = in.takeByte() catch |err| switch (err) { |
| | 509 | error.ReadFailed => return error.ReadFailed, |
| | 510 | error.EndOfStream => if (remaining_bits == 0) return error.EndOfStream else 0, |
| | 511 | }; |
| | 512 | d.next_bits = @as(usize, byte) >> remaining_needed_bits; |
| | 513 | d.remaining_bits = @intCast(8 - remaining_needed_bits); |
| 515 | } | 514 | } |
| 516 | | 515 | |
| 517 | fn takeBitsRuntime(d: *Decompress, n: u4) !u16 { | 516 | fn takeBitsRuntime(d: *Decompress, n: u4) !u16 { |