Wire resize algorithm selection, overwrite behavior, and fix rotation/flip scope
This commit is contained in:
@@ -8,7 +8,7 @@ use crate::encoder::{EncoderOptions, OutputEncoder};
|
||||
use crate::error::{PixstripError, Result};
|
||||
use crate::loader::ImageLoader;
|
||||
use crate::operations::adjustments::apply_adjustments;
|
||||
use crate::operations::resize::resize_image;
|
||||
use crate::operations::resize::resize_image_with_algorithm;
|
||||
use crate::operations::watermark::apply_watermark;
|
||||
use crate::operations::{Flip, Rotation};
|
||||
use crate::pipeline::ProcessingJob;
|
||||
@@ -344,7 +344,7 @@ impl PipelineExecutor {
|
||||
|
||||
// Resize
|
||||
if let Some(ref config) = job.resize {
|
||||
img = resize_image(&img, config)?;
|
||||
img = resize_image_with_algorithm(&img, config, job.resize_algorithm)?;
|
||||
}
|
||||
|
||||
// Adjustments (brightness, contrast, saturation, effects, crop, padding)
|
||||
@@ -413,6 +413,25 @@ impl PipelineExecutor {
|
||||
job.output_path_for(source, Some(output_format))
|
||||
};
|
||||
|
||||
// Handle overwrite behavior
|
||||
let output_path = match job.overwrite_behavior {
|
||||
crate::operations::OverwriteBehavior::Skip => {
|
||||
if output_path.exists() {
|
||||
// Return 0 bytes written - file was skipped
|
||||
return Ok((input_size, 0));
|
||||
}
|
||||
output_path
|
||||
}
|
||||
crate::operations::OverwriteBehavior::AutoRename => {
|
||||
if output_path.exists() {
|
||||
find_unique_path(&output_path)
|
||||
} else {
|
||||
output_path
|
||||
}
|
||||
}
|
||||
crate::operations::OverwriteBehavior::Overwrite => output_path,
|
||||
};
|
||||
|
||||
// Ensure output directory exists
|
||||
if let Some(parent) = output_path.parent() {
|
||||
std::fs::create_dir_all(parent).map_err(PixstripError::Io)?;
|
||||
@@ -451,6 +470,30 @@ fn num_cpus() -> usize {
|
||||
.unwrap_or(1)
|
||||
}
|
||||
|
||||
fn find_unique_path(path: &std::path::Path) -> std::path::PathBuf {
|
||||
let stem = path
|
||||
.file_stem()
|
||||
.and_then(|s| s.to_str())
|
||||
.unwrap_or("output");
|
||||
let ext = path
|
||||
.extension()
|
||||
.and_then(|e| e.to_str())
|
||||
.unwrap_or("bin");
|
||||
let parent = path.parent().unwrap_or_else(|| std::path::Path::new("."));
|
||||
|
||||
for i in 1u32..10000 {
|
||||
let candidate = parent.join(format!("{}_{}.{}", stem, i, ext));
|
||||
if !candidate.exists() {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
// Extremely unlikely fallback
|
||||
parent.join(format!("{}_{}.{}", stem, std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.map(|d| d.as_millis())
|
||||
.unwrap_or(0), ext))
|
||||
}
|
||||
|
||||
fn copy_metadata_from_source(source: &std::path::Path, output: &std::path::Path) {
|
||||
// Best-effort: try to copy EXIF from source to output using little_exif.
|
||||
// If it fails (e.g. non-JPEG, no EXIF), silently continue.
|
||||
|
||||
Reference in New Issue
Block a user