diff -Nru ruby-mini-magick-3.6.0+gh/.travis.yml ruby-mini-magick-3.7.0/.travis.yml --- ruby-mini-magick-3.6.0+gh/.travis.yml 2013-05-21 02:40:21.000000000 +0000 +++ ruby-mini-magick-3.7.0/.travis.yml 2013-11-26 01:14:08.000000000 +0000 @@ -5,11 +5,11 @@ - 1.9.3 - 2.0.0 - ruby-head - - rbx-18mode - - rbx-19mode - ree - jruby-18mode - jruby-19mode + - jruby-20mode + - jruby-head matrix: allow_failures: - rvm: ruby-head diff -Nru ruby-mini-magick-3.6.0+gh/CHANGELOG ruby-mini-magick-3.7.0/CHANGELOG --- ruby-mini-magick-3.6.0+gh/CHANGELOG 2013-05-21 02:40:21.000000000 +0000 +++ ruby-mini-magick-3.7.0/CHANGELOG 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -* Dec 28, 2011 - Releasing v3.4 - Better windows support. Fixed problem with combine_options. Fixed up readme. [hcatlin] -* Dec 21, 2011 - Refactored gem structure a little and added a few bug fixes to better support Windows users - No changes to API though [2potatocakes] -* June 2, 2011 - Releasing v3.3 - A lot more bugfixes, plus a few new features (like better mime_type accessing) [hcatlin] -* Jan 11, 2011 - Releasing v3.2 - Bugfix release. Some small changes to the API in very rare circumstances. Mostly having to do with passing multiple arguments to format options. Also, you can now query an image's "colorspace". [hcatlin] -* October 28, 2010 - Releasing v3.0. Some small bugfixes. This is 3.0 because of the big interface changes and they are fairly stable from before. [hcatlin] -* A new interface! [hcatlin] -* Adding in deprecation warnings [hcatlin] -* October 12, 2010 - Added support for loading images from URIs with the MiniMagick::Image.open method [hcatlin] -* August 28, 2010 - Just quote all arguements now. [hcatlin] -* August 24, 2010 - Closing an issue with quoting colors... Issue #11 [hcatlin] -* August 17, 2010 - Added compositing! [hcatlin] -* August 17, 2010 - Moved a lot of the command logic into the CommandBuilder. This way, we don't have to repeat things like checking to see if a MOGRIFY_COMMAND is valid or not. Also added some new tests for some behaviour I noticed that wasn't specifically being tested for. Depricated the "+" method as the API was clunky. Moved to "<<" with slightly different behaviour. Image.new(path) no longer throws an error if the 'path' isn't valid. Allows us to create new images (copies, etc), however Image.open(path) will throw an Invalid error if the file stinks. Please use valid? if you want to find out if an image is recognized. [hcatlin] -* August 17, 2010 - Merged in changes to allow subexec to run on 1.8.7. -* August 16, 2010 - Merged in a bugfix change from kepi that makes 'dashed' commands (like "auto-correct") work well with the method_missing overrides. I made some changes to that patch that included simplifying the tests and also decreasing the size of the test images again. Sorry cute cats.... but your bits aren't needed! -* July 29, 2010 - Made the test images much, much smaller. Now, the size of the gem has gone from 1,080kb to 68kb. Should save a bunch of bandwidth with bundler deploys. [hcatlin] -* July 29, 2010 - Merged in my changes to allow it to work under 1.8. subex is only used in 1.9.2. diff -Nru ruby-mini-magick-3.6.0+gh/README.md ruby-mini-magick-3.7.0/README.md --- ruby-mini-magick-3.6.0+gh/README.md 2013-05-21 02:40:21.000000000 +0000 +++ ruby-mini-magick-3.7.0/README.md 2013-11-26 01:14:08.000000000 +0000 @@ -14,6 +14,11 @@ gem "mini_magick" ``` +## Information + +* [Rdoc](http://rubydoc.info/github/minimagick/minimagick) + + ## Why? I was using RMagick and loving it, but it was eating up huge amounts @@ -27,7 +32,7 @@ ImageMagick's command line program mogrify which takes up some memory as well, but is much smaller compared to RMagick) -MiniMagick gives you access to all the commandline options ImageMagick +MiniMagick gives you access to all the command line options ImageMagick has (Found here http://www.imagemagick.org/script/mogrify.php) @@ -110,20 +115,20 @@ ```ruby first_image = MiniMagick::Image.open "first.jpg" second_image = MiniMagick::Image.open "second.jpg" -first_image.composite(second_image) do |c| +result = first_image.composite(second_image) do |c| c.compose "Over" # OverCompositeOp c.geometry "+20+20" # copy second_image onto first_image from (20, 20) end -first_image.write "output.jpg" +result.write "output.jpg" ``` ## Thinking of switching from RMagick? Unlike [RMagick](http://rmagick.rubyforge.org), MiniMagick is a much thinner wrapper around ImageMagick. -* To piece together MiniMagick commands is to refer to the [Mogrify Documentation](http://www.imagemagick.org/script/mogrify.php). For instance you can use the `-flop` option as `image.flop`. +* To piece together MiniMagick commands refer to the [Mogrify Documentation](http://www.imagemagick.org/script/mogrify.php). For instance you can use the `-flop` option as `image.flop`. * Operations on a MiniMagick image tend to happen in-place as `image.trim`, whereas RMagick has both copying and in-place methods like `image.trim` and `image.trim!`. -* Top open files with MiniMagick you use `MiniMagick::Image.open` as you would `Magick::Image.read`. To open a file and directly edit it, use `MiniMagick::Image.new`. +* To open files with MiniMagick you use `MiniMagick::Image.open` as you would `Magick::Image.read`. To open a file and directly edit it, use `MiniMagick::Image.new`. ## Windows Users diff -Nru ruby-mini-magick-3.6.0+gh/Rakefile ruby-mini-magick-3.7.0/Rakefile --- ruby-mini-magick-3.6.0+gh/Rakefile 2013-05-21 02:40:21.000000000 +0000 +++ ruby-mini-magick-3.7.0/Rakefile 2013-11-26 01:14:08.000000000 +0000 @@ -1,20 +1,18 @@ require 'bundler' Bundler::GemHelper.install_tasks -require 'rake/testtask' - $:.unshift 'lib' desc 'Default: run unit tests.' -task :default => [:print_version, :test] +task :default => [:print_version, :spec] task :print_version do puts `mogrify --version` end -desc 'Test the mini_magick plugin.' -Rake::TestTask.new(:test) do |t| - t.libs << 'test' - t.test_files = Dir.glob("test/**/*_test.rb") - t.verbose = true +require 'rspec/core/rake_task' + +desc "Run specs" +RSpec::Core::RakeTask.new do |t| + t.pattern = "./spec/**/*_spec.rb" end diff -Nru ruby-mini-magick-3.6.0+gh/debian/changelog ruby-mini-magick-3.7.0/debian/changelog --- ruby-mini-magick-3.6.0+gh/debian/changelog 2013-05-25 10:46:54.000000000 +0000 +++ ruby-mini-magick-3.7.0/debian/changelog 2014-01-22 09:39:48.000000000 +0000 @@ -1,3 +1,11 @@ +ruby-mini-magick (3.7.0-1) unstable; urgency=medium + + * New upstream release + * ruby tests are moved from test/ to spec, refreshing patches + * updating Build-Dep to new requirements by upstream tests + + -- Markus Tornow Thu, 19 Dec 2013 02:46:19 +0000 + ruby-mini-magick (3.6.0+gh-1) unstable; urgency=low * New upstream release diff -Nru ruby-mini-magick-3.6.0+gh/debian/control ruby-mini-magick-3.7.0/debian/control --- ruby-mini-magick-3.6.0+gh/debian/control 2013-04-21 08:38:59.000000000 +0000 +++ ruby-mini-magick-3.7.0/debian/control 2014-01-22 09:39:48.000000000 +0000 @@ -3,8 +3,8 @@ Priority: optional Maintainer: Debian Ruby Extras Maintainers Uploaders: Markus Tornow -Build-Depends: debhelper (>= 7.0.50~), gem2deb (>= 0.3.0~), imagemagick (>= 8:6.6.3~) , rake, ruby-test-unit, ruby-subexec -Standards-Version: 3.9.4 +Build-Depends: debhelper (>= 7.0.50~), gem2deb (>= 0.3.0~), imagemagick (>= 8:6.6.3~), rake, ruby-subexec, ruby-mocha, ruby-rspec +Standards-Version: 3.9.5 Vcs-Git: git://anonscm.debian.org/pkg-ruby-extras/ruby-mini-magick.git Vcs-Browser: http://anonscm.debian.org/gitweb?p=pkg-ruby-extras/ruby-mini-magick.git;a=summary Homepage: https://github.com/minimagick/minimagick diff -Nru ruby-mini-magick-3.6.0+gh/debian/patches/remove-remote-tests ruby-mini-magick-3.7.0/debian/patches/remove-remote-tests --- ruby-mini-magick-3.6.0+gh/debian/patches/remove-remote-tests 2013-05-19 09:57:04.000000000 +0000 +++ ruby-mini-magick-3.7.0/debian/patches/remove-remote-tests 2014-01-22 09:39:48.000000000 +0000 @@ -2,27 +2,27 @@ Author: Felix Geyer Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=%23706517+ Forwarded: no -Last-Update: 2013-05-09 +Last-Update: 2013-12-19 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ ---- ruby-mini-magick-3.5.0.orig/test/image_test.rb -+++ ruby-mini-magick-3.5.0/test/image_test.rb -@@ -55,18 +55,6 @@ class ImageTest < Test::Unit::TestCase - image.destroy! - end +--- a/spec/lib/mini_magick/image_spec.rb ++++ b/spec/lib/mini_magick/image_spec.rb +@@ -57,18 +57,6 @@ + end.to_not raise_error + end -- def test_remote_image -- image = Image.open("http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png") -- assert image.valid? -- image.destroy! -- end +- it 'loads remote image' do +- image = MiniMagick::Image.open("http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png") +- image.valid?.should be true +- image.destroy! +- end - -- def test_remote_image_with_complex_url -- image = Image.open("http://a0.twimg.com/a/1296609216/images/fronts/logo_withbird_home.png?extra=foo&plus=bar") -- assert image.valid? -- image.destroy! -- end +- it 'loads remote image with complex url' do +- image = MiniMagick::Image.open("http://a0.twimg.com/a/1296609216/images/fronts/logo_withbird_home.png?extra=foo&plus=bar") +- image.valid?.should be true +- image.destroy! +- end - - def test_reformat_with_capitalized_extension - image = Image.open(CAP_EXT_PATH) - image.format "jpg" + it 'reformats an image with a given extension' do + expect do + image = MiniMagick::Image.open(CAP_EXT_PATH) diff -Nru ruby-mini-magick-3.6.0+gh/debian/patches/remove-rubygems ruby-mini-magick-3.7.0/debian/patches/remove-rubygems --- ruby-mini-magick-3.6.0+gh/debian/patches/remove-rubygems 2013-05-25 10:46:54.000000000 +0000 +++ ruby-mini-magick-3.7.0/debian/patches/remove-rubygems 2014-01-22 09:39:48.000000000 +0000 @@ -1,20 +1,14 @@ Description: remove require rubygems from test_helper.rb Author: Markus Tornow Forwarded: not-needed -Last-Update: 2013-05-24 +Last-Update: 2013-12-19 --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ ---- a/test/test_helper.rb -+++ b/test/test_helper.rb -@@ -1,4 +1,3 @@ +--- a/spec/spec_helper.rb ++++ b/spec/spec_helper.rb +@@ -1,5 +1,3 @@ -require 'rubygems' - require 'test/unit' - require 'pathname' - require 'tempfile' -@@ -19,4 +18,4 @@ module MiniMagickTestFiles - PNG_PATH = test_files + "/png.png" - COMP_IMAGE_PATH = test_files + "/composited.jpg" - ERRONEOUS_IMAGE_PATH = test_files + "/erroneous.jpg" --end -\ No newline at end of file -+end +-require 'bundler/setup' + require 'rspec' + require 'mocha/api' + diff -Nru ruby-mini-magick-3.6.0+gh/debian/patches/series ruby-mini-magick-3.7.0/debian/patches/series --- ruby-mini-magick-3.6.0+gh/debian/patches/series 2013-05-25 10:46:54.000000000 +0000 +++ ruby-mini-magick-3.7.0/debian/patches/series 2014-01-22 09:39:48.000000000 +0000 @@ -1,3 +1,2 @@ remove-rubygems remove-remote-tests -remove-function-valid_version_installed diff -Nru ruby-mini-magick-3.6.0+gh/debian/ruby-tests.rake ruby-mini-magick-3.7.0/debian/ruby-tests.rake --- ruby-mini-magick-3.6.0+gh/debian/ruby-tests.rake 1970-01-01 00:00:00.000000000 +0000 +++ ruby-mini-magick-3.7.0/debian/ruby-tests.rake 2014-01-22 09:39:48.000000000 +0000 @@ -0,0 +1,8 @@ +require 'rspec/core/rake_task' + +RSpec::Core::RakeTask.new(:spec) do |spec| + spec.pattern = './spec/**/*_spec.rb' +end + +task :default => :spec + diff -Nru ruby-mini-magick-3.6.0+gh/debian/ruby-tests.rb ruby-mini-magick-3.7.0/debian/ruby-tests.rb --- ruby-mini-magick-3.6.0+gh/debian/ruby-tests.rb 2013-04-21 08:38:59.000000000 +0000 +++ ruby-mini-magick-3.7.0/debian/ruby-tests.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -$: << 'test' << '.' -Dir['{test}/**/*.rb'].each { |f| require f } diff -Nru ruby-mini-magick-3.6.0+gh/lib/mini_magick/command_builder.rb ruby-mini-magick-3.7.0/lib/mini_magick/command_builder.rb --- ruby-mini-magick-3.6.0+gh/lib/mini_magick/command_builder.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-mini-magick-3.7.0/lib/mini_magick/command_builder.rb 2013-11-26 01:14:08.000000000 +0000 @@ -0,0 +1,104 @@ +module MiniMagick + class CommandBuilder + MOGRIFY_COMMANDS = %w{adaptive-blur adaptive-resize adaptive-sharpen adjoin affine alpha annotate antialias append attenuate authenticate auto-gamma auto-level auto-orient backdrop background bench bias black-point-compensation black-threshold blend blue-primary blue-shift blur border bordercolor borderwidth brightness-contrast cache caption cdl channel charcoal chop clamp clip clip-mask clip-path clone clut coalesce colorize colormap color-matrix colors colorspace combine comment compose composite compress contrast contrast-stretch convolve crop cycle debug decipher deconstruct define delay delete density depth descend deskew despeckle direction displace display dispose dissimilarity-threshold dissolve distort dither draw duplicate edge emboss encipher encoding endian enhance equalize evaluate evaluate-sequence extent extract family features fft fill filter flatten flip floodfill flop font foreground format frame function fuzz fx gamma gaussian-blur geometry gravity green-primary hald-clut help highlight-color iconGeometry iconic identify ift immutable implode insert intent interlace interpolate interline-spacing interword-spacing kerning label lat layers level level-colors limit linear-stretch linewidth liquid-rescale list log loop lowlight-color magnify map mask mattecolor median metric mode modulate monitor monochrome morph morphology mosaic motion-blur name negate noise normalize opaque ordered-dither orient page paint path pause pen perceptible ping pointsize polaroid poly posterize precision preview print process profile quality quantize quiet radial-blur raise random-threshold red-primary regard-warnings region remap remote render repage resample resize respect-parentheses reverse roll rotate sample sampling-factor scale scene screen seed segment selective-blur separate sepia-tone set shade shadow shared-memory sharpen shave shear sigmoidal-contrast silent size sketch smush snaps solarize sparse-color splice spread statistic stegano stereo stretch strip stroke strokewidth style subimage-search swap swirl synchronize taint text-font texture threshold thumbnail tile tile-offset tint title transform transparent transparent-color transpose transverse treedepth trim type undercolor unique-colors units unsharp update verbose version view vignette virtual-pixel visual watermark wave weight white-point white-threshold window window-group write} + IMAGE_CREATION_OPERATORS = %w{canvas caption gradient label logo pattern plasma radial radient rose text tile xc } + + def initialize(tool, *options) + @tool = tool + @args = [] + options.each { |arg| push(arg) } + end + + def command + com = "#{@tool} #{args.join(' ')}".strip + com = "#{MiniMagick.processor} #{com}" unless MiniMagick.mogrify? + + com = File.join MiniMagick.processor_path, com unless MiniMagick.processor_path.nil? + com.strip + end + + def escape_string_windows(value) + # For Windows, ^ is the escape char, equivalent to \ in Unix. + escaped = value.gsub(/\^/, '^^').gsub(/>/, '^>') + if escaped !~ /^".+"$/ && escaped.include?("'") + escaped.inspect + else + escaped + end + + end + + def args + if !MiniMagick::Utilities.windows? + @args.map(&:shellescape) + else + @args.map { |arg| escape_string_windows(arg) } + end + end + + # Add each mogrify command in both underscore and dash format + MOGRIFY_COMMANDS.each do |mogrify_command| + + # Example of what is generated here: + # + # def auto_orient(*options) + # add_command("auto-orient", *options) + # self + # end + # alias_method :"auto-orient", :auto_orient + + dashed_command = mogrify_command.to_s.gsub("_","-") + underscored_command = mogrify_command.to_s.gsub("-","_") + + define_method(underscored_command) do |*options| + add_command(__method__.to_s.gsub("_","-"), *options) + self + end + alias_method dashed_command, underscored_command + end + + def format(*options) + raise Error, "You must call 'format' on the image object directly!" + end + + IMAGE_CREATION_OPERATORS.each do |operator| + define_method operator do |*options| + add_creation_operator(__method__.to_s, *options) + self + end + end + + def +(*options) + push(@args.pop.gsub(/^-/, '+')) + if options.any? + options.each do |o| + push o + end + end + end + + def add_command(command, *options) + push "-#{command}" + if options.any? + options.each do |o| + push o + end + end + end + + def add_creation_operator(command, *options) + creation_command = command + if options.any? + options.each do |option| + creation_command << ":#{option}" + end + end + push creation_command + end + + def push(arg) + @args << arg.to_s.strip + end + alias :<< :push + end +end diff -Nru ruby-mini-magick-3.6.0+gh/lib/mini_magick/errors.rb ruby-mini-magick-3.7.0/lib/mini_magick/errors.rb --- ruby-mini-magick-3.6.0+gh/lib/mini_magick/errors.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-mini-magick-3.7.0/lib/mini_magick/errors.rb 2013-11-26 01:14:08.000000000 +0000 @@ -0,0 +1,4 @@ +module MiniMagick + class Error < RuntimeError; end + class Invalid < StandardError; end +end diff -Nru ruby-mini-magick-3.6.0+gh/lib/mini_magick/image.rb ruby-mini-magick-3.7.0/lib/mini_magick/image.rb --- ruby-mini-magick-3.6.0+gh/lib/mini_magick/image.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-mini-magick-3.7.0/lib/mini_magick/image.rb 2013-11-26 01:14:08.000000000 +0000 @@ -0,0 +1,405 @@ +module MiniMagick + class Image + # @return [String] The location of the current working file + attr_accessor :path + + def path_for_windows_quote_space(path) + path = Pathname.new(@path).to_s + # For Windows, if a path contains space char, you need to quote it, otherwise you SHOULD NOT quote it. + # If you quote a path that does not contains space, it will not work. + @path.include?(' ') ? path.inspect : path + end + + def path + MiniMagick::Utilities.windows? ? path_for_windows_quote_space(@path) : @path + end + + def path=(path) + @path = path + end + + # Class Methods + # ------------- + class << self + # This is the primary loading method used by all of the other class methods. + # + # Use this to pass in a stream object. Must respond to Object#read(size) or be a binary string object (BLOBBBB) + # + # As a change from the old API, please try and use IOStream objects. They are much, much better and more efficient! + # + # Probably easier to use the #open method if you want to open a file or a URL. + # + # @param stream [IOStream, String] Some kind of stream object that needs to be read or is a binary String blob! + # @param ext [String] A manual extension to use for reading the file. Not required, but if you are having issues, give this a try. + # @return [Image] + def read(stream, ext = nil) + if stream.is_a?(String) + stream = StringIO.new(stream) + elsif stream.is_a?(StringIO) + # Do nothing, we want a StringIO-object + elsif stream.respond_to? :path + if File.respond_to?(:binread) + stream = StringIO.new File.binread(stream.path.to_s) + else + stream = StringIO.new File.open(stream.path.to_s,"rb") { |f| f.read } + end + end + + create(ext) do |f| + while chunk = stream.read(8192) + f.write(chunk) + end + end + end + + # @deprecated Please use Image.read instead! + def from_blob(blob, ext = nil) + warn "Warning: MiniMagick::Image.from_blob method is deprecated. Instead, please use Image.read" + create(ext) { |f| f.write(blob) } + end + + # Creates an image object from a binary string blob which contains raw pixel data (i.e. no header data). + # + # === Returns + # + # * [Image] The loaded image. + # + # === Parameters + # + # * [blob] String -- Binary string blob containing raw pixel data. + # * [columns] Integer -- Number of columns. + # * [rows] Integer -- Number of rows. + # * [depth] Integer -- Bit depth of the encoded pixel data. + # * [map] String -- A code for the mapping of the pixel data. Example: 'gray' or 'rgb'. + # * [format] String -- The file extension of the image format to be used when creating the image object. Defaults to 'png'. + # + def import_pixels(blob, columns, rows, depth, map, format="png") + # Create an image object with the raw pixel data string: + image = create(".dat", validate = false) { |f| f.write(blob) } + # Use ImageMagick to convert the raw data file to an image file of the desired format: + converted_image_path = image.path[0..-4] + format + arguments = ["-size", "#{columns}x#{rows}", "-depth", "#{depth}", "#{map}:#{image.path}", "#{converted_image_path}"] + cmd = CommandBuilder.new("convert", *arguments) #Example: convert -size 256x256 -depth 16 gray:blob.dat blob.png + image.run(cmd) + # Update the image instance with the path of the properly formatted image, and return: + image.path = converted_image_path + image + end + + # Opens a specific image file either on the local file system or at a URI. + # + # Use this if you don't want to overwrite the image file. + # + # Extension is either guessed from the path or you can specify it as a second parameter. + # + # If you pass in what looks like a URL, we require 'open-uri' before opening it. + # + # @param file_or_url [String] Either a local file path or a URL that open-uri can read + # @param ext [String] Specify the extension you want to read it as + # @return [Image] The loaded image + def open(file_or_url, ext = nil) + file_or_url = file_or_url.to_s # Force it to be a String... hell or highwater + if file_or_url.include?("://") + require 'open-uri' + ext ||= File.extname(URI.parse(file_or_url).path) + Kernel::open(file_or_url) do |f| + self.read(f, ext) + end + else + ext ||= File.extname(file_or_url) + File.open(file_or_url, "rb") do |f| + self.read(f, ext) + end + end + end + + # @deprecated Please use MiniMagick::Image.open(file_or_url) now + def from_file(file, ext = nil) + warn "Warning: MiniMagick::Image.from_file is now deprecated. Please use Image.open" + open(file, ext) + end + + # Used to create a new Image object data-copy. Not used to "paint" or that kind of thing. + # + # Takes an extension in a block and can be used to build a new Image object. Used + # by both #open and #read to create a new object! Ensures we have a good tempfile! + # + # @param ext [String] Specify the extension you want to read it as + # @param validate [Boolean] If false, skips validation of the created image. Defaults to true. + # @yield [IOStream] You can #write bits to this object to create the new Image + # @return [Image] The created image + def create(ext = nil, validate = true, &block) + begin + tempfile = Tempfile.new(['mini_magick', ext.to_s.downcase]) + tempfile.binmode + block.call(tempfile) + tempfile.close + + image = self.new(tempfile.path, tempfile) + + if validate and !image.valid? + raise MiniMagick::Invalid + end + return image + ensure + tempfile.close if tempfile + end + end + end + + # Create a new MiniMagick::Image object + # + # _DANGER_: The file location passed in here is the *working copy*. That is, it gets *modified*. + # you can either copy it yourself or use the MiniMagick::Image.open(path) method which creates a + # temporary file for you and protects your original! + # + # @param input_path [String] The location of an image file + # @todo Allow this to accept a block that can pass off to Image#combine_options + def initialize(input_path, tempfile = nil) + @path = input_path + @tempfile = tempfile # ensures that the tempfile will stick around until this image is garbage collected. + end + + # Checks to make sure that MiniMagick can read the file and understand it. + # + # This uses the 'identify' command line utility to check the file. If you are having + # issues with this, then please work directly with the 'identify' command and see if you + # can figure out what the issue is. + # + # @return [Boolean] + def valid? + run_command("identify", path) + true + rescue MiniMagick::Invalid + false + end + + # A rather low-level way to interact with the "identify" command. No nice API here, just + # the crazy stuff you find in ImageMagick. See the examples listed! + # + # @example + # image["format"] #=> "TIFF" + # image["height"] #=> 41 (pixels) + # image["width"] #=> 50 (pixels) + # image["colorspace"] #=> "DirectClassRGB" + # image["dimensions"] #=> [50, 41] + # image["size"] #=> 2050 (bits) + # image["original_at"] #=> 2005-02-23 23:17:24 +0000 (Read from Exif data) + # image["EXIF:ExifVersion"] #=> "0220" (Can read anything from Exif) + # + # @param format [String] A format for the "identify" command + # @see For reference see http://www.imagemagick.org/script/command-line-options.php#format + # @return [String, Numeric, Array, Time, Object] Depends on the method called! Defaults to String for unknown commands + def [](value) + # Why do I go to the trouble of putting in newlines? Because otherwise animated gifs screw everything up + case value.to_s + when "colorspace" + run_command("identify", "-format", '%r\n', path).split("\n")[0].strip + when "format" + run_command("identify", "-format", '%m\n', path).split("\n")[0] + when "height" + run_command("identify", "-format", '%h\n', path).split("\n")[0].to_i + when "width" + run_command("identify", "-format", '%w\n', path).split("\n")[0].to_i + when "dimensions" + run_command("identify", "-format", MiniMagick::Utilities.windows? ? '"%w %h\n"' : '%w %h\n', path).split("\n")[0].split.map{|v|v.to_i} + when "size" + File.size(path) # Do this because calling identify -format "%b" on an animated gif fails! + when "original_at" + # Get the EXIF original capture as a Time object + Time.local(*self["EXIF:DateTimeOriginal"].split(/:|\s+/)) rescue nil + when /^EXIF\:/i + result = run_command('identify', '-format', "%[#{value}]", path).chomp + if result.include?(",") + read_character_data(result) + else + result + end + else + run_command('identify', '-format', value, path).split("\n")[0] + end + end + + # Sends raw commands to imagemagick's `mogrify` command. The image path is automatically appended to the command. + # + # Remember, we are always acting on this instance of the Image when messing with this. + # + # @return [String] Whatever the result from the command line is. May not be terribly useful. + def <<(*args) + run_command("mogrify", *args << path) + end + + # This is used to change the format of the image. That is, from "tiff to jpg" or something like that. + # Once you run it, the instance is pointing to a new file with a new extension! + # + # *DANGER*: This renames the file that the instance is pointing to. So, if you manually opened the + # file with Image.new(file_path)... then that file is DELETED! If you used Image.open(file) then + # you are ok. The original file will still be there. But, any changes to it might not be... + # + # Formatting an animation into a non-animated type will result in ImageMagick creating multiple + # pages (starting with 0). You can choose which page you want to manipulate. We default to the + # first page. + # + # If you would like to convert between animated formats, pass nil as your + # page and ImageMagick will copy all of the pages. + # + # @param format [String] The target format... like 'jpg', 'gif', 'tiff', etc. + # @param page [Integer] If this is an animated gif, say which 'page' you want + # with an integer. Default 0 will convert only the first page; 'nil' will + # convert all pages. + # @return [nil] + def format(format, page = 0) + c = CommandBuilder.new('mogrify', '-format', format) + yield c if block_given? + if page + c << "#{path}[#{page}]" + else + c << path + end + run(c) + + old_path = path + self.path = path.sub(/(\.\w*)?$/, ".#{format}") + File.delete(old_path) if old_path != path + + unless File.exists?(path) + raise MiniMagick::Error, "Unable to format to #{format}" + end + end + + # Collapse images with sequences to the first frame (ie. animated gifs) and + # preserve quality + def collapse! + run_command("mogrify", "-quality", "100", "#{path}[0]") + end + + # Writes the temporary file out to either a file location (by passing in a String) or by + # passing in a Stream that you can #write(chunk) to repeatedly + # + # @param output_to [IOStream, String] Some kind of stream object that needs to be read or a file path as a String + # @return [IOStream, Boolean] If you pass in a file location [String] then you get a success boolean. If its a stream, you get it back. + # Writes the temporary image that we are using for processing to the output path + def write(output_to) + if output_to.kind_of?(String) || !output_to.respond_to?(:write) + FileUtils.copy_file path, output_to + run_command "identify", MiniMagick::Utilities.windows? ? path_for_windows_quote_space(output_to.to_s) : output_to.to_s # Verify that we have a good image + else # stream + File.open(path, "rb") do |f| + f.binmode + while chunk = f.read(8192) + output_to.write(chunk) + end + end + output_to + end + end + + # Gives you raw image data back + # @return [String] binary string + def to_blob + f = File.new path + f.binmode + f.read + ensure + f.close if f + end + + def mime_type + format = self[:format] + "image/" + format.to_s.downcase + end + + # If an unknown method is called then it is sent through the mogrify program + # Look here to find all the commands (http://www.imagemagick.org/script/mogrify.php) + def method_missing(symbol, *args) + combine_options do |c| + c.send(symbol, *args) + end + end + + # You can use multiple commands together using this method. Very easy to use! + # + # @example + # image.combine_options do |c| + # c.draw "image Over 0,0 10,10 '#{MINUS_IMAGE_PATH}'" + # c.thumbnail "300x500>" + # c.background background + # end + # + # @yieldparam command [CommandBuilder] + def combine_options(tool = "mogrify", &block) + c = CommandBuilder.new(tool) + + c << path if tool.to_s == "convert" + block.call(c) + c << path + run(c) + end + + def composite(other_image, output_extension = 'jpg', &block) + begin + second_tempfile = Tempfile.new(output_extension) + second_tempfile.binmode + ensure + second_tempfile.close + end + + command = CommandBuilder.new("composite") + block.call(command) if block + command.push(other_image.path) + command.push(self.path) + command.push(second_tempfile.path) + + run(command) + return Image.new(second_tempfile.path, second_tempfile) + end + + def run_command(command, *args) + if command == 'identify' + args.unshift '-ping' # -ping "efficiently determine image characteristics." + args.unshift '-quiet' if MiniMagick.mogrify? # graphicsmagick has no -quiet option. + end + + run(CommandBuilder.new(command, *args)) + end + + def run(command_builder) + command = command_builder.command + + sub = Subexec.run(command, :timeout => MiniMagick.timeout) + + if sub.exitstatus != 0 + # Clean up after ourselves in case of an error + destroy! + + # Raise the appropriate error + if sub.output =~ /no decode delegate/i || sub.output =~ /did not return an image/i + raise Invalid, sub.output + else + # TODO: should we do something different if the command times out ...? + # its definitely better for logging.. otherwise we dont really know + raise Error, "Command (#{command.inspect.gsub("\\", "")}) failed: #{{:status_code => sub.exitstatus, :output => sub.output}.inspect}" + end + else + sub.output + end + end + + def destroy! + return if @tempfile.nil? + File.unlink(path) if File.exists?(path) + @tempfile = nil + end + + private + # Sometimes we get back a list of character values + def read_character_data(list_of_characters) + chars = list_of_characters.gsub(" ", "").split(",") + result = "" + chars.each do |val| + result << ("%c" % val.to_i) + end + result + end + end +end diff -Nru ruby-mini-magick-3.6.0+gh/lib/mini_magick/utilities.rb ruby-mini-magick-3.7.0/lib/mini_magick/utilities.rb --- ruby-mini-magick-3.6.0+gh/lib/mini_magick/utilities.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-mini-magick-3.7.0/lib/mini_magick/utilities.rb 2013-11-26 01:14:08.000000000 +0000 @@ -0,0 +1,31 @@ +require 'rbconfig' + +module MiniMagick + module Utilities + class << self + # Cross-platform way of finding an executable in the $PATH. + # + # which('ruby') #=> /usr/bin/ruby + def which(cmd) + exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : [''] + ENV['PATH'].split(File::PATH_SEPARATOR).each do |path| + exts.each { |ext| + exe = File.join(path, "#{cmd}#{ext}") + return exe if File.executable? exe + } + end + return nil + end + + # Finds out if the host OS is windows + def windows? + RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/ + end + + def windows_escape(cmdline) + '"' + cmdline.gsub(/\\(?=\\*\")/, "\\\\\\").gsub(/\"/, "\\\"").gsub(/\\$/, "\\\\\\").gsub("%", "%%") + '"' + end + end + end +end + diff -Nru ruby-mini-magick-3.6.0+gh/lib/mini_magick/version.rb ruby-mini-magick-3.7.0/lib/mini_magick/version.rb --- ruby-mini-magick-3.6.0+gh/lib/mini_magick/version.rb 2013-05-21 02:40:21.000000000 +0000 +++ ruby-mini-magick-3.7.0/lib/mini_magick/version.rb 2013-11-26 01:14:08.000000000 +0000 @@ -1,3 +1,3 @@ module MiniMagick - VERSION = "3.6.0" + VERSION = "3.7.0" end diff -Nru ruby-mini-magick-3.6.0+gh/lib/mini_magick.rb ruby-mini-magick-3.7.0/lib/mini_magick.rb --- ruby-mini-magick-3.6.0+gh/lib/mini_magick.rb 2013-05-21 02:40:21.000000000 +0000 +++ ruby-mini-magick-3.7.0/lib/mini_magick.rb 2013-11-26 01:14:08.000000000 +0000 @@ -3,6 +3,10 @@ require 'stringio' require 'pathname' require 'shellwords' +require 'mini_magick/command_builder' +require 'mini_magick/errors' +require 'mini_magick/image' +require 'mini_magick/utilities' module MiniMagick class << self @@ -10,509 +14,67 @@ attr_accessor :processor_path attr_accessor :timeout - - # Experimental method for automatically selecting a processor - # such as gm. Only works on *nix. + ## + # Tries to detect the current processor based if any of the processors exist. + # Mogrify have precedence over gm by default. # - # TODO: Write tests for this and figure out what platforms it supports + # === Returns + # * [String] The detected procesor def choose_processor - if `type -P mogrify`.size > 0 - return - elsif `type -P gm`.size > 0 + if MiniMagick::Utilities.which('mogrify').size > 0 + self.processor = 'mogrify' + elsif MiniMagick::Utilities.which('gm').size > 0 self.processor = "gm" end end - + + ## + # Discovers the imagemagick version based on mogrify's output. + # + # === Returns + # * The imagemagick version def image_magick_version @@version ||= Gem::Version.create(`mogrify --version`.split(" ")[2].split("-").first) end - + + ## + # The minimum allowed imagemagick version + # + # === Returns + # * The minimum imagemagick version def minimum_image_magick_version @@minimum_version ||= Gem::Version.create("6.6.3") end + ## + # Checks whether the imagemagick's version is valid + # + # === Returns + # * [Boolean] def valid_version_installed? image_magick_version >= minimum_image_magick_version end - end - - MOGRIFY_COMMANDS = %w{adaptive-blur adaptive-resize adaptive-sharpen adjoin affine alpha annotate antialias append attenuate authenticate auto-gamma auto-level auto-orient backdrop background bench bias black-point-compensation black-threshold blend blue-primary blue-shift blur border bordercolor borderwidth brightness-contrast cache caption cdl channel charcoal chop clamp clip clip-mask clip-path clone clut coalesce colorize colormap color-matrix colors colorspace combine comment compose composite compress contrast contrast-stretch convolve crop cycle debug decipher deconstruct define delay delete density depth descend deskew despeckle direction displace display dispose dissimilarity-threshold dissolve distort dither draw duplicate edge emboss encipher encoding endian enhance equalize evaluate evaluate-sequence extent extract family features fft fill filter flatten flip floodfill flop font foreground format frame function fuzz fx gamma gaussian-blur geometry gravity green-primary hald-clut help highlight-color iconGeometry iconic identify ift immutable implode insert intent interlace interpolate interline-spacing interword-spacing kerning label lat layers level level-colors limit linear-stretch linewidth liquid-rescale list log loop lowlight-color magnify map mask mattecolor median metric mode modulate monitor monochrome morph morphology mosaic motion-blur name negate noise normalize opaque ordered-dither orient page paint path pause pen perceptible ping pointsize polaroid poly posterize precision preview print process profile quality quantize quiet radial-blur raise random-threshold red-primary regard-warnings region remap remote render repage resample resize respect-parentheses reverse roll rotate sample sampling-factor scale scene screen seed segment selective-blur separate sepia-tone set shade shadow shared-memory sharpen shave shear sigmoidal-contrast silent size sketch smush snaps solarize sparse-color splice spread statistic stegano stereo stretch strip stroke strokewidth style subimage-search swap swirl synchronize taint text-font texture threshold thumbnail tile tile-offset tint title transform transparent transparent-color transpose transverse treedepth trim type undercolor unique-colors units unsharp update verbose version view vignette virtual-pixel visual watermark wave weight white-point white-threshold window window-group write} - IMAGE_CREATION_OPERATORS = %w{canvas caption gradient label logo pattern plasma radial radient rose text tile xc } - - class Error < RuntimeError; end - class Invalid < StandardError; end - - class Image - # @return [String] The location of the current working file - attr_accessor :path - - # Class Methods - # ------------- - class << self - # This is the primary loading method used by all of the other class methods. - # - # Use this to pass in a stream object. Must respond to Object#read(size) or be a binary string object (BLOBBBB) - # - # As a change from the old API, please try and use IOStream objects. They are much, much better and more efficient! - # - # Probably easier to use the #open method if you want to open a file or a URL. - # - # @param stream [IOStream, String] Some kind of stream object that needs to be read or is a binary String blob! - # @param ext [String] A manual extension to use for reading the file. Not required, but if you are having issues, give this a try. - # @return [Image] - def read(stream, ext = nil) - if stream.is_a?(String) - stream = StringIO.new(stream) - elsif stream.is_a?(StringIO) - # Do nothing, we want a StringIO-object - elsif stream.respond_to? :path - if File.respond_to?(:binread) - stream = StringIO.new File.binread(stream.path.to_s) - else - stream = StringIO.new File.open(stream.path.to_s,"rb") { |f| f.read } - end - end - - create(ext) do |f| - while chunk = stream.read(8192) - f.write(chunk) - end - end - end - - # @deprecated Please use Image.read instead! - def from_blob(blob, ext = nil) - warn "Warning: MiniMagick::Image.from_blob method is deprecated. Instead, please use Image.read" - create(ext) { |f| f.write(blob) } - end - - # Creates an image object from a binary string blob which contains raw pixel data (i.e. no header data). - # - # === Returns - # - # * [Image] The loaded image. - # - # === Parameters - # - # * [blob] String -- Binary string blob containing raw pixel data. - # * [columns] Integer -- Number of columns. - # * [rows] Integer -- Number of rows. - # * [depth] Integer -- Bit depth of the encoded pixel data. - # * [map] String -- A code for the mapping of the pixel data. Example: 'gray' or 'rgb'. - # * [format] String -- The file extension of the image format to be used when creating the image object. Defaults to 'png'. - # - def import_pixels(blob, columns, rows, depth, map, format="png") - # Create an image object with the raw pixel data string: - image = create(".dat", validate = false) { |f| f.write(blob) } - # Use ImageMagick to convert the raw data file to an image file of the desired format: - converted_image_path = image.path[0..-4] + format - arguments = ["-size", "#{columns}x#{rows}", "-depth", "#{depth}", "#{map}:#{image.path}", "#{converted_image_path}"] - cmd = CommandBuilder.new("convert", *arguments) #Example: convert -size 256x256 -depth 16 gray:blob.dat blob.png - image.run(cmd) - # Update the image instance with the path of the properly formatted image, and return: - image.path = converted_image_path - image - end - - # Opens a specific image file either on the local file system or at a URI. - # - # Use this if you don't want to overwrite the image file. - # - # Extension is either guessed from the path or you can specify it as a second parameter. - # - # If you pass in what looks like a URL, we require 'open-uri' before opening it. - # - # @param file_or_url [String] Either a local file path or a URL that open-uri can read - # @param ext [String] Specify the extension you want to read it as - # @return [Image] The loaded image - def open(file_or_url, ext = nil) - file_or_url = file_or_url.to_s # Force it to be a String... hell or highwater - if file_or_url.include?("://") - require 'open-uri' - ext ||= File.extname(URI.parse(file_or_url).path) - self.read(Kernel::open(file_or_url), ext) - else - ext ||= File.extname(file_or_url) - File.open(file_or_url, "rb") do |f| - self.read(f, ext) - end - end - end - - # @deprecated Please use MiniMagick::Image.open(file_or_url) now - def from_file(file, ext = nil) - warn "Warning: MiniMagick::Image.from_file is now deprecated. Please use Image.open" - open(file, ext) - end - - # Used to create a new Image object data-copy. Not used to "paint" or that kind of thing. - # - # Takes an extension in a block and can be used to build a new Image object. Used - # by both #open and #read to create a new object! Ensures we have a good tempfile! - # - # @param ext [String] Specify the extension you want to read it as - # @param validate [Boolean] If false, skips validation of the created image. Defaults to true. - # @yield [IOStream] You can #write bits to this object to create the new Image - # @return [Image] The created image - def create(ext = nil, validate = true, &block) - begin - tempfile = Tempfile.new(['mini_magick', ext.to_s.downcase]) - tempfile.binmode - block.call(tempfile) - tempfile.close - - image = self.new(tempfile.path, tempfile) - - if validate and !image.valid? - raise MiniMagick::Invalid - end - return image - ensure - tempfile.close if tempfile - end - end - end - - # Create a new MiniMagick::Image object - # - # _DANGER_: The file location passed in here is the *working copy*. That is, it gets *modified*. - # you can either copy it yourself or use the MiniMagick::Image.open(path) method which creates a - # temporary file for you and protects your original! + ## + # Picks the right processor if it isn't set and returns whether it's mogrify or not. # - # @param input_path [String] The location of an image file - # @todo Allow this to accept a block that can pass off to Image#combine_options - def initialize(input_path, tempfile = nil) - @path = input_path - @tempfile = tempfile # ensures that the tempfile will stick around until this image is garbage collected. - end + # === Returns + # * [Boolean] + def mogrify? + self.choose_processor if self.processor.nil? - # Checks to make sure that MiniMagick can read the file and understand it. - # - # This uses the 'identify' command line utility to check the file. If you are having - # issues with this, then please work directly with the 'identify' command and see if you - # can figure out what the issue is. - # - # @return [Boolean] - def valid? - run_command("identify", path) - true - rescue MiniMagick::Invalid - false - end - - # A rather low-level way to interact with the "identify" command. No nice API here, just - # the crazy stuff you find in ImageMagick. See the examples listed! - # - # @example - # image["format"] #=> "TIFF" - # image["height"] #=> 41 (pixels) - # image["width"] #=> 50 (pixels) - # image["colorspace"] #=> "DirectClassRGB" - # image["dimensions"] #=> [50, 41] - # image["size"] #=> 2050 (bits) - # image["original_at"] #=> 2005-02-23 23:17:24 +0000 (Read from Exif data) - # image["EXIF:ExifVersion"] #=> "0220" (Can read anything from Exif) - # - # @param format [String] A format for the "identify" command - # @see For reference see http://www.imagemagick.org/script/command-line-options.php#format - # @return [String, Numeric, Array, Time, Object] Depends on the method called! Defaults to String for unknown commands - def [](value) - # Why do I go to the trouble of putting in newlines? Because otherwise animated gifs screw everything up - case value.to_s - when "colorspace" - run_command("identify", "-format", '%r\n', path).split("\n")[0].strip - when "format" - run_command("identify", "-format", '%m\n', path).split("\n")[0] - when "height" - run_command("identify", "-format", '%h\n', path).split("\n")[0].to_i - when "width" - run_command("identify", "-format", '%w\n', path).split("\n")[0].to_i - when "dimensions" - run_command("identify", "-format", '%w %h\n', path).split("\n")[0].split.map{|v|v.to_i} - when "size" - File.size(path) # Do this because calling identify -format "%b" on an animated gif fails! - when "original_at" - # Get the EXIF original capture as a Time object - Time.local(*self["EXIF:DateTimeOriginal"].split(/:|\s+/)) rescue nil - when /^EXIF\:/i - result = run_command('identify', '-format', "%[#{value}]", path).chop - if result.include?(",") - read_character_data(result) - else - result - end - else - run_command('identify', '-format', value, path).split("\n")[0] - end - end - - # Sends raw commands to imagemagick's `mogrify` command. The image path is automatically appended to the command. - # - # Remember, we are always acting on this instance of the Image when messing with this. - # - # @return [String] Whatever the result from the command line is. May not be terribly useful. - def <<(*args) - run_command("mogrify", *args << path) - end - - # This is used to change the format of the image. That is, from "tiff to jpg" or something like that. - # Once you run it, the instance is pointing to a new file with a new extension! - # - # *DANGER*: This renames the file that the instance is pointing to. So, if you manually opened the - # file with Image.new(file_path)... then that file is DELETED! If you used Image.open(file) then - # you are ok. The original file will still be there. But, any changes to it might not be... - # - # Formatting an animation into a non-animated type will result in ImageMagick creating multiple - # pages (starting with 0). You can choose which page you want to manipulate. We default to the - # first page. - # - # If you would like to convert between animated formats, pass nil as your - # page and ImageMagick will copy all of the pages. - # - # @param format [String] The target format... like 'jpg', 'gif', 'tiff', etc. - # @param page [Integer] If this is an animated gif, say which 'page' you want - # with an integer. Default 0 will convert only the first page; 'nil' will - # convert all pages. - # @return [nil] - def format(format, page = 0) - c = CommandBuilder.new('mogrify', '-format', format) - yield c if block_given? - if page - c << "#{path}[#{page}]" - else - c << path - end - run(c) - - old_path = path - self.path = path.sub(/(\.\w*)?$/, ".#{format}") - File.delete(old_path) if old_path != path - - unless File.exists?(path) - raise MiniMagick::Error, "Unable to format to #{format}" - end + self.processor == 'mogrify' end - # Collapse images with sequences to the first frame (ie. animated gifs) and - # preserve quality - def collapse! - run_command("mogrify", "-quality", "100", "#{path}[0]") - end - - # Writes the temporary file out to either a file location (by passing in a String) or by - # passing in a Stream that you can #write(chunk) to repeatedly + ## + # Picks the right processor if it isn't set and returns whether it's graphicsmagick or not. # - # @param output_to [IOStream, String] Some kind of stream object that needs to be read or a file path as a String - # @return [IOStream, Boolean] If you pass in a file location [String] then you get a success boolean. If its a stream, you get it back. - # Writes the temporary image that we are using for processing to the output path - def write(output_to) - if output_to.kind_of?(String) || !output_to.respond_to?(:write) - FileUtils.copy_file path, output_to - run_command "identify", output_to.to_s # Verify that we have a good image - else # stream - File.open(path, "rb") do |f| - f.binmode - while chunk = f.read(8192) - output_to.write(chunk) - end - end - output_to - end - end - - # Gives you raw image data back - # @return [String] binary string - def to_blob - f = File.new path - f.binmode - f.read - ensure - f.close if f - end - - def mime_type - format = self[:format] - "image/" + format.to_s.downcase - end - - # If an unknown method is called then it is sent through the mogrify program - # Look here to find all the commands (http://www.imagemagick.org/script/mogrify.php) - def method_missing(symbol, *args) - combine_options do |c| - c.send(symbol, *args) - end - end - - # You can use multiple commands together using this method. Very easy to use! - # - # @example - # image.combine_options do |c| - # c.draw "image Over 0,0 10,10 '#{MINUS_IMAGE_PATH}'" - # c.thumbnail "300x500>" - # c.background background - # end - # - # @yieldparam command [CommandBuilder] - def combine_options(tool = "mogrify", &block) - c = CommandBuilder.new(tool) - - c << path if tool.to_s == "convert" - block.call(c) - c << path - run(c) - end - - def composite(other_image, output_extension = 'jpg', &block) - begin - second_tempfile = Tempfile.new(output_extension) - second_tempfile.binmode - ensure - second_tempfile.close - end - - command = CommandBuilder.new("composite") - block.call(command) if block - command.push(other_image.path) - command.push(self.path) - command.push(second_tempfile.path) - - run(command) - return Image.new(second_tempfile.path, second_tempfile) - end - - def run_command(command, *args) - # -ping "efficiently determine image characteristics." - if command == 'identify' - args.unshift '-ping' - args.unshift '-quiet' unless MiniMagick.processor.to_s == 'gm' - end - - run(CommandBuilder.new(command, *args)) - end - - def run(command_builder) - command = command_builder.command - - sub = Subexec.run(command, :timeout => MiniMagick.timeout) - - if sub.exitstatus != 0 - # Clean up after ourselves in case of an error - destroy! - - # Raise the appropriate error - if sub.output =~ /no decode delegate/i || sub.output =~ /did not return an image/i - raise Invalid, sub.output - else - # TODO: should we do something different if the command times out ...? - # its definitely better for logging.. otherwise we dont really know - raise Error, "Command (#{command.inspect.gsub("\\", "")}) failed: #{{:status_code => sub.exitstatus, :output => sub.output}.inspect}" - end - else - sub.output - end - end - - def destroy! - return if @tempfile.nil? - File.unlink(@tempfile.path) if File.exists?(@tempfile.path) - @tempfile = nil - end - - private - # Sometimes we get back a list of character values - def read_character_data(list_of_characters) - chars = list_of_characters.gsub(" ", "").split(",") - result = "" - chars.each do |val| - result << ("%c" % val.to_i) - end - result - end - end - - class CommandBuilder - def initialize(tool, *options) - @tool = tool - @args = [] - options.each { |arg| push(arg) } - end - - def command - com = "#{@tool} #{args.join(' ')}".strip - com = "#{MiniMagick.processor} #{com}" unless MiniMagick.processor.nil? - - com = File.join MiniMagick.processor_path, com unless MiniMagick.processor_path.nil? - com.strip - end - - def args - @args.map(&:shellescape) - end - - # Add each mogrify command in both underscore and dash format - MOGRIFY_COMMANDS.each do |mogrify_command| - - # Example of what is generated here: - # - # def auto_orient(*options) - # add_command("auto-orient", *options) - # self - # end - # alias_method :"auto-orient", :auto_orient - - dashed_command = mogrify_command.to_s.gsub("_","-") - underscored_command = mogrify_command.to_s.gsub("-","_") - - define_method(underscored_command) do |*options| - add_command(__method__.to_s.gsub("_","-"), *options) - self - end - alias_method dashed_command, underscored_command - end - - def format(*options) - raise Error, "You must call 'format' on the image object directly!" - end - - IMAGE_CREATION_OPERATORS.each do |operator| - define_method operator do |*options| - add_creation_operator(__method__.to_s, *options) - self - end - end - - def +(*options) - push(@args.pop.gsub(/^-/, '+')) - if options.any? - options.each do |o| - push o - end - end - end - - def add_command(command, *options) - push "-#{command}" - if options.any? - options.each do |o| - push o - end - end - end - - def add_creation_operator(command, *options) - creation_command = command - if options.any? - options.each do |option| - creation_command << ":#{option}" - end - end - push creation_command - end + # === Returns + # * [Boolean] + def gm? + self.choose_processor if self.processor.nil? - def push(arg) - @args << arg.to_s.strip + self.processor == 'gm' end - alias :<< :push end end diff -Nru ruby-mini-magick-3.6.0+gh/mini_magick.gemspec ruby-mini-magick-3.7.0/mini_magick.gemspec --- ruby-mini-magick-3.6.0+gh/mini_magick.gemspec 2013-05-21 02:40:21.000000000 +0000 +++ ruby-mini-magick-3.7.0/mini_magick.gemspec 2013-11-26 01:14:08.000000000 +0000 @@ -22,4 +22,6 @@ s.add_development_dependency('rake') s.add_development_dependency('test-unit') + s.add_development_dependency('rspec') + s.add_development_dependency('mocha') end Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/spec/files/actually_a_gif.jpg and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/spec/files/actually_a_gif.jpg differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/spec/files/animation.gif and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/spec/files/animation.gif differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/spec/files/composited.jpg and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/spec/files/composited.jpg differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/spec/files/erroneous.jpg and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/spec/files/erroneous.jpg differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/spec/files/leaves (spaced).tiff and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/spec/files/leaves (spaced).tiff differ diff -Nru ruby-mini-magick-3.6.0+gh/spec/files/not_an_image.php ruby-mini-magick-3.7.0/spec/files/not_an_image.php --- ruby-mini-magick-3.6.0+gh/spec/files/not_an_image.php 1970-01-01 00:00:00.000000000 +0000 +++ ruby-mini-magick-3.7.0/spec/files/not_an_image.php 2013-11-26 01:14:08.000000000 +0000 @@ -0,0 +1 @@ + \ No newline at end of file Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/spec/files/png.png and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/spec/files/png.png differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/spec/files/simple-minus.gif and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/spec/files/simple-minus.gif differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/spec/files/simple.gif and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/spec/files/simple.gif differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/spec/files/trogdor.jpg and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/spec/files/trogdor.jpg differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/spec/files/trogdor_capitalized.JPG and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/spec/files/trogdor_capitalized.JPG differ diff -Nru ruby-mini-magick-3.6.0+gh/spec/lib/mini_magick/command_builder_spec.rb ruby-mini-magick-3.7.0/spec/lib/mini_magick/command_builder_spec.rb --- ruby-mini-magick-3.6.0+gh/spec/lib/mini_magick/command_builder_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-mini-magick-3.7.0/spec/lib/mini_magick/command_builder_spec.rb 2013-11-26 01:14:08.000000000 +0000 @@ -0,0 +1,135 @@ +require 'spec_helper' + +# All tests tagged as `ported` are ported from +# testunit tests and are there for backwards compatibility + +MiniMagick.processor = 'mogrify' + +describe MiniMagick::CommandBuilder do + before(:each) do + @processor = MiniMagick.processor + @processor_path = MiniMagick.processor_path + end + + after(:each) do + MiniMagick.processor_path = @processor_path + MiniMagick.processor = @processor + end + + describe "ported from testunit", :ported => true do + let(:builder){ MiniMagick::CommandBuilder.new('test') } + + it "builds a basic command" do + builder.resize "30x40" + builder.args.join(" ").should == '-resize 30x40' + end + + it "builds a full command" do + builder.resize "30x40" + builder.command.should == "test -resize 30x40" + end + + describe 'windows only', :if => MiniMagick::Utilities.windows? do + it "builds a complicated command" do + builder.resize "30x40" + builder.alpha '1 3 4' + builder.resize 'mome fingo' + builder.args.join(" ").should == '-resize 30x40 -alpha 1 3 4 -resize mome fingo' + end + + it "builds a command with multiple options and plus modifier" do + builder.distort.+ 'srt', '0.6 20' + builder.args.join(" ").should == '+distort srt 0.6 20' + end + + it "sets a colorspace correctly" do + builder.set 'colorspace RGB' + builder.command.should == 'test -set colorspace RGB' + end + end + + describe 'not windows', :if => !MiniMagick::Utilities.windows? do + it "builds a complicated command" do + builder.resize "30x40" + builder.alpha '1 3 4' + builder.resize 'mome fingo' + builder.args.join(" ").should == '-resize 30x40 -alpha 1\ 3\ 4 -resize mome\ fingo' + end + + it "sets a colorspace correctly" do + builder.set 'colorspace RGB' + builder.command.should == 'test -set colorspace\ RGB' + end + + it "builds a command with multiple options and plus modifier" do + builder.distort.+ 'srt', '0.6 20' + builder.args.join(" ").should == '\+distort srt 0.6\ 20' + end + end + + it "raises error when command is invalid" do + expect do + command = MiniMagick::CommandBuilder.new('test', 'path') + command.input 2 + end.to raise_error(NoMethodError) + end + + it "builds a dashed command" do + builder.auto_orient + builder.args.join(" ").should == '-auto-orient' + end + + it "builds a dashed command via send" do + builder.send('auto-orient') + builder.args.join(' ').should == '-auto-orient' + end + + it "builds a canvas command" do + builder.canvas 'black' + builder.args.join(' ').should == 'canvas:black' + end + + it "sets a processor path correctly" do + MiniMagick.processor_path = "/a/strange/path" + builder.auto_orient + builder.command.should == "/a/strange/path/test -auto-orient" + end + + it "builds a processor path with processor" do + MiniMagick.processor_path = "/a/strange/path" + MiniMagick.processor = "processor" + builder.auto_orient + builder.command.should == "/a/strange/path/processor test -auto-orient" + end + end + + context 'deprecated' do + let(:builder){ MiniMagick::CommandBuilder.new('test') } + before(:each) { MiniMagick.processor = nil } + + it "builds a full command" do + builder.resize "30x40" + builder.command.should == "test -resize 30x40" + end + + describe 'windows only', :if => MiniMagick::Utilities.windows? do + it "sets a colorspace correctly" do + builder.set 'colorspace RGB' + builder.command.should == 'test -set colorspace RGB' + end + end + + describe 'not windows', :if => !MiniMagick::Utilities.windows? do + it "sets a colorspace correctly" do + builder.set 'colorspace RGB' + builder.command.should == 'test -set colorspace\ RGB' + end + end + + it "sets a processor path correctly" do + MiniMagick.processor_path = "/a/strange/path" + builder.auto_orient + builder.command.should == "/a/strange/path/test -auto-orient" + end + end +end diff -Nru ruby-mini-magick-3.6.0+gh/spec/lib/mini_magick/image_spec.rb ruby-mini-magick-3.7.0/spec/lib/mini_magick/image_spec.rb --- ruby-mini-magick-3.6.0+gh/spec/lib/mini_magick/image_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-mini-magick-3.7.0/spec/lib/mini_magick/image_spec.rb 2013-11-26 01:14:08.000000000 +0000 @@ -0,0 +1,359 @@ +require 'spec_helper' +require 'pathname' +require 'tempfile' + +MiniMagick.processor = 'mogrify' + +describe MiniMagick::Image do + describe "ported from testunit", :ported => true do + it 'reads image from blob' do + File.open(SIMPLE_IMAGE_PATH, "rb") do |f| + image = MiniMagick::Image.read(f.read) + image.valid?.should be true + image.destroy! + end + end + + it 'reads image from tempfile', :if => !MiniMagick::Utilities.windows? do + tempfile = Tempfile.new('magick') + + File.open(SIMPLE_IMAGE_PATH, 'rb') do |f| + tempfile.write(f.read) + tempfile.rewind + end + + image = MiniMagick::Image.read(tempfile) + image.valid?.should be true + image.destroy! + end + + it 'opens image' do + image = MiniMagick::Image.open(SIMPLE_IMAGE_PATH) + image.valid?.should be true + image.destroy! + end + + it 'reads image from buffer' do + buffer = StringIO.new File.open(SIMPLE_IMAGE_PATH,"rb") { |f| f.read } + image = MiniMagick::Image.read(buffer) + image.valid?.should be true + image.destroy! + end + + it 'creates an image' do + expect do + image = MiniMagick::Image.create do |f| + #Had to replace the old File.read with the following to work across all platforms + f.write(File.open(SIMPLE_IMAGE_PATH,"rb") { |f| f.read }) + end + image.destroy! + end.to_not raise_error + end + + it 'loads a new image' do + expect do + image = MiniMagick::Image.new(SIMPLE_IMAGE_PATH) + image.destroy! + end.to_not raise_error + end + + it 'loads remote image' do + image = MiniMagick::Image.open("http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png") + image.valid?.should be true + image.destroy! + end + + it 'loads remote image with complex url' do + image = MiniMagick::Image.open("http://a0.twimg.com/a/1296609216/images/fronts/logo_withbird_home.png?extra=foo&plus=bar") + image.valid?.should be true + image.destroy! + end + + it 'reformats an image with a given extension' do + expect do + image = MiniMagick::Image.open(CAP_EXT_PATH) + image.format "jpg" + end.to_not raise_error + end + + it 'opens and writes an image' do + output_path = "output.gif" + begin + image = MiniMagick::Image.new(SIMPLE_IMAGE_PATH) + image.write output_path + + File.exists?(output_path).should be true + ensure + File.delete output_path + end + image.destroy! + end + + it 'opens and writes an image with space in its filename' do + output_path = "test output.gif" + begin + image = MiniMagick::Image.new(SIMPLE_IMAGE_PATH) + image.write output_path + + File.exists?(output_path).should be true + ensure + File.delete output_path + end + image.destroy! + end + + it 'writes an image with stream' do + stream = StringIO.new + image = MiniMagick::Image.open(SIMPLE_IMAGE_PATH) + image.write("#{Dir.tmpdir}/foo.gif") + image.write(stream) + MiniMagick::Image.read(stream.string).valid?.should be true + image.destroy! + end + + it 'tells when an image is invalid' do + image = MiniMagick::Image.new(NOT_AN_IMAGE_PATH) + image.valid?.should be false + image.destroy! + end + + it "raises error when opening a file that isn't an image" do + expect do + image = MiniMagick::Image.open(NOT_AN_IMAGE_PATH) + image.destroy + end.to raise_error(MiniMagick::Invalid) + end + + it 'inspects image meta info' do + image = MiniMagick::Image.new(SIMPLE_IMAGE_PATH) + image[:width].should be 150 + image[:height].should be 55 + image[:dimensions].should == [150, 55] + image[:colorspace].should be_an_instance_of(String) + image[:format].should match(/^gif$/i) + image.destroy! + end + + it 'inspects an erroneus image meta info' do + image = MiniMagick::Image.new(ERRONEOUS_IMAGE_PATH) + image[:width].should be 10 + image[:height].should be 10 + image[:dimensions].should == [10, 10] + image[:format].should == 'JPEG' + image.destroy! + end + + it 'inspects meta info from tiff images' do + image = MiniMagick::Image.new(TIFF_IMAGE_PATH) + image[:format].to_s.downcase.should == 'tiff' + image[:width].should be 50 + image[:height].should be 41 + image.destroy! + end + + it 'inspects a gif with jpg format correctly' do + image = MiniMagick::Image.new(GIF_WITH_JPG_EXT) + image[:format].to_s.downcase.should == 'gif' + image.destroy! + end + + it 'resizes an image correctly' do + image = MiniMagick::Image.open(SIMPLE_IMAGE_PATH) + image.resize "20x30!" + + image[:width].should be 20 + image[:height].should be 30 + image[:format].should match(/^gif$/i) + image.destroy! + end + + it 'resizes an image with minimum dimensions' do + image = MiniMagick::Image.open(SIMPLE_IMAGE_PATH) + original_width, original_height = image[:width], image[:height] + image.resize "#{original_width + 10}x#{original_height + 10}>" + + image[:width].should be original_width + image[:height].should be original_height + image.destroy! + end + + it 'combines options to create an image with resize and blur' do + image = MiniMagick::Image.open(SIMPLE_IMAGE_PATH) + image.combine_options do |c| + c.resize "20x30!" + c.blur "50" + end + + image[:width].should be 20 + image[:height].should be 30 + image[:format].should match(/^gif$/i) + image.destroy! + end + + it "combines options to create an image even with minuses symbols on it's name it" do + image = MiniMagick::Image.open(SIMPLE_IMAGE_PATH) + background = "#000000" + expect do + image.combine_options do |c| + c.draw "image Over 0,0 10,10 '#{MINUS_IMAGE_PATH}'" + c.thumbnail "300x500>" + c.background background + end + end.to_not raise_error + image.destroy! + end + + it "inspects the EXIF of an image" do + image = MiniMagick::Image.open(EXIF_IMAGE_PATH) + image["exif:ExifVersion"].should == '0220' + image = MiniMagick::Image.open(SIMPLE_IMAGE_PATH) + image["EXIF:ExifVersion"].should == '' + image.destroy! + end + + it 'inspects the original at of an image' do + image = MiniMagick::Image.open(EXIF_IMAGE_PATH) + image[:original_at].should == Time.local('2005', '2', '23', '23', '17', '24') + image = MiniMagick::Image.open(SIMPLE_IMAGE_PATH) + image[:original_at].should be nil + image.destroy! + end + + it 'has the same path for tempfile and image' do + image = MiniMagick::Image.open(TIFF_IMAGE_PATH) + image.instance_eval("@tempfile.path").should == image.path + image.destroy! + end + + it 'has the tempfile at path after format' do + image = MiniMagick::Image.open(TIFF_IMAGE_PATH) + image.format('png') + File.exists?(image.path).should be true + image.destroy! + end + + it "hasn't previous tempfile at path after format" do + image = MiniMagick::Image.open(TIFF_IMAGE_PATH) + before = image.path.dup + image.format('png') + File.exist?(before).should be false + image.destroy! + end + + it "changes the format of image with special characters", :if => !MiniMagick::Utilities.windows? do + tempfile = Tempfile.new('magick with special! "chars\'') + + File.open(SIMPLE_IMAGE_PATH, 'rb') do |f| + tempfile.write(f.read) + tempfile.rewind + end + + image = MiniMagick::Image.new(tempfile.path) + image.format('png') + File.exists?(image.path).should be true + image.destroy! + + File.delete(image.path) + tempfile.unlink + end + + it "raises exception when calling wrong method" do + image = MiniMagick::Image.open(TIFF_IMAGE_PATH) + expect { image.to_blog }.to raise_error(NoMethodError) + image.to_blob + image.destroy! + end + + it "can create a composite of two images" do + if MiniMagick.valid_version_installed? + image = MiniMagick::Image.open(EXIF_IMAGE_PATH) + result = image.composite(MiniMagick::Image.open(TIFF_IMAGE_PATH)) do |c| + c.gravity "center" + end + File.exists?(result.path).should be true + else + puts "Need at least version #{MiniMagick.minimum_image_magick_version} of ImageMagick" + end + end + + # https://github.com/minimagick/minimagick/issues/8 + it "has issue 8 fixed" do + image = MiniMagick::Image.open(SIMPLE_IMAGE_PATH) + expect do + image.combine_options do |c| + c.sample "50%" + c.rotate "-90>" + end + end.to_not raise_error + image.destroy! + end + + # https://github.com/minimagick/minimagick/issues/8 + it 'has issue 15 fixed' do + expect do + image = MiniMagick::Image.open(Pathname.new(SIMPLE_IMAGE_PATH)) + output = Pathname.new("test.gif") + image.write(output) + end.to_not raise_error + FileUtils.rm("test.gif") + end + + # https://github.com/minimagick/minimagick/issues/37 + it 'respects the language set' do + original_lang = ENV["LANG"] + ENV["LANG"] = "fr_FR.UTF-8" + + expect do + image = MiniMagick::Image.open(NOT_AN_IMAGE_PATH) + image.destroy + end.to raise_error(MiniMagick::Invalid) + + ENV["LANG"] = original_lang + end + + it 'can import pixels with default format' do + columns = 325 + rows = 200 + depth = 16 # 16 bits (2 bytes) per pixel + map = 'gray' + pixels = Array.new(columns*rows) {|i| i} + blob = pixels.pack("S*") # unsigned short, native byte order + image = MiniMagick::Image.import_pixels(blob, columns, rows, depth, map) + image.valid?.should be true + image[:format].to_s.downcase.should == 'png' + image[:width].should == columns + image[:height].should == rows + image.write("#{Dir.tmpdir}/imported_pixels_image.png") + end + + it 'can import pixels with custom format' do + columns = 325 + rows = 200 + depth = 16 # 16 bits (2 bytes) per pixel + map = 'gray' + format = 'jpeg' + pixels = Array.new(columns*rows) {|i| i} + blob = pixels.pack("S*") # unsigned short, native byte order + image = MiniMagick::Image.import_pixels(blob, columns, rows, depth, map, format) + image.valid?.should be true + image[:format].to_s.downcase.should == format + image[:width].should == columns + image[:height].should == rows + image.write("#{Dir.tmpdir}/imported_pixels_image." + format) + end + + it 'loads mimetype correctly' do + gif = MiniMagick::Image.open(SIMPLE_IMAGE_PATH) + jpeg = MiniMagick::Image.open(EXIF_IMAGE_PATH) + png = MiniMagick::Image.open(PNG_PATH) + tiff = MiniMagick::Image.open(TIFF_IMAGE_PATH) + hidden_gif = MiniMagick::Image.open(GIF_WITH_JPG_EXT) + + gif.mime_type.should == "image/gif" + jpeg.mime_type.should == "image/jpeg" + png.mime_type.should == "image/png" + tiff.mime_type.should == "image/tiff" + hidden_gif.mime_type == "image/gif" + end + end +end diff -Nru ruby-mini-magick-3.6.0+gh/spec/lib/mini_magick_spec.rb ruby-mini-magick-3.7.0/spec/lib/mini_magick_spec.rb --- ruby-mini-magick-3.6.0+gh/spec/lib/mini_magick_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-mini-magick-3.7.0/spec/lib/mini_magick_spec.rb 2013-11-26 01:14:08.000000000 +0000 @@ -0,0 +1,57 @@ +require 'spec_helper' + +describe MiniMagick do + context '.choose_processor' do + it "identifies when mogrify exists" do + MiniMagick::Utilities.expects(:which).with('mogrify').returns('/usr/bin/mogrify\n') + MiniMagick.choose_processor.should == 'mogrify' + end + + it "identifies when gm exists" do + MiniMagick::Utilities.expects(:which).with('mogrify').returns('') + MiniMagick::Utilities.expects(:which).with('gm').returns('/usr/bin/gm\n') + MiniMagick.choose_processor.should == 'gm' + end + end + + context '.mogrify?' do + it "checks if minimagick is using mogrify" do + MiniMagick.processor = 'mogrify' + MiniMagick.mogrify?.should == true + end + + it "checks if minimagick isn't using mogrify" do + MiniMagick.processor = 'gm' + MiniMagick.mogrify?.should == false + end + + it "sets the processor if it's not set" do + MiniMagick.processor = nil + MiniMagick::Utilities.expects(:which).with('mogrify').returns('/usr/bin/mogrify\n') + MiniMagick.mogrify? + + MiniMagick.processor = 'mogrify' + end + end + + context '.gm?' do + it "checks if minimagick is using gm" do + MiniMagick.processor = 'gm' + MiniMagick.gm?.should == true + end + + it "checks if minimagick isn't using gm" do + MiniMagick.processor = 'mogrify' + MiniMagick.gm?.should == false + end + + it "sets the processor if it's not set" do + MiniMagick.processor = nil + MiniMagick::Utilities.expects(:which).with('mogrify').returns('') + MiniMagick::Utilities.expects(:which).with('gm').returns('/usr/bin/gm\n') + MiniMagick.gm? + + MiniMagick.processor = 'gm' + end + end +end diff -Nru ruby-mini-magick-3.6.0+gh/spec/spec_helper.rb ruby-mini-magick-3.7.0/spec/spec_helper.rb --- ruby-mini-magick-3.6.0+gh/spec/spec_helper.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-mini-magick-3.7.0/spec/spec_helper.rb 2013-11-26 01:14:08.000000000 +0000 @@ -0,0 +1,26 @@ +require 'rubygems' +require 'bundler/setup' +require 'rspec' +require 'mocha/api' + +require 'mini_magick' + +RSpec.configure do |config| + config.mock_framework = :mocha + config.color_enabled = true + config.formatter = 'documentation' +end + +# Image files from testunit port to RSpec +test_files = File.expand_path(File.dirname(__FILE__) + "/files") +SIMPLE_IMAGE_PATH = test_files + "/simple.gif" +MINUS_IMAGE_PATH = test_files + "/simple-minus.gif" +TIFF_IMAGE_PATH = test_files + "/leaves (spaced).tiff" +NOT_AN_IMAGE_PATH = test_files + "/not_an_image.php" +GIF_WITH_JPG_EXT = test_files + "/actually_a_gif.jpg" +EXIF_IMAGE_PATH = test_files + "/trogdor.jpg" +CAP_EXT_PATH = test_files + "/trogdor_capitalized.JPG" +ANIMATION_PATH = test_files + "/animation.gif" +PNG_PATH = test_files + "/png.png" +COMP_IMAGE_PATH = test_files + "/composited.jpg" +ERRONEOUS_IMAGE_PATH = test_files + "/erroneous.jpg" diff -Nru ruby-mini-magick-3.6.0+gh/test/command_builder_test.rb ruby-mini-magick-3.7.0/test/command_builder_test.rb --- ruby-mini-magick-3.6.0+gh/test/command_builder_test.rb 2013-05-21 02:40:21.000000000 +0000 +++ ruby-mini-magick-3.7.0/test/command_builder_test.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ -require 'test_helper' - -class CommandBuilderTest < Test::Unit::TestCase - include MiniMagick - - def setup - @processor_path = MiniMagick.processor_path - @processor = MiniMagick.processor - end - - def teardown - MiniMagick.processor_path = @processor_path - MiniMagick.processor = @processor - end - - def test_basic - c = CommandBuilder.new("test") - c.resize "30x40" - assert_equal '-resize 30x40', c.args.join(" ") - end - - def test_full_command - c = CommandBuilder.new("test") - c.resize "30x40" - assert_equal "test -resize 30x40", c.command - end - - def test_complicated - c = CommandBuilder.new("test") - c.resize "30x40" - c.alpha "1 3 4" - c.resize "mome fingo" - assert_equal '-resize 30x40 -alpha 1\ 3\ 4 -resize mome\ fingo', c.args.join(" ") - end - - def test_plus_modifier_and_multiple_options - c = CommandBuilder.new("test") - c.distort.+ 'srt', '0.6 20' - assert_equal '\+distort srt 0.6\ 20', c.args.join(" ") - end - - def test_valid_command - begin - c = CommandBuilder.new("test", "path") - c.input 2 - assert false - rescue NoMethodError - assert true - end - end - - def test_dashed - c = CommandBuilder.new("test") - c.auto_orient - assert_equal "-auto-orient", c.args.join(" ") - end - - def test_dashed_via_send - c = CommandBuilder.new("test") - c.send("auto-orient") - assert_equal "-auto-orient", c.args.join(" ") - end - - def test_canvas - c = CommandBuilder.new('test') - c.canvas 'black' - assert_equal "canvas:black", c.args.join - end - - def test_set - c = CommandBuilder.new("test") - c.set "colorspace RGB" - assert_equal 'test -set colorspace\ RGB', c.command - end - - def test_processor_path - MiniMagick.processor_path = "/a/strange/path" - c = CommandBuilder.new('test') - c.auto_orient - assert_equal c.command, "/a/strange/path/test -auto-orient" - end - - def test_processor_path_with_processor - MiniMagick.processor_path = "/a/strange/path" - MiniMagick.processor = "processor" - c = CommandBuilder.new('test') - c.auto_orient - assert_equal c.command, "/a/strange/path/processor test -auto-orient" - end -end Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/test/files/actually_a_gif.jpg and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/test/files/actually_a_gif.jpg differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/test/files/animation.gif and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/test/files/animation.gif differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/test/files/composited.jpg and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/test/files/composited.jpg differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/test/files/erroneous.jpg and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/test/files/erroneous.jpg differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/test/files/leaves (spaced).tiff and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/test/files/leaves (spaced).tiff differ diff -Nru ruby-mini-magick-3.6.0+gh/test/files/not_an_image.php ruby-mini-magick-3.7.0/test/files/not_an_image.php --- ruby-mini-magick-3.6.0+gh/test/files/not_an_image.php 2013-05-21 02:40:21.000000000 +0000 +++ ruby-mini-magick-3.7.0/test/files/not_an_image.php 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ - \ No newline at end of file Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/test/files/png.png and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/test/files/png.png differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/test/files/simple-minus.gif and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/test/files/simple-minus.gif differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/test/files/simple.gif and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/test/files/simple.gif differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/test/files/special! "chars'.gif and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/test/files/special! "chars'.gif differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/test/files/trogdor.jpg and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/test/files/trogdor.jpg differ Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/test/files/trogdor_capitalized.JPG and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/test/files/trogdor_capitalized.JPG differ diff -Nru ruby-mini-magick-3.6.0+gh/test/image_test.rb ruby-mini-magick-3.7.0/test/image_test.rb --- ruby-mini-magick-3.6.0+gh/test/image_test.rb 2013-05-21 02:40:21.000000000 +0000 +++ ruby-mini-magick-3.7.0/test/image_test.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,384 +0,0 @@ -require 'test_helper' -require 'digest/md5' - -#MiniMagick.processor = :gm - -class ImageTest < Test::Unit::TestCase - include MiniMagick - include MiniMagickTestFiles - - def test_image_from_blob - File.open(SIMPLE_IMAGE_PATH, "rb") do |f| - image = Image.read(f.read) - assert image.valid? - image.destroy! - end - end - - def test_image_from_tempfile - tempfile = Tempfile.new('magick') - - File.open(SIMPLE_IMAGE_PATH, 'rb') do |f| - tempfile.write(f.read) - tempfile.rewind - end - - image = Image.read(tempfile) - assert image.valid? - image.destroy! - end - - def test_image_open - image = Image.open(SIMPLE_IMAGE_PATH) - assert image.valid? - image.destroy! - end - - def test_image_io_reading -# buffer = StringIO.new(File.read(SIMPLE_IMAGE_PATH)) #This way does not work properly on windows - buffer = StringIO.new File.open(SIMPLE_IMAGE_PATH,"rb") { |f| f.read } #This way works the same on all platforms - image = Image.read(buffer) - assert image.valid? - image.destroy! - end - - def test_image_create - image = Image.create do |f| - #Had to replace the old File.read with the following to work across all platforms - f.write(File.open(SIMPLE_IMAGE_PATH,"rb") { |f| f.read }) - end - image.destroy! - end - - def test_image_new - image = Image.new(SIMPLE_IMAGE_PATH) - image.destroy! - end - - def test_remote_image - image = Image.open("http://upload.wikimedia.org/wikipedia/en/b/bc/Wiki.png") - assert image.valid? - image.destroy! - end - - def test_remote_image_with_complex_url - image = Image.open("http://a0.twimg.com/a/1296609216/images/fronts/logo_withbird_home.png?extra=foo&plus=bar") - assert image.valid? - image.destroy! - end - - def test_reformat_with_capitalized_extension - image = Image.open(CAP_EXT_PATH) - image.format "jpg" - end - - def test_image_write - output_path = "output.gif" - begin - image = Image.new(SIMPLE_IMAGE_PATH) - image.write output_path - - assert File.exists?(output_path) - ensure - File.delete output_path - end - image.destroy! - end - - def test_image_write_with_space_in_output_path - output_path = "test output.gif" - begin - image = Image.new(SIMPLE_IMAGE_PATH) - image.write output_path - - assert File.exists?(output_path) - ensure - File.delete output_path - end - image.destroy! - end - - def test_image_write_with_stream - stream = StringIO.new - image = Image.open(SIMPLE_IMAGE_PATH) - image.write("#{Dir.tmpdir}/foo.gif") - image.write(stream) -# assert Image.read(stream.string).valid? - image.destroy! - end - - def test_not_an_image - image = Image.new(NOT_AN_IMAGE_PATH) - assert_equal false, image.valid? - image.destroy! - end - - def test_throw_on_opening_not_an_image - assert_raise(MiniMagick::Invalid) do - image = Image.open(NOT_AN_IMAGE_PATH) - image.destroy - end - end - - def test_image_meta_info - image = Image.new(SIMPLE_IMAGE_PATH) - assert_equal 150, image[:width] - assert_equal 55, image[:height] - assert_equal [150, 55], image[:dimensions] - assert_true String == image[:colorspace].class - assert_match(/^gif$/i, image[:format]) - image.destroy! - end - - def test_erroneous_image_meta_info - image = Image.new(ERRONEOUS_IMAGE_PATH) - assert_equal 10, image[:width] - assert_equal 10, image[:height] - assert_equal [10, 10], image[:dimensions] - assert_equal('JPEG', image[:format]) - image.destroy! - end - - def test_tiff - image = Image.new(TIFF_IMAGE_PATH) - assert_equal "tiff", image[:format].to_s.downcase - assert_equal 50, image[:width] - assert_equal 41, image[:height] - image.destroy! - end - - def test_gif_with_jpg_format - image = Image.new(GIF_WITH_JPG_EXT) - assert_equal "gif", image[:format].to_s.downcase - image.destroy! - end - - def test_image_resize - image = Image.open(SIMPLE_IMAGE_PATH) - image.resize "20x30!" - - assert_equal 20, image[:width] - assert_equal 30, image[:height] - assert_match(/^gif$/i, image[:format]) - image.destroy! - end - - def test_image_resize_with_minimum - image = Image.open(SIMPLE_IMAGE_PATH) - original_width, original_height = image[:width], image[:height] - image.resize "#{original_width + 10}x#{original_height + 10}>" - - assert_equal original_width, image[:width] - assert_equal original_height, image[:height] - image.destroy! - end - - def test_image_combine_options_resize_blur - image = Image.open(SIMPLE_IMAGE_PATH) - image.combine_options do |c| - c.resize "20x30!" - c.blur "50" - end - - assert_equal 20, image[:width] - assert_equal 30, image[:height] - assert_match(/^gif$/i, image[:format]) - image.destroy! - end - - def test_image_combine_options_with_filename_with_minusses_in_it - image = Image.open(SIMPLE_IMAGE_PATH) - background = "#000000" - assert_nothing_raised do - image.combine_options do |c| - c.draw "image Over 0,0 10,10 '#{MINUS_IMAGE_PATH}'" - c.thumbnail "300x500>" - c.background background - end - end - image.destroy! - end - - def test_image_combine_options_with_filename_with_special_characters_in_it - image = Image.new(SPECIAL_CHARS_IMAGE_PATH) - assert_nothing_raised do - image.combine_options("identify") do |c| - c.ping - end - end - image.destroy! - end - - def test_exif - image = Image.open(EXIF_IMAGE_PATH) - assert_equal('0220', image["exif:ExifVersion"]) - image = Image.open(SIMPLE_IMAGE_PATH) - assert_equal('', image["EXIF:ExifVersion"]) - image.destroy! - end - - def test_original_at - image = Image.open(EXIF_IMAGE_PATH) - assert_equal(Time.local('2005', '2', '23', '23', '17', '24'), image[:original_at]) - image = Image.open(SIMPLE_IMAGE_PATH) - assert_nil(image[:original_at]) - image.destroy! - end - - def test_tempfile_at_path - image = Image.open(TIFF_IMAGE_PATH) - assert_equal image.path, image.instance_eval("@tempfile.path") - image.destroy! - end - - def test_tempfile_at_path_after_format - image = Image.open(TIFF_IMAGE_PATH) - image.format('png') - assert File.exists?(image.path) - image.destroy! - end - - def test_previous_tempfile_deleted_after_format - image = Image.open(TIFF_IMAGE_PATH) - before = image.path.dup - image.format('png') - assert !File.exist?(before) - image.destroy! - end - - def test_change_format_of_image_with_special_characters - tempfile = Tempfile.new('magick with special! "chars\'') - - File.open(SIMPLE_IMAGE_PATH, 'rb') do |f| - tempfile.write(f.read) - tempfile.rewind - end - - image = Image.new(tempfile.path) - image.format('png') - assert File.exists?(image.path) - image.destroy! - - File.delete(image.path) - tempfile.unlink - end - - def test_bad_method_bug - image = Image.open(TIFF_IMAGE_PATH) - begin - image.to_blog - rescue NoMethodError - assert true - end - image.to_blob - assert true #we made it this far without error - image.destroy! - end - - def test_simple_composite - if MiniMagick.valid_version_installed? - image = Image.open(EXIF_IMAGE_PATH) - result = image.composite(Image.open(TIFF_IMAGE_PATH)) do |c| - c.gravity "center" - end - assert_true File.exists?(result.path) - else - puts "Need at least version #{MiniMagick.minimum_image_magick_version} of ImageMagick" - end - end - - # http://github.com/probablycorey/mini_magick/issues#issue/8 - def test_issue_8 - image = Image.open(SIMPLE_IMAGE_PATH) - assert_nothing_raised do - image.combine_options do |c| - c.sample "50%" - c.rotate "-90>" - end - end - image.destroy! - end - - # http://github.com/probablycorey/mini_magick/issues#issue/15 - def test_issue_15 - image = Image.open(Pathname.new(SIMPLE_IMAGE_PATH)) - output = Pathname.new("test.gif") - image.write(output) - ensure - FileUtils.rm("test.gif") - end - - # https://github.com/probablycorey/mini_magick/issues/37 - def test_nonstandard_locale - original_lang = ENV["LANG"] - ENV["LANG"] = "fr_FR.UTF-8" - - # This test should break - test_throw_on_opening_not_an_image - ensure - ENV["LANG"] = original_lang - end - - def test_poop - img = MiniMagick::Image.open(SIMPLE_IMAGE_PATH) - img.gravity "Center" - img.crop "480x480" - img.resize "250x250" - img.write "#{Dir.tmpdir}/output.png" - end - - def test_throw_format_error - image = Image.open(SIMPLE_IMAGE_PATH) - assert_raise MiniMagick::Error do - image.combine_options do |c| - c.format "png" - end - end - image.destroy! - end - - def test_import_pixels_default_format - columns = 325 - rows = 200 - depth = 16 # 16 bits (2 bytes) per pixel - map = 'gray' - pixels = Array.new(columns*rows) {|i| i} - blob = pixels.pack("S*") # unsigned short, native byte order - image = Image.import_pixels(blob, columns, rows, depth, map) - assert image.valid? - assert_equal "png", image[:format].to_s.downcase - assert_equal columns, image[:width] - assert_equal rows, image[:height] - image.write("#{Dir.tmpdir}/imported_pixels_image.png") - end - - def test_import_pixels_custom_format - columns = 325 - rows = 200 - depth = 16 # 16 bits (2 bytes) per pixel - map = 'gray' - format = 'jpeg' - pixels = Array.new(columns*rows) {|i| i} - blob = pixels.pack("S*") # unsigned short, native byte order - image = Image.import_pixels(blob, columns, rows, depth, map, format) - assert image.valid? - assert_equal format, image[:format].to_s.downcase - assert_equal columns, image[:width] - assert_equal rows, image[:height] - image.write("#{Dir.tmpdir}/imported_pixels_image." + format) - end - - def test_mime_type - gif = Image.open(SIMPLE_IMAGE_PATH) - jpeg = Image.open(EXIF_IMAGE_PATH) - png = Image.open(PNG_PATH) - tiff = Image.open(TIFF_IMAGE_PATH) - hidden_gif = Image.open(GIF_WITH_JPG_EXT) - - assert_equal "image/gif", gif.mime_type - assert_equal "image/jpeg", jpeg.mime_type - assert_equal "image/png", png.mime_type - assert_equal "image/tiff", tiff.mime_type - assert_equal "image/gif", hidden_gif.mime_type - end -end Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/test/leaves (spaced).tiff and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/test/leaves (spaced).tiff differ diff -Nru ruby-mini-magick-3.6.0+gh/test/test_helper.rb ruby-mini-magick-3.7.0/test/test_helper.rb --- ruby-mini-magick-3.6.0+gh/test/test_helper.rb 2013-05-21 02:40:21.000000000 +0000 +++ ruby-mini-magick-3.7.0/test/test_helper.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -require 'rubygems' -require 'test/unit' -require 'pathname' -require 'tempfile' -require File.expand_path('../../lib/mini_magick', __FILE__) - - -module MiniMagickTestFiles - test_files = File.expand_path(File.dirname(__FILE__) + "/files") - SIMPLE_IMAGE_PATH = test_files + "/simple.gif" - MINUS_IMAGE_PATH = test_files + "/simple-minus.gif" - SPECIAL_CHARS_IMAGE_PATH = test_files + "/special! \"chars'.gif" - TIFF_IMAGE_PATH = test_files + "/leaves (spaced).tiff" - NOT_AN_IMAGE_PATH = test_files + "/not_an_image.php" - GIF_WITH_JPG_EXT = test_files + "/actually_a_gif.jpg" - EXIF_IMAGE_PATH = test_files + "/trogdor.jpg" - CAP_EXT_PATH = test_files + "/trogdor_capitalized.JPG" - ANIMATION_PATH = test_files + "/animation.gif" - PNG_PATH = test_files + "/png.png" - COMP_IMAGE_PATH = test_files + "/composited.jpg" - ERRONEOUS_IMAGE_PATH = test_files + "/erroneous.jpg" -end \ No newline at end of file Binary files /tmp/eumykWxCBU/ruby-mini-magick-3.6.0+gh/test/trogdor_capitalized.JPG and /tmp/ccPTldKqDh/ruby-mini-magick-3.7.0/test/trogdor_capitalized.JPG differ