1#![doc = include_str!("../README.md")]
2#![feature(seek_stream_len)]
3#![feature(iter_array_chunks)]
4use std::{
5 io::{self, ErrorKind},
6 iter,
7};
8
9mod reader;
10
11pub use reader::Reader;
12
13#[derive(Debug, thiserror::Error)]
14pub enum Error {
16 #[error("Input does not contain enough packbits data to fill the buffer")]
18 NotEnoughInputData,
19
20 #[error("Output buffer is too small to hold decoded data")]
22 TooMuchOutputData,
23
24 #[error("Input has unread data left after filling the output buffer")]
26 TooMuchInputData,
27
28 #[error(transparent)]
30 Io(#[from] io::Error),
31}
32
33impl From<Error> for io::Error {
34 fn from(value: Error) -> Self {
35 match value {
36 Error::Io(error) => error,
37 me => io::Error::other(me),
38 }
39 }
40}
41#[derive(Debug)]
42pub enum Command {
44 Escape,
46 Literal(u8),
48 Repeat(u16),
50}
51
52impl Command {
53 #[inline]
54 pub fn execute<T: io::Read>(self, reader: &mut T) -> Result<(u8, Operation), OperationError> {
56 match self {
57 Command::Escape => {
58 let byte = Self::read_byte(reader)?;
59 Ok((byte, Operation::Literal(0)))
60 }
61 Command::Literal(count) => {
62 let literal = Self::read_byte(reader)?;
63 Ok((literal, Operation::Literal(count - 1)))
64 }
65 Command::Repeat(count) => {
66 let literal = Self::read_byte(reader)?;
67 Ok((literal, Operation::Repeat(literal, count - 1)))
68 }
69 }
70 }
71
72 #[inline]
73 fn read_byte<T: io::Read>(reader: &mut T) -> Result<u8, OperationError> {
74 let mut buf = [0u8];
75 match reader.read(&mut buf) {
76 Ok(0) => Err(OperationError::UnexpectedEof),
77 Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => {
78 Err(OperationError::UnexpectedEof)
79 }
80 Err(e) => Err(e)?,
81 Ok(_) => Ok(buf[0]),
82 }
83 }
84}
85
86impl From<i8> for Command {
87 #[inline]
88 fn from(val: i8) -> Self {
89 match val {
90 -128 => Command::Escape,
91 n if n < 0 => Command::Repeat((1 - n) as u16),
92 n => Command::Literal((1 + n) as u8),
93 }
94 }
95}
96
97impl From<u8> for Command {
98 #[inline]
99 fn from(val: u8) -> Self {
100 match val {
101 n if n < 128 => Command::Literal(1 + n),
102 128 => Command::Escape,
103 n => Command::Repeat(257 - n as u16),
104 }
105 }
106}
107
108#[derive(Debug)]
109pub enum Operation {
112 Literal(u8),
114 Repeat(u8, u16),
116}
117
118#[derive(Debug)]
119pub enum Operation16 {
122 Literal(u8),
124 Repeat(u16, u16),
126}
127
128#[derive(Debug, thiserror::Error)]
129pub enum OperationError {
132 #[error("More input data is required to executed command")]
137 InsufficientInput(Command),
138
139 #[error("More input data is required to continue")]
142 UnexpectedEof,
143
144 #[error(transparent)]
146 Io(#[from] io::Error),
147}
148
149impl From<OperationError> for io::Error {
150 fn from(value: OperationError) -> Self {
151 match value {
152 OperationError::Io(error) => error,
153 other => io::Error::other(other),
154 }
155 }
156}
157
158impl Default for Operation {
159 fn default() -> Self {
160 Self::new()
161 }
162}
163
164impl Default for Operation16 {
165 fn default() -> Self {
166 Self::new()
167 }
168}
169impl Operation16 {
170 pub fn new() -> Self {
173 Self::Literal(0)
174 }
175
176 #[inline]
177 fn read_byte<T: io::Read>(reader: &mut T) -> Result<u8, OperationError> {
178 let mut buf = [0u8];
179 match reader.read(&mut buf) {
180 Ok(0) => Err(OperationError::UnexpectedEof),
181 Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => {
182 Err(OperationError::UnexpectedEof)
183 }
184 Err(e) => Err(e)?,
185 Ok(_) => Ok(buf[0]),
186 }
187 }
188
189 #[inline]
190 fn read_word<T: io::Read>(reader: &mut T) -> Result<u16, OperationError> {
191 let mut buf = [0u8, 0u8];
192 match reader.read(&mut buf) {
193 Ok(0) => Err(OperationError::UnexpectedEof),
194 Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => {
195 Err(OperationError::UnexpectedEof)
196 }
197 Err(e) => Err(e)?,
198 Ok(_) => Ok(((buf[0] as u16) << 8) | buf[1] as u16),
199 }
200 }
201
202 #[inline]
203 pub fn advance<T: io::Read>(&self, reader: &mut T) -> Result<(u16, Self), OperationError> {
208 match self {
209 op if op.is_completed() => match Self::read_byte(reader)? {
210 128 => match Self::read_byte(reader) {
211 Ok(byte) => Ok((
212 (byte as u16) << 8 | (Self::read_byte(reader)? as u16),
213 Operation16::Literal(0),
214 )),
215 Err(OperationError::UnexpectedEof) => {
216 Err(OperationError::InsufficientInput(Command::Escape))
217 }
218 Err(e) => Err(e),
219 },
220 n if n < 128 => match Self::read_word(reader) {
221 Ok(byte) => Ok((byte, Operation16::Literal(n))),
222 Err(OperationError::UnexpectedEof) => {
223 Err(OperationError::InsufficientInput(Command::Literal(n + 1)))
224 }
225 Err(e) => Err(e),
226 },
227 n => match Self::read_word(reader) {
228 Err(OperationError::UnexpectedEof) => Err(OperationError::InsufficientInput(
229 Command::Repeat(256 - n as u16 + 1),
230 )),
231 Ok(byte) => Ok((byte, Operation16::Repeat(byte, 256 - n as u16))),
232 Err(e) => Err(e),
233 },
234 },
235 Operation16::Repeat(value, count) => {
236 Ok((*value, Operation16::Repeat(*value, count - 1)))
237 }
238 Operation16::Literal(count) => match Self::read_word(reader) {
239 Ok(byte) => Ok((byte, Self::Literal(count - 1))),
240 Err(OperationError::UnexpectedEof) => {
241 Err(OperationError::InsufficientInput(Command::Literal(*count)))
242 }
243 Err(e) => Err(e),
244 },
245 }
246 }
247
248 #[inline]
249 pub fn is_completed(&self) -> bool {
251 matches!(self, Self::Literal(0) | Self::Repeat(_, 0))
252 }
253}
254
255impl Operation {
256 pub fn new() -> Self {
259 Self::Literal(0)
260 }
261
262 #[inline]
263 fn read_byte<T: io::Read>(reader: &mut T) -> Result<u8, OperationError> {
264 let mut buf = [0u8];
265 match reader.read(&mut buf) {
266 Ok(0) => Err(OperationError::UnexpectedEof),
267 Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => {
268 Err(OperationError::UnexpectedEof)
269 }
270 Err(e) => Err(e)?,
271 Ok(_) => Ok(buf[0]),
272 }
273 }
274
275 #[inline]
276 pub fn advance<T: io::Read>(&self, reader: &mut T) -> Result<(u8, Self), OperationError> {
281 match self {
282 op if op.is_completed() => match Self::read_byte(reader)? {
283 128 => match Self::read_byte(reader) {
284 Ok(byte) => Ok((byte, Operation::Literal(0))),
285 Err(OperationError::UnexpectedEof) => {
286 Err(OperationError::InsufficientInput(Command::Escape))
287 }
288 Err(e) => Err(e),
289 },
290 n if n < 128 => match Self::read_byte(reader) {
291 Ok(byte) => Ok((byte, Operation::Literal(n))),
292 Err(OperationError::UnexpectedEof) => {
293 Err(OperationError::InsufficientInput(Command::Literal(n + 1)))
294 }
295 Err(e) => Err(e),
296 },
297 n => match Self::read_byte(reader) {
298 Err(OperationError::UnexpectedEof) => Err(OperationError::InsufficientInput(
299 Command::Repeat(256 - n as u16 + 1),
300 )),
301 Ok(byte) => Ok((byte, Operation::Repeat(byte, 256 - n as u16))),
302 Err(e) => Err(e),
303 },
304 },
305 Operation::Repeat(value, count) => Ok((*value, Operation::Repeat(*value, count - 1))),
306 Operation::Literal(count) => match Self::read_byte(reader) {
307 Ok(byte) => Ok((byte, Self::Literal(count - 1))),
308 Err(OperationError::UnexpectedEof) => {
309 Err(OperationError::InsufficientInput(Command::Literal(*count)))
310 }
311 Err(e) => Err(e),
312 },
313 }
314 }
315
316 #[inline]
317 pub fn is_completed(&self) -> bool {
319 matches!(self, Self::Literal(0) | Self::Repeat(_, 0))
320 }
321}
322
323#[cfg(test)]
324mod operation {
325 use crate::{Command, Operation, OperationError};
326 use std::io;
327
328 #[test]
329 fn read_literal() {
330 let mut reader = io::Cursor::new(b"\x01\xAB\xBC");
331 assert!(matches!(
332 Operation::default().advance(&mut reader),
333 Ok((0xab, Operation::Literal(1)))
334 ));
335 }
336
337 #[test]
338 fn read_repeat() {
339 let mut reader = io::Cursor::new(b"\xFF\xAB");
340 assert!(matches!(
341 Operation::default().advance(&mut reader),
342 Ok((0xab, Operation::Repeat(0xab, 1)))
343 ));
344 }
345
346 #[test]
347 fn read_escape() {
348 let mut reader = io::Cursor::new(b"\x80\xAB");
349 assert!(matches!(
350 Operation::default().advance(&mut reader),
351 Ok((0xAB, Operation::Repeat(_, 0) | Operation::Literal(0)))
352 ));
353 }
354
355 #[test]
356 fn read_partial_literal() {
357 let mut reader = io::Cursor::new(b"\x01");
358 assert!(matches!(
359 Operation::default().advance(&mut reader),
360 Err(OperationError::InsufficientInput(Command::Literal(2)))
361 ));
362 }
363
364 #[test]
365 fn read_partial_literal_to_completion() {
366 let mut reader = io::Cursor::new(b"\xAB");
367 assert!(matches!(
368 Command::Literal(2).execute(&mut reader),
369 Ok((0xab, Operation::Literal(1)))
370 ));
371 }
372
373 #[test]
374 fn read_partial_repeat() {
375 let mut reader = io::Cursor::new(b"\xFF");
376 assert!(matches!(
377 Operation::default().advance(&mut reader),
378 Err(OperationError::InsufficientInput(Command::Repeat(2)))
379 ));
380 }
381
382 #[test]
383 fn read_partial_repeat_to_completion() {
384 let mut reader = io::Cursor::new(b"\xAB");
385 assert!(matches!(
386 Command::Repeat(2).execute(&mut reader),
387 Ok((0xab, Operation::Repeat(0xab, 1)))
388 ));
389 }
390
391 #[test]
392 fn read_partial_escape() {
393 let mut reader = io::Cursor::new(b"\x80");
394 assert!(matches!(
395 Operation::default().advance(&mut reader),
396 Err(OperationError::InsufficientInput(Command::Escape))
397 ));
398 }
399
400 #[test]
401 fn read_partial_escape_to_completion() {
402 let mut reader = io::Cursor::new(b"\x80");
403 assert!(matches!(
404 Command::Escape.execute(&mut reader),
405 Ok((0x80, Operation::Literal(0) | Operation::Repeat(_, 0)))
406 ));
407 }
408}
409
410pub fn unpack_words_exact(input: &[u8], count: usize) -> Result<Vec<u8>, Error> {
411 let mut output = Vec::with_capacity(count);
412 let mut remaining_output = count;
413 let mut i = 0;
414
415 loop {
416 if remaining_output == 0 {
417 return if i == input.len() {
418 Ok(output)
419 } else {
420 Err(Error::TooMuchInputData)
421 };
422 }
423
424 if i == input.len() {
425 return Err(Error::NotEnoughInputData);
426 }
427
428 i = match input[i].into() {
429 Command::Escape => i + 1,
430 Command::Literal(count) => {
431 if input.len() < i + count as usize {
432 return Err(Error::NotEnoughInputData);
433 }
434
435 if count as usize > remaining_output {
436 return Err(Error::TooMuchOutputData);
437 }
438
439 output.extend(&input[i + 1..(i + 1 + (count as usize * 2))]);
440 remaining_output -= count as usize * 2;
441 i + count as usize * 2 + 1
442 }
443 Command::Repeat(count) => {
444 if input.len() < i + 2 {
445 return Err(Error::NotEnoughInputData);
446 }
447
448 if count as usize * 2 > remaining_output {
449 return Err(Error::TooMuchOutputData);
450 }
451
452 for _ in 0..(count as usize) {
453 output.extend(&input[(i + 1)..=(i + 2)]);
454 }
455
456 remaining_output -= count as usize * 2;
457 i + 3
458 }
459 }
460 }
461}
462
463pub fn unpack_exact(input: &[u8], count: usize) -> Result<Vec<u8>, Error> {
465 let mut output = Vec::with_capacity(count);
466 let mut remaining_output = count;
467 let mut i = 0;
468
469 loop {
470 if remaining_output == 0 {
471 return if i == input.len() {
472 Ok(output)
473 } else {
474 Err(Error::TooMuchInputData)
475 };
476 }
477
478 if i == input.len() {
479 return Err(Error::NotEnoughInputData);
480 }
481
482 i = match input[i].into() {
483 Command::Escape => i + 1,
484 Command::Literal(count) => {
485 if input.len() < i + count as usize {
486 return Err(Error::NotEnoughInputData);
487 }
488
489 if count as usize > remaining_output {
490 return Err(Error::TooMuchOutputData);
491 }
492
493 output.extend(&input[i + 1..(i + 1 + (count as usize))]);
494 remaining_output -= count as usize;
495 i + count as usize + 1
496 }
497 Command::Repeat(count) => {
498 if input.len() < i + 1 {
499 return Err(Error::NotEnoughInputData);
500 }
501
502 if count as usize > remaining_output {
503 return Err(Error::TooMuchOutputData);
504 }
505
506 output.extend(iter::repeat_n(input[i + 1], count as usize));
507 remaining_output -= count as usize;
508 i + 2
509 }
510 }
511 }
512}
513
514pub fn unpack_buf(buffer: &[u8]) -> io::Result<Vec<u8>> {
516 unpack(io::Cursor::new(buffer))
517}
518
519pub fn unpack<R: io::Read>(mut reader: R) -> io::Result<Vec<u8>> {
521 let mut output = Vec::new();
522 let mut buf = [0u8];
523 loop {
524 let command = match reader.read_exact(&mut buf) {
525 Ok(()) => buf[0].into(),
526 Err(e) if e.kind() == ErrorKind::UnexpectedEof => return Ok(output),
527 Err(e) => return Err(e)?,
528 };
529
530 match command {
531 Command::Escape => {
532 reader.read_exact(&mut buf)?;
533 output.push(buf[0]);
534 }
535 Command::Literal(count) => {
536 let mut buffer = vec![0u8; count as usize];
537 reader.read_exact(&mut buffer)?;
538 output.append(&mut buffer);
539 }
540 Command::Repeat(count) => {
541 reader.read_exact(&mut buf)?;
542 output.reserve(count as usize);
543 for _ in 0..count {
544 output.push(buf[0]);
545 }
546 }
547 }
548 }
549}
550
551pub trait PackBitsReaderExt {
553 fn read_packbits(&mut self, target: &mut [u8]) -> io::Result<usize>;
555 fn read_packbits_words(&mut self, target: &mut [u8]) -> io::Result<usize>;
556}
557
558impl<T: io::Read> PackBitsReaderExt for T {
559 fn read_packbits(&mut self, target: &mut [u8]) -> io::Result<usize> {
560 let mut op = Operation::default();
561 for (idx, byte) in target.iter_mut().enumerate() {
562 match op.advance(self) {
563 Err(OperationError::InsufficientInput(_)) => {
564 return Ok(idx);
567 }
568 Err(OperationError::UnexpectedEof) => return Ok(idx),
569 Err(other) => return Err(other)?,
570 Ok((value, next)) => {
571 *byte = value;
572 op = next;
573 }
574 }
575 }
576
577 Ok(target.len())
578 }
579
580 fn read_packbits_words(&mut self, target: &mut [u8]) -> io::Result<usize> {
581 let mut op = Operation16::default();
582 for (idx, [byte1, byte2]) in target.iter_mut().array_chunks().enumerate() {
583 match op.advance(self) {
584 Err(OperationError::InsufficientInput(_)) => {
585 return Ok(idx * 2);
588 }
589 Err(OperationError::UnexpectedEof) => return Ok(idx * 2),
590 Err(other) => return Err(other)?,
591 Ok((value, next)) => {
592 *byte1 = (value >> 8) as u8;
593 *byte2 = (value & 0xFF) as u8;
594 op = next;
595 }
596 }
597 }
598
599 Ok(target.len())
600 }
601}
602
603#[cfg(test)]
604mod test {
605 use crate::{Error, unpack_buf};
606
607 use super::{unpack, unpack_exact};
608
609 #[test]
610 fn canonical_example() {
611 let input = b"\xFE\xAA\x02\x80\x00\x2A\xFD\xAA\x03\x80\x00\x2A\x22\xF7\xAA";
612 let unpacked = b"\xAA\xAA\xAA\x80\x00\x2A\xAA\xAA\xAA\xAA\x80\x00\x2A\x22\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA";
613
614 assert_eq!(unpack(input.as_slice()).unwrap(), unpacked);
615 }
616
617 #[test]
618 fn test_simple_buffer_expansion() {
619 let input = b"\xFE\xAA\x02\x80\x00\x2A\xFD\xAA\x03\x80\x00\x2A\x22\xF7\xAA";
620 let expectation = b"\xAA\xAA\xAA\x80\x00\x2A\xAA\xAA\xAA\xAA\x80\x00\x2A\x22\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA";
621 let result = unpack_buf(input).unwrap();
622 assert_eq!(expectation.to_vec(), result);
623
624 let result = unpack_exact(input, 24);
625 assert_eq!(expectation.to_vec(), result.unwrap());
626 }
627
628 #[test]
642 fn test_too_much_output() {
643 let input = b"\xFE\xAA\x02\x80\x00\x2A\xFD\xAA\x03\x80\x00\x2A\x22\xF7\xAA";
644
645 let result = unpack_exact(input, 20);
646 assert!(result.is_err_and(|e| matches!(e, Error::TooMuchOutputData)));
647 }
648
649 #[test]
650 fn test_not_enough_input() {
651 let input = b"\xFE\xAA\x02\x80\x00\x2A\xFD\xAA\x03\x80\x00\x2A\x22\xF7\xAA";
652
653 let result = unpack_exact(input, 26);
654 assert!(result.is_err_and(|e| matches!(e, Error::NotEnoughInputData)));
655
656 let input = b"";
657 let result = unpack_exact(input, 1);
658 assert!(result.is_err_and(|e| matches!(e, Error::NotEnoughInputData)));
659 }
660
661 mod operation {
662 use crate::{Command, Operation, OperationError};
663 use std::io;
664
665 #[test]
666 fn read_literal() {
667 let mut reader = io::Cursor::new(b"\x01\xAB\xBC");
668 assert!(matches!(
669 Operation::default().advance(&mut reader),
670 Ok((0xab, Operation::Literal(1)))
671 ));
672 }
673
674 #[test]
675 fn read_repeat() {
676 let mut reader = io::Cursor::new(b"\xFF\xAB");
677 assert!(matches!(
678 Operation::default().advance(&mut reader),
679 Ok((0xab, Operation::Repeat(0xab, 1)))
680 ));
681 }
682
683 #[test]
684 fn read_escape() {
685 let mut reader = io::Cursor::new(b"\x80\xAB");
686 assert!(matches!(
687 Operation::default().advance(&mut reader),
688 Ok((0xAB, Operation::Repeat(_, 0) | Operation::Literal(0)))
689 ));
690 }
691
692 #[test]
693 fn read_partial_literal() {
694 let mut reader = io::Cursor::new(b"\x01");
695 assert!(matches!(
696 Operation::default().advance(&mut reader),
697 Err(OperationError::InsufficientInput(Command::Literal(2)))
698 ));
699 }
700
701 #[test]
702 fn read_partial_literal_to_completion() {
703 let mut reader = io::Cursor::new(b"\xAB");
704 assert!(matches!(
705 Command::Literal(2).execute(&mut reader),
706 Ok((0xab, Operation::Literal(1)))
707 ));
708 }
709
710 #[test]
711 fn read_partial_repeat() {
712 let mut reader = io::Cursor::new(b"\xFF");
713 assert!(matches!(
714 Operation::default().advance(&mut reader),
715 Err(OperationError::InsufficientInput(Command::Repeat(2)))
716 ));
717 }
718
719 #[test]
720 fn read_partial_repeat_to_completion() {
721 let mut reader = io::Cursor::new(b"\xAB");
722 assert!(matches!(
723 Command::Repeat(2).execute(&mut reader),
724 Ok((0xab, Operation::Repeat(0xab, 1)))
725 ));
726 }
727
728 #[test]
729 fn read_partial_escape() {
730 let mut reader = io::Cursor::new(b"\x80");
731 assert!(matches!(
732 Operation::default().advance(&mut reader),
733 Err(OperationError::InsufficientInput(Command::Escape))
734 ));
735 }
736
737 #[test]
738 fn read_partial_escape_to_completion() {
739 let mut reader = io::Cursor::new(b"\x80");
740 assert!(matches!(
741 Command::Escape.execute(&mut reader),
742 Ok((0x80, Operation::Literal(0) | Operation::Repeat(_, 0)))
743 ));
744 }
745 }
746}