1use oxideav_core::{
16 frame::VideoPlane, CodecCapabilities, CodecId, CodecInfo, CodecParameters, CodecRegistry,
17 ContainerRegistry, Decoder, Error, Frame, Packet, PixelFormat, Result, VideoFrame,
18};
19
20use crate::container;
21use crate::decoder::decode_tiff;
22use crate::error::TiffError;
23use crate::image::{TiffImage, TiffPixelFormat};
24use crate::CODEC_ID_STR;
25
26impl From<TiffError> for Error {
27 fn from(e: TiffError) -> Self {
28 match e {
29 TiffError::InvalidData(s) => Error::InvalidData(s),
30 TiffError::Unsupported(s) => Error::Unsupported(s),
31 }
32 }
33}
34
35impl From<TiffPixelFormat> for PixelFormat {
36 fn from(p: TiffPixelFormat) -> Self {
37 match p {
38 TiffPixelFormat::Gray8 => PixelFormat::Gray8,
39 TiffPixelFormat::Gray16Le => PixelFormat::Gray16Le,
40 TiffPixelFormat::Rgb24 => PixelFormat::Rgb24,
41 TiffPixelFormat::Rgb48Le => PixelFormat::Rgb48Le,
42 }
43 }
44}
45
46impl From<TiffImage> for VideoFrame {
47 fn from(img: TiffImage) -> Self {
48 let planes = img
49 .planes
50 .into_iter()
51 .map(|p| VideoPlane {
52 stride: p.stride,
53 data: p.data,
54 })
55 .collect();
56 VideoFrame { pts: None, planes }
57 }
58}
59
60impl From<TiffImage> for Frame {
61 fn from(img: TiffImage) -> Self {
62 Frame::Video(img.into())
63 }
64}
65
66pub fn register_codecs(reg: &mut CodecRegistry) {
68 let caps = CodecCapabilities::video("tiff_sw")
69 .with_intra_only(true)
70 .with_lossless(true)
71 .with_max_size(65535, 65535)
72 .with_pixel_formats(vec![
73 PixelFormat::Rgb24,
74 PixelFormat::Rgb48Le,
75 PixelFormat::Gray8,
76 PixelFormat::Gray16Le,
77 ]);
78 reg.register(
79 CodecInfo::new(CodecId::new(CODEC_ID_STR))
80 .capabilities(caps)
81 .decoder(make_decoder),
82 );
83}
84
85pub fn register_containers(reg: &mut ContainerRegistry) {
87 container::register(reg);
88}
89
90pub fn register(codecs: &mut CodecRegistry, containers: &mut ContainerRegistry) {
93 register_codecs(codecs);
94 register_containers(containers);
95}
96
97pub fn make_decoder(_params: &CodecParameters) -> Result<Box<dyn Decoder>> {
99 Ok(Box::new(TiffDecoder {
100 codec_id: CodecId::new(CODEC_ID_STR),
101 pending: None,
102 eof: false,
103 }))
104}
105
106struct TiffDecoder {
107 codec_id: CodecId,
108 pending: Option<VideoFrame>,
109 eof: bool,
110}
111
112impl Decoder for TiffDecoder {
113 fn codec_id(&self) -> &CodecId {
114 &self.codec_id
115 }
116 fn send_packet(&mut self, packet: &Packet) -> Result<()> {
117 let d = decode_tiff(&packet.data)?;
118 self.pending = Some(d.frame.into());
119 Ok(())
120 }
121 fn receive_frame(&mut self) -> Result<Frame> {
122 match self.pending.take() {
123 Some(f) => Ok(Frame::Video(f)),
124 None => {
125 if self.eof {
126 Err(Error::Eof)
127 } else {
128 Err(Error::NeedMore)
129 }
130 }
131 }
132 }
133 fn flush(&mut self) -> Result<()> {
134 self.eof = true;
135 Ok(())
136 }
137}