diff --git a/MagickCore/version.h b/MagickCore/version.h
index 091f73b..051ccb5 100644
--- a/MagickCore/version.h
+++ b/MagickCore/version.h
@@ -27,14 +27,14 @@
 */
 #define MagickPackageName "ImageMagick"
 #define MagickCopyright  "Copyright (C) 1999-2013 ImageMagick Studio LLC"
-#define MagickSVNRevision  "11008:11010M"
+#define MagickSVNRevision  "11008:11015M"
 #define MagickLibVersion  0x700
 #define MagickLibVersionText  "7.0.0"
 #define MagickLibVersionNumber  1,0,0
 #define MagickLibAddendum  "-0"
 #define MagickLibInterface  1
 #define MagickLibMinInterface  1
-#define MagickReleaseDate  "2013-02-12"
+#define MagickReleaseDate  "2013-02-13"
 #define MagickChangeDate   "20121005"
 #define MagickAuthoritativeURL  "http://www.imagemagick.org"
 #define MagickFeatures "DPC HDRI OpenMP"
diff --git a/Makefile.am b/Makefile.am
index 423cf32..231b8de 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -285,6 +285,7 @@
 html:
 	doxygen config/MagickCore.dox
 	doxygen config/MagickWand.dox
+	doxygen config/Magick++.dox
 
 #
 # Build Windows source Zip and 7Zip balls
diff --git a/Makefile.in b/Makefile.in
index 0d18f05..822738d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -187,6 +187,8 @@
 #
 #  Makefile for building PerlMagick.
 
+# If source files missing, see if they can be obtained via VPATH
+
 
 
 
@@ -257,9 +259,11 @@
 	$(top_srcdir)/MagickCore/MagickCore-config.in \
 	$(top_srcdir)/MagickCore/MagickCore.pc.in \
 	$(top_srcdir)/MagickCore/version.h.in $(srcdir)/magick.sh.in \
-	$(top_srcdir)/PerlMagick/Magick.pm.in \
-	$(top_srcdir)/PerlMagick/Makefile.PL.in \
 	$(top_srcdir)/PerlMagick/check.sh.in \
+	$(top_srcdir)/PerlMagick/Magick.pm.in \
+	$(top_srcdir)/PerlMagick/Magick.xs.in \
+	$(top_srcdir)/PerlMagick/Makefile.PL.in \
+	$(top_srcdir)/PerlMagick/typemap.in \
 	$(top_srcdir)/utilities/animate.1.in \
 	$(top_srcdir)/utilities/compare.1.in \
 	$(top_srcdir)/utilities/composite.1.in \
@@ -328,8 +332,9 @@
 	config/type.xml ImageMagick.spec Magick++/bin/Magick++-config \
 	MagickCore/ImageMagick.pc Magick++/lib/Magick++.pc \
 	MagickCore/MagickCore-config MagickCore/MagickCore.pc \
-	MagickCore/version.h magick.sh PerlMagick/Magick.pm \
-	PerlMagick/Makefile.PL PerlMagick/check.sh utilities/animate.1 \
+	MagickCore/version.h magick.sh PerlMagick/check.sh \
+	PerlMagick/Magick.pm PerlMagick/Magick.xs \
+	PerlMagick/Makefile.PL PerlMagick/typemap utilities/animate.1 \
 	utilities/compare.1 utilities/composite.1 utilities/conjure.1 \
 	utilities/convert.1 utilities/display.1 utilities/identify.1 \
 	utilities/ImageMagick.1 utilities/import.1 utilities/mogrify.1 \
@@ -5100,11 +5105,15 @@
 	cd $(top_builddir) && $(SHELL) ./config.status $@
 magick.sh: $(top_builddir)/config.status $(srcdir)/magick.sh.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
+PerlMagick/check.sh: $(top_builddir)/config.status $(top_srcdir)/PerlMagick/check.sh.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
 PerlMagick/Magick.pm: $(top_builddir)/config.status $(top_srcdir)/PerlMagick/Magick.pm.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
+PerlMagick/Magick.xs: $(top_builddir)/config.status $(top_srcdir)/PerlMagick/Magick.xs.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
 PerlMagick/Makefile.PL: $(top_builddir)/config.status $(top_srcdir)/PerlMagick/Makefile.PL.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
-PerlMagick/check.sh: $(top_builddir)/config.status $(top_srcdir)/PerlMagick/check.sh.in
+PerlMagick/typemap: $(top_builddir)/config.status $(top_srcdir)/PerlMagick/typemap.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
 utilities/animate.1: $(top_builddir)/config.status $(top_srcdir)/utilities/animate.1.in
 	cd $(top_builddir) && $(SHELL) ./config.status $@
@@ -10668,13 +10677,20 @@
 	  rm -f $$target ; \
 	done
 
-# If source files missing, see if they can be obtained via VPATH
-perl-sources:
+$(PERLMAGICK)/@MAGICK_ABI_SUFFIX@.xs: $(PERLMAGICK)/Magick.xs
+	$(AM_V_GEN) $(LN_S) $(notdir $^) $@
+
+$(PERLMAGICK)/@MAGICK_ABI_SUFFIX@.pm: $(PERLMAGICK)/Magick.pm
+	$(AM_V_GEN) $(LN_S) $(notdir $^) $@
+
+perl-quantum-sources: $(PERLMAGICK)/@MAGICK_ABI_SUFFIX@.xs $(PERLMAGICK)/@MAGICK_ABI_SUFFIX@.pm
+
+perl-sources: perl-quantum-sources
 	@if test -n "$(VPATH)" ; then \
 	  echo "Linking PerlMagick Sources ..." ; \
 	  imagemagick=`(cd $(VPATH) ; pwd)` && \
 	  ( cd $(PERLMAGICK) && \
-	    sh $$imagemagick/config/lndir.sh $$imagemagick/$(PERLMAGICK) ) \
+	    sh $$imagemagick/config/lndir.sh $$imagemagick/$(PERLMAGICK) ; ) \
 	fi ; \
 	touch perl-sources
 
@@ -10732,7 +10748,10 @@
 @WITH_PERL_TRUE@	( if test -f Makefile ; then $(MAKE) CC='@CC@' clean ; fi ) ; \
 @WITH_PERL_TRUE@	( if test -f Makefile ; then $(MAKE) CC='@CC@' clean ; fi ) ; \
 @WITH_PERL_TRUE@	rm -f Makefile.old PerlMagick ; \
-@WITH_PERL_TRUE@	rm -f t/output* t/jng/*_tmp.jng t/*/output* )
+@WITH_PERL_TRUE@	rm -f t/output* t/jng/*_tmp.jng t/*/output* ; \
+@WITH_PERL_TRUE@	rm -f @MAGICK_ABI_SUFFIX@.xs;\
+@WITH_PERL_TRUE@	rm -f @MAGICK_ABI_SUFFIX@.pm;\
+@WITH_PERL_TRUE@	rm -f Magick.pm;)
 @WITH_PERL_TRUE@	rm -f perl-sources
 
 @WITH_PERL_TRUE@distclean-perl: clean-perl
@@ -10839,6 +10858,7 @@
 html:
 	doxygen config/MagickCore.dox
 	doxygen config/MagickWand.dox
+	doxygen config/Magick++.dox
 $(DIST_WINDOWS_SRC_ZIP) $(DIST_WINDOWS_SRC_7ZIP) windows-dist:
 	if test -d $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM) ; then \
 	  chmod -R u+w $(PACKAGE_NAME)-$(PACKAGE_VERSION)$(PACKAGE_VERSION_ADDENDUM) ; \
diff --git a/PerlMagick/Magick.pm b/PerlMagick/Magick.pm
index 98b2f5e..509c74e 100644
--- a/PerlMagick/Magick.pm
+++ b/PerlMagick/Magick.pm
@@ -1,4 +1,4 @@
-package Image::Magick;
+package Image::Magick::Q16HDRI;
 
 #  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization
 #  dedicated to making software imaging solutions freely available.
@@ -16,7 +16,6 @@
 #
 #  Initial version, written by Kyle Shorter.
 
-
 use strict;
 use Carp;
 use vars qw($VERSION @ISA @EXPORT $AUTOLOAD);
@@ -69,14 +68,14 @@
     goto &$AUTOLOAD;
 }
 
-bootstrap Image::Magick $VERSION;
+bootstrap Image::Magick::Q16HDRI $VERSION;
 
 # Preloaded methods go here.
 
 sub new
 {
     my $this = shift;
-    my $class = ref($this) || $this || "Image::Magick";
+    my $class = ref($this) || $this || "Image::Magick::Q16HDRI";
     my $self = [ ];
     bless $self, $class;
     $self->set(@_) if @_;
@@ -86,7 +85,7 @@
 sub New
 {
     my $this = shift;
-    my $class = ref($this) || $this || "Image::Magick";
+    my $class = ref($this) || $this || "Image::Magick::Q16HDRI";
     my $self = [ ];
     bless $self, $class;
     $self->set(@_) if @_;
@@ -102,12 +101,12 @@
 
 =head1 NAME
 
-Image::Magick - objected-oriented Perl interface to ImageMagick. Use it to read, manipulate, or write an image or image sequence from within a Perl script.
+Image::Magick::Q16HDRI - objected-oriented Perl interface to ImageMagick (Q16HDRI). Use it to read, manipulate, or write an image or image sequence from within a Perl script.
 
 =head1 SYNOPSIS
 
-  use Image::Magick;
-  $p = new Image::Magick;
+  use Image::Magick::Q16HDRI;
+  $p = new Image::Magick::Q16HDRI;
   $p->Read("imagefile");
   $p->Set(attribute => value, ...)
   ($a, ...) = $p->Get("attribute", ...)
diff --git a/PerlMagick/Magick.pm.in b/PerlMagick/Magick.pm.in
index bbf6d45..ea5caac 100644
--- a/PerlMagick/Magick.pm.in
+++ b/PerlMagick/Magick.pm.in
@@ -1,4 +1,4 @@
-package Image::Magick;
+package Image::Magick::@MAGICK_ABI_SUFFIX@;
 
 #  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization
 #  dedicated to making software imaging solutions freely available.
@@ -16,7 +16,6 @@
 #
 #  Initial version, written by Kyle Shorter.
 
-
 use strict;
 use Carp;
 use vars qw($VERSION @ISA @EXPORT $AUTOLOAD);
@@ -69,14 +68,14 @@
     goto &$AUTOLOAD;
 }
 
-bootstrap Image::Magick $VERSION;
+bootstrap Image::Magick::@MAGICK_ABI_SUFFIX@ $VERSION;
 
 # Preloaded methods go here.
 
 sub new
 {
     my $this = shift;
-    my $class = ref($this) || $this || "Image::Magick";
+    my $class = ref($this) || $this || "Image::Magick::@MAGICK_ABI_SUFFIX@";
     my $self = [ ];
     bless $self, $class;
     $self->set(@_) if @_;
@@ -86,7 +85,7 @@
 sub New
 {
     my $this = shift;
-    my $class = ref($this) || $this || "Image::Magick";
+    my $class = ref($this) || $this || "Image::Magick::@MAGICK_ABI_SUFFIX@";
     my $self = [ ];
     bless $self, $class;
     $self->set(@_) if @_;
@@ -102,12 +101,12 @@
 
 =head1 NAME
 
-Image::Magick - objected-oriented Perl interface to ImageMagick. Use it to read, manipulate, or write an image or image sequence from within a Perl script.
+Image::Magick::@MAGICK_ABI_SUFFIX@ - objected-oriented Perl interface to ImageMagick (@MAGICK_ABI_SUFFIX@). Use it to read, manipulate, or write an image or image sequence from within a Perl script.
 
 =head1 SYNOPSIS
 
-  use Image::Magick;
-  $p = new Image::Magick;
+  use Image::Magick::@MAGICK_ABI_SUFFIX@;
+  $p = new Image::Magick::@MAGICK_ABI_SUFFIX@;
   $p->Read("imagefile");
   $p->Set(attribute => value, ...)
   ($a, ...) = $p->Get("attribute", ...)
diff --git a/PerlMagick/Magick.xs b/PerlMagick/Magick.xs
index 2148e72..ca9c6f5 100644
--- a/PerlMagick/Magick.xs
+++ b/PerlMagick/Magick.xs
@@ -79,7 +79,7 @@
 #define na  PL_na
 #endif
 #define NumberOf(array)  (sizeof(array)/sizeof(*array))
-#define PackageName   "Image::Magick"
+#define PackageName   "Image::Magick::@MAGICK_ABI_NAME@"
 #if PERL_VERSION <= 6
 #define PerlIO  FILE
 #define PerlIO_importFILE(f, fl)  (f)
@@ -189,7 +189,7 @@
 };
 
 typedef void
-  *Image__Magick;  /* data type for the Image::Magick package */
+  *Image__Magick__Q16HDRI;  /* data type for the Image::Magick::@MAGICK_ABI_NAME@ package */
 
 /*
   Static declarations.
@@ -2340,7 +2340,7 @@
 %
 %
 */
-MODULE = Image::Magick PACKAGE = Image::Magick
+MODULE = Image::Magick::Q16HDRI PACKAGE = Image::Magick::Q16HDRI
 
 PROTOTYPES: ENABLE
 
@@ -2379,7 +2379,7 @@
 #
 void
 Animate(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     AnimateImage  = 1
     animate       = 2
@@ -2458,7 +2458,7 @@
 #
 void
 Append(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     AppendImage  = 1
     append       = 2
@@ -2596,7 +2596,7 @@
 #
 void
 Average(ref)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     AverageImage   = 1
     average        = 2
@@ -2694,7 +2694,7 @@
 #
 void
 BlobToImage(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     BlobToImage  = 1
     blobtoimage  = 2
@@ -2850,7 +2850,7 @@
 #
 void
 ChannelFx(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     ChannelFxImage  = 1
     channelfx       = 2
@@ -3013,7 +3013,7 @@
 #
 void
 Clone(ref)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     CopyImage   = 1
     copy        = 2
@@ -3142,7 +3142,7 @@
 #
 void
 Coalesce(ref)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     CoalesceImage   = 1
     coalesce        = 2
@@ -3232,7 +3232,7 @@
 #
 void
 Compare(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     CompareImages = 1
     compare      = 2
@@ -3427,7 +3427,7 @@
 #
 void
 CompareLayers(ref)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     CompareImagesLayers   = 1
     comparelayers        = 2
@@ -3563,7 +3563,7 @@
 #
 void
 DESTROY(ref)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   PPCODE:
   {
     SV
@@ -3648,7 +3648,7 @@
 #
 void
 Display(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     DisplayImage  = 1
     display       = 2
@@ -3727,7 +3727,7 @@
 #
 void
 EvaluateImages(ref)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     EvaluateImages   = 1
     evaluateimages   = 2
@@ -3884,7 +3884,7 @@
 #
 void
 Features(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     FeaturesImage = 1
     features      = 2
@@ -4059,7 +4059,7 @@
 #
 void
 Flatten(ref)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     FlattenImage   = 1
     flatten        = 2
@@ -4196,7 +4196,7 @@
 #
 void
 Fx(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     FxImage  = 1
     fx       = 2
@@ -4359,7 +4359,7 @@
 #
 void
 Get(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     GetAttributes = 1
     GetAttribute  = 2
@@ -5645,7 +5645,7 @@
 #
 void *
 GetAuthenticPixels(ref,...)
-  Image::Magick ref = NO_INIT
+  Image::Magick::Q16HDRI ref = NO_INIT
   ALIAS:
     getauthenticpixels = 1
     GetImagePixels = 2
@@ -5800,7 +5800,7 @@
 #
 void *
 GetVirtualPixels(ref,...)
-  Image::Magick ref = NO_INIT
+  Image::Magick::Q16HDRI ref = NO_INIT
   ALIAS:
     getvirtualpixels = 1
     AcquireImagePixels = 2
@@ -5955,7 +5955,7 @@
 #
 void *
 GetAuthenticMetacontent(ref,...)
-  Image::Magick ref = NO_INIT
+  Image::Magick::Q16HDRI ref = NO_INIT
   ALIAS:
     getauthenticmetacontent = 1
     GetMetacontent = 2
@@ -6027,7 +6027,7 @@
 #
 void *
 GetVirtualMetacontent(ref,...)
-  Image::Magick ref = NO_INIT
+  Image::Magick::Q16HDRI ref = NO_INIT
   ALIAS:
     getvirtualmetacontent = 1
   CODE:
@@ -6097,7 +6097,7 @@
 #
 void
 Histogram(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     HistogramImage = 1
     histogram      = 2
@@ -6212,7 +6212,7 @@
 #
 void
 GetPixel(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     getpixel = 1
     getPixel = 2
@@ -6409,7 +6409,7 @@
 #
 void
 GetPixels(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     getpixels = 1
     getPixels = 2
@@ -6657,7 +6657,7 @@
 #
 void
 ImageToBlob(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     ImageToBlob  = 1
     imagetoblob  = 2
@@ -6763,7 +6763,7 @@
 #
 void
 Layers(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     Layers                = 1
     layers           = 2
@@ -7056,7 +7056,7 @@
 #
 SV *
 MagickToMime(ref,name)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   char *name
   ALIAS:
     magicktomime = 1
@@ -7088,7 +7088,7 @@
 #
 void
 Mogrify(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     Comment            =   1
     CommentImage       =   2
@@ -10981,7 +10981,7 @@
 #
 void
 Montage(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     MontageImage  = 1
     montage       = 2
@@ -11393,7 +11393,7 @@
 #
 void
 Morph(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     MorphImage  = 1
     morph       = 2
@@ -11524,7 +11524,7 @@
 #
 void
 Mosaic(ref)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     MosaicImage   = 1
     mosaic        = 2
@@ -11614,7 +11614,7 @@
 #
 void
 Ping(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     PingImage  = 1
     ping       = 2
@@ -11823,7 +11823,7 @@
 #
 void
 Preview(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     PreviewImage = 1
     preview      = 2
@@ -11923,7 +11923,7 @@
 #
 void
 QueryColor(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     querycolor = 1
   PPCODE:
@@ -12003,7 +12003,7 @@
 #
 void
 QueryColorname(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     querycolorname = 1
   PPCODE:
@@ -12078,7 +12078,7 @@
 #
 void
 QueryFont(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     queryfont = 1
   PPCODE:
@@ -12198,7 +12198,7 @@
 #
 void
 QueryFontMetrics(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     queryfontmetrics = 1
   PPCODE:
@@ -12609,7 +12609,7 @@
 #
 void
 QueryMultilineFontMetrics(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     querymultilinefontmetrics = 1
   PPCODE:
@@ -12982,7 +12982,7 @@
 #
 void
 QueryFormat(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     queryformat = 1
   PPCODE:
@@ -13074,7 +13074,7 @@
 #
 void
 QueryOption(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     queryoption = 1
   PPCODE:
@@ -13134,7 +13134,7 @@
 #
 void
 Read(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     ReadImage  = 1
     read       = 2
@@ -13352,7 +13352,7 @@
 #
 void
 Remote(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     RemoteCommand  = 1
     remote         = 2
@@ -13405,7 +13405,7 @@
 #
 void
 Set(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     SetAttributes  = 1
     SetAttribute   = 2
@@ -13471,7 +13471,7 @@
 #
 void
 SetPixel(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     setpixel = 1
     setPixel = 2
@@ -13722,7 +13722,7 @@
 #
 void
 Smush(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     SmushImage  = 1
     smush       = 2
@@ -13875,7 +13875,7 @@
 #
 void
 Statistics(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     StatisticsImage = 1
     statistics      = 2
@@ -13997,7 +13997,7 @@
 #
 void
 SyncAuthenticPixels(ref,...)
-  Image::Magick ref = NO_INIT
+  Image::Magick::Q16HDRI ref = NO_INIT
   ALIAS:
     Syncauthenticpixels = 1
     SyncImagePixels = 2
@@ -14064,7 +14064,7 @@
 #
 void
 Transform(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     TransformImage = 1
     transform      = 2
@@ -14212,7 +14212,7 @@
 #
 void
 Write(ref,...)
-  Image::Magick ref=NO_INIT
+  Image::Magick::Q16HDRI ref=NO_INIT
   ALIAS:
     WriteImage    = 1
     write         = 2
diff --git a/PerlMagick/Magick.xs.in b/PerlMagick/Magick.xs.in
new file mode 100644
index 0000000..8a323ca
--- /dev/null
+++ b/PerlMagick/Magick.xs.in
@@ -0,0 +1,14302 @@
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                         PPPP   EEEEE  RRRR   L                              %
+%                         P   P  E      R   R  L                              %
+%                         PPPP   EEE    RRRR   L                              %
+%                         P      E      R  R   L                              %
+%                         P      EEEEE  R   R  LLLLL                          %
+%                                                                             %
+%                  M   M   AAA    GGGG  IIIII   CCCC  K   K                   %
+%                  MM MM  A   A  G        I    C      K  K                    %
+%                  M M M  AAAAA  G GGG    I    C      KKK                     %
+%                  M   M  A   A  G   G    I    C      K  K                    %
+%                  M   M  A   A   GGGG  IIIII   CCCC  K   K                   %
+%                                                                             %
+%                                                                             %
+%                Object-oriented Perl interface to ImageMagick                %
+%                                                                             %
+%                            Software Design                                  %
+%                              Kyle Shorter                                   %
+%                              John Cristy                                    %
+%                             February 1997                                   %
+%                                                                             %
+%                                                                             %
+%  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
+%  dedicated to making software imaging solutions freely available.           %
+%                                                                             %
+%  You may not use this file except in compliance with the License.  You may  %
+%  obtain a copy of the License at                                            %
+%                                                                             %
+%    http://www.imagemagick.org/script/license.php                            %
+%                                                                             %
+%  Unless required by applicable law or agreed to in writing, software        %
+%  distributed under the License is distributed on an "AS IS" BASIS,          %
+%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
+%  See the License for the specific language governing permissions and        %
+%  limitations under the License.                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  PerlMagick is an objected-oriented Perl interface to ImageMagick.  Use
+%  the module to read, manipulate, or write an image or image sequence from
+%  within a Perl script.  This makes PerlMagick suitable for Web CGI scripts.
+%
+*/
+
+/*
+  Include declarations.
+*/
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+#define PERL_NO_GET_CONTEXT
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+#include <math.h>
+#include <MagickCore/MagickCore.h>
+#undef tainted
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+/*
+  Define declarations.
+*/
+#ifndef aTHX_
+#define aTHX_
+#define pTHX_
+#define dTHX
+#endif
+#define DegreesToRadians(x)  (MagickPI*(x)/180.0)
+#define EndOf(array)  (&array[NumberOf(array)])
+#define MaxArguments  33
+#ifndef na
+#define na  PL_na
+#endif
+#define NumberOf(array)  (sizeof(array)/sizeof(*array))
+#define PackageName   "Image::Magick::@MAGICK_ABI_NAME@"
+#if PERL_VERSION <= 6
+#define PerlIO  FILE
+#define PerlIO_importFILE(f, fl)  (f)
+#define PerlIO_findFILE(f)  NULL
+#endif
+#ifndef sv_undef
+#define sv_undef  PL_sv_undef
+#endif
+
+#define AddImageToRegistry(sv,image) \
+{ \
+  if (magick_registry != (SplayTreeInfo *) NULL) \
+    { \
+      (void) AddValueToSplayTree(magick_registry,image,image); \
+      (sv)=newSViv(PTR2IV(image)); \
+    } \
+}
+
+#define DeleteImageFromRegistry(reference,image) \
+{ \
+  if (magick_registry != (SplayTreeInfo *) NULL) \
+    { \
+      if (GetImageReferenceCount(image) == 1) \
+       (void) DeleteNodeByValueFromSplayTree(magick_registry,image); \
+      image=DestroyImage(image); \
+      sv_setiv(reference,0); \
+    } \
+}
+
+#define InheritPerlException(exception,perl_exception) \
+{ \
+  char \
+    message[MaxTextExtent]; \
+ \
+  if ((exception)->severity != UndefinedException) \
+    { \
+      (void) FormatLocaleString(message,MaxTextExtent,"Exception %d: %s%s%s%s",\
+        (exception)->severity, (exception)->reason ? \
+        GetLocaleExceptionMessage((exception)->severity,(exception)->reason) : \
+        "Unknown", (exception)->description ? " (" : "", \
+        (exception)->description ? GetLocaleExceptionMessage( \
+        (exception)->severity,(exception)->description) : "", \
+        (exception)->description ? ")" : ""); \
+      if ((perl_exception) != (SV *) NULL) \
+        { \
+          if (SvCUR(perl_exception)) \
+            sv_catpv(perl_exception,"\n"); \
+          sv_catpv(perl_exception,message); \
+        } \
+    } \
+}
+
+#define ThrowPerlException(exception,severity,tag,reason) \
+  (void) ThrowMagickException(exception,GetMagickModule(),severity, \
+    tag,"`%s'",reason); \
+
+/*
+  Typedef and structure declarations.
+*/
+typedef enum
+{
+  ArrayReference = (~0),
+  RealReference = (~0)-1,
+  FileReference = (~0)-2,
+  ImageReference = (~0)-3,
+  IntegerReference = (~0)-4,
+  StringReference = (~0)-5
+} MagickReference;
+
+typedef struct _Arguments
+{
+  const char
+    *method;
+
+  ssize_t
+    type;
+} Arguments;
+
+struct ArgumentList
+{
+  ssize_t
+    integer_reference;
+
+  double
+    real_reference;
+
+  const char
+    *string_reference;
+
+  Image
+    *image_reference;
+
+  SV
+    *array_reference;
+
+  FILE
+    *file_reference;
+
+  size_t
+    length;
+};
+
+struct PackageInfo
+{
+  ImageInfo
+    *image_info;
+};
+
+typedef void
+  *Image__Magick__@MAGICK_ABI_SUFFIX@;  /* data type for the Image::Magick::@MAGICK_ABI_NAME@ package */
+
+/*
+  Static declarations.
+*/
+static struct
+  Methods
+  {
+    const char
+      *name;
+
+    Arguments
+      arguments[MaxArguments];
+  } Methods[] =
+  {
+    { "Comment", { {"comment", StringReference} } },
+    { "Label", { {"label", StringReference} } },
+    { "AddNoise", { {"noise", MagickNoiseOptions}, {"attenuate", RealReference},
+      {"channel", MagickChannelOptions} } },
+    { "Colorize", { {"fill", StringReference}, {"blend", StringReference} } },
+    { "Border", { {"geometry", StringReference}, {"width", IntegerReference},
+      {"height", IntegerReference}, {"fill", StringReference},
+      {"bordercolor", StringReference}, {"color", StringReference},
+      {"compose", MagickComposeOptions} } },
+    { "Blur", { {"geometry", StringReference}, {"radius", RealReference},
+      {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
+    { "Chop", { {"geometry", StringReference}, {"width", IntegerReference},
+      {"height", IntegerReference}, {"x", IntegerReference},
+      {"y", IntegerReference} } },
+    { "Crop", { {"geometry", StringReference}, {"width", IntegerReference},
+      {"height", IntegerReference}, {"x", IntegerReference},
+      {"y", IntegerReference}, {"fuzz", StringReference},
+      {"gravity", MagickGravityOptions} } },
+    { "Despeckle", },
+    { "Edge", { {"radius", RealReference} } },
+    { "Emboss", { {"geometry", StringReference}, {"radius", RealReference},
+      {"sigma", RealReference} } },
+    { "Enhance", },
+    { "Flip", },
+    { "Flop", },
+    { "Frame", { {"geometry", StringReference}, {"width", IntegerReference},
+      {"height", IntegerReference}, {"inner", IntegerReference},
+      {"outer", IntegerReference}, {"fill", StringReference},
+      {"color", StringReference}, {"compose", MagickComposeOptions} } },
+    { "Implode", { {"amount", RealReference},
+      {"interpolate", MagickInterpolateOptions} } },
+    { "Magnify", },
+    { "MedianFilter", { {"geometry", StringReference},
+      {"width", IntegerReference}, {"height", IntegerReference},
+      {"channel", MagickChannelOptions} } },
+    { "Minify", },
+    { "OilPaint", { {"radius", RealReference}, {"sigma", RealReference} } },
+    { "ReduceNoise", { {"geometry", StringReference},
+      {"width", IntegerReference},{"height", IntegerReference},
+      {"channel", MagickChannelOptions} } },
+    { "Roll", { {"geometry", StringReference}, {"x", IntegerReference},
+      {"y", IntegerReference} } },
+    { "Rotate", { {"degrees", RealReference}, 
+      {"background", StringReference} } },
+    { "Sample", { {"geometry", StringReference}, {"width", IntegerReference},
+      {"height", IntegerReference} } },
+    { "Scale", { {"geometry", StringReference}, {"width", IntegerReference},
+      {"height", IntegerReference} } },
+    { "Shade", { {"geometry", StringReference}, {"azimuth", RealReference},
+      {"elevation", RealReference}, {"gray", MagickBooleanOptions} } },
+    { "Sharpen", { {"geometry", StringReference}, {"radius", RealReference},
+      {"sigma", RealReference}, {"channel", MagickChannelOptions} } },
+    { "Shear", { {"geometry", StringReference}, {"x", RealReference},
+      {"y", RealReference}, { "fill", StringReference},
+      {"color", StringReference} } },
+    { "Spread", { {"radius", RealReference},
+      {"interpolate", MagickInterpolateOptions} } },
+    { "Swirl", { {"degrees", RealReference},
+      {"interpolate", MagickInterpolateOptions} } },
+    { "Resize", { {"geometry", StringReference}, {"width", IntegerReference},
+      {"height", IntegerReference}, {"filter", MagickFilterOptions},
+      {"support", StringReference } } },
+    { "Zoom", { {"geometry", StringReference}, {"width", IntegerReference},
+      {"height", IntegerReference}, {"filter", MagickFilterOptions},
+      {"support", RealReference } } },
+    { "Annotate", { {"text", StringReference}, {"font", StringReference},
+      {"pointsize", RealReference}, {"density", StringReference},
+      {"undercolor", StringReference}, {"stroke", StringReference},
+      {"fill", StringReference}, {"geometry", StringReference},
+      {"sans", StringReference}, {"x", RealReference},
+      {"y", RealReference}, {"gravity", MagickGravityOptions},
+      {"translate", StringReference}, {"scale", StringReference},
+      {"rotate", RealReference}, {"skewX", RealReference},
+      {"skewY", RealReference}, {"strokewidth", RealReference},
+      {"antialias", MagickBooleanOptions}, {"family", StringReference},
+      {"style", MagickStyleOptions}, {"stretch", MagickStretchOptions},
+      {"weight", IntegerReference}, {"align", MagickAlignOptions},
+      {"encoding", StringReference}, {"affine", ArrayReference},
+      {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
+      {"tile", ImageReference}, {"kerning", RealReference},
+      {"interline-spacing", RealReference},
+      {"interword-spacing", RealReference},
+      {"direction", MagickDirectionOptions} } },
+    { "ColorFloodfill", { {"geometry", StringReference},
+      {"x", IntegerReference}, {"y", IntegerReference},
+      {"fill", StringReference}, {"bordercolor", StringReference},
+      {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
+    { "Composite", { {"image", ImageReference},
+      {"compose", MagickComposeOptions}, {"geometry", StringReference},
+      {"x", IntegerReference}, {"y", IntegerReference},
+      {"gravity", MagickGravityOptions}, {"opacity", StringReference},
+      {"tile", MagickBooleanOptions}, {"rotate", RealReference},
+      {"color", StringReference}, {"mask", ImageReference},
+      {"channel", MagickChannelOptions},
+      {"interpolate", MagickInterpolateOptions}, {"args", StringReference},
+      {"blend", StringReference}, {"crop-to-self", MagickBooleanOptions} } },
+    { "Contrast", { {"sharpen", MagickBooleanOptions} } },
+    { "CycleColormap", { {"display", IntegerReference} } },
+    { "Draw", { {"primitive", MagickPrimitiveOptions},
+      {"points", StringReference}, {"method", MagickMethodOptions},
+      {"stroke", StringReference}, {"fill", StringReference},
+      {"strokewidth", RealReference}, {"font", StringReference},
+      {"bordercolor", StringReference}, {"x", RealReference},
+      {"y", RealReference}, {"translate", StringReference},
+      {"scale", StringReference}, {"rotate", RealReference},
+      {"skewX", RealReference}, {"skewY", RealReference},
+      {"tile", ImageReference}, {"pointsize", RealReference},
+      {"antialias", MagickBooleanOptions}, {"density", StringReference},
+      {"linewidth", RealReference}, {"affine", ArrayReference},
+      {"stroke-dashoffset", RealReference},
+      {"stroke-dasharray", ArrayReference},
+      {"interpolate", MagickInterpolateOptions},
+      {"origin", StringReference}, {"text", StringReference},
+      {"fill-pattern", ImageReference}, {"stroke-pattern", ImageReference},
+      {"vector-graphics", StringReference}, {"kerning", RealReference},
+      {"interline-spacing", RealReference},
+      {"interword-spacing", RealReference},
+      {"direction", MagickDirectionOptions} } },
+    { "Equalize", { {"channel", MagickChannelOptions} } },
+    { "Gamma", { {"gamma", StringReference}, {"channel", MagickChannelOptions},
+      {"red", RealReference}, {"green", RealReference},
+      {"blue", RealReference} } },
+    { "Map", { {"image", ImageReference},
+      {"dither-method", MagickDitherOptions} } },
+    { "MatteFloodfill", { {"geometry", StringReference},
+      {"x", IntegerReference}, {"y", IntegerReference},
+      {"opacity", StringReference}, {"bordercolor", StringReference},
+      {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
+    { "Modulate", { {"factor", StringReference}, {"hue", RealReference},
+      {"saturation", RealReference}, {"whiteness", RealReference},
+      {"brightness", RealReference}, {"lightness", RealReference},
+      {"blackness", RealReference} } },
+    { "Negate", { {"gray", MagickBooleanOptions},
+      {"channel", MagickChannelOptions} } },
+    { "Normalize", { {"channel", MagickChannelOptions} } },
+    { "NumberColors", },
+    { "Opaque", { {"color", StringReference}, {"fill", StringReference},
+      {"fuzz", StringReference}, {"channel", MagickChannelOptions},
+      {"invert", MagickBooleanOptions} } },
+    { "Quantize", { {"colors", IntegerReference},
+      {"treedepth", IntegerReference}, {"colorspace", MagickColorspaceOptions},
+      {"dither", MagickDitherOptions}, {"measure", MagickBooleanOptions},
+      {"global", MagickBooleanOptions}, {"transparent-color", StringReference},
+      {"dither-method", MagickDitherOptions} } },
+    { "Raise", { {"geometry", StringReference}, {"width", IntegerReference},
+      {"height", IntegerReference}, {"raise", MagickBooleanOptions} } },
+    { "Segment", { {"geometry", StringReference},
+      {"cluster-threshold", RealReference},
+      {"smoothing-threshold", RealReference},
+      {"colorspace", MagickColorspaceOptions},
+      {"verbose", MagickBooleanOptions} } },
+    { "Signature", },
+    { "Solarize", { {"geometry", StringReference},
+      {"threshold", StringReference} } },
+    { "Sync", },
+    { "Texture", { {"texture", ImageReference} } },
+    { "Evaluate", { {"value", RealReference},
+      {"operator", MagickEvaluateOptions},
+      {"channel", MagickChannelOptions} } },
+    { "Transparent", { {"color", StringReference}, {"opacity", StringReference},
+      {"fuzz", StringReference}, {"invert", MagickBooleanOptions} } },
+    { "Threshold", { {"threshold", StringReference},
+      {"channel", MagickChannelOptions} } },
+    { "Charcoal", { {"geometry", StringReference}, {"radius", RealReference},
+      {"sigma", RealReference} } },
+    { "Trim", { {"fuzz", StringReference} } },
+    { "Wave", { {"geometry", StringReference}, {"amplitude", RealReference},
+      {"wavelength", RealReference},
+      {"interpolate", MagickInterpolateOptions} } },
+    { "Separate", { {"channel", MagickChannelOptions} } },
+    { "Condense", },
+    { "Stereo", { {"image", ImageReference}, {"x", IntegerReference},
+      {"y", IntegerReference} } },
+    { "Stegano", { {"image", ImageReference}, {"offset", IntegerReference} } },
+    { "Deconstruct", },
+    { "GaussianBlur", { {"geometry", StringReference},
+      {"radius", RealReference}, {"sigma", RealReference},
+      {"channel", MagickChannelOptions} } },
+    { "Convolve", { {"coefficients", ArrayReference},
+      {"channel", MagickChannelOptions}, {"bias", StringReference},
+      {"kernel", StringReference} } },
+    { "Profile", { {"name", StringReference}, {"profile", StringReference},
+      { "rendering-intent", MagickIntentOptions},
+      { "black-point-compensation", MagickBooleanOptions} } },
+    { "UnsharpMask", { {"geometry", StringReference},
+      {"radius", RealReference}, {"sigma", RealReference},
+      {"amount", RealReference}, {"threshold", RealReference},
+      {"channel", MagickChannelOptions} } },
+    { "MotionBlur", { {"geometry", StringReference},
+      {"radius", RealReference}, {"sigma", RealReference},
+      {"angle", RealReference}, {"channel", MagickChannelOptions} } },
+    { "OrderedDither", { {"threshold", StringReference},
+      {"channel", MagickChannelOptions} } },
+    { "Shave", { {"geometry", StringReference}, {"width", IntegerReference},
+      {"height", IntegerReference} } },
+    { "Level", { {"levels", StringReference}, {"black-point", RealReference},
+      {"white-point", RealReference}, {"gamma", RealReference},
+      {"channel", MagickChannelOptions}, {"level", StringReference} } },
+    { "Clip", { {"id", StringReference}, {"inside", MagickBooleanOptions} } },
+    { "AffineTransform", { {"affine", ArrayReference},
+      {"translate", StringReference}, {"scale", StringReference},
+      {"rotate", RealReference}, {"skewX", RealReference},
+      {"skewY", RealReference}, {"interpolate", MagickInterpolateOptions},
+      {"background", StringReference} } },
+    { "Difference", { {"image", ImageReference}, {"fuzz", StringReference} } },
+    { "AdaptiveThreshold", { {"geometry", StringReference},
+      {"width", IntegerReference}, {"height", IntegerReference} } },
+    { "Resample", { {"density", StringReference}, {"x", RealReference},
+      {"y", RealReference}, {"filter", MagickFilterOptions},
+      {"support", RealReference } } },
+    { "Describe", { {"file", FileReference} } },
+    { "BlackThreshold", { {"threshold", StringReference},
+      {"channel", MagickChannelOptions} } },
+    { "WhiteThreshold", { {"threshold", StringReference},
+      {"channel", MagickChannelOptions} } },
+    { "RadialBlur", { {"geometry", StringReference}, {"angle", RealReference},
+      {"channel", MagickChannelOptions} } },
+    { "Thumbnail", { {"geometry", StringReference}, {"width", IntegerReference},
+      {"height", IntegerReference} } },
+    { "Strip", },
+    { "Tint", { {"fill", StringReference}, {"blend", StringReference} } },
+    { "Channel", { {"channel", MagickChannelOptions} } },
+    { "Splice", { {"geometry", StringReference}, {"width", IntegerReference},
+      {"height", IntegerReference}, {"x", IntegerReference},
+      {"y", IntegerReference}, {"fuzz", StringReference},
+      {"background", StringReference}, {"gravity", MagickGravityOptions} } },
+    { "Posterize", { {"levels", IntegerReference},
+      {"dither", MagickBooleanOptions} } },
+    { "Shadow", { {"geometry", StringReference}, {"alpha", RealReference},
+      {"sigma", RealReference}, {"x", IntegerReference},
+      {"y", IntegerReference} } },
+    { "Identify", { {"file", FileReference}, {"features", StringReference},
+      {"unique", MagickBooleanOptions} } },
+    { "SepiaTone", { {"threshold", RealReference} } },
+    { "SigmoidalContrast", { {"geometry", StringReference},
+      {"contrast", RealReference}, {"mid-point", RealReference},
+      {"channel", MagickChannelOptions}, {"sharpen", MagickBooleanOptions} } },
+    { "Extent", { {"geometry", StringReference}, {"width", IntegerReference},
+      {"height", IntegerReference}, {"x", IntegerReference},
+      {"y", IntegerReference}, {"fuzz", StringReference},
+      {"background", StringReference}, {"gravity", MagickGravityOptions} } },
+    { "Vignette", { {"geometry", StringReference}, {"radius", RealReference},
+      {"sigma", RealReference}, {"x", IntegerReference},
+      {"y", IntegerReference}, {"background", StringReference} } },
+    { "ContrastStretch", { {"levels", StringReference},
+      {"black-point", RealReference},{"white-point", RealReference},
+      {"channel", MagickChannelOptions} } },
+    { "Sans0", },
+    { "Sans1", },
+    { "AdaptiveSharpen", { {"geometry", StringReference},
+      {"radius", RealReference}, {"sigma", RealReference},
+      {"bias", RealReference}, {"channel", MagickChannelOptions} } },
+    { "Transpose", },
+    { "Transverse", },
+    { "AutoOrient", },
+    { "AdaptiveBlur", { {"geometry", StringReference},
+      {"radius", RealReference}, {"sigma", RealReference},
+      {"channel", MagickChannelOptions} } },
+    { "Sketch", { {"geometry", StringReference},
+      {"radius", RealReference}, {"sigma", RealReference},
+      {"angle", RealReference} } },
+    { "UniqueColors", },
+    { "AdaptiveResize", { {"geometry", StringReference},
+      {"width", IntegerReference}, {"height", IntegerReference},
+      {"filter", MagickFilterOptions}, {"support", StringReference },
+      {"blur", RealReference } } },
+    { "ClipMask", { {"mask", ImageReference} } },
+    { "LinearStretch", { {"levels", StringReference},
+      {"black-point", RealReference},{"white-point", RealReference} } },
+    { "ColorMatrix", { {"matrix", ArrayReference} } },
+    { "Mask", { {"mask", ImageReference} } },
+    { "Polaroid", { {"caption", StringReference}, {"angle", RealReference},
+      {"font", StringReference}, {"stroke", StringReference},
+      {"fill", StringReference}, {"strokewidth", RealReference},
+      {"pointsize", RealReference}, {"gravity", MagickGravityOptions},
+      {"background", StringReference},
+      {"interpolate", MagickInterpolateOptions} } },
+    { "FloodfillPaint", { {"geometry", StringReference},
+      {"x", IntegerReference}, {"y", IntegerReference},
+      {"fill", StringReference}, {"bordercolor", StringReference},
+      {"fuzz", StringReference}, {"channel", MagickChannelOptions},
+      {"invert", MagickBooleanOptions} } },
+    { "Distort", { {"points", ArrayReference}, {"method", MagickDistortOptions},
+      {"virtual-pixel", MagickVirtualPixelOptions},
+      {"best-fit", MagickBooleanOptions} } },
+    { "Clut", { {"image", ImageReference},
+      {"interpolate", MagickInterpolateOptions},
+      {"channel", MagickChannelOptions} } },
+    { "LiquidRescale", { {"geometry", StringReference},
+      {"width", IntegerReference}, {"height", IntegerReference},
+      {"delta-x", RealReference}, {"rigidity", RealReference } } },
+    { "Encipher", { {"passphrase", StringReference} } },
+    { "Decipher", { {"passphrase", StringReference} } },
+    { "Deskew", { {"geometry", StringReference},
+      {"threshold", StringReference} } },
+    { "Remap", { {"image", ImageReference},
+      {"dither-method", MagickDitherOptions} } },
+    { "SparseColor", { {"points", ArrayReference},
+      {"method", MagickSparseColorOptions},
+      {"virtual-pixel", MagickVirtualPixelOptions},
+      {"channel", MagickChannelOptions} } },
+    { "Function", { {"parameters", ArrayReference},
+      {"function", MagickFunctionOptions},
+      {"virtual-pixel", MagickVirtualPixelOptions} } },
+    { "SelectiveBlur", { {"geometry", StringReference},
+      {"radius", RealReference}, {"sigma", RealReference},
+      {"threshold", RealReference}, {"channel", MagickChannelOptions} } },
+    { "HaldClut", { {"image", ImageReference},
+      {"channel", MagickChannelOptions} } },
+    { "BlueShift", { {"factor", StringReference} } },
+    { "ForwardFourierTransform", { {"magnitude", MagickBooleanOptions} } },
+    { "InverseFourierTransform", { {"magnitude", MagickBooleanOptions} } },
+    { "ColorDecisionList", {
+      {"color-correction-collection", StringReference} } },
+    { "AutoGamma", { {"channel", MagickChannelOptions} } },
+    { "AutoLevel", { {"channel", MagickChannelOptions} } },
+    { "LevelColors", { {"invert", MagickBooleanOptions},
+      {"black-point", StringReference}, {"white-point", StringReference},
+      {"channel", MagickChannelOptions}, {"invert", MagickBooleanOptions} } },
+    { "Clamp", { {"channel", MagickChannelOptions} } },
+    { "BrightnessContrast", { {"levels", StringReference},
+      {"brightness", RealReference},{"contrast", RealReference},
+      {"channel", MagickChannelOptions} } },
+    { "Morphology", { {"kernel", StringReference},
+      {"channel", MagickChannelOptions}, {"method", MagickMorphologyOptions},
+      {"iterations", IntegerReference} } },
+    { "Sans", { {"matrix", ArrayReference} } },
+    { "Color", { {"color", StringReference} } },
+    { "Mode", { {"geometry", StringReference},
+      {"width", IntegerReference},{"height", IntegerReference},
+      {"channel", MagickChannelOptions} } },
+    { "Statistic", { {"geometry", StringReference},
+      {"width", IntegerReference},{"height", IntegerReference},
+      {"channel", MagickChannelOptions}, {"type", MagickStatisticOptions} } },
+    { "Perceptible", { {"epsilon", RealReference},
+      {"channel", MagickChannelOptions} } },
+    { "Poly", { {"terms", ArrayReference},
+      {"channel", MagickChannelOptions} } }
+  };
+
+static SplayTreeInfo
+  *magick_registry = (SplayTreeInfo *) NULL;
+
+/*
+  Forward declarations.
+*/
+static Image
+  *SetupList(pTHX_ SV *,struct PackageInfo **,SV ***,ExceptionInfo *);
+
+static ssize_t
+  strEQcase(const char *,const char *);
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   C l o n e P a c k a g e I n f o                                           %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  ClonePackageInfo makes a duplicate of the given info, or if info is NULL,
+%  a new one.
+%
+%  The format of the ClonePackageInfo routine is:
+%
+%      struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
+%        exception)
+%
+%  A description of each parameter follows:
+%
+%    o info: a structure of type info.
+%
+%    o exception: Return any errors or warnings in this structure.
+%
+*/
+static struct PackageInfo *ClonePackageInfo(struct PackageInfo *info,
+  ExceptionInfo *exception)
+{
+  struct PackageInfo
+    *clone_info;
+
+  clone_info=(struct PackageInfo *) AcquireQuantumMemory(1,sizeof(*clone_info));
+  if (clone_info == (struct PackageInfo *) NULL)
+    {
+      ThrowPerlException(exception,ResourceLimitError,
+        "UnableToClonePackageInfo",PackageName);
+      return((struct PackageInfo *) NULL);
+    }
+  if (info == (struct PackageInfo *) NULL)
+    {
+      clone_info->image_info=CloneImageInfo((ImageInfo *) NULL);
+      return(clone_info);
+    }
+  *clone_info=(*info);
+  clone_info->image_info=CloneImageInfo(info->image_info);
+  return(clone_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   c o n s t a n t                                                           %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  constant() returns a double value for the specified name.
+%
+%  The format of the constant routine is:
+%
+%      double constant(char *name,ssize_t sans)
+%
+%  A description of each parameter follows:
+%
+%    o value: Method constant returns a double value for the specified name.
+%
+%    o name: The name of the constant.
+%
+%    o sans: This integer value is not used.
+%
+*/
+static double constant(char *name,ssize_t sans)
+{
+  (void) sans;
+  errno=0;
+  switch (*name)
+  {
+    case 'B':
+    {
+      if (strEQ(name,"BlobError"))
+        return(BlobError);
+      if (strEQ(name,"BlobWarning"))
+        return(BlobWarning);
+      break;
+    }
+    case 'C':
+    {
+      if (strEQ(name,"CacheError"))
+        return(CacheError);
+      if (strEQ(name,"CacheWarning"))
+        return(CacheWarning);
+      if (strEQ(name,"CoderError"))
+        return(CoderError);
+      if (strEQ(name,"CoderWarning"))
+        return(CoderWarning);
+      if (strEQ(name,"ConfigureError"))
+        return(ConfigureError);
+      if (strEQ(name,"ConfigureWarning"))
+        return(ConfigureWarning);
+      if (strEQ(name,"CorruptImageError"))
+        return(CorruptImageError);
+      if (strEQ(name,"CorruptImageWarning"))
+        return(CorruptImageWarning);
+      break;
+    }
+    case 'D':
+    {
+      if (strEQ(name,"DelegateError"))
+        return(DelegateError);
+      if (strEQ(name,"DelegateWarning"))
+        return(DelegateWarning);
+      if (strEQ(name,"DrawError"))
+        return(DrawError);
+      if (strEQ(name,"DrawWarning"))
+        return(DrawWarning);
+      break;
+    }
+    case 'E':
+    {
+      if (strEQ(name,"ErrorException"))
+        return(ErrorException);
+      if (strEQ(name,"ExceptionError"))
+        return(CoderError);
+      if (strEQ(name,"ExceptionWarning"))
+        return(CoderWarning);
+      break;
+    }
+    case 'F':
+    {
+      if (strEQ(name,"FatalErrorException"))
+        return(FatalErrorException);
+      if (strEQ(name,"FileOpenError"))
+        return(FileOpenError);
+      if (strEQ(name,"FileOpenWarning"))
+        return(FileOpenWarning);
+      break;
+    }
+    case 'I':
+    {
+      if (strEQ(name,"ImageError"))
+        return(ImageError);
+      if (strEQ(name,"ImageWarning"))
+        return(ImageWarning);
+      break;
+    }
+    case 'M':
+    {
+      if (strEQ(name,"MaxRGB"))
+        return(QuantumRange);
+      if (strEQ(name,"MissingDelegateError"))
+        return(MissingDelegateError);
+      if (strEQ(name,"MissingDelegateWarning"))
+        return(MissingDelegateWarning);
+      if (strEQ(name,"ModuleError"))
+        return(ModuleError);
+      if (strEQ(name,"ModuleWarning"))
+        return(ModuleWarning);
+      break;
+    }
+    case 'O':
+    {
+      if (strEQ(name,"Opaque"))
+        return(OpaqueAlpha);
+      if (strEQ(name,"OptionError"))
+        return(OptionError);
+      if (strEQ(name,"OptionWarning"))
+        return(OptionWarning);
+      break;
+    }
+    case 'Q':
+    {
+      if (strEQ(name,"MAGICKCORE_QUANTUM_DEPTH"))
+        return(MAGICKCORE_QUANTUM_DEPTH);
+      if (strEQ(name,"QuantumDepth"))
+        return(MAGICKCORE_QUANTUM_DEPTH);
+      if (strEQ(name,"QuantumRange"))
+        return(QuantumRange);
+      break;
+    }
+    case 'R':
+    {
+      if (strEQ(name,"ResourceLimitError"))
+        return(ResourceLimitError);
+      if (strEQ(name,"ResourceLimitWarning"))
+        return(ResourceLimitWarning);
+      if (strEQ(name,"RegistryError"))
+        return(RegistryError);
+      if (strEQ(name,"RegistryWarning"))
+        return(RegistryWarning);
+      break;
+    }
+    case 'S':
+    {
+      if (strEQ(name,"StreamError"))
+        return(StreamError);
+      if (strEQ(name,"StreamWarning"))
+        return(StreamWarning);
+      if (strEQ(name,"Success"))
+        return(0);
+      break;
+    }
+    case 'T':
+    {
+      if (strEQ(name,"Transparent"))
+        return(TransparentAlpha);
+      if (strEQ(name,"TypeError"))
+        return(TypeError);
+      if (strEQ(name,"TypeWarning"))
+        return(TypeWarning);
+      break;
+    }
+    case 'W':
+    {
+      if (strEQ(name,"WarningException"))
+        return(WarningException);
+      break;
+    }
+    case 'X':
+    {
+      if (strEQ(name,"XServerError"))
+        return(XServerError);
+      if (strEQ(name,"XServerWarning"))
+        return(XServerWarning);
+      break;
+    }
+  }
+  errno=EINVAL;
+  return(0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   D e s t r o y P a c k a g e I n f o                                       %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  Method DestroyPackageInfo frees a previously created info structure.
+%
+%  The format of the DestroyPackageInfo routine is:
+%
+%      DestroyPackageInfo(struct PackageInfo *info)
+%
+%  A description of each parameter follows:
+%
+%    o info: a structure of type info.
+%
+*/
+static void DestroyPackageInfo(struct PackageInfo *info)
+{
+  info->image_info=DestroyImageInfo(info->image_info);
+  info=(struct PackageInfo *) RelinquishMagickMemory(info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   G e t L i s t                                                             %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  Method GetList is recursively called by SetupList to traverse the
+%  Image__Magick reference.  If building an reference_vector (see SetupList),
+%  *current is the current position in *reference_vector and *last is the final
+%  entry in *reference_vector.
+%
+%  The format of the GetList routine is:
+%
+%      GetList(info)
+%
+%  A description of each parameter follows:
+%
+%    o info: a structure of type info.
+%
+*/
+static Image *GetList(pTHX_ SV *reference,SV ***reference_vector,
+  ssize_t *current,ssize_t *last,ExceptionInfo *exception)
+{
+  Image
+    *image;
+
+  if (reference == (SV *) NULL)
+    return(NULL);
+  switch (SvTYPE(reference))
+  {
+    case SVt_PVAV:
+    {
+      AV
+        *av;
+
+      Image
+        *head,
+        *previous;
+
+      register ssize_t
+        i;
+
+      ssize_t
+        n;
+
+      /*
+        Array of images.
+      */
+      previous=(Image *) NULL;
+      head=(Image *) NULL;
+      av=(AV *) reference;
+      n=av_len(av);
+      for (i=0; i <= n; i++)
+      {
+        SV
+          **rv;
+
+        rv=av_fetch(av,i,0);
+        if (rv && *rv && sv_isobject(*rv))
+          {
+            image=GetList(aTHX_ SvRV(*rv),reference_vector,current,last,
+              exception);
+            if (image == (Image *) NULL)
+              continue;
+            if (image == previous)
+              {
+                image=CloneImage(image,0,0,MagickTrue,exception);
+                if (image == (Image *) NULL)
+                  return(NULL);
+              }
+            image->previous=previous;
+            *(previous ? &previous->next : &head)=image;
+            for (previous=image; previous->next; previous=previous->next) ;
+          }
+      }
+      return(head);
+    }
+    case SVt_PVMG:
+    {
+      /*
+        Blessed scalar, one image.
+      */
+      image=INT2PTR(Image *,SvIV(reference));
+      if (image == (Image *) NULL)
+        return(NULL);
+      image->previous=(Image *) NULL;
+      image->next=(Image *) NULL;
+      if (reference_vector)
+        {
+          if (*current == *last)
+            {
+              *last+=256;
+              if (*reference_vector == (SV **) NULL)
+                *reference_vector=(SV **) AcquireQuantumMemory(*last,
+                  sizeof(*reference_vector));
+              else
+                *reference_vector=(SV **) ResizeQuantumMemory(*reference_vector,
+                  *last,sizeof(*reference_vector));
+            }
+          if (*reference_vector == (SV **) NULL)
+            {
+              ThrowPerlException(exception,ResourceLimitError,
+                "MemoryAllocationFailed",PackageName);
+              return((Image *) NULL);
+            }
+          (*reference_vector)[*current]=reference;
+          (*reference_vector)[++(*current)]=NULL;
+        }
+      return(image);
+    }
+    default:
+      break;
+  }
+  (void) fprintf(stderr,"GetList: UnrecognizedType %.20g\n",
+    (double) SvTYPE(reference));
+  return((Image *) NULL);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   G e t P a c k a g e I n f o                                               %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  Method GetPackageInfo looks up or creates an info structure for the given
+%  Image__Magick reference.  If it does create a new one, the information in
+%  package_info is used to initialize it.
+%
+%  The format of the GetPackageInfo routine is:
+%
+%      struct PackageInfo *GetPackageInfo(void *reference,
+%        struct PackageInfo *package_info,ExceptionInfo *exception)
+%
+%  A description of each parameter follows:
+%
+%    o info: a structure of type info.
+%
+%    o exception: Return any errors or warnings in this structure.
+%
+*/
+static struct PackageInfo *GetPackageInfo(pTHX_ void *reference,
+  struct PackageInfo *package_info,ExceptionInfo *exception)
+{
+  char
+    message[MaxTextExtent];
+
+  struct PackageInfo
+    *clone_info;
+
+  SV
+    *sv;
+
+  (void) FormatLocaleString(message,MaxTextExtent,"%s::package%s%p",
+    PackageName,XS_VERSION,reference);
+  sv=perl_get_sv(message,(TRUE | 0x02));
+  if (sv == (SV *) NULL)
+    {
+      ThrowPerlException(exception,ResourceLimitError,"UnableToGetPackageInfo",
+        message);
+      return(package_info);
+    }
+  if (SvREFCNT(sv) == 0)
+    (void) SvREFCNT_inc(sv);
+  if (SvIOKp(sv) && (clone_info=INT2PTR(struct PackageInfo *,SvIV(sv))))
+    return(clone_info);
+  clone_info=ClonePackageInfo(package_info,exception);
+  sv_setiv(sv,PTR2IV(clone_info));
+  return(clone_info);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   S e t A t t r i b u t e                                                   %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  SetAttribute() sets the attribute to the value in sval.  This can change
+%  either or both of image or info.
+%
+%  The format of the SetAttribute routine is:
+%
+%      SetAttribute(struct PackageInfo *info,Image *image,char *attribute,
+%        SV *sval,ExceptionInfo *exception)
+%
+%  A description of each parameter follows:
+%
+%    o list: a list of strings.
+%
+%    o string: a character string.
+%
+*/
+
+static double SiPrefixToDoubleInterval(const char *string,const double interval)
+{
+  char
+    *q;
+
+  double
+    value;
+
+  value=InterpretSiPrefixValue(string,&q);
+  if (*q == '%')
+    value*=interval/100.0;
+  return(value);
+}
+
+static inline double StringToDouble(const char *string,char **sentinal)
+{
+  return(InterpretLocaleValue(string,sentinal));
+}
+
+static double StringToDoubleInterval(const char *string,const double interval)
+{
+  char
+    *q;
+
+  double
+    value;
+
+  value=InterpretLocaleValue(string,&q);
+  if (*q == '%')
+    value*=interval/100.0;
+  return(value);
+}
+
+static inline ssize_t StringToLong(const char *value)
+{
+  return(strtol(value,(char **) NULL,10));
+}
+
+static void SetAttribute(pTHX_ struct PackageInfo *info,Image *image,
+  const char *attribute,SV *sval,ExceptionInfo *exception)
+{
+  GeometryInfo
+    geometry_info;
+
+  long
+    x,
+    y;
+
+  PixelInfo
+    pixel;
+
+  MagickStatusType
+    flags;
+
+  PixelInfo
+    *color,
+    target_color;
+
+  ssize_t
+    sp;
+
+  switch (*attribute)
+  {
+    case 'A':
+    case 'a':
+    {
+      if (LocaleCompare(attribute,"adjoin") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
+            SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                SvPV(sval,na));
+              break;
+            }
+          if (info)
+            info->image_info->adjoin=sp != 0 ? MagickTrue : MagickFalse;
+          break;
+        }
+      if (LocaleCompare(attribute,"alpha") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickAlphaChannelOptions,
+            MagickFalse,SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                SvPV(sval,na));
+              break;
+            }
+          for ( ; image; image=image->next)
+            (void) SetImageAlphaChannel(image,(AlphaChannelOption) sp,
+              exception);
+          break;
+        }
+      if (LocaleCompare(attribute,"antialias") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
+            SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                SvPV(sval,na));
+              break;
+            }
+          if (info)
+            info->image_info->antialias=sp != 0 ? MagickTrue : MagickFalse;
+          break;
+        }
+      if (LocaleCompare(attribute,"area-limit") == 0)
+        {
+          MagickSizeType
+            limit;
+
+          limit=MagickResourceInfinity;
+          if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
+            limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
+              100.0);
+          (void) SetMagickResourceLimit(AreaResource,limit);
+          break;
+        }
+      if (LocaleCompare(attribute,"attenuate") == 0)
+        {
+          if (info)
+            (void) SetImageOption(info->image_info,attribute,SvPV(sval,na));
+          break;
+        }
+      if (LocaleCompare(attribute,"authenticate") == 0)
+        {
+          if (info)
+            SetImageOption(info->image_info,attribute,SvPV(sval,na));
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'B':
+    case 'b':
+    {
+      if (LocaleCompare(attribute,"background") == 0)
+        {
+          (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
+            exception);
+          if (info)
+            info->image_info->background_color=target_color;
+          for ( ; image; image=image->next)
+            image->background_color=target_color;
+          break;
+        }
+      if (LocaleCompare(attribute,"blue-primary") == 0)
+        {
+          for ( ; image; image=image->next)
+          {
+            flags=ParseGeometry(SvPV(sval,na),&geometry_info);
+            image->chromaticity.blue_primary.x=geometry_info.rho;
+            image->chromaticity.blue_primary.y=geometry_info.sigma;
+            if ((flags & SigmaValue) == 0)
+              image->chromaticity.blue_primary.y=
+                image->chromaticity.blue_primary.x;
+          }
+          break;
+        }
+      if (LocaleCompare(attribute,"bordercolor") == 0)
+        {
+          (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
+            exception);
+          if (info)
+            info->image_info->border_color=target_color;
+          for ( ; image; image=image->next)
+            image->border_color=target_color;
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'C':
+    case 'c':
+    {
+      if (LocaleCompare(attribute,"cache-threshold") == 0)
+        {
+          (void) SetMagickResourceLimit(MemoryResource,(MagickSizeType)
+            SiPrefixToDoubleInterval(SvPV(sval,na),100.0));
+          (void) SetMagickResourceLimit(MapResource,(MagickSizeType)
+            (2.0*SiPrefixToDoubleInterval(SvPV(sval,na),100.0)));
+          break;
+        }
+      if (LocaleCompare(attribute,"clip-mask") == 0)
+        {
+          Image
+            *clip_mask;
+
+          clip_mask=(Image *) NULL;
+          if (SvPOK(sval))
+            clip_mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
+          for ( ; image; image=image->next)
+            SetImageMask(image,clip_mask,exception);
+          break;
+        }
+      if (LocaleNCompare(attribute,"colormap",8) == 0)
+        {
+          for ( ; image; image=image->next)
+          {
+            int
+              items;
+
+            long
+              i;
+
+            if (image->storage_class == DirectClass)
+              continue;
+            i=0;
+            items=sscanf(attribute,"%*[^[][%ld",&i);
+            (void) items;
+            if (i > (ssize_t) image->colors)
+              i%=image->colors;
+            if ((strchr(SvPV(sval,na),',') == 0) ||
+                (strchr(SvPV(sval,na),')') != 0))
+              QueryColorCompliance(SvPV(sval,na),AllCompliance,
+                image->colormap+i,exception);
+            else
+              {
+                color=image->colormap+i;
+                pixel.red=color->red;
+                pixel.green=color->green;
+                pixel.blue=color->blue;
+                flags=ParseGeometry(SvPV(sval,na),&geometry_info);
+                pixel.red=geometry_info.rho;
+                pixel.green=geometry_info.sigma;
+                pixel.blue=geometry_info.xi;
+                color->red=ClampToQuantum(pixel.red);
+                color->green=ClampToQuantum(pixel.green);
+                color->blue=ClampToQuantum(pixel.blue);
+              }
+          }
+          break;
+        }
+      if (LocaleCompare(attribute,"colorspace") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickColorspaceOptions,
+            MagickFalse,SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,"UnrecognizedColorspace",
+                SvPV(sval,na));
+              break;
+            }
+          for ( ; image; image=image->next)
+            (void) TransformImageColorspace(image,(ColorspaceType) sp,
+              exception);
+          break;
+        }
+      if (LocaleCompare(attribute,"comment") == 0)
+        {
+          for ( ; image; image=image->next)
+            (void) SetImageProperty(image,"Comment",InterpretImageProperties(
+              info ? info->image_info : (ImageInfo *) NULL,image,
+              SvPV(sval,na),exception),exception);
+          break;
+        }
+      if (LocaleCompare(attribute,"compression") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickCompressOptions,
+            MagickFalse,SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,
+                "UnrecognizedImageCompression",SvPV(sval,na));
+              break;
+            }
+          if (info)
+            info->image_info->compression=(CompressionType) sp;
+          for ( ; image; image=image->next)
+            image->compression=(CompressionType) sp;
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'D':
+    case 'd':
+    {
+      if (LocaleCompare(attribute,"debug") == 0)
+        {
+          SetLogEventMask(SvPV(sval,na));
+          break;
+        }
+      if (LocaleCompare(attribute,"delay") == 0)
+        {
+          flags=ParseGeometry(SvPV(sval,na),&geometry_info);
+          for ( ; image; image=image->next)
+          {
+            image->delay=(size_t) floor(geometry_info.rho+0.5);
+            if ((flags & SigmaValue) != 0)
+              image->ticks_per_second=(ssize_t)
+                floor(geometry_info.sigma+0.5);
+          }
+          break;
+        }
+      if (LocaleCompare(attribute,"disk-limit") == 0)
+        {
+          MagickSizeType
+            limit;
+
+          limit=MagickResourceInfinity;
+          if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
+            limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
+              100.0);
+          (void) SetMagickResourceLimit(DiskResource,limit);
+          break;
+        }
+      if (LocaleCompare(attribute,"density") == 0)
+        {
+          if (IsGeometry(SvPV(sval,na)) == MagickFalse)
+            {
+              ThrowPerlException(exception,OptionError,"MissingGeometry",
+                SvPV(sval,na));
+              break;
+            }
+          if (info)
+            (void) CloneString(&info->image_info->density,SvPV(sval,na));
+          for ( ; image; image=image->next)
+          {
+            flags=ParseGeometry(SvPV(sval,na),&geometry_info);
+            image->resolution.x=geometry_info.rho;
+            image->resolution.y=geometry_info.sigma;
+            if ((flags & SigmaValue) == 0)
+              image->resolution.y=image->resolution.x;
+          }
+          break;
+        }
+      if (LocaleCompare(attribute,"depth") == 0)
+        {
+          if (info)
+            info->image_info->depth=SvIV(sval);
+          for ( ; image; image=image->next)
+            (void) SetImageDepth(image,SvIV(sval),exception);
+          break;
+        }
+      if (LocaleCompare(attribute,"dispose") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickDisposeOptions,MagickFalse,
+            SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,
+                "UnrecognizedDisposeMethod",SvPV(sval,na));
+              break;
+            }
+          for ( ; image; image=image->next)
+            image->dispose=(DisposeType) sp;
+          break;
+        }
+      if (LocaleCompare(attribute,"dither") == 0)
+        {
+          if (info)
+            {
+              sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,
+                MagickFalse,SvPV(sval,na)) : SvIV(sval);
+              if (sp < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(sval,na));
+                  break;
+                }
+              info->image_info->dither=sp != 0 ? MagickTrue : MagickFalse;
+            }
+          break;
+        }
+      if (LocaleCompare(attribute,"display") == 0)
+        {
+          display:
+          if (info)
+            (void) CloneString(&info->image_info->server_name,SvPV(sval,na));
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'E':
+    case 'e':
+    {
+      if (LocaleCompare(attribute,"endian") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickEndianOptions,MagickFalse,
+            SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,"UnrecognizedEndianType",
+                SvPV(sval,na));
+              break;
+            }
+          if (info)
+            info->image_info->endian=(EndianType) sp;
+          for ( ; image; image=image->next)
+            image->endian=(EndianType) sp;
+          break;
+        }
+      if (LocaleCompare(attribute,"extract") == 0)
+        {
+          /*
+            Set image extract geometry.
+          */
+          (void) CloneString(&info->image_info->extract,SvPV(sval,na));
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'F':
+    case 'f':
+    {
+      if (LocaleCompare(attribute,"filename") == 0)
+        {
+          if (info)
+            (void) CopyMagickString(info->image_info->filename,SvPV(sval,na),
+              MaxTextExtent);
+          for ( ; image; image=image->next)
+            (void) CopyMagickString(image->filename,SvPV(sval,na),
+              MaxTextExtent);
+          break;
+        }
+      if (LocaleCompare(attribute,"file") == 0)
+        {
+          FILE
+            *file;
+
+          PerlIO
+            *io_info;
+
+          if (info == (struct PackageInfo *) NULL)
+            break;
+          io_info=IoIFP(sv_2io(sval));
+          if (io_info == (PerlIO *) NULL)
+            {
+              ThrowPerlException(exception,BlobError,"UnableToOpenFile",
+                PackageName);
+              break;
+            }
+          file=PerlIO_findFILE(io_info);
+          if (file == (FILE *) NULL)
+            {
+              ThrowPerlException(exception,BlobError,"UnableToOpenFile",
+                PackageName);
+              break;
+            }
+          SetImageInfoFile(info->image_info,file);
+          break;
+        }
+      if (LocaleCompare(attribute,"fill") == 0)
+        {
+          if (info)
+            (void) SetImageOption(info->image_info,"fill",SvPV(sval,na));
+          break;
+        }
+      if (LocaleCompare(attribute,"font") == 0)
+        {
+          if (info)
+            (void) CloneString(&info->image_info->font,SvPV(sval,na));
+          break;
+        }
+      if (LocaleCompare(attribute,"foreground") == 0)
+        break;
+      if (LocaleCompare(attribute,"fuzz") == 0)
+        {
+          if (info)
+            info->image_info->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
+              QuantumRange+1.0);
+          for ( ; image; image=image->next)
+            image->fuzz=StringToDoubleInterval(SvPV(sval,na),(double)
+              QuantumRange+1.0);
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'G':
+    case 'g':
+    {
+      if (LocaleCompare(attribute,"gamma") == 0)
+        {
+          for ( ; image; image=image->next)
+            image->gamma=SvNV(sval);
+          break;
+        }
+      if (LocaleCompare(attribute,"gravity") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickGravityOptions,MagickFalse,
+            SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,
+                "UnrecognizedGravityType",SvPV(sval,na));
+              break;
+            }
+          if (info)
+            SetImageOption(info->image_info,attribute,SvPV(sval,na));
+          for ( ; image; image=image->next)
+            image->gravity=(GravityType) sp;
+          break;
+        }
+      if (LocaleCompare(attribute,"green-primary") == 0)
+        {
+          for ( ; image; image=image->next)
+          {
+            flags=ParseGeometry(SvPV(sval,na),&geometry_info);
+            image->chromaticity.green_primary.x=geometry_info.rho;
+            image->chromaticity.green_primary.y=geometry_info.sigma;
+            if ((flags & SigmaValue) == 0)
+              image->chromaticity.green_primary.y=
+                image->chromaticity.green_primary.x;
+          }
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'I':
+    case 'i':
+    {
+      if (LocaleNCompare(attribute,"index",5) == 0)
+        {
+          int
+            items;
+
+          long
+            index;
+
+          register Quantum
+            *q;
+
+          CacheView
+            *image_view;
+
+          for ( ; image; image=image->next)
+          {
+            if (image->storage_class != PseudoClass)
+              continue;
+            x=0;
+            y=0;
+            items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
+            (void) items;
+            image_view=AcquireAuthenticCacheView(image,exception);
+            q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
+            if (q != (Quantum *) NULL)
+              {
+                items=sscanf(SvPV(sval,na),"%ld",&index);
+                if ((index >= 0) && (index < (ssize_t) image->colors))
+                  SetPixelIndex(image,index,q);
+                (void) SyncCacheViewAuthenticPixels(image_view,exception);
+              }
+            image_view=DestroyCacheView(image_view);
+          }
+          break;
+        }
+      if (LocaleCompare(attribute,"iterations") == 0)
+        {
+  iterations:
+          for ( ; image; image=image->next)
+            image->iterations=SvIV(sval);
+          break;
+        }
+      if (LocaleCompare(attribute,"interlace") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickInterlaceOptions,
+            MagickFalse,SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,
+                "UnrecognizedInterlaceType",SvPV(sval,na));
+              break;
+            }
+          if (info)
+            info->image_info->interlace=(InterlaceType) sp;
+          for ( ; image; image=image->next)
+            image->interlace=(InterlaceType) sp;
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'L':
+    case 'l':
+    {
+      if (LocaleCompare(attribute,"label") == 0)
+        {
+          for ( ; image; image=image->next)
+            (void) SetImageProperty(image,"label",InterpretImageProperties(
+              info ? info->image_info : (ImageInfo *) NULL,image,
+              SvPV(sval,na),exception),exception);
+          break;
+        }
+      if (LocaleCompare(attribute,"loop") == 0)
+        goto iterations;
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'M':
+    case 'm':
+    {
+      if (LocaleCompare(attribute,"magick") == 0)
+        {
+          if (info)
+            (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
+              "%s:",SvPV(sval,na));
+          for ( ; image; image=image->next)
+            (void) CopyMagickString(image->magick,SvPV(sval,na),MaxTextExtent);
+          break;
+        }
+      if (LocaleCompare(attribute,"map-limit") == 0)
+        {
+          MagickSizeType
+            limit;
+
+          limit=MagickResourceInfinity;
+          if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
+            limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
+              100.0);
+          (void) SetMagickResourceLimit(MapResource,limit);
+          break;
+        }
+      if (LocaleCompare(attribute,"mask") == 0)
+        {
+          Image
+            *mask;
+
+          mask=(Image *) NULL;
+          if (SvPOK(sval))
+            mask=SetupList(aTHX_ SvRV(sval),&info,(SV ***) NULL,exception);
+          for ( ; image; image=image->next)
+            SetImageMask(image,mask,exception);
+          break;
+        }
+      if (LocaleCompare(attribute,"mattecolor") == 0)
+        {
+          (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
+            exception);
+          if (info)
+            info->image_info->matte_color=target_color;
+          for ( ; image; image=image->next)
+            image->matte_color=target_color;
+          break;
+        }
+      if (LocaleCompare(attribute,"matte") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
+            SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                SvPV(sval,na));
+              break;
+            }
+          for ( ; image; image=image->next)
+            image->alpha_trait=sp != 0 ? BlendPixelTrait : UndefinedPixelTrait;
+          break;
+        }
+      if (LocaleCompare(attribute,"memory-limit") == 0)
+        {
+          MagickSizeType
+            limit;
+
+          limit=MagickResourceInfinity;
+          if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
+            limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
+              100.0);
+          (void) SetMagickResourceLimit(MemoryResource,limit);
+          break;
+        }
+      if (LocaleCompare(attribute,"monochrome") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
+            SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                SvPV(sval,na));
+              break;
+            }
+          if (info)
+            info->image_info->monochrome=sp != 0 ? MagickTrue : MagickFalse;
+          for ( ; image; image=image->next)
+            (void) SetImageType(image,BilevelType,exception);
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'O':
+    case 'o':
+    {
+      if (LocaleCompare(attribute,"option") == 0)
+        {
+          if (info)
+            DefineImageOption(info->image_info,SvPV(sval,na));
+          break;
+        }
+      if (LocaleCompare(attribute,"orientation") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickOrientationOptions,
+            MagickFalse,SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,
+                "UnrecognizedOrientationType",SvPV(sval,na));
+              break;
+            }
+          if (info)
+            info->image_info->orientation=(OrientationType) sp;
+          for ( ; image; image=image->next)
+            image->orientation=(OrientationType) sp;
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'P':
+    case 'p':
+    {
+      if (LocaleCompare(attribute,"page") == 0)
+        {
+          char
+            *geometry;
+
+          geometry=GetPageGeometry(SvPV(sval,na));
+          if (info)
+            (void) CloneString(&info->image_info->page,geometry);
+          for ( ; image; image=image->next)
+            (void) ParsePageGeometry(image,geometry,&image->page,exception);
+          geometry=(char *) RelinquishMagickMemory(geometry);
+          break;
+        }
+      if (LocaleNCompare(attribute,"pixel",5) == 0)
+        {
+          int
+            items;
+
+          PixelInfo
+            pixel;
+
+          register Quantum
+            *q;
+
+          CacheView
+            *image_view;
+
+          for ( ; image; image=image->next)
+          {
+            if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
+              break;
+            x=0;
+            y=0;
+            items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
+            (void) items;
+            image_view=AcquireVirtualCacheView(image,exception);
+            q=GetCacheViewAuthenticPixels(image_view,x,y,1,1,exception);
+            if (q != (Quantum *) NULL)
+              {
+                if ((strchr(SvPV(sval,na),',') == 0) ||
+                    (strchr(SvPV(sval,na),')') != 0))
+                  QueryColorCompliance(SvPV(sval,na),AllCompliance,
+                    &pixel,exception);
+                else
+                  {
+                    GetPixelInfo(image,&pixel);
+                    flags=ParseGeometry(SvPV(sval,na),&geometry_info);
+                    pixel.red=geometry_info.rho;
+                    if ((flags & SigmaValue) != 0)
+                      pixel.green=geometry_info.sigma;
+                    if ((flags & XiValue) != 0)
+                      pixel.blue=geometry_info.xi;
+                    if ((flags & PsiValue) != 0)
+                      pixel.alpha=geometry_info.psi;
+                    if ((flags & ChiValue) != 0)
+                      pixel.black=geometry_info.chi;
+                  }
+                SetPixelRed(image,ClampToQuantum(pixel.red),q);
+                SetPixelGreen(image,ClampToQuantum(pixel.green),q);
+                SetPixelBlue(image,ClampToQuantum(pixel.blue),q);
+                if (image->colorspace == CMYKColorspace)
+                  SetPixelBlack(image,ClampToQuantum(pixel.black),q);
+                SetPixelAlpha(image,ClampToQuantum(pixel.alpha),q);
+                (void) SyncCacheViewAuthenticPixels(image_view,exception);
+              }
+            image_view=DestroyCacheView(image_view);
+          }
+          break;
+        }
+      if (LocaleCompare(attribute,"pointsize") == 0)
+        {
+          if (info)
+            {
+              (void) ParseGeometry(SvPV(sval,na),&geometry_info);
+              info->image_info->pointsize=geometry_info.rho;
+            }
+          break;
+        }
+      if (LocaleCompare(attribute,"preview") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickPreviewOptions,MagickFalse,
+            SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                SvPV(sval,na));
+              break;
+            }
+          if (info)
+            info->image_info->preview_type=(PreviewType) sp;
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'Q':
+    case 'q':
+    {
+      if (LocaleCompare(attribute,"quality") == 0)
+        {
+          if (info)
+            info->image_info->quality=SvIV(sval);
+          for ( ; image; image=image->next)
+            image->quality=SvIV(sval);
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'R':
+    case 'r':
+    {
+      if (LocaleCompare(attribute,"red-primary") == 0)
+        {
+          for ( ; image; image=image->next)
+          {
+            flags=ParseGeometry(SvPV(sval,na),&geometry_info);
+            image->chromaticity.red_primary.x=geometry_info.rho;
+            image->chromaticity.red_primary.y=geometry_info.sigma;
+            if ((flags & SigmaValue) == 0)
+              image->chromaticity.red_primary.y=
+                image->chromaticity.red_primary.x;
+          }
+          break;
+        }
+      if (LocaleCompare(attribute,"render") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickIntentOptions,MagickFalse,
+            SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,"UnrecognizedIntentType",
+                SvPV(sval,na));
+              break;
+            }
+         for ( ; image; image=image->next)
+           image->rendering_intent=(RenderingIntent) sp;
+         break;
+       }
+      if (LocaleCompare(attribute,"repage") == 0)
+        {
+          RectangleInfo
+            geometry;
+
+          for ( ; image; image=image->next)
+          {
+            flags=ParseAbsoluteGeometry(SvPV(sval,na),&geometry);
+            if ((flags & WidthValue) != 0)
+              {
+                if ((flags & HeightValue) == 0)
+                  geometry.height=geometry.width;
+                image->page.width=geometry.width;
+                image->page.height=geometry.height;
+              }
+            if ((flags & AspectValue) != 0)
+              {
+                if ((flags & XValue) != 0)
+                  image->page.x+=geometry.x;
+                if ((flags & YValue) != 0)
+                  image->page.y+=geometry.y;
+              }
+            else
+              {
+                if ((flags & XValue) != 0)
+                  {
+                    image->page.x=geometry.x;
+                    if (((flags & WidthValue) != 0) && (geometry.x > 0))
+                      image->page.width=image->columns+geometry.x;
+                  }
+                if ((flags & YValue) != 0)
+                  {
+                    image->page.y=geometry.y;
+                    if (((flags & HeightValue) != 0) && (geometry.y > 0))
+                      image->page.height=image->rows+geometry.y;
+                  }
+              }
+          }
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'S':
+    case 's':
+    {
+      if (LocaleCompare(attribute,"sampling-factor") == 0)
+        {
+          if (IsGeometry(SvPV(sval,na)) == MagickFalse)
+            {
+              ThrowPerlException(exception,OptionError,"MissingGeometry",
+                SvPV(sval,na));
+              break;
+            }
+          if (info)
+            (void) CloneString(&info->image_info->sampling_factor,
+              SvPV(sval,na));
+          break;
+        }
+      if (LocaleCompare(attribute,"scene") == 0)
+        {
+          for ( ; image; image=image->next)
+            image->scene=SvIV(sval);
+          break;
+        }
+      if (LocaleCompare(attribute,"server") == 0)
+        goto display;
+      if (LocaleCompare(attribute,"size") == 0)
+        {
+          if (info)
+            {
+              if (IsGeometry(SvPV(sval,na)) == MagickFalse)
+                {
+                  ThrowPerlException(exception,OptionError,"MissingGeometry",
+                    SvPV(sval,na));
+                  break;
+                }
+              (void) CloneString(&info->image_info->size,SvPV(sval,na));
+            }
+          break;
+        }
+      if (LocaleCompare(attribute,"stroke") == 0)
+        {
+          if (info)
+            (void) SetImageOption(info->image_info,"stroke",SvPV(sval,na));
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'T':
+    case 't':
+    {
+      if (LocaleCompare(attribute,"texture") == 0)
+        {
+          if (info)
+            (void) CloneString(&info->image_info->texture,SvPV(sval,na));
+          break;
+        }
+      if (LocaleCompare(attribute,"thread-limit") == 0)
+        {
+          MagickSizeType
+            limit;
+
+          limit=MagickResourceInfinity;
+          if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
+            limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
+              100.0);
+          (void) SetMagickResourceLimit(ThreadResource,limit);
+          break;
+        }
+      if (LocaleCompare(attribute,"tile-offset") == 0)
+        {
+          char
+            *geometry;
+
+          geometry=GetPageGeometry(SvPV(sval,na));
+          if (info)
+            (void) CloneString(&info->image_info->page,geometry);
+          for ( ; image; image=image->next)
+            (void) ParsePageGeometry(image,geometry,&image->tile_offset,
+              exception);
+          geometry=(char *) RelinquishMagickMemory(geometry);
+          break;
+        }
+      if (LocaleCompare(attribute,"time-limit") == 0)
+        {
+          MagickSizeType
+            limit;
+
+          limit=MagickResourceInfinity;
+          if (LocaleCompare(SvPV(sval,na),"unlimited") != 0)
+            limit=(MagickSizeType) SiPrefixToDoubleInterval(SvPV(sval,na),
+              100.0);
+          (void) SetMagickResourceLimit(TimeResource,limit);
+          break;
+        }
+      if (LocaleCompare(attribute,"transparent-color") == 0)
+        {
+          (void) QueryColorCompliance(SvPV(sval,na),AllCompliance,&target_color,
+            exception);
+          if (info)
+            info->image_info->transparent_color=target_color;
+          for ( ; image; image=image->next)
+            image->transparent_color=target_color;
+          break;
+        }
+      if (LocaleCompare(attribute,"type") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickTypeOptions,MagickFalse,
+            SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                SvPV(sval,na));
+              break;
+            }
+          if (info)
+            info->image_info->type=(ImageType) sp;
+          for ( ; image; image=image->next)
+            SetImageType(image,(ImageType) sp,exception);
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'U':
+    case 'u':
+    {
+      if (LocaleCompare(attribute,"units") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickResolutionOptions,
+            MagickFalse,SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,"UnrecognizedUnitsType",
+                SvPV(sval,na));
+              break;
+            }
+          if (info)
+            info->image_info->units=(ResolutionType) sp;
+          for ( ; image; image=image->next)
+          {
+            ResolutionType
+              units;
+
+            units=(ResolutionType) sp;
+            if (image->units != units)
+              switch (image->units)
+              {
+                case UndefinedResolution:
+                case PixelsPerInchResolution:
+                {
+                  if (units == PixelsPerCentimeterResolution)
+                    {
+                      image->resolution.x*=2.54;
+                      image->resolution.y*=2.54;
+                    }
+                  break;
+                }
+                case PixelsPerCentimeterResolution:
+                {
+                  if (units == PixelsPerInchResolution)
+                    {
+                      image->resolution.x/=2.54;
+                      image->resolution.y/=2.54;
+                    }
+                  break;
+                }
+              }
+            image->units=units;
+          }
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'V':
+    case 'v':
+    {
+      if (LocaleCompare(attribute,"verbose") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickBooleanOptions,MagickFalse,
+            SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                SvPV(sval,na));
+              break;
+            }
+          if (info)
+            info->image_info->verbose=sp != 0 ? MagickTrue : MagickFalse;
+          break;
+        }
+      if (LocaleCompare(attribute,"view") == 0)
+        {
+          if (info)
+            (void) CloneString(&info->image_info->view,SvPV(sval,na));
+          break;
+        }
+      if (LocaleCompare(attribute,"virtual-pixel") == 0)
+        {
+          sp=SvPOK(sval) ? ParseCommandOption(MagickVirtualPixelOptions,
+            MagickFalse,SvPV(sval,na)) : SvIV(sval);
+          if (sp < 0)
+            {
+              ThrowPerlException(exception,OptionError,
+                "UnrecognizedVirtualPixelMethod",SvPV(sval,na));
+              break;
+            }
+          for ( ; image; image=image->next)
+            SetImageVirtualPixelMethod(image,(VirtualPixelMethod) sp,exception);
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    case 'W':
+    case 'w':
+    {
+      if (LocaleCompare(attribute,"white-point") == 0)
+        {
+          for ( ; image; image=image->next)
+          {
+            flags=ParseGeometry(SvPV(sval,na),&geometry_info);
+            image->chromaticity.white_point.x=geometry_info.rho;
+            image->chromaticity.white_point.y=geometry_info.sigma;
+            if ((flags & SigmaValue) == 0)
+              image->chromaticity.white_point.y=
+                image->chromaticity.white_point.x;
+          }
+          break;
+        }
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+    default:
+    {
+      if (info)
+        SetImageOption(info->image_info,attribute,SvPV(sval,na));
+      for ( ; image; image=image->next)
+        SetImageProperty(image,attribute,SvPV(sval,na),exception);
+      break;
+    }
+  }
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   S e t u p L i s t                                                         %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  Method SetupList returns the list of all the images linked by their
+%  image->next and image->previous link lists for use with ImageMagick.  If
+%  info is non-NULL, an info structure is returned in *info.  If
+%  reference_vector is non-NULL,an array of SV* are returned in
+%  *reference_vector.  Reference_vector is used when the images are going to be
+%  replaced with new Image*'s.
+%
+%  The format of the SetupList routine is:
+%
+%      Image *SetupList(SV *reference,struct PackageInfo **info,
+%        SV ***reference_vector,ExceptionInfo *exception)
+%
+%  A description of each parameter follows:
+%
+%    o list: a list of strings.
+%
+%    o string: a character string.
+%
+%    o exception: Return any errors or warnings in this structure.
+%
+*/
+static Image *SetupList(pTHX_ SV *reference,struct PackageInfo **info,
+  SV ***reference_vector,ExceptionInfo *exception)
+{
+  Image
+    *image;
+
+  ssize_t
+    current,
+    last;
+
+  if (reference_vector)
+    *reference_vector=NULL;
+  if (info)
+    *info=NULL;
+  current=0;
+  last=0;
+  image=GetList(aTHX_ reference,reference_vector,&current,&last,exception);
+  if (info && (SvTYPE(reference) == SVt_PVAV))
+    *info=GetPackageInfo(aTHX_ (void *) reference,(struct PackageInfo *) NULL,
+      exception);
+  return(image);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   s t r E Q c a s e                                                         %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%  strEQcase() compares two strings and returns 0 if they are the
+%  same or if the second string runs out first.  The comparison is case
+%  insensitive.
+%
+%  The format of the strEQcase routine is:
+%
+%      ssize_t strEQcase(const char *p,const char *q)
+%
+%  A description of each parameter follows:
+%
+%    o p: a character string.
+%
+%    o q: a character string.
+%
+%
+*/
+static ssize_t strEQcase(const char *p,const char *q)
+{
+  char
+    c;
+
+  register ssize_t
+    i;
+
+  for (i=0 ; (c=(*q)) != 0; i++)
+  {
+    if ((isUPPER((unsigned char) c) ? toLOWER(c) : c) !=
+        (isUPPER((unsigned char) *p) ? toLOWER(*p) : *p))
+      return(0);
+    p++;
+    q++;
+  }
+  return(((*q == 0) && (*p == 0)) ? i : 0);
+}
+
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%   I m a g e : : M a g i c k                                                 %
+%                                                                             %
+%                                                                             %
+%                                                                             %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
+*/
+MODULE = Image::Magick::@MAGICK_ABI_SUFFIX@ PACKAGE = Image::Magick::@MAGICK_ABI_SUFFIX@
+
+PROTOTYPES: ENABLE
+
+BOOT:
+  MagickCoreGenesis("PerlMagick",MagickFalse);
+  SetWarningHandler(NULL);
+  SetErrorHandler(NULL);
+  magick_registry=NewSplayTree((int (*)(const void *,const void *))
+    NULL,(void *(*)(void *)) NULL,(void *(*)(void *)) NULL);
+
+void
+UNLOAD()
+  PPCODE:
+  {
+    if (magick_registry != (SplayTreeInfo *) NULL)
+      magick_registry=DestroySplayTree(magick_registry);
+    MagickCoreTerminus();
+  }
+
+double
+constant(name,argument)
+  char *name
+  ssize_t argument
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   A n i m a t e                                                             #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Animate(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    AnimateImage  = 1
+    animate       = 2
+    animateimage  = 3
+  PPCODE:
+  {
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    register ssize_t
+      i;
+
+    struct PackageInfo
+      *info,
+      *package_info;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    package_info=(struct PackageInfo *) NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    package_info=ClonePackageInfo(info,exception);
+    if (items == 2)
+      SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
+    else
+      if (items > 2)
+        for (i=2; i < items; i+=2)
+          SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
+            exception);
+    (void) AnimateImages(package_info->image_info,image,exception);
+    (void) CatchImageException(image);
+
+  PerlException:
+    if (package_info != (struct PackageInfo *) NULL)
+      DestroyPackageInfo(package_info);
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   A p p e n d                                                               #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Append(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    AppendImage  = 1
+    append       = 2
+    appendimage  = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      stack;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *av_reference,
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    attribute=NULL;
+    av=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    av=newAV();
+    av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    /*
+      Get options.
+    */
+    stack=MagickTrue;
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'S':
+        case 's':
+        {
+          if (LocaleCompare(attribute,"stack") == 0)
+            {
+              stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
+                SvPV(ST(i),na));
+              if (stack < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  return;
+                }
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    image=AppendImages(image,stack != 0 ? MagickTrue : MagickFalse,exception);
+    if (image == (Image *) NULL)
+      goto PerlException;
+    for ( ; image; image=image->next)
+    {
+      AddImageToRegistry(sv,image);
+      rv=newRV(sv);
+      av_push(av,sv_bless(rv,hv));
+      SvREFCNT_dec(sv);
+    }
+    exception=DestroyExceptionInfo(exception);
+    ST(0)=av_reference;
+    SvREFCNT_dec(perl_exception);
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   A v e r a g e                                                             #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Average(ref)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    AverageImage   = 1
+    average        = 2
+    averageimage   = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *p;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    image=EvaluateImages(image,MeanEvaluateOperator,exception);
+    if (image == (Image *) NULL)
+      goto PerlException;
+    /*
+      Create blessed Perl array for the returned image.
+    */
+    av=newAV();
+    ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    AddImageToRegistry(sv,image);
+    rv=newRV(sv);
+    av_push(av,sv_bless(rv,hv));
+    SvREFCNT_dec(sv);
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
+      "average-%.*s",(int) (MaxTextExtent-9),
+      ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
+    (void) CopyMagickString(image->filename,info->image_info->filename,
+      MaxTextExtent);
+    SetImageInfo(info->image_info,0,exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   B l o b T o I m a g e                                                     #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+BlobToImage(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    BlobToImage  = 1
+    blobtoimage  = 2
+    blobto       = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      **keep,
+      **list;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image;
+
+    register char
+      **p;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      ac,
+      n,
+      number_images;
+
+    STRLEN
+      *length;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    number_images=0;
+    ac=(items < 2) ? 1 : items-1;
+    length=(STRLEN *) NULL;
+    list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
+    if (list == (char **) NULL)
+      {
+        ThrowPerlException(exception,ResourceLimitError,
+          "MemoryAllocationFailed",PackageName);
+        goto PerlException;
+      }
+    length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
+    if (length == (STRLEN *) NULL)
+      {
+        ThrowPerlException(exception,ResourceLimitError,
+          "MemoryAllocationFailed",PackageName);
+        goto PerlException;
+      }
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    if (SvTYPE(reference) != SVt_PVAV)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    av=(AV *) reference;
+    info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
+      exception);
+    n=1;
+    if (items <= 1)
+      {
+        ThrowPerlException(exception,OptionError,"NoBlobDefined",PackageName);
+        goto PerlException;
+      }
+    for (n=0, i=0; i < ac; i++)
+    {
+      list[n]=(char *) (SvPV(ST(i+1),length[n]));
+      if ((items >= 3) && strEQcase((char *) SvPV(ST(i+1),na),"blob"))
+        {
+          list[n]=(char *) (SvPV(ST(i+2),length[n]));
+          continue;
+        }
+      n++;
+    }
+    list[n]=(char *) NULL;
+    keep=list;
+    for (i=number_images=0; i < n; i++)
+    {
+      image=BlobToImage(info->image_info,list[i],length[i],exception);
+      if (image == (Image *) NULL)
+        break;
+      for ( ; image; image=image->next)
+      {
+        AddImageToRegistry(sv,image);
+        rv=newRV(sv);
+        av_push(av,sv_bless(rv,hv));
+        SvREFCNT_dec(sv);
+        number_images++;
+      }
+    }
+    /*
+      Free resources.
+    */
+    for (i=0; i < n; i++)
+      if (list[i] != (char *) NULL)
+        for (p=keep; list[i] != *p++; )
+          if (*p == (char *) NULL)
+            {
+              list[i]=(char *) RelinquishMagickMemory(list[i]);
+              break;
+            }
+
+  PerlException:
+    if (list)
+      list=(char **) RelinquishMagickMemory(list);
+    if (length)
+      length=(STRLEN *) RelinquishMagickMemory(length);
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) number_images);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   C h a n n e l F x                                                         #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+ChannelFx(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    ChannelFxImage  = 1
+    channelfx       = 2
+    channelfximage  = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute,
+      expression[MaxTextExtent];
+
+    ChannelType
+      channel,
+      channel_mask;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image;
+
+    register ssize_t
+      i;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *av_reference,
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    attribute=NULL;
+    av=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    av=newAV();
+    av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    /*
+      Get options.
+    */
+    channel=DefaultChannels;
+    (void) CopyMagickString(expression,"u",MaxTextExtent);
+    if (items == 2)
+      (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MaxTextExtent);
+    else
+      for (i=2; i < items; i+=2)
+      {
+        attribute=(char *) SvPV(ST(i-1),na);
+        switch (*attribute)
+        {
+          case 'C':
+          case 'c':
+          {
+            if (LocaleCompare(attribute,"channel") == 0)
+              {
+                ssize_t
+                  option;
+
+                option=ParseChannelOption(SvPV(ST(i),na));
+                if (option < 0)
+                  {
+                    ThrowPerlException(exception,OptionError,
+                      "UnrecognizedType",SvPV(ST(i),na));
+                    return;
+                  }
+                channel=(ChannelType) option;
+                break;
+              }
+            ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+              attribute);
+            break;
+          }
+          case 'E':
+          case 'e':
+          {
+            if (LocaleCompare(attribute,"expression") == 0)
+              {
+                (void) CopyMagickString(expression,SvPV(ST(i),na),
+                  MaxTextExtent);
+                break;
+              }
+            ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+              attribute);
+            break;
+          }
+          default:
+          {
+            ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+              attribute);
+            break;
+          }
+        }
+      }
+    channel_mask=SetImageChannelMask(image,channel);
+    image=ChannelFxImage(image,expression,exception);
+    if (image != (Image *) NULL)
+      (void) SetImageChannelMask(image,channel_mask);
+    if (image == (Image *) NULL)
+      goto PerlException;
+    for ( ; image; image=image->next)
+    {
+      AddImageToRegistry(sv,image);
+      rv=newRV(sv);
+      av_push(av,sv_bless(rv,hv));
+      SvREFCNT_dec(sv);
+    }
+    exception=DestroyExceptionInfo(exception);
+    ST(0)=av_reference;
+    SvREFCNT_dec(perl_exception);  /* can't return warning messages */
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   C l o n e                                                                 #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Clone(ref)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    CopyImage   = 1
+    copy        = 2
+    copyimage   = 3
+    CloneImage  = 4
+    clone       = 5
+    cloneimage  = 6
+    Clone       = 7
+  PPCODE:
+  {
+    AV
+      *av;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *clone,
+      *image;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    /*
+      Create blessed Perl array for the returned image.
+    */
+    av=newAV();
+    ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    for ( ; image; image=image->next)
+    {
+      clone=CloneImage(image,0,0,MagickTrue,exception);
+      if (clone == (Image *) NULL)
+        break;
+      AddImageToRegistry(sv,clone);
+      rv=newRV(sv);
+      av_push(av,sv_bless(rv,hv));
+      SvREFCNT_dec(sv);
+    }
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   C L O N E                                                                 #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+CLONE(ref,...)
+  SV *ref;
+  CODE:
+  {
+    PERL_UNUSED_VAR(ref);
+    if (magick_registry != (SplayTreeInfo *) NULL)
+      {
+        register Image
+          *p;
+
+        ResetSplayTreeIterator(magick_registry);
+        p=(Image *) GetNextKeyInSplayTree(magick_registry);
+        while (p != (Image *) NULL)
+        {
+          ReferenceImage(p);
+          p=(Image *) GetNextKeyInSplayTree(magick_registry);
+        }
+      }
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   C o a l e s c e                                                           #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Coalesce(ref)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    CoalesceImage   = 1
+    coalesce        = 2
+    coalesceimage   = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *av_reference,
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    av=newAV();
+    av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    image=CoalesceImages(image,exception);
+    if (image == (Image *) NULL)
+      goto PerlException;
+    for ( ; image; image=image->next)
+    {
+      AddImageToRegistry(sv,image);
+      rv=newRV(sv);
+      av_push(av,sv_bless(rv,hv));
+      SvREFCNT_dec(sv);
+    }
+    exception=DestroyExceptionInfo(exception);
+    ST(0)=av_reference;
+    SvREFCNT_dec(perl_exception);
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   C o m p a r e                                                             #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Compare(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    CompareImages = 1
+    compare      = 2
+    compareimage = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute;
+
+    double
+      distortion;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *difference_image,
+      *image,
+      *reconstruct_image;
+
+    MetricType
+      metric;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      option;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *av_reference,
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    av=NULL;
+    attribute=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    av=newAV();
+    av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    /*
+      Get attribute.
+    */
+    reconstruct_image=image;
+    metric=RootMeanSquaredErrorMetric;
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'C':
+        case 'c':
+        {
+          if (LocaleCompare(attribute,"channel") == 0)
+            {
+              ssize_t
+                option;
+
+              option=ParseChannelOption(SvPV(ST(i),na));
+              if (option < 0)
+                {
+                  ThrowPerlException(exception,OptionError,
+                    "UnrecognizedType",SvPV(ST(i),na));
+                  return;
+                }
+              SetPixelChannelMask(image,(ChannelType) option);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'F':
+        case 'f':
+        {
+          if (LocaleCompare(attribute,"fuzz") == 0)
+            {
+              image->fuzz=StringToDoubleInterval(SvPV(ST(i),na),100.0);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'I':
+        case 'i':
+        {
+          if (LocaleCompare(attribute,"image") == 0)
+            {
+              reconstruct_image=SetupList(aTHX_ SvRV(ST(i)),
+                (struct PackageInfo **) NULL,(SV ***) NULL,exception);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'M':
+        case 'm':
+        {
+          if (LocaleCompare(attribute,"metric") == 0)
+            {
+              option=ParseCommandOption(MagickMetricOptions,MagickFalse,
+                SvPV(ST(i),na));
+              if (option < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  break;
+                }
+              metric=(MetricType) option;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    difference_image=CompareImages(image,reconstruct_image,metric,&distortion,
+      exception);
+    if (difference_image != (Image *) NULL)
+      {
+        difference_image->error.mean_error_per_pixel=distortion;
+        AddImageToRegistry(sv,difference_image);
+        rv=newRV(sv);
+        av_push(av,sv_bless(rv,hv));
+        SvREFCNT_dec(sv);
+      }
+    exception=DestroyExceptionInfo(exception);
+    ST(0)=av_reference;
+    SvREFCNT_dec(perl_exception);  /* can't return warning messages */
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   C o m p a r e L a y e r s                                                 #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+CompareLayers(ref)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    CompareImagesLayers   = 1
+    comparelayers        = 2
+    compareimagelayers   = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image;
+
+    LayerMethod
+      method;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      option;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *av_reference,
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    av=newAV();
+    av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    method=CompareAnyLayer;
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'M':
+        case 'm':
+        {
+          if (LocaleCompare(attribute,"method") == 0)
+            {
+              option=ParseCommandOption(MagickLayerOptions,MagickFalse,
+                SvPV(ST(i),na));
+              if (option < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  break;
+                }
+               method=(LayerMethod) option;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    image=CompareImagesLayers(image,method,exception);
+    if (image == (Image *) NULL)
+      goto PerlException;
+    for ( ; image; image=image->next)
+    {
+      AddImageToRegistry(sv,image);
+      rv=newRV(sv);
+      av_push(av,sv_bless(rv,hv));
+      SvREFCNT_dec(sv);
+    }
+    exception=DestroyExceptionInfo(exception);
+    ST(0)=av_reference;
+    SvREFCNT_dec(perl_exception);
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   D e s t r o y                                                             #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+DESTROY(ref)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  PPCODE:
+  {
+    SV
+      *reference;
+
+    PERL_UNUSED_VAR(ref);
+    if (sv_isobject(ST(0)) == 0)
+      croak("ReferenceIsNotMyType");
+    reference=SvRV(ST(0));
+    switch (SvTYPE(reference))
+    {
+      case SVt_PVAV:
+      {
+        char
+          message[MaxTextExtent];
+
+        const SV
+          *key;
+
+        HV
+          *hv;
+
+        GV
+          **gvp;
+
+        struct PackageInfo
+          *info;
+
+        SV
+          *sv;
+
+        /*
+          Array (AV *) reference
+        */
+        (void) FormatLocaleString(message,MaxTextExtent,"package%s%p",
+          XS_VERSION,reference);
+        hv=gv_stashpv(PackageName, FALSE);
+        if (!hv)
+          break;
+        gvp=(GV **) hv_fetch(hv,message,(long) strlen(message),FALSE);
+        if (!gvp)
+          break;
+        sv=GvSV(*gvp);
+        if (sv && (SvREFCNT(sv) == 1) && SvIOK(sv))
+          {
+            info=INT2PTR(struct PackageInfo *,SvIV(sv));
+            DestroyPackageInfo(info);
+          }
+        key=hv_delete(hv,message,(long) strlen(message),G_DISCARD);
+        (void) key;
+        break;
+      }
+      case SVt_PVMG:
+      {
+        Image
+          *image;
+
+        /*
+          Blessed scalar = (Image *) SvIV(reference)
+        */
+        image=INT2PTR(Image *,SvIV(reference));
+        if (image != (Image *) NULL)
+          DeleteImageFromRegistry(reference,image);
+        break;
+      }
+      default:
+        break;
+    }
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   D i s p l a y                                                             #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Display(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    DisplayImage  = 1
+    display       = 2
+    displayimage  = 3
+  PPCODE:
+  {
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    register ssize_t
+      i;
+
+    struct PackageInfo
+      *info,
+      *package_info;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    package_info=(struct PackageInfo *) NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    package_info=ClonePackageInfo(info,exception);
+    if (items == 2)
+      SetAttribute(aTHX_ package_info,NULL,"server",ST(1),exception);
+    else
+      if (items > 2)
+        for (i=2; i < items; i+=2)
+          SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
+            exception);
+    (void) DisplayImages(package_info->image_info,image,exception);
+    (void) CatchImageException(image);
+
+  PerlException:
+    if (package_info != (struct PackageInfo *) NULL)
+      DestroyPackageInfo(package_info);
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   E v a l u a t e I m a g e s                                               #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+EvaluateImages(ref)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    EvaluateImages   = 1
+    evaluateimages   = 2
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute,
+      *p;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image;
+
+    MagickEvaluateOperator
+      op;
+
+    register ssize_t
+      i;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    op=MeanEvaluateOperator;
+    if (items == 2)
+      {
+        ssize_t
+          in;
+
+        in=ParseCommandOption(MagickEvaluateOptions,MagickFalse,(char *)
+          SvPV(ST(1),na));
+        if (in < 0)
+          {
+            ThrowPerlException(exception,OptionError,"UnrecognizedType",
+              SvPV(ST(1),na));
+            return;
+          }
+        op=(MagickEvaluateOperator) in;
+      }
+    else
+      for (i=2; i < items; i+=2)
+      {
+        attribute=(char *) SvPV(ST(i-1),na);
+        switch (*attribute)
+        {
+          case 'O':
+          case 'o':
+          {
+            if (LocaleCompare(attribute,"operator") == 0)
+              {
+                ssize_t
+                  in;
+
+                in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
+                  MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
+                if (in < 0)
+                  {
+                    ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                      SvPV(ST(i),na));
+                    return;
+                  }
+                op=(MagickEvaluateOperator) in;
+                break;
+              }
+            ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+              attribute);
+            break;
+          }
+          default:
+          {
+            ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+              attribute);
+            break;
+          }
+        }
+      }
+    image=EvaluateImages(image,op,exception);
+    if (image == (Image *) NULL)
+      goto PerlException;
+    /*
+      Create blessed Perl array for the returned image.
+    */
+    av=newAV();
+    ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    AddImageToRegistry(sv,image);
+    rv=newRV(sv);
+    av_push(av,sv_bless(rv,hv));
+    SvREFCNT_dec(sv);
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
+      "evaluate-%.*s",(int) (MaxTextExtent-9),
+      ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
+    (void) CopyMagickString(image->filename,info->image_info->filename,
+      MaxTextExtent);
+    SetImageInfo(info->image_info,0,exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   F e a t u r e s                                                           #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Features(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    FeaturesImage = 1
+    features      = 2
+    featuresimage = 3
+  PPCODE:
+  {
+#define ChannelFeatures(channel,direction) \
+{ \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].angular_second_moment[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].contrast[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].contrast[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].variance_sum_of_squares[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].inverse_difference_moment[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].sum_average[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].sum_variance[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].sum_entropy[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].entropy[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].difference_variance[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].difference_entropy[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].measure_of_correlation_1[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].measure_of_correlation_2[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_features[channel].maximum_correlation_coefficient[direction]); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+}
+
+    AV
+      *av;
+
+    char
+      *attribute,
+      message[MaxTextExtent];
+
+    ChannelFeatures
+      *channel_features;
+
+    double
+      distance;
+
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      count;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    av=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    av=newAV();
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    distance=1;
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'D':
+        case 'd':
+        {
+          if (LocaleCompare(attribute,"distance") == 0)
+            {
+              distance=StringToLong((char *) SvPV(ST(1),na));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    count=0;
+    for ( ; image; image=image->next)
+    {
+      channel_features=GetImageFeatures(image,distance,exception);
+      if (channel_features == (ChannelFeatures *) NULL)
+        continue;
+      count++;
+      EXTEND(sp,75*count);
+      for (i=0; i < 4; i++)
+      {
+        ChannelFeatures(RedChannel,i);
+        ChannelFeatures(GreenChannel,i);
+        ChannelFeatures(BlueChannel,i);
+        if (image->colorspace == CMYKColorspace)
+          ChannelFeatures(BlackChannel,i);
+        if (image->alpha_trait == BlendPixelTrait)
+          ChannelFeatures(AlphaChannel,i);
+      }
+      channel_features=(ChannelFeatures *)
+        RelinquishMagickMemory(channel_features);
+    }
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   F l a t t e n                                                             #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Flatten(ref)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    FlattenImage   = 1
+    flatten        = 2
+    flattenimage   = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute,
+      *p;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image;
+
+    PixelInfo
+      background_color;
+
+    register ssize_t
+      i;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    background_color=image->background_color;
+    if (items == 2)
+      (void) QueryColorCompliance((char *) SvPV(ST(1),na),AllCompliance,
+        &background_color,exception);
+    else
+      for (i=2; i < items; i+=2)
+      {
+        attribute=(char *) SvPV(ST(i-1),na);
+        switch (*attribute)
+        {
+          case 'B':
+          case 'b':
+          {
+            if (LocaleCompare(attribute,"background") == 0)
+              {
+                (void) QueryColorCompliance((char *) SvPV(ST(1),na),
+                  AllCompliance,&background_color,exception);
+                break;
+              }
+            ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+              attribute);
+            break;
+          }
+          default:
+          {
+            ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+              attribute);
+            break;
+          }
+        }
+      }
+    image->background_color=background_color;
+    image=MergeImageLayers(image,FlattenLayer,exception);
+    if (image == (Image *) NULL)
+      goto PerlException;
+    /*
+      Create blessed Perl array for the returned image.
+    */
+    av=newAV();
+    ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    AddImageToRegistry(sv,image);
+    rv=newRV(sv);
+    av_push(av,sv_bless(rv,hv));
+    SvREFCNT_dec(sv);
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    (void) FormatLocaleString(info->image_info->filename,MaxTextExtent,
+      "flatten-%.*s",(int) (MaxTextExtent-9),
+      ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
+    (void) CopyMagickString(image->filename,info->image_info->filename,
+      MaxTextExtent);
+    SetImageInfo(info->image_info,0,exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);  /* return messages in string context */
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   F x                                                                       #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Fx(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    FxImage  = 1
+    fx       = 2
+    fximage  = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute,
+      expression[MaxTextExtent];
+
+    ChannelType
+      channel,
+      channel_mask;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image;
+
+    register ssize_t
+      i;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *av_reference,
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    attribute=NULL;
+    av=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    av=newAV();
+    av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    /*
+      Get options.
+    */
+    channel=DefaultChannels;
+    (void) CopyMagickString(expression,"u",MaxTextExtent);
+    if (items == 2)
+      (void) CopyMagickString(expression,(char *) SvPV(ST(1),na),MaxTextExtent);
+    else
+      for (i=2; i < items; i+=2)
+      {
+        attribute=(char *) SvPV(ST(i-1),na);
+        switch (*attribute)
+        {
+          case 'C':
+          case 'c':
+          {
+            if (LocaleCompare(attribute,"channel") == 0)
+              {
+                ssize_t
+                  option;
+
+                option=ParseChannelOption(SvPV(ST(i),na));
+                if (option < 0)
+                  {
+                    ThrowPerlException(exception,OptionError,
+                      "UnrecognizedType",SvPV(ST(i),na));
+                    return;
+                  }
+                channel=(ChannelType) option;
+                break;
+              }
+            ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+              attribute);
+            break;
+          }
+          case 'E':
+          case 'e':
+          {
+            if (LocaleCompare(attribute,"expression") == 0)
+              {
+                (void) CopyMagickString(expression,SvPV(ST(i),na),
+                  MaxTextExtent);
+                break;
+              }
+            ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+              attribute);
+            break;
+          }
+          default:
+          {
+            ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+              attribute);
+            break;
+          }
+        }
+      }
+    channel_mask=SetImageChannelMask(image,channel);
+    image=FxImage(image,expression,exception);
+    if (image != (Image *) NULL)
+      (void) SetImageChannelMask(image,channel_mask);
+    if (image == (Image *) NULL)
+      goto PerlException;
+    for ( ; image; image=image->next)
+    {
+      AddImageToRegistry(sv,image);
+      rv=newRV(sv);
+      av_push(av,sv_bless(rv,hv));
+      SvREFCNT_dec(sv);
+    }
+    exception=DestroyExceptionInfo(exception);
+    ST(0)=av_reference;
+    SvREFCNT_dec(perl_exception);  /* can't return warning messages */
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   G e t                                                                     #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Get(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    GetAttributes = 1
+    GetAttribute  = 2
+    get           = 3
+    getattributes = 4
+    getattribute  = 5
+  PPCODE:
+  {
+    char
+      *attribute,
+      color[MaxTextExtent];
+
+    const char
+      *value;
+
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    long
+      j;
+
+    register ssize_t
+      i;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference,
+      *s;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        XSRETURN_EMPTY;
+      }
+    reference=SvRV(ST(0));
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL && !info)
+      XSRETURN_EMPTY;
+    EXTEND(sp,items);
+    for (i=1; i < items; i++)
+    {
+      attribute=(char *) SvPV(ST(i),na);
+      s=NULL;
+      switch (*attribute)
+      {
+        case 'A':
+        case 'a':
+        {
+          if (LocaleCompare(attribute,"adjoin") == 0)
+            {
+              if (info)
+                s=newSViv((ssize_t) info->image_info->adjoin);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"antialias") == 0)
+            {
+              if (info)
+                s=newSViv((ssize_t) info->image_info->antialias);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"area") == 0)
+            {
+              s=newSViv(GetMagickResource(AreaResource));
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"attenuate") == 0)
+            {
+              const char
+                *value;
+
+              value=GetImageProperty(image,attribute,exception);
+              if (value != (const char *) NULL)
+                s=newSVpv(value,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"authenticate") == 0)
+            {
+              if (info)
+                {
+                  const char
+                    *option;
+
+                  option=GetImageOption(info->image_info,attribute);
+                  if (option != (const char *) NULL)
+                    s=newSVpv(option,0);
+                }
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'B':
+        case 'b':
+        {
+          if (LocaleCompare(attribute,"background") == 0)
+            {
+              if (image == (Image *) NULL)
+                break;
+              (void) FormatLocaleString(color,MaxTextExtent,
+                "%.20g,%.20g,%.20g,%.20g",image->background_color.red,
+                image->background_color.green,image->background_color.blue,
+                image->background_color.alpha);
+              s=newSVpv(color,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"base-columns") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->magick_columns);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"base-filename") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSVpv(image->magick_filename,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"base-height") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->magick_rows);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"base-rows") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->magick_rows);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"base-width") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->magick_columns);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"blue-primary") == 0)
+            {
+              if (image == (Image *) NULL)
+                break;
+              (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
+                image->chromaticity.blue_primary.x,
+                image->chromaticity.blue_primary.y);
+              s=newSVpv(color,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"bordercolor") == 0)
+            {
+              if (image == (Image *) NULL)
+                break;
+              (void) FormatLocaleString(color,MaxTextExtent,
+                "%.20g,%.20g,%.20g,%.20g",image->border_color.red,
+                image->border_color.green,image->border_color.blue,
+                image->border_color.alpha);
+              s=newSVpv(color,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"bounding-box") == 0)
+            {
+              char
+                geometry[MaxTextExtent];
+
+              RectangleInfo
+                page;
+
+              if (image == (Image *) NULL)
+                break;
+              page=GetImageBoundingBox(image,exception);
+              (void) FormatLocaleString(geometry,MaxTextExtent,
+                "%.20gx%.20g%+.20g%+.20g",(double) page.width,(double)
+                page.height,(double) page.x,(double) page.y);
+              s=newSVpv(geometry,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'C':
+        case 'c':
+        {
+          if (LocaleCompare(attribute,"class") == 0)
+            {
+              if (image == (Image *) NULL)
+                break;
+              s=newSViv(image->storage_class);
+              (void) sv_setpv(s,CommandOptionToMnemonic(MagickClassOptions,
+                image->storage_class));
+              SvIOK_on(s);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"clip-mask") == 0)
+            {
+              if (image != (Image *) NULL)
+                {
+                  Image
+                    *mask_image;
+
+                  SV
+                    *sv;
+
+                  sv=NULL;
+                  if (image->mask == MagickFalse)
+                    ClipImage(image,exception);
+                  mask_image=GetImageMask(image,exception);
+                  if (mask_image != (Image *) NULL)
+                    {
+                      AddImageToRegistry(sv,mask_image);
+                      s=sv_bless(newRV(sv),SvSTASH(reference));
+                    }
+                }
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"clip-path") == 0)
+            {
+              if (image != (Image *) NULL)
+                {
+                  Image
+                    *mask_image;
+
+                  SV
+                    *sv;
+
+                  sv=NULL;
+                  if (image->mask != MagickFalse)
+                    ClipImage(image,exception);
+                  mask_image=GetImageMask(image,exception);
+                  if (mask_image != (Image *) NULL)
+                    {
+                      AddImageToRegistry(sv,mask_image);
+                      s=sv_bless(newRV(sv),SvSTASH(reference));
+                    }
+                }
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"compression") == 0)
+            {
+              j=info ? info->image_info->compression : image ?
+                image->compression : UndefinedCompression;
+              if (info)
+                if (info->image_info->compression == UndefinedCompression)
+                  j=image->compression;
+              s=newSViv(j);
+              (void) sv_setpv(s,CommandOptionToMnemonic(MagickCompressOptions,
+                j));
+              SvIOK_on(s);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"colorspace") == 0)
+            {
+              j=image ? image->colorspace : RGBColorspace;
+              s=newSViv(j);
+              (void) sv_setpv(s,CommandOptionToMnemonic(MagickColorspaceOptions,
+                j));
+              SvIOK_on(s);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"colors") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) GetNumberColors(image,(FILE *) NULL,
+                  exception));
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleNCompare(attribute,"colormap",8) == 0)
+            {
+              int
+                items;
+
+              if (image == (Image *) NULL || !image->colormap)
+                break;
+              j=0;
+              items=sscanf(attribute,"%*[^[][%ld",&j);
+              (void) items;
+              if (j > (ssize_t) image->colors)
+                j%=image->colors;
+              (void) FormatLocaleString(color,MaxTextExtent,
+                "%.20g,%.20g,%.20g,%.20g",image->colormap[j].red,
+                image->colormap[j].green,image->colormap[j].blue,
+                image->colormap[j].alpha);
+              s=newSVpv(color,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"columns") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->columns);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"comment") == 0)
+            {
+              const char
+                *value;
+
+              value=GetImageProperty(image,attribute,exception);
+              if (value != (const char *) NULL)
+                s=newSVpv(value,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"copyright") == 0)
+            {
+              s=newSVpv(GetMagickCopyright(),0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'D':
+        case 'd':
+        {
+          if (LocaleCompare(attribute,"density") == 0)
+            {
+              char
+                geometry[MaxTextExtent];
+
+              if (image == (Image *) NULL)
+                break;
+              (void) FormatLocaleString(geometry,MaxTextExtent,"%.15gx%.15g",
+                image->resolution.x,image->resolution.y);
+              s=newSVpv(geometry,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"delay") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->delay);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"depth") == 0)
+            {
+              s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) GetImageDepth(image,exception));
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"directory") == 0)
+            {
+              if (image && image->directory)
+                s=newSVpv(image->directory,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"dispose") == 0)
+            {
+              if (image == (Image *) NULL)
+                break;
+
+              s=newSViv(image->dispose);
+              (void) sv_setpv(s,
+                CommandOptionToMnemonic(MagickDisposeOptions,image->dispose));
+              SvIOK_on(s);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"disk") == 0)
+            {
+              s=newSViv(GetMagickResource(DiskResource));
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"dither") == 0)
+            {
+              if (info)
+                s=newSViv((ssize_t) info->image_info->dither);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"display") == 0)  /* same as server */
+            {
+              if (info && info->image_info->server_name)
+                s=newSVpv(info->image_info->server_name,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'E':
+        case 'e':
+        {
+          if (LocaleCompare(attribute,"elapsed-time") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSVnv(GetElapsedTime(&image->timer));
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"endian") == 0)
+            {
+              j=info ? info->image_info->endian : image ? image->endian :
+                UndefinedEndian;
+              s=newSViv(j);
+              (void) sv_setpv(s,CommandOptionToMnemonic(MagickEndianOptions,j));
+              SvIOK_on(s);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"error") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSVnv(image->error.mean_error_per_pixel);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'F':
+        case 'f':
+        {
+          if (LocaleCompare(attribute,"filesize") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) GetBlobSize(image));
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"filename") == 0)
+            {
+              if (info && info->image_info->filename &&
+                  *info->image_info->filename)
+                s=newSVpv(info->image_info->filename,0);
+              if (image != (Image *) NULL)
+                s=newSVpv(image->filename,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"filter") == 0)
+            {
+              s=image ? newSViv(image->filter) : newSViv(0);
+              (void) sv_setpv(s,CommandOptionToMnemonic(MagickFilterOptions,
+                image->filter));
+              SvIOK_on(s);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"font") == 0)
+            {
+              if (info && info->image_info->font)
+                s=newSVpv(info->image_info->font,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"foreground") == 0)
+            continue;
+          if (LocaleCompare(attribute,"format") == 0)
+            {
+              const MagickInfo
+                *magick_info;
+
+              magick_info=(const MagickInfo *) NULL;
+              if (info && (*info->image_info->magick != '\0'))
+                magick_info=GetMagickInfo(info->image_info->magick,exception);
+              if (image != (Image *) NULL)
+                magick_info=GetMagickInfo(image->magick,exception);
+              if ((magick_info != (const MagickInfo *) NULL) &&
+                  (*magick_info->description != '\0'))
+                s=newSVpv((char *) magick_info->description,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"fuzz") == 0)
+            {
+              if (info)
+                s=newSVnv(info->image_info->fuzz);
+              if (image != (Image *) NULL)
+                s=newSVnv(image->fuzz);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'G':
+        case 'g':
+        {
+          if (LocaleCompare(attribute,"gamma") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSVnv(image->gamma);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"geometry") == 0)
+            {
+              if (image && image->geometry)
+                s=newSVpv(image->geometry,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"gravity") == 0)
+            {
+              s=image ? newSViv(image->gravity) : newSViv(0);
+              (void) sv_setpv(s,CommandOptionToMnemonic(MagickGravityOptions,
+                image->gravity));
+              SvIOK_on(s);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"green-primary") == 0)
+            {
+              if (image == (Image *) NULL)
+                break;
+              (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
+                image->chromaticity.green_primary.x,
+                image->chromaticity.green_primary.y);
+              s=newSVpv(color,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'H':
+        case 'h':
+        {
+          if (LocaleCompare(attribute,"height") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->rows);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'I':
+        case 'i':
+        {
+          if (LocaleCompare(attribute,"icc") == 0)
+            {
+              if (image != (Image *) NULL)
+                {
+                  const StringInfo
+                    *profile;
+
+                  profile=GetImageProfile(image,"icc");
+                  if (profile != (StringInfo *) NULL)
+                    s=newSVpv((const char *) GetStringInfoDatum(profile),
+                      GetStringInfoLength(profile));
+                }
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"icm") == 0)
+            {
+              if (image != (Image *) NULL)
+                {
+                  const StringInfo
+                    *profile;
+
+                  profile=GetImageProfile(image,"icm");
+                  if (profile != (const StringInfo *) NULL)
+                    s=newSVpv((const char *) GetStringInfoDatum(profile),
+                      GetStringInfoLength(profile));
+                }
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"id") == 0)
+            {
+              if (image != (Image *) NULL)
+                {
+                  char
+                    key[MaxTextExtent];
+
+                  MagickBooleanType
+                    status;
+
+                  static ssize_t
+                    id = 0;
+
+                  (void) FormatLocaleString(key,MaxTextExtent,"%.20g\n",(double)
+                    id);
+                  status=SetImageRegistry(ImageRegistryType,key,image,
+                    exception);
+                  (void) status;
+                  s=newSViv(id++);
+                }
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleNCompare(attribute,"index",5) == 0)
+            {
+              char
+                name[MaxTextExtent];
+
+              int
+                items;
+
+              long
+                x,
+                y;
+
+              register const Quantum
+                *p;
+
+              CacheView
+                *image_view;
+
+              if (image == (Image *) NULL)
+                break;
+              if (image->storage_class != PseudoClass)
+                break;
+              x=0;
+              y=0;
+              items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
+              (void) items;
+              image_view=AcquireVirtualCacheView(image,exception);
+              p=GetCacheViewVirtualPixels(image_view,x,y,1,1,exception);
+              if (p != (const Quantum *) NULL)
+                {
+                  (void) FormatLocaleString(name,MaxTextExtent,QuantumFormat,
+                    GetPixelIndex(image,p));
+                  s=newSVpv(name,0);
+                  PUSHs(s ? sv_2mortal(s) : &sv_undef);
+                }
+              image_view=DestroyCacheView(image_view);
+              continue;
+            }
+          if (LocaleCompare(attribute,"iptc") == 0)
+            {
+              if (image != (Image *) NULL)
+                {
+                  const StringInfo
+                    *profile;
+
+                  profile=GetImageProfile(image,"iptc");
+                  if (profile != (const StringInfo *) NULL)
+                    s=newSVpv((const char *) GetStringInfoDatum(profile),
+                      GetStringInfoLength(profile));
+                }
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"iterations") == 0)  /* same as loop */
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->iterations);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"interlace") == 0)
+            {
+              j=info ? info->image_info->interlace : image ? image->interlace :
+                UndefinedInterlace;
+              s=newSViv(j);
+              (void) sv_setpv(s,CommandOptionToMnemonic(MagickInterlaceOptions,
+                j));
+              SvIOK_on(s);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'L':
+        case 'l':
+        {
+          if (LocaleCompare(attribute,"label") == 0)
+            {
+              const char
+                *value;
+
+              if (image == (Image *) NULL)
+                break;
+              value=GetImageProperty(image,"Label",exception);
+              if (value != (const char *) NULL)
+                s=newSVpv(value,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"loop") == 0)  /* same as iterations */
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->iterations);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'M':
+        case 'm':
+        {
+          if (LocaleCompare(attribute,"magick") == 0)
+            {
+              if (info && *info->image_info->magick)
+                s=newSVpv(info->image_info->magick,0);
+              if (image != (Image *) NULL)
+                s=newSVpv(image->magick,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"map") == 0)
+            {
+              s=newSViv(GetMagickResource(MapResource));
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"maximum-error") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSVnv(image->error.normalized_maximum_error);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"memory") == 0)
+            {
+              s=newSViv(GetMagickResource(MemoryResource));
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"mean-error") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSVnv(image->error.normalized_mean_error);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"mime") == 0)
+            {
+              if (info && *info->image_info->magick)
+                s=newSVpv(MagickToMime(info->image_info->magick),0);
+              if (image != (Image *) NULL)
+                s=newSVpv(MagickToMime(image->magick),0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"mattecolor") == 0)
+            {
+              if (image == (Image *) NULL)
+                break;
+              (void) FormatLocaleString(color,MaxTextExtent,
+                "%.20g,%.20g,%.20g,%.20g",image->matte_color.red,
+                image->matte_color.green,image->matte_color.blue,
+                image->matte_color.alpha);
+              s=newSVpv(color,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"matte") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->alpha_trait == BlendPixelTrait ?
+                  1 : 0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"mime") == 0)
+            {
+              const char
+                *magick;
+
+              magick=NULL;
+              if (info && *info->image_info->magick)
+                magick=info->image_info->magick;
+              if (image != (Image *) NULL)
+                magick=image->magick;
+              if (magick)
+                {
+                  char
+                    *mime;
+
+                  mime=MagickToMime(magick);
+                  s=newSVpv(mime,0);
+                  mime=(char *) RelinquishMagickMemory(mime);
+                }
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"monochrome") == 0)
+            {
+              if (image == (Image *) NULL)
+                continue;
+              j=info ? info->image_info->monochrome :
+                IsImageMonochrome(image,exception);
+              s=newSViv(j);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"montage") == 0)
+            {
+              if (image && image->montage)
+                s=newSVpv(image->montage,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'O':
+        case 'o':
+        {
+          if (LocaleCompare(attribute,"orientation") == 0)
+            {
+              j=info ? info->image_info->orientation : image ?
+                image->orientation : UndefinedOrientation;
+              s=newSViv(j);
+              (void) sv_setpv(s,CommandOptionToMnemonic(MagickOrientationOptions,
+                j));
+              SvIOK_on(s);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'P':
+        case 'p':
+        {
+          if (LocaleCompare(attribute,"page") == 0)
+            {
+              if (info && info->image_info->page)
+                s=newSVpv(info->image_info->page,0);
+              if (image != (Image *) NULL)
+                {
+                  char
+                    geometry[MaxTextExtent];
+
+                  (void) FormatLocaleString(geometry,MaxTextExtent,
+                    "%.20gx%.20g%+.20g%+.20g",(double) image->page.width,
+                    (double) image->page.height,(double) image->page.x,(double)
+                    image->page.y);
+                  s=newSVpv(geometry,0);
+                }
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"page.x") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->page.x);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"page.y") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->page.y);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleNCompare(attribute,"pixel",5) == 0)
+            {
+              char
+                tuple[MaxTextExtent];
+
+              int
+                items;
+
+              long
+                x,
+                y;
+
+              register const Quantum
+                *p;
+
+              if (image == (Image *) NULL)
+                break;
+              x=0;
+              y=0;
+              items=sscanf(attribute,"%*[^[][%ld%*[,/]%ld",&x,&y);
+              (void) items;
+              p=GetVirtualPixels(image,x,y,1,1,exception);
+              if (image->colorspace != CMYKColorspace)
+                (void) FormatLocaleString(tuple,MaxTextExtent,QuantumFormat ","
+                  QuantumFormat "," QuantumFormat "," QuantumFormat,
+                  GetPixelRed(image,p),GetPixelGreen(image,p),
+                  GetPixelBlue(image,p),GetPixelAlpha(image,p));
+              else
+                (void) FormatLocaleString(tuple,MaxTextExtent,QuantumFormat ","
+                  QuantumFormat "," QuantumFormat "," QuantumFormat ","
+                  QuantumFormat,GetPixelRed(image,p),GetPixelGreen(image,p),
+                  GetPixelBlue(image,p),GetPixelBlack(image,p),
+                  GetPixelAlpha(image,p));
+              s=newSVpv(tuple,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"pointsize") == 0)
+            {
+              if (info)
+                s=newSViv((ssize_t) info->image_info->pointsize);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"preview") == 0)
+            {
+              s=newSViv(info->image_info->preview_type);
+              (void) sv_setpv(s,CommandOptionToMnemonic(MagickPreviewOptions,
+                info->image_info->preview_type));
+              SvIOK_on(s);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'Q':
+        case 'q':
+        {
+          if (LocaleCompare(attribute,"quality") == 0)
+            {
+              if (info)
+                s=newSViv((ssize_t) info->image_info->quality);
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->quality);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"quantum") == 0)
+            {
+              if (info)
+                s=newSViv((ssize_t) MAGICKCORE_QUANTUM_DEPTH);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'R':
+        case 'r':
+        {
+          if (LocaleCompare(attribute,"rendering-intent") == 0)
+            {
+              s=newSViv(image->rendering_intent);
+              (void) sv_setpv(s,CommandOptionToMnemonic(MagickIntentOptions,
+                image->rendering_intent));
+              SvIOK_on(s);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"red-primary") == 0)
+            {
+              if (image == (Image *) NULL)
+                break;
+              (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
+                image->chromaticity.red_primary.x,
+                image->chromaticity.red_primary.y);
+              s=newSVpv(color,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"rows") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->rows);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'S':
+        case 's':
+        {
+          if (LocaleCompare(attribute,"sampling-factor") == 0)
+            {
+              if (info && info->image_info->sampling_factor)
+                s=newSVpv(info->image_info->sampling_factor,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"server") == 0)  /* same as display */
+            {
+              if (info && info->image_info->server_name)
+                s=newSVpv(info->image_info->server_name,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"size") == 0)
+            {
+              if (info && info->image_info->size)
+                s=newSVpv(info->image_info->size,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"scene") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->scene);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"scenes") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) info->image_info->number_scenes);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"signature") == 0)
+            {
+              const char
+                *value;
+
+              if (image == (Image *) NULL)
+                break;
+              (void) SignatureImage(image,exception);
+              value=GetImageProperty(image,"Signature",exception);
+              if (value != (const char *) NULL)
+                s=newSVpv(value,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'T':
+        case 't':
+        {
+          if (LocaleCompare(attribute,"taint") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) IsTaintImage(image));
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"texture") == 0)
+            {
+              if (info && info->image_info->texture)
+                s=newSVpv(info->image_info->texture,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"total-ink-density") == 0)
+            {
+              s=newSViv(MAGICKCORE_QUANTUM_DEPTH);
+              if (image != (Image *) NULL)
+                s=newSVnv(GetImageTotalInkDensity(image,exception));
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"transparent-color") == 0)
+            {
+              if (image == (Image *) NULL)
+                break;
+              (void) FormatLocaleString(color,MaxTextExtent,
+                "%.20g,%.20g,%.20g,%.20g",image->transparent_color.red,
+                image->transparent_color.green,image->transparent_color.blue,
+                image->transparent_color.alpha);
+              s=newSVpv(color,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"type") == 0)
+            {
+              if (image == (Image *) NULL)
+                break;
+              j=(ssize_t) GetImageType(image,exception);
+              s=newSViv(j);
+              (void) sv_setpv(s,CommandOptionToMnemonic(MagickTypeOptions,j));
+              SvIOK_on(s);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'U':
+        case 'u':
+        {
+          if (LocaleCompare(attribute,"units") == 0)
+            {
+              j=info ? info->image_info->units : image ? image->units :
+                UndefinedResolution;
+              if (info && (info->image_info->units == UndefinedResolution))
+                if (image)
+                  j=image->units;
+              if (j == UndefinedResolution)
+                s=newSVpv("undefined units",0);
+              else
+                if (j == PixelsPerInchResolution)
+                  s=newSVpv("pixels / inch",0);
+                else
+                  s=newSVpv("pixels / centimeter",0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"user-time") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSVnv(GetUserTime(&image->timer));
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'V':
+        case 'v':
+        {
+          if (LocaleCompare(attribute,"verbose") == 0)
+            {
+              if (info)
+                s=newSViv((ssize_t) info->image_info->verbose);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"version") == 0)
+            {
+              s=newSVpv(GetMagickVersion((size_t *) NULL),0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"view") == 0)
+            {
+              if (info && info->image_info->view)
+                s=newSVpv(info->image_info->view,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"virtual-pixel") == 0)
+            {
+              if (image == (Image *) NULL)
+                break;
+              j=(ssize_t) GetImageVirtualPixelMethod(image);
+              s=newSViv(j);
+              (void) sv_setpv(s,CommandOptionToMnemonic(
+                MagickVirtualPixelOptions,j));
+              SvIOK_on(s);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'W':
+        case 'w':
+        {
+          if (LocaleCompare(attribute,"white-point") == 0)
+            {
+              if (image == (Image *) NULL)
+                break;
+              (void) FormatLocaleString(color,MaxTextExtent,"%.15g,%.15g",
+                image->chromaticity.white_point.x,
+                image->chromaticity.white_point.y);
+              s=newSVpv(color,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          if (LocaleCompare(attribute,"width") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSViv((ssize_t) image->columns);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+             attribute);
+          break;
+        }
+        case 'X':
+        case 'x':
+        {
+          if (LocaleCompare(attribute,"x-resolution") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSVnv(image->resolution.x);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'Y':
+        case 'y':
+        {
+          if (LocaleCompare(attribute,"y-resolution") == 0)
+            {
+              if (image != (Image *) NULL)
+                s=newSVnv(image->resolution.y);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+          break;
+      }
+      if (image == (Image *) NULL)
+        ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+          attribute)
+      else
+        {
+          value=GetImageProperty(image,attribute,exception);
+          if (value != (const char *) NULL)
+            {
+              s=newSVpv(value,0);
+              PUSHs(s ? sv_2mortal(s) : &sv_undef);
+            }
+          else
+            if (*attribute != '%')
+              ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+                attribute)
+            else
+              {
+                 char
+                   *meta;
+
+                 meta=InterpretImageProperties(info ? info->image_info :
+                   (ImageInfo *) NULL,image,attribute,exception);
+                 s=newSVpv(meta,0);
+                 PUSHs(s ? sv_2mortal(s) : &sv_undef);
+                 meta=(char *) RelinquishMagickMemory(meta);
+              }
+        }
+    }
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);  /* can't return warning messages */
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   G e t A u t h e n t i c P i x e l s                                       #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void *
+GetAuthenticPixels(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref = NO_INIT
+  ALIAS:
+    getauthenticpixels = 1
+    GetImagePixels = 2
+    getimagepixels = 3
+  CODE:
+  {
+    char
+      *attribute;
+
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    RectangleInfo
+      region;
+
+    ssize_t
+      i;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    void
+      *blob = NULL;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+
+    region.x=0;
+    region.y=0;
+    region.width=image->columns;
+    region.height=1;
+    if (items == 1)
+      (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'g':
+        case 'G':
+        {
+          if (LocaleCompare(attribute,"geometry") == 0)
+            {
+              (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'H':
+        case 'h':
+        {
+          if (LocaleCompare(attribute,"height") == 0)
+            {
+              region.height=SvIV(ST(i));
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedOption",
+            attribute);
+          break;
+        }
+        case 'X':
+        case 'x':
+        {
+          if (LocaleCompare(attribute,"x") == 0)
+            {
+              region.x=SvIV(ST(i));
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedOption",
+            attribute);
+          break;
+        }
+        case 'Y':
+        case 'y':
+        {
+          if (LocaleCompare(attribute,"y") == 0)
+            {
+              region.y=SvIV(ST(i));
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedOption",
+            attribute);
+          break;
+        }
+        case 'W':
+        case 'w':
+        {
+          if (LocaleCompare(attribute,"width") == 0)
+            {
+              region.width=SvIV(ST(i));
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedOption",
+            attribute);
+          break;
+        }
+      }
+    }
+    blob=(void *) GetAuthenticPixels(image,region.x,region.y,region.width,
+      region.height,exception);
+    if (blob != (void *) NULL)
+      goto PerlEnd;
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);  /* throw away all errors */
+
+  PerlEnd:
+    RETVAL = blob;
+  }
+  OUTPUT:
+    RETVAL
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   G e t V i r t u a l P i x e l s                                           #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void *
+GetVirtualPixels(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref = NO_INIT
+  ALIAS:
+    getvirtualpixels = 1
+    AcquireImagePixels = 2
+    acquireimagepixels = 3
+  CODE:
+  {
+    char
+      *attribute;
+
+    const void
+      *blob = NULL;
+
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    RectangleInfo
+      region;
+
+    ssize_t
+      i;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+
+    region.x=0;
+    region.y=0;
+    region.width=image->columns;
+    region.height=1;
+    if (items == 1)
+      (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'g':
+        case 'G':
+        {
+          if (LocaleCompare(attribute,"geometry") == 0)
+            {
+              (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'H':
+        case 'h':
+        {
+          if (LocaleCompare(attribute,"height") == 0)
+            {
+              region.height=SvIV(ST(i));
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedOption",
+            attribute);
+          break;
+        }
+        case 'X':
+        case 'x':
+        {
+          if (LocaleCompare(attribute,"x") == 0)
+            {
+              region.x=SvIV(ST(i));
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedOption",
+            attribute);
+          break;
+        }
+        case 'Y':
+        case 'y':
+        {
+          if (LocaleCompare(attribute,"y") == 0)
+            {
+              region.y=SvIV(ST(i));
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedOption",
+            attribute);
+          break;
+        }
+        case 'W':
+        case 'w':
+        {
+          if (LocaleCompare(attribute,"width") == 0)
+            {
+              region.width=SvIV(ST(i));
+              continue;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedOption",
+            attribute);
+          break;
+        }
+      }
+    }
+    blob=(const void *) GetVirtualPixels(image,region.x,region.y,region.width,
+      region.height,exception);
+    if (blob != (void *) NULL)
+      goto PerlEnd;
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);  /* throw away all errors */
+
+  PerlEnd:
+    RETVAL = (void *) blob;
+  }
+  OUTPUT:
+    RETVAL
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   G e t A u t h e n t i c M e t a c o n t e n t                             #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void *
+GetAuthenticMetacontent(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref = NO_INIT
+  ALIAS:
+    getauthenticmetacontent = 1
+    GetMetacontent = 2
+    getmetacontent = 3
+  CODE:
+  {
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    void
+      *blob = NULL;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+
+    blob=(void *) GetAuthenticMetacontent(image);
+    if (blob != (void *) NULL)
+      goto PerlEnd;
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);  /* throw away all errors */
+
+  PerlEnd:
+    RETVAL = blob;
+  }
+  OUTPUT:
+    RETVAL
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   G e t V i r t u a l M e t a c o n t e n t                                 #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void *
+GetVirtualMetacontent(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref = NO_INIT
+  ALIAS:
+    getvirtualmetacontent = 1
+  CODE:
+  {
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    void
+      *blob = NULL;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+
+    blob=(void *) GetVirtualMetacontent(image);
+    if (blob != (void *) NULL)
+      goto PerlEnd;
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);  /* throw away all errors */
+
+  PerlEnd:
+    RETVAL = blob;
+  }
+  OUTPUT:
+    RETVAL
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   H i s t o g r a m                                                         #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Histogram(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    HistogramImage = 1
+    histogram      = 2
+    histogramimage = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      message[MaxTextExtent];
+
+    PixelInfo
+      *histogram;
+
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      count;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    size_t
+      number_colors;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    av=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    av=newAV();
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    count=0;
+    for ( ; image; image=image->next)
+    {
+      histogram=GetImageHistogram(image,&number_colors,exception);
+      if (histogram == (PixelInfo *) NULL)
+        continue;
+      count+=(ssize_t) number_colors;
+      EXTEND(sp,6*count);
+      for (i=0; i < (ssize_t) number_colors; i++)
+      {
+        (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
+          histogram[i].red);
+        PUSHs(sv_2mortal(newSVpv(message,0)));
+        (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
+          histogram[i].green);
+        PUSHs(sv_2mortal(newSVpv(message,0)));
+        (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
+          histogram[i].blue);
+        PUSHs(sv_2mortal(newSVpv(message,0)));
+        if (image->colorspace == CMYKColorspace)
+          {
+            (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
+              histogram[i].black);
+            PUSHs(sv_2mortal(newSVpv(message,0)));
+          }
+        (void) FormatLocaleString(message,MaxTextExtent,"%.20g",
+          histogram[i].alpha);
+        PUSHs(sv_2mortal(newSVpv(message,0)));
+        (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double)
+          histogram[i].count);
+        PUSHs(sv_2mortal(newSVpv(message,0)));
+      }
+      histogram=(PixelInfo *) RelinquishMagickMemory(histogram);
+    }
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   G e t P i x e l                                                           #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+GetPixel(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    getpixel = 1
+    getPixel = 2
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute;
+
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    MagickBooleanType
+      normalize;
+
+    RectangleInfo
+      region;
+
+    register const Quantum
+      *p;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      option;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference;  /* reference is the SV* of ref=SvIV(reference) */
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    reference=SvRV(ST(0));
+    av=(AV *) reference;
+    info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
+      exception);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    normalize=MagickTrue;
+    region.x=0;
+    region.y=0;
+    region.width=image->columns;
+    region.height=1;
+    if (items == 1)
+      (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'C':
+        case 'c':
+        {
+          if (LocaleCompare(attribute,"channel") == 0)
+            {
+              ssize_t
+                option;
+
+              option=ParseChannelOption(SvPV(ST(i),na));
+              if (option < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  return;
+                }
+              SetPixelChannelMask(image,(ChannelType) option);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'g':
+        case 'G':
+        {
+          if (LocaleCompare(attribute,"geometry") == 0)
+            {
+              (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'N':
+        case 'n':
+        {
+          if (LocaleCompare(attribute,"normalize") == 0)
+            {
+              option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
+                SvPV(ST(i),na));
+              if (option < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  break;
+                }
+             normalize=option != 0 ? MagickTrue : MagickFalse;
+             break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'x':
+        case 'X':
+        {
+          if (LocaleCompare(attribute,"x") == 0)
+            {
+              region.x=SvIV(ST(i));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'y':
+        case 'Y':
+        {
+          if (LocaleCompare(attribute,"y") == 0)
+            {
+              region.y=SvIV(ST(i));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    p=GetVirtualPixels(image,region.x,region.y,1,1,exception);
+    if (p == (const Quantum *) NULL)
+      PUSHs(&sv_undef);
+    else
+      {
+        double
+          scale;
+
+        scale=1.0;
+        if (normalize != MagickFalse)
+          scale=1.0/QuantumRange;
+        if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
+          PUSHs(sv_2mortal(newSVnv(scale*GetPixelRed(image,p))));
+        if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
+          PUSHs(sv_2mortal(newSVnv(scale*GetPixelGreen(image,p))));
+        if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
+          PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlue(image,p))));
+        if (((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
+            (image->colorspace == CMYKColorspace))
+          PUSHs(sv_2mortal(newSVnv(scale*GetPixelBlack(image,p))));
+        if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
+          PUSHs(sv_2mortal(newSVnv(scale*GetPixelAlpha(image,p))));
+      }
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   G e t P i x e l s                                                         #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+GetPixels(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    getpixels = 1
+    getPixels = 2
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute;
+
+    const char
+      *map;
+
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    MagickBooleanType
+      normalize,
+      status;
+
+    RectangleInfo
+      region;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      option;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference;  /* reference is the SV* of ref=SvIV(reference) */
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    reference=SvRV(ST(0));
+    av=(AV *) reference;
+    info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
+      exception);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    map="RGB";
+    if (image->alpha_trait == BlendPixelTrait)
+      map="RGBA";
+    if (image->colorspace == CMYKColorspace)
+      {
+        map="CMYK";
+        if (image->alpha_trait == BlendPixelTrait)
+          map="CMYKA";
+      }
+    normalize=MagickFalse;
+    region.x=0;
+    region.y=0;
+    region.width=image->columns;
+    region.height=1;
+    if (items == 1)
+      (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'g':
+        case 'G':
+        {
+          if (LocaleCompare(attribute,"geometry") == 0)
+            {
+              (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'H':
+        case 'h':
+        {
+          if (LocaleCompare(attribute,"height") == 0)
+            {
+              region.height=SvIV(ST(i));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'M':
+        case 'm':
+        {
+          if (LocaleCompare(attribute,"map") == 0)
+            {
+              map=SvPV(ST(i),na);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'N':
+        case 'n':
+        {
+          if (LocaleCompare(attribute,"normalize") == 0)
+            {
+              option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
+                SvPV(ST(i),na));
+              if (option < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  break;
+                }
+             normalize=option != 0 ? MagickTrue : MagickFalse;
+             break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'W':
+        case 'w':
+        {
+          if (LocaleCompare(attribute,"width") == 0)
+            {
+              region.width=SvIV(ST(i));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'x':
+        case 'X':
+        {
+          if (LocaleCompare(attribute,"x") == 0)
+            {
+              region.x=SvIV(ST(i));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'y':
+        case 'Y':
+        {
+          if (LocaleCompare(attribute,"y") == 0)
+            {
+              region.y=SvIV(ST(i));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    if (normalize != MagickFalse)
+      {
+        float
+          *pixels;
+
+        pixels=(float *) AcquireQuantumMemory(strlen(map)*region.width,
+          region.height*sizeof(*pixels));
+        if (pixels == (float *) NULL)
+          {
+            ThrowPerlException(exception,ResourceLimitError,
+              "MemoryAllocationFailed",PackageName);
+            goto PerlException;
+          }
+        status=ExportImagePixels(image,region.x,region.y,region.width,
+          region.height,map,FloatPixel,pixels,exception);
+        if (status == MagickFalse)
+          PUSHs(&sv_undef);
+        else
+          {
+            EXTEND(sp,strlen(map)*region.width*region.height);
+            for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
+              PUSHs(sv_2mortal(newSVnv(pixels[i])));
+          }
+        pixels=(float *) RelinquishMagickMemory(pixels);
+      }
+    else
+      {
+        Quantum
+          *pixels;
+
+        pixels=(Quantum *) AcquireQuantumMemory(strlen(map)*region.width,
+          region.height*sizeof(*pixels));
+        if (pixels == (Quantum *) NULL)
+          {
+            ThrowPerlException(exception,ResourceLimitError,
+              "MemoryAllocationFailed",PackageName);
+            goto PerlException;
+          }
+        status=ExportImagePixels(image,region.x,region.y,region.width,
+          region.height,map,QuantumPixel,pixels,exception);
+        if (status == MagickFalse)
+          PUSHs(&sv_undef);
+        else
+          {
+            EXTEND(sp,strlen(map)*region.width*region.height);
+            for (i=0; i < (ssize_t) (strlen(map)*region.width*region.height); i++)
+              PUSHs(sv_2mortal(newSViv(pixels[i])));
+          }
+        pixels=(Quantum *) RelinquishMagickMemory(pixels);
+      }
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   I m a g e T o B l o b                                                     #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+ImageToBlob(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    ImageToBlob  = 1
+    imagetoblob  = 2
+    toblob       = 3
+    blob         = 4
+  PPCODE:
+  {
+    char
+      filename[MaxTextExtent];
+
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image,
+      *next;
+
+    register ssize_t
+      i;
+
+    struct PackageInfo
+      *info,
+      *package_info;
+
+    size_t
+      length;
+
+    ssize_t
+      scene;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    void
+      *blob;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    package_info=(struct PackageInfo *) NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    package_info=ClonePackageInfo(info,exception);
+    for (i=2; i < items; i+=2)
+      SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),exception);
+    (void) CopyMagickString(filename,package_info->image_info->filename,
+      MaxTextExtent);
+    scene=0;
+    for (next=image; next; next=next->next)
+    {
+      (void) CopyMagickString(next->filename,filename,MaxTextExtent);
+      next->scene=scene++;
+    }
+    SetImageInfo(package_info->image_info,(unsigned int)
+      GetImageListLength(image),exception);
+    EXTEND(sp,(ssize_t) GetImageListLength(image));
+    for ( ; image; image=image->next)
+    {
+      length=0;
+      blob=ImagesToBlob(package_info->image_info,image,&length,exception);
+      if (blob != (char *) NULL)
+        {
+          PUSHs(sv_2mortal(newSVpv((const char *) blob,length)));
+          blob=(unsigned char *) RelinquishMagickMemory(blob);
+        }
+      if (package_info->image_info->adjoin)
+        break;
+    }
+
+  PerlException:
+    if (package_info != (struct PackageInfo *) NULL)
+      DestroyPackageInfo(package_info);
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);  /* throw away all errors */
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   L a y e r s                                                               #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Layers(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    Layers                = 1
+    layers           = 2
+    OptimizeImageLayers   = 3
+    optimizelayers        = 4
+    optimizeimagelayers   = 5
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute;
+
+    CompositeOperator
+      compose;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image,
+      *layers;
+
+    LayerMethod
+      method;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      option,
+      sp;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *av_reference,
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    av=newAV();
+    av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    compose=image->compose;
+    method=OptimizeLayer;
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'C':
+        case 'c':
+        {
+          if (LocaleCompare(attribute,"compose") == 0)
+            {
+              sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
+                MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
+              if (sp < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  break;
+                }
+              compose=(CompositeOperator) sp;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'M':
+        case 'm':
+        {
+          if (LocaleCompare(attribute,"method") == 0)
+            {
+              option=ParseCommandOption(MagickLayerOptions,MagickFalse,
+                SvPV(ST(i),na));
+              if (option < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  break;
+                }
+              method=(LayerMethod) option;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    layers=(Image *) NULL;
+    switch (method)
+    {
+      case CompareAnyLayer:
+      case CompareClearLayer:
+      case CompareOverlayLayer:
+      default:
+      {
+        layers=CompareImagesLayers(image,method,exception);
+        break;
+      }
+      case MergeLayer:
+      case FlattenLayer:
+      case MosaicLayer:
+      {
+        layers=MergeImageLayers(image,method,exception);
+        break;
+      }
+      case DisposeLayer:
+      {
+        layers=DisposeImages(image,exception);
+        break;
+      }
+      case OptimizeImageLayer:
+      {
+        layers=OptimizeImageLayers(image,exception);
+        break;
+      }
+      case OptimizePlusLayer:
+      {
+        layers=OptimizePlusImageLayers(image,exception);
+        break;
+      }
+      case OptimizeTransLayer:
+      {
+        OptimizeImageTransparency(image,exception);
+        break;
+      }
+      case RemoveDupsLayer:
+      {
+        RemoveDuplicateLayers(&image,exception);
+        break;
+      }
+      case RemoveZeroLayer:
+      {
+        RemoveZeroDelayLayers(&image,exception);
+        break;
+      }
+      case OptimizeLayer:
+      {
+        QuantizeInfo
+          *quantize_info;
+
+        /*
+          General Purpose, GIF Animation Optimizer.
+        */
+        layers=CoalesceImages(image,exception);
+        if (layers == (Image *) NULL)
+          break;
+        image=layers;
+        layers=OptimizeImageLayers(image,exception);
+        if (layers == (Image *) NULL)
+          break;
+        image=DestroyImageList(image);
+        image=layers;
+        layers=(Image *) NULL;
+        OptimizeImageTransparency(image,exception);
+        quantize_info=AcquireQuantizeInfo(info->image_info);
+        (void) RemapImages(quantize_info,image,(Image *) NULL,exception);
+        quantize_info=DestroyQuantizeInfo(quantize_info);
+        break;
+      }
+      case CompositeLayer:
+      {
+        Image
+          *source;
+
+        RectangleInfo
+          geometry;
+
+        /*
+          Split image sequence at the first 'NULL:' image.
+        */
+        source=image;
+        while (source != (Image *) NULL)
+        {
+          source=GetNextImageInList(source);
+          if ((source != (Image *) NULL) &&
+              (LocaleCompare(source->magick,"NULL") == 0))
+            break;
+        }
+        if (source != (Image *) NULL)
+          {
+            if ((GetPreviousImageInList(source) == (Image *) NULL) ||
+                (GetNextImageInList(source) == (Image *) NULL))
+              source=(Image *) NULL;
+            else
+              {
+                /*
+                  Separate the two lists, junk the null: image.
+                */
+                source=SplitImageList(source->previous);
+                DeleteImageFromList(&source);
+              }
+          }
+        if (source == (Image *) NULL)
+          {
+            (void) ThrowMagickException(exception,GetMagickModule(),
+              OptionError,"MissingNullSeparator","layers Composite");
+            break;
+          }
+        /*
+          Adjust offset with gravity and virtual canvas.
+        */
+        SetGeometry(image,&geometry);
+        (void) ParseAbsoluteGeometry(image->geometry,&geometry);
+        geometry.width=source->page.width != 0 ? source->page.width :
+          source->columns;
+        geometry.height=source->page.height != 0 ? source->page.height :
+          source->rows;
+        GravityAdjustGeometry(image->page.width != 0 ? image->page.width :
+          image->columns,image->page.height != 0 ? image->page.height :
+          image->rows,image->gravity,&geometry);
+        CompositeLayers(image,compose,source,geometry.x,geometry.y,exception);
+        source=DestroyImageList(source);
+        break;
+      }
+    }
+    if (layers != (Image *) NULL)
+      image=layers;
+    if (image == (Image *) NULL)
+      goto PerlException;
+    for ( ; image; image=image->next)
+    {
+      AddImageToRegistry(sv,image);
+      rv=newRV(sv);
+      av_push(av,sv_bless(rv,hv));
+      SvREFCNT_dec(sv);
+    }
+    exception=DestroyExceptionInfo(exception);
+    ST(0)=av_reference;
+    SvREFCNT_dec(perl_exception);
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   M a g i c k T o M i m e                                                   #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+SV *
+MagickToMime(ref,name)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  char *name
+  ALIAS:
+    magicktomime = 1
+  CODE:
+  {
+    char
+      *mime;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    mime=MagickToMime(name);
+    RETVAL=newSVpv(mime,0);
+    mime=(char *) RelinquishMagickMemory(mime);
+  }
+  OUTPUT:
+    RETVAL
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   M o g r i f y                                                             #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Mogrify(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    Comment            =   1
+    CommentImage       =   2
+    Label              =   3
+    LabelImage         =   4
+    AddNoise           =   5
+    AddNoiseImage      =   6
+    Colorize           =   7
+    ColorizeImage      =   8
+    Border             =   9
+    BorderImage        =  10
+    Blur               =  11
+    BlurImage          =  12
+    Chop               =  13
+    ChopImage          =  14
+    Crop               =  15
+    CropImage          =  16
+    Despeckle          =  17
+    DespeckleImage     =  18
+    Edge               =  19
+    EdgeImage          =  20
+    Emboss             =  21
+    EmbossImage        =  22
+    Enhance            =  23
+    EnhanceImage       =  24
+    Flip               =  25
+    FlipImage          =  26
+    Flop               =  27
+    FlopImage          =  28
+    Frame              =  29
+    FrameImage         =  30
+    Implode            =  31
+    ImplodeImage       =  32
+    Magnify            =  33
+    MagnifyImage       =  34
+    MedianFilter       =  35
+    MedianConvolveImage  =  36
+    Minify             =  37
+    MinifyImage        =  38
+    OilPaint           =  39
+    OilPaintImage      =  40
+    ReduceNoise        =  41
+    ReduceNoiseImage   =  42
+    Roll               =  43
+    RollImage          =  44
+    Rotate             =  45
+    RotateImage        =  46
+    Sample             =  47
+    SampleImage        =  48
+    Scale              =  49
+    ScaleImage         =  50
+    Shade              =  51
+    ShadeImage         =  52
+    Sharpen            =  53
+    SharpenImage       =  54
+    Shear              =  55
+    ShearImage         =  56
+    Spread             =  57
+    SpreadImage        =  58
+    Swirl              =  59
+    SwirlImage         =  60
+    Resize             =  61
+    ResizeImage        =  62
+    Zoom               =  63
+    ZoomImage          =  64
+    Annotate           =  65
+    AnnotateImage      =  66
+    ColorFloodfill     =  67
+    ColorFloodfillImage=  68
+    Composite          =  69
+    CompositeImage     =  70
+    Contrast           =  71
+    ContrastImage      =  72
+    CycleColormap      =  73
+    CycleColormapImage =  74
+    Draw               =  75
+    DrawImage          =  76
+    Equalize           =  77
+    EqualizeImage      =  78
+    Gamma              =  79
+    GammaImage         =  80
+    Map                =  81
+    MapImage           =  82
+    MatteFloodfill     =  83
+    MatteFloodfillImage=  84
+    Modulate           =  85
+    ModulateImage      =  86
+    Negate             =  87
+    NegateImage        =  88
+    Normalize          =  89
+    NormalizeImage     =  90
+    NumberColors       =  91
+    NumberColorsImage  =  92
+    Opaque             =  93
+    OpaqueImage        =  94
+    Quantize           =  95
+    QuantizeImage      =  96
+    Raise              =  97
+    RaiseImage         =  98
+    Segment            =  99
+    SegmentImage       = 100
+    Signature          = 101
+    SignatureImage     = 102
+    Solarize           = 103
+    SolarizeImage      = 104
+    Sync               = 105
+    SyncImage          = 106
+    Texture            = 107
+    TextureImage       = 108
+    Evaluate           = 109
+    EvaluateImage      = 110
+    Transparent        = 111
+    TransparentImage   = 112
+    Threshold          = 113
+    ThresholdImage     = 114
+    Charcoal           = 115
+    CharcoalImage      = 116
+    Trim               = 117
+    TrimImage          = 118
+    Wave               = 119
+    WaveImage          = 120
+    Separate           = 121
+    SeparateImage      = 122
+    Stereo             = 125
+    StereoImage        = 126
+    Stegano            = 127
+    SteganoImage       = 128
+    Deconstruct        = 129
+    DeconstructImage   = 130
+    GaussianBlur       = 131
+    GaussianBlurImage  = 132
+    Convolve           = 133
+    ConvolveImage      = 134
+    Profile            = 135
+    ProfileImage       = 136
+    UnsharpMask        = 137
+    UnsharpMaskImage   = 138
+    MotionBlur         = 139
+    MotionBlurImage    = 140
+    OrderedDither      = 141
+    OrderedDitherImage = 142
+    Shave              = 143
+    ShaveImage         = 144
+    Level              = 145
+    LevelImage         = 146
+    Clip               = 147
+    ClipImage          = 148
+    AffineTransform    = 149
+    AffineTransformImage = 150
+    Difference         = 151
+    DifferenceImage    = 152
+    AdaptiveThreshold  = 153
+    AdaptiveThresholdImage = 154
+    Resample           = 155
+    ResampleImage      = 156
+    Describe           = 157
+    DescribeImage      = 158
+    BlackThreshold     = 159
+    BlackThresholdImage= 160
+    WhiteThreshold     = 161
+    WhiteThresholdImage= 162
+    RadialBlur         = 163
+    RadialBlurImage    = 164
+    Thumbnail          = 165
+    ThumbnailImage     = 166
+    Strip              = 167
+    StripImage         = 168
+    Tint               = 169
+    TintImage          = 170
+    Channel            = 171
+    ChannelImage       = 172
+    Splice             = 173
+    SpliceImage        = 174
+    Posterize          = 175
+    PosterizeImage     = 176
+    Shadow             = 177
+    ShadowImage        = 178
+    Identify           = 179
+    IdentifyImage      = 180
+    SepiaTone          = 181
+    SepiaToneImage     = 182
+    SigmoidalContrast  = 183
+    SigmoidalContrastImage = 184
+    Extent             = 185
+    ExtentImage        = 186
+    Vignette           = 187
+    VignetteImage      = 188
+    ContrastStretch    = 189
+    ContrastStretchImage = 190
+    Sans0              = 191
+    Sans0Image         = 192
+    Sans1              = 193
+    Sans1Image         = 194
+    AdaptiveSharpen    = 195
+    AdaptiveSharpenImage = 196
+    Transpose          = 197
+    TransposeImage     = 198
+    Transverse         = 199
+    TransverseImage    = 200
+    AutoOrient         = 201
+    AutoOrientImage    = 202
+    AdaptiveBlur       = 203
+    AdaptiveBlurImage  = 204
+    Sketch             = 205
+    SketchImage        = 206
+    UniqueColors       = 207
+    UniqueColorsImage  = 208
+    AdaptiveResize     = 209
+    AdaptiveResizeImage= 210
+    ClipMask           = 211
+    ClipMaskImage      = 212
+    LinearStretch      = 213
+    LinearStretchImage = 214
+    ColorMatrix        = 215
+    ColorMatrixImage   = 216
+    Mask               = 217
+    MaskImage          = 218
+    Polaroid           = 219
+    PolaroidImage      = 220
+    FloodfillPaint     = 221
+    FloodfillPaintImage= 222
+    Distort            = 223
+    DistortImage       = 224
+    Clut               = 225
+    ClutImage          = 226
+    LiquidRescale      = 227
+    LiquidRescaleImage = 228
+    Encipher           = 229
+    EncipherImage      = 230
+    Decipher           = 231
+    DecipherImage      = 232
+    Deskew             = 233
+    DeskewImage        = 234
+    Remap              = 235
+    RemapImage         = 236
+    SparseColor        = 237
+    SparseColorImage   = 238
+    Function           = 239
+    FunctionImage      = 240
+    SelectiveBlur      = 241
+    SelectiveBlurImage = 242
+    HaldClut           = 243
+    HaldClutImage      = 244
+    BlueShift          = 245
+    BlueShiftImage     = 246
+    ForwardFourierTransform  = 247
+    ForwardFourierTransformImage = 248
+    InverseFourierTransform = 249
+    InverseFourierTransformImage = 250
+    ColorDecisionList  = 251
+    ColorDecisionListImage = 252
+    AutoGamma          = 253
+    AutoGammaImage     = 254
+    AutoLevel          = 255
+    AutoLevelImage     = 256
+    LevelColors        = 257
+    LevelImageColors   = 258
+    Clamp              = 259
+    ClampImage         = 260
+    BrightnessContrast = 261
+    BrightnessContrastImage = 262
+    Morphology         = 263
+    MorphologyImage    = 264
+    Color              = 265
+    ColorImage         = 266
+    Mode               = 267
+    ModeImage          = 268
+    Statistic          = 269
+    StatisticImage     = 270
+    Perceptible        = 271
+    PerceptibleImage   = 272
+    Poly               = 273
+    PolyImage          = 274
+    MogrifyRegion      = 666
+  PPCODE:
+  {
+    AffineMatrix
+      affine,
+      current;
+
+    char
+      attribute_flag[MaxArguments],
+      message[MaxTextExtent];
+
+    ChannelType
+      channel,
+      channel_mask;
+
+    CompositeOperator
+      compose;
+
+    const char
+      *attribute,
+      *value;
+
+    double
+      angle;
+
+    ExceptionInfo
+      *exception;
+
+    GeometryInfo
+      geometry_info;
+
+    Image
+      *image,
+      *next,
+      *region_image;
+
+    MagickBooleanType
+      status;
+
+    MagickStatusType
+      flags;
+
+    PixelInfo
+      fill_color;
+
+    RectangleInfo
+      geometry,
+      region_info;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      base,
+      j,
+      number_images;
+
+    struct Methods
+      *rp;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      **pv,
+      *reference,
+      **reference_vector;
+
+    struct ArgumentList
+      argument_list[MaxArguments];
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    reference_vector=NULL;
+    region_image=NULL;
+    number_images=0;
+    base=2;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    region_info.width=0;
+    region_info.height=0;
+    region_info.x=0;
+    region_info.y=0;
+    region_image=(Image *) NULL;
+    image=SetupList(aTHX_ reference,&info,&reference_vector,exception);
+    if (ix && (ix != 666))
+      {
+        /*
+          Called as Method(...)
+        */
+        ix=(ix+1)/2;
+        rp=(&Methods[ix-1]);
+        attribute=rp->name;
+      }
+    else
+      {
+        /*
+          Called as Mogrify("Method",...)
+        */
+        attribute=(char *) SvPV(ST(1),na);
+        if (ix)
+          {
+            flags=ParseGravityGeometry(image,attribute,&region_info,exception);
+            attribute=(char *) SvPV(ST(2),na);
+            base++;
+          }
+        for (rp=Methods; ; rp++)
+        {
+          if (rp >= EndOf(Methods))
+            {
+              ThrowPerlException(exception,OptionError,
+                "UnrecognizedPerlMagickMethod",attribute);
+              goto PerlException;
+            }
+          if (strEQcase(attribute,rp->name))
+            break;
+        }
+        ix=rp-Methods+1;
+        base++;
+      }
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",attribute);
+        goto PerlException;
+      }
+    Zero(&argument_list,NumberOf(argument_list),struct ArgumentList);
+    Zero(&attribute_flag,NumberOf(attribute_flag),char);
+    for (i=base; (i < items) || ((i == items) && (base == items)); i+=2)
+    {
+      Arguments
+        *pp,
+        *qq;
+
+      ssize_t
+        ssize_test;
+
+      struct ArgumentList
+        *al;
+
+      SV
+        *sv;
+
+      sv=NULL;
+      ssize_test=0;
+      pp=(Arguments *) NULL;
+      qq=rp->arguments;
+      if (i == items)
+        {
+          pp=rp->arguments,
+          sv=ST(i-1);
+        }
+      else
+        for (sv=ST(i), attribute=(char *) SvPV(ST(i-1),na); ; qq++)
+        {
+          if ((qq >= EndOf(rp->arguments)) || (qq->method == NULL))
+            break;
+          if (strEQcase(attribute,qq->method) > ssize_test)
+            {
+              pp=qq;
+              ssize_test=strEQcase(attribute,qq->method);
+            }
+        }
+      if (pp == (Arguments *) NULL)
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedOption",
+            attribute);
+          goto continue_outer_loop;
+        }
+      al=(&argument_list[pp-rp->arguments]);
+      switch (pp->type)
+      {
+        case ArrayReference:
+        {
+          if (SvTYPE(sv) != SVt_RV)
+            {
+              (void) FormatLocaleString(message,MaxTextExtent,
+                "invalid %.60s value",pp->method);
+              ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
+              goto continue_outer_loop;
+            }
+          al->array_reference=SvRV(sv);
+          break;
+        }
+        case RealReference:
+        {
+          al->real_reference=SvNV(sv);
+          break;
+        }
+        case FileReference:
+        {
+          al->file_reference=(FILE *) PerlIO_findFILE(IoIFP(sv_2io(sv)));
+          break;
+        }
+        case ImageReference:
+        {
+          if (!sv_isobject(sv) ||
+              !(al->image_reference=SetupList(aTHX_ SvRV(sv),
+                (struct PackageInfo **) NULL,(SV ***) NULL,exception)))
+            {
+              ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+                PackageName);
+              goto PerlException;
+            }
+          break;
+        }
+        case IntegerReference:
+        {
+          al->integer_reference=SvIV(sv);
+          break;
+        }
+        case StringReference:
+        {
+          al->string_reference=(char *) SvPV(sv,al->length);
+          if (sv_isobject(sv))
+            al->image_reference=SetupList(aTHX_ SvRV(sv),
+              (struct PackageInfo **) NULL,(SV ***) NULL,exception);
+          break;
+        }
+        default:
+        {
+          /*
+            Is a string; look up name.
+          */
+          if ((al->length > 1) && (*(char *) SvPV(sv,al->length) == '@'))
+            {
+              al->string_reference=(char *) SvPV(sv,al->length);
+              al->integer_reference=(-1);
+              break;
+            }
+          al->integer_reference=ParseCommandOption((CommandOption) pp->type,
+            MagickFalse,SvPV(sv,na));
+          if (pp->type == MagickChannelOptions)
+            al->integer_reference=ParseChannelOption(SvPV(sv,na));
+          if ((al->integer_reference < 0) && ((al->integer_reference=SvIV(sv)) <= 0))
+            {
+              (void) FormatLocaleString(message,MaxTextExtent,
+                "invalid %.60s value",pp->method);
+              ThrowPerlException(exception,OptionError,message,SvPV(sv,na));
+              goto continue_outer_loop;
+            }
+          break;
+        }
+      }
+      attribute_flag[pp-rp->arguments]++;
+      continue_outer_loop: ;
+    }
+    (void) ResetMagickMemory((char *) &fill_color,0,sizeof(fill_color));
+    pv=reference_vector;
+    SetGeometryInfo(&geometry_info);
+    channel=DefaultChannels;
+    for (next=image; next; next=next->next)
+    {
+      image=next;
+      SetGeometry(image,&geometry);
+      if ((region_info.width*region_info.height) != 0)
+        {
+          region_image=image;
+          image=CropImage(image,&region_info,exception);
+        }
+      switch (ix)
+      {
+        default:
+        {
+          (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double) ix);
+          ThrowPerlException(exception,OptionError,
+            "UnrecognizedPerlMagickMethod",message);
+          goto PerlException;
+        }
+        case 1:  /* Comment */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].string_reference=(char *) NULL;
+          (void) SetImageProperty(image,"comment",InterpretImageProperties(
+            info ? info->image_info : (ImageInfo *) NULL,image,
+            argument_list[0].string_reference,exception),exception);
+          break;
+        }
+        case 2:  /* Label */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].string_reference=(char *) NULL;
+          (void) SetImageProperty(image,"label",InterpretImageProperties(
+            info ? info->image_info : (ImageInfo *) NULL,image,
+            argument_list[0].string_reference,exception),exception);
+          break;
+        }
+        case 3:  /* AddNoise */
+        {
+          double
+            attenuate;
+
+          if (attribute_flag[0] == 0)
+            argument_list[0].integer_reference=UniformNoise;
+          attenuate=1.0;
+          if (attribute_flag[1] != 0)
+            attenuate=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            channel=(ChannelType) argument_list[2].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=AddNoiseImage(image,(NoiseType)
+            argument_list[0].integer_reference,attenuate,exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 4:  /* Colorize */
+        {
+          PixelInfo
+            target;
+
+          (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
+            0,0,&target,exception);
+          if (attribute_flag[0] != 0)
+            (void) QueryColorCompliance(argument_list[0].string_reference,
+              AllCompliance,&target,exception);
+          if (attribute_flag[1] == 0)
+            argument_list[1].string_reference="100%";
+          image=ColorizeImage(image,argument_list[1].string_reference,&target,
+            exception);
+          break;
+        }
+        case 5:  /* Border */
+        {
+          CompositeOperator
+            compose;
+
+          geometry.width=0;
+          geometry.height=0;
+          if (attribute_flag[0] != 0)
+            flags=ParsePageGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.height=argument_list[2].integer_reference;
+          if (attribute_flag[3] != 0)
+            QueryColorCompliance(argument_list[3].string_reference,
+              AllCompliance,&image->border_color,exception);
+          if (attribute_flag[4] != 0)
+            QueryColorCompliance(argument_list[4].string_reference,
+              AllCompliance,&image->border_color,exception);
+          if (attribute_flag[5] != 0)
+            QueryColorCompliance(argument_list[5].string_reference,
+              AllCompliance,&image->border_color,exception);
+          compose=image->compose;
+          if (attribute_flag[6] != 0)
+            compose=(CompositeOperator) argument_list[6].integer_reference;
+          image=BorderImage(image,&geometry,compose,exception);
+          break;
+        }
+        case 6:  /* Blur */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            channel=(ChannelType) argument_list[3].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=BlurImage(image,geometry_info.rho,geometry_info.sigma,
+            exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 7:  /* Chop */
+        {
+          if (attribute_flag[0] != 0)
+            flags=ParseGravityGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.height=argument_list[2].integer_reference;
+          if (attribute_flag[3] != 0)
+            geometry.x=argument_list[3].integer_reference;
+          if (attribute_flag[4] != 0)
+            geometry.y=argument_list[4].integer_reference;
+          image=ChopImage(image,&geometry,exception);
+          break;
+        }
+        case 8:  /* Crop */
+        {
+          if (attribute_flag[6] != 0)
+            image->gravity=(GravityType) argument_list[6].integer_reference;
+          if (attribute_flag[0] != 0)
+            flags=ParseGravityGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.height=argument_list[2].integer_reference;
+          if (attribute_flag[3] != 0)
+            geometry.x=argument_list[3].integer_reference;
+          if (attribute_flag[4] != 0)
+            geometry.y=argument_list[4].integer_reference;
+          if (attribute_flag[5] != 0)
+            image->fuzz=StringToDoubleInterval(
+              argument_list[5].string_reference,(double) QuantumRange+1.0);
+          image=CropImage(image,&geometry,exception);
+          break;
+        }
+        case 9:  /* Despeckle */
+        {
+          image=DespeckleImage(image,exception);
+          break;
+        }
+        case 10:  /* Edge */
+        {
+          if (attribute_flag[0] != 0)
+            geometry_info.rho=argument_list[0].real_reference;
+          image=EdgeImage(image,geometry_info.rho,geometry_info.sigma,
+            exception);
+          break;
+        }
+        case 11:  /* Emboss */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          image=EmbossImage(image,geometry_info.rho,geometry_info.sigma,
+            exception);
+          break;
+        }
+        case 12:  /* Enhance */
+        {
+          image=EnhanceImage(image,exception);
+          break;
+        }
+        case 13:  /* Flip */
+        {
+          image=FlipImage(image,exception);
+          break;
+        }
+        case 14:  /* Flop */
+        {
+          image=FlopImage(image,exception);
+          break;
+        }
+        case 15:  /* Frame */
+        {
+          CompositeOperator
+            compose;
+
+          FrameInfo
+            frame_info;
+
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParsePageGeometry(image,argument_list[0].string_reference,
+                &geometry,exception);
+              frame_info.width=geometry.width;
+              frame_info.height=geometry.height;
+              frame_info.outer_bevel=geometry.x;
+              frame_info.inner_bevel=geometry.y;
+            }
+          if (attribute_flag[1] != 0)
+            frame_info.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            frame_info.height=argument_list[2].integer_reference;
+          if (attribute_flag[3] != 0)
+            frame_info.inner_bevel=argument_list[3].integer_reference;
+          if (attribute_flag[4] != 0)
+            frame_info.outer_bevel=argument_list[4].integer_reference;
+          if (attribute_flag[5] != 0)
+            QueryColorCompliance(argument_list[5].string_reference,
+              AllCompliance,&fill_color,exception);
+          if (attribute_flag[6] != 0)
+            QueryColorCompliance(argument_list[6].string_reference,
+              AllCompliance,&fill_color,exception);
+          frame_info.x=(ssize_t) frame_info.width;
+          frame_info.y=(ssize_t) frame_info.height;
+          frame_info.width=image->columns+2*frame_info.x;
+          frame_info.height=image->rows+2*frame_info.y;
+          if ((attribute_flag[5] != 0) || (attribute_flag[6] != 0))
+            image->matte_color=fill_color;
+          compose=image->compose;
+          if (attribute_flag[7] != 0)
+            compose=(CompositeOperator) argument_list[7].integer_reference;
+          image=FrameImage(image,&frame_info,compose,exception);
+          break;
+        }
+        case 16:  /* Implode */
+        {
+          PixelInterpolateMethod
+            method;
+
+          if (attribute_flag[0] == 0)
+            argument_list[0].real_reference=0.5;
+          method=UndefinedInterpolatePixel;
+          if (attribute_flag[1] != 0)
+            method=(PixelInterpolateMethod) argument_list[1].integer_reference;
+          image=ImplodeImage(image,argument_list[0].real_reference,
+            method,exception);
+          break;
+        }
+        case 17:  /* Magnify */
+        {
+          image=MagnifyImage(image,exception);
+          break;
+        }
+        case 18:  /* MedianFilter */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=geometry_info.rho;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            channel=(ChannelType) argument_list[3].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=StatisticImage(image,MedianStatistic,(size_t) geometry_info.rho,
+            (size_t) geometry_info.sigma,exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 19:  /* Minify */
+        {
+          image=MinifyImage(image,exception);
+          break;
+        }
+        case 20:  /* OilPaint */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].real_reference=0.0;
+          if (attribute_flag[1] == 0)
+            argument_list[1].real_reference=1.0;
+          image=OilPaintImage(image,argument_list[0].real_reference,
+            argument_list[1].real_reference,exception);
+          break;
+        }
+        case 21:  /* ReduceNoise */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            channel=(ChannelType) argument_list[3].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=StatisticImage(image,NonpeakStatistic,(size_t)
+            geometry_info.rho,(size_t) geometry_info.sigma,exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 22:  /* Roll */
+        {
+          if (attribute_flag[0] != 0)
+            flags=ParsePageGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.x=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.y=argument_list[2].integer_reference;
+          image=RollImage(image,geometry.x,geometry.y,exception);
+          break;
+        }
+        case 23:  /* Rotate */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].real_reference=90.0;
+          if (attribute_flag[1] != 0)
+            {
+              QueryColorCompliance(argument_list[1].string_reference,
+                AllCompliance,&image->background_color,exception);
+              if ((image->background_color.alpha_trait == BlendPixelTrait) &&
+                  (image->alpha_trait != BlendPixelTrait))
+                (void) SetImageAlpha(image,OpaqueAlpha,exception);
+            }
+          image=RotateImage(image,argument_list[0].real_reference,exception);
+          break;
+        }
+        case 24:  /* Sample */
+        {
+          if (attribute_flag[0] != 0)
+            flags=ParseRegionGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.height=argument_list[2].integer_reference;
+          image=SampleImage(image,geometry.width,geometry.height,exception);
+          break;
+        }
+        case 25:  /* Scale */
+        {
+          if (attribute_flag[0] != 0)
+            flags=ParseRegionGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.height=argument_list[2].integer_reference;
+          image=ScaleImage(image,geometry.width,geometry.height,exception);
+          break;
+        }
+        case 26:  /* Shade */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=0.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          image=ShadeImage(image,
+            argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
+            geometry_info.rho,geometry_info.sigma,exception);
+          break;
+        }
+        case 27:  /* Sharpen */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            channel=(ChannelType) argument_list[3].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=SharpenImage(image,geometry_info.rho,geometry_info.sigma,
+            exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 28:  /* Shear */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=geometry_info.rho;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            QueryColorCompliance(argument_list[3].string_reference,
+              AllCompliance,&image->background_color,exception);
+          if (attribute_flag[4] != 0)
+            QueryColorCompliance(argument_list[4].string_reference,
+              AllCompliance,&image->background_color,exception);
+          image=ShearImage(image,geometry_info.rho,geometry_info.sigma,
+            exception);
+          break;
+        }
+        case 29:  /* Spread */
+        {
+          PixelInterpolateMethod
+            method;
+
+          if (attribute_flag[0] == 0)
+            argument_list[0].real_reference=1.0;
+          method=UndefinedInterpolatePixel;
+          if (attribute_flag[1] != 0)
+            method=(PixelInterpolateMethod) argument_list[1].integer_reference;
+          image=SpreadImage(image,argument_list[0].real_reference,method,
+            exception);
+          break;
+        }
+        case 30:  /* Swirl */
+        {
+          PixelInterpolateMethod
+            method;
+
+          if (attribute_flag[0] == 0)
+            argument_list[0].real_reference=50.0;
+          method=UndefinedInterpolatePixel;
+          if (attribute_flag[1] != 0)
+            method=(PixelInterpolateMethod) argument_list[1].integer_reference;
+          image=SwirlImage(image,argument_list[0].real_reference,
+            method,exception);
+          break;
+        }
+        case 31:  /* Resize */
+        case 32:  /* Zoom */
+        {
+          if (attribute_flag[0] != 0)
+            flags=ParseRegionGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.height=argument_list[2].integer_reference;
+          if (attribute_flag[3] == 0)
+            argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
+          if (attribute_flag[4] != 0)
+            SetImageArtifact(image,"filter:support",
+              argument_list[4].string_reference);
+          image=ResizeImage(image,geometry.width,geometry.height,
+            (FilterTypes) argument_list[3].integer_reference,
+            exception);
+          break;
+        }
+        case 33:  /* Annotate */
+        {
+          DrawInfo
+            *draw_info;
+
+          draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
+            (DrawInfo *) NULL);
+          if (attribute_flag[0] != 0)
+            {
+              char
+                *text;
+
+              text=InterpretImageProperties(info ? info->image_info :
+                (ImageInfo *) NULL,image,argument_list[0].string_reference,
+                exception);
+              (void) CloneString(&draw_info->text,text);
+              text=DestroyString(text);
+            }
+          if (attribute_flag[1] != 0)
+            (void) CloneString(&draw_info->font,
+              argument_list[1].string_reference);
+          if (attribute_flag[2] != 0)
+            draw_info->pointsize=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            (void) CloneString(&draw_info->density,
+              argument_list[3].string_reference);
+          if (attribute_flag[4] != 0)
+            (void) QueryColorCompliance(argument_list[4].string_reference,
+              AllCompliance,&draw_info->undercolor,exception);
+          if (attribute_flag[5] != 0)
+            {
+              (void) QueryColorCompliance(argument_list[5].string_reference,
+                AllCompliance,&draw_info->stroke,exception);
+              if (argument_list[5].image_reference != (Image *) NULL)
+                draw_info->stroke_pattern=CloneImage(
+                  argument_list[5].image_reference,0,0,MagickTrue,exception);
+            }
+          if (attribute_flag[6] != 0)
+            {
+              (void) QueryColorCompliance(argument_list[6].string_reference,
+                AllCompliance,&draw_info->fill,exception);
+              if (argument_list[6].image_reference != (Image *) NULL)
+                draw_info->fill_pattern=CloneImage(
+                  argument_list[6].image_reference,0,0,MagickTrue,exception);
+            }
+          if (attribute_flag[7] != 0)
+            {
+              (void) CloneString(&draw_info->geometry,
+                argument_list[7].string_reference);
+              flags=ParsePageGeometry(image,argument_list[7].string_reference,
+                &geometry,exception);
+              if (((flags & SigmaValue) == 0) && ((flags & XiValue) != 0))
+                geometry_info.sigma=geometry_info.xi;
+            }
+          if (attribute_flag[8] != 0)
+            (void) QueryColorCompliance(argument_list[8].string_reference,
+              AllCompliance,&draw_info->fill,exception);
+          if (attribute_flag[11] != 0)
+            draw_info->gravity=(GravityType)
+              argument_list[11].integer_reference;
+          if (attribute_flag[25] != 0)
+            {
+              AV
+                *av;
+
+              av=(AV *) argument_list[25].array_reference;
+              if ((av_len(av) != 3) && (av_len(av) != 5))
+                {
+                  ThrowPerlException(exception,OptionError,
+                    "affine matrix must have 4 or 6 elements",PackageName);
+                  goto PerlException;
+                }
+              draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
+              draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
+              draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
+              draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
+              if (fabs(draw_info->affine.sx*draw_info->affine.sy-
+                  draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
+                {
+                  ThrowPerlException(exception,OptionError,
+                    "affine matrix is singular",PackageName);
+                   goto PerlException;
+                }
+              if (av_len(av) == 5)
+                {
+                  draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
+                  draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
+                }
+            }
+          for (j=12; j < 17; j++)
+          {
+            if (attribute_flag[j] == 0)
+              continue;
+            value=argument_list[j].string_reference;
+            angle=argument_list[j].real_reference;
+            current=draw_info->affine;
+            GetAffineMatrix(&affine);
+            switch (j)
+            {
+              case 12:
+              {
+                /*
+                  Translate.
+                */
+                flags=ParseGeometry(value,&geometry_info);
+                affine.tx=geometry_info.xi;
+                affine.ty=geometry_info.psi;
+                if ((flags & PsiValue) == 0)
+                  affine.ty=affine.tx;
+                break;
+              }
+              case 13:
+              {
+                /*
+                  Scale.
+                */
+                flags=ParseGeometry(value,&geometry_info);
+                affine.sx=geometry_info.rho;
+                affine.sy=geometry_info.sigma;
+                if ((flags & SigmaValue) == 0)
+                  affine.sy=affine.sx;
+                break;
+              }
+              case 14:
+              {
+                /*
+                  Rotate.
+                */
+                if (angle == 0.0)
+                  break;
+                affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
+                affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
+                affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
+                affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
+                break;
+              }
+              case 15:
+              {
+                /*
+                  SkewX.
+                */
+                affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
+                break;
+              }
+              case 16:
+              {
+                /*
+                  SkewY.
+                */
+                affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
+                break;
+              }
+            }
+            draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+            draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+            draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+            draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+            draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+
+              current.tx;
+            draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+
+              current.ty;
+          }
+          if (attribute_flag[9] == 0)
+            argument_list[9].real_reference=0.0;
+          if (attribute_flag[10] == 0)
+            argument_list[10].real_reference=0.0;
+          if ((attribute_flag[9] != 0) || (attribute_flag[10] != 0))
+            {
+              char
+                geometry[MaxTextExtent];
+
+              (void) FormatLocaleString(geometry,MaxTextExtent,"%+f%+f",
+                (double) argument_list[9].real_reference+draw_info->affine.tx,
+                (double) argument_list[10].real_reference+draw_info->affine.ty);
+              (void) CloneString(&draw_info->geometry,geometry);
+            }
+          if (attribute_flag[17] != 0)
+            draw_info->stroke_width=argument_list[17].real_reference;
+          if (attribute_flag[18] != 0)
+            {
+              draw_info->text_antialias=argument_list[18].integer_reference != 0 ?
+                MagickTrue : MagickFalse;
+              draw_info->stroke_antialias=draw_info->text_antialias;
+            }
+          if (attribute_flag[19] != 0)
+            (void) CloneString(&draw_info->family,
+              argument_list[19].string_reference);
+          if (attribute_flag[20] != 0)
+            draw_info->style=(StyleType) argument_list[20].integer_reference;
+          if (attribute_flag[21] != 0)
+            draw_info->stretch=(StretchType) argument_list[21].integer_reference;
+          if (attribute_flag[22] != 0)
+            draw_info->weight=argument_list[22].integer_reference;
+          if (attribute_flag[23] != 0)
+            draw_info->align=(AlignType) argument_list[23].integer_reference;
+          if (attribute_flag[24] != 0)
+            (void) CloneString(&draw_info->encoding,
+              argument_list[24].string_reference);
+          if (attribute_flag[25] != 0)
+            draw_info->fill_pattern=CloneImage(
+              argument_list[25].image_reference,0,0,MagickTrue,exception);
+          if (attribute_flag[26] != 0)
+            draw_info->fill_pattern=CloneImage(
+              argument_list[26].image_reference,0,0,MagickTrue,exception);
+          if (attribute_flag[27] != 0)
+            draw_info->stroke_pattern=CloneImage(
+              argument_list[27].image_reference,0,0,MagickTrue,exception);
+          if (attribute_flag[29] != 0)
+            draw_info->kerning=argument_list[29].real_reference;
+          if (attribute_flag[30] != 0)
+            draw_info->interline_spacing=argument_list[30].real_reference;
+          if (attribute_flag[31] != 0)
+            draw_info->interword_spacing=argument_list[31].real_reference;
+          if (attribute_flag[32] != 0)
+            draw_info->direction=(DirectionType)
+              argument_list[32].integer_reference;
+          (void) AnnotateImage(image,draw_info,exception);
+          draw_info=DestroyDrawInfo(draw_info);
+          break;
+        }
+        case 34:  /* ColorFloodfill */
+        {
+          DrawInfo
+            *draw_info;
+
+          MagickBooleanType
+            invert;
+
+          PixelInfo
+            target;
+
+          draw_info=CloneDrawInfo(info ? info->image_info :
+            (ImageInfo *) NULL,(DrawInfo *) NULL);
+          if (attribute_flag[0] != 0)
+            flags=ParsePageGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.x=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.y=argument_list[2].integer_reference;
+          if (attribute_flag[3] != 0)
+            (void) QueryColorCompliance(argument_list[3].string_reference,
+              AllCompliance,&draw_info->fill,exception);
+          (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
+            geometry.x,geometry.y,&target,exception);
+          invert=MagickFalse;
+          if (attribute_flag[4] != 0)
+            {
+              QueryColorCompliance(argument_list[4].string_reference,
+                AllCompliance,&target,exception);
+              invert=MagickTrue;
+            }
+          if (attribute_flag[5] != 0)
+            image->fuzz=StringToDoubleInterval(
+              argument_list[5].string_reference,(double) QuantumRange+1.0);
+          if (attribute_flag[6] != 0)
+            invert=(MagickBooleanType) argument_list[6].integer_reference;
+          (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
+            geometry.y,invert,exception);
+          draw_info=DestroyDrawInfo(draw_info);
+          break;
+        }
+        case 35:  /* Composite */
+        {
+          char
+            composite_geometry[MaxTextExtent];
+
+          Image
+            *composite_image,
+            *rotate_image;
+
+          MagickBooleanType
+            clip_to_self;
+
+          compose=OverCompositeOp;
+          if (attribute_flag[0] != 0)
+            composite_image=argument_list[0].image_reference;
+          else
+            {
+              ThrowPerlException(exception,OptionError,
+                "CompositeImageRequired",PackageName);
+              goto PerlException;
+            }
+          /*
+            Parameter Handling used for BOTH normal and tiled composition.
+          */
+          if (attribute_flag[1] != 0) /* compose */
+            compose=(CompositeOperator) argument_list[1].integer_reference;
+          if (attribute_flag[6] != 0) /* opacity  */
+            {
+              if (compose != DissolveCompositeOp)
+                (void) SetImageAlpha(composite_image,(Quantum)
+                  StringToDoubleInterval(argument_list[6].string_reference,
+                  (double) QuantumRange+1.0),exception);
+              else
+                {
+                  CacheView
+                    *composite_view;
+
+                  double
+                    opacity;
+
+                  MagickBooleanType
+                    sync;
+
+                  register ssize_t
+                    x;
+
+                  register Quantum
+                    *q;
+
+                  ssize_t
+                    y;
+
+                  /*
+                    Handle dissolve composite operator (patch by
+                    Kevin A. McGrail).
+                  */
+                  (void) CloneString(&image->geometry,
+                    argument_list[6].string_reference);
+                  opacity=(Quantum) StringToDoubleInterval(
+                    argument_list[6].string_reference,(double) QuantumRange+
+                    1.0);
+                  if (composite_image->alpha_trait == BlendPixelTrait)
+                    (void) SetImageAlpha(composite_image,OpaqueAlpha,exception);
+                  composite_view=AcquireAuthenticCacheView(composite_image,exception);
+                  for (y=0; y < (ssize_t) composite_image->rows ; y++)
+                  {
+                    q=GetCacheViewAuthenticPixels(composite_view,0,y,(ssize_t)
+                      composite_image->columns,1,exception);
+                    for (x=0; x < (ssize_t) composite_image->columns; x++)
+                    {
+                      if (GetPixelAlpha(image,q) == OpaqueAlpha)
+                        SetPixelAlpha(composite_image,ClampToQuantum(opacity),
+                          q);
+                      q+=GetPixelChannels(composite_image);
+                    }
+                    sync=SyncCacheViewAuthenticPixels(composite_view,exception);
+                    if (sync == MagickFalse)
+                      break;
+                  }
+                  composite_view=DestroyCacheView(composite_view);
+                }
+            }
+          if (attribute_flag[9] != 0)    /* "color=>" */
+            QueryColorCompliance(argument_list[9].string_reference,
+              AllCompliance,&composite_image->background_color,exception);
+          if (attribute_flag[12] != 0) /* "interpolate=>" */
+            image->interpolate=(PixelInterpolateMethod)
+              argument_list[12].integer_reference;
+          if (attribute_flag[13] != 0)   /* "args=>" */
+            (void) SetImageArtifact(composite_image,"compose:args",
+              argument_list[13].string_reference);
+          if (attribute_flag[14] != 0)   /* "blend=>"  depreciated */
+            (void) SetImageArtifact(composite_image,"compose:args",
+              argument_list[14].string_reference);
+          clip_to_self=MagickTrue;
+          if (attribute_flag[15] != 0)
+            clip_to_self=(MagickBooleanType)
+              argument_list[15].integer_reference;
+          /*
+            Tiling Composition (with orthogonal rotate).
+          */
+          rotate_image=(Image *) NULL;
+          if (attribute_flag[8] != 0)   /* "rotate=>" */
+            {
+               /*
+                 Rotate image.
+               */
+               rotate_image=RotateImage(composite_image,
+                 argument_list[8].real_reference,exception);
+               if (rotate_image == (Image *) NULL)
+                 break;
+            }
+          if ((attribute_flag[7] != 0) &&
+              (argument_list[7].integer_reference != 0)) /* tile */
+            {
+              ssize_t
+                x,
+                y;
+
+              /*
+                Tile the composite image.
+              */
+             if (attribute_flag[8] != 0)   /* "tile=>" */
+               (void) SetImageArtifact(rotate_image,"compose:outside-overlay",
+                 "false");
+             else
+               (void) SetImageArtifact(composite_image,
+                 "compose:outside-overlay","false");
+             for (y=0; y < (ssize_t) image->rows; y+=(ssize_t) composite_image->rows)
+                for (x=0; x < (ssize_t) image->columns; x+=(ssize_t) composite_image->columns)
+                {
+                  if (attribute_flag[8] != 0) /* rotate */
+                    (void) CompositeImage(image,rotate_image,compose,
+                      MagickTrue,x,y,exception);
+                  else
+                    (void) CompositeImage(image,composite_image,compose,
+                      MagickTrue,x,y,exception);
+                }
+              if (attribute_flag[8] != 0) /* rotate */
+                rotate_image=DestroyImage(rotate_image);
+              break;
+            }
+          /*
+            Parameter Handling used used ONLY for normal composition.
+          */
+          if (attribute_flag[5] != 0) /* gravity */
+            image->gravity=(GravityType) argument_list[5].integer_reference;
+          if (attribute_flag[2] != 0) /* geometry offset */
+            {
+              SetGeometry(image,&geometry);
+              (void) ParseAbsoluteGeometry(argument_list[2].string_reference,
+                &geometry);
+              GravityAdjustGeometry(image->columns,image->rows,image->gravity,
+                &geometry);
+            }
+          if (attribute_flag[3] != 0) /* x offset */
+            geometry.x=argument_list[3].integer_reference;
+          if (attribute_flag[4] != 0) /* y offset */
+            geometry.y=argument_list[4].integer_reference;
+          if (attribute_flag[10] != 0) /* mask */
+            {
+              if ((image->compose == DisplaceCompositeOp) ||
+                  (image->compose == DistortCompositeOp))
+                {
+                  /*
+                    Merge Y displacement into X displacement image.
+                  */
+                  composite_image=CloneImage(composite_image,0,0,MagickTrue,
+                    exception);
+                  (void) CompositeImage(composite_image,
+                    argument_list[10].image_reference,CopyGreenCompositeOp,
+                    MagickTrue,0,0,exception);
+                }
+              else
+                {
+                  Image
+                    *mask_image;
+
+                  /*
+                    Set a blending mask for the composition.
+                  */
+                  mask_image=CloneImage(argument_list[10].image_reference,0,0,
+                    MagickTrue,exception);
+                  (void) NegateImage(mask_image,MagickFalse,exception);
+                  (void) SetImageMask(composite_image,mask_image,exception);
+                  mask_image=DestroyImage(mask_image);
+                }
+            }
+          if (attribute_flag[11] != 0) /* channel */
+            channel=(ChannelType) argument_list[11].integer_reference;
+          /*
+            Composite two images (normal composition).
+          */
+          (void) FormatLocaleString(composite_geometry,MaxTextExtent,
+            "%.20gx%.20g%+.20g%+.20g",(double) composite_image->columns,
+            (double) composite_image->rows,(double) geometry.x,(double)
+            geometry.y);
+          flags=ParseGravityGeometry(image,composite_geometry,&geometry,
+            exception);
+          channel_mask=SetImageChannelMask(image,channel);
+          if (attribute_flag[8] == 0) /* no rotate */
+            CompositeImage(image,composite_image,compose,clip_to_self,
+              geometry.x,geometry.y,exception);
+          else
+            {
+              /*
+                Position adjust rotated image then composite.
+              */
+              geometry.x-=(ssize_t) (rotate_image->columns-
+                composite_image->columns)/2;
+              geometry.y-=(ssize_t) (rotate_image->rows-
+                composite_image->rows)/2;
+              CompositeImage(image,rotate_image,compose,clip_to_self,geometry.x,
+                geometry.y,exception);
+              rotate_image=DestroyImage(rotate_image);
+            }
+          if (attribute_flag[10] != 0) /* mask */
+            {
+              if ((image->compose == DisplaceCompositeOp) ||
+                  (image->compose == DistortCompositeOp))
+                composite_image=DestroyImage(composite_image);
+              else
+                (void) SetImageMask(image,(Image *) NULL,exception);
+            }
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 36:  /* Contrast */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].integer_reference=0;
+          (void) ContrastImage(image,argument_list[0].integer_reference != 0 ?
+            MagickTrue : MagickFalse,exception);
+          break;
+        }
+        case 37:  /* CycleColormap */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].integer_reference=6;
+          (void) CycleColormapImage(image,argument_list[0].integer_reference,
+            exception);
+          break;
+        }
+        case 38:  /* Draw */
+        {
+          DrawInfo
+            *draw_info;
+
+          draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
+            (DrawInfo *) NULL);
+          (void) CloneString(&draw_info->primitive,"point");
+          if (attribute_flag[0] != 0)
+            {
+              if (argument_list[0].integer_reference < 0)
+                (void) CloneString(&draw_info->primitive,
+                  argument_list[0].string_reference);
+              else
+                (void) CloneString(&draw_info->primitive,CommandOptionToMnemonic(
+                  MagickPrimitiveOptions,argument_list[0].integer_reference));
+            }
+          if (attribute_flag[1] != 0)
+            {
+              if (LocaleCompare(draw_info->primitive,"path") == 0)
+                {
+                  (void) ConcatenateString(&draw_info->primitive," '");
+                  ConcatenateString(&draw_info->primitive,
+                    argument_list[1].string_reference);
+                  (void) ConcatenateString(&draw_info->primitive,"'");
+                }
+              else
+                {
+                  (void) ConcatenateString(&draw_info->primitive," ");
+                  ConcatenateString(&draw_info->primitive,
+                    argument_list[1].string_reference);
+                }
+            }
+          if (attribute_flag[2] != 0)
+            {
+              (void) ConcatenateString(&draw_info->primitive," ");
+              (void) ConcatenateString(&draw_info->primitive,
+                CommandOptionToMnemonic(MagickMethodOptions,
+                argument_list[2].integer_reference));
+            }
+          if (attribute_flag[3] != 0)
+            {
+              (void) QueryColorCompliance(argument_list[3].string_reference,
+                AllCompliance,&draw_info->stroke,exception);
+              if (argument_list[3].image_reference != (Image *) NULL)
+                draw_info->stroke_pattern=CloneImage(
+                  argument_list[3].image_reference,0,0,MagickTrue,exception);
+            }
+          if (attribute_flag[4] != 0)
+            {
+              (void) QueryColorCompliance(argument_list[4].string_reference,
+                AllCompliance,&draw_info->fill,exception);
+              if (argument_list[4].image_reference != (Image *) NULL)
+                draw_info->fill_pattern=CloneImage(
+                  argument_list[4].image_reference,0,0,MagickTrue,exception);
+            }
+          if (attribute_flag[5] != 0)
+            draw_info->stroke_width=argument_list[5].real_reference;
+          if (attribute_flag[6] != 0)
+            (void) CloneString(&draw_info->font,
+              argument_list[6].string_reference);
+          if (attribute_flag[7] != 0)
+            (void) QueryColorCompliance(argument_list[7].string_reference,
+              AllCompliance,&draw_info->border_color,exception);
+          if (attribute_flag[8] != 0)
+            draw_info->affine.tx=argument_list[8].real_reference;
+          if (attribute_flag[9] != 0)
+            draw_info->affine.ty=argument_list[9].real_reference;
+          if (attribute_flag[20] != 0)
+            {
+              AV
+                *av;
+
+              av=(AV *) argument_list[20].array_reference;
+              if ((av_len(av) != 3) && (av_len(av) != 5))
+                {
+                  ThrowPerlException(exception,OptionError,
+                    "affine matrix must have 4 or 6 elements",PackageName);
+                  goto PerlException;
+                }
+              draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
+              draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
+              draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
+              draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
+              if (fabs(draw_info->affine.sx*draw_info->affine.sy-
+                  draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
+                {
+                  ThrowPerlException(exception,OptionError,
+                    "affine matrix is singular",PackageName);
+                   goto PerlException;
+                }
+              if (av_len(av) == 5)
+                {
+                  draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
+                  draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
+                }
+            }
+          for (j=10; j < 15; j++)
+          {
+            if (attribute_flag[j] == 0)
+              continue;
+            value=argument_list[j].string_reference;
+            angle=argument_list[j].real_reference;
+            current=draw_info->affine;
+            GetAffineMatrix(&affine);
+            switch (j)
+            {
+              case 10:
+              {
+                /*
+                  Translate.
+                */
+                flags=ParseGeometry(value,&geometry_info);
+                affine.tx=geometry_info.xi;
+                affine.ty=geometry_info.psi;
+                if ((flags & PsiValue) == 0)
+                  affine.ty=affine.tx;
+                break;
+              }
+              case 11:
+              {
+                /*
+                  Scale.
+                */
+                flags=ParseGeometry(value,&geometry_info);
+                affine.sx=geometry_info.rho;
+                affine.sy=geometry_info.sigma;
+                if ((flags & SigmaValue) == 0)
+                  affine.sy=affine.sx;
+                break;
+              }
+              case 12:
+              {
+                /*
+                  Rotate.
+                */
+                if (angle == 0.0)
+                  break;
+                affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
+                affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
+                affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
+                affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
+                break;
+              }
+              case 13:
+              {
+                /*
+                  SkewX.
+                */
+                affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
+                break;
+              }
+              case 14:
+              {
+                /*
+                  SkewY.
+                */
+                affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
+                break;
+              }
+            }
+            draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+            draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+            draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+            draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+            draw_info->affine.tx=
+              current.sx*affine.tx+current.ry*affine.ty+current.tx;
+            draw_info->affine.ty=
+              current.rx*affine.tx+current.sy*affine.ty+current.ty;
+          }
+          if (attribute_flag[15] != 0)
+            draw_info->fill_pattern=CloneImage(
+              argument_list[15].image_reference,0,0,MagickTrue,exception);
+          if (attribute_flag[16] != 0)
+            draw_info->pointsize=argument_list[16].real_reference;
+          if (attribute_flag[17] != 0)
+            {
+              draw_info->stroke_antialias=argument_list[17].integer_reference != 0
+                ? MagickTrue : MagickFalse;
+              draw_info->text_antialias=draw_info->stroke_antialias;
+            }
+          if (attribute_flag[18] != 0)
+            (void) CloneString(&draw_info->density,
+              argument_list[18].string_reference);
+          if (attribute_flag[19] != 0)
+            draw_info->stroke_width=argument_list[19].real_reference;
+          if (attribute_flag[21] != 0)
+            draw_info->dash_offset=argument_list[21].real_reference;
+          if (attribute_flag[22] != 0)
+            {
+              AV
+                *av;
+
+              av=(AV *) argument_list[22].array_reference;
+              draw_info->dash_pattern=(double *) AcquireQuantumMemory(
+                av_len(av)+2UL,sizeof(*draw_info->dash_pattern));
+              if (draw_info->dash_pattern != (double *) NULL)
+                {
+                  for (i=0; i <= av_len(av); i++)
+                    draw_info->dash_pattern[i]=(double)
+                      SvNV(*(av_fetch(av,i,0)));
+                  draw_info->dash_pattern[i]=0.0;
+                }
+            }
+          if (attribute_flag[23] != 0)
+            image->interpolate=(PixelInterpolateMethod)
+              argument_list[23].integer_reference;
+          if ((attribute_flag[24] != 0) &&
+              (draw_info->fill_pattern != (Image *) NULL))
+            flags=ParsePageGeometry(draw_info->fill_pattern,
+              argument_list[24].string_reference,
+              &draw_info->fill_pattern->tile_offset,exception);
+          if (attribute_flag[25] != 0)
+            {
+              (void) ConcatenateString(&draw_info->primitive," '");
+              (void) ConcatenateString(&draw_info->primitive,
+                argument_list[25].string_reference);
+              (void) ConcatenateString(&draw_info->primitive,"'");
+            }
+          if (attribute_flag[26] != 0)
+            draw_info->fill_pattern=CloneImage(
+              argument_list[26].image_reference,0,0,MagickTrue,exception);
+          if (attribute_flag[27] != 0)
+            draw_info->stroke_pattern=CloneImage(
+              argument_list[27].image_reference,0,0,MagickTrue,exception);
+          if (attribute_flag[28] != 0)
+            (void) CloneString(&draw_info->primitive,
+              argument_list[28].string_reference);
+          if (attribute_flag[29] != 0)
+            draw_info->kerning=argument_list[29].real_reference;
+          if (attribute_flag[30] != 0)
+            draw_info->interline_spacing=argument_list[30].real_reference;
+          if (attribute_flag[31] != 0)
+            draw_info->interword_spacing=argument_list[31].real_reference;
+          if (attribute_flag[32] != 0)
+            draw_info->direction=(DirectionType)
+              argument_list[32].integer_reference;
+          DrawImage(image,draw_info,exception);
+          draw_info=DestroyDrawInfo(draw_info);
+          break;
+        }
+        case 39:  /* Equalize */
+        {
+          if (attribute_flag[0] != 0)
+            channel=(ChannelType) argument_list[0].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          EqualizeImage(image,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 40:  /* Gamma */
+        {
+          if (attribute_flag[1] != 0)
+            channel=(ChannelType) argument_list[1].integer_reference;
+          if (attribute_flag[2] == 0)
+            argument_list[2].real_reference=1.0;
+          if (attribute_flag[3] == 0)
+            argument_list[3].real_reference=1.0;
+          if (attribute_flag[4] == 0)
+            argument_list[4].real_reference=1.0;
+          if (attribute_flag[0] == 0)
+            {
+              (void) FormatLocaleString(message,MaxTextExtent,
+                "%.15g,%.15g,%.15g",(double) argument_list[2].real_reference,
+                (double) argument_list[3].real_reference,
+                (double) argument_list[4].real_reference);
+              argument_list[0].string_reference=message;
+            }
+          (void) GammaImage(image,StringToDouble(
+            argument_list[0].string_reference,(char **) NULL),exception);
+          break;
+        }
+        case 41:  /* Map */
+        {
+          QuantizeInfo
+            *quantize_info;
+
+          if (attribute_flag[0] == 0)
+            {
+              ThrowPerlException(exception,OptionError,"MapImageRequired",
+                PackageName);
+              goto PerlException;
+            }
+          quantize_info=AcquireQuantizeInfo(info->image_info);
+          if (attribute_flag[1] != 0)
+            quantize_info->dither_method=(DitherMethod)
+              argument_list[1].integer_reference;
+          (void) RemapImages(quantize_info,image,
+            argument_list[0].image_reference,exception);
+          quantize_info=DestroyQuantizeInfo(quantize_info);
+          break;
+        }
+        case 42:  /* MatteFloodfill */
+        {
+          DrawInfo
+            *draw_info;
+
+          MagickBooleanType
+            invert;
+
+          PixelInfo
+            target;
+
+          draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
+            (DrawInfo *) NULL);
+          if (attribute_flag[0] != 0)
+            flags=ParsePageGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.x=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.y=argument_list[2].integer_reference;
+          if (image->alpha_trait != BlendPixelTrait)
+            (void) SetImageAlpha(image,OpaqueAlpha,exception);
+          (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
+            geometry.x,geometry.y,&target,exception);
+          if (attribute_flag[4] != 0)
+            QueryColorCompliance(argument_list[4].string_reference,
+              AllCompliance,&target,exception);
+          if (attribute_flag[3] != 0)
+            target.alpha=StringToDoubleInterval(
+              argument_list[3].string_reference,(double) (double) QuantumRange+
+              1.0);
+          if (attribute_flag[5] != 0)
+            image->fuzz=StringToDoubleInterval(
+              argument_list[5].string_reference,(double) QuantumRange+1.0);
+          invert=MagickFalse;
+          if (attribute_flag[6] != 0)
+            invert=(MagickBooleanType) argument_list[6].integer_reference;
+          channel_mask=SetImageChannelMask(image,AlphaChannel);
+          (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
+            geometry.y,invert,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          draw_info=DestroyDrawInfo(draw_info);
+          break;
+        }
+        case 43:  /* Modulate */
+        {
+          char
+            modulate[MaxTextExtent];
+
+          geometry_info.rho=100.0;
+          geometry_info.sigma=100.0;
+          geometry_info.xi=100.0;
+          if (attribute_flag[0] != 0)
+            (void)ParseGeometry(argument_list[0].string_reference,
+              &geometry_info);
+          if (attribute_flag[1] != 0)
+            geometry_info.xi=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            {
+              geometry_info.sigma=argument_list[3].real_reference;
+              SetImageArtifact(image,"modulate:colorspace","HWB");
+            }
+          if (attribute_flag[4] != 0)
+            {
+              geometry_info.rho=argument_list[4].real_reference;
+              SetImageArtifact(image,"modulate:colorspace","HSB");
+            }
+          if (attribute_flag[5] != 0)
+            {
+              geometry_info.sigma=argument_list[5].real_reference;
+              SetImageArtifact(image,"modulate:colorspace","HSL");
+            }
+          if (attribute_flag[6] != 0)
+            {
+              geometry_info.rho=argument_list[6].real_reference;
+              SetImageArtifact(image,"modulate:colorspace","HWB");
+            }
+          (void) FormatLocaleString(modulate,MaxTextExtent,"%.15g,%.15g,%.15g",
+            geometry_info.rho,geometry_info.sigma,geometry_info.xi);
+          (void) ModulateImage(image,modulate,exception);
+          break;
+        }
+        case 44:  /* Negate */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].integer_reference=0;
+          if (attribute_flag[1] != 0)
+            channel=(ChannelType) argument_list[1].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) NegateImage(image,argument_list[0].integer_reference != 0 ?
+            MagickTrue : MagickFalse,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 45:  /* Normalize */
+        {
+          if (attribute_flag[0] != 0)
+            channel=(ChannelType) argument_list[0].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          NormalizeImage(image,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 46:  /* NumberColors */
+          break;
+        case 47:  /* Opaque */
+        {
+          MagickBooleanType
+            invert;
+
+          PixelInfo
+            fill_color,
+            target;
+
+          (void) QueryColorCompliance("none",AllCompliance,&target,
+             exception);
+          (void) QueryColorCompliance("none",AllCompliance,&fill_color,
+            exception);
+          if (attribute_flag[0] != 0)
+            (void) QueryColorCompliance(argument_list[0].string_reference,
+              AllCompliance,&target,exception);
+          if (attribute_flag[1] != 0)
+            (void) QueryColorCompliance(argument_list[1].string_reference,
+              AllCompliance,&fill_color,exception);
+          if (attribute_flag[2] != 0)
+            image->fuzz=StringToDoubleInterval(
+              argument_list[2].string_reference,(double) QuantumRange+1.0);
+          if (attribute_flag[3] != 0)
+            channel=(ChannelType) argument_list[3].integer_reference;
+          invert=MagickFalse;
+          if (attribute_flag[4] != 0)
+            invert=(MagickBooleanType) argument_list[4].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) OpaquePaintImage(image,&target,&fill_color,invert,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 48:  /* Quantize */
+        {
+          QuantizeInfo
+            *quantize_info;
+
+          quantize_info=AcquireQuantizeInfo(info->image_info);
+          if (attribute_flag[0] != 0)
+            quantize_info->number_colors=(size_t)
+              argument_list[0].integer_reference;
+          if (attribute_flag[1] != 0)
+            quantize_info->tree_depth=(size_t)
+              argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            quantize_info->colorspace=(ColorspaceType)
+              argument_list[2].integer_reference;
+          if (attribute_flag[3] != 0)
+            quantize_info->dither_method=(DitherMethod)
+              argument_list[3].integer_reference;
+          if (attribute_flag[4] != 0)
+            quantize_info->measure_error=argument_list[4].integer_reference !=
+              0 ? MagickTrue : MagickFalse;
+          if (attribute_flag[5] != 0)
+            (void) QueryColorCompliance(argument_list[5].string_reference,
+              AllCompliance,&image->transparent_color,exception);
+          if (attribute_flag[5] && argument_list[5].integer_reference)
+            {
+              (void) QuantizeImages(quantize_info,image,exception);
+              goto PerlException;
+            }
+          if (attribute_flag[6] != 0)
+            quantize_info->dither_method=(DitherMethod)
+              argument_list[6].integer_reference;
+          if ((image->storage_class == DirectClass) ||
+              (image->colors > quantize_info->number_colors) ||
+              (quantize_info->colorspace == GRAYColorspace))
+            (void) QuantizeImage(quantize_info,image,exception);
+          else
+            CompressImageColormap(image,exception);
+          quantize_info=DestroyQuantizeInfo(quantize_info);
+          break;
+        }
+        case 49:  /* Raise */
+        {
+          if (attribute_flag[0] != 0)
+            flags=ParsePageGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.height=argument_list[2].integer_reference;
+          if (attribute_flag[3] == 0)
+            argument_list[3].integer_reference=1;
+          (void) RaiseImage(image,&geometry,
+            argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
+            exception);
+          break;
+        }
+        case 50:  /* Segment */
+        {
+          ColorspaceType
+            colorspace;
+
+          double
+            cluster_threshold,
+            smoothing_threshold;
+
+          MagickBooleanType
+            verbose;
+
+          cluster_threshold=1.0;
+          smoothing_threshold=1.5;
+          colorspace=sRGBColorspace;
+          verbose=MagickFalse;
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              cluster_threshold=geometry_info.rho;
+              if (flags & SigmaValue)
+                smoothing_threshold=geometry_info.sigma;
+            }
+          if (attribute_flag[1] != 0)
+            cluster_threshold=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            smoothing_threshold=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            colorspace=(ColorspaceType) argument_list[3].integer_reference;
+          if (attribute_flag[4] != 0)
+            verbose=argument_list[4].integer_reference != 0 ?
+              MagickTrue : MagickFalse;
+          (void) SegmentImage(image,colorspace,verbose,cluster_threshold,
+            smoothing_threshold,exception);
+          break;
+        }
+        case 51:  /* Signature */
+        {
+          (void) SignatureImage(image,exception);
+          break;
+        }
+        case 52:  /* Solarize */
+        {
+          geometry_info.rho=QuantumRange/2.0;
+          if (attribute_flag[0] != 0)
+            flags=ParseGeometry(argument_list[0].string_reference,
+              &geometry_info);
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=StringToDoubleInterval(
+              argument_list[1].string_reference,(double) QuantumRange+1.0);
+          (void) SolarizeImage(image,geometry_info.rho,exception);
+          break;
+        }
+        case 53:  /* Sync */
+        {
+          (void) SyncImage(image,exception);
+          break;
+        }
+        case 54:  /* Texture */
+        {
+          if (attribute_flag[0] == 0)
+            break;
+          TextureImage(image,argument_list[0].image_reference,exception);
+          break;
+        }
+        case 55:  /* Evalute */
+        {
+          MagickEvaluateOperator
+            op;
+
+          op=SetEvaluateOperator;
+          if (attribute_flag[0] == MagickFalse)
+            argument_list[0].real_reference=0.0;
+          if (attribute_flag[1] != MagickFalse)
+            op=(MagickEvaluateOperator) argument_list[1].integer_reference;
+          if (attribute_flag[2] != MagickFalse)
+            channel=(ChannelType) argument_list[2].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) EvaluateImage(image,op,argument_list[0].real_reference,
+            exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 56:  /* Transparent */
+        {
+          double
+            opacity;
+
+          MagickBooleanType
+            invert;
+
+          PixelInfo
+            target;
+
+          (void) QueryColorCompliance("none",AllCompliance,&target,
+            exception);
+          if (attribute_flag[0] != 0)
+            (void) QueryColorCompliance(argument_list[0].string_reference,
+              AllCompliance,&target,exception);
+          opacity=TransparentAlpha;
+          if (attribute_flag[1] != 0)
+            opacity=StringToDoubleInterval(argument_list[1].string_reference,
+              (double) QuantumRange+1.0);
+          if (attribute_flag[2] != 0)
+            image->fuzz=StringToDoubleInterval(
+              argument_list[2].string_reference,(double) QuantumRange+1.0);
+          if (attribute_flag[3] == 0)
+            argument_list[3].integer_reference=0;
+          invert=MagickFalse;
+          if (attribute_flag[3] != 0)
+            invert=(MagickBooleanType) argument_list[3].integer_reference;
+          (void) TransparentPaintImage(image,&target,ClampToQuantum(opacity),
+            invert,exception);
+          break;
+        }
+        case 57:  /* Threshold */
+        {
+          double
+            threshold;
+
+          if (attribute_flag[0] == 0)
+            argument_list[0].string_reference="50%";
+          if (attribute_flag[1] != 0)
+            channel=(ChannelType) argument_list[1].integer_reference;
+          threshold=StringToDoubleInterval(argument_list[0].string_reference,
+            (double) QuantumRange+1.0);
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) BilevelImage(image,threshold,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 58:  /* Charcoal */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          image=CharcoalImage(image,geometry_info.rho,geometry_info.sigma,
+            exception);
+          break;
+        }
+        case 59:  /* Trim */
+        {
+          if (attribute_flag[0] != 0)
+            image->fuzz=StringToDoubleInterval(
+              argument_list[0].string_reference,(double) QuantumRange+1.0);
+          image=TrimImage(image,exception);
+          break;
+        }
+        case 60:  /* Wave */
+        {
+          PixelInterpolateMethod
+            method;
+
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          method=UndefinedInterpolatePixel;
+          if (attribute_flag[3] != 0)
+            method=(PixelInterpolateMethod) argument_list[3].integer_reference;
+          image=WaveImage(image,geometry_info.rho,geometry_info.sigma,
+            method,exception);
+          break;
+        }
+        case 61:  /* Separate */
+        {
+          if (attribute_flag[0] != 0)
+            channel=(ChannelType) argument_list[0].integer_reference;
+          image=SeparateImage(image,channel,exception);
+          break;
+        }
+        case 63:  /* Stereo */
+        {
+          if (attribute_flag[0] == 0)
+            {
+              ThrowPerlException(exception,OptionError,"StereoImageRequired",
+                PackageName);
+              goto PerlException;
+            }
+          if (attribute_flag[1] != 0)
+            geometry.x=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.y=argument_list[2].integer_reference;
+          image=StereoAnaglyphImage(image,argument_list[0].image_reference,
+            geometry.x,geometry.y,exception);
+          break;
+        }
+        case 64:  /* Stegano */
+        {
+          if (attribute_flag[0] == 0)
+            {
+              ThrowPerlException(exception,OptionError,"SteganoImageRequired",
+                PackageName);
+              goto PerlException;
+            }
+          if (attribute_flag[1] == 0)
+            argument_list[1].integer_reference=0;
+          image->offset=argument_list[1].integer_reference;
+          image=SteganoImage(image,argument_list[0].image_reference,exception);
+          break;
+        }
+        case 65:  /* Deconstruct */
+        {
+          image=CompareImagesLayers(image,CompareAnyLayer,exception);
+          break;
+        }
+        case 66:  /* GaussianBlur */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            channel=(ChannelType) argument_list[3].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=GaussianBlurImage(image,geometry_info.rho,geometry_info.sigma,
+            exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 67:  /* Convolve */
+        {
+          KernelInfo
+            *kernel;
+
+          kernel=(KernelInfo *) NULL;
+          if ((attribute_flag[0] == 0) && (attribute_flag[3] == 0))
+            break;
+          if (attribute_flag[0] != 0)
+            {
+              AV
+                *av;
+
+              size_t
+                order;
+
+              kernel=AcquireKernelInfo((const char *) NULL);
+              if (kernel == (KernelInfo *) NULL)
+                break;
+              av=(AV *) argument_list[0].array_reference;
+              order=(size_t) sqrt(av_len(av)+1);
+              kernel->width=order;
+              kernel->height=order;
+              kernel->values=(MagickRealType *) AcquireAlignedMemory(order,
+                order*sizeof(*kernel->values));
+              if (kernel->values == (MagickRealType *) NULL)
+                {
+                  kernel=DestroyKernelInfo(kernel);
+                  ThrowPerlException(exception,ResourceLimitFatalError,
+                    "MemoryAllocationFailed",PackageName);
+                  goto PerlException;
+                }
+              for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
+                kernel->values[j]=(MagickRealType) SvNV(*(av_fetch(av,j,0)));
+              for ( ; j < (ssize_t) (order*order); j++)
+                kernel->values[j]=0.0;
+            }
+          if (attribute_flag[1] != 0)
+            channel=(ChannelType) argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            SetImageArtifact(image,"filter:blur",
+              argument_list[2].string_reference);
+          if (attribute_flag[3] != 0)
+            {
+              kernel=AcquireKernelInfo(argument_list[3].string_reference);
+              if (kernel == (KernelInfo *) NULL)
+                break;
+            }
+          channel_mask=SetImageChannelMask(image,channel);
+          image=ConvolveImage(image,kernel,exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          kernel=DestroyKernelInfo(kernel);
+          break;
+        }
+        case 68:  /* Profile */
+        {
+          const char
+            *name;
+
+          Image
+            *profile_image;
+
+          ImageInfo
+            *profile_info;
+
+          StringInfo
+            *profile;
+
+          name="*";
+          if (attribute_flag[0] != 0)
+            name=argument_list[0].string_reference;
+          if (attribute_flag[2] != 0)
+            image->rendering_intent=(RenderingIntent)
+              argument_list[2].integer_reference;
+          if (attribute_flag[3] != 0)
+            image->black_point_compensation=
+              argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse;
+          if (attribute_flag[1] != 0)
+            {
+              if (argument_list[1].length == 0)
+                {
+                  /*
+                    Remove a profile from the image.
+                  */
+                  (void) ProfileImage(image,name,(const unsigned char *) NULL,0,
+                    exception);
+                  break;
+                }
+              /*
+                Associate user supplied profile with the image.
+              */
+              profile=AcquireStringInfo(argument_list[1].length);
+              SetStringInfoDatum(profile,(const unsigned char *)
+                argument_list[1].string_reference);
+              (void) ProfileImage(image,name,GetStringInfoDatum(profile),
+                (size_t) GetStringInfoLength(profile),exception);
+              profile=DestroyStringInfo(profile);
+              break;
+            }
+          /*
+            Associate a profile with the image.
+          */
+          profile_info=CloneImageInfo(info ? info->image_info :
+            (ImageInfo *) NULL);
+          profile_image=ReadImages(profile_info,name,exception);
+          if (profile_image == (Image *) NULL)
+            break;
+          ResetImageProfileIterator(profile_image);
+          name=GetNextImageProfile(profile_image);
+          while (name != (const char *) NULL)
+          {
+            const StringInfo
+              *profile;
+
+            profile=GetImageProfile(profile_image,name);
+            if (profile != (const StringInfo *) NULL)
+              (void) ProfileImage(image,name,GetStringInfoDatum(profile),
+                (size_t) GetStringInfoLength(profile),exception);
+            name=GetNextImageProfile(profile_image);
+          }
+          profile_image=DestroyImage(profile_image);
+          profile_info=DestroyImageInfo(profile_info);
+          break;
+        }
+        case 69:  /* UnsharpMask */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+              if ((flags & XiValue) == 0)
+                geometry_info.xi=1.0;
+              if ((flags & PsiValue) == 0)
+                geometry_info.psi=0.5;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            geometry_info.xi=argument_list[3].real_reference;
+          if (attribute_flag[4] != 0)
+            geometry_info.psi=argument_list[4].real_reference;
+          if (attribute_flag[5] != 0)
+            channel=(ChannelType) argument_list[5].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=UnsharpMaskImage(image,geometry_info.rho,geometry_info.sigma,
+            geometry_info.xi,geometry_info.psi,exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 70:  /* MotionBlur */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+              if ((flags & XiValue) == 0)
+                geometry_info.xi=1.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            geometry_info.xi=argument_list[3].real_reference;
+          if (attribute_flag[4] != 0)
+            channel=(ChannelType) argument_list[4].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=MotionBlurImage(image,geometry_info.rho,geometry_info.sigma,
+            geometry_info.xi,exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 71:  /* OrderedDither */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].string_reference="o8x8";
+          if (attribute_flag[1] != 0)
+            channel=(ChannelType) argument_list[1].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) OrderedPosterizeImage(image,argument_list[0].string_reference,
+            exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 72:  /* Shave */
+        {
+          if (attribute_flag[0] != 0)
+            flags=ParsePageGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.height=argument_list[2].integer_reference;
+          image=ShaveImage(image,&geometry,exception);
+          break;
+        }
+        case 73:  /* Level */
+        {
+          double
+            black_point,
+            gamma,
+            white_point;
+
+          black_point=0.0;
+          white_point=(double) image->columns*image->rows;
+          gamma=1.0;
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              black_point=geometry_info.rho;
+              if ((flags & SigmaValue) != 0)
+                white_point=geometry_info.sigma;
+              if ((flags & XiValue) != 0)
+                gamma=geometry_info.xi;
+              if ((flags & PercentValue) != 0)
+                {
+                  black_point*=(double) (QuantumRange/100.0);
+                  white_point*=(double) (QuantumRange/100.0);
+                }
+              if ((flags & SigmaValue) == 0)
+                white_point=(double) QuantumRange-black_point;
+            }
+          if (attribute_flag[1] != 0)
+            black_point=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            white_point=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            gamma=argument_list[3].real_reference;
+          if (attribute_flag[4] != 0)
+            channel=(ChannelType) argument_list[4].integer_reference;
+          if (attribute_flag[5] != 0)
+            {
+              argument_list[0].real_reference=argument_list[5].real_reference;
+              attribute_flag[0]=attribute_flag[5];
+            }
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) LevelImage(image,black_point,white_point,gamma,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 74:  /* Clip */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].string_reference="#1";
+          if (attribute_flag[1] == 0)
+            argument_list[1].integer_reference=MagickTrue;
+          (void) ClipImagePath(image,argument_list[0].string_reference,
+            argument_list[1].integer_reference != 0 ? MagickTrue : MagickFalse,
+            exception);
+          break;
+        }
+        case 75:  /* AffineTransform */
+        {
+          DrawInfo
+            *draw_info;
+
+          draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
+            (DrawInfo *) NULL);
+          if (attribute_flag[0] != 0)
+            {
+              AV
+                *av;
+
+              av=(AV *) argument_list[0].array_reference;
+              if ((av_len(av) != 3) && (av_len(av) != 5))
+                {
+                  ThrowPerlException(exception,OptionError,
+                    "affine matrix must have 4 or 6 elements",PackageName);
+                  goto PerlException;
+                }
+              draw_info->affine.sx=(double) SvNV(*(av_fetch(av,0,0)));
+              draw_info->affine.rx=(double) SvNV(*(av_fetch(av,1,0)));
+              draw_info->affine.ry=(double) SvNV(*(av_fetch(av,2,0)));
+              draw_info->affine.sy=(double) SvNV(*(av_fetch(av,3,0)));
+              if (fabs(draw_info->affine.sx*draw_info->affine.sy-
+                  draw_info->affine.rx*draw_info->affine.ry) < MagickEpsilon)
+                {
+                  ThrowPerlException(exception,OptionError,
+                    "affine matrix is singular",PackageName);
+                   goto PerlException;
+                }
+              if (av_len(av) == 5)
+                {
+                  draw_info->affine.tx=(double) SvNV(*(av_fetch(av,4,0)));
+                  draw_info->affine.ty=(double) SvNV(*(av_fetch(av,5,0)));
+                }
+            }
+          for (j=1; j < 6; j++)
+          {
+            if (attribute_flag[j] == 0)
+              continue;
+            value=argument_list[j].string_reference;
+            angle=argument_list[j].real_reference;
+            current=draw_info->affine;
+            GetAffineMatrix(&affine);
+            switch (j)
+            {
+              case 1:
+              {
+                /*
+                  Translate.
+                */
+                flags=ParseGeometry(value,&geometry_info);
+                affine.tx=geometry_info.xi;
+                affine.ty=geometry_info.psi;
+                if ((flags & PsiValue) == 0)
+                  affine.ty=affine.tx;
+                break;
+              }
+              case 2:
+              {
+                /*
+                  Scale.
+                */
+                flags=ParseGeometry(value,&geometry_info);
+                affine.sx=geometry_info.rho;
+                affine.sy=geometry_info.sigma;
+                if ((flags & SigmaValue) == 0)
+                  affine.sy=affine.sx;
+                break;
+              }
+              case 3:
+              {
+                /*
+                  Rotate.
+                */
+                if (angle == 0.0)
+                  break;
+                affine.sx=cos(DegreesToRadians(fmod(angle,360.0)));
+                affine.rx=sin(DegreesToRadians(fmod(angle,360.0)));
+                affine.ry=(-sin(DegreesToRadians(fmod(angle,360.0))));
+                affine.sy=cos(DegreesToRadians(fmod(angle,360.0)));
+                break;
+              }
+              case 4:
+              {
+                /*
+                  SkewX.
+                */
+                affine.ry=tan(DegreesToRadians(fmod(angle,360.0)));
+                break;
+              }
+              case 5:
+              {
+                /*
+                  SkewY.
+                */
+                affine.rx=tan(DegreesToRadians(fmod(angle,360.0)));
+                break;
+              }
+            }
+            draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+            draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+            draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+            draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+            draw_info->affine.tx=
+              current.sx*affine.tx+current.ry*affine.ty+current.tx;
+            draw_info->affine.ty=
+              current.rx*affine.tx+current.sy*affine.ty+current.ty;
+          }
+          if (attribute_flag[6] != 0)
+            image->interpolate=(PixelInterpolateMethod)
+              argument_list[6].integer_reference;
+          if (attribute_flag[7] != 0)
+            QueryColorCompliance(argument_list[7].string_reference,
+              AllCompliance,&image->background_color,exception);
+          image=AffineTransformImage(image,&draw_info->affine,exception);
+          draw_info=DestroyDrawInfo(draw_info);
+          break;
+        }
+        case 76:  /* Difference */
+        {
+          if (attribute_flag[0] == 0)
+            {
+              ThrowPerlException(exception,OptionError,
+                "ReferenceImageRequired",PackageName);
+              goto PerlException;
+            }
+          if (attribute_flag[1] != 0)
+            image->fuzz=StringToDoubleInterval(
+              argument_list[1].string_reference,(double) QuantumRange+1.0);
+          (void) IsImagesEqual(image,argument_list[0].image_reference,
+            exception);
+          break;
+        }
+        case 77:  /* AdaptiveThreshold */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & PercentValue) != 0)
+                geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].integer_reference;
+          if (attribute_flag[3] != 0)
+            geometry_info.xi=argument_list[3].integer_reference;;
+          image=AdaptiveThresholdImage(image,(size_t) geometry_info.rho,
+            (size_t) geometry_info.sigma,(double) geometry_info.xi,exception);
+          break;
+        }
+        case 78:  /* Resample */
+        {
+          size_t
+            height,
+            width;
+
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=geometry_info.rho;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] == 0)
+            argument_list[3].integer_reference=(ssize_t) UndefinedFilter;
+          if (attribute_flag[4] == 0)
+            SetImageArtifact(image,"filter:support",
+              argument_list[4].string_reference);
+          width=(size_t) (geometry_info.rho*image->columns/
+            (image->resolution.x == 0.0 ? 72.0 : image->resolution.x)+0.5);
+          height=(size_t) (geometry_info.sigma*image->rows/
+            (image->resolution.y == 0.0 ? 72.0 : image->resolution.y)+0.5);
+          image=ResizeImage(image,width,height,(FilterTypes)
+            argument_list[3].integer_reference,exception);
+          if (image != (Image *) NULL)
+            {
+              image->resolution.x=geometry_info.rho;
+              image->resolution.y=geometry_info.sigma;
+            }
+          break;
+        }
+        case 79:  /* Describe */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].file_reference=(FILE *) NULL;
+          if (attribute_flag[1] != 0)
+            (void) SetImageArtifact(image,"identify:features",
+              argument_list[1].string_reference);
+          (void) IdentifyImage(image,argument_list[0].file_reference,
+            MagickTrue,exception);
+          break;
+        }
+        case 80:  /* BlackThreshold */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].string_reference="50%";
+          if (attribute_flag[2] != 0)
+            channel=(ChannelType) argument_list[2].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          BlackThresholdImage(image,argument_list[0].string_reference,
+            exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 81:  /* WhiteThreshold */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].string_reference="50%";
+          if (attribute_flag[2] != 0)
+            channel=(ChannelType) argument_list[2].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          WhiteThresholdImage(image,argument_list[0].string_reference,
+            exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 82:  /* RadialBlur */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            channel=(ChannelType) argument_list[2].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=RadialBlurImage(image,geometry_info.rho,exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 83:  /* Thumbnail */
+        {
+          if (attribute_flag[0] != 0)
+            flags=ParseRegionGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.height=argument_list[2].integer_reference;
+          image=ThumbnailImage(image,geometry.width,geometry.height,exception);
+          break;
+        }
+        case 84:  /* Strip */
+        {
+          (void) StripImage(image,exception);
+          break;
+        }
+        case 85:  /* Tint */
+        {
+          PixelInfo
+            tint;
+
+          GetPixelInfo(image,&tint);
+          if (attribute_flag[0] != 0)
+            (void) QueryColorCompliance(argument_list[0].string_reference,
+              AllCompliance,&tint,exception);
+          if (attribute_flag[1] == 0)
+            argument_list[1].string_reference="100";
+          image=TintImage(image,argument_list[1].string_reference,&tint,
+            exception);
+          break;
+        }
+        case 86:  /* Channel */
+        {
+          if (attribute_flag[0] != 0)
+            channel=(ChannelType) argument_list[0].integer_reference;
+          image=SeparateImage(image,channel,exception);
+          break;
+        }
+        case 87:  /* Splice */
+        {
+          if (attribute_flag[0] != 0)
+            flags=ParseGravityGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.height=argument_list[2].integer_reference;
+          if (attribute_flag[3] != 0)
+            geometry.x=argument_list[3].integer_reference;
+          if (attribute_flag[4] != 0)
+            geometry.y=argument_list[4].integer_reference;
+          if (attribute_flag[5] != 0)
+            image->fuzz=StringToDoubleInterval(
+              argument_list[5].string_reference,(double) QuantumRange+1.0);
+          if (attribute_flag[6] != 0)
+            (void) QueryColorCompliance(argument_list[6].string_reference,
+              AllCompliance,&image->background_color,exception);
+          if (attribute_flag[7] != 0)
+            image->gravity=(GravityType) argument_list[7].integer_reference;
+          image=SpliceImage(image,&geometry,exception);
+          break;
+        }
+        case 88:  /* Posterize */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].integer_reference=3;
+          if (attribute_flag[1] == 0)
+            argument_list[1].integer_reference=0;
+          (void) PosterizeImage(image,argument_list[0].integer_reference,
+            argument_list[1].integer_reference ? RiemersmaDitherMethod :
+            NoDitherMethod,exception);
+          break;
+        }
+        case 89:  /* Shadow */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+              if ((flags & XiValue) == 0)
+                geometry_info.xi=4.0;
+              if ((flags & PsiValue) == 0)
+                geometry_info.psi=4.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            geometry_info.xi=argument_list[3].integer_reference;
+          if (attribute_flag[4] != 0)
+            geometry_info.psi=argument_list[4].integer_reference;
+          image=ShadowImage(image,geometry_info.rho,geometry_info.sigma,
+            (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
+            ceil(geometry_info.psi-0.5),exception);
+          break;
+        }
+        case 90:  /* Identify */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].file_reference=(FILE *) NULL;
+          if (attribute_flag[1] != 0)
+            (void) SetImageArtifact(image,"identify:features",
+              argument_list[1].string_reference);
+          if ((attribute_flag[2] != 0) &&
+              (argument_list[2].integer_reference != 0))
+            (void) SetImageArtifact(image,"identify:unique","true");
+          (void) IdentifyImage(image,argument_list[0].file_reference,
+            MagickTrue,exception);
+          break;
+        }
+        case 91:  /* SepiaTone */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].real_reference=80.0*QuantumRange/100.0;
+          image=SepiaToneImage(image,argument_list[0].real_reference,
+            exception);
+          break;
+        }
+        case 92:  /* SigmoidalContrast */
+        {
+          MagickBooleanType
+            sharpen;
+
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=QuantumRange/2.0;
+              if ((flags & PercentValue) != 0)
+                geometry_info.sigma=QuantumRange*geometry_info.sigma/100.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            channel=(ChannelType) argument_list[3].integer_reference;
+          sharpen=MagickTrue;
+          if (attribute_flag[4] != 0)
+            sharpen=argument_list[4].integer_reference != 0 ? MagickTrue :
+              MagickFalse;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) SigmoidalContrastImage(image,sharpen,geometry_info.rho,
+            geometry_info.sigma,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 93:  /* Extent */
+        {
+          if (attribute_flag[7] != 0)
+            image->gravity=(GravityType) argument_list[7].integer_reference;
+          if (attribute_flag[0] != 0)
+            {
+              int
+                flags;
+
+              flags=ParseGravityGeometry(image,
+                argument_list[0].string_reference,&geometry,exception);
+              (void) flags;
+              if (geometry.width == 0)
+                geometry.width=image->columns;
+              if (geometry.height == 0)
+                geometry.height=image->rows;
+            }
+          if (attribute_flag[1] != 0)
+            geometry.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.height=argument_list[2].integer_reference;
+          if (attribute_flag[3] != 0)
+            geometry.x=argument_list[3].integer_reference;
+          if (attribute_flag[4] != 0)
+            geometry.y=argument_list[4].integer_reference;
+          if (attribute_flag[5] != 0)
+            image->fuzz=StringToDoubleInterval(
+              argument_list[5].string_reference,(double) QuantumRange+1.0);
+          if (attribute_flag[6] != 0)
+            (void) QueryColorCompliance(argument_list[6].string_reference,
+              AllCompliance,&image->background_color,exception);
+          image=ExtentImage(image,&geometry,exception);
+          break;
+        }
+        case 94:  /* Vignette */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+              if ((flags & XiValue) == 0)
+                geometry_info.xi=0.1*image->columns;
+              if ((flags & PsiValue) == 0)
+                geometry_info.psi=0.1*image->rows;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            geometry_info.xi=argument_list[3].integer_reference;
+          if (attribute_flag[4] != 0)
+            geometry_info.psi=argument_list[4].integer_reference;
+          if (attribute_flag[5] != 0)
+            (void) QueryColorCompliance(argument_list[5].string_reference,
+              AllCompliance,&image->background_color,exception);
+          image=VignetteImage(image,geometry_info.rho,geometry_info.sigma,
+            (ssize_t) ceil(geometry_info.xi-0.5),(ssize_t)
+            ceil(geometry_info.psi-0.5),exception);
+          break;
+        }
+        case 95:  /* ContrastStretch */
+        {
+          double
+            black_point,
+            white_point;
+
+          black_point=0.0;
+          white_point=(double) image->columns*image->rows;
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              black_point=geometry_info.rho;
+              white_point=(flags & SigmaValue) != 0 ? geometry_info.sigma :
+                black_point;
+              if ((flags & PercentValue) != 0)
+                {
+                  black_point*=(double) image->columns*image->rows/100.0;
+                  white_point*=(double) image->columns*image->rows/100.0;
+                }
+              white_point=(double) image->columns*image->rows-
+                white_point;
+            }
+          if (attribute_flag[1] != 0)
+            black_point=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            white_point=argument_list[2].real_reference;
+          if (attribute_flag[4] != 0)
+            channel=(ChannelType) argument_list[4].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) ContrastStretchImage(image,black_point,white_point,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 96:  /* Sans0 */
+        {
+          break;
+        }
+        case 97:  /* Sans1 */
+        {
+          break;
+        }
+        case 98:  /* AdaptiveSharpen */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+              if ((flags & XiValue) == 0)
+                geometry_info.xi=0.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            geometry_info.xi=argument_list[3].real_reference;
+          if (attribute_flag[4] != 0)
+            channel=(ChannelType) argument_list[4].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=AdaptiveSharpenImage(image,geometry_info.rho,
+            geometry_info.sigma,exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 99:  /* Transpose */
+        {
+          image=TransposeImage(image,exception);
+          break;
+        }
+        case 100:  /* Tranverse */
+        {
+          image=TransverseImage(image,exception);
+          break;
+        }
+        case 101:  /* AutoOrient */
+        {
+          image=AutoOrientImage(image,image->orientation,exception);
+          break;
+        }
+        case 102:  /* AdaptiveBlur */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+              if ((flags & XiValue) == 0)
+                geometry_info.xi=0.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            channel=(ChannelType) argument_list[3].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=AdaptiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
+            exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 103:  /* Sketch */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+              if ((flags & XiValue) == 0)
+                geometry_info.xi=1.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            geometry_info.xi=argument_list[3].real_reference;
+          image=SketchImage(image,geometry_info.rho,geometry_info.sigma,
+            geometry_info.xi,exception);
+          break;
+        }
+        case 104:  /* UniqueColors */
+        {
+          image=UniqueImageColors(image,exception);
+          break;
+        }
+        case 105:  /* AdaptiveResize */
+        {
+          if (attribute_flag[0] != 0)
+            flags=ParseRegionGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.height=argument_list[2].integer_reference;
+          if (attribute_flag[3] != 0)
+            image->filter=(FilterTypes) argument_list[4].integer_reference;
+          if (attribute_flag[4] != 0)
+            SetImageArtifact(image,"filter:support",
+              argument_list[4].string_reference);
+          image=AdaptiveResizeImage(image,geometry.width,geometry.height,
+            exception);
+          break;
+        }
+        case 106:  /* ClipMask */
+        {
+          Image
+            *mask_image;
+
+          if (attribute_flag[0] == 0)
+            {
+              ThrowPerlException(exception,OptionError,"MaskImageRequired",
+                PackageName);
+              goto PerlException;
+            }
+          mask_image=CloneImage(argument_list[0].image_reference,0,0,MagickTrue,
+            exception);
+          (void) NegateImage(mask_image,MagickFalse,exception);
+          (void) SetImageMask(image,mask_image,exception);
+          mask_image=DestroyImage(mask_image);
+          break;
+        }
+        case 107:  /* LinearStretch */
+        {
+           double
+             black_point,
+             white_point;
+
+           black_point=0.0;
+           white_point=(double) image->columns*image->rows;
+           if (attribute_flag[0] != 0)
+             {
+               flags=ParseGeometry(argument_list[0].string_reference,
+                 &geometry_info);
+               if ((flags & SigmaValue) != 0)
+                  white_point=geometry_info.sigma;
+               if ((flags & PercentValue) != 0)
+                 {
+                   black_point*=(double) image->columns*image->rows/100.0;
+                   white_point*=(double) image->columns*image->rows/100.0;
+                 }
+               if ((flags & SigmaValue) == 0)
+                 white_point=(double) image->columns*image->rows-black_point;
+             }
+          if (attribute_flag[1] != 0)
+            black_point=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            white_point=argument_list[2].real_reference;
+          (void) LinearStretchImage(image,black_point,white_point,exception);
+          break;
+        }
+        case 108:  /* ColorMatrix */
+        {
+          AV
+            *av;
+
+          double
+            *color_matrix;
+
+          KernelInfo
+            *kernel_info;
+
+          size_t
+            order;
+
+          if (attribute_flag[0] == 0)
+            break;
+          av=(AV *) argument_list[0].array_reference;
+          order=(size_t) sqrt(av_len(av)+1);
+          color_matrix=(double *) AcquireQuantumMemory(order,order*
+            sizeof(*color_matrix));
+          if (color_matrix == (double *) NULL)
+            {
+              ThrowPerlException(exception,ResourceLimitFatalError,
+                "MemoryAllocationFailed",PackageName);
+              goto PerlException;
+           }
+          for (j=0; (j < (ssize_t) (order*order)) && (j < (av_len(av)+1)); j++)
+            color_matrix[j]=(double) SvNV(*(av_fetch(av,j,0)));
+          for ( ; j < (ssize_t) (order*order); j++)
+            color_matrix[j]=0.0;
+          kernel_info=AcquireKernelInfo((const char *) NULL);
+          if (kernel_info == (KernelInfo *) NULL)
+            break;
+          kernel_info->width=order;
+          kernel_info->height=order;
+          kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order,
+            order*sizeof(*kernel_info->values));
+          if (kernel_info->values != (MagickRealType *) NULL)
+            {
+              for (i=0; i < (ssize_t) (order*order); i++)
+                kernel_info->values[i]=(MagickRealType) color_matrix[i];
+              image=ColorMatrixImage(image,kernel_info,exception);
+            }
+          kernel_info=DestroyKernelInfo(kernel_info);
+          color_matrix=(double *) RelinquishMagickMemory(color_matrix);
+          break;
+        }
+        case 109:  /* Mask */
+        {
+          Image
+            *mask_image;
+
+          if (attribute_flag[0] == 0)
+            {
+              ThrowPerlException(exception,OptionError,"MaskImageRequired",
+                PackageName);
+              goto PerlException;
+            }
+          mask_image=CloneImage(argument_list[0].image_reference,0,0,
+            MagickTrue,exception);
+          (void) NegateImage(mask_image,MagickFalse,exception);
+          (void) SetImageMask(image,mask_image,exception);
+          mask_image=DestroyImage(mask_image);
+          break;
+        }
+        case 110:  /* Polaroid */
+        {
+          char
+            *caption;
+
+          DrawInfo
+            *draw_info;
+
+          double
+            angle;
+
+          PixelInterpolateMethod
+            method;
+
+          draw_info=CloneDrawInfo(info ? info->image_info : (ImageInfo *) NULL,
+            (DrawInfo *) NULL);
+          caption=(char *) NULL;
+          if (attribute_flag[0] != 0)
+            caption=InterpretImageProperties(info ? info->image_info :
+              (ImageInfo *) NULL,image,argument_list[0].string_reference,
+              exception);
+          angle=0.0;
+          if (attribute_flag[1] != 0)
+            angle=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            (void) CloneString(&draw_info->font,
+              argument_list[2].string_reference);
+          if (attribute_flag[3] != 0)
+            (void) QueryColorCompliance(argument_list[3].string_reference,
+              AllCompliance,&draw_info->stroke,exception);
+          if (attribute_flag[4] != 0)
+            (void) QueryColorCompliance(argument_list[4].string_reference,
+              AllCompliance,&draw_info->fill,exception);
+          if (attribute_flag[5] != 0)
+            draw_info->stroke_width=argument_list[5].real_reference;
+          if (attribute_flag[6] != 0)
+            draw_info->pointsize=argument_list[6].real_reference;
+          if (attribute_flag[7] != 0)
+            draw_info->gravity=(GravityType) argument_list[7].integer_reference;
+          if (attribute_flag[8] != 0)
+            (void) QueryColorCompliance(argument_list[8].string_reference,
+              AllCompliance,&image->background_color,exception);
+          method=UndefinedInterpolatePixel;
+          if (attribute_flag[9] != 0)
+            method=(PixelInterpolateMethod) argument_list[9].integer_reference;
+          image=PolaroidImage(image,draw_info,caption,angle,method,exception);
+          draw_info=DestroyDrawInfo(draw_info);
+          if (caption != (char *) NULL)
+            caption=DestroyString(caption);
+          break;
+        }
+        case 111:  /* FloodfillPaint */
+        {
+          DrawInfo
+            *draw_info;
+
+          MagickBooleanType
+            invert;
+
+          PixelInfo
+            target;
+
+          draw_info=CloneDrawInfo(info ? info->image_info :
+            (ImageInfo *) NULL,(DrawInfo *) NULL);
+          if (attribute_flag[0] != 0)
+            flags=ParsePageGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.x=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.y=argument_list[2].integer_reference;
+          if (attribute_flag[3] != 0)
+            (void) QueryColorCompliance(argument_list[3].string_reference,
+              AllCompliance,&draw_info->fill,exception);
+          (void) GetOneVirtualPixelInfo(image,UndefinedVirtualPixelMethod,
+            geometry.x,geometry.y,&target,exception);
+          if (attribute_flag[4] != 0)
+            QueryColorCompliance(argument_list[4].string_reference,
+              AllCompliance,&target,exception);
+          if (attribute_flag[5] != 0)
+            image->fuzz=StringToDoubleInterval(
+              argument_list[5].string_reference,(double) QuantumRange+1.0);
+          if (attribute_flag[6] != 0)
+            channel=(ChannelType) argument_list[6].integer_reference;
+          invert=MagickFalse;
+          if (attribute_flag[7] != 0)
+            invert=(MagickBooleanType) argument_list[7].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) FloodfillPaintImage(image,draw_info,&target,geometry.x,
+            geometry.y,invert,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          draw_info=DestroyDrawInfo(draw_info);
+          break;
+        }
+        case 112:  /* Distort */
+        {
+          AV
+            *av;
+
+          double
+            *coordinates;
+
+          DistortImageMethod
+            method;
+
+          size_t
+            number_coordinates;
+
+          VirtualPixelMethod
+            virtual_pixel;
+
+          if (attribute_flag[0] == 0)
+            break;
+          method=UndefinedDistortion;
+          if (attribute_flag[1] != 0)
+            method=(DistortImageMethod) argument_list[1].integer_reference;
+          av=(AV *) argument_list[0].array_reference;
+          number_coordinates=(size_t) av_len(av)+1;
+          coordinates=(double *) AcquireQuantumMemory(number_coordinates,
+            sizeof(*coordinates));
+          if (coordinates == (double *) NULL)
+            {
+              ThrowPerlException(exception,ResourceLimitFatalError,
+                "MemoryAllocationFailed",PackageName);
+              goto PerlException;
+            }
+          for (j=0; j < (ssize_t) number_coordinates; j++)
+            coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
+          virtual_pixel=UndefinedVirtualPixelMethod;
+          if (attribute_flag[2] != 0)
+            virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
+              argument_list[2].integer_reference,exception);
+          image=DistortImage(image,method,number_coordinates,coordinates,
+            argument_list[3].integer_reference != 0 ? MagickTrue : MagickFalse,
+            exception);
+          if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
+            virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
+              exception);
+          coordinates=(double *) RelinquishMagickMemory(coordinates);
+          break;
+        }
+        case 113:  /* Clut */
+        {
+          PixelInterpolateMethod
+            method;
+
+          if (attribute_flag[0] == 0)
+            {
+              ThrowPerlException(exception,OptionError,"ClutImageRequired",
+                PackageName);
+              goto PerlException;
+            }
+          method=UndefinedInterpolatePixel;
+          if (attribute_flag[1] != 0)
+            method=(PixelInterpolateMethod) argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            channel=(ChannelType) argument_list[2].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) ClutImage(image,argument_list[0].image_reference,method,
+            exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 114:  /* LiquidRescale */
+        {
+          if (attribute_flag[0] != 0)
+            flags=ParseRegionGeometry(image,argument_list[0].string_reference,
+              &geometry,exception);
+          if (attribute_flag[1] != 0)
+            geometry.width=argument_list[1].integer_reference;
+          if (attribute_flag[2] != 0)
+            geometry.height=argument_list[2].integer_reference;
+          if (attribute_flag[3] == 0)
+            argument_list[3].real_reference=1.0;
+          if (attribute_flag[4] == 0)
+            argument_list[4].real_reference=0.0;
+          image=LiquidRescaleImage(image,geometry.width,geometry.height,
+            argument_list[3].real_reference,argument_list[4].real_reference,
+            exception);
+          break;
+        }
+        case 115:  /* EncipherImage */
+        {
+          (void) EncipherImage(image,argument_list[0].string_reference,
+            exception);
+          break;
+        }
+        case 116:  /* DecipherImage */
+        {
+          (void) DecipherImage(image,argument_list[0].string_reference,
+            exception);
+          break;
+        }
+        case 117:  /* Deskew */
+        {
+          geometry_info.rho=QuantumRange/2.0;
+          if (attribute_flag[0] != 0)
+            flags=ParseGeometry(argument_list[0].string_reference,
+              &geometry_info);
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=StringToDoubleInterval(
+              argument_list[1].string_reference,(double) QuantumRange+1.0);
+          image=DeskewImage(image,geometry_info.rho,exception);
+          break;
+        }
+        case 118:  /* Remap */
+        {
+          QuantizeInfo
+            *quantize_info;
+
+          if (attribute_flag[0] == 0)
+            {
+              ThrowPerlException(exception,OptionError,"RemapImageRequired",
+                PackageName);
+              goto PerlException;
+            }
+          quantize_info=AcquireQuantizeInfo(info->image_info);
+          if (attribute_flag[1] != 0)
+            quantize_info->dither_method=(DitherMethod)
+              argument_list[1].integer_reference;
+          (void) RemapImages(quantize_info,image,
+            argument_list[0].image_reference,exception);
+          quantize_info=DestroyQuantizeInfo(quantize_info);
+          break;
+        }
+        case 119:  /* SparseColor */
+        {
+          AV
+            *av;
+
+          double
+            *coordinates;
+
+          SparseColorMethod
+            method;
+
+          size_t
+            number_coordinates;
+
+          VirtualPixelMethod
+            virtual_pixel;
+
+          if (attribute_flag[0] == 0)
+            break;
+          method=UndefinedColorInterpolate;
+          if (attribute_flag[1] != 0)
+            method=(SparseColorMethod) argument_list[1].integer_reference;
+          av=(AV *) argument_list[0].array_reference;
+          number_coordinates=(size_t) av_len(av)+1;
+          coordinates=(double *) AcquireQuantumMemory(number_coordinates,
+            sizeof(*coordinates));
+          if (coordinates == (double *) NULL)
+            {
+              ThrowPerlException(exception,ResourceLimitFatalError,
+                "MemoryAllocationFailed",PackageName);
+              goto PerlException;
+            }
+          for (j=0; j < (ssize_t) number_coordinates; j++)
+            coordinates[j]=(double) SvNV(*(av_fetch(av,j,0)));
+          virtual_pixel=UndefinedVirtualPixelMethod;
+          if (attribute_flag[2] != 0)
+            virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
+              argument_list[2].integer_reference,exception);
+          if (attribute_flag[3] != 0)
+            channel=(ChannelType) argument_list[3].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=SparseColorImage(image,method,number_coordinates,coordinates,
+            exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
+            virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
+              exception);
+          coordinates=(double *) RelinquishMagickMemory(coordinates);
+          break;
+        }
+        case 120:  /* Function */
+        {
+          AV
+            *av;
+
+          double
+            *parameters;
+
+          MagickFunction
+            function;
+
+          size_t
+            number_parameters;
+
+          VirtualPixelMethod
+            virtual_pixel;
+
+          if (attribute_flag[0] == 0)
+            break;
+          function=UndefinedFunction;
+          if (attribute_flag[1] != 0)
+            function=(MagickFunction) argument_list[1].integer_reference;
+          av=(AV *) argument_list[0].array_reference;
+          number_parameters=(size_t) av_len(av)+1;
+          parameters=(double *) AcquireQuantumMemory(number_parameters,
+            sizeof(*parameters));
+          if (parameters == (double *) NULL)
+            {
+              ThrowPerlException(exception,ResourceLimitFatalError,
+                "MemoryAllocationFailed",PackageName);
+              goto PerlException;
+            }
+          for (j=0; j < (ssize_t) number_parameters; j++)
+            parameters[j]=(double) SvNV(*(av_fetch(av,j,0)));
+          virtual_pixel=UndefinedVirtualPixelMethod;
+          if (attribute_flag[2] != 0)
+            virtual_pixel=SetImageVirtualPixelMethod(image,(VirtualPixelMethod)
+              argument_list[2].integer_reference,exception);
+          (void) FunctionImage(image,function,number_parameters,parameters,
+            exception);
+          if ((attribute_flag[2] != 0) && (image != (Image *) NULL))
+            virtual_pixel=SetImageVirtualPixelMethod(image,virtual_pixel,
+              exception);
+          parameters=(double *) RelinquishMagickMemory(parameters);
+          break;
+        }
+        case 121:  /* SelectiveBlur */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+              if ((flags & PercentValue) != 0)
+                geometry_info.xi=QuantumRange*geometry_info.xi/100.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            geometry_info.xi=argument_list[3].integer_reference;;
+          if (attribute_flag[5] != 0)
+            channel=(ChannelType) argument_list[5].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=SelectiveBlurImage(image,geometry_info.rho,geometry_info.sigma,
+            geometry_info.xi,exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 122:  /* HaldClut */
+        {
+          if (attribute_flag[0] == 0)
+            {
+              ThrowPerlException(exception,OptionError,"ClutImageRequired",
+                PackageName);
+              goto PerlException;
+            }
+          if (attribute_flag[1] != 0)
+            channel=(ChannelType) argument_list[1].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) HaldClutImage(image,argument_list[0].image_reference,
+            exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 123:  /* BlueShift */
+        {
+          if (attribute_flag[0] != 0)
+            (void) ParseGeometry(argument_list[0].string_reference,
+              &geometry_info);
+          image=BlueShiftImage(image,geometry_info.rho,exception);
+          break;
+        }
+        case 124:  /* ForwardFourierTransformImage */
+        {
+          image=ForwardFourierTransformImage(image,
+            argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
+            exception);
+          break;
+        }
+        case 125:  /* InverseFourierTransformImage */
+        {
+          image=InverseFourierTransformImage(image,image->next,
+            argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
+            exception);
+          break;
+        }
+        case 126:  /* ColorDecisionList */
+        {
+          if (attribute_flag[0] == 0)
+            argument_list[0].string_reference=(char *) NULL;
+          (void) ColorDecisionListImage(image,
+            argument_list[0].string_reference,exception);
+          break;
+        }
+        case 127:  /* AutoGamma */
+        {
+          if (attribute_flag[0] != 0)
+            channel=(ChannelType) argument_list[0].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) AutoGammaImage(image,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 128:  /* AutoLevel */
+        {
+          if (attribute_flag[0] != 0)
+            channel=(ChannelType) argument_list[0].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) AutoLevelImage(image,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 129:  /* LevelColors */
+        {
+          PixelInfo
+            black_point,
+            white_point;
+
+          (void) QueryColorCompliance("#000000",AllCompliance,&black_point,
+            exception);
+          (void) QueryColorCompliance("#ffffff",AllCompliance,&white_point,
+            exception);
+          if (attribute_flag[1] != 0)
+             (void) QueryColorCompliance(
+               argument_list[1].string_reference,AllCompliance,&black_point,
+               exception);
+          if (attribute_flag[2] != 0)
+             (void) QueryColorCompliance(
+               argument_list[2].string_reference,AllCompliance,&white_point,
+               exception);
+          if (attribute_flag[3] != 0)
+            channel=(ChannelType) argument_list[3].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) LevelImageColors(image,&black_point,&white_point,
+            argument_list[0].integer_reference != 0 ? MagickTrue : MagickFalse,
+            exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 130:  /* Clamp */
+        {
+          if (attribute_flag[0] != 0)
+            channel=(ChannelType) argument_list[0].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) ClampImage(image,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 131:  /* BrightnessContrast */
+        {
+          double
+            brightness,
+            contrast;
+
+          brightness=0.0;
+          contrast=0.0;
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              brightness=geometry_info.rho;
+              if ((flags & SigmaValue) == 0)
+                contrast=geometry_info.sigma;
+            }
+          if (attribute_flag[1] != 0)
+            brightness=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            contrast=argument_list[2].real_reference;
+          if (attribute_flag[4] != 0)
+            channel=(ChannelType) argument_list[4].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) BrightnessContrastImage(image,brightness,contrast,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 132:  /* Morphology */
+        {
+          KernelInfo
+            *kernel;
+
+          MorphologyMethod
+            method;
+
+          ssize_t
+            iterations;
+
+          if (attribute_flag[0] == 0)
+            break;
+          kernel=AcquireKernelInfo(argument_list[0].string_reference);
+          if (kernel == (KernelInfo *) NULL)
+            break;
+          if (attribute_flag[1] != 0)
+            channel=(ChannelType) argument_list[1].integer_reference;
+          method=UndefinedMorphology;
+          if (attribute_flag[2] != 0)
+            method=argument_list[2].integer_reference;
+          iterations=1;
+          if (attribute_flag[3] != 0)
+            iterations=argument_list[3].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=MorphologyImage(image,method,iterations,kernel,exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          kernel=DestroyKernelInfo(kernel);
+          break;
+        }
+        case 133:  /* Mode */
+        {
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            channel=(ChannelType) argument_list[3].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=StatisticImage(image,ModeStatistic,(size_t) geometry_info.rho,
+            (size_t) geometry_info.sigma,exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 134:  /* Statistic */
+        {
+          StatisticType
+            statistic;
+
+          statistic=UndefinedStatistic;
+          if (attribute_flag[0] != 0)
+            {
+              flags=ParseGeometry(argument_list[0].string_reference,
+                &geometry_info);
+              if ((flags & SigmaValue) == 0)
+                geometry_info.sigma=1.0;
+            }
+          if (attribute_flag[1] != 0)
+            geometry_info.rho=argument_list[1].real_reference;
+          if (attribute_flag[2] != 0)
+            geometry_info.sigma=argument_list[2].real_reference;
+          if (attribute_flag[3] != 0)
+            channel=(ChannelType) argument_list[3].integer_reference;
+          if (attribute_flag[4] != 0)
+            statistic=(StatisticType) argument_list[4].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          image=StatisticImage(image,statistic,(size_t) geometry_info.rho,
+            (size_t) geometry_info.sigma,exception);
+          if (image != (Image *) NULL)
+            (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 135:  /* Perceptible */
+        {
+          double
+            epsilon;
+
+          epsilon=MagickEpsilon;
+          if (attribute_flag[0] != 0)
+            epsilon=argument_list[0].real_reference;
+          if (attribute_flag[1] != 0)
+            channel=(ChannelType) argument_list[1].integer_reference;
+          channel_mask=SetImageChannelMask(image,channel);
+          (void) PerceptibleImage(image,epsilon,exception);
+          (void) SetImageChannelMask(image,channel_mask);
+          break;
+        }
+        case 136:  /* Poly */
+        {
+          AV
+            *av;
+
+          double
+            *terms;
+
+          size_t
+            number_terms;
+
+          if (attribute_flag[0] == 0)
+            break;
+          if (attribute_flag[1] != 0)
+            channel=(ChannelType) argument_list[1].integer_reference;
+          av=(AV *) argument_list[0].array_reference;
+          number_terms=(size_t) av_len(av);
+          terms=(double *) AcquireQuantumMemory(number_terms,sizeof(*terms));
+          if (terms == (double *) NULL)
+            {
+              ThrowPerlException(exception,ResourceLimitFatalError,
+                "MemoryAllocationFailed",PackageName);
+              goto PerlException;
+            }
+          for (j=0; j < av_len(av); j++)
+            terms[j]=(double) SvNV(*(av_fetch(av,j,0)));
+          image=PolynomialImage(image,number_terms >> 1,terms,exception);
+          terms=(double *) RelinquishMagickMemory(terms);
+          break;
+        }
+      }
+      if (next != (Image *) NULL)
+        (void) CatchImageException(next);
+      if (region_image != (Image *) NULL)
+        {
+          /*
+            Composite region.
+          */ 
+          status=CompositeImage(region_image,image,CopyCompositeOp,MagickTrue,
+            region_info.x,region_info.y,exception);
+          (void) status;
+          (void) CatchImageException(region_image);
+          image=DestroyImage(image);
+          image=region_image;
+        }
+      if (image != (Image *) NULL)
+        {
+          number_images++;
+          if (next && (next != image))
+            {
+              image->next=next->next;
+              if (image->next != (Image *) NULL)
+                image->next->previous=image;
+              DeleteImageFromRegistry(*pv,next);
+            }
+          sv_setiv(*pv,PTR2IV(image));
+          next=image;
+        }
+      if (*pv)
+        pv++;
+    }
+
+  PerlException:
+    if (reference_vector)
+      reference_vector=(SV **) RelinquishMagickMemory(reference_vector);
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) number_images);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   M o n t a g e                                                             #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Montage(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    MontageImage  = 1
+    montage       = 2
+    montageimage  = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image,
+      *next;
+
+    PixelInfo
+      transparent_color;
+
+    MontageInfo
+      *montage_info;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      sp;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *av_reference,
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    attribute=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    av=newAV();
+    av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    /*
+      Get options.
+    */
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    montage_info=CloneMontageInfo(info->image_info,(MontageInfo *) NULL);
+    (void) QueryColorCompliance("none",AllCompliance,&transparent_color,
+      exception);
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'B':
+        case 'b':
+        {
+          if (LocaleCompare(attribute,"background") == 0)
+            {
+              (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
+                &montage_info->background_color,exception);
+              for (next=image; next; next=next->next)
+                next->background_color=montage_info->background_color;
+              break;
+            }
+          if (LocaleCompare(attribute,"border") == 0)
+            {
+              montage_info->border_width=SvIV(ST(i));
+              break;
+            }
+          if (LocaleCompare(attribute,"bordercolor") == 0)
+            {
+              (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
+                &montage_info->border_color,exception);
+              for (next=image; next; next=next->next)
+                next->border_color=montage_info->border_color;
+              break;
+            }
+          if (LocaleCompare(attribute,"borderwidth") == 0)
+            {
+              montage_info->border_width=SvIV(ST(i));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'C':
+        case 'c':
+        {
+          if (LocaleCompare(attribute,"compose") == 0)
+            {
+              sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
+                MagickComposeOptions,MagickFalse,SvPV(ST(i),na));
+              if (sp < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  break;
+                }
+              for (next=image; next; next=next->next)
+                next->compose=(CompositeOperator) sp;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'F':
+        case 'f':
+        {
+          if (LocaleCompare(attribute,"fill") == 0)
+            {
+              (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
+                &montage_info->fill,exception);
+              break;
+            }
+          if (LocaleCompare(attribute,"font") == 0)
+            {
+              (void) CloneString(&montage_info->font,SvPV(ST(i),na));
+              break;
+            }
+          if (LocaleCompare(attribute,"frame") == 0)
+            {
+              char
+                *p;
+
+              p=SvPV(ST(i),na);
+              if (IsGeometry(p) == MagickFalse)
+                {
+                  ThrowPerlException(exception,OptionError,"MissingGeometry",
+                    p);
+                  break;
+                }
+              (void) CloneString(&montage_info->frame,p);
+              if (*p == '\0')
+                montage_info->frame=(char *) NULL;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'G':
+        case 'g':
+        {
+          if (LocaleCompare(attribute,"geometry") == 0)
+            {
+              char
+                *p;
+
+              p=SvPV(ST(i),na);
+              if (IsGeometry(p) == MagickFalse)
+                {
+                  ThrowPerlException(exception,OptionError,"MissingGeometry",
+                    p);
+                  break;
+                }
+             (void) CloneString(&montage_info->geometry,p);
+             if (*p == '\0')
+               montage_info->geometry=(char *) NULL;
+             break;
+           }
+         if (LocaleCompare(attribute,"gravity") == 0)
+           {
+             ssize_t
+               in;
+
+             in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
+               MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
+             if (in < 0)
+               {
+                 ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                   SvPV(ST(i),na));
+                 return;
+               }
+             montage_info->gravity=(GravityType) in;
+             for (next=image; next; next=next->next)
+               next->gravity=(GravityType) in;
+             break;
+           }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'L':
+        case 'l':
+        {
+          if (LocaleCompare(attribute,"label") == 0)
+            {
+              for (next=image; next; next=next->next)
+                (void) SetImageProperty(next,"label",InterpretImageProperties(
+                  info ? info->image_info : (ImageInfo *) NULL,next,
+                  SvPV(ST(i),na),exception),exception);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'M':
+        case 'm':
+        {
+          if (LocaleCompare(attribute,"mattecolor") == 0)
+            {
+              (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
+                &montage_info->matte_color,exception);
+              for (next=image; next; next=next->next)
+                next->matte_color=montage_info->matte_color;
+              break;
+            }
+          if (LocaleCompare(attribute,"mode") == 0)
+            {
+              ssize_t
+                in;
+
+              in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
+                MagickModeOptions,MagickFalse,SvPV(ST(i),na));
+              switch (in)
+              {
+                default:
+                {
+                  ThrowPerlException(exception,OptionError,
+                    "UnrecognizedModeType",SvPV(ST(i),na));
+                  break;
+                }
+                case FrameMode:
+                {
+                  (void) CloneString(&montage_info->frame,"15x15+3+3");
+                  montage_info->shadow=MagickTrue;
+                  break;
+                }
+                case UnframeMode:
+                {
+                  montage_info->frame=(char *) NULL;
+                  montage_info->shadow=MagickFalse;
+                  montage_info->border_width=0;
+                  break;
+                }
+                case ConcatenateMode:
+                {
+                  montage_info->frame=(char *) NULL;
+                  montage_info->shadow=MagickFalse;
+                  (void) CloneString(&montage_info->geometry,"+0+0");
+                  montage_info->border_width=0;
+                }
+              }
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'P':
+        case 'p':
+        {
+          if (LocaleCompare(attribute,"pointsize") == 0)
+            {
+              montage_info->pointsize=SvIV(ST(i));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'S':
+        case 's':
+        {
+          if (LocaleCompare(attribute,"shadow") == 0)
+            {
+              sp=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseCommandOption(
+                MagickBooleanOptions,MagickFalse,SvPV(ST(i),na));
+              if (sp < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  break;
+                }
+             montage_info->shadow=sp != 0 ? MagickTrue : MagickFalse;
+             break;
+            }
+          if (LocaleCompare(attribute,"stroke") == 0)
+            {
+              (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
+                &montage_info->stroke,exception);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'T':
+        case 't':
+        {
+          if (LocaleCompare(attribute,"texture") == 0)
+            {
+              (void) CloneString(&montage_info->texture,SvPV(ST(i),na));
+              break;
+            }
+          if (LocaleCompare(attribute,"tile") == 0)
+            {
+              char *p=SvPV(ST(i),na);
+              if (IsGeometry(p) == MagickFalse)
+                {
+                  ThrowPerlException(exception,OptionError,"MissingGeometry",
+                    p);
+                  break;
+                }
+              (void) CloneString(&montage_info->tile,p);
+              if (*p == '\0')
+                montage_info->tile=(char *) NULL;
+              break;
+            }
+          if (LocaleCompare(attribute,"title") == 0)
+            {
+              (void) CloneString(&montage_info->title,SvPV(ST(i),na));
+              break;
+            }
+          if (LocaleCompare(attribute,"transparent") == 0)
+            {
+              PixelInfo
+                transparent_color;
+
+              QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
+                &transparent_color,exception);
+              for (next=image; next; next=next->next)
+                (void) TransparentPaintImage(next,&transparent_color,
+                  TransparentAlpha,MagickFalse,exception);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    image=MontageImageList(info->image_info,montage_info,image,exception);
+    montage_info=DestroyMontageInfo(montage_info);
+    if (image == (Image *) NULL)
+      goto PerlException;
+    if (transparent_color.alpha != TransparentAlpha)
+      for (next=image; next; next=next->next)
+        (void) TransparentPaintImage(next,&transparent_color,
+          TransparentAlpha,MagickFalse,exception);
+    for (  ; image; image=image->next)
+    {
+      AddImageToRegistry(sv,image);
+      rv=newRV(sv);
+      av_push(av,sv_bless(rv,hv));
+      SvREFCNT_dec(sv);
+    }
+    exception=DestroyExceptionInfo(exception);
+    ST(0)=av_reference;
+    SvREFCNT_dec(perl_exception);
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   M o r p h                                                                 #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Morph(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    MorphImage  = 1
+    morph       = 2
+    morphimage  = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      number_frames;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *av_reference,
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    av=NULL;
+    attribute=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    av=newAV();
+    av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    /*
+      Get attribute.
+    */
+    number_frames=30;
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'F':
+        case 'f':
+        {
+          if (LocaleCompare(attribute,"frames") == 0)
+            {
+              number_frames=SvIV(ST(i));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    image=MorphImages(image,number_frames,exception);
+    if (image == (Image *) NULL)
+      goto PerlException;
+    for ( ; image; image=image->next)
+    {
+      AddImageToRegistry(sv,image);
+      rv=newRV(sv);
+      av_push(av,sv_bless(rv,hv));
+      SvREFCNT_dec(sv);
+    }
+    exception=DestroyExceptionInfo(exception);
+    ST(0)=av_reference;
+    SvREFCNT_dec(perl_exception);  /* can't return warning messages */
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   M o s a i c                                                               #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Mosaic(ref)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    MosaicImage   = 1
+    mosaic        = 2
+    mosaicimage   = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    image=MergeImageLayers(image,MosaicLayer,exception);
+    /*
+      Create blessed Perl array for the returned image.
+    */
+    av=newAV();
+    ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    AddImageToRegistry(sv,image);
+    rv=newRV(sv);
+    av_push(av,sv_bless(rv,hv));
+    SvREFCNT_dec(sv);
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    (void) CopyMagickString(info->image_info->filename,image->filename,
+      MaxTextExtent);
+    SetImageInfo(info->image_info,0,exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);  /* return messages in string context */
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   P i n g                                                                   #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Ping(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    PingImage  = 1
+    ping       = 2
+    pingimage  = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      **keep,
+      **list;
+
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image,
+      *next;
+
+    int
+      n;
+
+    MagickBooleanType
+      status;
+
+    register char
+      **p;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      ac;
+
+    STRLEN
+      *length;
+
+    struct PackageInfo
+      *info,
+      *package_info;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    size_t
+      count;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    package_info=(struct PackageInfo *) NULL;
+    ac=(items < 2) ? 1 : items-1;
+    list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
+    keep=list;
+    length=(STRLEN *) NULL;
+    if (list == (char **) NULL)
+      {
+        ThrowPerlException(exception,ResourceLimitError,
+          "MemoryAllocationFailed",PackageName);
+        goto PerlException;
+      }
+    keep=list;
+    length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
+    if (length == (STRLEN *) NULL)
+      {
+        ThrowPerlException(exception,ResourceLimitError,
+          "MemoryAllocationFailed",PackageName);
+        goto PerlException;
+      }
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    if (SvTYPE(reference) != SVt_PVAV)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    av=(AV *) reference;
+    info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
+      exception);
+    package_info=ClonePackageInfo(info,exception);
+    n=1;
+    if (items <= 1)
+      *list=(char *) (*package_info->image_info->filename ?
+        package_info->image_info->filename : "XC:black");
+    else
+      for (n=0, i=0; i < ac; i++)
+      {
+        list[n]=(char *) SvPV(ST(i+1),length[n]);
+        if ((items >= 3) && strEQcase(list[n],"blob"))
+          {
+            void
+              *blob;
+
+            i++;
+            blob=(void *) (SvPV(ST(i+1),length[n]));
+            SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
+          }
+        if ((items >= 3) && strEQcase(list[n],"filename"))
+          continue;
+        if ((items >= 3) && strEQcase(list[n],"file"))
+          {
+            FILE
+              *file;
+
+            PerlIO
+              *io_info;
+
+            i++;
+            io_info=IoIFP(sv_2io(ST(i+1)));
+            if (io_info == (PerlIO *) NULL)
+              {
+                ThrowPerlException(exception,BlobError,"UnableToOpenFile",
+                  PackageName);
+                continue;
+              }
+            file=PerlIO_findFILE(io_info);
+            if (file == (FILE *) NULL)
+              {
+                ThrowPerlException(exception,BlobError,"UnableToOpenFile",
+                  PackageName);
+                continue;
+              }
+            SetImageInfoFile(package_info->image_info,file);
+          }
+        if ((items >= 3) && strEQcase(list[n],"magick"))
+          continue;
+        n++;
+      }
+    list[n]=(char *) NULL;
+    keep=list;
+    status=ExpandFilenames(&n,&list);
+    if (status == MagickFalse)
+      {
+        ThrowPerlException(exception,ResourceLimitError,
+          "MemoryAllocationFailed",PackageName);
+        goto PerlException;
+      }
+    count=0;
+    for (i=0; i < n; i++)
+    {
+      (void) CopyMagickString(package_info->image_info->filename,list[i],
+        MaxTextExtent);
+      image=PingImage(package_info->image_info,exception);
+      if (image == (Image *) NULL)
+        break;
+      if ((package_info->image_info->file != (FILE *) NULL) ||
+          (package_info->image_info->blob != (void *) NULL))
+        DisassociateImageStream(image);
+      count+=GetImageListLength(image);
+      EXTEND(sp,4*count);
+      for (next=image; next; next=next->next)
+      {
+        PUSHs(sv_2mortal(newSViv(next->columns)));
+        PUSHs(sv_2mortal(newSViv(next->rows)));
+        PUSHs(sv_2mortal(newSViv((size_t) GetBlobSize(next))));
+        PUSHs(sv_2mortal(newSVpv(next->magick,0)));
+      }
+      image=DestroyImageList(image);
+    }
+    /*
+      Free resources.
+    */
+    for (i=0; i < n; i++)
+      if (list[i] != (char *) NULL)
+        for (p=keep; list[i] != *p++; )
+          if (*p == NULL)
+            {
+              list[i]=(char *) RelinquishMagickMemory(list[i]);
+              break;
+            }
+
+  PerlException:
+    if (package_info != (struct PackageInfo *) NULL)
+      DestroyPackageInfo(package_info);
+    if (list && (list != keep))
+      list=(char **) RelinquishMagickMemory(list);
+    if (keep)
+      keep=(char **) RelinquishMagickMemory(keep);
+    if (length)
+      length=(STRLEN *) RelinquishMagickMemory(length);
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);  /* throw away all errors */
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   P r e v i e w                                                             #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Preview(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    PreviewImage = 1
+    preview      = 2
+    previewimage = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image,
+      *preview_image;
+
+    PreviewType
+      preview_type;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *av_reference,
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    av=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    av=newAV();
+    av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    preview_type=GammaPreview;
+    if (items > 1)
+      preview_type=(PreviewType)
+        ParseCommandOption(MagickPreviewOptions,MagickFalse,SvPV(ST(1),na));
+    for ( ; image; image=image->next)
+    {
+      preview_image=PreviewImage(image,preview_type,exception);
+      if (preview_image == (Image *) NULL)
+        goto PerlException;
+      AddImageToRegistry(sv,preview_image);
+      rv=newRV(sv);
+      av_push(av,sv_bless(rv,hv));
+      SvREFCNT_dec(sv);
+    }
+    exception=DestroyExceptionInfo(exception);
+    ST(0)=av_reference;
+    SvREFCNT_dec(perl_exception);  /* can't return warning messages */
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   Q u e r y C o l o r                                                       #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+QueryColor(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    querycolor = 1
+  PPCODE:
+  {
+    char
+      *name;
+
+    ExceptionInfo
+      *exception;
+
+    PixelInfo
+      color;
+
+    register ssize_t
+      i;
+
+    SV
+      *perl_exception;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    if (items == 1)
+      {
+        const ColorInfo
+          **colorlist;
+
+        size_t
+          colors;
+
+        colorlist=GetColorInfoList("*",&colors,exception);
+        EXTEND(sp,colors);
+        for (i=0; i < (ssize_t) colors; i++)
+        {
+          PUSHs(sv_2mortal(newSVpv(colorlist[i]->name,0)));
+        }
+        colorlist=(const ColorInfo **)
+          RelinquishMagickMemory((ColorInfo **) colorlist);
+        goto PerlException;
+      }
+    EXTEND(sp,5*items);
+    for (i=1; i < items; i++)
+    {
+      name=(char *) SvPV(ST(i),na);
+      if (QueryColorCompliance(name,AllCompliance,&color,exception) == MagickFalse)
+        {
+          PUSHs(&sv_undef);
+          continue;
+        }
+      PUSHs(sv_2mortal(newSViv((size_t) floor(color.red+0.5))));
+      PUSHs(sv_2mortal(newSViv((size_t) floor(color.green+0.5))));
+      PUSHs(sv_2mortal(newSViv((size_t) floor(color.blue+0.5))));
+      if (color.colorspace == CMYKColorspace)
+        PUSHs(sv_2mortal(newSViv((size_t) floor(color.black+0.5))));
+      if (color.alpha_trait == BlendPixelTrait)
+        PUSHs(sv_2mortal(newSViv((size_t) floor(color.alpha+0.5))));
+    }
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   Q u e r y C o l o r N a m e                                               #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+QueryColorname(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    querycolorname = 1
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      message[MaxTextExtent];
+
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    PixelInfo
+      target_color;
+
+    register ssize_t
+      i;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference;  /* reference is the SV* of ref=SvIV(reference) */
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    reference=SvRV(ST(0));
+    av=(AV *) reference;
+    info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
+      exception);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    EXTEND(sp,items);
+    for (i=1; i < items; i++)
+    {
+      (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,&target_color,
+        exception);
+      (void) QueryColorname(image,&target_color,SVGCompliance,message,
+        exception);
+      PUSHs(sv_2mortal(newSVpv(message,0)));
+    }
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   Q u e r y F o n t                                                         #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+QueryFont(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    queryfont = 1
+  PPCODE:
+  {
+    char
+      *name,
+      message[MaxTextExtent];
+
+    ExceptionInfo
+      *exception;
+
+    register ssize_t
+      i;
+
+    SV
+      *perl_exception;
+
+    volatile const TypeInfo
+      *type_info;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    if (items == 1)
+      {
+        const TypeInfo
+          **typelist;
+
+        size_t
+          types;
+
+        typelist=GetTypeInfoList("*",&types,exception);
+        EXTEND(sp,types);
+        for (i=0; i < (ssize_t) types; i++)
+        {
+          PUSHs(sv_2mortal(newSVpv(typelist[i]->name,0)));
+        }
+        typelist=(const TypeInfo **) RelinquishMagickMemory((TypeInfo **)
+          typelist);
+        goto PerlException;
+      }
+    EXTEND(sp,10*items);
+    for (i=1; i < items; i++)
+    {
+      name=(char *) SvPV(ST(i),na);
+      type_info=GetTypeInfo(name,exception);
+      if (type_info == (TypeInfo *) NULL)
+        {
+          PUSHs(&sv_undef);
+          continue;
+        }
+      if (type_info->name == (char *) NULL)
+        PUSHs(&sv_undef);
+      else
+        PUSHs(sv_2mortal(newSVpv(type_info->name,0)));
+      if (type_info->description == (char *) NULL)
+        PUSHs(&sv_undef);
+      else
+        PUSHs(sv_2mortal(newSVpv(type_info->description,0)));
+      if (type_info->family == (char *) NULL)
+        PUSHs(&sv_undef);
+      else
+        PUSHs(sv_2mortal(newSVpv(type_info->family,0)));
+      if (type_info->style == UndefinedStyle)
+        PUSHs(&sv_undef);
+      else
+        PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStyleOptions,
+          type_info->style),0)));
+      if (type_info->stretch == UndefinedStretch)
+        PUSHs(&sv_undef);
+      else
+        PUSHs(sv_2mortal(newSVpv(CommandOptionToMnemonic(MagickStretchOptions,
+          type_info->stretch),0)));
+      (void) FormatLocaleString(message,MaxTextExtent,"%.20g",(double)
+        type_info->weight);
+      PUSHs(sv_2mortal(newSVpv(message,0)));
+      if (type_info->encoding == (char *) NULL)
+        PUSHs(&sv_undef);
+      else
+        PUSHs(sv_2mortal(newSVpv(type_info->encoding,0)));
+      if (type_info->foundry == (char *) NULL)
+        PUSHs(&sv_undef);
+      else
+        PUSHs(sv_2mortal(newSVpv(type_info->foundry,0)));
+      if (type_info->format == (char *) NULL)
+        PUSHs(&sv_undef);
+      else
+        PUSHs(sv_2mortal(newSVpv(type_info->format,0)));
+      if (type_info->metrics == (char *) NULL)
+        PUSHs(&sv_undef);
+      else
+        PUSHs(sv_2mortal(newSVpv(type_info->metrics,0)));
+      if (type_info->glyphs == (char *) NULL)
+        PUSHs(&sv_undef);
+      else
+        PUSHs(sv_2mortal(newSVpv(type_info->glyphs,0)));
+    }
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   Q u e r y F o n t M e t r i c s                                           #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+QueryFontMetrics(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    queryfontmetrics = 1
+  PPCODE:
+  {
+    AffineMatrix
+      affine,
+      current;
+
+    AV
+      *av;
+
+    char
+      *attribute;
+
+    double
+      x,
+      y;
+
+    DrawInfo
+      *draw_info;
+
+    ExceptionInfo
+      *exception;
+
+    GeometryInfo
+      geometry_info;
+
+    Image
+      *image;
+
+    MagickBooleanType
+      status;
+
+    MagickStatusType
+      flags;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      type;
+
+    struct PackageInfo
+      *info,
+      *package_info;
+
+    SV
+      *perl_exception,
+      *reference;  /* reference is the SV* of ref=SvIV(reference) */
+
+    TypeMetric
+      metrics;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    package_info=(struct PackageInfo *) NULL;
+    perl_exception=newSVpv("",0);
+    reference=SvRV(ST(0));
+    av=(AV *) reference;
+    info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
+      exception);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    package_info=ClonePackageInfo(info,exception);
+    draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
+    CloneString(&draw_info->text,"");
+    current=draw_info->affine;
+    GetAffineMatrix(&affine);
+    x=0.0;
+    y=0.0;
+    EXTEND(sp,7*items);
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'A':
+        case 'a':
+        {
+          if (LocaleCompare(attribute,"antialias") == 0)
+            {
+              type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
+                SvPV(ST(i),na));
+              if (type < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  break;
+                }
+              draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'd':
+        case 'D':
+        {
+          if (LocaleCompare(attribute,"density") == 0)
+            {
+              CloneString(&draw_info->density,SvPV(ST(i),na));
+              break;
+            }
+          if (LocaleCompare(attribute,"direction") == 0)
+            {
+              draw_info->direction=(DirectionType) ParseCommandOption(
+                MagickDirectionOptions,MagickFalse,SvPV(ST(i),na));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'e':
+        case 'E':
+        {
+          if (LocaleCompare(attribute,"encoding") == 0)
+            {
+              CloneString(&draw_info->encoding,SvPV(ST(i),na));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'f':
+        case 'F':
+        {
+          if (LocaleCompare(attribute,"family") == 0)
+            {
+              CloneString(&draw_info->family,SvPV(ST(i),na));
+              break;
+            }
+          if (LocaleCompare(attribute,"fill") == 0)
+            {
+              if (info)
+                (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
+                  &draw_info->fill,exception);
+              break;
+            }
+          if (LocaleCompare(attribute,"font") == 0)
+            {
+              CloneString(&draw_info->font,SvPV(ST(i),na));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'g':
+        case 'G':
+        {
+          if (LocaleCompare(attribute,"geometry") == 0)
+            {
+              CloneString(&draw_info->geometry,SvPV(ST(i),na));
+              break;
+            }
+          if (LocaleCompare(attribute,"gravity") == 0)
+            {
+              draw_info->gravity=(GravityType) ParseCommandOption(
+                MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'i':
+        case 'I':
+        {
+          if (LocaleCompare(attribute,"interline-spacing") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              draw_info->interline_spacing=geometry_info.rho;
+              break;
+            }
+          if (LocaleCompare(attribute,"interword-spacing") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              draw_info->interword_spacing=geometry_info.rho;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'k':
+        case 'K':
+        {
+          if (LocaleCompare(attribute,"kerning") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              draw_info->kerning=geometry_info.rho;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'p':
+        case 'P':
+        {
+          if (LocaleCompare(attribute,"pointsize") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              draw_info->pointsize=geometry_info.rho;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'r':
+        case 'R':
+        {
+          if (LocaleCompare(attribute,"rotate") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              affine.rx=geometry_info.rho;
+              affine.ry=geometry_info.sigma;
+              if ((flags & SigmaValue) == 0)
+                affine.ry=affine.rx;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 's':
+        case 'S':
+        {
+          if (LocaleCompare(attribute,"scale") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              affine.sx=geometry_info.rho;
+              affine.sy=geometry_info.sigma;
+              if ((flags & SigmaValue) == 0)
+                affine.sy=affine.sx;
+              break;
+            }
+          if (LocaleCompare(attribute,"skew") == 0)
+            {
+              double
+                x_angle,
+                y_angle;
+
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              x_angle=geometry_info.rho;
+              y_angle=geometry_info.sigma;
+              if ((flags & SigmaValue) == 0)
+                y_angle=x_angle;
+              affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
+              affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
+              break;
+            }
+          if (LocaleCompare(attribute,"stroke") == 0)
+            {
+              if (info)
+                (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
+                  &draw_info->stroke,exception);
+              break;
+            }
+          if (LocaleCompare(attribute,"style") == 0)
+            {
+              type=ParseCommandOption(MagickStyleOptions,MagickFalse,
+                SvPV(ST(i),na));
+              if (type < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  break;
+                }
+              draw_info->style=(StyleType) type;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 't':
+        case 'T':
+        {
+          if (LocaleCompare(attribute,"text") == 0)
+            {
+              CloneString(&draw_info->text,SvPV(ST(i),na));
+              break;
+            }
+          if (LocaleCompare(attribute,"translate") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              affine.tx=geometry_info.rho;
+              affine.ty=geometry_info.sigma;
+              if ((flags & SigmaValue) == 0)
+                affine.ty=affine.tx;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'w':
+        case 'W':
+        {
+          if (LocaleCompare(attribute,"weight") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              draw_info->weight=(size_t) geometry_info.rho;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'x':
+        case 'X':
+        {
+          if (LocaleCompare(attribute,"x") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              x=geometry_info.rho;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'y':
+        case 'Y':
+        {
+          if (LocaleCompare(attribute,"y") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              y=geometry_info.rho;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+    draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+    draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+    draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+    draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
+    draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
+    if (draw_info->geometry == (char *) NULL)
+      {
+        draw_info->geometry=AcquireString((char *) NULL);
+        (void) FormatLocaleString(draw_info->geometry,MaxTextExtent,
+          "%.15g,%.15g",x,y);
+      }
+    status=GetTypeMetrics(image,draw_info,&metrics,exception);
+    (void) CatchImageException(image);
+    if (status == MagickFalse)
+      PUSHs(&sv_undef);
+    else
+      {
+        PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
+        PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
+        PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
+        PUSHs(sv_2mortal(newSVnv(metrics.descent)));
+        PUSHs(sv_2mortal(newSVnv(metrics.width)));
+        PUSHs(sv_2mortal(newSVnv(metrics.height)));
+        PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
+        PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
+        PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
+        PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
+        PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
+        PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
+        PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
+      }
+    draw_info=DestroyDrawInfo(draw_info);
+
+  PerlException:
+    if (package_info != (struct PackageInfo *) NULL)
+      DestroyPackageInfo(package_info);
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);  /* can't return warning messages */
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   Q u e r y M u l t i l i n e F o n t M e t r i c s                         #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+QueryMultilineFontMetrics(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    querymultilinefontmetrics = 1
+  PPCODE:
+  {
+    AffineMatrix
+      affine,
+      current;
+
+    AV
+      *av;
+
+    char
+      *attribute;
+
+    double
+      x,
+      y;
+
+    DrawInfo
+      *draw_info;
+
+    ExceptionInfo
+      *exception;
+
+    GeometryInfo
+      geometry_info;
+
+    Image
+      *image;
+
+    MagickBooleanType
+      status;
+
+    MagickStatusType
+      flags;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      type;
+
+    struct PackageInfo
+      *info,
+      *package_info;
+
+    SV
+      *perl_exception,
+      *reference;  /* reference is the SV* of ref=SvIV(reference) */
+
+    TypeMetric
+      metrics;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    package_info=(struct PackageInfo *) NULL;
+    perl_exception=newSVpv("",0);
+    reference=SvRV(ST(0));
+    av=(AV *) reference;
+    info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
+      exception);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    package_info=ClonePackageInfo(info,exception);
+    draw_info=CloneDrawInfo(package_info->image_info,(DrawInfo *) NULL);
+    CloneString(&draw_info->text,"");
+    current=draw_info->affine;
+    GetAffineMatrix(&affine);
+    x=0.0;
+    y=0.0;
+    EXTEND(sp,7*items);
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'A':
+        case 'a':
+        {
+          if (LocaleCompare(attribute,"antialias") == 0)
+            {
+              type=ParseCommandOption(MagickBooleanOptions,MagickFalse,
+                SvPV(ST(i),na));
+              if (type < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  break;
+                }
+              draw_info->text_antialias=type != 0 ? MagickTrue : MagickFalse;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'd':
+        case 'D':
+        {
+          if (LocaleCompare(attribute,"density") == 0)
+            {
+              CloneString(&draw_info->density,SvPV(ST(i),na));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'e':
+        case 'E':
+        {
+          if (LocaleCompare(attribute,"encoding") == 0)
+            {
+              CloneString(&draw_info->encoding,SvPV(ST(i),na));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'f':
+        case 'F':
+        {
+          if (LocaleCompare(attribute,"family") == 0)
+            {
+              CloneString(&draw_info->family,SvPV(ST(i),na));
+              break;
+            }
+          if (LocaleCompare(attribute,"fill") == 0)
+            {
+              if (info)
+                (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
+                  &draw_info->fill,exception);
+              break;
+            }
+          if (LocaleCompare(attribute,"font") == 0)
+            {
+              CloneString(&draw_info->font,SvPV(ST(i),na));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'g':
+        case 'G':
+        {
+          if (LocaleCompare(attribute,"geometry") == 0)
+            {
+              CloneString(&draw_info->geometry,SvPV(ST(i),na));
+              break;
+            }
+          if (LocaleCompare(attribute,"gravity") == 0)
+            {
+              draw_info->gravity=(GravityType) ParseCommandOption(
+                MagickGravityOptions,MagickFalse,SvPV(ST(i),na));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'p':
+        case 'P':
+        {
+          if (LocaleCompare(attribute,"pointsize") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              draw_info->pointsize=geometry_info.rho;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'r':
+        case 'R':
+        {
+          if (LocaleCompare(attribute,"rotate") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              affine.rx=geometry_info.rho;
+              affine.ry=geometry_info.sigma;
+              if ((flags & SigmaValue) == 0)
+                affine.ry=affine.rx;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 's':
+        case 'S':
+        {
+          if (LocaleCompare(attribute,"scale") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              affine.sx=geometry_info.rho;
+              affine.sy=geometry_info.sigma;
+              if ((flags & SigmaValue) == 0)
+                affine.sy=affine.sx;
+              break;
+            }
+          if (LocaleCompare(attribute,"skew") == 0)
+            {
+              double
+                x_angle,
+                y_angle;
+
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              x_angle=geometry_info.rho;
+              y_angle=geometry_info.sigma;
+              if ((flags & SigmaValue) == 0)
+                y_angle=x_angle;
+              affine.ry=tan(DegreesToRadians(fmod(x_angle,360.0)));
+              affine.rx=tan(DegreesToRadians(fmod(y_angle,360.0)));
+              break;
+            }
+          if (LocaleCompare(attribute,"stroke") == 0)
+            {
+              if (info)
+                (void) QueryColorCompliance(SvPV(ST(i),na),AllCompliance,
+                  &draw_info->stroke,exception);
+              break;
+            }
+          if (LocaleCompare(attribute,"style") == 0)
+            {
+              type=ParseCommandOption(MagickStyleOptions,MagickFalse,
+                SvPV(ST(i),na));
+              if (type < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  break;
+                }
+              draw_info->style=(StyleType) type;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 't':
+        case 'T':
+        {
+          if (LocaleCompare(attribute,"text") == 0)
+            {
+              CloneString(&draw_info->text,SvPV(ST(i),na));
+              break;
+            }
+          if (LocaleCompare(attribute,"translate") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              affine.tx=geometry_info.rho;
+              affine.ty=geometry_info.sigma;
+              if ((flags & SigmaValue) == 0)
+                affine.ty=affine.tx;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'w':
+        case 'W':
+        {
+          if (LocaleCompare(attribute,"weight") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              draw_info->weight=(size_t) geometry_info.rho;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'x':
+        case 'X':
+        {
+          if (LocaleCompare(attribute,"x") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              x=geometry_info.rho;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'y':
+        case 'Y':
+        {
+          if (LocaleCompare(attribute,"y") == 0)
+            {
+              flags=ParseGeometry(SvPV(ST(i),na),&geometry_info);
+              y=geometry_info.rho;
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    draw_info->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
+    draw_info->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
+    draw_info->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
+    draw_info->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
+    draw_info->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
+    draw_info->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
+    if (draw_info->geometry == (char *) NULL)
+      {
+        draw_info->geometry=AcquireString((char *) NULL);
+        (void) FormatLocaleString(draw_info->geometry,MaxTextExtent,
+          "%.15g,%.15g",x,y);
+      }
+    status=GetMultilineTypeMetrics(image,draw_info,&metrics,exception);
+    (void) CatchException(exception);
+    if (status == MagickFalse)
+      PUSHs(&sv_undef);
+    else
+      {
+        PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.x)));
+        PUSHs(sv_2mortal(newSVnv(metrics.pixels_per_em.y)));
+        PUSHs(sv_2mortal(newSVnv(metrics.ascent)));
+        PUSHs(sv_2mortal(newSVnv(metrics.descent)));
+        PUSHs(sv_2mortal(newSVnv(metrics.width)));
+        PUSHs(sv_2mortal(newSVnv(metrics.height)));
+        PUSHs(sv_2mortal(newSVnv(metrics.max_advance)));
+        PUSHs(sv_2mortal(newSVnv(metrics.bounds.x1)));
+        PUSHs(sv_2mortal(newSVnv(metrics.bounds.y1)));
+        PUSHs(sv_2mortal(newSVnv(metrics.bounds.x2)));
+        PUSHs(sv_2mortal(newSVnv(metrics.bounds.y2)));
+        PUSHs(sv_2mortal(newSVnv(metrics.origin.x)));
+        PUSHs(sv_2mortal(newSVnv(metrics.origin.y)));
+      }
+    draw_info=DestroyDrawInfo(draw_info);
+
+  PerlException:
+    if (package_info != (struct PackageInfo *) NULL)
+      DestroyPackageInfo(package_info);
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);  /* can't return warning messages */
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   Q u e r y F o r m a t                                                     #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+QueryFormat(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    queryformat = 1
+  PPCODE:
+  {
+    char
+      *name;
+
+    ExceptionInfo
+      *exception;
+
+    register ssize_t
+      i;
+
+    SV
+      *perl_exception;
+
+    volatile const MagickInfo
+      *magick_info;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    if (items == 1)
+      {
+        char
+          format[MaxTextExtent];
+
+        const MagickInfo
+          **format_list;
+
+        size_t
+          types;
+
+        format_list=GetMagickInfoList("*",&types,exception);
+        EXTEND(sp,types);
+        for (i=0; i < (ssize_t) types; i++)
+        {
+          (void) CopyMagickString(format,format_list[i]->name,MaxTextExtent);
+          LocaleLower(format);
+          PUSHs(sv_2mortal(newSVpv(format,0)));
+        }
+        format_list=(const MagickInfo **)
+          RelinquishMagickMemory((MagickInfo *) format_list);
+        goto PerlException;
+      }
+    EXTEND(sp,8*items);
+    for (i=1; i < items; i++)
+    {
+      name=(char *) SvPV(ST(i),na);
+      magick_info=GetMagickInfo(name,exception);
+      if (magick_info == (const MagickInfo *) NULL)
+        {
+          PUSHs(&sv_undef);
+          continue;
+        }
+      PUSHs(sv_2mortal(newSViv(magick_info->adjoin)));
+      PUSHs(sv_2mortal(newSViv(magick_info->blob_support)));
+      PUSHs(sv_2mortal(newSViv(magick_info->raw)));
+      PUSHs(sv_2mortal(newSViv((long) magick_info->decoder)));
+      PUSHs(sv_2mortal(newSViv((long) magick_info->encoder)));
+      if (magick_info->description == (char *) NULL)
+        PUSHs(&sv_undef);
+      else
+        PUSHs(sv_2mortal(newSVpv(magick_info->description,0)));
+      if (magick_info->module == (char *) NULL)
+        PUSHs(&sv_undef);
+      else
+        PUSHs(sv_2mortal(newSVpv(magick_info->module,0)));
+    }
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   Q u e r y O p t i o n                                                     #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+QueryOption(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    queryoption = 1
+  PPCODE:
+  {
+    char
+      **options;
+
+    ExceptionInfo
+      *exception;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      j,
+      option;
+
+    SV
+      *perl_exception;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    EXTEND(sp,8*items);
+    for (i=1; i < items; i++)
+    {
+      option=ParseCommandOption(MagickListOptions,MagickFalse,(char *)
+        SvPV(ST(i),na));
+      options=GetCommandOptions((CommandOption) option);
+      if (options == (char **) NULL)
+        PUSHs(&sv_undef);
+      else
+        {
+          for (j=0; options[j] != (char *) NULL; j++)
+            PUSHs(sv_2mortal(newSVpv(options[j],0)));
+          options=DestroyStringList(options);
+        }
+    }
+
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   R e a d                                                                   #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Read(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    ReadImage  = 1
+    read       = 2
+    readimage  = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      **keep,
+      **list;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image;
+
+    int
+      n;
+
+    MagickBooleanType
+      status;
+
+    register char
+      **p;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      ac,
+      number_images;
+
+    STRLEN
+      *length;
+
+    struct PackageInfo
+      *info,
+      *package_info;
+
+    SV
+      *perl_exception,  /* Perl variable for storing messages */
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    package_info=(struct PackageInfo *) NULL;
+    number_images=0;
+    ac=(items < 2) ? 1 : items-1;
+    list=(char **) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*list));
+    keep=list;
+    length=(STRLEN *) NULL;
+    if (list == (char **) NULL)
+      {
+        ThrowPerlException(exception,ResourceLimitError,
+          "MemoryAllocationFailed",PackageName);
+        goto PerlException;
+      }
+    length=(STRLEN *) AcquireQuantumMemory((size_t) ac+1UL,sizeof(*length));
+    if (length == (STRLEN *) NULL)
+      {
+        ThrowPerlException(exception,ResourceLimitError,
+          "MemoryAllocationFailed",PackageName);
+        goto PerlException;
+      }
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    if (SvTYPE(reference) != SVt_PVAV)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    av=(AV *) reference;
+    info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
+      exception);
+    package_info=ClonePackageInfo(info,exception);
+    n=1;
+    if (items <= 1)
+      *list=(char *) (*package_info->image_info->filename ?
+        package_info->image_info->filename : "XC:black");
+    else
+      for (n=0, i=0; i < ac; i++)
+      {
+        list[n]=(char *) SvPV(ST(i+1),length[n]);
+        if ((items >= 3) && strEQcase(list[n],"blob"))
+          {
+            void
+              *blob;
+
+            i++;
+            blob=(void *) (SvPV(ST(i+1),length[n]));
+            SetImageInfoBlob(package_info->image_info,blob,(size_t) length[n]);
+          }
+        if ((items >= 3) && strEQcase(list[n],"filename"))
+          continue;
+        if ((items >= 3) && strEQcase(list[n],"file"))
+          {
+            FILE
+              *file;
+
+            PerlIO
+              *io_info;
+
+            i++;
+            io_info=IoIFP(sv_2io(ST(i+1)));
+            if (io_info == (PerlIO *) NULL)
+              {
+                ThrowPerlException(exception,BlobError,"UnableToOpenFile",
+                  PackageName);
+                continue;
+              }
+            file=PerlIO_findFILE(io_info);
+            if (file == (FILE *) NULL)
+              {
+                ThrowPerlException(exception,BlobError,"UnableToOpenFile",
+                  PackageName);
+                continue;
+              }
+            SetImageInfoFile(package_info->image_info,file);
+          }
+        if ((items >= 3) && strEQcase(list[n],"magick"))
+          continue;
+        n++;
+      }
+    list[n]=(char *) NULL;
+    keep=list;
+    status=ExpandFilenames(&n,&list);
+    if (status == MagickFalse)
+      {
+        ThrowPerlException(exception,ResourceLimitError,
+          "MemoryAllocationFailed",PackageName);
+        goto PerlException;
+      }
+    number_images=0;
+    for (i=0; i < n; i++)
+    {
+      if ((package_info->image_info->file == (FILE *) NULL) &&
+          (package_info->image_info->blob == (void *) NULL))
+        image=ReadImages(package_info->image_info,list[i],exception);
+      else
+        {
+          image=ReadImages(package_info->image_info,
+            package_info->image_info->filename,exception);
+          if (image != (Image *) NULL)
+            DisassociateImageStream(image);
+        }
+      if (image == (Image *) NULL)
+        break;
+      for ( ; image; image=image->next)
+      {
+        AddImageToRegistry(sv,image);
+        rv=newRV(sv);
+        av_push(av,sv_bless(rv,hv));
+        SvREFCNT_dec(sv);
+        number_images++;
+      }
+    }
+    /*
+      Free resources.
+    */
+    for (i=0; i < n; i++)
+      if (list[i] != (char *) NULL)
+        for (p=keep; list[i] != *p++; )
+          if (*p == (char *) NULL)
+            {
+              list[i]=(char *) RelinquishMagickMemory(list[i]);
+              break;
+            }
+
+  PerlException:
+    if (package_info != (struct PackageInfo *) NULL)
+      DestroyPackageInfo(package_info);
+    if (list && (list != keep))
+      list=(char **) RelinquishMagickMemory(list);
+    if (keep)
+      keep=(char **) RelinquishMagickMemory(keep);
+    if (length)
+      length=(STRLEN *) RelinquishMagickMemory(length);
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) number_images);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   R e m o t e                                                               #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Remote(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    RemoteCommand  = 1
+    remote         = 2
+    remoteCommand  = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    ExceptionInfo
+      *exception;
+
+    register ssize_t
+      i;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    struct PackageInfo
+      *info;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    reference=SvRV(ST(0));
+    av=(AV *) reference;
+    info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
+      exception);
+    for (i=1; i < items; i++)
+      (void) RemoteDisplayCommand(info->image_info,(char *) NULL,(char *)
+        SvPV(ST(i),na),exception);
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);    /* throw away all errors */
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   S e t                                                                     #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Set(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    SetAttributes  = 1
+    SetAttribute   = 2
+    set            = 3
+    setattributes  = 4
+    setattribute   = 5
+  PPCODE:
+  {
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    register ssize_t
+      i;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference;  /* reference is the SV* of ref=SvIV(reference) */
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (items == 2)
+      SetAttribute(aTHX_ info,image,"size",ST(1),exception);
+    else
+      for (i=2; i < items; i+=2)
+        SetAttribute(aTHX_ info,image,SvPV(ST(i-1),na),ST(i),exception);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) (SvCUR(perl_exception) != 0));
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   S e t P i x e l                                                           #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+SetPixel(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    setpixel = 1
+    setPixel = 2
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute;
+
+    ChannelType
+      channel,
+      channel_mask;
+
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    MagickBooleanType
+      normalize;
+
+    RectangleInfo
+      region;
+
+    register ssize_t
+      i;
+
+    register Quantum
+      *q;
+
+    ssize_t
+      option;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference;  /* reference is the SV* of ref=SvIV(reference) */
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    reference=SvRV(ST(0));
+    av=(AV *) reference;
+    info=GetPackageInfo(aTHX_ (void *) av,(struct PackageInfo *) NULL,
+      exception);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    av=(AV *) NULL;
+    normalize=MagickTrue;
+    region.x=0;
+    region.y=0;
+    region.width=image->columns;
+    region.height=1;
+    if (items == 1)
+      (void) ParseAbsoluteGeometry(SvPV(ST(1),na),&region);
+    channel=DefaultChannels;
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'C':
+        case 'c':
+        {
+          if (LocaleCompare(attribute,"channel") == 0)
+            {
+              ssize_t
+                option;
+
+              option=ParseChannelOption(SvPV(ST(i),na));
+              if (option < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  return;
+                }
+              channel=(ChannelType) option;
+              break;
+            }
+          if (LocaleCompare(attribute,"color") == 0)
+            {
+              if (SvTYPE(ST(i)) != SVt_RV)
+                {
+                  char
+                    message[MaxTextExtent];
+
+                  (void) FormatLocaleString(message,MaxTextExtent,
+                    "invalid %.60s value",attribute);
+                  ThrowPerlException(exception,OptionError,message,
+                    SvPV(ST(i),na));
+                }
+              av=(AV *) SvRV(ST(i));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'g':
+        case 'G':
+        {
+          if (LocaleCompare(attribute,"geometry") == 0)
+            {
+              (void) ParseAbsoluteGeometry(SvPV(ST(i),na),&region);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'N':
+        case 'n':
+        {
+          if (LocaleCompare(attribute,"normalize") == 0)
+            {
+              option=ParseCommandOption(MagickBooleanOptions,MagickFalse,
+                SvPV(ST(i),na));
+              if (option < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  break;
+                }
+             normalize=option != 0 ? MagickTrue : MagickFalse;
+             break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'x':
+        case 'X':
+        {
+          if (LocaleCompare(attribute,"x") == 0)
+            {
+              region.x=SvIV(ST(i));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'y':
+        case 'Y':
+        {
+          if (LocaleCompare(attribute,"y") == 0)
+            {
+              region.y=SvIV(ST(i));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    (void) SetImageStorageClass(image,DirectClass,exception);
+    channel_mask=SetImageChannelMask(image,channel);
+    q=GetAuthenticPixels(image,region.x,region.y,1,1,exception);
+    if ((q == (Quantum *) NULL) || (av == (AV *) NULL) ||
+        (SvTYPE(av) != SVt_PVAV))
+      PUSHs(&sv_undef);
+    else
+      {
+        double
+          scale;
+
+        register ssize_t
+          i;
+
+        i=0;
+        scale=1.0;
+        if (normalize != MagickFalse)
+          scale=QuantumRange;
+        if (((GetPixelRedTraits(image) & UpdatePixelTrait) != 0) &&
+            (i <= av_len(av)))
+          {
+            SetPixelRed(image,ClampToQuantum(scale*SvNV(*(
+              av_fetch(av,i,0)))),q);
+            i++;
+          }
+        if (((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0) &&
+            (i <= av_len(av)))
+          {
+            SetPixelGreen(image,ClampToQuantum(scale*SvNV(*(
+              av_fetch(av,i,0)))),q);
+            i++;
+          }
+        if (((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0) &&
+            (i <= av_len(av)))
+          {
+            SetPixelBlue(image,ClampToQuantum(scale*SvNV(*(
+              av_fetch(av,i,0)))),q);
+            i++;
+          }
+        if ((((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0) &&
+            (image->colorspace == CMYKColorspace)) && (i <= av_len(av)))
+          {
+            SetPixelBlack(image,ClampToQuantum(scale*
+              SvNV(*(av_fetch(av,i,0)))),q);
+            i++;
+          }
+        if (((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0) &&
+            (i <= av_len(av)))
+          {
+            SetPixelAlpha(image,ClampToQuantum(scale*
+              SvNV(*(av_fetch(av,i,0)))),q);
+            i++;
+          }
+        (void) SyncAuthenticPixels(image,exception);
+      }
+    (void) SetImageChannelMask(image,channel_mask);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   S m u s h                                                                 #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Smush(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    SmushImage  = 1
+    smush       = 2
+    smushimage  = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *image;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      offset,
+      stack;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *av_reference,
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    attribute=NULL;
+    av=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    av=newAV();
+    av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    /*
+      Get options.
+    */
+    offset=0;
+    stack=MagickTrue;
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'O':
+        case 'o':
+        {
+          if (LocaleCompare(attribute,"offset") == 0)
+            {
+              offset=(ssize_t) StringToLong((char *) SvPV(ST(1),na));
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'S':
+        case 's':
+        {
+          if (LocaleCompare(attribute,"stack") == 0)
+            {
+              stack=ParseCommandOption(MagickBooleanOptions,MagickFalse,
+                SvPV(ST(i),na));
+              if (stack < 0)
+                {
+                  ThrowPerlException(exception,OptionError,"UnrecognizedType",
+                    SvPV(ST(i),na));
+                  return;
+                }
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    image=SmushImages(image,stack != 0 ? MagickTrue : MagickFalse,offset,
+      exception);
+    if (image == (Image *) NULL)
+      goto PerlException;
+    for ( ; image; image=image->next)
+    {
+      AddImageToRegistry(sv,image);
+      rv=newRV(sv);
+      av_push(av,sv_bless(rv,hv));
+      SvREFCNT_dec(sv);
+    }
+    exception=DestroyExceptionInfo(exception);
+    ST(0)=av_reference;
+    SvREFCNT_dec(perl_exception);
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   S t a t i s t i c s                                                       #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Statistics(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    StatisticsImage = 1
+    statistics      = 2
+    statisticsimage = 3
+  PPCODE:
+  {
+#define ChannelStatistics(channel) \
+{ \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.20g", \
+    (double) channel_statistics[channel].depth); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_statistics[channel].minima/scale); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_statistics[channel].maxima/scale); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_statistics[channel].mean/scale); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_statistics[channel].standard_deviation/scale); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_statistics[channel].kurtosis); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+  (void) FormatLocaleString(message,MaxTextExtent,"%.15g", \
+    channel_statistics[channel].skewness); \
+  PUSHs(sv_2mortal(newSVpv(message,0))); \
+}
+
+    AV
+      *av;
+
+    char
+      message[MaxTextExtent];
+
+    ChannelStatistics
+      *channel_statistics;
+
+    double
+      scale;
+
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    ssize_t
+      count;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    av=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    av=newAV();
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    count=0;
+    for ( ; image; image=image->next)
+    {
+      channel_statistics=GetImageStatistics(image,exception);
+      if (channel_statistics == (ChannelStatistics *) NULL)
+        continue;
+      count++;
+      EXTEND(sp,35*count);
+      scale=(double) QuantumRange;
+      ChannelStatistics(RedChannel);
+      ChannelStatistics(GreenChannel);
+      ChannelStatistics(BlueChannel);
+      if (image->colorspace == CMYKColorspace)
+        ChannelStatistics(BlackChannel);
+      if (image->alpha_trait == BlendPixelTrait)
+        ChannelStatistics(AlphaChannel);
+      channel_statistics=(ChannelStatistics *)
+        RelinquishMagickMemory(channel_statistics);
+    }
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   S y n c A u t h e n t i c P i x e l s                                     #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+SyncAuthenticPixels(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref = NO_INIT
+  ALIAS:
+    Syncauthenticpixels = 1
+    SyncImagePixels = 2
+    syncimagepixels = 3
+  CODE:
+  {
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image;
+
+    MagickBooleanType
+      status;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+
+    reference=SvRV(ST(0));
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+
+    status=SyncAuthenticPixels(image,exception);
+    if (status != MagickFalse)
+      return;
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    SvREFCNT_dec(perl_exception);  /* throw away all errors */
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   T r a n s f o r m                                                         #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Transform(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    TransformImage = 1
+    transform      = 2
+    transformimage = 3
+  PPCODE:
+  {
+    AV
+      *av;
+
+    char
+      *attribute,
+      *crop_geometry,
+      *geometry;
+
+    ExceptionInfo
+      *exception;
+
+    HV
+      *hv;
+
+    Image
+      *clone,
+      *image;
+
+    register ssize_t
+      i;
+
+    struct PackageInfo
+      *info;
+
+    SV
+      *av_reference,
+      *perl_exception,
+      *reference,
+      *rv,
+      *sv;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    sv=NULL;
+    av=NULL;
+    attribute=NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    hv=SvSTASH(reference);
+    av=newAV();
+    av_reference=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+    SvREFCNT_dec(av);
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+    /*
+      Get attribute.
+    */
+    crop_geometry=(char *) NULL;
+    geometry=(char *) NULL;
+    for (i=2; i < items; i+=2)
+    {
+      attribute=(char *) SvPV(ST(i-1),na);
+      switch (*attribute)
+      {
+        case 'c':
+        case 'C':
+        {
+          if (LocaleCompare(attribute,"crop") == 0)
+            {
+              crop_geometry=SvPV(ST(i),na);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        case 'g':
+        case 'G':
+        {
+          if (LocaleCompare(attribute,"geometry") == 0)
+            {
+              geometry=SvPV(ST(i),na);
+              break;
+            }
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+        default:
+        {
+          ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+            attribute);
+          break;
+        }
+      }
+    }
+    for ( ; image; image=image->next)
+    {
+      clone=CloneImage(image,0,0,MagickTrue,exception);
+      if (clone == (Image *) NULL)
+        goto PerlException;
+      TransformImage(&clone,crop_geometry,geometry,exception);
+      for ( ; clone; clone=clone->next)
+      {
+        AddImageToRegistry(sv,clone);
+        rv=newRV(sv);
+        av_push(av,sv_bless(rv,hv));
+        SvREFCNT_dec(sv);
+      }
+    }
+    exception=DestroyExceptionInfo(exception);
+    ST(0)=av_reference;
+    SvREFCNT_dec(perl_exception);  /* can't return warning messages */
+    XSRETURN(1);
+
+  PerlException:
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
+
+#
+###############################################################################
+#                                                                             #
+#                                                                             #
+#                                                                             #
+#   W r i t e                                                                 #
+#                                                                             #
+#                                                                             #
+#                                                                             #
+###############################################################################
+#
+#
+void
+Write(ref,...)
+  Image::Magick::@MAGICK_ABI_SUFFIX@ ref=NO_INIT
+  ALIAS:
+    WriteImage    = 1
+    write         = 2
+    writeimage    = 3
+  PPCODE:
+  {
+    char
+      filename[MaxTextExtent];
+
+    ExceptionInfo
+      *exception;
+
+    Image
+      *image,
+      *next;
+
+    register ssize_t
+      i;
+
+    ssize_t
+      number_images,
+      scene;
+
+    struct PackageInfo
+      *info,
+      *package_info;
+
+    SV
+      *perl_exception,
+      *reference;
+
+    PERL_UNUSED_VAR(ref);
+    PERL_UNUSED_VAR(ix);
+    exception=AcquireExceptionInfo();
+    perl_exception=newSVpv("",0);
+    number_images=0;
+    package_info=(struct PackageInfo *) NULL;
+    if (sv_isobject(ST(0)) == 0)
+      {
+        ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+          PackageName);
+        goto PerlException;
+      }
+    reference=SvRV(ST(0));
+    image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+    if (image == (Image *) NULL)
+      {
+        ThrowPerlException(exception,OptionError,"NoImagesDefined",
+          PackageName);
+        goto PerlException;
+      }
+    package_info=ClonePackageInfo(info,exception);
+    if (items == 2)
+      SetAttribute(aTHX_ package_info,NULL,"filename",ST(1),exception);
+    else
+      if (items > 2)
+        for (i=2; i < items; i+=2)
+          SetAttribute(aTHX_ package_info,image,SvPV(ST(i-1),na),ST(i),
+            exception);
+    (void) CopyMagickString(filename,package_info->image_info->filename,
+      MaxTextExtent);
+    scene=0;
+    for (next=image; next; next=next->next)
+    {
+      (void) CopyMagickString(next->filename,filename,MaxTextExtent);
+      next->scene=scene++;
+    }
+    SetImageInfo(package_info->image_info,(unsigned int)
+      GetImageListLength(image),exception);
+    for (next=image; next; next=next->next)
+    {
+      (void) WriteImage(package_info->image_info,next,exception);
+      number_images++;
+      if (package_info->image_info->adjoin)
+        break;
+    }
+
+  PerlException:
+    if (package_info != (struct PackageInfo *) NULL)
+      DestroyPackageInfo(package_info);
+    InheritPerlException(exception,perl_exception);
+    exception=DestroyExceptionInfo(exception);
+    sv_setiv(perl_exception,(IV) number_images);
+    SvPOK_on(perl_exception);
+    ST(0)=sv_2mortal(perl_exception);
+    XSRETURN(1);
+  }
diff --git a/PerlMagick/Makefile.PL b/PerlMagick/Makefile.PL
index fb32d75..278d5f8 100644
--- a/PerlMagick/Makefile.PL
+++ b/PerlMagick/Makefile.PL
@@ -185,10 +185,10 @@
 WriteMakefile
   (
    # Module description
-   'ABSTRACT'	=> 'ImageMagick PERL Extension',
+   'ABSTRACT'	=> 'ImageMagick PERL Extension (Q16HDRI)',
 
    # Perl module name is Image::Magick
-   'NAME'	=> 'Image::Magick',
+   'NAME'	=> 'Image::Magick::Q16HDRI',
 
    # Module author
    'AUTHOR' => 'ImageMagick Studio LLC',
@@ -234,6 +234,8 @@
 
    # Use same compiler as ImageMagick
    'PERLMAINCC'	=> ' -fopenmp',
+   'PM' => { 'Q16HDRI.pm' => '$(INST_LIBDIR)/Q16HDRI.pm' },
+   'XS' => { 'Q16HDRI.xs' => 'Q16HDRI.xs' },
    'AR' => 'ar',
    'LD' => '',
 
@@ -244,6 +246,9 @@
    test	=> { TESTS	=>	$delegate_tests},
 
    ($Config{'archname'} =~ /-object$/i ? ('CAPI' => 'TRUE') : ()),
+
+# sane vesion
+   depend => { '$(FIRST_MAKEFILE)' => '$(VERSION_FROM)' }
 );
 
 
diff --git a/PerlMagick/Makefile.PL.in b/PerlMagick/Makefile.PL.in
index cd5604b..2ec5b05 100644
--- a/PerlMagick/Makefile.PL.in
+++ b/PerlMagick/Makefile.PL.in
@@ -185,10 +185,10 @@
 WriteMakefile
   (
    # Module description
-   'ABSTRACT'	=> 'ImageMagick PERL Extension',
+   'ABSTRACT'	=> 'ImageMagick PERL Extension (@MAGICK_ABI_SUFFIX@)',
 
    # Perl module name is Image::Magick
-   'NAME'	=> 'Image::Magick',
+   'NAME'	=> 'Image::Magick::@MAGICK_ABI_SUFFIX@',
 
    # Module author
    'AUTHOR' => 'ImageMagick Studio LLC',
@@ -234,6 +234,8 @@
 
    # Use same compiler as ImageMagick
    'PERLMAINCC'	=> '@PERLMAINCC@ @OPENMP_CFLAGS@',
+   'PM' => { '@MAGICK_ABI_SUFFIX@.pm' => '$(INST_LIBDIR)/@MAGICK_ABI_SUFFIX@.pm' },
+   'XS' => { '@MAGICK_ABI_SUFFIX@.xs' => '@MAGICK_ABI_SUFFIX@.xs' },
    'AR' => '@AR@',
    'LD' => '@PERLMAINCC@',
 
@@ -244,6 +246,9 @@
    test	=> { TESTS	=>	$delegate_tests},
 
    ($Config{'archname'} =~ /-object$/i ? ('CAPI' => 'TRUE') : ()),
+
+# sane vesion
+   depend => { '$(FIRST_MAKEFILE)' => '$(VERSION_FROM)' }
 );
 
 
diff --git a/PerlMagick/Makefile.am b/PerlMagick/Makefile.am
index 4134520..26c1de1 100644
--- a/PerlMagick/Makefile.am
+++ b/PerlMagick/Makefile.am
@@ -17,12 +17,21 @@
 #  Makefile for building PerlMagick.
 
 # If source files missing, see if they can be obtained via VPATH
-perl-sources:
+
+$(PERLMAGICK)/@MAGICK_ABI_SUFFIX@.xs: $(PERLMAGICK)/Magick.xs
+	$(AM_V_GEN) $(LN_S) $(notdir $^) $@
+
+$(PERLMAGICK)/@MAGICK_ABI_SUFFIX@.pm: $(PERLMAGICK)/Magick.pm
+	$(AM_V_GEN) $(LN_S) $(notdir $^) $@
+
+perl-quantum-sources: $(PERLMAGICK)/@MAGICK_ABI_SUFFIX@.xs $(PERLMAGICK)/@MAGICK_ABI_SUFFIX@.pm
+
+perl-sources: perl-quantum-sources
 	@if test -n "$(VPATH)" ; then \
 	  echo "Linking PerlMagick Sources ..." ; \
 	  imagemagick=`(cd $(VPATH) ; pwd)` && \
 	  ( cd $(PERLMAGICK) && \
-	    sh $$imagemagick/config/lndir.sh $$imagemagick/$(PERLMAGICK) ) \
+	    sh $$imagemagick/config/lndir.sh $$imagemagick/$(PERLMAGICK) ; ) \
 	fi ; \
 	touch perl-sources
 
@@ -110,7 +119,10 @@
 	( if test -f Makefile ; then $(MAKE) CC='@CC@' clean ; fi ) ; \
 	( if test -f Makefile ; then $(MAKE) CC='@CC@' clean ; fi ) ; \
 	rm -f Makefile.old PerlMagick ; \
-	rm -f t/output* t/jng/*_tmp.jng t/*/output* )
+	rm -f t/output* t/jng/*_tmp.jng t/*/output* ; \
+	rm -f @MAGICK_ABI_SUFFIX@.xs;\
+	rm -f @MAGICK_ABI_SUFFIX@.pm;\
+	rm -f Magick.pm;)
 	rm -f perl-sources
 
 distclean-perl: clean-perl
diff --git a/PerlMagick/t/filter.t b/PerlMagick/t/filter.t
index 6701574..6d29991 100644
--- a/PerlMagick/t/filter.t
+++ b/PerlMagick/t/filter.t
@@ -28,7 +28,7 @@
 autoflush STDOUT 1;
 autoflush STDERR 1;
 
-$fuzz=int(0.0*QuantumRange);
+$fuzz=int(0.0*Image::Magick->new()->QuantumRange);
 
 testFilterCompare('input.miff',  q//, 'reference/filter/AdaptiveThreshold.miff', 'AdaptiveThreshold', q/'5x5+5%'/, 0.0, 0.0);
 ++$test;
diff --git a/PerlMagick/t/subroutines.pl b/PerlMagick/t/subroutines.pl
index 4463fbc..b99c4f0 100644
--- a/PerlMagick/t/subroutines.pl
+++ b/PerlMagick/t/subroutines.pl
@@ -182,11 +182,11 @@
       $ref_32 = $ref_16;
     }
 
-  if (QuantumDepth == 32)
+  if (Image::Magick->new()->QuantumDepth == 32)
     {
       $ref_signature=$ref_32;
     }
-  elsif (QuantumDepth == 16)
+  elsif (Image::Magick->new()->QuantumDepth == 16)
     {
       $ref_signature=$ref_16;
     }
@@ -223,7 +223,7 @@
        	print "Image: $infile, signatures do not match.\n";
       	print "     Expected: $ref_signature\n";
       	print "     Computed: $signature\n";
-        print "     Depth:    ", QuantumDepth, "\n";
+        print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
         ++$failure;
         $image->Display();
       }
@@ -261,7 +261,7 @@
               print "Image: $infile, signatures do not match.\n";
               print "     Expected: $ref_signature\n";
               print "     Computed: $signature\n";
-              print "     Depth:    ", QuantumDepth, "\n";
+              print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
               #$image->Display();
               ++$failure;
             }
@@ -420,11 +420,11 @@
       $ref_32 = $ref_16;
     }
 
-  if (QuantumDepth == 32)
+  if (Image::Magick->new()->QuantumDepth == 32)
     {
       $ref_signature=$ref_32;
     }
-  elsif (QuantumDepth == 16)
+  elsif (Image::Magick->new()->QuantumDepth == 16)
     {
       $ref_signature=$ref_16;
     }
@@ -440,8 +440,8 @@
   warn "$status" if "$status";
 
   # If depth is not zero, then set it
-  if ( QuantumDepth != 0 ) {
-    $status=$image->SetAttribute(depth=>QuantumDepth);
+  if ( Image::Magick->new()->QuantumDepth != 0 ) {
+    $status=$image->SetAttribute(depth=>Image::Magick->new()->QuantumDepth);
     warn "$status" if "$status";
   }
 
@@ -456,7 +456,7 @@
       	print "Image: $infile, signatures do not match.\n";
       	print "     Expected: $ref_signature\n";
       	print "     Computed: $signature\n";
-        print "     Depth:    ", QuantumDepth, "\n";
+        print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
         print "not ok $test\n";
         #$image->Display();
       } else {
@@ -494,11 +494,11 @@
       $ref_32 = $ref_16;
     }
 
-  if (QuantumDepth == 32)
+  if (Image::Magick->new()->QuantumDepth == 32)
     {
       $ref_signature=$ref_32;
     }
-  elsif (QuantumDepth == 16)
+  elsif (Image::Magick->new()->QuantumDepth == 16)
     {
       $ref_signature=$ref_16;
     }
@@ -543,7 +543,7 @@
           print "Image: $infile, signatures do not match.\n";
           print "     Expected: $ref_signature\n";
           print "     Computed: $signature\n";
-          print "     Depth:    ", QuantumDepth, "\n";
+          print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
           print "not ok $test\n";
           $image->Display();
         } else {
@@ -785,11 +785,11 @@
       $ref_32 = $ref_16;
     }
 
-  if (QuantumDepth == 32)
+  if (Image::Magick->new()->QuantumDepth == 32)
     {
       $ref_signature=$ref_32;
     }
-  elsif (QuantumDepth == 16)
+  elsif (Image::Magick->new()->QuantumDepth == 16)
     {
       $ref_signature=$ref_16;
     }
@@ -856,7 +856,7 @@
           print "Image: $infile, signatures do not match.\n";
           print "     Expected: $ref_signature\n";
           print "     Computed: $signature\n";
-          print "     Depth:    ", QuantumDepth, "\n";
+          print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
           print "not ok $test\n";
           #$image->Display();
         } else {
@@ -969,11 +969,11 @@
       $ref_32 = $ref_16;
     }
 
-  if (QuantumDepth == 32)
+  if (Image::Magick->new()->QuantumDepth == 32)
     {
       $ref_signature=$ref_32;
     }
-  elsif (QuantumDepth == 16)
+  elsif (Image::Magick->new()->QuantumDepth == 16)
     {
       $ref_signature=$ref_16;
     }
@@ -1042,7 +1042,7 @@
         print "Test $test, signatures do not match.\n";
       	print "     Expected: $ref_signature\n";
       	print "     Computed: $signature\n";
-        print "     Depth:    ", QuantumDepth, "\n";
+        print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
         $status = $montage->Write("test_${test}_out.miff");
         warn "Write: $status" if "$status";
           
@@ -1100,11 +1100,11 @@
       $ref_32 = $ref_16;
     }
 
-  if (QuantumDepth == 32)
+  if (Image::Magick->new()->QuantumDepth == 32)
     {
       $ref_signature=$ref_32;
     }
-  elsif (QuantumDepth == 16)
+  elsif (Image::Magick->new()->QuantumDepth == 16)
     {
       $ref_signature=$ref_16;
     }
@@ -1129,7 +1129,7 @@
       print "Test $test, signatures do not match.\n";
       print "     Expected: $ref_signature\n";
       print "     Computed: $signature\n";
-      print "     Depth:    ", QuantumDepth, "\n";
+      print "     Depth:    ", Image::Magick->new()->QuantumDepth, "\n";
       #$image->Display();
       print "not ok $test\n";
     } else {
diff --git a/PerlMagick/typemap b/PerlMagick/typemap
index 89f947b..d901f17 100644
--- a/PerlMagick/typemap
+++ b/PerlMagick/typemap
@@ -1 +1 @@
-Image::Magick T_PTROBJ
+Image::Magick::Q16HDRI T_PTROBJ
diff --git a/PerlMagick/typemap.in b/PerlMagick/typemap.in
new file mode 100644
index 0000000..3fd2b88
--- /dev/null
+++ b/PerlMagick/typemap.in
@@ -0,0 +1 @@
+Image::Magick::@MAGICK_ABI_SUFFIX@ T_PTROBJ
diff --git a/configure b/configure
index 9e981d5..ff3d072 100755
--- a/configure
+++ b/configure
@@ -3494,7 +3494,7 @@
 
 ac_config_commands="$ac_config_commands MagickCore/magick-baseconfig.h"
 
-ac_config_files="$ac_config_files common.shi config/configure.xml config/delegates.xml config/ImageMagick.rdf config/MagickCore.dox config/MagickWand.dox config/Magick++.dox config/type-dejavu.xml config/type-ghostscript.xml config/type-windows.xml config/type.xml ImageMagick.spec Magick++/bin/Magick++-config MagickCore/ImageMagick.pc Magick++/lib/Magick++.pc MagickCore/MagickCore-config MagickCore/MagickCore.pc MagickCore/version.h Makefile magick.sh PerlMagick/Magick.pm PerlMagick/Makefile.PL PerlMagick/check.sh utilities/animate.1 utilities/compare.1 utilities/composite.1 utilities/conjure.1 utilities/convert.1 utilities/display.1 utilities/identify.1 utilities/ImageMagick.1 utilities/import.1 utilities/mogrify.1 utilities/montage.1 utilities/stream.1 MagickWand/MagickWand-config MagickWand/MagickWand.pc"
+ac_config_files="$ac_config_files common.shi config/configure.xml config/delegates.xml config/ImageMagick.rdf config/MagickCore.dox config/MagickWand.dox config/Magick++.dox config/type-dejavu.xml config/type-ghostscript.xml config/type-windows.xml config/type.xml ImageMagick.spec Magick++/bin/Magick++-config MagickCore/ImageMagick.pc Magick++/lib/Magick++.pc MagickCore/MagickCore-config MagickCore/MagickCore.pc MagickCore/version.h Makefile magick.sh PerlMagick/check.sh PerlMagick/Magick.pm PerlMagick/Magick.xs PerlMagick/Makefile.PL PerlMagick/typemap utilities/animate.1 utilities/compare.1 utilities/composite.1 utilities/conjure.1 utilities/convert.1 utilities/display.1 utilities/identify.1 utilities/ImageMagick.1 utilities/import.1 utilities/mogrify.1 utilities/montage.1 utilities/stream.1 MagickWand/MagickWand-config MagickWand/MagickWand.pc"
 
 
 #
@@ -3668,7 +3668,7 @@
 
 MAGICK_VERSION=7.0.0-0
 
-MAGICK_SVN_REVISION=11008:11010M
+MAGICK_SVN_REVISION=11008:11015M
 
 
 # Substitute library versioning
@@ -36830,9 +36830,11 @@
     "MagickCore/version.h") CONFIG_FILES="$CONFIG_FILES MagickCore/version.h" ;;
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
     "magick.sh") CONFIG_FILES="$CONFIG_FILES magick.sh" ;;
-    "PerlMagick/Magick.pm") CONFIG_FILES="$CONFIG_FILES PerlMagick/Magick.pm" ;;
-    "PerlMagick/Makefile.PL") CONFIG_FILES="$CONFIG_FILES PerlMagick/Makefile.PL" ;;
     "PerlMagick/check.sh") CONFIG_FILES="$CONFIG_FILES PerlMagick/check.sh" ;;
+    "PerlMagick/Magick.pm") CONFIG_FILES="$CONFIG_FILES PerlMagick/Magick.pm" ;;
+    "PerlMagick/Magick.xs") CONFIG_FILES="$CONFIG_FILES PerlMagick/Magick.xs" ;;
+    "PerlMagick/Makefile.PL") CONFIG_FILES="$CONFIG_FILES PerlMagick/Makefile.PL" ;;
+    "PerlMagick/typemap") CONFIG_FILES="$CONFIG_FILES PerlMagick/typemap" ;;
     "utilities/animate.1") CONFIG_FILES="$CONFIG_FILES utilities/animate.1" ;;
     "utilities/compare.1") CONFIG_FILES="$CONFIG_FILES utilities/compare.1" ;;
     "utilities/composite.1") CONFIG_FILES="$CONFIG_FILES utilities/composite.1" ;;
diff --git a/configure.ac b/configure.ac
index 67ba8f1..660ab95 100755
--- a/configure.ac
+++ b/configure.ac
@@ -56,9 +56,11 @@
     MagickCore/version.h \
     Makefile \
     magick.sh \
-    PerlMagick/Magick.pm \
-    PerlMagick/Makefile.PL \
     PerlMagick/check.sh \
+    PerlMagick/Magick.pm \
+    PerlMagick/Magick.xs \
+    PerlMagick/Makefile.PL \
+    PerlMagick/typemap \
     utilities/animate.1 \
     utilities/compare.1 \
     utilities/composite.1 \