]> git.nihav.org Git - nihav.git/blame - nihav-commonfmt/src/codecs/jpeg.rs
avimux: do not record palette change chunks in OpenDML index
[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
b5e49861
KS
18fn idct_row(row: &mut [i16]) {
19 let in0 = ((i32::from(row[0])) << 11) + (1 << (ROW_SHIFT - 1));
20 let in1 = (i32::from(row[4])) << 11;
21 let in2 = i32::from(row[6]);
22 let in3 = i32::from(row[2]);
23 let in4 = i32::from(row[1]);
24 let in5 = i32::from(row[7]);
25 let in6 = i32::from(row[5]);
26 let in7 = i32::from(row[3]);
27
28 let tmp = W7 * (in4 + in5);
29 let a4 = tmp + (W1 - W7) * in4;
30 let a5 = tmp - (W1 + W7) * in5;
31
32 let tmp = W3 * (in6 + in7);
33 let a6 = tmp - (W3 - W5) * in6;
34 let a7 = tmp - (W3 + W5) * in7;
35
36 let tmp = in0 + in1;
37
38 let a0 = in0 - in1;
39 let t1 = W6 * (in2 + in3);
40 let a2 = t1 - (W2 + W6) * in2;
41 let a3 = t1 + (W2 - W6) * in3;
42 let b1 = a4 + a6;
43
44 let b4 = a4 - a6;
45 let t2 = a5 - a7;
46 let b6 = a5 + a7;
47 let b7 = tmp + a3;
48 let b5 = tmp - a3;
49 let b3 = a0 + a2;
50 let b0 = a0 - a2;
51 let b2 = (W8 * (b4 + t2) + 128) >> 8;
52 let b4 = (W8 * (b4 - t2) + 128) >> 8;
53
54 row[0] = ((b7 + b1) >> ROW_SHIFT) as i16;
55 row[7] = ((b7 - b1) >> ROW_SHIFT) as i16;
56 row[1] = ((b3 + b2) >> ROW_SHIFT) as i16;
57 row[6] = ((b3 - b2) >> ROW_SHIFT) as i16;
58 row[2] = ((b0 + b4) >> ROW_SHIFT) as i16;
59 row[5] = ((b0 - b4) >> ROW_SHIFT) as i16;
60 row[3] = ((b5 + b6) >> ROW_SHIFT) as i16;
61 row[4] = ((b5 - b6) >> ROW_SHIFT) as i16;
62}
63
64#[allow(clippy::erasing_op)]
cc0a023d 65#[allow(clippy::identity_op)]
b5e49861
KS
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)]
b5e49861
KS
133enum JPEGType {
134 None,
135 Baseline,
136 Extended,
137 Progressive,
138 Lossless,
139 Differential,
140 DiffProgressive,
141 DiffLossless,
ba8718ff 142 //JPEGLS,
b5e49861
KS
143}
144
145struct JPEGDecoder {
146 info: NACodecInfoRef,
147 quant: [[i16; 64]; 4],
148 qselect: [u8; MAX_CHROMATONS],
149 comp_id: [u8; MAX_CHROMATONS],
150 subsamp: [u8; MAX_CHROMATONS],
151 codebook: [[Option<Codebook<u8>>; 4]; 2],
152 width: usize,
153 height: usize,
154 depth: u8,
155 buf: Vec<u8>,
156}
157
158fn read_dc(br: &mut BitReader, cb: &Codebook<u8>) -> DecoderResult<i16> {
159 let cat = br.read_cb(cb)?;
160 if cat == 0 {
161 Ok(0)
162 } else {
163 validate!(cat < 12);
164 let add_bits = br.read(cat)? as i16;
165 let pivot = 1 << (cat - 1);
166 if add_bits < pivot {
167 Ok(add_bits + 1 - pivot * 2)
168 } else {
169 Ok(add_bits)
170 }
171 }
172}
173
174fn read_ac(br: &mut BitReader, cb: &Codebook<u8>) -> DecoderResult<(usize, i16)> {
175 let val = br.read_cb(cb)?;
176 let run = usize::from(val >> 4);
177 let cat = val & 0xF;
178 let level = if cat != 0 {
179 validate!(cat < 11);
180 let add_bits = br.read(cat)? as i16;
181 let pivot = 1 << (cat - 1);
182 if add_bits < pivot {
183 add_bits + 1 - pivot * 2
184 } else {
185 add_bits
186 }
187 } else {
188 validate!(run == 0 || run == 15);
189 0
190 };
191 Ok((run, level))
192}
193
194fn 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<()> {
195 if ss == 0 {
196 blk[0] = read_dc(br, dc_cb)?;
197 blk[0] *= qmat[0];
198 }
199 let mut idx = 1;
200 while idx <= se {
201 let (run, level) = read_ac(br, ac_cb)?;
202 if run == 0 && level == 0 {
203 break;
204 }
205 idx += run;
206 validate!(idx < 64);
207 blk[ZIGZAG[idx]] = level * qmat[idx];
208 idx += 1;
209 }
210 Ok(())
211}
212
213impl JPEGDecoder {
214 fn new() -> Self {
215 let dummy_info = NACodecInfo::new_dummy();
216
217 Self {
218 info: dummy_info,
219 quant: [[0; 64]; 4],
220 qselect: [0; MAX_CHROMATONS],
221 subsamp: [0; MAX_CHROMATONS],
222 comp_id: [0; MAX_CHROMATONS],
223 codebook: [[None, None, None, None], [None, None, None, None]],
224 width: 0,
225 height: 0,
226 depth: 0,
227 buf: Vec::new(),
228 }
229 }
230 fn reset(&mut self) {
231 self.quant = [[0; 64]; 4];
232 self.codebook = [[None, None, None, None], [None, None, None, None]];
233 self.width = 0;
234 self.height = 0;
235 self.depth = 0;
236 }
237
238 fn parse_sof(&mut self, br: &mut ByteReader) -> DecoderResult<NABufferType> {
239 validate!(self.width == 0);
240
241 let len = br.read_u16be()? as usize;
242 validate!(len >= 11);
243 let p = br.read_byte()?;
244 validate!(p > 2);
245 if p != 8 {
246 return Err(DecoderError::NotImplemented);
247 }
248 let y = br.read_u16be()? as usize;
249 let x = br.read_u16be()? as usize;
250 validate!(x > 0);
251 if y == 0 {
252 return Err(DecoderError::NotImplemented);
253 }
254 self.depth = p;
255 self.width = x;
256 self.height = y;
257 let nf = br.read_byte()? as usize;
258 validate!(nf > 0);
259 validate!(len == 8 + nf * 3);
260 if nf > MAX_CHROMATONS {
261 return Err(DecoderError::NotImplemented);
262 }
263 let mut max_h = 0;
264 let mut max_v = 0;
265 for i in 0..nf {
266 let c = br.read_byte()?;
267 self.comp_id[i] = c;
268 let hv = br.read_byte()?;
269 let t = br.read_byte()?;
270 validate!(t < 4);
271 self.qselect[i] = t;
272 self.subsamp[i] = hv;
273 let hs = hv >> 4;
274 validate!(hs == 1 || hs == 2);
275 let vs = hv & 0xF;
276 validate!(vs == 1 || vs == 2);
277 max_h = max_h.max(hs);
278 max_v = max_v.max(vs);
279 }
280 let mut chromatons = [None; MAX_CHROMATONS];
281 for (i, chr) in chromatons[..nf].iter_mut().enumerate() {
282 let h_ss = match max_h / (self.subsamp[i] >> 4) {
283 1 => 0,
284 2 => 1,
285 _ => unreachable!(),
286 };
287 let v_ss = match max_v / (self.subsamp[i] & 0xF) {
288 1 => 0,
289 2 => 1,
290 _ => return Err(DecoderError::InvalidData),
291 };
292
293 *chr = Some(NAPixelChromaton {
294 h_ss, v_ss,
295 packed: false,
296 depth: p,
297 shift: 0,
298 comp_offs: i as u8,
299 next_elem: (p + 7) >> 3,
300 });
301 }
302 for i in 0..nf {
303 for j in i + 1..nf {
304 validate!(self.comp_id[i] != self.comp_id[j]);
305 }
306 }
307 let formaton = NAPixelFormaton {
308 model: ColorModel::YUV(YUVSubmodel::YUVJ),
309 components: nf as u8,
310 comp_info: chromatons,
311 elem_size: 0,
312 be: false,
313 alpha: nf == 2 || nf == 4,
314 palette: false,
315 };
316 let vinfo = NAVideoInfo::new(x, y, false, formaton);
317 Ok(alloc_video_buffer(vinfo, 4)?)
318 }
319
320 fn decode_scan(&mut self, src: &[u8], mut buf: NAVideoBufferRef<u8>, ci: &[ComponentInfo], ss: usize, se: usize) -> DecoderResult<usize> {
321 let num_components = ci.len();
322 let mut last_dc = [1024; MAX_CHROMATONS];
323 let mut dc_cbs = Vec::with_capacity(num_components);
324 let mut ac_cbs = Vec::with_capacity(num_components);
325 let mut qmats = [&self.quant[0]; MAX_CHROMATONS];
326 for (i, cinfo) in ci.iter().enumerate() {
327 dc_cbs.push(if let Some(ref cb) = self.codebook[0][cinfo.dc_table_id] {
328 cb
329 } else { unreachable!(); });
330 ac_cbs.push(if let Some(ref cb) = self.codebook[1][cinfo.ac_table_id] {
331 cb
332 } else { unreachable!(); });
333 qmats[i] = &self.quant[self.qselect[cinfo.component_id] as usize];
334 }
335
336 let frm = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
337
338 let mut br = BitReader::new(src, BitReaderMode::BE);
339
340 let mut offs = frm.offset;
341 let mut nblks = [0; MAX_CHROMATONS];
342 let mut xstep = [0; MAX_CHROMATONS];
343 let mut ystep = [0; MAX_CHROMATONS];
344 let mut hstep = 8;
345 let mut vstep = 8;
346 for i in 0..num_components {
347 let hs = (self.subsamp[i] >> 4) as usize;
348 let vs = (self.subsamp[i] & 0xF) as usize;
349 hstep = hstep.max(hs * 8);
350 vstep = vstep.max(vs * 8);
351 nblks[i] = hs * vs;
352 xstep[i] = hs * 8;
353 ystep[i] = vs * 8;
354 }
355
356 let mut blocks;
357 for _y in (0..self.height).step_by(vstep) {
358 for x in 0..(self.width + hstep - 1) / hstep {
359 for i in 0..num_components {
360 blocks = [[0; 64]; 4];
361 for blk in blocks[..nblks[i]].iter_mut() {
362 read_block(&mut br, blk, dc_cbs[i], ac_cbs[i], ss, se, qmats[i])?;
363 blk[0] += last_dc[i];
364 last_dc[i] = blk[0];
365 idct(blk);
366 }
367 match self.subsamp[i] {
368 0x11 => {
369 put_block(&blocks[0], &mut frm.data[offs[i] + x * 8..], frm.stride[i]);
370 },
371 0x21 => {
372 put_block(&blocks[0], &mut frm.data[offs[i] + x * 16..], frm.stride[i]);
373 put_block(&blocks[1], &mut frm.data[offs[i] + x * 16 + 8..], frm.stride[i]);
374 },
375 0x12 => {
376 put_block(&blocks[0], &mut frm.data[offs[i] + x * 8..], frm.stride[i]);
377 put_block(&blocks[1], &mut frm.data[offs[i] + x * 8 + frm.stride[i] * 8..], frm.stride[i]);
378 },
379 0x22 => {
ba8718ff 380 #[allow(clippy::needless_range_loop)]
b5e49861
KS
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 {
6f263099 444 generate_cb(&AC_LENS[idx], AC_SYMS[idx])
b5e49861
KS
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);
e6aaad5c 638 ret?;
b5e49861
KS
639 } else { unreachable!(); }
640 },
641 JPEGType::Progressive => {
642 validate!(ss < 64 && se < 64 && se >= ss);
643 validate!(ah < 14 && al < 14);
644 return Err(DecoderError::NotImplemented);
645 },
646 JPEGType::Lossless => {
647 validate!(ss >= 1 && ss < 8 && se == 0);
648 validate!(ah == 0);
649 return Err(DecoderError::NotImplemented);
650 },
651 _ => return Err(DecoderError::NotImplemented),
652 };
653 let tag = br.peek_u16be()?;
654 validate!((tag >= 0xFFD0 && tag <= 0xFFD7) || (tag == 0xFFD9));
655 },
656 0xFFDB => { //quant tables
657 let mut len = br.read_u16be()? as usize;
658 validate!(len >= 64 + 3);
659 len -= 2;
660 while len > 0 {
661 let pt = br.read_byte()?;
662 let precision = pt >> 4;
663 validate!(precision < 2);
664 let id = (pt & 0xF) as usize;
665 validate!(id < 4);
666 let qsize = if precision == 0 { 64 } else { 64 * 2 } + 1;
667 validate!(len >= qsize);
668 if precision == 0 {
669 for el in self.quant[id].iter_mut() {
670 *el = i16::from(br.read_byte()?);
671 }
672 } else {
673 for el in self.quant[id].iter_mut() {
674 *el = br.read_u16be()? as i16;
675 }
676 }
677 len -= qsize;
678 }
679 },
680 0xFFDC => { //number of lines
681 return Err(DecoderError::NotImplemented);
682 },
683 0xFFDD => {
684 let len = br.read_u16be()?;
685 validate!(len == 4);
686 let ri = br.read_u16be()?;
687 if ri != 0 {
688 println!("restart interval {}", ri);
689 return Err(DecoderError::NotImplemented);
690 }
691 },
692 0xFFDE => return Err(DecoderError::NotImplemented),
693 0xFFDF => return Err(DecoderError::NotImplemented),
694 0xFFE0..=0xFFEF => { // application data
695 let len = br.read_u16be()? as usize;
696 validate!(len >= 2);
697 br.read_skip(len - 2)?;
698 },
699 0xFFF0..=0xFFF6 => return Err(DecoderError::NotImplemented),
700 0xFFF7 => {
701 //jtype = JPEGType::JPEGLS;
702 //arith = false;
703 return Err(DecoderError::NotImplemented);
704 },
705 0xFFF8 => return Err(DecoderError::NotImplemented), //JPEG-LS parameters
706 0xFFF9..=0xFFFD => return Err(DecoderError::NotImplemented),
707 0xFFFE => { //comment
708 let len = br.read_u16be()? as usize;
709 validate!(len >= 2);
710 br.read_skip(len - 2)?;
711 },
712 0xFF01 => return Err(DecoderError::NotImplemented),
713 0xFF02..=0xFFBF => return Err(DecoderError::NotImplemented),
714 _ => return Err(DecoderError::InvalidData),
715 };
716 }
717 validate!(jtype != JPEGType::None);
718
719 if let NABufferType::None = bufinfo {
720 return Err(DecoderError::InvalidData);
721 }
722
723 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
724 frm.set_keyframe(true);
725 frm.set_frame_type(FrameType::I);
726 Ok(frm.into_ref())
727 }
728 fn flush(&mut self) {
729 }
730}
731
732impl NAOptionHandler for JPEGDecoder {
733 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
734 fn set_options(&mut self, _options: &[NAOption]) { }
735 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
736}
737
738pub fn get_decoder() -> Box<dyn NADecoder + Send> {
739 Box::new(JPEGDecoder::new())
740}
741
742#[cfg(test)]
743mod test {
744 use nihav_core::codecs::RegisteredDecoders;
745 use nihav_core::demuxers::RegisteredDemuxers;
746 use nihav_codec_support::test::dec_video::*;
747 use crate::generic_register_all_decoders;
748 use crate::generic_register_all_demuxers;
749 #[test]
750 fn test_jpeg() {
751 let mut dmx_reg = RegisteredDemuxers::new();
752 generic_register_all_demuxers(&mut dmx_reg);
753 let mut dec_reg = RegisteredDecoders::new();
754 generic_register_all_decoders(&mut dec_reg);
886cde48 755 // sample: self-created with avconv
b5e49861
KS
756 test_decoding("avi", "jpeg", "assets/Misc/mjpeg.avi", Some(1), &dmx_reg,
757 &dec_reg, ExpectedTestResult::MD5Frames(vec![
758 [0xe07f7128, 0x8c55eb5d, 0x03bfdee5, 0x358b24a4],
759 [0xd3ec3f92, 0x1664c56d, 0xfc049754, 0xf65165b9]]));
760 }
761}
762
763const DC_LENS: [[u8; 16]; 2] = [
764 [ 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 ],
765 [ 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 ]
766];
767const DC_SYMS: [u8; 12] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ];
768const AC_LENS: [[u8; 16]; 2] = [
769 [ 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125 ],
770 [ 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119 ]
771];
772const AC_SYMS: [&[u8]; 2] = [
773 &[
774 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
775 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
776 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
777 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
778 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
779 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
780 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
781 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
782 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
783 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
784 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
785 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
786 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
787 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
788 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
789 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
790 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
791 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
792 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
793 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
794 0xf9, 0xfa
795 ],
796 &[
797 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
798 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
799 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
800 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
801 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
802 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
803 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
804 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
805 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
806 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
807 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
808 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
809 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
810 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
811 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
812 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
813 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
814 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
815 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
816 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
817 0xf9, 0xfa
818 ]
819];