]> git.nihav.org Git - nihav.git/blame_incremental - nihav-commonfmt/src/codecs/jpeg.rs
add YUV4MPEG muxer
[nihav.git] / nihav-commonfmt / src / codecs / jpeg.rs
... / ...
CommitLineData
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)]
66#[allow(clippy::identity_op)]
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
240 #[allow(clippy::many_single_char_names)]
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 {
446 generate_cb(&AC_LENS[idx], AC_SYMS[idx])
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);
640 if let Err(err) = ret {
641 return Err(err);
642 }
643 } else { unreachable!(); }
644 },
645 JPEGType::Progressive => {
646 validate!(ss < 64 && se < 64 && se >= ss);
647 validate!(ah < 14 && al < 14);
648 return Err(DecoderError::NotImplemented);
649 },
650 JPEGType::Lossless => {
651 validate!(ss >= 1 && ss < 8 && se == 0);
652 validate!(ah == 0);
653 return Err(DecoderError::NotImplemented);
654 },
655 _ => return Err(DecoderError::NotImplemented),
656 };
657 let tag = br.peek_u16be()?;
658 validate!((tag >= 0xFFD0 && tag <= 0xFFD7) || (tag == 0xFFD9));
659 },
660 0xFFDB => { //quant tables
661 let mut len = br.read_u16be()? as usize;
662 validate!(len >= 64 + 3);
663 len -= 2;
664 while len > 0 {
665 let pt = br.read_byte()?;
666 let precision = pt >> 4;
667 validate!(precision < 2);
668 let id = (pt & 0xF) as usize;
669 validate!(id < 4);
670 let qsize = if precision == 0 { 64 } else { 64 * 2 } + 1;
671 validate!(len >= qsize);
672 if precision == 0 {
673 for el in self.quant[id].iter_mut() {
674 *el = i16::from(br.read_byte()?);
675 }
676 } else {
677 for el in self.quant[id].iter_mut() {
678 *el = br.read_u16be()? as i16;
679 }
680 }
681 len -= qsize;
682 }
683 },
684 0xFFDC => { //number of lines
685 return Err(DecoderError::NotImplemented);
686 },
687 0xFFDD => {
688 let len = br.read_u16be()?;
689 validate!(len == 4);
690 let ri = br.read_u16be()?;
691 if ri != 0 {
692 println!("restart interval {}", ri);
693 return Err(DecoderError::NotImplemented);
694 }
695 },
696 0xFFDE => return Err(DecoderError::NotImplemented),
697 0xFFDF => return Err(DecoderError::NotImplemented),
698 0xFFE0..=0xFFEF => { // application data
699 let len = br.read_u16be()? as usize;
700 validate!(len >= 2);
701 br.read_skip(len - 2)?;
702 },
703 0xFFF0..=0xFFF6 => return Err(DecoderError::NotImplemented),
704 0xFFF7 => {
705 //jtype = JPEGType::JPEGLS;
706 //arith = false;
707 return Err(DecoderError::NotImplemented);
708 },
709 0xFFF8 => return Err(DecoderError::NotImplemented), //JPEG-LS parameters
710 0xFFF9..=0xFFFD => return Err(DecoderError::NotImplemented),
711 0xFFFE => { //comment
712 let len = br.read_u16be()? as usize;
713 validate!(len >= 2);
714 br.read_skip(len - 2)?;
715 },
716 0xFF01 => return Err(DecoderError::NotImplemented),
717 0xFF02..=0xFFBF => return Err(DecoderError::NotImplemented),
718 _ => return Err(DecoderError::InvalidData),
719 };
720 }
721 validate!(jtype != JPEGType::None);
722
723 if let NABufferType::None = bufinfo {
724 return Err(DecoderError::InvalidData);
725 }
726
727 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
728 frm.set_keyframe(true);
729 frm.set_frame_type(FrameType::I);
730 Ok(frm.into_ref())
731 }
732 fn flush(&mut self) {
733 }
734}
735
736impl NAOptionHandler for JPEGDecoder {
737 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
738 fn set_options(&mut self, _options: &[NAOption]) { }
739 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
740}
741
742pub fn get_decoder() -> Box<dyn NADecoder + Send> {
743 Box::new(JPEGDecoder::new())
744}
745
746#[cfg(test)]
747mod test {
748 use nihav_core::codecs::RegisteredDecoders;
749 use nihav_core::demuxers::RegisteredDemuxers;
750 use nihav_codec_support::test::dec_video::*;
751 use crate::generic_register_all_decoders;
752 use crate::generic_register_all_demuxers;
753 #[test]
754 fn test_jpeg() {
755 let mut dmx_reg = RegisteredDemuxers::new();
756 generic_register_all_demuxers(&mut dmx_reg);
757 let mut dec_reg = RegisteredDecoders::new();
758 generic_register_all_decoders(&mut dec_reg);
759 // sample: self-created with avconv
760 test_decoding("avi", "jpeg", "assets/Misc/mjpeg.avi", Some(1), &dmx_reg,
761 &dec_reg, ExpectedTestResult::MD5Frames(vec![
762 [0xe07f7128, 0x8c55eb5d, 0x03bfdee5, 0x358b24a4],
763 [0xd3ec3f92, 0x1664c56d, 0xfc049754, 0xf65165b9]]));
764 }
765}
766
767const DC_LENS: [[u8; 16]; 2] = [
768 [ 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 ],
769 [ 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ]
770];
771const DC_SYMS: [u8; 12] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];
772const AC_LENS: [[u8; 16]; 2] = [
773 [ 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125 ],
774 [ 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119 ]
775];
776const AC_SYMS: [&[u8]; 2] = [
777 &[
778 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
779 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
780 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
781 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
782 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
783 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
784 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
785 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
786 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
787 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
788 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
789 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
790 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
791 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
792 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
793 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
794 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
795 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
796 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
797 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
798 0xf9, 0xfa
799 ],
800 &[
801 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
802 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
803 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
804 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
805 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
806 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
807 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
808 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
809 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
810 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
811 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
812 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
813 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
814 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
815 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
816 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
817 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
818 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
819 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
820 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
821 0xf9, 0xfa
822 ]
823];