Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions crates/resvg/src/filter/composite.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
// Copyright 2020 the Resvg Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT

use super::{ImageRef, ImageRefMut, f32_bound};
use super::{Error, ImageRef, ImageRefMut, f32_bound};
use rgb::RGBA8;
use usvg::ApproxZeroUlps;

/// Performs an arithmetic composition.
///
/// - `src1` and `src2` image pixels should have a **premultiplied alpha**.
/// - `dest` image pixels will have a **premultiplied alpha**.
///
/// # Panics
///
/// When `src1`, `src2` and `dest` have different sizes.
pub fn arithmetic(
k1: f32,
k2: f32,
Expand All @@ -21,9 +17,13 @@ pub fn arithmetic(
src1: ImageRef,
src2: ImageRef,
dest: ImageRefMut,
) {
assert!(src1.width == src2.width && src1.width == dest.width);
assert!(src1.height == src2.height && src1.height == dest.height);
) -> Result<(), Error> {
if src1.width != src2.width || src1.width != dest.width {
return Err(Error::InvalidRegion);
}
if src1.height != src2.height || src1.height != dest.height {
return Err(Error::InvalidRegion);
}

let calc = |i1, i2, max| {
let i1 = i1 as f32 / 255.0;
Expand All @@ -49,4 +49,5 @@ pub fn arithmetic(

i += 1;
}
Ok(())
}
15 changes: 10 additions & 5 deletions crates/resvg/src/filter/convolve_matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use usvg::filter::{ConvolveMatrix, EdgeMode};
/// # Allocations
///
/// This method will allocate a copy of the `src` image as a back buffer.
pub fn apply(matrix: &ConvolveMatrix, src: ImageRefMut) {
pub fn apply(matrix: &ConvolveMatrix, src: ImageRefMut) -> Result<(), super::Error> {
fn bound(min: i32, val: i32, max: i32) -> i32 {
core::cmp::max(min, core::cmp::min(max, val))
}
Expand Down Expand Up @@ -57,10 +57,13 @@ pub fn apply(matrix: &ConvolveMatrix, src: ImageRefMut) {
}
}

let k = matrix.matrix().get(
matrix.matrix().columns() - ox - 1,
matrix.matrix().rows() - oy - 1,
);
let k = matrix
.matrix()
.get(
matrix.matrix().columns() - ox - 1,
matrix.matrix().rows() - oy - 1,
)
.ok_or(super::Error::InvalidRegion)?;

let p = src.pixel_at(tx as u32, ty as u32);
new_r += (p.r as f32) / 255.0 * k;
Expand Down Expand Up @@ -108,4 +111,6 @@ pub fn apply(matrix: &ConvolveMatrix, src: ImageRefMut) {

// Do not use `mem::swap` because `data` referenced via FFI.
src.data.copy_from_slice(buf.data);

Ok(())
}
15 changes: 8 additions & 7 deletions crates/resvg/src/filter/displacement_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ use usvg::filter::{ColorChannel, DisplacementMap};
/// - `src` pixels can have any alpha method.
///
/// `sx` and `sy` indicate canvas scale.
///
/// # Panics
///
/// When `src`, `map` and `dest` have different sizes.
pub fn apply(
fe: &DisplacementMap,
sx: f32,
sy: f32,
src: ImageRef,
map: ImageRef,
dest: ImageRefMut,
) {
assert!(src.width == map.width && src.width == dest.width);
assert!(src.height == map.height && src.height == dest.height);
) -> Result<(), super::Error> {
if src.width != map.width || src.width != dest.width {
return Err(super::Error::InvalidRegion);
}
if src.height != map.height || src.height != dest.height {
return Err(super::Error::InvalidRegion);
}

let w = src.width as i32;
let h = src.height as i32;
Expand Down Expand Up @@ -61,4 +61,5 @@ pub fn apply(
y += 1;
}
}
Ok(())
}
22 changes: 10 additions & 12 deletions crates/resvg/src/filter/lighting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,15 @@ impl Normal {
/// - `dest` will have an **unpremultiplied alpha**.
///
/// Does nothing when `src` is less than 3x3.
///
/// # Panics
///
/// - When `src` and `dest` have different sizes.
pub fn diffuse_lighting(
fe: &DiffuseLighting,
light_source: LightSource,
src: ImageRef,
dest: ImageRefMut,
) {
assert!(src.width == dest.width && src.height == dest.height);
) -> Result<(), crate::filter::Error> {
if src.width != dest.width || src.height != dest.height {
return Err(crate::filter::Error::InvalidRegion);
}

let light_factor = |normal: Normal, light_vector: Vector3| {
let k = if normal.normal.approx_zero() {
Expand All @@ -164,6 +162,7 @@ pub fn diffuse_lighting(
src,
dest,
);
Ok(())
}

/// Renders a specular lighting.
Expand All @@ -172,17 +171,15 @@ pub fn diffuse_lighting(
/// - `dest` will have a **premultiplied alpha**.
///
/// Does nothing when `src` is less than 3x3.
///
/// # Panics
///
/// - When `src` and `dest` have different sizes.
pub fn specular_lighting(
fe: &SpecularLighting,
light_source: LightSource,
src: ImageRef,
dest: ImageRefMut,
) {
assert!(src.width == dest.width && src.height == dest.height);
) -> Result<(), crate::filter::Error> {
if src.width != dest.width || src.height != dest.height {
return Err(crate::filter::Error::InvalidRegion);
}

let light_factor = |normal: Normal, light_vector: Vector3| {
let h = light_vector + Vector3::new(0.0, 0.0, 1.0);
Expand Down Expand Up @@ -226,6 +223,7 @@ pub fn specular_lighting(
src,
dest,
);
Ok(())
}

fn apply(
Expand Down
19 changes: 10 additions & 9 deletions crates/resvg/src/filter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,9 @@ impl Image {
self,
color_space: usvg::filter::ColorInterpolation,
) -> Result<Self, Error> {
if color_space != self.color_space {
if color_space == self.color_space {
Ok(self)
} else {
let region = self.region;

let mut image = self.take()?;
Expand All @@ -302,8 +304,6 @@ impl Image {
region,
color_space,
})
} else {
Ok(self)
}
}

Expand Down Expand Up @@ -348,7 +348,8 @@ pub fn apply(
match result {
Ok(_) => {}
Err(Error::InvalidRegion) => {
log::warn!("Filter has an invalid region.");
let id = filter.id();
log::warn!("Filter '{id}' has an invalid region.");
}
Err(Error::NoResults) => {}
}
Expand Down Expand Up @@ -747,7 +748,7 @@ fn apply_composite(
pixmap1.as_image_ref(),
pixmap2.as_image_ref(),
pixmap.as_image_ref_mut(),
);
)?;

return Ok(Image::from_image(pixmap, cs));
}
Expand Down Expand Up @@ -920,7 +921,7 @@ fn apply_convolve_matrix(
demultiply_alpha(pixmap.data_mut().as_rgba_mut());
}

convolve_matrix::apply(fe, pixmap.as_image_ref_mut());
convolve_matrix::apply(fe, pixmap.as_image_ref_mut())?;

Ok(Image::from_image(pixmap, cs))
}
Expand Down Expand Up @@ -973,7 +974,7 @@ fn apply_displacement_map(
pixmap1.as_image_ref(),
pixmap2.as_image_ref(),
pixmap.as_image_ref_mut(),
);
)?;

Ok(Image::from_image(pixmap, cs))
}
Expand Down Expand Up @@ -1026,7 +1027,7 @@ fn apply_diffuse_lighting(
light_source,
input.as_ref().as_image_ref(),
pixmap.as_image_ref_mut(),
);
)?;

Ok(Image::from_image(pixmap, cs))
}
Expand All @@ -1047,7 +1048,7 @@ fn apply_specular_lighting(
light_source,
input.as_ref().as_image_ref(),
pixmap.as_image_ref_mut(),
);
)?;

Ok(Image::from_image(pixmap, cs))
}
Expand Down
8 changes: 4 additions & 4 deletions crates/resvg/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ pub fn render(
) {
let target_size = tiny_skia::IntSize::from_wh(pixmap.width(), pixmap.height()).unwrap();
let max_bbox = tiny_skia::IntRect::from_xywh(
-(target_size.width() as i32) * 2,
-(target_size.height() as i32) * 2,
target_size.width() * 5,
target_size.height() * 5,
-((target_size.width() as i32) * 2).max(1024),
-((target_size.height() as i32) * 2).max(1024),
(target_size.width() * 5).max(1024 * 2),
(target_size.height() * 5).max(1024 * 2),
)
.unwrap();

Expand Down
8 changes: 2 additions & 6 deletions crates/usvg/src/tree/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,12 +469,8 @@ impl ConvolveMatrixData {
}

/// Returns a matrix value at the specified position.
///
/// # Panics
///
/// - When position is out of bounds.
pub fn get(&self, x: u32, y: u32) -> f32 {
self.data[(y * self.columns + x) as usize]
pub fn get(&self, x: u32, y: u32) -> Option<f32> {
self.data.get((y * self.columns + x) as usize).cloned()
}
}

Expand Down