#!/usr/bin/env ruby -w

require 'rmagick'
require 'test/unit'
require 'test/unit/ui/console/testrunner'  unless RUBY_VERSION[/^1\.9|^2/]

# TODO: improve exif tests - need a benchmark image with EXIF data

class Image2_UT < Test::Unit::TestCase
  FreezeError = RUBY_VERSION[/^1\.9|^2/] ? RuntimeError : TypeError

  def setup
    @img = Magick::Image.new(20, 20)
  end

  def test_composite!
    img1 = Magick::Image.read(IMAGES_DIR+'/Button_0.gif').first
    img2 = Magick::Image.read(IMAGES_DIR+'/Button_1.gif').first
    assert_nothing_raised do
    res = img1.composite!(img2, Magick::NorthWestGravity, Magick::OverCompositeOp)
    assert_same(img1, res)
    end
    img1.freeze
    assert_raise(FreezeError) { img1.composite!(img2, Magick::NorthWestGravity, Magick::OverCompositeOp) }
  end

  def test_composite_affine
    affine = Magick::AffineMatrix.new(1, 0, 1, 0, 0, 0)
    img1 = Magick::Image.read(IMAGES_DIR+'/Button_0.gif').first
    img2 = Magick::Image.read(IMAGES_DIR+'/Button_1.gif').first
    assert_nothing_raised do
    res = img1.composite_affine(img2, affine)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
  end

  def test_composite_mathematics
    bg = Magick::Image.new(50, 50)
    fg = Magick::Image.new(50, 50) {self.background_color = 'black' }
    res = nil
    assert_nothing_raised { res = bg.composite_mathematics(fg, 1, 0, 0, 0, Magick::CenterGravity) }
    assert_instance_of(Magick::Image, res)
    assert_not_same(bg, res)
    assert_not_same(fg, res)
    assert_nothing_raised { res = bg.composite_mathematics(fg, 1, 0, 0, 0, 0.0, 0.0) }
    assert_nothing_raised { res = bg.composite_mathematics(fg, 1, 0, 0, 0, Magick::CenterGravity, 0.0, 0.0) }

    # too few arguments
    assert_raise(ArgumentError) { bg.composite_mathematics(fg, 1, 0, 0, 0) }
    # too many arguments
    assert_raise(ArgumentError) { bg.composite_mathematics(fg, 1, 0, 0, 0, Magick::CenterGravity, 0.0, 0.0, 'x') }
  end

  def test_composite_tiled
    bg = Magick::Image.new(200,200)
    fg = Magick::Image.new(50,100) { self.background_color = 'black' }
    res = nil
    assert_nothing_raised do
    res = bg.composite_tiled(fg)
    end
    assert_instance_of(Magick::Image, res)
    assert_not_same(bg, res)
    assert_not_same(fg, res)
    assert_nothing_raised { bg.composite_tiled!(fg) }
    assert_nothing_raised { bg.composite_tiled(fg, Magick::AtopCompositeOp) }
    assert_nothing_raised { bg.composite_tiled(fg, Magick::OverCompositeOp) }
    assert_nothing_raised { bg.composite_tiled(fg, Magick::RedChannel) }
    assert_nothing_raised { bg.composite_tiled(fg, Magick::RedChannel, Magick::GreenChannel) }

    fg.destroy!
    assert_raise(Magick::DestroyedImageError) { bg.composite_tiled(fg) }
  end

  def test_compress_colormap!
    # DirectClass images are converted to PseudoClass
    assert_equal(Magick::DirectClass, @img.class_type)
    assert_nothing_raised { @img.compress_colormap! }
    assert_equal(Magick::PseudoClass, @img.class_type)
    img = Magick::Image.read(IMAGES_DIR+'/Button_0.gif').first
    assert_equal(Magick::PseudoClass, @img.class_type)
    assert_nothing_raised { @img.compress_colormap! }
  end

  def test_contrast
    assert_nothing_raised do
    res = @img.contrast
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.contrast(true) }
    assert_raise(ArgumentError) { @img.contrast(true, 2) }
  end

  def test_contrast_stretch_channel
    assert_nothing_raised do
    res = @img.contrast_stretch_channel(25)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.contrast_stretch_channel(25, 50) }
    assert_nothing_raised { @img.contrast_stretch_channel('10%') }
    assert_nothing_raised { @img.contrast_stretch_channel('10%', '50%') }
    assert_nothing_raised { @img.contrast_stretch_channel(25, 50, Magick::RedChannel) }
    assert_nothing_raised { @img.contrast_stretch_channel(25, 50, Magick::RedChannel, Magick::GreenChannel) }
    assert_raise(TypeError) { @img.contrast_stretch_channel(25, 50, 'x') }
    assert_raise(ArgumentError) { @img.contrast_stretch_channel }
    assert_raise(ArgumentError) { @img.contrast_stretch_channel('x') }
    assert_raise(ArgumentError) { @img.contrast_stretch_channel(25, 'x') }
  end

  def test_convolve
    kernel = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
    order = 3
    assert_nothing_raised do
    res = @img.convolve(order, kernel)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_raise(ArgumentError) { @img.convolve }
    assert_raise(ArgumentError) { @img.convolve(order) }
    assert_raise(IndexError) { @img.convolve(5, kernel) }
    assert_raise(IndexError) { @img.convolve(order, 'x') }
    assert_raise(TypeError) { @img.convolve(3, [1.0, 1.0, 1.0, 1.0, 'x', 1.0, 1.0, 1.0, 1.0]) }
    assert_raise(Magick::ImageMagickError) { @img.convolve(-1, [1.0, 1.0, 1.0, 1.0]) }
  end

  def test_convolve_channel
    assert_raise(ArgumentError) { @img.convolve_channel }
    assert_raise(ArgumentError) { @img.convolve_channel(3) }
    kernel = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
    order = 3
    assert_nothing_raised do
    res = @img.convolve_channel(order, kernel, Magick::RedChannel)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end

    assert_nothing_raised { @img.convolve_channel(order, kernel, Magick::RedChannel, Magick:: BlueChannel) }
    assert_raise(TypeError) { @img.convolve_channel(order, kernel, Magick::RedChannel, 2) }
  end

  def test_copy
    assert_nothing_raised do
    ditto = @img.copy
    assert_equal(@img, ditto)
    end
    ditto = @img.copy
    assert_equal(@img.tainted?, ditto.tainted?)
    @img.taint
    ditto = @img.copy
    assert_equal(@img.tainted?, ditto.tainted?)
  end

  def test_crop
    assert_raise(ArgumentError) { @img.crop }
    assert_raise(ArgumentError) { @img.crop(0, 0) }
    assert_nothing_raised do
    res = @img.crop(0, 0, @img.columns/2, @img.rows/2)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    gravity = [
    Magick::NorthEastGravity,
    Magick::EastGravity,
    Magick::SouthWestGravity,
    Magick::SouthGravity,
    Magick::SouthEastGravity]

    # 3-argument form
    gravity.each do |grav|
    assert_nothing_raised { @img.crop(grav, @img.columns/2, @img.rows/2) }
    end
    assert_raise(TypeError) { @img.crop(2, @img.columns/2, @img.rows/2) }
    assert_raise(TypeError) { @img.crop(Magick::NorthWestGravity, @img.columns/2, @img.rows/2, 2) }

    # 4-argument form
    assert_raise(TypeError) { @img.crop(0, 0, @img.columns/2, 'x') }
    assert_raise(TypeError) { @img.crop(0, 0, 'x', @img.rows/2) }
    assert_raise(TypeError) { @img.crop(0, 'x', @img.columns/2, @img.rows/2) }
    assert_raise(TypeError) { @img.crop('x', 0, @img.columns/2, @img.rows/2) }
    assert_raise(TypeError) { @img.crop(0, 0, @img.columns/2, @img.rows/2, 2) }

    # 5-argument form
    gravity.each do |grav|
    assert_nothing_raised { @img.crop(grav, 0, 0, @img.columns/2, @img.rows/2) }
    end

    assert_raise(ArgumentError) { @img.crop(Magick::NorthWestGravity, 0, 0, @img.columns/2, @img.rows/2, 2) }
  end

  def test_crop!
    assert_nothing_raised do
    res = @img.crop!(0, 0, @img.columns/2, @img.rows/2)
    assert_same(@img, res)
    end
  end

  def test_cycle_colormap
    assert_nothing_raised do
    res = @img.cycle_colormap(5)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    assert_equal(Magick::PseudoClass, res.class_type)
    end
  end

  def test_decipher         # tests encipher, too.
    res = res2 = nil
    assert_nothing_raised do
    res = @img.encipher 'passphrase'
    res2 = res.decipher 'passphrase'
    end
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    assert_equal(@img.columns, res.columns)
    assert_equal(@img.rows, res.rows)
    assert_instance_of(Magick::Image, res2)
    assert_not_same(@img, res2)
    assert_equal(@img.columns, res2.columns)
    assert_equal(@img.rows, res2.rows)
    assert_equal(@img, res2)
  end

  def test_define
    assert_nothing_raised { @img.define('deskew:auto-crop', 40) }
    assert_nothing_raised { @img.undefine('deskew:auto-crop') }
  end

  def test_deskew
    assert_nothing_raised do
    res = @img.deskew
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end

    assert_nothing_raised { @img.deskew(0.10) }
    assert_nothing_raised { @img.deskew('95%') }
    assert_raise(ArgumentError) { @img.deskew('x') }
    assert_raise(TypeError) {@img.deskew(0.40, 'x') }
    assert_raise(ArgumentError) {@img.deskew(0.40, 20, [1]) }
  end

  def test_despeckle
    assert_nothing_raised do
    res = @img.despeckle
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
  end

  # ensure methods detect destroyed images
  def test_destroy
    methods = Magick::Image.instance_methods(false).sort
    if RUBY_VERSION[/^1\.9|^2/]
    methods -= [:__display__, :destroy!, :destroyed?, :inspect, :cur_image, :marshal_load]
    else
    methods -= %w{ __display__ destroy! destroyed? inspect cur_image  marshal_load}
    end

    assert_equal(false, @img.destroyed?)
    @img.destroy!
    assert_equal(true, @img.destroyed?)
    assert_raises(Magick::DestroyedImageError) { @img.check_destroyed }

    methods.each do |method|
    arity = @img.method(method).arity
    method = method.to_s

    case
    when method == '[]='
      assert_raises(Magick::DestroyedImageError) { @img['foo'] = 1 }
    when method == 'difference'
      other = Magick::Image.new(20,20)
      assert_raises(Magick::DestroyedImageError) { @img.difference(other) }
    when method == 'get_iptc_dataset'
      assert_raises(Magick::DestroyedImageError) { @img.get_iptc_dataset('x') }
    when method == 'profile!'
      assert_raises(Magick::DestroyedImageError) { @img.profile!('x', 'y') }
    when /=\Z/.match(method)
      assert_raises(Magick::DestroyedImageError) { @img.send(method, 1) }
    when arity == 0
      assert_raises(Magick::DestroyedImageError) { @img.send(method) }
    when arity < 0
      args = (1..(-arity)).to_a
      assert_raises(Magick::DestroyedImageError) { @img.send(method, *args) }
    when arity > 0
      args = (1..(arity)).to_a
      assert_raises(Magick::DestroyedImageError) { @img.send(method, *args) }
    else
      # Don't know how to test!
      flunk("don't know how to test method #{method}")
    end
    end
  end

  # ensure destroy! works
  def test_destroy2
    images = {}
    GC.disable

    Magick.trace_proc = proc do |which, id, addr, method|
    m = id.split(/ /)
    name = File.basename m[0]
    format = m[1]
    size = m[2]
    geometry = m[3]
    image_class = m[4]

    assert(which == :c || which == :d, "unexpected value for which: #{which}")
    assert_equal(:destroy!, method) if which == :d

    if which == :c
      assert(!images.has_key?(addr), 'duplicate image addresses')
      images[addr] = name
    else
      assert(images.has_key?(addr), 'destroying image that was not created')
      assert_equal(name, images[addr])
    end
    end

    unmapped = Magick::ImageList.new(IMAGES_DIR+'/Hot_Air_Balloons.jpg', IMAGES_DIR+'/Violin.jpg', IMAGES_DIR+'/Polynesia.jpg')
    map = Magick::ImageList.new 'netscape:'
    mapped = unmapped.map map, false
    unmapped.each {|i| i.destroy!}
    map.destroy!
    mapped.each {|i| i.destroy!}
  ensure
    GC.enable
    Magick.trace_proc = nil
  end

  def test_difference
    img1 = Magick::Image.read(IMAGES_DIR+'/Button_0.gif').first
    img2 = Magick::Image.read(IMAGES_DIR+'/Button_1.gif').first
    assert_nothing_raised do
    res = img1.difference(img2)
    assert_instance_of(Array, res)
    assert_equal(3, res.length)
    assert_instance_of(Float, res[0])
    assert_instance_of(Float, res[1])
    assert_instance_of(Float, res[2])
    end

    assert_raise(NoMethodError) { img1.difference(2) }
    img2.destroy!
    assert_raise(Magick::DestroyedImageError) { img1.difference(img2) }
  end

  def test_displace
    @img2 = Magick::Image.new(20,20) {self.background_color = 'black'}
    assert_nothing_raised { @img.displace(@img2, 25) }
    res = @img.displace(@img2, 25)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    assert_nothing_raised { @img.displace(@img2, 25, 25) }
    assert_nothing_raised { @img.displace(@img2, 25, 25, 10) }
    assert_nothing_raised { @img.displace(@img2, 25, 25, 10, 10) }
    assert_nothing_raised { @img.displace(@img2, 25, 25, Magick::CenterGravity) }
    assert_nothing_raised { @img.displace(@img2, 25, 25, Magick::CenterGravity, 10) }
    assert_nothing_raised { @img.displace(@img2, 25, 25, Magick::CenterGravity, 10, 10) }
    assert_raise(ArgumentError) { @img.displace }
    assert_raise(TypeError) { @img.displace(@img2, 'x') }
    assert_raise(TypeError) { @img.displace(@img2, 25, []) }
    assert_raise(TypeError) { @img.displace(@img2, 25, 25, 'x') }
    assert_raise(TypeError) { @img.displace(@img2, 25, 25, Magick::CenterGravity, 'x') }
    assert_raise(TypeError) { @img.displace(@img2, 25, 25, Magick::CenterGravity, 10, []) }

    @img2.destroy!
    assert_raise(Magick::DestroyedImageError) { @img.displace(@img2, 25, 25) }
  end

  def test_dissolve
    src = Magick::Image.new(@img.columns, @img.rows)
    src_list = Magick::ImageList.new
    src_list << src.copy
    assert_nothing_raised { @img.dissolve(src, 0.50) }
    assert_nothing_raised { @img.dissolve(src_list, 0.50) }
    assert_nothing_raised { @img.dissolve(src, '50%') }
    assert_nothing_raised { @img.dissolve(src, 0.50, 0.10) }
    assert_nothing_raised { @img.dissolve(src, 0.50, 0.10, 10) }
    assert_nothing_raised { @img.dissolve(src, 0.50, 0.10, Magick::NorthEastGravity) }
    assert_nothing_raised { @img.dissolve(src, 0.50, 0.10, Magick::NorthEastGravity, 10) }
    assert_nothing_raised { @img.dissolve(src, 0.50, 0.10, Magick::NorthEastGravity, 10, 10) }

    assert_raise(ArgumentError) { @img.dissolve(src, 'x') }
    assert_raise(ArgumentError) { @img.dissolve(src, 0.50, 'x') }
    assert_raise(TypeError) { @img.dissolve(src, 0.50, Magick::NorthEastGravity, 'x') }
    assert_raise(TypeError) { @img.dissolve(src, 0.50, Magick::NorthEastGravity, 10, 'x') }

    src.destroy!
    assert_raise(Magick::DestroyedImageError) { @img.dissolve(src, 0.50) }
  end

  def test_distort
    @img = Magick::Image.new(200, 200)
    assert_nothing_raised { @img.distort(Magick::AffineDistortion, [2,60, 2,60,     32,60, 32,60,    2,30, 17,35]) }
    assert_nothing_raised { @img.distort(Magick::AffineProjectionDistortion, [1,0,0,1,0,0]) }
    assert_nothing_raised { @img.distort(Magick::BilinearDistortion, [7,40, 4,30,   4,124, 4,123,   85,122, 100,123,   85,2, 100,30]) }
    assert_nothing_raised { @img.distort(Magick::PerspectiveDistortion, [7,40, 4,30,   4,124, 4,123,   85,122, 100,123,   85,2, 100,30]) }
    assert_nothing_raised { @img.distort(Magick::ScaleRotateTranslateDistortion, [28,24,  0.4,0.8  -110,  37.5,60]) }
    assert_raise(ArgumentError) { @img.distort }
    assert_raise(ArgumentError) { @img.distort(Magick::AffineDistortion) }
    assert_raise(TypeError) { @img.distort(1, [1]) }
  end

  def test_distortion_channel
    assert_nothing_raised do
    metric = @img.distortion_channel(@img, Magick::MeanAbsoluteErrorMetric)
    assert_instance_of(Float, metric)
    assert_equal(0.0, metric)
    end
    assert_nothing_raised { @img.distortion_channel(@img, Magick::MeanSquaredErrorMetric) }
    assert_nothing_raised { @img.distortion_channel(@img, Magick::PeakAbsoluteErrorMetric) }
    assert_nothing_raised { @img.distortion_channel(@img, Magick::PeakSignalToNoiseRatioMetric) }
    assert_nothing_raised { @img.distortion_channel(@img, Magick::RootMeanSquaredErrorMetric) }
    assert_nothing_raised { @img.distortion_channel(@img, Magick::MeanSquaredErrorMetric, Magick::RedChannel, Magick:: BlueChannel) }
    assert_raise(TypeError) { @img.distortion_channel(@img, 2) }
    assert_raise(TypeError) { @img.distortion_channel(@img, Magick::RootMeanSquaredErrorMetric, 2) }
    assert_raise(ArgumentError) { @img.distortion_channel }
    assert_raise(ArgumentError) { @img.distortion_channel(@img) }

    img = Magick::Image.new(20,20)
    img.destroy!
    assert_raise(Magick::DestroyedImageError) { @img.distortion_channel(img, Magick::MeanSquaredErrorMetric) }
  end

  def test_dup
    assert_nothing_raised do
    ditto = @img.dup
    assert_equal(@img, ditto)
    end
    ditto = @img.dup
    assert_equal(@img.tainted?, ditto.tainted?)
    @img.taint
    ditto = @img.dup
    assert_equal(@img.tainted?, ditto.tainted?)
  end

  def test_each_profile
    @img.iptc_profile = 'test profile'
    assert_nothing_raised do
    @img.each_profile do |name, value|
      assert_equal('iptc', name)
      # As of 6.3.1
      if IM_VERSION < Gem::Version.new('6.6.4') || (IM_VERSION == Gem::Version.new('6.6.4') && IM_REVISION < Gem::Version.new('5'))
      assert_equal("8BIM\004\004\000\000\000\000\001\340test profile", value)
      else
      assert_equal('test profile', value)
      end
    end
    end
  end

  def test_edge
    assert_nothing_raised do
    res = @img.edge
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.edge(2.0) }
    assert_raise(ArgumentError) { @img.edge(2.0, 2) }
    assert_raise(TypeError) { @img.edge('x') }
  end

  def test_emboss
    assert_nothing_raised do
    res = @img.emboss
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.emboss(1.0) }
    assert_nothing_raised { @img.emboss(1.0, 0.5) }
    assert_raise(ArgumentError) { @img.emboss(1.0, 0.5, 2) }
    assert_raise(TypeError) { @img.emboss(1.0, 'x') }
    assert_raise(TypeError) { @img.emboss('x', 1.0) }
  end

  def test_enhance
    assert_nothing_raised do
    res = @img.enhance
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
  end

  def test_equalize
    assert_nothing_raised do
    res = @img.equalize
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
  end

  def test_equalize_channel
    assert_nothing_raised do
    res = @img.equalize_channel
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.equalize_channel }
    assert_nothing_raised { @img.equalize_channel(Magick::RedChannel) }
    assert_nothing_raised { @img.equalize_channel(Magick::RedChannel, Magick::BlueChannel) }
    assert_raise(TypeError) { @img.equalize_channel(Magick::RedChannel, 2) }
  end

  def test_erase!
    assert_nothing_raised do
    res = @img.erase!
    assert_same(@img, res)
    end
  end

  def test_excerpt
    res = nil
    img = Magick::Image.new(200, 200)
    assert_nothing_raised { res = @img.excerpt(20,20,50,100) }
    assert_not_same(img, res)
    assert_equal(50, res.columns)
    assert_equal(100, res.rows)

    assert_nothing_raised { img.excerpt!(20,20,50,100) }
    assert_equal(50, img.columns)
    assert_equal(100, img.rows)
  end

  def test_export_pixels
    assert_nothing_raised do
    res = @img.export_pixels
    assert_instance_of(Array, res)
    assert_equal(@img.columns*@img.rows*'RGB'.length, res.length)
    res.each do |p|
      assert_kind_of(Integer, p)
    end
    end
    assert_nothing_raised { res = @img.export_pixels(0) }
    assert_nothing_raised { res = @img.export_pixels(0, 0) }
    assert_nothing_raised { res = @img.export_pixels(0, 0, 10) }
    assert_nothing_raised { res = @img.export_pixels(0, 0, 10, 10) }
    assert_nothing_raised do
    res = @img.export_pixels(0, 0, 10, 10, 'RGBA')
    assert_equal(10*10*'RGBA'.length, res.length)
    end
    assert_nothing_raised do
    res = @img.export_pixels(0, 0, 10, 10, 'I')
    assert_equal(10*10*'I'.length, res.length)
    end

    # too many arguments
    assert_raise(ArgumentError) { @img.export_pixels(0, 0, 10, 10, 'I', 2) }
  end

  def test_export_pixels_to_str
    assert_nothing_raised do
    res = @img.export_pixels_to_str
    assert_instance_of(String, res)
    assert_equal(@img.columns*@img.rows*'RGB'.length, res.length)
    end
    assert_nothing_raised { @img.export_pixels_to_str(0) }
    assert_nothing_raised { @img.export_pixels_to_str(0, 0) }
    assert_nothing_raised { @img.export_pixels_to_str(0, 0, 10) }
    assert_nothing_raised { @img.export_pixels_to_str(0, 0, 10, 10) }
    assert_nothing_raised do
    res = @img.export_pixels_to_str(0, 0, 10, 10, 'RGBA')
    assert_equal(10*10*'RGBA'.length, res.length)
    end
    assert_nothing_raised do
    res = @img.export_pixels_to_str(0, 0, 10, 10, 'I')
    assert_equal(10*10*'I'.length, res.length)
    end

    assert_nothing_raised do
    res = @img.export_pixels_to_str(0, 0, 10, 10, 'I', Magick::CharPixel)
    assert_equal(10*10*1, res.length)
    end
    assert_nothing_raised do
    res = @img.export_pixels_to_str(0, 0, 10, 10, 'I', Magick::ShortPixel)
    assert_equal(10*10*2, res.length)
    end
    assert_nothing_raised do
    res = @img.export_pixels_to_str(0, 0, 10, 10, 'I', Magick::IntegerPixel)
    assert_equal(10*10*4, res.length)
    end
    assert_nothing_raised do
    res = @img.export_pixels_to_str(0, 0, 10, 10, 'I', Magick::LongPixel)
    assert_equal(10*10*[1].pack('L!').length, res.length)
    end
    assert_nothing_raised do
    res = @img.export_pixels_to_str(0, 0, 10, 10, 'I', Magick::FloatPixel)
    assert_equal(10*10*4, res.length)
    end
    assert_nothing_raised do
    res = @img.export_pixels_to_str(0, 0, 10, 10, 'I', Magick::DoublePixel)
    assert_equal(10*10*8, res.length)
    end
    assert_nothing_raised { @img.export_pixels_to_str(0, 0, 10, 10, 'I', Magick::QuantumPixel) }

    # too many arguments
    assert_raise(ArgumentError) { @img.export_pixels_to_str(0, 0, 10, 10, 'I', Magick::QuantumPixel, 1) }
    # last arg s/b StorageType
    assert_raise(TypeError) { @img.export_pixels_to_str(0, 0, 10, 10, 'I', 2) }
  end

  def test_extent
    assert_nothing_raised { @img.extent(40, 40) }
    res = @img.extent(40, 40)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    assert_equal(40, res.columns)
    assert_equal(40, res.rows)
    assert_nothing_raised { @img.extent(40, 40, 5) }
    assert_nothing_raised { @img.extent(40, 40, 5, 5) }
    assert_raises(ArgumentError) { @img.extent(-40, 40) }
    assert_raises(ArgumentError) { @img.extent(40, -40) }
    assert_raises(TypeError) { @img.extent('x', 40) }
    assert_raises(TypeError) { @img.extent(40, 'x') }
    assert_raises(TypeError) { @img.extent(40, 40, 'x') }
    assert_raises(TypeError) { @img.extent(40, 40, 5, 'x') }
  end

  def test_find_similar_region
    girl = Magick::Image.read(IMAGES_DIR+'/Flower_Hat.jpg').first
    region = girl.crop(10, 10, 50, 50)
    assert_nothing_raised do
    x, y = girl.find_similar_region(region)
    assert_not_nil(x)
    assert_not_nil(y)
    assert_equal(10, x)
    assert_equal(10, y)
    end
    assert_nothing_raised do
    x, y = girl.find_similar_region(region, 0)
    assert_equal(10, x)
    assert_equal(10, y)
    end
    assert_nothing_raised do
    x, y = girl.find_similar_region(region, 0, 0)
    assert_equal(10, x)
    assert_equal(10, y)
    end

    list = Magick::ImageList.new
    list << region
    assert_nothing_raised do
    x, y = girl.find_similar_region(list, 0, 0)
    assert_equal(10, x)
    assert_equal(10, y)
    end

    x = girl.find_similar_region(@img)
    assert_nil(x)

    assert_raise(ArgumentError) { girl.find_similar_region(region, 10, 10, 10) }
    assert_raise(TypeError) { girl.find_similar_region(region, 10, 'x') }
    assert_raise(TypeError) { girl.find_similar_region(region, 'x') }

    region.destroy!
    assert_raise(Magick::DestroyedImageError) { girl.find_similar_region(region) }
  end

  def test_flip
    assert_nothing_raised do
    res = @img.flip
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
  end

  def test_flip!
    assert_nothing_raised do
    res = @img.flip!
    assert_same(@img, res)
    end
  end

  def test_flop
    assert_nothing_raised do
    res = @img.flop
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
  end

  def test_flop!
    assert_nothing_raised do
    res = @img.flop!
    assert_same(@img, res)
    end
  end

  def test_frame
    assert_nothing_raised do
    res = @img.frame
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.frame(50) }
    assert_nothing_raised { @img.frame(50, 50) }
    assert_nothing_raised { @img.frame(50, 50, 25) }
    assert_nothing_raised { @img.frame(50, 50, 25, 25) }
    assert_nothing_raised { @img.frame(50, 50, 25, 25, 6) }
    assert_nothing_raised { @img.frame(50, 50, 25, 25, 6, 6) }
    assert_nothing_raised { @img.frame(50, 50, 25, 25, 6, 6, 'red') }
    red = Magick::Pixel.new(Magick::QuantumRange)
    assert_nothing_raised { @img.frame(50, 50, 25, 25, 6, 6, red) }
    assert_raise(TypeError) { @img.frame(50, 50, 25, 25, 6, 6, 2) }
  end

  def test_gamma_channel
    assert_nothing_raised do
    res = @img.gamma_channel(0.8)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_raise(ArgumentError) { @img.gamma_channel }
    assert_nothing_raised { @img.gamma_channel(0.8, Magick::RedChannel) }
    assert_nothing_raised { @img.gamma_channel(0.8, Magick::RedChannel, Magick::BlueChannel) }
    assert_raise(TypeError) { @img.gamma_channel(0.8, Magick::RedChannel, 2) }
  end

  def test_function_channel
    img = Magick::Image.read('gradient:') {self.size = '20x600'}
    img = img.first
    img.rotate!(90)
    assert_nothing_raised { img.function_channel Magick::PolynomialFunction, 0.33 }
    assert_nothing_raised { img.function_channel Magick::PolynomialFunction, 4, -1.5 }
    assert_nothing_raised { img.function_channel Magick::PolynomialFunction, 4, -4, 1 }
    assert_nothing_raised { img.function_channel Magick::PolynomialFunction, -25, 53, -36, 8.3, 0.2 }

    assert_nothing_raised { img.function_channel Magick::SinusoidFunction, 1 }
    assert_nothing_raised { img.function_channel Magick::SinusoidFunction, 1, 90 }
    assert_nothing_raised { img.function_channel Magick::SinusoidFunction, 5, 90, 0.25, 0.75 }

    assert_nothing_raised { img.function_channel Magick::ArcsinFunction, 1 }
    assert_nothing_raised { img.function_channel Magick::ArcsinFunction, 0.5 }
    assert_nothing_raised { img.function_channel Magick::ArcsinFunction, 0.4, 0.7 }
    assert_nothing_raised { img.function_channel Magick::ArcsinFunction, 0.5, 0.5, 0.5, 0.5 }

    assert_nothing_raised { img.function_channel Magick::ArctanFunction, 1 }
    assert_nothing_raised { img.function_channel Magick::ArctanFunction, 10, 0.7 }
    assert_nothing_raised { img.function_channel Magick::ArctanFunction, 5, 0.7, 1.2 }
    assert_nothing_raised { img.function_channel Magick::ArctanFunction, 15, 0.7, 0.5, 0.75 }

    # with channel args
    assert_nothing_raised { img.function_channel Magick::PolynomialFunction, 0.33, Magick::RedChannel }
    assert_nothing_raised { img.function_channel Magick::SinusoidFunction, 1, Magick::RedChannel, Magick::BlueChannel }

    # invalid args
    assert_raise(ArgumentError) { img.function_channel }
    assert_raise(TypeError) { img.function_channel 1 }
    assert_raise(ArgumentError) { img.function_channel Magick::PolynomialFunction }
    assert_raise(TypeError) { img.function_channel Magick::PolynomialFunction, [] }
    assert_raise(ArgumentError) { img.function_channel Magick::SinusoidFunction, 5, 90, 0.25, 0.75, 0.1 }
    assert_raise(ArgumentError) { img.function_channel Magick::ArcsinFunction, 0.5, 0.5, 0.5, 0.5, 0.1 }
    assert_raise(ArgumentError) { img.function_channel Magick::ArctanFunction, 15, 0.7, 0.5, 0.75, 0.1 }
  end

  def test_gramma_correct
    assert_raise(ArgumentError) { @img.gamma_correct }
    # All 4 arguments can't default to 1.0
    assert_raise(ArgumentError) { @img.gamma_correct(1.0) }
    assert_nothing_raised do
    res = @img.gamma_correct(0.8)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.gamma_correct(0.8, 0.9) }
    assert_nothing_raised { @img.gamma_correct(0.8, 0.9, 1.0) }
    assert_nothing_raised { @img.gamma_correct(0.8, 0.9, 1.0, 1.1) }
    # too many arguments
    assert_raise(ArgumentError) { @img.gamma_correct(0.8, 0.9, 1.0, 1.1, 2) }
  end

  def test_gaussian_blur
    assert_nothing_raised do
    res = @img.gaussian_blur
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.gaussian_blur(0.0) }
    assert_nothing_raised { @img.gaussian_blur(0.0, 3.0) }
    # sigma must be != 0.0
    assert_raise(ArgumentError) { @img.gaussian_blur(1.0, 0.0) }
    assert_raise(ArgumentError) { @img.gaussian_blur(1.0, 3.0, 2) }
  end

  def test_gaussian_blur_channel
    assert_nothing_raised do
    res = @img.gaussian_blur_channel
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.gaussian_blur_channel(0.0) }
    assert_nothing_raised { @img.gaussian_blur_channel(0.0, 3.0) }
    assert_nothing_raised { @img.gaussian_blur_channel(0.0, 3.0, Magick::RedChannel) }
    assert_nothing_raised { @img.gaussian_blur_channel(0.0, 3.0, Magick::RedChannel, Magick::BlueChannel) }
    assert_raise(TypeError) { @img.gaussian_blur_channel(0.0, 3.0, Magick::RedChannel, 2) }
  end

  def test_get_exif_by_entry
    assert_nothing_raised do
    res = @img.get_exif_by_entry
    assert_instance_of(Array, res)
    end
  end

  def test_get_exif_by_number
    assert_nothing_raised do
    res = @img.get_exif_by_number
    assert_instance_of(Hash, res)
    end
  end

  def test_get_pixels
    assert_nothing_raised do
    pixels = @img.get_pixels(0, 0, @img.columns, 1)
    assert_instance_of(Array, pixels)
    assert_equal(@img.columns, pixels.length)
    assert_block do
      pixels.all? { |p| p.is_a? Magick::Pixel }
    end
    end
    assert_raise(RangeError) { @img.get_pixels(0,  0, -1, 1) }
    assert_raise(RangeError) { @img.get_pixels(0,  0, @img.columns, -1) }
    assert_raise(RangeError) { @img.get_pixels(0,  0, @img.columns+1, 1) }
    assert_raise(RangeError) { @img.get_pixels(0,  0, @img.columns, @img.rows+1) }
  end

  def test_gray?
    gray = Magick::Image.new(20, 20) { self.background_color = 'gray50' }
    assert(gray.gray?)
    red = Magick::Image.new(20, 20) { self.background_color = 'red' }
    assert(!red.gray?)
  end

  def test_histogram?
    assert_nothing_raised { @img.histogram? }
    assert(@img.histogram?)
  end

  def test_implode
    assert_nothing_raised do
    res = @img.implode(0.5)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
  end

  def test_import_pixels
    pixels = @img.export_pixels(0, 0, @img.columns, 1, 'RGB')
    assert_nothing_raised do
    res = @img.import_pixels(0, 0, @img.columns, 1, 'RGB', pixels)
    assert_same(@img, res)
    end
    assert_raise(ArgumentError) { @img.import_pixels }
    assert_raise(ArgumentError) { @img.import_pixels(0) }
    assert_raise(ArgumentError) { @img.import_pixels(0, 0) }
    assert_raise(ArgumentError) { @img.import_pixels(0, 0, @img.columns) }
    assert_raise(ArgumentError) { @img.import_pixels(0, 0, @img.columns, 1) }
    assert_raise(ArgumentError) { @img.import_pixels(0, 0, @img.columns, 1, 'RGB') }
    assert_raise(TypeError) { @img.import_pixels('x', 0, @img.columns, 1, 'RGB', pixels) }
    assert_raise(TypeError) { @img.import_pixels(0, 'x', @img.columns, 1, 'RGB', pixels) }
    assert_raise(TypeError) { @img.import_pixels(0, 0, 'x', 1, 'RGB', pixels) }
    assert_raise(TypeError) { @img.import_pixels(0, 0, @img.columns, 'x', 'RGB', pixels) }
    assert_raise(TypeError) { @img.import_pixels(0, 0, @img.columns, 1, [2], pixels) }
    assert_raise(ArgumentError) { @img.import_pixels(-1, 0, @img.columns, 1, 'RGB', pixels) }
    assert_raise(ArgumentError) { @img.import_pixels(0, -1, @img.columns, 1, 'RGB', pixels) }
    assert_raise(ArgumentError) { @img.import_pixels(0, 0, -1, 1, 'RGB', pixels) }
    assert_raise(ArgumentError) { @img.import_pixels(0, 0, @img.columns, -1, 'RGB', pixels) }

    # pixel array is too small
    assert_raise(ArgumentError) { @img.import_pixels(0, 0, @img.columns, 2, 'RGB', pixels) }
    # pixel array doesn't contain a multiple of the map length
    pixels.shift
    assert_raise(ArgumentError) { @img.import_pixels(0, 0, @img.columns, 1, 'RGB', pixels) }
  end

  def test_level
    assert_nothing_raised do
    res = @img.level
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.level(0.0) }
    assert_nothing_raised { @img.level(0.0, 1.0) }
    assert_nothing_raised { @img.level(0.0, 1.0, Magick::QuantumRange) }
    assert_raise(ArgumentError) { @img.level(0.0, 1.0, Magick::QuantumRange, 2) }
    assert_raise(ArgumentError) { @img.level('x') }
    assert_raise(ArgumentError) { @img.level(0.0, 'x') }
    assert_raise(ArgumentError) { @img.level(0.0, 1.0, 'x') }
  end

  # Ensure that #level properly swaps old-style arg list
  def test_level2
    img1 = @img.level(10, 2, 200)
    img2 = @img.level(10, 200, 2)
    assert_equal(img2, img1)

    # Ensure that level2 uses new arg order
    img1 = @img.level2(10, 200, 2)
    assert_equal(img2, img1)
  end

  def test_level_channel
    assert_raise(ArgumentError) { @img.level_channel }
    assert_nothing_raised do
    res = @img.level_channel(Magick::RedChannel)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end

    assert_nothing_raised { @img.level_channel(Magick::RedChannel, 0.0) }
    assert_nothing_raised { @img.level_channel(Magick::RedChannel, 0.0, 1.0) }
    assert_nothing_raised { @img.level_channel(Magick::RedChannel, 0.0, 1.0, Magick::QuantumRange) }

    assert_raise(ArgumentError) { @img.level_channel(Magick::RedChannel, 0.0, 1.0, Magick::QuantumRange, 2) }
    assert_raise(TypeError) { @img.level_channel(2) }
    assert_raise(TypeError) { @img.level_channel(Magick::RedChannel, 'x') }
    assert_raise(TypeError) { @img.level_channel(Magick::RedChannel, 0.0, 'x') }
    assert_raise(TypeError) { @img.level_channel(Magick::RedChannel, 0.0, 1.0, 'x') }
  end

  def level_colors
    res = nil
    assert_nothing_raised do
    res = @img.level_colors
    end
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)

    assert_nothing_raised { @img.level_colors('black') }
    assert_nothing_raised { @img.level_colors('black', Pixel.new(0,0,0)) }
    assert_nothing_raised { @img.level_colors(Pixel.new(0,0,0), Pixel.new(Magick::QuantumRange,Magick::QuantumRange,Magick::QuantumRange)) }
    assert_nothing_raised { @img.level_colors('black', 'white') }
    assert_nothing_raised { @img.level_colors('black', 'white', false) }
    # too many arguments
    assert_raises(ArgumentError) { @img.level_colors('black', 'white', false, 1) }
    # not a pixel or a string
    assert_raises(ArgumentError) { @img.level_colors([]) }
    # not a color name
    assert_raises(ArgumentError) { @img.level_colors('xxx') }
  end

  def levelize_channel
    res = nil
    assert_nothing_raised do
    res = @img.levelize_channel(0, Magick::QuantumRange)
    end
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)

    assert_nothing_raised { @img.levelize_channel(0, Magick::QuantumRange, 0.5) }
    assert_nothing_raised { @img.levelize_channel(0, Magick::QuantumRange, 0.5, Magick::RedChannel) }
    assert_nothing_raised { @img.levelize_channel(0, Magick::QuantumRange, 0.5, Magick::RedChannel, Magick::BlueChannel) }
    # too many arguments
    assert_raise(ArgumentError) { @img.levelize_channel(0, Magick::QuantumRange, 0.5, 1, Magick::RedChannel) }
    # not enough arguments
    assert_raise(ArgumentError) { @img.levelize_channel }
  end

