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