1use core::ops::{Index, IndexMut};
26
27#[derive(Debug,Copy,Clone,PartialEq,Eq)]
28pub enum Lj92Error {
29 Corrupt = -1,
30 NoMemory = -2,
31 BadHandle = -3,
32 TooWide = -4,
33 Encoder = -5,
34 EndOfImage = -6, }
36
37#[derive(Debug)]
38pub struct Lj92<'a, HuffLut> {
39 data: &'a [u8],
40
41 scanstart: usize,
42 ix: usize, x: u32, y: u32, bitdepth: u8, components: u8, hufflut: HuffLut,
51 huffbits: u32,
52
53 cnt: usize,
55 bits: i32, }
57
58#[cfg(feature = "std")]
59impl<'a> Lj92<'a, Vec<u16>> {
60 #[inline]
61 pub fn open_vec(data: &'a [u8]) -> Result<Self, Lj92Error> {
62 let mut lj = Self::with_custom_lut(vec![0u16; 65536]);
63 lj.data = data;
64 let ret = lj.find_soi();
65 ret.map(|_| lj)
66 }
67}
68
69impl<'a> Lj92<'a, [u16; 16384]> {
70 #[inline]
71 pub fn open(data: &'a [u8]) -> Result<Self, Lj92Error> {
72 let mut lj = Self::with_custom_lut([0u16; 16384]);
73 lj.data = data;
74 let ret = lj.find_soi();
75 ret.map(|_| lj)
76 }
77}
78
79impl<'a, HuffLut> Lj92<'a, HuffLut>
80where
81 HuffLut: Index<usize, Output=u16> + IndexMut<usize, Output=u16>
82{
83 pub fn with_custom_lut(hufflut: HuffLut) -> Self {
84 Self {
85 data: Default::default(), scanstart: 0, ix: 0, x: 0, y: 0, bitdepth: 0,
86 components: 0, hufflut, huffbits: 0, cnt: 0, bits: 0,
87 }
88 }
89
90 pub fn width(&self) -> u32 { self.x }
92 pub fn height(&self) -> u32 { self.y }
93 pub fn bitdepth(&self) -> u8 { self.bitdepth }
94 pub fn components(&self) -> u8 { self.components }
95
96 #[inline(always)]
99 fn get_be_u16(&self, off: usize) -> u16 {
100 u16::from_be_bytes([self.data[self.ix+off], self.data[self.ix+off+1]])
101 }
102
103 #[inline]
106 pub fn decode(
107 &mut self,
108 out: &'a mut [u16],
109 skip_length: usize,
110 linearize: Option<&[u16]>
111 ) -> Result<(), Lj92Error> {
112 self.ix = self.scanstart;
114 let compcount = self.data[self.ix+2];
115 let pred = self.data[self.ix+3+2*compcount as usize];
116 if pred > 7 { return Err(Lj92Error::Corrupt); }
117 self.ix += self.get_be_u16(0) as usize;
119 self.cnt = 0;
120 self.bits = 0;
121
122 let to_u16 = |x: i32| (x & 0xffff) as u16;
124
125 let mut diff;
127 let mut px;
128 let mut left = 0i32;
129 let row_out_len = (self.x * self.components as u32) as usize + skip_length;
130
131 for row in 0..(self.y as usize) {
132 let row_start = row * row_out_len;
133 let prev_row_start = row.saturating_sub(1) * row_out_len;
134 let lastrow = |data: &mut [u16], i: usize| -> u16 { data[prev_row_start + i] };
135 let thisrow = |data: &mut [u16], i: usize| -> u16 { data[row_start + i] };
136 for col in 0..(self.x as usize) {
137 let colx = col * self.components as usize;
138 for c in 0..(self.components as usize) {
139 px = match (row, col) {
140 (0, 0) => 1 << (self.bitdepth - 1),
141 (0, _) => thisrow(out, colx - self.components as usize + c),
142 (_, 0) => lastrow(out, c),
143 (_, _) => {
144 let prev_colx = colx - self.components as usize;
145 match pred {
146 0 => 0,
147 1 => thisrow(out, prev_colx + c),
148 2 => lastrow(out, colx + c),
149 3 => lastrow(out, prev_colx + c),
150 4 => to_u16(left + lastrow(out, colx + c) as i32 - lastrow(out, prev_colx + c) as i32),
151 5 => to_u16(left + ((lastrow(out, colx + c) as i32 - lastrow(out, prev_colx + c) as i32) >> 1)),
152 6 => to_u16(lastrow(out, colx + c) as i32 + ((left - lastrow(out, prev_colx + c) as i32) >> 1)),
153 7 => to_u16((left + lastrow(out, colx + c) as i32) >> 1),
154 _ => unreachable!("Invalid prediction mode")
155 }
156 }
157 };
158
159 diff = self.next_diff();
160 left = to_u16((px as i32) + diff) as i32;
161
162 let linear = if let Some(linearize) = linearize {
163 if left > linearize.len() as i32 { return Err(Lj92Error::Corrupt); }
165 linearize[left as usize]
166 } else { left as u16 };
167
168 if let Some(out) = out.get_mut(row_start + colx + c) {
170 *out = linear;
171 } else { return Ok(()); } } } } Ok(())
177 }
178
179 #[inline]
180 fn find_soi(&mut self) -> Result<(),Lj92Error> {
181 if self.find() == Ok(0xd8) {
182 self.parse_image()
183 } else { Err(Lj92Error::Corrupt) }
184 }
185
186 #[inline]
187 fn find(&mut self) -> Result<u8,Lj92Error> {
188 while self.data[self.ix] != 0xFF && self.ix < (self.data.len()-1) { self.ix += 1; }
189 self.ix += 2;
190 if self.ix >= self.data.len() { return Err(Lj92Error::EndOfImage); }
191 Ok(self.data[self.ix-1])
192 }
193
194 #[inline]
195 fn parse_image(&mut self) -> Result<(),Lj92Error> {
196 let mut ret = Ok(());
197 while let Ok(next_marker) = self.find() {
198 match next_marker {
199 0xC4 => ret = self.parse_huff(),
200 0xC3 => ret = self.parse_sof3(),
201 0xFE => ret = self.parse_block(),
202 0xD9 => {break},
203 0xDA => {
204 self.scanstart = self.ix;
205 ret = Ok(());
206 break;
207 },
208 _ => ret = self.parse_block(),
209 }
210
211 if ret != Ok(()) {break;}
212 }
213 return ret;
214 }
215
216 #[inline]
217 fn parse_block(&mut self) -> Result<(),Lj92Error> {
218 self.ix += self.get_be_u16(0) as usize;
219 if self.ix >= self.data.len() { return Err(Lj92Error::Corrupt); }
220 return Ok(());
221 }
222
223 #[inline]
224 fn parse_sof3(&mut self) -> Result<(),Lj92Error> {
225 if (self.ix + 6) >= self.data.len() { return Err(Lj92Error::Corrupt); }
226 self.y = self.get_be_u16(3) as u32;
227 self.x = self.get_be_u16(5) as u32;
228 self.bitdepth = self.data[self.ix+2];
229 self.components = self.data[self.ix+7];
230 self.ix += self.get_be_u16(0) as usize;
231 Ok(())
232 }
233
234 #[inline]
235 fn parse_huff(&mut self) -> Result<(),Lj92Error> {
236 let mut ret = Err(Lj92Error::Corrupt);
237 let huffhead = &self.data[self.ix..]; let bits = &huffhead[2..];
239 let hufflen = u16::from_be_bytes([huffhead[0], huffhead[1]]);
242 if (self.ix + hufflen as usize) >= self.data.len() { return ret; }
243
244 let huffvals = &self.data[(self.ix+19)..];
247 let mut maxbits = 16;
248 while maxbits > 0 {
249 if bits[maxbits] != 0 { break; }
250 maxbits -= 1;
251 }
252 self.huffbits = maxbits as u32;
253 let mut i = 0;
256 let mut hv = 0;
257 let mut rv = 0;
258 let mut vl = 0; let mut hcode;
260 let mut bitsused = 1;
261
262 while i < (1 << maxbits) {
263 if bitsused > maxbits {
264 break; }
266 if vl >= bits[bitsused] {
267 bitsused += 1;
268 vl = 0;
269 continue;
270 }
271 if rv == 1 << (maxbits-bitsused) {
272 rv = 0;
273 vl += 1;
274 hv += 1;
275 continue;
276 }
277 hcode = huffvals[hv];
278 self.hufflut[i] = ((hcode as u16) << 8) | bitsused as u16;
279 i += 1;
280 rv += 1;
281 }
282 ret = Ok(());
283 return ret;
284 }
285
286 #[inline]
287 fn next_diff(&mut self) -> i32 {
288 let mut bits = self.bits;
289 let mut cnt = self.cnt;
290 let huffbits = self.huffbits;
291 let mut ix = self.ix;
292 while cnt < huffbits as usize {
293 let one = self.data[ix] as i32;
295 let two = self.data[ix+1] as i32;
296 bits = (bits << 16) | (one << 8) | two;
297 cnt += 16;
298 ix += 2;
299 if one == 0xFF {
300 bits >>= 8;
301 cnt -= 8;
302 } else if two == 0xFF { ix += 1; };
303 }
304 let index = bits >> (cnt - huffbits as usize);
305 let ssssused: u16 = self.hufflut[index as usize];
306 let usedbits = ssssused & 0xFF;
307 let t = ssssused >> 8;
308 cnt -= usedbits as usize;
310 let mut keepbitsmask = (1 << cnt ) - 1;
311 bits &= keepbitsmask;
312 let mut diff;
313 if t == 16 {
314 diff = 1 << 15;
315 } else {
316 while cnt < t as usize {
317 let one = self.data[ix] as i32;
319 let two = self.data[ix+1] as i32;
320 bits = (bits << 16) | (one << 8) | two;
321 cnt += 16;
322 ix += 2;
323 if one == 0xFF {
325 bits >>= 8;
326 cnt -= 8;
327 } else if two == 0xFF { ix += 1; }
328 }
329 cnt -= t as usize;
330 diff = bits >> cnt;
331 let mut vt = 1 << (t - 1);
332 if diff < vt {
333 vt = (-1 << t) + 1;
334 diff += vt;
335 }
336 }
337 keepbitsmask = (1 << cnt)-1;
338 self.bits = bits & keepbitsmask;
339 self.cnt = cnt;
340 self.ix = ix;
341
342 return diff;
343 }
344}