1mod apple_compression;
8pub mod codec;
9mod color;
10mod model;
11mod predictor;
12pub mod raw;
13pub mod tile;
14
15pub use crate::model::{DecodeType, PixelFormat, Predictor};
16
17use thiserror::Error;
18
19#[derive(Error, Debug)]
20pub enum Deepmap2Error {
21 #[error("invalid magic bytes")]
22 InvalidMagic,
23 #[error("truncated data")]
24 Truncated,
25 #[error("unsupported decode type: {0}")]
26 UnsupportedDecodeType(u8),
27 #[error("unsupported pixel format: {0}")]
28 UnsupportedPixelFormat(u8),
29 #[error("invalid palette size: {0}")]
30 InvalidPaletteSize(u16),
31 #[error("invalid palette type: {0}")]
32 InvalidPaletteType(u16),
33 #[error("invalid data: {0}")]
34 InvalidData(String),
35 #[error("lzfse decompression failed")]
36 LzfseDecompress,
37 #[error("native fallback unavailable: {0}")]
38 NativeFallbackUnavailable(&'static str),
39 #[error("lzvn decompression failed")]
40 LzvnDecompress,
41 #[error("deku parse error: {0}")]
42 DekuParse(#[from] deku::DekuError),
43}
44
45pub type Deepmap2Result<T> = Result<T, Deepmap2Error>;
46
47pub struct DecodedImage {
48 pub source_header: raw::Deepmap2Header,
49 pub width: u16,
50 pub height: u16,
51 pub pixel_format: PixelFormat,
52 pub rgba: Vec<u8>,
53}
54
55pub fn decode(data: &[u8]) -> Deepmap2Result<DecodedImage> {
56 decode_with_options(data, None, None, None)
57}
58
59pub fn decode_with_options(
60 data: &[u8],
61 output_width: Option<u16>,
62 output_height: Option<u16>,
63 pixel_format_override: Option<PixelFormat>,
64) -> Deepmap2Result<DecodedImage> {
65 use deku::prelude::*;
66
67 let mut cursor = std::io::Cursor::new(data);
68 let mut reader = Reader::new(&mut cursor);
69 let header = raw::Deepmap2Header::from_reader_with_ctx(&mut reader, ())?;
70 let header_size = header.header_size();
71 let payload = data.get(header_size..).ok_or(Deepmap2Error::Truncated)?;
72
73 let width = output_width.unwrap_or(header.width);
74 let height = output_height.unwrap_or(header.height);
75 let rgba = codec::decode_raw_with_options(
76 &header,
77 payload,
78 Some(width),
79 Some(height),
80 pixel_format_override,
81 )?;
82 let pixel_format = pixel_format_override.unwrap_or(header.pixel_format);
83
84 Ok(DecodedImage {
85 source_header: header,
86 width,
87 height,
88 pixel_format,
89 rgba,
90 })
91}
92
93pub fn decode_kcbc(data: &[u8]) -> Deepmap2Result<DecodedImage> {
94 decode_kcbc_with_options(data, None, None, None)
95}
96
97pub fn decode_kcbc_with_options(
98 data: &[u8],
99 expected_width: Option<u16>,
100 expected_height: Option<u16>,
101 pixel_format_override: Option<PixelFormat>,
102) -> Deepmap2Result<DecodedImage> {
103 tile::decode_kcbc_sequence_with_options(
104 data,
105 expected_width,
106 expected_height,
107 pixel_format_override,
108 )
109}