zenjxl_decoder/api/
input.rs1use std::io::{BufRead, BufReader, Error, IoSliceMut, Read, Seek, SeekFrom};
7
8pub trait JxlBitstreamInput {
9 fn available_bytes(&mut self) -> Result<usize, Error>;
13
14 fn read(&mut self, bufs: &mut [IoSliceMut]) -> Result<usize, Error>;
17
18 fn skip(&mut self, bytes: usize) -> Result<usize, Error> {
23 let mut bytes = bytes;
24 const BUF_SIZE: usize = 1024;
25 let mut skip_buf = [0; BUF_SIZE];
26 let mut skipped = 0;
27 while bytes > 0 {
28 let num = bytes.min(BUF_SIZE);
29 self.read(&mut [IoSliceMut::new(&mut skip_buf[..num])])?;
30 bytes -= num;
31 skipped += num;
32 }
33 Ok(skipped)
34 }
35
36 fn unconsume(&mut self, _count: usize) -> Result<(), Error> {
41 Ok(())
42 }
43}
44
45impl JxlBitstreamInput for &[u8] {
46 fn available_bytes(&mut self) -> Result<usize, Error> {
47 Ok(self.len())
48 }
49
50 fn read(&mut self, bufs: &mut [IoSliceMut]) -> Result<usize, Error> {
51 self.read_vectored(bufs)
52 }
53
54 fn skip(&mut self, bytes: usize) -> Result<usize, Error> {
55 let num = bytes.min(self.len());
56 self.consume(num);
57 Ok(num)
58 }
59}
60
61impl<R: Read + Seek> JxlBitstreamInput for BufReader<R> {
62 fn available_bytes(&mut self) -> Result<usize, Error> {
63 let pos = self.stream_position()?;
64 let end = self.seek(SeekFrom::End(0))?;
65 self.seek(SeekFrom::Start(pos))?;
66 Ok(end.saturating_sub(pos) as usize)
67 }
68
69 fn read(&mut self, bufs: &mut [IoSliceMut]) -> Result<usize, Error> {
70 self.read_vectored(bufs)
71 }
72
73 fn skip(&mut self, bytes: usize) -> Result<usize, Error> {
74 let cur = self.stream_position()?;
75 self.seek(SeekFrom::Current(bytes as i64))
76 .map(|x| x.saturating_sub(cur) as usize)
77 }
78
79 fn unconsume(&mut self, count: usize) -> Result<(), Error> {
80 self.seek_relative(-(count as i64))
81 }
82}