1 //! Deflate format (RFC 1951) support.
3 //! This module provides functionality for decompressing raw deflated streams via [`Inflate`] and gzip files (RFC 1952) via [`gzip_decode`].
5 //! [`Inflate`]: ./struct.Inflate.html
6 //! [`gzip_decode`]: ./fn.gzip_decode.html
10 //! Decompressing full input buffer into sufficiently large output buffer:
12 //! # use nihav_core::compr::DecompressError;
13 //! use nihav_core::compr::deflate::Inflate;
15 //! # fn decompress(input: &[u8]) -> Result<(), DecompressError> {
16 //! # let mut output_buffer = [0u8; 16];
17 //! let output_length = Inflate::uncompress(input, &mut output_buffer)?;
22 //! Decompressing input chunks into portions of output:
24 //! use nihav_core::compr::DecompressError;
25 //! use nihav_core::compr::deflate::Inflate;
27 //! # fn decompress(input_data: &[u8]) -> Result<(), DecompressError> {
28 //! let mut inflate = Inflate::new();
29 //! let mut dst_buf: Vec<u8> = Vec::new();
30 //! let mut output_chunk = [0u8; 1024];
31 //! for src in input_data.chunks(512) {
32 //! let mut repeat = false;
34 //! let ret = inflate.decompress_data(src, &mut output_chunk, repeat);
36 //! Ok(len) => { // we got a buffer decoded successfully to the end
37 //! dst_buf.extend_from_slice(&output_chunk[..len]);
40 //! Err(DecompressError::ShortData) => { // this block of data was fully read
43 //! Err(DecompressError::OutputFull) => {
44 //! // the output buffer is full, flush it and continue decoding the same block
46 //! dst_buf.extend_from_slice(&output_chunk);
58 use crate::io::byteio::*;
59 use crate::io::bitreader::*;
60 use crate::io::codebook::*;
63 const NUM_LITERALS: usize = 287;
64 const NUM_DISTS: usize = 32;
66 struct FixedLenCodeReader {}
68 impl CodebookDescReader<u16> for FixedLenCodeReader {
69 fn bits(&mut self, idx: usize) -> u8 {
71 else if idx < 256 { 9 }
72 else if idx < 280 { 7 }
75 #[allow(clippy::identity_op)]
76 fn code(&mut self, idx: usize) -> u32 {
77 let base = idx as u32;
78 let bits = self.bits(idx);
79 if idx < 144 { reverse_bits(base + 0x30, bits) }
80 else if idx < 256 { reverse_bits(base + 0x190 - 144, bits) }
81 else if idx < 280 { reverse_bits(base + 0x000 - 256, bits) }
82 else { reverse_bits(base + 0xC0 - 280, bits) }
84 fn sym (&mut self, idx: usize) -> u16 { idx as u16 }
85 fn len(&mut self) -> usize { NUM_LITERALS + 1 }
88 #[derive(Clone,Copy,Default)]
89 struct BitReaderState {
95 struct CurrentSource<'a> {
100 impl<'a> CurrentSource<'a> {
101 fn new(src: &'a [u8], br: BitReaderState) -> Self {
102 let mut newsrc = Self { src, br };
107 fn reinit(src: &'a [u8], br: BitReaderState) -> Self {
108 let mut newsrc = Self { src, br };
112 fn refill(&mut self) {
113 while (self.br.bits <= 24) && (self.br.pos < self.src.len()) {
114 self.br.bitbuf |= u32::from(self.src[self.br.pos]) << self.br.bits;
119 fn skip_cache(&mut self, nbits: u8) {
120 self.br.bitbuf >>= nbits;
121 self.br.bits -= nbits;
123 fn read(&mut self, nbits: u8) -> BitReaderResult<u32> {
124 if nbits == 0 { return Ok(0); }
125 if nbits > 16 { return Err(BitReaderError::TooManyBitsRequested); }
126 if self.br.bits < nbits {
128 if self.br.bits < nbits { return Err(BitReaderError::BitstreamEnd); }
130 let ret = self.br.bitbuf & ((1 << nbits) - 1);
131 self.skip_cache(nbits);
134 fn read_bool(&mut self) -> BitReaderResult<bool> {
135 if self.br.bits == 0 {
137 if self.br.bits == 0 { return Err(BitReaderError::BitstreamEnd); }
139 let ret = (self.br.bitbuf & 1) != 0;
143 fn peek(&mut self, nbits: u8) -> u32 {
144 if nbits == 0 || nbits > 16 { return 0; }
145 if self.br.bits < nbits {
148 self.br.bitbuf & ((1 << nbits) - 1)
150 fn skip(&mut self, nbits: u32) -> BitReaderResult<()> {
151 if u32::from(self.br.bits) >= nbits {
152 self.skip_cache(nbits as u8);
158 fn align(&mut self) {
159 let b = self.br.bits & 7;
161 self.skip_cache(8 - (b as u8));
164 fn left(&self) -> isize {
165 ((self.src.len() as isize) - (self.br.pos as isize)) * 8 + (self.br.bits as isize)
169 impl<'a, S: Copy> CodebookReader<S> for CurrentSource<'a> {
170 fn read_cb(&mut self, cb: &Codebook<S>) -> CodebookResult<S> {
173 let mut lut_bits = cb.lut_bits;
174 let orig_br = self.br;
176 let lut_idx = (self.peek(lut_bits) as usize) + (idx as usize);
177 if cb.table[lut_idx] == TABLE_FILL_VALUE { return Err(CodebookError::InvalidCode); }
178 let bits = cb.table[lut_idx] & 0x7F;
179 esc = (cb.table[lut_idx] & 0x80) != 0;
180 idx = (cb.table[lut_idx] >> 8) as usize;
181 let skip_bits = if esc { u32::from(lut_bits) } else { bits };
182 if (skip_bits as isize) > self.left() {
185 return Err(CodebookError::MemoryError);
187 self.skip(skip_bits as u32).unwrap();
188 lut_bits = bits as u8;
199 StaticBlockInvLen(u32),
200 StaticBlockCopy(usize),
202 FixedBlockLengthExt(usize, u8),
203 FixedBlockDist(usize),
204 FixedBlockDistExt(usize, usize, u8),
205 FixedBlockCopy(usize, usize),
206 FixedBlockLiteral(u8),
212 DynCodeLengthsAdd(usize),
214 DynBlockLengthExt(usize, u8),
216 DynBlockDistExt(usize, usize, u8),
217 DynCopy(usize, usize),
222 ///! The decompressor for deflated streams (RFC 1951).
225 fix_len_cb: Codebook<u16>,
235 dyn_len_cb: Option<Codebook<u32>>,
236 dyn_lit_cb: Option<Codebook<u32>>,
237 dyn_dist_cb: Option<Codebook<u32>>,
238 len_lengths: [u8; 19],
239 all_lengths: [u8; NUM_LITERALS + NUM_DISTS],
243 const LENGTH_ADD_BITS: [u8; 29] = [
244 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
245 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
246 4, 4, 4, 4, 5, 5, 5, 5, 0
248 const LENGTH_BASE: [u16; 29] = [
249 3, 4, 5, 6, 7, 8, 9, 10, 11, 13,
250 15, 17, 19, 23, 27, 31, 35, 43, 51, 59,
251 67, 83, 99, 115, 131, 163, 195, 227, 258
253 const DIST_ADD_BITS: [u8; 30] = [
254 0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
255 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
256 9, 9, 10, 10, 11, 11, 12, 12, 13, 13
258 const DIST_BASE: [u16; 30] = [
259 1, 2, 3, 4, 5, 7, 9, 13, 17, 25,
260 33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
261 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577
263 const LEN_RECODE: [usize; 19] = [
264 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
266 const REPEAT_BITS: [u8; 3] = [ 2, 3, 7 ];
267 const REPEAT_BASE: [u8; 3] = [ 3, 3, 11 ];
269 macro_rules! read_bits {
270 ($self: expr, $csrc: expr, $bits: expr) => ({
271 if $csrc.left() < $bits as isize {
273 return Err(DecompressError::ShortData);
275 $csrc.read($bits).unwrap()
279 macro_rules! read_cb {
280 ($self: expr, $csrc: expr, $cb: expr) => ({
281 let ret = $csrc.read_cb($cb);
282 if let Err(CodebookError::MemoryError) = ret {
284 return Err(DecompressError::ShortData);
289 $self.state = InflateState::End;
290 return Err(DecompressError::InvalidData);
297 ///! Creates a new instance of `Inflate` struct.
298 pub fn new() -> Self {
299 let mut cr = FixedLenCodeReader {};
300 let fix_len_cb = Codebook::new(&mut cr, CodebookMode::LSB).unwrap();
302 br: BitReaderState::default(),
309 state: InflateState::Start,
316 len_lengths: [0; 19],
317 all_lengths: [0; NUM_LITERALS + NUM_DISTS],
321 fn put_literal(&mut self, val: u8) {
322 self.buf[self.bpos] = val;
325 fn lz_copy(&mut self, offset: usize, len: usize, dst: &mut [u8]) -> DecompressResult<()> {
326 let mask = self.buf.len() - 1;
327 if self.bpos < offset {
328 return Err(DecompressError::InvalidData);
330 let cstart = (self.bpos - offset) & mask;
332 self.buf[(self.bpos + i) & mask] = self.buf[(cstart + i) & mask];
333 dst[i] = self.buf[(cstart + i) & mask];
338 ///! Reports whether decoder has finished decoding the input.
339 pub fn is_finished(&self) -> bool {
341 InflateState::End => true,
345 ///! Reports the current amount of bytes output into the destination buffer after the last run.
346 pub fn get_current_output_size(&self) -> usize { self.output_idx }
347 ///! Reports the total amount of bytes decoded so far.
348 pub fn get_total_output_size(&self) -> usize { self.bpos }
349 ///! Tries to decompress input data and write it to the output buffer.
351 ///! Since the decompressor can work with arbitrary input and output chunks its return value may have several meanings:
352 ///! * `Ok(len)` means the stream has been fully decoded and then number of bytes output into the destination buffer is returned.
353 ///! * [`DecompressError::ShortData`] means the input stream has been fully read but more data is needed.
354 ///! * [`DecompressError::OutputFull`] means the output buffer is full and should be flushed. Then decoding should continue on the same input block with `continue_block` parameter set to `true`.
356 ///! [`DecompressError::ShortData`]: ../enum.DecompressError.html#variant.ShortData
357 ///! [`DecompressError::OutputFull`]: ../enum.DecompressError.html#variant.OutputFull
358 pub fn decompress_data(&mut self, src: &[u8], dst: &mut [u8], continue_block: bool) -> DecompressResult<usize> {
359 if src.is_empty() || dst.is_empty() {
360 return Err(DecompressError::InvalidArgument);
362 let mut csrc = if !continue_block {
363 CurrentSource::new(src, self.br)
366 CurrentSource::reinit(src, self.br)
370 InflateState::Start | InflateState::BlockStart => {
371 if csrc.left() == 0 {
373 return Err(DecompressError::ShortData);
375 self.final_block = csrc.read_bool().unwrap();
376 self.state = InflateState::BlockMode;
378 InflateState::BlockMode => {
379 let bmode = read_bits!(self, csrc, 2);
383 self.state = InflateState::StaticBlockLen;
385 1 => { self.state = InflateState::FixedBlock; },
386 2 => { self.state = InflateState::DynBlockHlit; },
388 self.state = InflateState::End;
389 return Err(DecompressError::InvalidHeader);
393 InflateState::StaticBlockLen => {
394 let len = read_bits!(self, csrc, 16);
395 self.state = InflateState::StaticBlockInvLen(len);
397 InflateState::StaticBlockInvLen(len) => {
398 let inv_len = read_bits!(self, csrc, 16);
400 self.state = InflateState::End;
401 return Err(DecompressError::InvalidHeader);
403 self.state = InflateState::StaticBlockCopy(len as usize);
405 InflateState::StaticBlockCopy(len) => {
409 self.state = InflateState::StaticBlockCopy(len - i);
410 return Err(DecompressError::ShortData);
412 let val = csrc.read(8).unwrap() as u8;
413 self.put_literal(val);
415 self.state = InflateState::BlockStart;
417 InflateState::FixedBlock => {
418 let val = read_cb!(self, csrc, &self.fix_len_cb);
420 if self.output_idx >= dst.len() {
422 self.state = InflateState::FixedBlockLiteral(val as u8);
423 return Err(DecompressError::OutputFull);
425 self.put_literal(val as u8);
426 dst[self.output_idx] = val as u8;
427 self.output_idx += 1;
428 } else if val == 256 {
429 if self.final_block {
430 self.state = InflateState::End;
431 return Ok(self.output_idx);
433 self.state = InflateState::BlockStart;
436 let len_idx = (val - 257) as usize;
437 if len_idx >= LENGTH_BASE.len() {
438 self.state = InflateState::End;
439 return Err(DecompressError::InvalidData);
441 let len_bits = LENGTH_ADD_BITS[len_idx];
442 let add_base = LENGTH_BASE[len_idx] as usize;
444 self.state = InflateState::FixedBlockLengthExt(add_base, len_bits);
446 self.state = InflateState::FixedBlockDist(add_base);
450 InflateState::FixedBlockLiteral(sym) => {
451 if self.output_idx >= dst.len() {
453 return Err(DecompressError::OutputFull);
455 self.put_literal(sym);
456 dst[self.output_idx] = sym;
457 self.output_idx += 1;
458 self.state = InflateState::FixedBlock;
460 InflateState::FixedBlockLengthExt(base, bits) => {
461 let add = read_bits!(self, csrc, bits) as usize;
462 self.state = InflateState::FixedBlockDist(base + add);
464 InflateState::FixedBlockDist(length) => {
465 let dist_idx = reverse_bits(read_bits!(self, csrc, 5), 5) as usize;
466 if dist_idx >= DIST_BASE.len() {
467 self.state = InflateState::End;
468 return Err(DecompressError::InvalidData);
470 let dist_bits = DIST_ADD_BITS[dist_idx];
471 let dist_base = DIST_BASE[dist_idx] as usize;
473 self.state = InflateState::FixedBlockCopy(length, dist_base);
475 self.state = InflateState::FixedBlockDistExt(length, dist_base, dist_bits);
478 InflateState::FixedBlockDistExt(length, base, bits) => {
479 let add = read_bits!(self, csrc, bits) as usize;
480 self.state = InflateState::FixedBlockCopy(length, base + add);
482 InflateState::FixedBlockCopy(length, dist) => {
483 if self.output_idx + length > dst.len() {
484 let copy_size = dst.len() - self.output_idx;
485 let ret = self.lz_copy(dist, copy_size, &mut dst[self.output_idx..]);
487 self.state = InflateState::End;
488 return Err(DecompressError::InvalidData);
490 self.output_idx += copy_size;
492 self.state = InflateState::FixedBlockCopy(length - copy_size, dist);
493 return Err(DecompressError::OutputFull);
495 let ret = self.lz_copy(dist, length, &mut dst[self.output_idx..]);
497 self.state = InflateState::End;
498 return Err(DecompressError::InvalidData);
500 self.output_idx += length;
501 self.state = InflateState::FixedBlock;
503 InflateState::DynBlockHlit => {
504 self.hlit = (read_bits!(self, csrc, 5) as usize) + 257;
505 if self.hlit >= 287 {
506 self.state = InflateState::End;
507 return Err(DecompressError::InvalidHeader);
509 self.state = InflateState::DynBlockHdist;
511 InflateState::DynBlockHdist => {
512 self.hdist = (read_bits!(self, csrc, 5) as usize) + 1;
513 self.state = InflateState::DynBlockHclen;
515 InflateState::DynBlockHclen => {
516 let hclen = (read_bits!(self, csrc, 4) as usize) + 4;
517 self.cur_len_idx = 0;
518 self.len_lengths = [0; 19];
519 self.all_lengths = [0; NUM_LITERALS + NUM_DISTS];
520 self.state = InflateState::DynLengths(hclen);
522 InflateState::DynLengths(len) => {
526 self.state = InflateState::DynLengths(len - i);
527 return Err(DecompressError::ShortData);
529 self.len_lengths[LEN_RECODE[self.cur_len_idx]] = csrc.read(3).unwrap() as u8;
530 self.cur_len_idx += 1;
532 let mut len_codes = [ShortCodebookDesc { code: 0, bits: 0 }; 19];
533 lengths_to_codes(&self.len_lengths, &mut len_codes)?;
534 let mut cr = ShortCodebookDescReader::new(len_codes.to_vec());
535 let ret = Codebook::new(&mut cr, CodebookMode::LSB);
537 self.state = InflateState::End;
538 return Err(DecompressError::InvalidHeader);
540 self.dyn_len_cb = Some(ret.unwrap());
541 self.cur_len_idx = 0;
542 self.state = InflateState::DynCodeLengths;
544 InflateState::DynCodeLengths => {
545 if let Some(ref len_cb) = self.dyn_len_cb {
546 while self.cur_len_idx < self.hlit + self.hdist {
547 let ret = csrc.read_cb(len_cb);
548 let val = match ret {
550 Err(CodebookError::MemoryError) => {
552 return Err(DecompressError::ShortData);
555 self.state = InflateState::End;
556 return Err(DecompressError::InvalidHeader);
560 self.all_lengths[self.cur_len_idx] = val as u8;
561 self.cur_len_idx += 1;
563 let idx = (val as usize) - 16;
565 self.state = InflateState::End;
566 return Err(DecompressError::InvalidHeader);
568 self.state = InflateState::DynCodeLengthsAdd(idx);
572 let (lit_lengths, dist_lengths) = self.all_lengths.split_at(self.hlit);
574 let mut lit_codes = [ShortCodebookDesc { code: 0, bits: 0 }; NUM_LITERALS];
575 lengths_to_codes(&lit_lengths, &mut lit_codes)?;
576 let mut cr = ShortCodebookDescReader::new(lit_codes.to_vec());
577 let ret = Codebook::new(&mut cr, CodebookMode::LSB);
578 if ret.is_err() { return Err(DecompressError::InvalidHeader); }
579 self.dyn_lit_cb = Some(ret.unwrap());
581 let mut dist_codes = [ShortCodebookDesc { code: 0, bits: 0 }; NUM_DISTS];
582 lengths_to_codes(&dist_lengths[..self.hdist], &mut dist_codes)?;
583 let mut cr = ShortCodebookDescReader::new(dist_codes.to_vec());
584 let ret = Codebook::new(&mut cr, CodebookMode::LSB);
585 if ret.is_err() { return Err(DecompressError::InvalidHeader); }
586 self.dyn_dist_cb = Some(ret.unwrap());
588 self.state = InflateState::DynBlock;
593 InflateState::DynCodeLengthsAdd(mode) => {
594 let base = REPEAT_BASE[mode] as usize;
595 let bits = REPEAT_BITS[mode];
596 let len = base + read_bits!(self, csrc, bits) as usize;
597 if self.cur_len_idx + len > self.hlit + self.hdist {
598 self.state = InflateState::End;
599 return Err(DecompressError::InvalidHeader);
601 let rpt = if mode == 0 {
602 if self.cur_len_idx == 0 {
603 self.state = InflateState::End;
604 return Err(DecompressError::InvalidHeader);
606 self.all_lengths[self.cur_len_idx - 1]
611 self.all_lengths[self.cur_len_idx] = rpt;
612 self.cur_len_idx += 1;
614 self.state = InflateState::DynCodeLengths;
616 InflateState::DynBlock => {
617 if let Some(ref lit_cb) = self.dyn_lit_cb {
618 let val = read_cb!(self, csrc, lit_cb);
620 if self.output_idx >= dst.len() {
622 self.state = InflateState::DynBlockLiteral(val as u8);
623 return Err(DecompressError::OutputFull);
625 self.put_literal(val as u8);
626 dst[self.output_idx] = val as u8;
627 self.output_idx += 1;
628 } else if val == 256 {
629 if self.final_block {
630 self.state = InflateState::End;
631 return Ok(self.output_idx);
633 self.state = InflateState::BlockStart;
636 let len_idx = (val - 257) as usize;
637 if len_idx >= LENGTH_BASE.len() {
638 self.state = InflateState::End;
639 return Err(DecompressError::InvalidData);
641 let len_bits = LENGTH_ADD_BITS[len_idx];
642 let add_base = LENGTH_BASE[len_idx] as usize;
644 self.state = InflateState::DynBlockLengthExt(add_base, len_bits);
646 self.state = InflateState::DynBlockDist(add_base);
653 InflateState::DynBlockLiteral(sym) => {
654 if self.output_idx >= dst.len() {
656 return Err(DecompressError::OutputFull);
658 self.put_literal(sym);
659 dst[self.output_idx] = sym;
660 self.output_idx += 1;
661 self.state = InflateState::DynBlock;
663 InflateState::DynBlockLengthExt(base, bits) => {
664 let add = read_bits!(self, csrc, bits) as usize;
665 self.state = InflateState::DynBlockDist(base + add);
667 InflateState::DynBlockDist(length) => {
668 if let Some(ref dist_cb) = self.dyn_dist_cb {
669 let dist_idx = read_cb!(self, csrc, dist_cb) as usize;
670 if dist_idx >= DIST_BASE.len() {
671 self.state = InflateState::End;
672 return Err(DecompressError::InvalidData);
674 let dist_bits = DIST_ADD_BITS[dist_idx];
675 let dist_base = DIST_BASE[dist_idx] as usize;
677 self.state = InflateState::DynCopy(length, dist_base);
679 self.state = InflateState::DynBlockDistExt(length, dist_base, dist_bits);
685 InflateState::DynBlockDistExt(length, base, bits) => {
686 let add = read_bits!(self, csrc, bits) as usize;
687 self.state = InflateState::DynCopy(length, base + add);
689 InflateState::DynCopy(length, dist) => {
690 if self.output_idx + length > dst.len() {
691 let copy_size = dst.len() - self.output_idx;
692 let ret = self.lz_copy(dist, copy_size, &mut dst[self.output_idx..]);
694 self.state = InflateState::End;
695 return Err(DecompressError::InvalidData);
697 self.output_idx += copy_size;
699 self.state = InflateState::DynCopy(length - copy_size, dist);
700 return Err(DecompressError::OutputFull);
702 let ret = self.lz_copy(dist, length, &mut dst[self.output_idx..]);
704 self.state = InflateState::End;
705 return Err(DecompressError::InvalidData);
707 self.output_idx += length;
708 self.state = InflateState::DynBlock;
710 InflateState::End => {
716 ///! Decompresses input data into output returning the uncompressed data length.
717 pub fn uncompress(src: &[u8], dst: &mut [u8]) -> DecompressResult<usize> {
718 let mut inflate = Self::new();
719 inflate.decompress_data(src, dst, false)
723 impl Default for Inflate {
724 fn default() -> Self {
729 fn lengths_to_codes(lens: &[u8], codes: &mut [ShortCodebookDesc]) -> DecompressResult<()> {
730 let mut bits = [0u32; 32];
731 let mut pfx = [0u32; 33];
732 for len in lens.iter() {
733 let len = *len as usize;
734 if len >= bits.len() {
735 return Err(DecompressError::InvalidHeader);
741 for i in 0..bits.len() {
742 code = (code + bits[i]) << 1;
746 for (len, codes) in lens.iter().zip(codes.iter_mut()) {
747 let len = *len as usize;
749 let bits = len as u8;
750 *codes = ShortCodebookDesc { code: reverse_bits(pfx[len], bits), bits };
753 *codes = ShortCodebookDesc { code: 0, bits: 0 };
766 #[allow(clippy::unreadable_literal)]
768 let mut tab = [0u32; 256];
770 let mut c = i as u32;
773 c = 0xEDB88320 ^ (c >> 1);
782 fn update_crc(&mut self, src: &[u8]) {
783 let mut c = !self.crc;
784 for el in src.iter() {
785 c = self.tab[((c ^ u32::from(*el)) & 0xFF) as usize] ^ (c >> 8);
791 ///! Decodes input data in gzip file format (RFC 1952) returning a vector containing decoded data.
792 pub fn gzip_decode(br: &mut ByteReader, skip_crc: bool) -> DecompressResult<Vec<u8>> {
793 const FLAG_HCRC: u8 = 0x02;
794 const FLAG_EXTRA: u8 = 0x04;
795 const FLAG_NAME: u8 = 0x08;
796 const FLAG_COMMENT: u8 = 0x10;
798 let id1 = br.read_byte()?;
799 let id2 = br.read_byte()?;
800 let cm = br.read_byte()?;
801 let flg = br.read_byte()?;
802 let _mtime = br.read_u32le()?;
803 let _xfl = br.read_byte()?;
804 let _os = br.read_byte()?;
805 if id1 != 0x1F || id2 != 0x8B || cm != 8 {
806 return Err(DecompressError::InvalidHeader);
809 if (flg & FLAG_EXTRA) != 0 {
810 let xlen = br.read_u16le()? as usize;
813 if (flg & FLAG_NAME) != 0 {
815 let b = br.read_byte()?;
821 if (flg & FLAG_COMMENT) != 0 {
823 let b = br.read_byte()?;
829 let _hcrc = if (flg & FLAG_HCRC) != 0 {
834 if (flg & 0xE0) != 0 {
835 return Err(DecompressError::Unsupported);
838 let mut output: Vec<u8> = Vec::new();
839 let mut tail = [0u8; 8];
840 let mut inblk = [0u8; 1024];
841 let mut oblk = [0u8; 4096];
842 let mut inflate = Inflate::new();
843 let mut checker = GzipCRC32::new();
846 let ret = br.read_buf_some(&mut inblk);
847 if let Err(ByteIOError::EOF) = ret {
850 let inlen = match ret {
852 Err(_) => return Err(DecompressError::IOError),
854 let mut repeat = false;
856 let ret = inflate.decompress_data(&inblk[..inlen], &mut oblk, repeat);
859 checker.update_crc(&oblk[..outlen]);
860 output.extend_from_slice(&oblk[..outlen]);
863 Err(DecompressError::ShortData) => {
866 Err(DecompressError::OutputFull) => {
868 checker.update_crc(&oblk);
869 output.extend_from_slice(&oblk);
876 // Save last 8 bytes for CRC and size.
878 tail.copy_from_slice(&inblk[inlen - 8..][..8]);
880 let shift_len = 8 - inlen;
881 for i in 0..shift_len {
882 tail[i] = tail[i + inlen];
884 for i in shift_len..8 {
885 tail[i] = inblk[i - shift_len];
890 if !inflate.is_finished() { println!("???"); }
891 let crc = read_u32le(&tail[0..4])?;
892 let size = read_u32le(&tail[4..8])?;
893 if size != (output.len() as u32) {
894 return Err(DecompressError::CRCError);
896 if crc != checker.crc {
897 return Err(DecompressError::CRCError);
910 const TEST_DATA: &[u8] = &[
911 0xF3, 0x48, 0xCD, 0xC9, 0xC9, 0xD7, 0x51, 0x28,
912 0xCF, 0x2F, 0xCA, 0x49, 0x51, 0x04, 0x00 ];
913 const TEST_REF: &[u8] = b"Hello, world!";
914 let mut dst_buf = [0u8; 13];
915 let len = Inflate::uncompress(TEST_DATA, &mut dst_buf).unwrap();
918 assert_eq!(dst_buf[i], TEST_REF[i]);
923 const TEST_DATA3: &[u8] = &[ 0x4B, 0x4C, 0x44, 0x80, 0x24, 0x54, 0x80, 0x2C, 0x06, 0x00 ];
924 const TEST_REF3: &[u8] = b"aaaaaaaaaaaabbbbbbbbbbbbbbbaaaaabbbbbbb";
925 let mut dst_buf = [0u8; 39];
927 let mut inflate = Inflate::new();
928 let mut output_chunk = [0u8; 7];
929 let mut output_pos = 0;
930 for input in TEST_DATA3.chunks(3) {
931 let mut repeat = false;
933 let ret = inflate.decompress_data(input, &mut output_chunk, repeat);
937 dst_buf[output_pos + i] = output_chunk[i];
942 Err(DecompressError::ShortData) => {
945 Err(DecompressError::OutputFull) => {
947 for i in 0..output_chunk.len() {
948 dst_buf[output_pos + i] = output_chunk[i];
950 output_pos += output_chunk.len();
953 panic!("decompress error {:?}", ret.err().unwrap());
959 assert_eq!(output_pos, dst_buf.len());
960 for i in 0..output_pos {
961 assert_eq!(dst_buf[i], TEST_REF3[i]);
966 const TEST_DATA: &[u8] = &[
967 0x1F, 0x8B, 0x08, 0x08, 0xF6, 0x7B, 0x90, 0x5E, 0x02, 0x03, 0x31, 0x2E, 0x74, 0x78, 0x74, 0x00,
968 0xE5, 0x95, 0x4B, 0x4E, 0xC3, 0x30, 0x10, 0x40, 0xF7, 0x39, 0xC5, 0x1C, 0x00, 0x16, 0x70, 0x83,
969 0x0A, 0xB5, 0x3B, 0xE8, 0x82, 0x5E, 0x60, 0x1A, 0x4F, 0xE2, 0x11, 0xFE, 0x44, 0x1E, 0xA7, 0x69,
970 0x6E, 0xCF, 0x38, 0xDD, 0xB0, 0x40, 0xA2, 0x46, 0x2D, 0x20, 0x2A, 0xE5, 0xAB, 0xCC, 0xE7, 0xBD,
971 0x49, 0xAC, 0x6C, 0x03, 0x64, 0x4B, 0xD0, 0x71, 0x92, 0x0C, 0x06, 0x67, 0x88, 0x1D, 0x3C, 0xD9,
972 0xC4, 0x92, 0x3D, 0x4A, 0xF3, 0x3C, 0x43, 0x4E, 0x23, 0x81, 0x8B, 0x07, 0x82, 0x1E, 0xF5, 0x90,
973 0x23, 0x78, 0x6A, 0x56, 0x30, 0x60, 0xCA, 0x89, 0x4D, 0x4F, 0xC0, 0x01, 0x10, 0x06, 0xC2, 0xA4,
974 0xA1, 0x44, 0xCD, 0xF6, 0x54, 0x50, 0xA8, 0x8D, 0xC1, 0x9C, 0x5F, 0x71, 0x37, 0x45, 0xC8, 0x63,
975 0xCA, 0x8E, 0xC0, 0xE8, 0x23, 0x69, 0x56, 0x9A, 0x8D, 0x5F, 0xB6, 0xC9, 0x96, 0x53, 0x4D, 0x17,
976 0xAB, 0xB9, 0xB0, 0x49, 0x14, 0x5A, 0x0B, 0x96, 0x82, 0x7C, 0xB7, 0x6F, 0x17, 0x35, 0xC7, 0x9E,
977 0xDF, 0x78, 0xA3, 0xF1, 0xD0, 0xA2, 0x73, 0x1C, 0x7A, 0xD8, 0x2B, 0xB3, 0x5C, 0x90, 0x85, 0xBB,
978 0x2A, 0x14, 0x2E, 0xF7, 0xD1, 0x19, 0x48, 0x0A, 0x23, 0x57, 0x45, 0x13, 0x3E, 0xD6, 0xA0, 0xBD,
979 0xF2, 0x11, 0x7A, 0x22, 0x21, 0xAD, 0xE5, 0x70, 0x56, 0xA0, 0x9F, 0xA5, 0xA5, 0x03, 0x85, 0x2A,
980 0xDE, 0x92, 0x00, 0x32, 0x61, 0x10, 0xAD, 0x27, 0x13, 0x7B, 0x5F, 0x98, 0x7F, 0x59, 0x83, 0xB8,
981 0xB7, 0x35, 0x16, 0xEB, 0x12, 0x0F, 0x1E, 0xD9, 0x14, 0x0B, 0xCF, 0xEE, 0x6D, 0x91, 0xF8, 0x93,
982 0x6E, 0x81, 0x3F, 0x7F, 0x41, 0xA4, 0x22, 0x1F, 0xB7, 0xE6, 0x85, 0x83, 0x9A, 0xA2, 0x61, 0x12,
983 0x0D, 0x0F, 0x6D, 0x01, 0xBD, 0xB0, 0xE8, 0x1D, 0xEC, 0xD1, 0xA0, 0xBF, 0x1F, 0x4E, 0xFB, 0x55,
984 0xBD, 0x73, 0xDD, 0x87, 0xB9, 0x53, 0x23, 0x17, 0xD3, 0xE2, 0xE9, 0x08, 0x87, 0x42, 0xFF, 0xCF,
985 0x26, 0x42, 0xAE, 0x76, 0xB5, 0xAE, 0x97, 0x0C, 0x18, 0x78, 0xA0, 0x24, 0xE5, 0x54, 0x0C, 0x6E,
986 0x60, 0x52, 0x79, 0x22, 0x57, 0xF5, 0x87, 0x78, 0x78, 0x04, 0x93, 0x46, 0xEF, 0xCB, 0x98, 0x96,
987 0x8B, 0x65, 0x00, 0xB7, 0x36, 0xBD, 0x77, 0xA8, 0xBD, 0x5A, 0xAA, 0x1A, 0x09, 0x00, 0x00
990 let mut mr = MemoryReader::new_read(TEST_DATA);
991 let mut br = ByteReader::new(&mut mr);
992 let _dst_buf = gzip_decode(&mut br, false).unwrap();
994 // println!("{}", String::from_utf8_lossy(_dst_buf.as_slice()));