add LinePack decoder
[nihav.git] / nihav-commonfmt / src / codecs / jpeg.rs
CommitLineData
b5e49861
KS
1use nihav_core::io::byteio::{ByteReader,MemoryReader};
2use nihav_core::io::bitreader::*;
3use nihav_core::io::codebook::*;
4use nihav_core::codecs::*;
5use nihav_codec_support::codecs::ZIGZAG;
6
7const W1: i32 = 2841;
8const W2: i32 = 2676;
9const W3: i32 = 2408;
10const W5: i32 = 1609;
11const W6: i32 = 1108;
12const W7: i32 = 565;
13const W8: i32 = 181;
14
15const ROW_SHIFT: u8 = 8;
16const COL_SHIFT: u8 = 14;
17
18#[allow(clippy::erasing_op)]
19fn idct_row(row: &mut [i16]) {
20 let in0 = ((i32::from(row[0])) << 11) + (1 << (ROW_SHIFT - 1));
21 let in1 = (i32::from(row[4])) << 11;
22 let in2 = i32::from(row[6]);
23 let in3 = i32::from(row[2]);
24 let in4 = i32::from(row[1]);
25 let in5 = i32::from(row[7]);
26 let in6 = i32::from(row[5]);
27 let in7 = i32::from(row[3]);
28
29 let tmp = W7 * (in4 + in5);
30 let a4 = tmp + (W1 - W7) * in4;
31 let a5 = tmp - (W1 + W7) * in5;
32
33 let tmp = W3 * (in6 + in7);
34 let a6 = tmp - (W3 - W5) * in6;
35 let a7 = tmp - (W3 + W5) * in7;
36
37 let tmp = in0 + in1;
38
39 let a0 = in0 - in1;
40 let t1 = W6 * (in2 + in3);
41 let a2 = t1 - (W2 + W6) * in2;
42 let a3 = t1 + (W2 - W6) * in3;
43 let b1 = a4 + a6;
44
45 let b4 = a4 - a6;
46 let t2 = a5 - a7;
47 let b6 = a5 + a7;
48 let b7 = tmp + a3;
49 let b5 = tmp - a3;
50 let b3 = a0 + a2;
51 let b0 = a0 - a2;
52 let b2 = (W8 * (b4 + t2) + 128) >> 8;
53 let b4 = (W8 * (b4 - t2) + 128) >> 8;
54
55 row[0] = ((b7 + b1) >> ROW_SHIFT) as i16;
56 row[7] = ((b7 - b1) >> ROW_SHIFT) as i16;
57 row[1] = ((b3 + b2) >> ROW_SHIFT) as i16;
58 row[6] = ((b3 - b2) >> ROW_SHIFT) as i16;
59 row[2] = ((b0 + b4) >> ROW_SHIFT) as i16;
60 row[5] = ((b0 - b4) >> ROW_SHIFT) as i16;
61 row[3] = ((b5 + b6) >> ROW_SHIFT) as i16;
62 row[4] = ((b5 - b6) >> ROW_SHIFT) as i16;
63}
64
65#[allow(clippy::erasing_op)]
cc0a023d 66#[allow(clippy::identity_op)]
b5e49861
KS
67fn idct_col(blk: &mut [i16; 64], off: usize) {
68 let in0 = ((i32::from(blk[off + 0*8])) << 8) + (1 << (COL_SHIFT - 1));
69 let in1 = (i32::from(blk[off + 4*8])) << 8;
70 let in2 = i32::from(blk[off + 6*8]);
71 let in3 = i32::from(blk[off + 2*8]);
72 let in4 = i32::from(blk[off + 1*8]);
73 let in5 = i32::from(blk[off + 7*8]);
74 let in6 = i32::from(blk[off + 5*8]);
75 let in7 = i32::from(blk[off + 3*8]);
76
77 let tmp = W7 * (in4 + in5);
78 let a4 = (tmp + (W1 - W7) * in4) >> 3;
79 let a5 = (tmp - (W1 + W7) * in5) >> 3;
80
81 let tmp = W3 * (in6 + in7);
82 let a6 = (tmp - (W3 - W5) * in6) >> 3;
83 let a7 = (tmp - (W3 + W5) * in7) >> 3;
84
85 let tmp = in0 + in1;
86
87 let a0 = in0 - in1;
88 let t1 = W6 * (in2 + in3);
89 let a2 = (t1 - (W2 + W6) * in2) >> 3;
90 let a3 = (t1 + (W2 - W6) * in3) >> 3;
91 let b1 = a4 + a6;
92
93 let b4 = a4 - a6;
94 let t2 = a5 - a7;
95 let b6 = a5 + a7;
96 let b7 = tmp + a3;
97 let b5 = tmp - a3;
98 let b3 = a0 + a2;
99 let b0 = a0 - a2;
100 let b2 = (W8 * (b4 + t2) + 128) >> 8;
101 let b4 = (W8 * (b4 - t2) + 128) >> 8;
102
103 blk[off + 0*8] = ((b7 + b1) >> COL_SHIFT) as i16;
104 blk[off + 7*8] = ((b7 - b1) >> COL_SHIFT) as i16;
105 blk[off + 1*8] = ((b3 + b2) >> COL_SHIFT) as i16;
106 blk[off + 6*8] = ((b3 - b2) >> COL_SHIFT) as i16;
107 blk[off + 2*8] = ((b0 + b4) >> COL_SHIFT) as i16;
108 blk[off + 5*8] = ((b0 - b4) >> COL_SHIFT) as i16;
109 blk[off + 3*8] = ((b5 + b6) >> COL_SHIFT) as i16;
110 blk[off + 4*8] = ((b5 - b6) >> COL_SHIFT) as i16;
111}
112
113fn idct(blk: &mut [i16; 64]) {
114 for i in 0..8 { idct_row(&mut blk[i*8..(i+1)*8]); }
115 for i in 0..8 { idct_col(blk, i); }
116}
117
118fn put_block(blk: &[i16; 64], dst: &mut [u8], stride: usize) {
119 for (drow, srow) in dst.chunks_mut(stride).zip(blk.chunks(8)) {
120 for (del, &pix) in drow.iter_mut().zip(srow.iter()) {
121 *del = pix.max(0).min(255) as u8;
122 }
123 }
124}
125
126#[derive(Clone,Copy,Default)]
127struct ComponentInfo {
128 component_id: usize,
129 dc_table_id: usize,
130 ac_table_id: usize,
131}
132
133#[derive(Debug,PartialEq)]
134#[allow(dead_code)]
135enum JPEGType {
136 None,
137 Baseline,
138 Extended,
139 Progressive,
140 Lossless,
141 Differential,
142 DiffProgressive,
143 DiffLossless,
144 JPEGLS,
145}
146
147struct JPEGDecoder {
148 info: NACodecInfoRef,
149 quant: [[i16; 64]; 4],
150 qselect: [u8; MAX_CHROMATONS],
151 comp_id: [u8; MAX_CHROMATONS],
152 subsamp: [u8; MAX_CHROMATONS],
153 codebook: [[Option<Codebook<u8>>; 4]; 2],
154 width: usize,
155 height: usize,
156 depth: u8,
157 buf: Vec<u8>,
158}
159
160fn read_dc(br: &mut BitReader, cb: &Codebook<u8>) -> DecoderResult<i16> {
161 let cat = br.read_cb(cb)?;
162 if cat == 0 {
163 Ok(0)
164 } else {
165 validate!(cat < 12);
166 let add_bits = br.read(cat)? as i16;
167 let pivot = 1 << (cat - 1);
168 if add_bits < pivot {
169 Ok(add_bits + 1 - pivot * 2)
170 } else {
171 Ok(add_bits)
172 }
173 }
174}
175
176fn read_ac(br: &mut BitReader, cb: &Codebook<u8>) -> DecoderResult<(usize, i16)> {
177 let val = br.read_cb(cb)?;
178 let run = usize::from(val >> 4);
179 let cat = val & 0xF;
180 let level = if cat != 0 {
181 validate!(cat < 11);
182 let add_bits = br.read(cat)? as i16;
183 let pivot = 1 << (cat - 1);
184 if add_bits < pivot {
185 add_bits + 1 - pivot * 2
186 } else {
187 add_bits
188 }
189 } else {
190 validate!(run == 0 || run == 15);
191 0
192 };
193 Ok((run, level))
194}
195
196fn read_block(br: &mut BitReader, blk: &mut [i16; 64], dc_cb: &Codebook<u8>, ac_cb: &Codebook<u8>, ss: usize, se: usize, qmat: &[i16; 64]) -> DecoderResult<()> {
197 if ss == 0 {
198 blk[0] = read_dc(br, dc_cb)?;
199 blk[0] *= qmat[0];
200 }
201 let mut idx = 1;
202 while idx <= se {
203 let (run, level) = read_ac(br, ac_cb)?;
204 if run == 0 && level == 0 {
205 break;
206 }
207 idx += run;
208 validate!(idx < 64);
209 blk[ZIGZAG[idx]] = level * qmat[idx];
210 idx += 1;
211 }
212 Ok(())
213}
214
215impl JPEGDecoder {
216 fn new() -> Self {
217 let dummy_info = NACodecInfo::new_dummy();
218
219 Self {
220 info: dummy_info,
221 quant: [[0; 64]; 4],
222 qselect: [0; MAX_CHROMATONS],
223 subsamp: [0; MAX_CHROMATONS],
224 comp_id: [0; MAX_CHROMATONS],
225 codebook: [[None, None, None, None], [None, None, None, None]],
226 width: 0,
227 height: 0,
228 depth: 0,
229 buf: Vec::new(),
230 }
231 }
232 fn reset(&mut self) {
233 self.quant = [[0; 64]; 4];
234 self.codebook = [[None, None, None, None], [None, None, None, None]];
235 self.width = 0;
236 self.height = 0;
237 self.depth = 0;
238 }
239
cc0a023d 240 #[allow(clippy::many_single_char_names)]
b5e49861
KS
241 fn parse_sof(&mut self, br: &mut ByteReader) -> DecoderResult<NABufferType> {
242 validate!(self.width == 0);
243
244 let len = br.read_u16be()? as usize;
245 validate!(len >= 11);
246 let p = br.read_byte()?;
247 validate!(p > 2);
248 if p != 8 {
249 return Err(DecoderError::NotImplemented);
250 }
251 let y = br.read_u16be()? as usize;
252 let x = br.read_u16be()? as usize;
253 validate!(x > 0);
254 if y == 0 {
255 return Err(DecoderError::NotImplemented);
256 }
257 self.depth = p;
258 self.width = x;
259 self.height = y;
260 let nf = br.read_byte()? as usize;
261 validate!(nf > 0);
262 validate!(len == 8 + nf * 3);
263 if nf > MAX_CHROMATONS {
264 return Err(DecoderError::NotImplemented);
265 }
266 let mut max_h = 0;
267 let mut max_v = 0;
268 for i in 0..nf {
269 let c = br.read_byte()?;
270 self.comp_id[i] = c;
271 let hv = br.read_byte()?;
272 let t = br.read_byte()?;
273 validate!(t < 4);
274 self.qselect[i] = t;
275 self.subsamp[i] = hv;
276 let hs = hv >> 4;
277 validate!(hs == 1 || hs == 2);
278 let vs = hv & 0xF;
279 validate!(vs == 1 || vs == 2);
280 max_h = max_h.max(hs);
281 max_v = max_v.max(vs);
282 }
283 let mut chromatons = [None; MAX_CHROMATONS];
284 for (i, chr) in chromatons[..nf].iter_mut().enumerate() {
285 let h_ss = match max_h / (self.subsamp[i] >> 4) {
286 1 => 0,
287 2 => 1,
288 _ => unreachable!(),
289 };
290 let v_ss = match max_v / (self.subsamp[i] & 0xF) {
291 1 => 0,
292 2 => 1,
293 _ => return Err(DecoderError::InvalidData),
294 };
295
296 *chr = Some(NAPixelChromaton {
297 h_ss, v_ss,
298 packed: false,
299 depth: p,
300 shift: 0,
301 comp_offs: i as u8,
302 next_elem: (p + 7) >> 3,
303 });
304 }
305 for i in 0..nf {
306 for j in i + 1..nf {
307 validate!(self.comp_id[i] != self.comp_id[j]);
308 }
309 }
310 let formaton = NAPixelFormaton {
311 model: ColorModel::YUV(YUVSubmodel::YUVJ),
312 components: nf as u8,
313 comp_info: chromatons,
314 elem_size: 0,
315 be: false,
316 alpha: nf == 2 || nf == 4,
317 palette: false,
318 };
319 let vinfo = NAVideoInfo::new(x, y, false, formaton);
320 Ok(alloc_video_buffer(vinfo, 4)?)
321 }
322
323 fn decode_scan(&mut self, src: &[u8], mut buf: NAVideoBufferRef<u8>, ci: &[ComponentInfo], ss: usize, se: usize) -> DecoderResult<usize> {
324 let num_components = ci.len();
325 let mut last_dc = [1024; MAX_CHROMATONS];
326 let mut dc_cbs = Vec::with_capacity(num_components);
327 let mut ac_cbs = Vec::with_capacity(num_components);
328 let mut qmats = [&self.quant[0]; MAX_CHROMATONS];
329 for (i, cinfo) in ci.iter().enumerate() {
330 dc_cbs.push(if let Some(ref cb) = self.codebook[0][cinfo.dc_table_id] {
331 cb
332 } else { unreachable!(); });
333 ac_cbs.push(if let Some(ref cb) = self.codebook[1][cinfo.ac_table_id] {
334 cb
335 } else { unreachable!(); });
336 qmats[i] = &self.quant[self.qselect[cinfo.component_id] as usize];
337 }
338
339 let frm = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
340
341 let mut br = BitReader::new(src, BitReaderMode::BE);
342
343 let mut offs = frm.offset;
344 let mut nblks = [0; MAX_CHROMATONS];
345 let mut xstep = [0; MAX_CHROMATONS];
346 let mut ystep = [0; MAX_CHROMATONS];
347 let mut hstep = 8;
348 let mut vstep = 8;
349 for i in 0..num_components {
350 let hs = (self.subsamp[i] >> 4) as usize;
351 let vs = (self.subsamp[i] & 0xF) as usize;
352 hstep = hstep.max(hs * 8);
353 vstep = vstep.max(vs * 8);
354 nblks[i] = hs * vs;
355 xstep[i] = hs * 8;
356 ystep[i] = vs * 8;
357 }
358
359 let mut blocks;
360 for _y in (0..self.height).step_by(vstep) {
361 for x in 0..(self.width + hstep - 1) / hstep {
362 for i in 0..num_components {
363 blocks = [[0; 64]; 4];
364 for blk in blocks[..nblks[i]].iter_mut() {
365 read_block(&mut br, blk, dc_cbs[i], ac_cbs[i], ss, se, qmats[i])?;
366 blk[0] += last_dc[i];
367 last_dc[i] = blk[0];
368 idct(blk);
369 }
370 match self.subsamp[i] {
371 0x11 => {
372 put_block(&blocks[0], &mut frm.data[offs[i] + x * 8..], frm.stride[i]);
373 },
374 0x21 => {
375 put_block(&blocks[0], &mut frm.data[offs[i] + x * 16..], frm.stride[i]);
376 put_block(&blocks[1], &mut frm.data[offs[i] + x * 16 + 8..], frm.stride[i]);
377 },
378 0x12 => {
379 put_block(&blocks[0], &mut frm.data[offs[i] + x * 8..], frm.stride[i]);
380 put_block(&blocks[1], &mut frm.data[offs[i] + x * 8 + frm.stride[i] * 8..], frm.stride[i]);
381 },
382 0x22 => {
383 for j in 0..4 {
384 put_block(&blocks[j], &mut frm.data[offs[i] + x * 16 + (j & 1) * 8 + (j >> 1) * 8 * frm.stride[i]..], frm.stride[i]);
385 }
386 },
387 _ => unreachable!(),
388 };
389 }
390 }
391 for i in 0..num_components {
392 offs[i] += frm.stride[i] * ystep[i];
393 }
394 }
395
396 Ok((br.tell() + 7) / 8)
397 }
398}
399
400struct HuffDescReader<'a> {
401 codes: &'a [u16],
402 bits: &'a [u8],
403 syms: &'a [u8],
404}
405
406impl<'a> CodebookDescReader<u8> for HuffDescReader<'a> {
407 fn bits(&mut self, idx: usize) -> u8 { self.bits[idx] }
408 fn code(&mut self, idx: usize) -> u32 { u32::from(self.codes[idx]) }
409 fn sym (&mut self, idx: usize) -> u8 { self.syms[idx] }
410 fn len(&mut self) -> usize { self.syms.len() }
411}
412
413fn generate_cb(lens: &[u8; 16], syms: &[u8]) -> DecoderResult<Codebook<u8>> {
414 let mut codes = [0; 256];
415 let mut bits = [0; 256];
416
417 let mut iter = bits.iter_mut();
418 for (i, &len) in lens.iter().enumerate() {
419 for _ in 0..len {
420 *iter.next().unwrap() = (i + 1) as u8;
421 }
422 }
423 let mut code = 0;
424 let mut si = bits[0];
425 let mut idx = 0;
426 while idx < syms.len() {
427 while idx < syms.len() && bits[idx] == si {
428 codes[idx] = code;
429 code += 1;
430 idx += 1;
431 }
432 while idx < syms.len() && bits[idx] != si {
433 code <<= 1;
434 si += 1;
435 }
436 }
437
438 let mut cbr = HuffDescReader { codes: &codes, bits: &bits, syms };
439 Ok(Codebook::new(&mut cbr, CodebookMode::MSB)?)
440}
441
442fn build_default_cb(dc: bool, idx: usize) -> DecoderResult<Codebook<u8>> {
443 if dc {
444 generate_cb(&DC_LENS[idx], &DC_SYMS)
445 } else {
6f263099 446 generate_cb(&AC_LENS[idx], AC_SYMS[idx])
b5e49861
KS
447 }
448}
449
450impl NADecoder for JPEGDecoder {
451 fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
452 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
453 let w = vinfo.get_width();
454 let h = vinfo.get_height();
455 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(w, h, false, YUV420_FORMAT));
456 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
457 Ok(())
458 } else {
459 Err(DecoderError::InvalidData)
460 }
461 }
462 fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
463 let src = pkt.get_buffer();
464 if src.len() <= 4 { return Err(DecoderError::ShortData); }
465
466 let mut bufinfo = NABufferType::None;
467 let mut mr = MemoryReader::new_read(&src);
468 let mut br = ByteReader::new(&mut mr);
469 let start_tag = br.read_u16be()?;
470 validate!(start_tag == 0xFFD8);
471
472 let mut jtype = JPEGType::None;
473 let mut arith = false;
474 self.reset();
475 loop {
476 let tag = br.read_u16be()?;
477 match tag {
478 0xFFC0 => { //baseline DCT header
479 jtype = JPEGType::Baseline;
480 arith = false;
481 bufinfo = self.parse_sof(&mut br)?;
482 },
483 0xFFC1 => {
484 jtype = JPEGType::Extended;
485 arith = false;
486 bufinfo = self.parse_sof(&mut br)?;
487 },
488 0xFFC2 => {
489 jtype = JPEGType::Progressive;
490 arith = false;
491 bufinfo = self.parse_sof(&mut br)?;
492 },
493 0xFFC3 => {
494 jtype = JPEGType::Lossless;
495 arith = false;
496 bufinfo = self.parse_sof(&mut br)?;
497 },
498 0xFFC5 => {
499 jtype = JPEGType::Differential;
500 arith = false;
501 bufinfo = self.parse_sof(&mut br)?;
502 },
503 0xFFC6 => {
504 jtype = JPEGType::DiffProgressive;
505 arith = false;
506 bufinfo = self.parse_sof(&mut br)?;
507 },
508 0xFFC7 => {
509 jtype = JPEGType::DiffLossless;
510 arith = false;
511 bufinfo = self.parse_sof(&mut br)?;
512 },
513 0xFFC8 => return Err(DecoderError::NotImplemented),
514 0xFFC9 => {
515 jtype = JPEGType::Extended;
516 arith = true;
517 bufinfo = self.parse_sof(&mut br)?;
518 },
519 0xFFCA => {
520 jtype = JPEGType::Progressive;
521 arith = true;
522 bufinfo = self.parse_sof(&mut br)?;
523 },
524 0xFFCB => {
525 jtype = JPEGType::Lossless;
526 arith = true;
527 bufinfo = self.parse_sof(&mut br)?;
528 },
529 0xFFCD => {
530 jtype = JPEGType::Differential;
531 arith = true;
532 bufinfo = self.parse_sof(&mut br)?;
533 },
534 0xFFCE => {
535 jtype = JPEGType::DiffProgressive;
536 arith = true;
537 bufinfo = self.parse_sof(&mut br)?;
538 },
539 0xFFCF => {
540 jtype = JPEGType::DiffLossless;
541 arith = true;
542 bufinfo = self.parse_sof(&mut br)?;
543 },
544 0xFFC4 => { //huff table
545 validate!(!arith);
546 let len = u64::from(br.read_u16be()?);
547 validate!(len > 2);
548 let end = br.tell() + len - 2;
549 let mut lens = [0; 16];
550 let mut syms = [0; 256];
551 while br.tell() < end {
552 let tctn = br.read_byte()? as usize;
553 let tclass = tctn >> 4;
554 validate!(tclass < 2);
555 let id = tctn & 0xF;
556 validate!(id < 4);
557 br.read_buf(&mut lens)?;
558 let mut tot_len = 0usize;
559 for &el in lens.iter() {
560 tot_len += usize::from(el);
561 }
562 validate!(tot_len > 0 && tot_len <= 256);
563 br.read_buf(&mut syms[..tot_len])?;
564 self.codebook[tclass][id] = Some(generate_cb(&lens, &syms[..tot_len])?);
565 }
566 validate!(br.tell() == end);
567 },
568 0xFFCC => { // arith coding conditioning
569 return Err(DecoderError::NotImplemented);
570 }
571 0xFFD0..=0xFFD7 => return Err(DecoderError::NotImplemented),
572 0xFFD9 => break,
573 0xFFDA => { //start of scan
574 let len = br.read_u16be()? as usize;
575 let ns = br.read_byte()? as usize;
576 validate!(len == ns * 2 + 6);
577 let mut ci = [ComponentInfo::default(); MAX_CHROMATONS];
578 for info in ci[..ns].iter_mut() {
579 let id = br.read_byte()?;
580 let mut found = false;
581 for (i, &c_id) in self.comp_id.iter().enumerate() {
582 if c_id == id {
583 info.component_id = i;
584 found = true;
585 break;
586 }
587 }
588 validate!(found);
589 let tdta = br.read_byte()? as usize;
590 let dc_id = tdta >> 4;
591 validate!(dc_id < 4);
592 if self.codebook[0][dc_id].is_none() {
593 validate!(dc_id < 2);
594 self.codebook[0][dc_id] = Some(build_default_cb(true, dc_id)?);
595 }
596 let ac_id = tdta & 0xF;
597 validate!(ac_id < 4);
598 if self.codebook[1][ac_id].is_none() {
599 validate!(ac_id < 2);
600 self.codebook[1][ac_id] = Some(build_default_cb(false, ac_id)?);
601 }
602 info.dc_table_id = dc_id;
603 info.ac_table_id = ac_id;
604 }
605 let ss = br.read_byte()? as usize;
606 let se = br.read_byte()? as usize;
607 let ahal = br.read_byte()?;
608 let ah = ahal >> 4;
609 let al = ahal & 0xF;
610 match jtype {
611 JPEGType::Baseline | JPEGType::Extended => {
612 if arith {
613 return Err(DecoderError::NotImplemented);
614 }
615 validate!(ss == 0 && se == 63);
616 validate!(ah == 0 && al == 0);
617 if let Some(buf) = bufinfo.get_vbuf() {
618 let max_size = src.len() - (br.tell() as usize);
619 self.buf.clear();
620 self.buf.reserve(max_size);
621 loop {
622 let b = br.read_byte()?;
623 if b != 0xFF {
624 self.buf.push(b);
625 } else {
626 let b2 = br.read_byte()?;
627 if b2 == 0 {
628 self.buf.push(b);
629 } else {
630 br.seek(std::io::SeekFrom::Current(-2))?;
631 break;
632 }
633 }
634 }
635
636 let mut data = Vec::new();
637 std::mem::swap(&mut self.buf, &mut data);
638 let ret = self.decode_scan(&data, buf, &ci[..ns], ss, se);
639 std::mem::swap(&mut self.buf, &mut data);
e6aaad5c 640 ret?;
b5e49861
KS
641 } else { unreachable!(); }
642 },
643 JPEGType::Progressive => {
644 validate!(ss < 64 && se < 64 && se >= ss);
645 validate!(ah < 14 && al < 14);
646 return Err(DecoderError::NotImplemented);
647 },
648 JPEGType::Lossless => {
649 validate!(ss >= 1 && ss < 8 && se == 0);
650 validate!(ah == 0);
651 return Err(DecoderError::NotImplemented);
652 },
653 _ => return Err(DecoderError::NotImplemented),
654 };
655 let tag = br.peek_u16be()?;
656 validate!((tag >= 0xFFD0 && tag <= 0xFFD7) || (tag == 0xFFD9));
657 },
658 0xFFDB => { //quant tables
659 let mut len = br.read_u16be()? as usize;
660 validate!(len >= 64 + 3);
661 len -= 2;
662 while len > 0 {
663 let pt = br.read_byte()?;
664 let precision = pt >> 4;
665 validate!(precision < 2);
666 let id = (pt & 0xF) as usize;
667 validate!(id < 4);
668 let qsize = if precision == 0 { 64 } else { 64 * 2 } + 1;
669 validate!(len >= qsize);
670 if precision == 0 {
671 for el in self.quant[id].iter_mut() {
672 *el = i16::from(br.read_byte()?);
673 }
674 } else {
675 for el in self.quant[id].iter_mut() {
676 *el = br.read_u16be()? as i16;
677 }
678 }
679 len -= qsize;
680 }
681 },
682 0xFFDC => { //number of lines
683 return Err(DecoderError::NotImplemented);
684 },
685 0xFFDD => {
686 let len = br.read_u16be()?;
687 validate!(len == 4);
688 let ri = br.read_u16be()?;
689 if ri != 0 {
690 println!("restart interval {}", ri);
691 return Err(DecoderError::NotImplemented);
692 }
693 },
694 0xFFDE => return Err(DecoderError::NotImplemented),
695 0xFFDF => return Err(DecoderError::NotImplemented),
696 0xFFE0..=0xFFEF => { // application data
697 let len = br.read_u16be()? as usize;
698 validate!(len >= 2);
699 br.read_skip(len - 2)?;
700 },
701 0xFFF0..=0xFFF6 => return Err(DecoderError::NotImplemented),
702 0xFFF7 => {
703 //jtype = JPEGType::JPEGLS;
704 //arith = false;
705 return Err(DecoderError::NotImplemented);
706 },
707 0xFFF8 => return Err(DecoderError::NotImplemented), //JPEG-LS parameters
708 0xFFF9..=0xFFFD => return Err(DecoderError::NotImplemented),
709 0xFFFE => { //comment
710 let len = br.read_u16be()? as usize;
711 validate!(len >= 2);
712 br.read_skip(len - 2)?;
713 },
714 0xFF01 => return Err(DecoderError::NotImplemented),
715 0xFF02..=0xFFBF => return Err(DecoderError::NotImplemented),
716 _ => return Err(DecoderError::InvalidData),
717 };
718 }
719 validate!(jtype != JPEGType::None);
720
721 if let NABufferType::None = bufinfo {
722 return Err(DecoderError::InvalidData);
723 }
724
725 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
726 frm.set_keyframe(true);
727 frm.set_frame_type(FrameType::I);
728 Ok(frm.into_ref())
729 }
730 fn flush(&mut self) {
731 }
732}
733
734impl NAOptionHandler for JPEGDecoder {
735 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
736 fn set_options(&mut self, _options: &[NAOption]) { }
737 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
738}
739
740pub fn get_decoder() -> Box<dyn NADecoder + Send> {
741 Box::new(JPEGDecoder::new())
742}
743
744#[cfg(test)]
745mod test {
746 use nihav_core::codecs::RegisteredDecoders;
747 use nihav_core::demuxers::RegisteredDemuxers;
748 use nihav_codec_support::test::dec_video::*;
749 use crate::generic_register_all_decoders;
750 use crate::generic_register_all_demuxers;
751 #[test]
752 fn test_jpeg() {
753 let mut dmx_reg = RegisteredDemuxers::new();
754 generic_register_all_demuxers(&mut dmx_reg);
755 let mut dec_reg = RegisteredDecoders::new();
756 generic_register_all_decoders(&mut dec_reg);
886cde48 757 // sample: self-created with avconv
b5e49861
KS
758 test_decoding("avi", "jpeg", "assets/Misc/mjpeg.avi", Some(1), &dmx_reg,
759 &dec_reg, ExpectedTestResult::MD5Frames(vec![
760 [0xe07f7128, 0x8c55eb5d, 0x03bfdee5, 0x358b24a4],
761 [0xd3ec3f92, 0x1664c56d, 0xfc049754, 0xf65165b9]]));
762 }
763}
764
765const DC_LENS: [[u8; 16]; 2] = [
766 [ 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 ],
767 [ 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ]
768];
769const DC_SYMS: [u8; 12] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];
770const AC_LENS: [[u8; 16]; 2] = [
771 [ 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125 ],
772 [ 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119 ]
773];
774const AC_SYMS: [&[u8]; 2] = [
775 &[
776 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
777 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
778 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
779 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
780 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
781 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
782 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
783 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
784 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
785 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
786 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
787 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
788 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
789 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
790 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
791 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
792 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
793 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
794 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
795 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
796 0xf9, 0xfa
797 ],
798 &[
799 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
800 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
801 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
802 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
803 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
804 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
805 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
806 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
807 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
808 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
809 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
810 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
811 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
812 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
813 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
814 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
815 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
816 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
817 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
818 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
819 0xf9, 0xfa
820 ]
821];