| ... | ... | @@ -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 | 142 | fn decodeSymbol(self: *Decompress, decoder: anytype) !Symbol { |
| 143 | // Maximum code len is 15 bits. |
| 147 | 144 | const sym = try decoder.find(@bitReverse(try self.peekBits(u15))); |
| 148 | 145 | try self.tossBits(sym.code_bits); |
| 149 | 146 | return sym; |
| ... | ... | @@ -451,31 +448,30 @@ fn peekBitsEnding(d: *Decompress, comptime U: type) !U { |
| 451 | 448 | const remaining_bits = d.remaining_bits; |
| 452 | 449 | const next_bits = d.next_bits; |
| 453 | 450 | const in = d.input; |
| 454 | | var u: U = 0; |
| 451 | var u: usize = 0; |
| 455 | 452 | var remaining_needed_bits = @bitSizeOf(U) - remaining_bits; |
| 456 | | var peek_len: usize = 0; |
| 457 | | while (@bitSizeOf(U) >= 8 and remaining_needed_bits >= 8) { |
| 458 | | peek_len += 1; |
| 459 | | const byte = try specialPeek(in, next_bits, peek_len); |
| 460 | | u = (u << 8) | byte; |
| 453 | var i: usize = 0; |
| 454 | while (remaining_needed_bits >= 8) { |
| 455 | const byte = try specialPeek(in, next_bits, i); |
| 456 | u |= @as(usize, byte) << @intCast(i * 8); |
| 461 | 457 | remaining_needed_bits -= 8; |
| 458 | i += 1; |
| 462 | 459 | } |
| 463 | 460 | if (remaining_needed_bits != 0) { |
| 464 | | peek_len += 1; |
| 465 | | const byte = try specialPeek(in, next_bits, peek_len); |
| 466 | | u = @intCast((@as(usize, u) << remaining_needed_bits) | (byte & ((@as(usize, 1) << remaining_needed_bits) - 1))); |
| 461 | const byte = try specialPeek(in, next_bits, i); |
| 462 | u |= @as(usize, byte) << @intCast((i * 8) + remaining_needed_bits); |
| 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 | 467 | /// If there is any unconsumed data, handles EndOfStream by pretending there |
| 472 | 468 | /// are zeroes afterwards. |
| 473 | | fn specialPeek(in: *Reader, next_bits: usize, n: usize) Reader.Error!u8 { |
| 474 | | const peeked = in.peek(n) catch |err| switch (err) { |
| 469 | fn specialPeek(in: *Reader, next_bits: usize, i: usize) Reader.Error!u8 { |
| 470 | const peeked = in.peek(i + 1) catch |err| switch (err) { |
| 475 | 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 | 477 | fn tossBits(d: *Decompress, n: u6) !void { |
| ... | ... | @@ -507,11 +503,14 @@ fn tossBitsEnding(d: *Decompress, n: u6) !void { |
| 507 | 503 | if (remaining_needed_bits == 0) { |
| 508 | 504 | d.next_bits = 0; |
| 509 | 505 | d.remaining_bits = 0; |
| 510 | | } else { |
| 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); |
| 506 | return; |
| 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 | 516 | fn takeBitsRuntime(d: *Decompress, n: u4) !u16 { |