1use clap::{App, Arg, ArgMatches};
2
3use crate::config::{
4 Config, FormatEncodingSettings, JPEGEncodingSettings, PNMEncodingSettings, SelectedLicenses,
5};
6use crate::io::{export, import};
7use crate::operations::Operation;
8use crate::processor::encoding_format::EncodingFormatDecider;
9use crate::processor::image_operations::ImageOperationsProcessor;
10use crate::processor::license_display::LicenseDisplayProcessor;
11use crate::processor::{ProcessMutWithConfig, ProcessWithConfig};
12
13mod config;
14mod io;
15pub mod operations;
16mod processor;
17
18pub fn get_app_skeleton(name: &str) -> App<'static, 'static> {
19 App::new(name)
20 .version(env!("CARGO_PKG_VERSION"))
21 .author("Martijn Gribnau <garm@ilumeo.com>")
22 .about("This tool is part of the Stew image toolset. Stew is a set of image transformation tools, adapted from `sic`.")
23 .after_help("For more information, visit: https://github.com/foresterre/stew")
24 .arg(Arg::with_name("forced_output_format")
25 .short("f")
26 .long("output-format")
27 .value_name("FORMAT")
28 .help("Force the output image format to use FORMAT, regardless of the (if any) extension of the given output file path. \
29 Output formats (FORMAT values) supported: BMP, GIF, ICO, JPEG, PNG, PBM, PGM, PPM and PAM.")
30 .takes_value(true))
31 .arg(Arg::with_name("license")
32 .long("license")
33 .help("Displays the license of this piece of software (`stew`).")
34 .takes_value(false))
35 .arg(Arg::with_name("dep_licenses")
36 .long("dep-licenses")
37 .help("Displays the licenses of the dependencies on which this software relies.")
38 .takes_value(false))
39 .arg(Arg::with_name("jpeg_encoding_quality")
40 .long("jpeg-encoding-quality")
41 .help("Set the jpeg quality to QUALITY. Valid values are natural numbers from 1 up to and including 100. Will only be used when the output format is determined to be jpeg.")
42 .value_name("QUALITY")
43 .takes_value(true))
44 .arg(Arg::with_name("pnm_encoding_ascii")
45 .long("pnm-encoding-ascii")
46 .help("Use ascii based encoding when using a PNM image output format (pbm, pgm or ppm). Doesn't apply to 'pam' (PNM Arbitrary Map)."))
47 .arg(Arg::with_name("disable_automatic_color_type_adjustment")
48 .long("disable-automatic-color-type-adjustment")
49 .help("Some image output formats do not support the color type of the image buffer prior to encoding. By default Stew tries to adjust the color type. If this flag is provided, sic will not try to adjust the color type."))
50 .arg(Arg::with_name("input")
51 .long("input")
52 .short("i")
53 .value_name("FILE_INPUT")
54 .takes_value(true)
55 .help("Input of qualified (TBD) image file. Use this file option XOR pipe from stdin."))
56 .arg(Arg::with_name("output")
57 .long("output")
58 .short("o")
59 .value_name("FILE_OUTPUT")
60 .takes_value(true)
61 .help("Output of qualified (TBD) image file. Use this file option XOR pipe to stdout."))
62}
63
64pub fn get_default_config(matches: &ArgMatches) -> Result<Config, String> {
67 let res = Config {
68 licenses: match (
69 matches.is_present("license"),
70 matches.is_present("dep_licenses"),
71 ) {
72 (true, true) => vec![
73 SelectedLicenses::ThisSoftware,
74 SelectedLicenses::Dependencies,
75 ],
76 (true, _) => vec![SelectedLicenses::ThisSoftware],
77 (_, true) => vec![SelectedLicenses::Dependencies],
78 _ => vec![],
79 },
80
81 forced_output_format: matches.value_of("forced_output_format").map(String::from),
82
83 disable_automatic_color_type_adjustment: matches
84 .is_present("disable_automatic_color_type_adjustment"),
85
86 encoding_settings: FormatEncodingSettings {
87 jpeg_settings: JPEGEncodingSettings::new_result((
92 matches.is_present("jpeg_encoding_quality"),
93 matches.value_of("jpeg_encoding_quality"),
94 ))?,
95 pnm_settings: PNMEncodingSettings::new(matches.is_present("pnm_encoding_ascii")),
96 },
97
98 output: matches.value_of("output").map(|v| v.into()),
99 };
100
101 Ok(res)
102}
103
104pub fn run(matches: &ArgMatches, operation: Option<Operation>) -> Result<(), String> {
108 let options = get_default_config(&matches)?;
109
110 if options.output.is_none() {
111 eprintln!(
112 "The default output format is BMP. Use --output-format <FORMAT> to specify \
113 a different output format."
114 );
115 }
116
117 let license_display_processor = LicenseDisplayProcessor::new();
118 license_display_processor.process(&options);
119
120 let mut img = import(matches.value_of("input"))?;
121
122 let mut image_operations_processor = ImageOperationsProcessor::new(&mut img, operation);
123 image_operations_processor.process_mut(&options)?;
124
125 let format_decider = EncodingFormatDecider::new();
126 export(&img, &format_decider, &options)
127}
128
129pub fn run_display_licenses(matches: &ArgMatches) -> Result<(), String> {
130 let options = get_default_config(&matches)?;
131
132 let license_display_processor = LicenseDisplayProcessor::new();
133 let res = license_display_processor.process(&options);
134 Ok(res)
135}