Commit e68b083dc6e767ed24ba2ec345b9d0351f4a5904

Cléo Rebert 2024-01-19T16:44:27

Optimize drawing loop Signed-off-by: Cléo Rebert <cleo.rebert@gmail.com>

diff --git a/qrcodegen-image/CHANGELOG.md b/qrcodegen-image/CHANGELOG.md
index 076afc9..f4b2009 100644
--- a/qrcodegen-image/CHANGELOG.md
+++ b/qrcodegen-image/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## [1.3.0](https://github.com/constantoine/totp-rs/releases/tag/qrcodegen-image%2Fv1.3.0) (19/01/2024)
+
+### What's new
+
+- `draw_canvas` is now 70%(!) faster on my machine after optimizing the "drawing_square" loop.
+
 ## [1.2.0](https://github.com/constantoine/totp-rs/releases/tag/qrcodegen-image%2Fv1.2.0) (14/09/2023)
 
 ### What's new
diff --git a/qrcodegen-image/Cargo.toml b/qrcodegen-image/Cargo.toml
index a7f1f5b..9968cc4 100644
--- a/qrcodegen-image/Cargo.toml
+++ b/qrcodegen-image/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "qrcodegen-image"
-version = "1.2.0"
+version = "1.3.0"
 edition = "2021"
 authors = ["Cleo Rebert <cleo.rebert@gmail.com>"]
 rust-version = "1.61"
diff --git a/qrcodegen-image/src/lib.rs b/qrcodegen-image/src/lib.rs
index 9e9d3a1..8208216 100644
--- a/qrcodegen-image/src/lib.rs
+++ b/qrcodegen-image/src/lib.rs
@@ -18,6 +18,8 @@ pub fn draw_canvas(qr: qrcodegen::QrCode) -> image::ImageBuffer<Luma<u8>, Vec<u8
         *pixel = Luma([255]);
     }
 
+    let raw = canvas.as_mut();
+
     // The QR inside the white border
     for x_qr in 0..size {
         for y_qr in 0..size {
@@ -32,10 +34,9 @@ pub fn draw_canvas(qr: qrcodegen::QrCode) -> image::ImageBuffer<Luma<u8>, Vec<u8
             let y_start = y_qr * 8 + 8 * 4;
 
             // Draw a 8-pixels-wide square
-            for x_img in x_start..x_start + 8 {
-                for y_img in y_start..y_start + 8 {
-                    canvas.put_pixel(x_img, y_img, Luma([val]));
-                }
+            for y_img in y_start..y_start + 8 {
+                let start = (x_start + y_img * image_size) as usize;
+                raw[start..start + 8].copy_from_slice(&[val; 8]);
             }
         }
     }
@@ -99,5 +100,5 @@ pub fn draw_png(text: &str) -> Result<Vec<u8>, String> {
 #[cfg(feature = "base64")]
 pub fn draw_base64(text: &str) -> Result<String, String> {
     use base64::{engine::general_purpose, Engine as _};
-    Ok(draw_png(text).map(|vec| general_purpose::STANDARD.encode(vec))?)
+    draw_png(text).map(|vec| general_purpose::STANDARD.encode(vec))
 }