forked from kornelski/pngquant
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbin.rs
141 lines (121 loc) · 4.23 KB
/
bin.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
** © 2017 by Kornel Lesiński.
**
** See COPYRIGHT file for license.
*/
#![allow(unused_extern_crates)]
#![cfg_attr(feature="alloc_system", feature(alloc_system))]
#[cfg(feature="alloc_system")]
extern crate alloc_system;
#[cfg(feature = "openmp")]
extern crate openmp_sys;
extern crate imagequant_sys;
#[cfg(feature = "cocoa")]
extern crate cocoa_image;
extern crate libpng_sys;
extern crate libc;
extern crate getopts;
extern crate wild;
#[cfg(feature = "cocoa")]
pub mod rwpng_cocoa;
#[cfg(feature = "lcms2")]
extern crate lcms2_sys;
use std::os::raw::{c_uint, c_char};
use std::process;
use std::ptr;
use std::ffi::CString;
mod ffi;
use ffi::*;
fn unwrap_ptr(opt: Option<&CString>) -> *const c_char {
opt.map(|c| c.as_ptr()).unwrap_or(ptr::null())
}
fn main() {
let mut opts = getopts::Options::new();
opts.optflag("v", "verbose", "");
opts.optflag("h", "help", "");
opts.optflag("q", "quiet", "");
opts.optflag("f", "force", "");
opts.optflag("", "no-force", "");
opts.optflag("", "ordered", "");
opts.optflag("", "nofs", "");
opts.optflag("", "iebug", "");
opts.optflag("", "transbug", "");
opts.optflag("", "skip-if-larger", "");
opts.optflag("", "strip", "");
opts.optflag("V", "version", "");
opts.optflagopt("", "floyd", "0.0-1.0", "");
opts.optopt("", "ext", "extension", "");
opts.optopt("o", "output", "file", "");
opts.optopt("s", "speed", "3", "");
opts.optopt("Q", "quality", "0-100", "");
opts.optopt("", "posterize", "0", "");
opts.optopt("", "map", "png", "");
let args: Vec<_> = wild::args().skip(1).collect();
let has_some_explicit_args = !args.is_empty();
let mut m = match opts.parse(args) {
Ok(m) => m,
Err(err) => {
eprintln!("{}", err);
process::exit(2);
},
};
let posterize = m.opt_str("posterize").and_then(|p| p.parse().ok()).unwrap_or(0);
let speed = m.opt_str("speed").and_then(|p| p.parse().ok()).unwrap_or(0);
let floyd = m.opt_str("floyd").and_then(|p| p.parse().ok()).unwrap_or(1.);
let quality = m.opt_str("quality").and_then(|s| CString::new(s).ok());
let extension = m.opt_str("ext").and_then(|s| CString::new(s).ok());
let map_file = m.opt_str("map").and_then(|s| CString::new(s).ok());
let colors = if let Some(c) = m.free.get(0).and_then(|s| s.parse().ok()) {
m.free.remove(0);
if m.free.len() == 0 {
m.free.push("-".to_owned()); // stdin default
}
c
} else {0};
let using_stdin = m.free.len() == 1 && Some("-") == m.free.get(0).map(|s| s.as_str());
let mut using_stdout = using_stdin;
let output_file_path = m.opt_str("o").and_then(|s| {
if s == "-" {
using_stdout = true;
None
} else {
using_stdout = false;
CString::new(s).ok()
}
});
let files: Vec<_> = m.free.drain(..).filter_map(|s| CString::new(s).ok()).collect();
let file_ptrs: Vec<_> = files.iter().map(|s| s.as_ptr()).collect();
let mut options = pngquant_options {
quality: unwrap_ptr(quality.as_ref()),
extension: unwrap_ptr(extension.as_ref()),
output_file_path: unwrap_ptr(output_file_path.as_ref()),
map_file: unwrap_ptr(map_file.as_ref()),
files: file_ptrs.as_ptr(),
num_files: file_ptrs.len() as c_uint,
using_stdin,
using_stdout,
missing_arguments: !has_some_explicit_args,
colors,
speed,
posterize,
floyd,
force: m.opt_present("force") && !m.opt_present("no-force"),
skip_if_larger: m.opt_present("skip-if-larger"),
strip: m.opt_present("strip"),
iebug: m.opt_present("iebug"),
last_index_transparent: m.opt_present("transbug"),
print_help: m.opt_present("h"),
print_version: m.opt_present("V"),
verbose: m.opt_present("v"),
liq: ptr::null_mut(),
fixed_palette_image: ptr::null_mut(),
log_callback: None,
log_callback_user_info: ptr::null_mut(),
fast_compression: false,
min_quality_limit: false,
};
if m.opt_present("nofs") || m.opt_present("ordered") {
options.floyd = 0.;
}
process::exit(unsafe {pngquant_main(&mut options)});
}