1#![forbid(unsafe_code)]
20#![forbid(trivial_casts)]
21#![forbid(trivial_numeric_casts)]
22#![forbid(non_ascii_idents)]
23#![forbid(unused_extern_crates)]
24#![forbid(unused_import_braces)]
25#![forbid(redundant_lifetimes)]
26#![forbid(single_use_lifetimes)]
27#![forbid(unused_extern_crates)]
28#![forbid(unused_lifetimes)]
29#![forbid(unused_macro_rules)]
30#![forbid(macro_use_extern_crate)]
31#![forbid(missing_unsafe_on_extern)]
32#![deny(missing_docs)]
33
34mod consts;
35mod helpers;
36mod jpeg;
37mod metrics;
38mod structs;
39
40mod enabled_features;
41mod lepton_error;
42
43pub use enabled_features::EnabledFeatures;
44pub use helpers::catch_unwind_result;
45pub use lepton_error::{ExitCode, LeptonError};
46pub use metrics::{CpuTimeMeasure, Metrics};
47pub use structs::lepton_file_writer::get_git_version;
48
49use crate::lepton_error::{AddContext, Result};
50pub use crate::structs::simple_threadpool::{
51 DEFAULT_THREAD_POOL, LeptonThreadPool, LeptonThreadPriority, SimpleThreadPool,
52 SingleThreadPool, ThreadPoolHolder,
53};
54
55#[cfg(feature = "micro_benchmark")]
56pub mod micro_benchmark;
58
59pub trait StreamPosition {
68 fn position(&mut self) -> u64;
70}
71
72impl<T: std::io::Seek> StreamPosition for T {
73 fn position(&mut self) -> u64 {
74 self.stream_position().unwrap()
75 }
76}
77
78pub use structs::lepton_file_reader::decode_lepton;
79
80pub use structs::lepton_file_writer::{encode_lepton, encode_lepton_verify};
81
82static PACKAGE_VERSION: &str = env!("CARGO_PKG_VERSION");
83
84pub use structs::lepton_file_reader::LeptonFileReader;
85
86pub fn get_version_string() -> String {
89 format!("{}-{}", PACKAGE_VERSION, get_git_version())
90}
91
92#[allow(dead_code)]
94pub fn dump_jpeg(input_data: &[u8], all: bool, enabled_features: &EnabledFeatures) -> Result<()> {
95 use std::io::Cursor;
96 use structs::lepton_file_reader::decode_lepton_file_image;
97 use structs::lepton_file_writer::read_jpeg;
98
99 let mut lh;
100 let block_image;
101
102 if input_data[0] == 0xff && input_data[1] == 0xd8 {
103 let mut reader = Cursor::new(input_data);
104
105 (lh, block_image) = read_jpeg(&mut reader, enabled_features, |jh, _ri| {
106 println!("parsed header:");
107 let s = format!("{jh:?}");
108 println!("{0}", s.replace("},", "},\r\n").replace("],", "],\r\n"));
109 })?;
110 } else {
111 let mut reader = Cursor::new(input_data);
112
113 (lh, block_image) =
114 decode_lepton_file_image(&mut reader, enabled_features, &DEFAULT_THREAD_POOL)
115 .context()?;
116
117 loop {
118 println!("parsed header:");
119 let s = format!("{0:?}", lh.jpeg_header);
120 println!("{0}", s.replace("},", "},\r\n").replace("],", "],\r\n"));
121
122 if !lh
123 .advance_next_header_segment(&enabled_features)
124 .context()?
125 {
126 break;
127 }
128 }
129 }
130
131 let s = format!("{lh:?}");
132 println!("{0}", s.replace("},", "},\r\n").replace("],", "],\r\n"));
133
134 if all {
135 for i in 0..block_image.len() {
136 println!("Component {0}", i);
137 let image = &block_image[i];
138 for dpos in 0..image.get_block_width() * image.get_original_height() {
139 print!("dpos={0} ", dpos);
140 let block = image.get_block(dpos);
141
142 print!("{0}", block.get_transposed_from_zigzag(0));
143 for i in 1..64 {
144 print!(",{0}", block.get_transposed_from_zigzag(i));
145 }
146 println!();
147 }
148 }
149 }
150
151 return Ok(());
152}