#     def test_liquid_rescale
#       begin
#         @img.liquid_rescale(15,15)
#       rescue NotImplementedError
#         puts "liquid_rescale not implemented."
#         return
#       end
#
#       res = nil
#       assert_nothing_raised do
#         res = @img.liquid_rescale(15, 15)
#       end
#       assert_equal(15, res.columns)
#       assert_equal(15, res.rows)
#       assert_nothing_raised { @img.liquid_rescale(15, 15, 0, 0) }
#       assert_raise(ArgumentError) { @img.liquid_rescale(15) }
#       assert_raise(ArgumentError) { @img.liquid_rescale(15, 15, 0, 0, 0) }
#       assert_raise(TypeError) { @img.liquid_rescale([], 15) }
#       assert_raise(TypeError) { @img.liquid_rescale(15, []) }
#       assert_raise(TypeError) { @img.liquid_rescale(15, 15, []) }
#       assert_raise(TypeError) { @img.liquid_rescale(15, 15, 0, []) }
#     end

  def test_magnify
    assert_nothing_raised do
    res = @img.magnify
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end

    res = @img.magnify!
    assert_same(@img, res)
  end

  def test_map
    map = Magick::Image.read('netscape:').first
    assert_nothing_raised do
    res = @img.map(map)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.map(map, true) }
    assert_raise(NoMethodError) { @img.map(2) }
    assert_raise(ArgumentError) { @img.map(map, true, 2) }
    assert_raise(ArgumentError) { @img.map }
    map.destroy!
    assert_raise(Magick::DestroyedImageError) { @img.map(map, true) }
  end

  def test_marshal
    img =  Magick::Image.read(IMAGES_DIR+'/Button_0.gif').first
    d = nil
    img2 = nil
    assert_nothing_raised { d = Marshal.dump(img) }
    assert_nothing_raised { img2 = Marshal.load(d) }
    assert_equal(img, img2)
  end

  def test_mask
    cimg = Magick::Image.new(10,10)
    assert_nothing_raised { @img.mask(cimg) }
    res = nil
    assert_nothing_raised { res = @img.mask }
    assert_not_nil(res)
    assert_not_same(cimg, res)
    assert_equal(20, res.columns)
    assert_equal(20, res.rows)

    # mask expects an Image and calls `cur_image'
    assert_raise(NoMethodError) { @img.mask = 2 }

    img = @img.copy.freeze
    assert_raise(FreezeError) { img.mask cimg }

    @img.destroy!
    assert_raise(Magick::DestroyedImageError) { @img.mask cimg }
  end

  def test_matte_fill_to_border
    assert_nothing_raised do
    res = @img.matte_fill_to_border(@img.columns/2, @img.rows/2)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.matte_fill_to_border(@img.columns, @img.rows) }
    assert_raise(ArgumentError) { @img.matte_fill_to_border(@img.columns+1, @img.rows) }
    assert_raise(ArgumentError) { @img.matte_fill_to_border(@img.columns, @img.rows+1) }
  end

  def test_matte_floodfill
    assert_nothing_raised do
    res = @img.matte_floodfill(@img.columns/2, @img.rows/2)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.matte_floodfill(@img.columns, @img.rows) }
    assert_raise(ArgumentError) { @img.matte_floodfill(@img.columns+1, @img.rows) }
    assert_raise(ArgumentError) { @img.matte_floodfill(@img.columns, @img.rows+1) }
  end

  def test_matte_replace
    assert_nothing_raised do
    res = @img.matte_replace(@img.columns/2, @img.rows/2)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
  end

  def test_matte_reset!
    assert_nothing_raised do
    res = @img.matte_reset!
    assert_same(@img, res)
    end
  end

  def test_median_filter
    assert_nothing_raised do
    res = @img.median_filter
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.median_filter(0.5) }
    assert_raise(ArgumentError) { @img.median_filter(0.5, 'x') }
    assert_raise(TypeError) { @img.median_filter('x') }
  end

  def test_minify
    assert_nothing_raised do
    res = @img.minify
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end

    res = @img.minify!
    assert_same(@img, res)
  end

  def test_modulate
    assert_nothing_raised do
    res = @img.modulate
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.modulate(0.5) }
    assert_nothing_raised { @img.modulate(0.5, 0.5) }
    assert_nothing_raised { @img.modulate(0.5, 0.5, 0.5) }
    assert_raise(ArgumentError) { @img.modulate(0.5, 0.5, 0.5, 0.5) }
    assert_raise(TypeError) { @img.modulate('x', 0.5, 0.5) }
    assert_raise(TypeError) { @img.modulate(0.5, 'x', 0.5) }
    assert_raise(TypeError) { @img.modulate(0.5, 0.5, 'x') }
  end

  def test_monochrome?
