pconvert_rust/pymodule/
utils.rs1use crate::blending::params::{BlendAlgorithmParams, Options, Value};
4use crate::blending::BlendAlgorithm;
5use crate::errors::PConvertError;
6use crate::utils::{image_compression_from, image_filter_from};
7use image::codecs::png::{CompressionType, FilterType};
8use pyo3::prelude::*;
9use pyo3::types::{PySequence, PyString};
10use std::str::FromStr;
11
12pub fn build_algorithm(algorithm: &str) -> Result<BlendAlgorithm, PyErr> {
15 match BlendAlgorithm::from_str(algorithm) {
16 Ok(algorithm) => Ok(algorithm),
17 Err(algorithm) => Err(PyErr::from(PConvertError::ArgumentError(format!(
18 "ArgumentError: invalid algorithm '{}'",
19 algorithm
20 )))),
21 }
22}
23
24pub fn build_params(
27 algorithms: &PySequence,
28) -> Result<Vec<(BlendAlgorithm, Option<BlendAlgorithmParams>)>, PyErr> {
29 let mut result = Vec::new();
30
31 for i in 0..algorithms.len()? {
34 let element = algorithms.get_item(i)?;
35
36 if let Ok(string) = element.cast_as::<PyString>() {
37 let algorithm = build_algorithm(&string.to_string())?;
38 result.push((algorithm, None));
39 } else if let Ok(sequence) = element.cast_as::<PySequence>() {
40 let algorithm = sequence.get_item(0)?.extract::<String>()?;
41 let algorithm = build_algorithm(&algorithm)?;
42
43 let mut blending_params = BlendAlgorithmParams::new();
44 let params_sequence = sequence.get_item(1)?;
45 if let Ok(params_sequence) = params_sequence.cast_as::<PySequence>() {
46 for j in 0..params_sequence.len()? {
47 if let Ok(property_value) = params_sequence.get_item(j)?.cast_as::<PySequence>()
48 {
49 let param_name = property_value.get_item(0)?.extract::<String>()?;
50 let param_value = property_value.get_item(1)?;
51 let param_value = param_value.extract::<Value>()?;
52 blending_params.insert(param_name, param_value);
53 }
54 }
55 } else {
56 return Err(PyErr::from(PConvertError::ArgumentError(
57 "Parameters should be given as a python sequence object".to_string(),
58 )));
59 }
60
61 result.push((algorithm, Some(blending_params)));
62 }
63 }
64
65 Ok(result)
66}
67
68pub fn get_compression_type(options: &Option<Options>) -> CompressionType {
71 options.clone().map_or(CompressionType::Fast, |options| {
72 options
73 .get("compression")
74 .map_or(CompressionType::Fast, |compression| match compression {
75 Value::Str(compression) => image_compression_from(compression.to_string()),
76 _ => CompressionType::Fast,
77 })
78 })
79}
80
81pub fn get_filter_type(options: &Option<Options>) -> FilterType {
84 options.clone().map_or(FilterType::NoFilter, |options| {
85 options
86 .get("filter")
87 .map_or(FilterType::NoFilter, |filter| match filter {
88 Value::Str(filter) => image_filter_from(filter.to_string()),
89 _ => FilterType::NoFilter,
90 })
91 })
92}
93
94pub fn get_num_threads(options: &Option<Options>) -> usize {
97 options.clone().map_or(0, |options| {
98 options
99 .get("num_threads")
100 .map_or(0, |num_threads| match num_threads {
101 Value::UInt(num_threads) => *num_threads,
102 _ => 0,
103 })
104 })
105}