PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, July 28, 2022

[FIXED] How do I avoid using clone here?

 July 28, 2022     image, rust     No comments   

Issue

use rayon::prelude::*;
use image::RgbImage;


#[inline]
fn lerp(pct: f32, a: f32, b: f32) -> f32 {
    pct.mul_add(b - a, a)
}
#[inline]
fn distance(x: i32, y: i32) -> f32 {
    ((x * x + y * y) as f32).sqrt()
}

struct ColorCalculator {
    from: [f32; 3],
    to: [f32; 3],
    center_x: i32,
    center_y: i32,
    max_dist: f32,
}

impl ColorCalculator {
    fn new(from: [u8; 3], to: [u8; 3], width: u32, height: u32) -> Self {
        let center_x = width as i32 / 2;
        let center_y = height as i32 / 2;
        Self {
            from: from.map(|channel| channel as f32),
            to: to.map(|channel| channel as f32),
            center_x,
            center_y,
            max_dist: distance(center_x, center_y),
        }
    }
    fn calculate(&self, x: u32, y: u32) -> [u8; 3] {
        let x_dist = self.center_x - x as i32;
        let y_dist = self.center_y - y as i32;

        let t = distance(x_dist, y_dist) / self.max_dist;
    }
}

pub fn radial_gradient_mirror(
    geometry: [u32; 2],
    inner_color: [u8; 3],
    outer_color: [u8; 3],
) -> RgbImage {
    let [width, height] = geometry;

    let color_calculator = ColorCalculator::new(inner_color, outer_color, geometry[0], geometry[1]);

    let mut buf: Vec<_> = (0..(height / 2))
        .into_par_iter()
        .flat_map(|y| {
            let mut row: Vec<[u8; 3]> = Vec::with_capacity(width as usize);
            for x in 0..(width / 2) {
                row.push(color_calculator.calculate(x, y))
            }
            row.extend(row.clone().iter().rev());
            row
        })
        .collect();

    buf.extend(buf.clone().iter().rev());
    let buf = buf.into_iter().flatten().collect();

    RgbImage::from_raw(width, height, buf).unwrap()
}

I have an algorithm to generate a radial gradient. The original version would calculate the color of each pixel but because there is a horizontal and vertical line of symmetry I can calculate the colors for the top left corner and use some vector manipulation to mirror. I managed to do this by cloning and reversing the iterator buf.clone().iter().rev() although this is slow. How can I avoid this and are there any other optimizations I could use?


Solution

You do not really need to populate the buffer as later you override it, you can use direct chained iterators for doing so (copied is used to to have owned values), original buff will be droped at the end of the scope:

let i1 = buf.iter().copied();
let i2 = buf.iter().copied().rev();
let buf = i1.chain(i2).flatten().collect();

Full method:

pub fn radial_gradient_mirror(
    geometry: [u32; 2],
    inner_color: [u8; 3],
    outer_color: [u8; 3],
) -> RgbImage {
    let [width, height] = geometry;

    let color_calculator = ColorCalculator::new(inner_color, outer_color, geometry[0], geometry[1]);

    let mut buf: Vec<_> = (0..(height / 2))
        .into_par_iter()
        .flat_map(|y| {
            let mut row: Vec<[u8; 3]> = Vec::with_capacity(width as usize);
            for x in 0..(width / 2) {
                row.push(color_calculator.calculate(x, y))
            }
            row.extend(row.clone().iter().rev());
            row
        })
        .collect();

    let i1 = buf.iter().copied();
    let i2 = buf.iter().copied().rev();
    let buf = i1.chain(i2).flatten().collect();

    RgbImage::from_raw(width, height, buf).unwrap()
}

Playground



Answered By - Netwave
Answer Checked By - Robin (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

1,254,409

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © 2025 PHPFixing