#       assert_block { @img.monochrome? }
    @img.pixel_color(0,0, 'red')
    assert_block { ! @img.monochrome? }
  end

  def test_motion_blur
    assert_nothing_raised do
    res = @img.motion_blur(1.0, 7.0, 180)
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_raise(ArgumentError) { @img.motion_blur(1.0, 0.0, 180) }
    assert_nothing_raised { @img.motion_blur(1.0, -1.0, 180) }
  end

  def test_negate
    assert_nothing_raised do
    res = @img.negate
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.negate(true) }
    assert_raise(ArgumentError) { @img.negate(true, 2) }
  end

  def test_negate_channel
    assert_nothing_raised do
    res = @img.negate_channel
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.negate_channel(true) }
    assert_nothing_raised { @img.negate_channel(true, Magick::RedChannel) }
    assert_nothing_raised { @img.negate_channel(true, Magick::RedChannel, Magick::BlueChannel) }
    assert_raise(TypeError) { @img.negate_channel(true, Magick::RedChannel, 2) }
  end

  def test_normalize
    assert_nothing_raised do
    res = @img.normalize
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
  end

  def test_normalize_channel
    assert_nothing_raised do
    res = @img.normalize_channel
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.normalize_channel(Magick::RedChannel) }
    assert_nothing_raised { @img.normalize_channel(Magick::RedChannel, Magick::BlueChannel) }
    assert_raise(TypeError) { @img.normalize_channel(Magick::RedChannel, 2) }
  end

  def test_oil_paint
    assert_nothing_raised do
    res = @img.oil_paint
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.oil_paint(2.0) }
    assert_raise(ArgumentError) { @img.oil_paint(2.0, 1.0) }
  end

  def test_opaque
    assert_nothing_raised do
    res = @img.opaque('white', 'red')
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    red = Magick::Pixel.new(Magick::QuantumRange)
    blue = Magick::Pixel.new(0, 0, Magick::QuantumRange)
    assert_nothing_raised { @img.opaque(red, blue) }
    assert_raise(TypeError) { @img.opaque(red, 2) }
    assert_raise(TypeError) { @img.opaque(2, blue) }
  end

  def test_opaque_channel
    res = nil
    assert_nothing_raised { res = @img.opaque_channel('white', 'red') }
    assert_not_nil(res)
    assert_instance_of(Magick::Image, res)
    assert_not_same(res, @img)
    assert_nothing_raised { @img.opaque_channel('red', 'blue', true) }
    assert_nothing_raised { @img.opaque_channel('red', 'blue', true, 50) }
    assert_nothing_raised { @img.opaque_channel('red', 'blue', true, 50, Magick::RedChannel) }
    assert_nothing_raised { @img.opaque_channel('red', 'blue', true, 50, Magick::RedChannel, Magick::GreenChannel) }
    assert_nothing_raised do
    @img.opaque_channel('red', 'blue', true, 50, Magick::RedChannel, Magick::GreenChannel, Magick::BlueChannel)
    end

    assert_raise(TypeError) { @img.opaque_channel('red', 'blue', true, 50, 50) }
    assert_raise(TypeError) { @img.opaque_channel('red', 'blue', true, []) }
    assert_raise(ArgumentError) { @img.opaque_channel('red') }
    assert_raise(TypeError) { @img.opaque_channel('red', []) }
  end

  def test_opaque?
    assert_nothing_raised do
    assert_block { @img.opaque? }
    end
    @img.opacity = Magick::TransparentOpacity
    assert_block { ! @img.opaque? }
  end

  def test_ordered_dither
    assert_nothing_raised do
    res = @img.ordered_dither
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.ordered_dither(2) }
    assert_nothing_raised { @img.ordered_dither(3) }
    assert_nothing_raised { @img.ordered_dither(4) }
    assert_raise(ArgumentError) { @img.ordered_dither(5) }
    assert_raise(ArgumentError) { @img.ordered_dither(2, 1) }
  end

  def test_paint_transparent
    res = nil
    assert_nothing_raised { res = @img.paint_transparent('red') }
    assert_not_nil(res)
    assert_instance_of(Magick::Image, res)
    assert_not_same(res, @img)
    assert_nothing_raised { @img.paint_transparent('red', Magick::TransparentOpacity) }
    assert_nothing_raised { @img.paint_transparent('red', Magick::TransparentOpacity, true) }
    assert_nothing_raised { @img.paint_transparent('red', Magick::TransparentOpacity, true, 50) }

    # Too many arguments
    assert_raise(ArgumentError) { @img.paint_transparent('red', Magick::TransparentOpacity, true, 50, 50) }
    # Not enough
    assert_raise(ArgumentError) { @img.paint_transparent }
    assert_raise(TypeError) { @img.paint_transparent('red', Magick::TransparentOpacity, true, []) }
    assert_raise(TypeError) { @img.paint_transparent('red', 'blue') }
    assert_raise(TypeError) { @img.paint_transparent(50) }
  end

  def test_palette?
    img = Magick::Image.read(IMAGES_DIR+'/Flower_Hat.jpg').first
    assert_nothing_raised do
    assert_block { !img.palette? }
    end
    img = Magick::Image.read(IMAGES_DIR+'/Button_0.gif').first
    assert_block { img.palette? }
  end

  def test_pixel_color
    assert_nothing_raised do
    res = @img.pixel_color(0,0)
    assert_instance_of(Magick::Pixel, res)
    end
    res = @img.pixel_color(0,0)
    assert_equal(@img.background_color, res.to_color)
    res = @img.pixel_color(0, 0, 'red')
    assert_equal('white', res.to_color)
    res = @img.pixel_color(0, 0)
    assert_equal('red', res.to_color)

    blue = Magick::Pixel.new(0, 0, Magick::QuantumRange)
    assert_nothing_raised { @img.pixel_color(0,0, blue) }
    # If args are out-of-bounds return the background color
    img = Magick::Image.new(10, 10) { self.background_color = 'blue' }
    assert_equal('blue', img.pixel_color(50, 50).to_color)
  end

  def test_polaroid
    assert_nothing_raised { @img.polaroid }
    assert_nothing_raised { @img.polaroid(5) }
    assert_instance_of(Magick::Image, @img.polaroid)
    assert_raises(TypeError) { @img.polaroid('x') }
  end

  def test_posterize
    assert_nothing_raised do
    res = @img.posterize
    assert_instance_of(Magick::Image, res)
    assert_not_same(@img, res)
    end
    assert_nothing_raised { @img.posterize(5) }
    assert_nothing_raised { @img.posterize(5, true) }
    assert_raise(ArgumentError) { @img.posterize(5, true, 'x') }
  end
end

if __FILE__ == $PROGRAM_NAME
  IMAGES_DIR = '../doc/ex/images'
  FILES = Dir[IMAGES_DIR+'/Button_*.gif']
  Test::Unit::UI::Console::TestRunner.run(Image2_UT) unless RUBY_VERSION[/^1\.9|^2/]
end
