Source: ruby-rmagick
Version: 2.13.2-4
Severity: wishlist
Tags: patch
User: reproducible-builds@lists.alioth.debian.org
Usertags: randomness timestamps
X-Debbugs-Cc: reproducible-builds@lists.alioth.debian.org

Hi,

While working on the "reproducible builds" effort [1], we have noticed
that ruby-rmagick could not be built reproducibly.

This is due to:

 - Inherent randomness in some of the documentation images. For example,
   using fractals and/or random noise.

 - Examples using timestamps as image captions.

In order to fix the former, I needed to expose ImageMagick's
SeedPseudoRandomGenerator method via the RMagick interface itself and
then ensure it is called in the right documentation fragments. To fix
the later, I simply hardcoded the image captions.

Patch attached. Once applied, ruby-rmagick can be built reproducibly
in our reproducible toolchain.

 [1]: https://wiki.debian.org/ReproducibleBuilds


Regards,

-- 
      ,''`.
     : :'  :     Chris Lamb
     `. `'`      la...@debian.org / chris-lamb.co.uk
       `-
diff --git a/doc/ex/add_noise.rb b/doc/ex/add_noise.rb
index 4756efe..1fff60d 100644
--- a/doc/ex/add_noise.rb
+++ b/doc/ex/add_noise.rb
@@ -1,5 +1,6 @@
 #! /usr/local/bin/ruby -w
 require 'RMagick'
+Magick::seed_pseudo_random_generator 0
 
 # Demonstrate the Image#add_noise method
 NOISE_TYPES = [Magick::UniformNoise, Magick::GaussianNoise,
diff --git a/doc/ex/enhance.rb b/doc/ex/enhance.rb
index fd76795..e9daac3 100644
--- a/doc/ex/enhance.rb
+++ b/doc/ex/enhance.rb
@@ -1,5 +1,6 @@
 #!/usr/local/bin/ruby -w
 require 'RMagick'
+Magick::seed_pseudo_random_generator 0
 
 # Demonstrate the Image#enhance method
 
diff --git a/doc/ex/matte_fill_to_border.rb b/doc/ex/matte_fill_to_border.rb
index 3ae1a15..05a2412 100644
--- a/doc/ex/matte_fill_to_border.rb
+++ b/doc/ex/matte_fill_to_border.rb
@@ -1,6 +1,7 @@
 #! /usr/local/bin/ruby -w
 
 require 'RMagick'
+Magick::seed_pseudo_random_generator 0
 
 img = Magick::Image.new(200,200)
 img.compression = Magick::LZWCompression
diff --git a/doc/ex/matte_floodfill.rb b/doc/ex/matte_floodfill.rb
index e528d11..b101024 100644
--- a/doc/ex/matte_floodfill.rb
+++ b/doc/ex/matte_floodfill.rb
@@ -1,6 +1,7 @@
 #! /usr/local/bin/ruby -w
 
 require 'RMagick'
+Magick::seed_pseudo_random_generator 0
 
 img = Magick::Image.new(200,200)
 img.compression = Magick::LZWCompression
diff --git a/doc/ex/matte_replace.rb b/doc/ex/matte_replace.rb
index fa047cd..655bd0f 100644
--- a/doc/ex/matte_replace.rb
+++ b/doc/ex/matte_replace.rb
@@ -1,6 +1,7 @@
 #! /usr/local/bin/ruby -w
 
 require 'RMagick'
+Magick::seed_pseudo_random_generator 0
 
 img = Magick::Image.new(200,200)
 img.compression = Magick::LZWCompression
diff --git a/doc/ex/median_filter.rb b/doc/ex/median_filter.rb
index 70dc899..7202b4e 100644
--- a/doc/ex/median_filter.rb
+++ b/doc/ex/median_filter.rb
@@ -1,5 +1,6 @@
 #! /usr/local/bin/ruby -w
 require 'RMagick'
+Magick::seed_pseudo_random_generator 0
 
 # Demonstrate the Image#median_filter method
 
diff --git a/doc/ex/polaroid.rb b/doc/ex/polaroid.rb
index 026af47..23f3ebc 100644
--- a/doc/ex/polaroid.rb
+++ b/doc/ex/polaroid.rb
@@ -5,7 +5,7 @@ require 'date'
 # Demonstrate the Image#polaroid method
 
 img = Magick::Image.read('images/Flower_Hat.jpg').first
-img[:Caption] = "\nLosha\n" + Date.today.to_s
+img[:Caption] = "\nLosha\nPlus hat"
 
 begin
     picture = img.polaroid do
diff --git a/doc/ex/reduce_noise.rb b/doc/ex/reduce_noise.rb
index 05615e4..b139c2d 100644
--- a/doc/ex/reduce_noise.rb
+++ b/doc/ex/reduce_noise.rb
@@ -1,5 +1,6 @@
 #! /usr/local/bin/ruby -w
 require 'RMagick'
+Magick::seed_pseudo_random_generator 0
 
 # Demonstrate the Image#reduce_noise method
 
diff --git a/doc/ex/sketch.rb b/doc/ex/sketch.rb
index f4e7eda..f263c86 100644
--- a/doc/ex/sketch.rb
+++ b/doc/ex/sketch.rb
@@ -1,6 +1,7 @@
 #! /usr/local/bin/ruby -w
 
 require 'RMagick'
+Magick::seed_pseudo_random_generator 0
 
 img = Magick::Image.read('images/Flower_Hat.jpg').first
 
diff --git a/doc/ex/spread.rb b/doc/ex/spread.rb
index 7bf9d96..fd4d86d 100644
--- a/doc/ex/spread.rb
+++ b/doc/ex/spread.rb
@@ -1,5 +1,6 @@
 #! /usr/local/bin/ruby -w
 require 'RMagick'
+Magick::seed_pseudo_random_generator 0
 
 # Demonstrate the Image#spread method
 
diff --git a/doc/ex/transparent.rb b/doc/ex/transparent.rb
index 3280021..8fdc887 100644
--- a/doc/ex/transparent.rb
+++ b/doc/ex/transparent.rb
@@ -1,5 +1,6 @@
 #! /usr/local/bin/ruby -w
 require 'RMagick'
+Magick::seed_pseudo_random_generator 0
 
 # Demonstrate the Image#transparent method.
 # Change all black pixels in the image to transparent.
diff --git a/ext/RMagick/rmagick.c b/ext/RMagick/rmagick.c
index 661f95f..5c81108 100644
--- a/ext/RMagick/rmagick.c
+++ b/ext/RMagick/rmagick.c
@@ -392,3 +392,24 @@ Magick_set_log_format(VALUE class, VALUE format)
     return class;
 }
 
+
+/**
+ * Sets the pseudo-random number generator secret key
+ *
+ * Ruby usage:
+ *   - @verbatim Magick.seed_pseudo_random_generator(seed) @endverbatim
+ *
+ * Notes:
+ *   - singleton method
+ *
+ * @param class the class on which the method is run.
+ * @param seed the secret key
+ * @return the class.
+ */
+VALUE
+Magick_seed_pseudo_random_generator(VALUE class, VALUE seed)
+{
+    unsigned long s = NUM2ULONG(seed);
+    (void) SeedPseudoRandomGenerator(s);
+    return class;
+}
diff --git a/ext/RMagick/rmagick.h b/ext/RMagick/rmagick.h
index 8aa6f3f..30c4f38 100644
--- a/ext/RMagick/rmagick.h
+++ b/ext/RMagick/rmagick.h
@@ -676,6 +676,7 @@ extern VALUE Magick_limit_resource(int, VALUE *, VALUE);
 extern VALUE Magick_set_cache_threshold(VALUE, VALUE);
 extern VALUE Magick_set_log_event_mask(int, VALUE *, VALUE);
 extern VALUE Magick_set_log_format(VALUE, VALUE);
+extern VALUE Magick_seed_pseudo_random_generator(VALUE, VALUE);
 
 // rmdraw.c
 ATTR_WRITER(Draw, affine)
diff --git a/ext/RMagick/rmmain.c b/ext/RMagick/rmmain.c
index e5ebc92..6fc465c 100644
--- a/ext/RMagick/rmmain.c
+++ b/ext/RMagick/rmmain.c
@@ -184,6 +184,7 @@ Init_RMagick2(void)
     rb_define_module_function(Module_Magick, "set_cache_threshold", 
Magick_set_cache_threshold, 1);
     rb_define_module_function(Module_Magick, "set_log_event_mask", 
Magick_set_log_event_mask, -1);
     rb_define_module_function(Module_Magick, "set_log_format", 
Magick_set_log_format, 1);
+    rb_define_module_function(Module_Magick, "seed_pseudo_random_generator", 
Magick_seed_pseudo_random_generator, 1);
 
     /*-----------------------------------------------------------------------*/
     /* Class Magick::Image methods                                           */
_______________________________________________
Reproducible-builds mailing list
Reproducible-builds@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/reproducible-builds

Reply via email to