Image.cpp revision e6e40ada97dd07b629238f845f92c9c0b75dc487
1// This may look like C code, but it is really -*- C++ -*-
2//
3// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
4//
5// Implementation of Image
6//
7
8#define MAGICKCORE_IMPLEMENTATION  1
9#define MAGICK_PLUSPLUS_IMPLEMENTATION 1
10
11#include "Magick++/Include.h"
12#include <cstdlib>
13#include <string>
14#include <string.h>
15#include <errno.h>
16#include <math.h>
17
18using namespace std;
19
20#include "Magick++/Image.h"
21#include "Magick++/Functions.h"
22#include "Magick++/Pixels.h"
23#include "Magick++/Options.h"
24#include "Magick++/ImageRef.h"
25
26#define AbsoluteValue(x)  ((x) < 0 ? -(x) : (x))
27#define DegreesToRadians(x)  (MagickPI*(x)/180.0)
28
29#define GetPPException \
30  ExceptionInfo \
31    exceptionInfo; \
32  GetExceptionInfo(&exceptionInfo)
33#define ClonePPDrawException(wand) \
34  ExceptionInfo \
35    *exceptionInfo; \
36  exceptionInfo=DrawCloneExceptionInfo(wand)
37#define RestorePPChannelMask \
38  SetPixelChannelMask(image(),channel_mask)
39#define SetPPChannelMask(channel) \
40  ChannelType \
41    channel_mask; \
42  channel_mask=SetImageChannelMask(image(),channel)
43#define ThrowPPDrawException \
44  throwException(*exceptionInfo); \
45  (void) DestroyExceptionInfo(exceptionInfo)
46#define ThrowPPException \
47  throwException(exceptionInfo); \
48  (void) DestroyExceptionInfo(&exceptionInfo)
49
50MagickPPExport const char *Magick::borderGeometryDefault="6x6+0+0";
51MagickPPExport const char *Magick::frameGeometryDefault="25x25+6+6";
52MagickPPExport const char *Magick::raiseGeometryDefault="6x6+0+0";
53
54MagickPPExport int Magick::operator == (const Magick::Image &left_,
55  const Magick::Image &right_)
56{
57  // If image pixels and signature are the same, then the image is identical
58  return((left_.rows() == right_.rows()) &&
59    (left_.columns() == right_.columns()) &&
60    (left_.signature() == right_.signature()));
61}
62
63MagickPPExport int Magick::operator != (const Magick::Image &left_,
64  const Magick::Image &right_)
65{
66  return(!(left_ == right_));
67}
68
69MagickPPExport int Magick::operator > (const Magick::Image &left_,
70  const Magick::Image &right_)
71{
72  return(!(left_ < right_) && (left_ != right_));
73}
74
75MagickPPExport int Magick::operator < (const Magick::Image &left_,
76  const Magick::Image &right_)
77{
78  // If image pixels are less, then image is smaller
79  return((left_.rows() * left_.columns()) <
80    (right_.rows() * right_.columns()));
81}
82
83MagickPPExport int Magick::operator >= (const Magick::Image &left_,
84  const Magick::Image &right_)
85{
86  return((left_ > right_) || (left_ == right_));
87}
88
89MagickPPExport int Magick::operator <= (const Magick::Image &left_,
90  const Magick::Image &right_)
91{
92  return((left_ < right_) || ( left_ == right_));
93}
94
95Magick::Image::Image(void)
96  : _imgRef(new ImageRef)
97{
98}
99
100Magick::Image::Image(const Blob &blob_)
101  : _imgRef(new ImageRef)
102{
103  try
104  {
105    // Initialize, Allocate and Read images
106    read(blob_);
107  }
108  catch(const Warning &/*warning_*/)
109  {
110    // FIXME: need a way to report warnings in constructor
111  }
112  catch (const Error &/*error_*/)
113  {
114    // Release resources
115    delete _imgRef;
116    throw;
117  }
118}
119
120Magick::Image::Image(const Blob &blob_,const Geometry &size_)
121  : _imgRef(new ImageRef)
122{
123  try
124  {
125    // Read from Blob
126    read(blob_, size_);
127  }
128  catch(const Warning &/*warning_*/)
129  {
130    // FIXME: need a way to report warnings in constructor
131  }
132  catch(const Error &/*error_*/)
133  {
134    // Release resources
135    delete _imgRef;
136    throw;
137  }
138}
139
140Magick::Image::Image(const Blob &blob_,const Geometry &size_,
141  const size_t depth_)
142  : _imgRef(new ImageRef)
143{
144  try
145  {
146    // Read from Blob
147    read(blob_,size_,depth_);
148  }
149  catch(const Warning &/*warning_*/)
150  {
151    // FIXME: need a way to report warnings in constructor
152  }
153  catch(const Error &/*error_*/)
154  {
155    // Release resources
156    delete _imgRef;
157    throw;
158  }
159}
160
161Magick::Image::Image(const Blob &blob_,const Geometry &size_,
162  const size_t depth_,const std::string &magick_)
163  : _imgRef(new ImageRef)
164{
165  try
166  {
167    // Read from Blob
168    read(blob_,size_,depth_,magick_);
169  }
170  catch(const Warning &/*warning_*/)
171  {
172    // FIXME: need a way to report warnings in constructor
173  }
174  catch(const Error &/*error_*/)
175  {
176    // Release resources
177    delete _imgRef;
178    throw;
179  }
180}
181
182Magick::Image::Image(const Blob &blob_,const Geometry &size_,
183  const std::string &magick_)
184  : _imgRef(new ImageRef)
185{
186  try
187  {
188    // Read from Blob
189    read(blob_,size_,magick_);
190  }
191  catch(const Warning &/*warning_*/)
192  {
193    // FIXME: need a way to report warnings in constructor
194  }
195  catch(const Error &/*error_*/)
196  {
197    // Release resources
198    delete _imgRef;
199    throw;
200  }
201}
202
203Magick::Image::Image(const Geometry &size_,const Color &color_)
204  : _imgRef(new ImageRef)
205{
206  // xc: prefix specifies an X11 color string
207  std::string imageSpec("xc:");
208  imageSpec+=color_;
209
210  try
211  {
212    // Set image size
213    size(size_);
214
215    // Initialize, Allocate and Read images
216    read(imageSpec);
217  }
218  catch(const Warning &/*warning_*/)
219  {
220    // FIXME: need a way to report warnings in constructor
221  }
222  catch(const Error & /*error_*/)
223  {
224    // Release resources
225    delete _imgRef;
226    throw;
227  }
228}
229
230Magick::Image::Image(const Image &image_)
231  : _imgRef(image_._imgRef)
232{
233  Lock(&_imgRef->_mutexLock);
234
235  // Increase reference count
236  ++_imgRef->_refCount;
237}
238
239Magick::Image::Image(const size_t width_,const size_t height_,
240  const std::string &map_,const StorageType type_,const void *pixels_)
241  : _imgRef(new ImageRef)
242{
243  try
244  {
245    read(width_,height_,map_.c_str(),type_,pixels_);
246  }
247  catch(const Warning &/*warning_*/)
248  {
249    // FIXME: need a way to report warnings in constructor
250  }
251  catch(const Error &/*error_*/)
252  {
253    // Release resources
254    delete _imgRef;
255    throw;
256  }
257}
258
259Magick::Image::Image(const std::string &imageSpec_)
260  : _imgRef(new ImageRef)
261{
262  try
263  {
264    // Initialize, Allocate and Read images
265    read(imageSpec_);
266  }
267  catch(const Warning &/*warning_*/)
268  {
269    // FIXME: need a way to report warnings in constructor
270  }
271  catch(const Error &/*error_*/)
272  {
273    // Release resources
274    delete _imgRef;
275    throw;
276  }
277}
278
279Magick::Image::~Image()
280{
281  bool
282    doDelete=false;
283
284  {
285    Lock(&_imgRef->_mutexLock);
286    if (--_imgRef->_refCount == 0)
287      doDelete=true;
288  }
289
290  if (doDelete)
291    delete _imgRef;
292
293  _imgRef=0;
294}
295
296Magick::Image& Magick::Image::operator=(const Magick::Image &image_)
297{
298  if(this != &image_)
299    {
300      bool
301        doDelete=false;
302
303      {
304        Lock(&image_._imgRef->_mutexLock);
305        ++image_._imgRef->_refCount;
306      }
307
308      {
309        Lock(&_imgRef->_mutexLock);
310        if (--_imgRef->_refCount == 0)
311          doDelete=true;
312      }
313
314      if (doDelete)
315        {
316          // Delete old image reference with associated image and options.
317          delete _imgRef;
318          _imgRef=0;
319        }
320      // Use new image reference
321      _imgRef=image_._imgRef;
322    }
323
324  return(*this);
325}
326
327void Magick::Image::adjoin(const bool flag_)
328{
329  modifyImage();
330  options()->adjoin(flag_);
331}
332
333bool Magick::Image::adjoin(void) const
334{
335  return(constOptions()->adjoin());
336}
337
338void Magick::Image::alpha(const bool matteFlag_)
339{
340  modifyImage();
341
342  // If matte channel is requested, but image doesn't already have a
343  // matte channel, then create an opaque matte channel.  Likewise, if
344  // the image already has a matte channel but a matte channel is not
345  // desired, then set the matte channel to opaque.
346  GetPPException;
347  if ((matteFlag_ && !constImage()->alpha_trait) ||
348      (constImage()->alpha_trait && !matteFlag_))
349    SetImageAlpha(image(),OpaqueAlpha,&exceptionInfo);
350  ThrowPPException;
351
352  image()->alpha_trait=matteFlag_ ? BlendPixelTrait : UndefinedPixelTrait;
353}
354
355bool Magick::Image::alpha(void) const
356{
357  if (constImage()->alpha_trait == BlendPixelTrait)
358    return(true);
359  else
360    return(false);
361}
362
363void Magick::Image::alphaColor(const Color &alphaColor_)
364{
365  modifyImage();
366
367  if (alphaColor_.isValid())
368    {
369      image()->matte_color=alphaColor_;
370      options()->matteColor(alphaColor_);
371    }
372  else
373    {
374      // Set to default matte color
375      Color tmpColor("#BDBDBD");
376      image()->matte_color=tmpColor;
377      options()->matteColor(tmpColor);
378    }
379}
380
381Magick::Color Magick::Image::alphaColor(void) const
382{
383  return(Color(ClampToQuantum(constImage()->matte_color.red),
384    ClampToQuantum(constImage()->matte_color.green),
385    ClampToQuantum(constImage()->matte_color.blue)));
386}
387
388void Magick::Image::antiAlias(const bool flag_)
389{
390  modifyImage();
391  options()->antiAlias(static_cast<size_t>(flag_));
392}
393
394bool Magick::Image::antiAlias(void)
395{
396  return(static_cast<bool>(options()->antiAlias()));
397}
398
399void Magick::Image::animationDelay(const size_t delay_)
400{
401  modifyImage();
402  image()->delay=delay_;
403}
404
405size_t Magick::Image::animationDelay(void) const
406{
407  return(constImage()->delay);
408}
409
410void Magick::Image::animationIterations(const size_t iterations_)
411{
412  modifyImage();
413  image()->iterations=iterations_;
414}
415
416size_t Magick::Image::animationIterations(void) const
417{
418  return(constImage()->iterations);
419}
420
421void Magick::Image::backgroundColor(const Color &backgroundColor_)
422{
423  modifyImage();
424
425  if (backgroundColor_.isValid())
426    image()->background_color=backgroundColor_;
427  else
428    image()->background_color=Color();
429
430  options()->backgroundColor(backgroundColor_);
431}
432
433Magick::Color Magick::Image::backgroundColor(void) const
434{
435  return(constOptions()->backgroundColor());
436}
437
438void Magick::Image::backgroundTexture(const std::string &backgroundTexture_)
439{
440  modifyImage();
441  options()->backgroundTexture(backgroundTexture_);
442}
443
444std::string Magick::Image::backgroundTexture(void) const
445{
446  return(constOptions()->backgroundTexture());
447}
448
449size_t Magick::Image::baseColumns(void) const
450{
451  return(constImage()->magick_columns);
452}
453
454std::string Magick::Image::baseFilename(void) const
455{
456  return(std::string(constImage()->magick_filename));
457}
458
459size_t Magick::Image::baseRows(void) const
460{
461  return(constImage()->magick_rows);
462}
463
464void Magick::Image::borderColor(const Color &borderColor_)
465{
466  modifyImage();
467
468  if (borderColor_.isValid())
469    image()->border_color=borderColor_;
470  else
471    image()->border_color=Color();
472
473  options()->borderColor(borderColor_);
474}
475
476Magick::Color Magick::Image::borderColor(void) const
477{
478  return(constOptions()->borderColor());
479}
480
481Magick::Geometry Magick::Image::boundingBox(void) const
482{
483  RectangleInfo
484    bbox;
485
486  GetPPException;
487  bbox=GetImageBoundingBox(constImage(),&exceptionInfo);
488  ThrowPPException;
489  return(Geometry(bbox));
490}
491
492void Magick::Image::boxColor(const Color &boxColor_)
493{
494  modifyImage();
495  options()->boxColor(boxColor_);
496}
497
498Magick::Color Magick::Image::boxColor(void) const
499{
500  return(constOptions()->boxColor());
501}
502
503void Magick::Image::channelDepth(const size_t depth_)
504{
505  modifyImage();
506  GetPPException;
507  SetImageDepth(image(),depth_,&exceptionInfo);
508  ThrowPPException;
509}
510
511size_t Magick::Image::channelDepth()
512{
513  size_t
514    channel_depth;
515
516  GetPPException;
517  channel_depth=GetImageDepth(constImage(),&exceptionInfo);
518  ThrowPPException;
519  return(channel_depth);
520}
521
522size_t Magick::Image::channels() const
523{
524  return(constImage()->number_channels);
525}
526
527void Magick::Image::classType(const ClassType class_)
528{
529  if (classType() == PseudoClass && class_ == DirectClass)
530    {
531      // Use SyncImage to synchronize the DirectClass pixels with the
532      // color map and then set to DirectClass type.
533      modifyImage();
534      GetPPException;
535      SyncImage(image(),&exceptionInfo);
536      ThrowPPException;
537      image()->colormap=(PixelInfo *)RelinquishMagickMemory(image()->colormap);
538      image()->storage_class=static_cast<MagickCore::ClassType>(DirectClass);
539      return;
540    }
541
542  if (classType() == DirectClass && class_ == PseudoClass)
543    {
544      // Quantize to create PseudoClass color map
545      modifyImage();
546      quantizeColors(MaxColormapSize);
547      quantize();
548      image()->storage_class=static_cast<MagickCore::ClassType>(PseudoClass);
549    }
550}
551
552Magick::ClassType Magick::Image::classType(void) const
553{
554  return static_cast<Magick::ClassType>(constImage()->storage_class);
555}
556
557void Magick::Image::clipMask(const Magick::Image &clipMask_)
558{
559  modifyImage();
560
561  GetPPException;
562  if (clipMask_.isValid())
563    SetImageMask(image(),clipMask_.constImage(),&exceptionInfo);
564  else
565    SetImageMask(image(),0,&exceptionInfo);
566  ThrowPPException;
567}
568
569Magick::Image Magick::Image::clipMask(void) const
570{
571  MagickCore::Image
572    *image;
573
574  GetPPException;
575  image=GetImageMask(constImage(),&exceptionInfo);
576  ThrowPPException;
577  if (image == (MagickCore::Image *) NULL)
578    return(Magick::Image());
579  else
580    return(Magick::Image(image));
581}
582
583void Magick::Image::colorFuzz(const double fuzz_)
584{
585  modifyImage();
586  image()->fuzz=fuzz_;
587  options()->colorFuzz(fuzz_);
588}
589
590double Magick::Image::colorFuzz(void) const
591{
592  return(constOptions()->colorFuzz());
593}
594
595void Magick::Image::colorMapSize(const size_t entries_)
596{
597  if (entries_ >MaxColormapSize)
598    throwExceptionExplicit(OptionError,
599      "Colormap entries must not exceed MaxColormapSize");
600
601  modifyImage();
602  GetPPException;
603  AcquireImageColormap(image(),entries_,&exceptionInfo);
604  ThrowPPException;
605}
606
607size_t Magick::Image::colorMapSize(void) const
608{
609  if (!constImage()->colormap)
610    throwExceptionExplicit(OptionError,"Image does not contain a colormap");
611
612  return(constImage()->colors);
613}
614
615void Magick::Image::colorSpace(const ColorspaceType colorSpace_)
616{
617  if (image()->colorspace == colorSpace_)
618    return;
619
620  modifyImage();
621  GetPPException;
622  TransformImageColorspace(image(),colorSpace_,&exceptionInfo);
623  ThrowPPException;
624}
625
626Magick::ColorspaceType Magick::Image::colorSpace(void) const
627{
628  return (constImage()->colorspace);
629}
630
631void Magick::Image::colorSpaceType(const ColorspaceType colorSpace_)
632{
633  modifyImage();
634  GetPPException;
635  SetImageColorspace(image(),colorSpace_,&exceptionInfo);
636  ThrowPPException;
637  options()->colorspaceType(colorSpace_);
638}
639
640Magick::ColorspaceType Magick::Image::colorSpaceType(void) const
641{
642  return(constOptions()->colorspaceType());
643}
644
645size_t Magick::Image::columns(void) const
646{
647  return(constImage()->columns);
648}
649
650void Magick::Image::comment(const std::string &comment_)
651{
652  modifyImage();
653  GetPPException;
654  SetImageProperty(image(),"Comment",NULL,&exceptionInfo);
655  if (comment_.length() > 0)
656    SetImageProperty(image(),"Comment",comment_.c_str(),&exceptionInfo);
657  ThrowPPException;
658}
659
660std::string Magick::Image::comment(void) const
661{
662  const char
663    *value;
664
665  GetPPException;
666  value=GetImageProperty(constImage(),"Comment",&exceptionInfo);
667  ThrowPPException;
668
669  if (value)
670    return(std::string(value));
671
672  return(std::string()); // Intentionally no exception
673}
674
675void Magick::Image::compose(const CompositeOperator compose_)
676{
677  image()->compose=compose_;
678}
679
680Magick::CompositeOperator Magick::Image::compose(void) const
681{
682  return(constImage()->compose);
683}
684
685void Magick::Image::compressType(const CompressionType compressType_)
686{
687  modifyImage();
688  image()->compression=compressType_;
689  options()->compressType(compressType_);
690}
691
692Magick::CompressionType Magick::Image::compressType(void) const
693{
694  return(constImage()->compression);
695}
696
697void Magick::Image::debug(const bool flag_)
698{
699  modifyImage();
700  options()->debug(flag_);
701}
702
703bool Magick::Image::debug(void) const
704{
705  return(constOptions()->debug());
706}
707
708void Magick::Image::density(const Geometry &density_)
709{
710  modifyImage();
711  options()->density(density_);
712  if (density_.isValid())
713    {
714      image()->resolution.x=density_.width();
715      if (density_.height() != 0)
716        image()->resolution.y=density_.height();
717      else
718        image()->resolution.y=density_.width();
719    }
720  else
721    {
722      // Reset to default
723      image()->resolution.x=0;
724      image()->resolution.y=0;
725    }
726}
727
728Magick::Geometry Magick::Image::density(void) const
729{
730  if (isValid())
731    {
732      ssize_t
733        x_resolution=72,
734        y_resolution=72;
735
736      if (constImage()->resolution.x > 0.0)
737        x_resolution=static_cast<ssize_t>(constImage()->resolution.x + 0.5);
738
739      if (constImage()->resolution.y > 0.0)
740        y_resolution=static_cast<ssize_t>(constImage()->resolution.y + 0.5);
741
742      return(Geometry(x_resolution,y_resolution));
743    }
744
745  return(constOptions()->density());
746}
747
748void Magick::Image::depth(const size_t depth_)
749{
750  size_t
751    depth = depth_;
752
753  if (depth > MAGICKCORE_QUANTUM_DEPTH)
754    depth=MAGICKCORE_QUANTUM_DEPTH;
755
756  modifyImage();
757  image()->depth=depth;
758  options()->depth(depth);
759}
760
761size_t Magick::Image::depth(void) const
762{
763  return(constImage()->depth);
764}
765
766std::string Magick::Image::directory(void) const
767{
768  if (constImage()->directory)
769    return(std::string(constImage()->directory));
770
771  throwExceptionExplicit(CorruptImageWarning,
772    "Image does not contain a directory");
773
774  return(std::string());
775}
776
777void Magick::Image::endian(const Magick::EndianType endian_)
778{
779  modifyImage();
780  options()->endian(endian_);
781  image()->endian=endian_;
782}
783
784Magick::EndianType Magick::Image::endian(void) const
785{
786  return(constImage()->endian);
787}
788
789void Magick::Image::exifProfile(const Magick::Blob &exifProfile_)
790{
791  modifyImage();
792
793  if (exifProfile_.data() != 0)
794    {
795      StringInfo
796        *exif_profile;
797
798      exif_profile=AcquireStringInfo(exifProfile_.length());
799      SetStringInfoDatum(exif_profile,(unsigned char *) exifProfile_.data());
800      GetPPException;
801      (void) SetImageProfile(image(),"exif",exif_profile,&exceptionInfo);
802      exif_profile=DestroyStringInfo(exif_profile);
803      ThrowPPException;
804    }
805}
806
807Magick::Blob Magick::Image::exifProfile(void) const
808{
809  const StringInfo
810    *exif_profile;
811
812  exif_profile=GetImageProfile(constImage(),"exif");
813  if (exif_profile == (StringInfo *) NULL)
814    return(Blob());
815  return(Blob(GetStringInfoDatum(exif_profile),
816    GetStringInfoLength(exif_profile)));
817}
818
819void Magick::Image::fileName(const std::string &fileName_)
820{
821  modifyImage();
822
823  fileName_.copy(image()->filename,sizeof(image()->filename)-1);
824  image()->filename[fileName_.length()]=0; // Null terminate
825
826  options()->fileName(fileName_);
827}
828
829std::string Magick::Image::fileName(void) const
830{
831  return(constOptions()->fileName());
832}
833
834MagickCore::MagickSizeType Magick::Image::fileSize(void) const
835{
836  return(GetBlobSize(constImage()));
837}
838
839void Magick::Image::fillColor(const Magick::Color &fillColor_)
840{
841  modifyImage();
842  options()->fillColor(fillColor_);
843}
844
845Magick::Color Magick::Image::fillColor(void) const
846{
847  return(constOptions()->fillColor());
848}
849
850void Magick::Image::fillRule(const Magick::FillRule &fillRule_)
851{
852  modifyImage();
853  options()->fillRule(fillRule_);
854}
855
856Magick::FillRule Magick::Image::fillRule(void) const
857{
858  return constOptions()->fillRule();
859}
860
861void Magick::Image::fillPattern(const Image &fillPattern_)
862{
863  modifyImage();
864  if (fillPattern_.isValid())
865    options()->fillPattern(fillPattern_.constImage());
866  else
867    options()->fillPattern(static_cast<MagickCore::Image*>(NULL));
868}
869
870Magick::Image Magick::Image::fillPattern(void) const
871{
872  // FIXME: This is inordinately innefficient
873  const MagickCore::Image
874    *tmpTexture;
875
876  Image
877    texture;
878
879  tmpTexture=constOptions()->fillPattern();
880
881  if (tmpTexture)
882    {
883      MagickCore::Image
884        *image;
885
886      GetPPException;
887      image=CloneImage(tmpTexture,0,0,MagickTrue,&exceptionInfo);
888      texture.replaceImage(image);
889      ThrowPPException;
890    }
891  return(texture);
892}
893
894void Magick::Image::filterType(const Magick::FilterTypes filterType_)
895{
896  modifyImage();
897  image()->filter=filterType_;
898}
899
900Magick::FilterTypes Magick::Image::filterType(void) const
901{
902  return(constImage()->filter);
903}
904
905void Magick::Image::font(const std::string &font_)
906{
907  modifyImage();
908  options()->font(font_);
909}
910
911std::string Magick::Image::font(void) const
912{
913  return(constOptions()->font());
914}
915
916void Magick::Image::fontPointsize(const double pointSize_)
917{
918  modifyImage();
919  options()->fontPointsize(pointSize_);
920}
921
922double Magick::Image::fontPointsize(void) const
923{
924  return(constOptions()->fontPointsize());
925}
926
927std::string Magick::Image::format(void) const
928{
929  const MagickInfo
930   *magick_info;
931
932  GetPPException;
933  magick_info=GetMagickInfo(constImage()->magick,&exceptionInfo);
934  ThrowPPException;
935
936  if ((magick_info != 0) && (*magick_info->description != '\0'))
937    return(std::string(magick_info->description));
938
939  throwExceptionExplicit(CorruptImageWarning,"Unrecognized image magick type");
940  return(std::string());
941}
942
943std::string Magick::Image::formatExpression(const std::string expression)
944{
945  char
946    *text;
947
948  std::string
949    result;
950
951  GetPPException;
952  text=InterpretImageProperties(imageInfo(),image(),expression.c_str(),
953    &exceptionInfo);
954  if (text != (char *) NULL)
955    {
956      result=std::string(text);
957      text=DestroyString(text);
958    }
959  ThrowPPException;
960  return(result);
961}
962
963double Magick::Image::gamma(void) const
964{
965  return(constImage()->gamma);
966}
967
968Magick::Geometry Magick::Image::geometry(void) const
969{
970  if (constImage()->geometry)
971    return Geometry(constImage()->geometry);
972
973  throwExceptionExplicit(OptionWarning,"Image does not contain a geometry");
974
975  return(Geometry());
976}
977
978void Magick::Image::gifDisposeMethod(
979  const MagickCore::DisposeType disposeMethod_)
980{
981  modifyImage();
982  image()->dispose=disposeMethod_;
983}
984
985MagickCore::DisposeType Magick::Image::gifDisposeMethod(void) const
986{
987  return(constImage()->dispose);
988}
989
990void Magick::Image::iccColorProfile(const Magick::Blob &colorProfile_)
991{
992  profile("icm",colorProfile_);
993}
994
995Magick::Blob Magick::Image::iccColorProfile(void) const
996{
997  const StringInfo
998    *color_profile;
999
1000  color_profile=GetImageProfile(constImage(),"icc");
1001  if (color_profile == (StringInfo *) NULL)
1002    return(Blob());
1003  return(Blob(GetStringInfoDatum(color_profile),GetStringInfoLength(
1004    color_profile)));
1005}
1006
1007void Magick::Image::interlaceType(const Magick::InterlaceType interlace_)
1008{
1009  modifyImage();
1010  image()->interlace=interlace_;
1011  options()->interlaceType(interlace_);
1012}
1013
1014Magick::InterlaceType Magick::Image::interlaceType(void) const
1015{
1016  return(constImage()->interlace);
1017}
1018
1019void Magick::Image::interpolate(const PixelInterpolateMethod interpolate_)
1020{
1021  modifyImage();
1022  image()->interpolate=interpolate_;
1023}
1024
1025Magick::PixelInterpolateMethod Magick::Image::interpolate(void) const
1026{
1027  return constImage()->interpolate;
1028}
1029
1030void Magick::Image::iptcProfile(const Magick::Blob &iptcProfile_)
1031{
1032  modifyImage();
1033  if (iptcProfile_.data() != 0)
1034    {
1035      StringInfo
1036        *iptc_profile;
1037
1038      iptc_profile=AcquireStringInfo(iptcProfile_.length());
1039      SetStringInfoDatum(iptc_profile,(unsigned char *) iptcProfile_.data());
1040      GetPPException;
1041      (void) SetImageProfile(image(),"iptc",iptc_profile,&exceptionInfo);
1042      iptc_profile=DestroyStringInfo(iptc_profile);
1043      ThrowPPException;
1044    }
1045}
1046
1047Magick::Blob Magick::Image::iptcProfile(void) const
1048{
1049  const StringInfo
1050    *iptc_profile;
1051
1052  iptc_profile=GetImageProfile(constImage(),"iptc");
1053  if (iptc_profile == (StringInfo *) NULL)
1054    return(Blob());
1055  return(Blob(GetStringInfoDatum(iptc_profile),GetStringInfoLength(
1056    iptc_profile)));
1057}
1058
1059void Magick::Image::isValid(const bool isValid_)
1060{
1061  if (!isValid_)
1062    {
1063      delete _imgRef;
1064      _imgRef=new ImageRef;
1065    }
1066  else if (!isValid())
1067    {
1068      // Construct with single-pixel black image to make
1069      // image valid. This is an obvious hack.
1070      size(Geometry(1,1));
1071      read("xc:black");
1072    }
1073}
1074
1075bool Magick::Image::isValid(void) const
1076{
1077  return rows() && columns();
1078}
1079
1080void Magick::Image::label(const std::string &label_)
1081{
1082  modifyImage();
1083  GetPPException;
1084  SetImageProperty(image(),"Label",NULL,&exceptionInfo);
1085  if (label_.length() > 0)
1086    SetImageProperty(image(),"Label",label_.c_str(),&exceptionInfo);
1087  ThrowPPException;
1088}
1089
1090std::string Magick::Image::label(void) const
1091{
1092  const char
1093    *value;
1094
1095  GetPPException;
1096  value=GetImageProperty(constImage(),"Label",&exceptionInfo);
1097  ThrowPPException;
1098
1099  if (value)
1100    return(std::string(value));
1101
1102  return(std::string());
1103}
1104
1105void Magick::Image::magick(const std::string &magick_)
1106{
1107  modifyImage();
1108
1109  magick_.copy(image()->magick,sizeof(image()->magick)-1);
1110  image()->magick[magick_.length()]=0;
1111
1112  options()->magick(magick_);
1113}
1114
1115std::string Magick::Image::magick(void) const
1116{
1117  if (*(constImage()->magick) != '\0')
1118    return(std::string(constImage()->magick));
1119
1120  return(constOptions()->magick());
1121}
1122
1123double Magick::Image::meanErrorPerPixel(void) const
1124{
1125  return(constImage()->error.mean_error_per_pixel);
1126}
1127
1128void Magick::Image::modulusDepth(const size_t depth_)
1129{
1130  modifyImage();
1131  GetPPException;
1132  SetImageDepth(image(),depth_,&exceptionInfo);
1133  ThrowPPException;
1134  options()->depth(depth_);
1135}
1136
1137size_t Magick::Image::modulusDepth(void) const
1138{
1139  size_t
1140    depth;
1141
1142  GetPPException;
1143  depth=GetImageDepth(constImage(),&exceptionInfo);
1144  ThrowPPException;
1145  return(depth);
1146}
1147
1148void Magick::Image::monochrome(const bool monochromeFlag_)
1149{
1150  modifyImage();
1151  options()->monochrome(monochromeFlag_);
1152}
1153
1154bool Magick::Image::monochrome(void) const
1155{
1156  return(constOptions()->monochrome());
1157}
1158
1159Magick::Geometry Magick::Image::montageGeometry(void) const
1160{
1161  if (constImage()->montage)
1162    return Magick::Geometry(constImage()->montage);
1163
1164  throwExceptionExplicit(CorruptImageWarning,
1165    "Image does not contain a montage");
1166
1167  return(Magick::Geometry());
1168}
1169
1170double Magick::Image::normalizedMaxError(void) const
1171{
1172  return(constImage()->error.normalized_maximum_error);
1173}
1174
1175double Magick::Image::normalizedMeanError(void) const
1176{
1177  return(constImage()->error.normalized_mean_error);
1178}
1179
1180void Magick::Image::orientation(const Magick::OrientationType orientation_)
1181{
1182  modifyImage();
1183  image()->orientation=orientation_;
1184}
1185
1186Magick::OrientationType Magick::Image::orientation(void) const
1187{
1188  return(constImage()->orientation);
1189}
1190
1191void Magick::Image::page(const Magick::Geometry &pageSize_)
1192{
1193  modifyImage();
1194  options()->page(pageSize_);
1195  image()->page=pageSize_;
1196}
1197
1198Magick::Geometry Magick::Image::page(void) const
1199{
1200  return(Geometry(constImage()->page.width,constImage()->page.height,
1201    AbsoluteValue(constImage()->page.x),AbsoluteValue(constImage()->page.y),
1202    constImage()->page.x < 0 ? true : false,
1203    constImage()->page.y < 0 ? true : false));
1204}
1205
1206void Magick::Image::quality(const size_t quality_)
1207{
1208  modifyImage();
1209  image()->quality=quality_;
1210  options()->quality(quality_);
1211}
1212
1213size_t Magick::Image::quality(void) const
1214{
1215  return(constImage()->quality);
1216}
1217
1218void Magick::Image::quantizeColors(const size_t colors_)
1219{
1220  modifyImage();
1221  options()->quantizeColors(colors_);
1222}
1223
1224size_t Magick::Image::quantizeColors(void) const
1225{
1226  return(constOptions()->quantizeColors());
1227}
1228
1229void Magick::Image::quantizeColorSpace(
1230  const Magick::ColorspaceType colorSpace_)
1231{
1232  modifyImage();
1233  options()->quantizeColorSpace(colorSpace_);
1234}
1235
1236Magick::ColorspaceType Magick::Image::quantizeColorSpace(void) const
1237{
1238  return(constOptions()->quantizeColorSpace());
1239}
1240
1241void Magick::Image::quantizeDither(const bool ditherFlag_)
1242{
1243  modifyImage();
1244  options()->quantizeDither(ditherFlag_);
1245}
1246
1247bool Magick::Image::quantizeDither(void) const
1248{
1249  return(constOptions()->quantizeDither());
1250}
1251
1252void Magick::Image::quantizeTreeDepth(const size_t treeDepth_)
1253{
1254  modifyImage();
1255  options()->quantizeTreeDepth(treeDepth_);
1256}
1257
1258size_t Magick::Image::quantizeTreeDepth() const
1259{
1260  return(constOptions()->quantizeTreeDepth());
1261}
1262
1263void Magick::Image::renderingIntent(
1264  const Magick::RenderingIntent renderingIntent_)
1265{
1266  modifyImage();
1267  image()->rendering_intent=renderingIntent_;
1268}
1269
1270Magick::RenderingIntent Magick::Image::renderingIntent(void) const
1271{
1272  return(static_cast<Magick::RenderingIntent>(constImage()->rendering_intent));
1273}
1274
1275void Magick::Image::resolutionUnits(
1276  const Magick::ResolutionType resolutionUnits_)
1277{
1278  modifyImage();
1279  image()->units=resolutionUnits_;
1280  options()->resolutionUnits(resolutionUnits_);
1281}
1282
1283Magick::ResolutionType Magick::Image::resolutionUnits(void) const
1284{
1285  return(constOptions()->resolutionUnits());
1286}
1287
1288size_t Magick::Image::rows(void) const
1289{
1290  return(constImage()->rows);
1291}
1292
1293void Magick::Image::scene(const size_t scene_)
1294{
1295  modifyImage();
1296  image()->scene=scene_;
1297}
1298
1299size_t Magick::Image::scene(void) const
1300{
1301  return(constImage()->scene);
1302}
1303
1304void Magick::Image::size(const Geometry &geometry_)
1305{
1306  modifyImage();
1307  options()->size(geometry_);
1308  image()->rows=geometry_.height();
1309  image()->columns=geometry_.width();
1310}
1311
1312Magick::Geometry Magick::Image::size(void) const
1313{
1314  return(Magick::Geometry(constImage()->columns,constImage()->rows));
1315}
1316
1317void Magick::Image::strokeAntiAlias(const bool flag_)
1318{
1319  modifyImage();
1320  options()->strokeAntiAlias(flag_);
1321}
1322
1323bool Magick::Image::strokeAntiAlias(void) const
1324{
1325  return(constOptions()->strokeAntiAlias());
1326}
1327
1328void Magick::Image::strokeColor(const Magick::Color &strokeColor_)
1329{
1330  modifyImage();
1331  options()->strokeColor(strokeColor_);
1332}
1333
1334Magick::Color Magick::Image::strokeColor(void) const
1335{
1336  return(constOptions()->strokeColor());
1337}
1338
1339void Magick::Image::strokeDashArray(const double *strokeDashArray_)
1340{
1341  modifyImage();
1342  options()->strokeDashArray(strokeDashArray_);
1343}
1344
1345const double* Magick::Image::strokeDashArray(void) const
1346{
1347  return(constOptions()->strokeDashArray());
1348}
1349
1350void Magick::Image::strokeDashOffset(const double strokeDashOffset_)
1351{
1352  modifyImage();
1353  options()->strokeDashOffset(strokeDashOffset_);
1354}
1355
1356double Magick::Image::strokeDashOffset(void) const
1357{
1358  return(constOptions()->strokeDashOffset());
1359}
1360
1361void Magick::Image::strokeLineCap(const Magick::LineCap lineCap_)
1362{
1363  modifyImage();
1364  options()->strokeLineCap(lineCap_);
1365}
1366
1367Magick::LineCap Magick::Image::strokeLineCap(void) const
1368{
1369  return(constOptions()->strokeLineCap());
1370}
1371
1372void Magick::Image::strokeLineJoin(const Magick::LineJoin lineJoin_)
1373{
1374  modifyImage();
1375  options()->strokeLineJoin(lineJoin_);
1376}
1377
1378Magick::LineJoin Magick::Image::strokeLineJoin(void) const
1379{
1380  return(constOptions()->strokeLineJoin());
1381}
1382
1383void Magick::Image::strokeMiterLimit(const size_t strokeMiterLimit_)
1384{
1385  modifyImage();
1386  options()->strokeMiterLimit(strokeMiterLimit_);
1387}
1388
1389size_t Magick::Image::strokeMiterLimit(void) const
1390{
1391  return(constOptions()->strokeMiterLimit());
1392}
1393
1394void Magick::Image::strokePattern(const Image &strokePattern_)
1395{
1396  modifyImage();
1397  if(strokePattern_.isValid())
1398    options()->strokePattern(strokePattern_.constImage());
1399  else
1400    options()->strokePattern(static_cast<MagickCore::Image*>(NULL));
1401}
1402
1403Magick::Image Magick::Image::strokePattern(void) const
1404{
1405  // FIXME: This is inordinately innefficient
1406  const MagickCore::Image
1407    *tmpTexture;
1408
1409  Image
1410    texture;
1411
1412  tmpTexture=constOptions()->strokePattern();
1413
1414  if (tmpTexture)
1415    {
1416      MagickCore::Image
1417        *image;
1418
1419      GetPPException;
1420      image=CloneImage(tmpTexture,0,0,MagickTrue,&exceptionInfo);
1421      texture.replaceImage(image);
1422      ThrowPPException;
1423    }
1424  return(texture);
1425}
1426
1427void Magick::Image::strokeWidth(const double strokeWidth_)
1428{
1429  modifyImage();
1430  options()->strokeWidth(strokeWidth_);
1431}
1432
1433double Magick::Image::strokeWidth(void) const
1434{
1435  return(constOptions()->strokeWidth());
1436}
1437
1438void Magick::Image::subImage(const size_t subImage_)
1439{
1440  modifyImage();
1441  options()->subImage(subImage_);
1442}
1443
1444size_t Magick::Image::subImage(void) const
1445{
1446  return(constOptions()->subImage());
1447}
1448
1449void Magick::Image::subRange(const size_t subRange_)
1450{
1451  modifyImage();
1452  options()->subRange(subRange_);
1453}
1454
1455size_t Magick::Image::subRange(void) const
1456{
1457  return(constOptions()->subRange());
1458}
1459
1460void Magick::Image::textEncoding(const std::string &encoding_)
1461{
1462  modifyImage();
1463  options()->textEncoding(encoding_);
1464}
1465
1466std::string Magick::Image::textEncoding(void) const
1467{
1468  return(constOptions()->textEncoding());
1469}
1470
1471void Magick::Image::textInterlineSpacing(double spacing_)
1472{
1473  modifyImage();
1474  options()->textInterlineSpacing(spacing_);
1475}
1476
1477double Magick::Image::textInterlineSpacing(void) const
1478{
1479  return(constOptions()->textInterlineSpacing());
1480}
1481
1482void Magick::Image::textInterwordSpacing(double spacing_)
1483{
1484  modifyImage();
1485  options()->textInterwordSpacing(spacing_);
1486}
1487
1488double Magick::Image::textInterwordSpacing(void) const
1489{
1490  return(constOptions()->textInterwordSpacing());
1491}
1492
1493void Magick::Image::textKerning(double kerning_)
1494{
1495  modifyImage();
1496  options()->textKerning(kerning_);
1497}
1498
1499double Magick::Image::textKerning(void) const
1500{
1501  return(constOptions()->textKerning());
1502}
1503
1504size_t Magick::Image::totalColors(void) const
1505{
1506  size_t
1507    colors;
1508
1509  GetPPException;
1510  colors=GetNumberColors(constImage(),0,&exceptionInfo);
1511  ThrowPPException;
1512  return colors;
1513}
1514
1515void Magick::Image::transformRotation(const double angle_)
1516{
1517  modifyImage();
1518  options()->transformRotation(angle_);
1519}
1520
1521void Magick::Image::transformSkewX(const double skewx_)
1522{
1523  modifyImage();
1524  options()->transformSkewX(skewx_);
1525}
1526
1527void Magick::Image::transformSkewY(const double skewy_)
1528{
1529  modifyImage();
1530  options()->transformSkewY(skewy_);
1531}
1532
1533Magick::ImageType Magick::Image::type(void) const
1534{
1535  ImageType
1536    image_type;
1537
1538  GetPPException;
1539  image_type=constOptions()->type();
1540  if (image_type == UndefinedType)
1541    image_type=GetImageType(constImage(),&exceptionInfo);
1542  ThrowPPException;
1543  return image_type;
1544}
1545
1546void Magick::Image::type(const Magick::ImageType type_)
1547{
1548  modifyImage();
1549  options()->type(type_);
1550  GetPPException;
1551  SetImageType(image(),type_,&exceptionInfo);
1552  ThrowPPException;
1553}
1554
1555void Magick::Image::verbose(const bool verboseFlag_)
1556{
1557  modifyImage();
1558  options()->verbose(verboseFlag_);
1559}
1560
1561bool Magick::Image::verbose(void) const
1562{
1563  return(constOptions()->verbose());
1564}
1565
1566void Magick::Image::view(const std::string &view_)
1567{
1568  modifyImage();
1569  options()->view(view_);
1570}
1571
1572std::string Magick::Image::view(void) const
1573{
1574  return(constOptions()->view());
1575}
1576
1577void Magick::Image::virtualPixelMethod(
1578  const VirtualPixelMethod virtualPixelMethod_)
1579{
1580  modifyImage();
1581  GetPPException;
1582  SetImageVirtualPixelMethod(image(),virtualPixelMethod_,&exceptionInfo);
1583  ThrowPPException;
1584}
1585
1586Magick::VirtualPixelMethod Magick::Image::virtualPixelMethod(void) const
1587{
1588  return(GetImageVirtualPixelMethod(constImage()));
1589}
1590
1591void Magick::Image::x11Display(const std::string &display_)
1592{
1593  modifyImage();
1594  options()->x11Display(display_);
1595}
1596
1597std::string Magick::Image::x11Display(void) const
1598{
1599  return(constOptions()->x11Display());
1600}
1601
1602double Magick::Image::xResolution(void) const
1603{
1604  return(constImage()->resolution.x);
1605}
1606
1607double Magick::Image::yResolution(void) const
1608{
1609  return(constImage()->resolution.y);
1610}
1611
1612void Magick::Image::adaptiveBlur(const double radius_,const double sigma_)
1613{
1614  MagickCore::Image
1615    *newImage;
1616
1617  GetPPException;
1618  newImage=AdaptiveBlurImage(constImage(),radius_,sigma_,&exceptionInfo);
1619  replaceImage(newImage);
1620  ThrowPPException;
1621}
1622
1623void Magick::Image::adaptiveResize(const Geometry &geometry_)
1624{
1625  MagickCore::Image
1626    *newImage;
1627
1628  size_t
1629    height=rows(),
1630    width=columns();
1631
1632  ssize_t
1633    x=0,
1634    y=0;
1635
1636  ParseMetaGeometry(static_cast<std::string>(geometry_).c_str(),&x,&y,&width,
1637    &height);
1638
1639  GetPPException;
1640  newImage=AdaptiveResizeImage(constImage(),width,height,&exceptionInfo);
1641  replaceImage(newImage);
1642  ThrowPPException;
1643}
1644
1645void Magick::Image::adaptiveSharpen(const double radius_,const double sigma_)
1646{
1647  MagickCore::Image
1648    *newImage;
1649
1650  GetPPException;
1651  newImage=AdaptiveSharpenImage(constImage(),radius_,sigma_,&exceptionInfo);
1652  replaceImage(newImage);
1653  ThrowPPException;
1654}
1655
1656void Magick::Image::adaptiveSharpenChannel(const ChannelType channel_,
1657  const double radius_,const double sigma_ )
1658{
1659  MagickCore::Image
1660    *newImage;
1661
1662  GetPPException;
1663  SetPPChannelMask(channel_);
1664  newImage=AdaptiveSharpenImage(constImage(),radius_,sigma_,&exceptionInfo);
1665  RestorePPChannelMask;
1666  replaceImage(newImage);
1667  ThrowPPException;
1668}
1669
1670void Magick::Image::adaptiveThreshold(const size_t width_,const size_t height_,
1671  const ssize_t offset_)
1672{
1673
1674  MagickCore::Image
1675    *newImage;
1676
1677  GetPPException;
1678  newImage=AdaptiveThresholdImage(constImage(),width_,height_,offset_,
1679    &exceptionInfo);
1680  replaceImage(newImage);
1681  ThrowPPException;
1682}
1683
1684void Magick::Image::addNoise(const NoiseType noiseType_)
1685{
1686  MagickCore::Image
1687    *newImage;
1688
1689  GetPPException;
1690  newImage=AddNoiseImage(constImage(),noiseType_,1.0,&exceptionInfo);
1691  replaceImage(newImage);
1692  ThrowPPException;
1693}
1694
1695void Magick::Image::addNoiseChannel(const ChannelType channel_,
1696  const NoiseType noiseType_)
1697{
1698  MagickCore::Image
1699    *newImage;
1700
1701  GetPPException;
1702  SetPPChannelMask(channel_);
1703  newImage=AddNoiseImage(constImage(),noiseType_,1.0,&exceptionInfo);
1704  RestorePPChannelMask;
1705  replaceImage(newImage);
1706  ThrowPPException;
1707}
1708
1709void Magick::Image::affineTransform(const DrawableAffine &affine_)
1710{
1711  AffineMatrix
1712    _affine;
1713
1714  MagickCore::Image
1715    *newImage;
1716
1717  _affine.sx=affine_.sx();
1718  _affine.sy=affine_.sy();
1719  _affine.rx=affine_.rx();
1720  _affine.ry=affine_.ry();
1721  _affine.tx=affine_.tx();
1722  _affine.ty=affine_.ty();
1723
1724  GetPPException;
1725  newImage=AffineTransformImage(constImage(),&_affine,&exceptionInfo);
1726  replaceImage(newImage);
1727  ThrowPPException;
1728}
1729
1730void Magick::Image::alpha(const unsigned int alpha_)
1731{
1732  modifyImage();
1733  GetPPException;
1734  SetImageAlpha(image(),alpha_,&exceptionInfo);
1735  ThrowPPException;
1736}
1737
1738void Magick::Image::alphaChannel(AlphaChannelOption alphaOption_)
1739{
1740  modifyImage();
1741  GetPPException;
1742  SetImageAlphaChannel(image(),alphaOption_,&exceptionInfo);
1743  ThrowPPException;
1744}
1745
1746void Magick::Image::alphaFloodfill(const Color &target_,
1747  const unsigned int alpha_,const ssize_t x_,const ssize_t y_,
1748  const Magick::PaintMethod method_)
1749{
1750  PixelInfo
1751    target;
1752
1753  modifyImage();
1754  GetPixelInfo(constImage(),&target);
1755  target.red=static_cast<PixelInfo>(target_).red;
1756  target.green=static_cast<PixelInfo>(target_).green;
1757  target.blue=static_cast<PixelInfo>(target_).blue;
1758  target.alpha=alpha_;
1759  GetPPException;
1760  SetPPChannelMask(AlphaChannel);
1761  FloodfillPaintImage(image(),options()->drawInfo(),&target,x_,y_,
1762    method_ == FloodfillMethod ? MagickFalse : MagickTrue,&exceptionInfo);
1763  RestorePPChannelMask;
1764  ThrowPPException;
1765}
1766
1767void Magick::Image::annotate(const std::string &text_,
1768  const Geometry &location_)
1769{
1770  annotate(text_,location_,NorthWestGravity,0.0);
1771}
1772
1773void Magick::Image::annotate(const std::string &text_,
1774  const Geometry &boundingArea_,const GravityType gravity_)
1775{
1776  annotate(text_,boundingArea_,gravity_,0.0);
1777}
1778
1779void Magick::Image::annotate(const std::string &text_,
1780  const Geometry &boundingArea_,const GravityType gravity_,
1781  const double degrees_)
1782{
1783  AffineMatrix
1784    oaffine;
1785
1786  char
1787    boundingArea[MaxTextExtent];
1788
1789  DrawInfo
1790    *drawInfo;
1791
1792  modifyImage();
1793
1794  drawInfo=options()->drawInfo();
1795  drawInfo->text=const_cast<char *>(text_.c_str());
1796  drawInfo->geometry=0;
1797
1798  if (boundingArea_.isValid())
1799    {
1800      if (boundingArea_.width() == 0 || boundingArea_.height() == 0)
1801        {
1802          FormatLocaleString(boundingArea,MaxTextExtent,"%+.20g%+.20g",
1803            (double) boundingArea_.xOff(),(double) boundingArea_.yOff());
1804        }
1805      else
1806        {
1807          (void) CopyMagickString(boundingArea,string(boundingArea_).c_str(),
1808            MaxTextExtent);
1809        }
1810      drawInfo->geometry=boundingArea;
1811    }
1812
1813  drawInfo->gravity=gravity_;
1814
1815  oaffine=drawInfo->affine;
1816  if (degrees_ != 0.0)
1817    {
1818       AffineMatrix
1819         affine,
1820         current;
1821
1822       affine.sx=1.0;
1823       affine.rx=0.0;
1824       affine.ry=0.0;
1825       affine.sy=1.0;
1826       affine.tx=0.0;
1827       affine.ty=0.0;
1828
1829       current=drawInfo->affine;
1830       affine.sx=cos(DegreesToRadians(fmod(degrees_,360.0)));
1831       affine.rx=sin(DegreesToRadians(fmod(degrees_,360.0)));
1832       affine.ry=(-sin(DegreesToRadians(fmod(degrees_,360.0))));
1833       affine.sy=cos(DegreesToRadians(fmod(degrees_,360.0)));
1834
1835       drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
1836       drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
1837       drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
1838       drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
1839       drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty
1840         +current.tx;
1841    }
1842
1843  GetPPException;
1844  AnnotateImage(image(),drawInfo,&exceptionInfo);
1845
1846  // Restore original values
1847  drawInfo->affine=oaffine;
1848  drawInfo->text=0;
1849  drawInfo->geometry=0;
1850
1851  ThrowPPException;
1852}
1853
1854void Magick::Image::annotate(const std::string &text_,
1855  const GravityType gravity_)
1856{
1857  DrawInfo
1858    *drawInfo;
1859
1860  modifyImage();
1861
1862  drawInfo=options()->drawInfo();
1863  drawInfo->text=const_cast<char *>(text_.c_str());
1864  drawInfo->gravity=gravity_;
1865
1866  GetPPException;
1867  AnnotateImage(image(),drawInfo,&exceptionInfo);
1868
1869  drawInfo->gravity=NorthWestGravity;
1870  drawInfo->text=0;
1871
1872  ThrowPPException;
1873}
1874
1875void Magick::Image::artifact(const std::string &name_,const std::string &value_)
1876{
1877  modifyImage();
1878  (void) SetImageArtifact(image(),name_.c_str(),value_.c_str());
1879}
1880
1881std::string Magick::Image::artifact(const std::string &name_)
1882{
1883  const char
1884    *value;
1885
1886  value=GetImageArtifact(constImage(),name_.c_str());
1887  if (value)
1888    return(std::string(value));
1889  return(std::string());
1890}
1891
1892void Magick::Image::attribute(const std::string name_,const std::string value_)
1893{
1894  modifyImage();
1895  GetPPException;
1896  SetImageProperty(image(),name_.c_str(),value_.c_str(),&exceptionInfo);
1897  ThrowPPException;
1898}
1899
1900std::string Magick::Image::attribute(const std::string name_)
1901{
1902  const char
1903    *value;
1904
1905  GetPPException;
1906  value=GetImageProperty(constImage(),name_.c_str(),&exceptionInfo);
1907  ThrowPPException;
1908
1909  if (value)
1910    return(std::string(value));
1911
1912  return(std::string()); // Intentionally no exception
1913}
1914
1915void Magick::Image::autoGamma(void)
1916{
1917  modifyImage();
1918  GetPPException;
1919  (void) SyncImageSettings(imageInfo(),image(),&exceptionInfo);
1920  (void) AutoGammaImage(image(),&exceptionInfo);
1921  ThrowPPException;
1922}
1923
1924void Magick::Image::autoGammaChannel(const ChannelType channel_)
1925{
1926  modifyImage();
1927  GetPPException;
1928  SetPPChannelMask(channel_);
1929  (void) SyncImageSettings(imageInfo(),image(),&exceptionInfo);
1930  (void) AutoGammaImage(image(),&exceptionInfo);
1931  RestorePPChannelMask;
1932  ThrowPPException;
1933}
1934
1935void Magick::Image::autoLevel(void)
1936{
1937  modifyImage();
1938  GetPPException;
1939  (void) SyncImageSettings(imageInfo(),image(),&exceptionInfo);
1940  (void) AutoLevelImage(image(),&exceptionInfo);
1941  ThrowPPException;
1942}
1943
1944void Magick::Image::autoLevelChannel(const ChannelType channel_)
1945{
1946  modifyImage();
1947  GetPPException;
1948  SetPPChannelMask(channel_);
1949  (void) SyncImageSettings(imageInfo(),image(),&exceptionInfo);
1950  (void) AutoLevelImage(image(),&exceptionInfo);
1951  RestorePPChannelMask;
1952  ThrowPPException;
1953}
1954
1955void Magick::Image::autoOrient(void)
1956{
1957  MagickCore::Image
1958    *newImage;
1959
1960  if (image()->orientation == UndefinedOrientation ||
1961      image()->orientation == TopLeftOrientation)
1962    return;
1963
1964  GetPPException;
1965  (void) SyncImageSettings(imageInfo(),image(),&exceptionInfo);
1966  newImage=AutoOrientImage(constImage(),image()->orientation,&exceptionInfo);
1967  replaceImage(newImage);
1968  ThrowPPException;
1969}
1970
1971void Magick::Image::blackThreshold(const std::string &threshold_)
1972{
1973  modifyImage();
1974  GetPPException;
1975  BlackThresholdImage(image(),threshold_.c_str(),&exceptionInfo);
1976  ThrowPPException;
1977}
1978
1979void Magick::Image::blackThresholdChannel(const ChannelType channel_,
1980  const std::string &threshold_)
1981{
1982  modifyImage();
1983  GetPPException;
1984  SetPPChannelMask(channel_);
1985  BlackThresholdImage(image(),threshold_.c_str(),&exceptionInfo);
1986  RestorePPChannelMask;
1987  ThrowPPException;
1988}
1989
1990void Magick::Image::blueShift(const double factor_)
1991{
1992  MagickCore::Image
1993    *newImage;
1994
1995  GetPPException;
1996  newImage=BlueShiftImage(constImage(),factor_,&exceptionInfo);
1997  replaceImage(newImage);
1998  ThrowPPException;
1999}
2000
2001void Magick::Image::blur(const double radius_,const double sigma_)
2002{
2003  MagickCore::Image
2004    *newImage;
2005
2006  GetPPException;
2007  newImage=BlurImage(constImage(),radius_,sigma_,&exceptionInfo);
2008  replaceImage(newImage);
2009  ThrowPPException;
2010}
2011
2012void Magick::Image::blurChannel(const ChannelType channel_,
2013  const double radius_,const double sigma_)
2014{
2015  MagickCore::Image
2016    *newImage;
2017
2018  GetPPException;
2019  SetPPChannelMask(channel_);
2020  newImage=BlurImage(constImage(),radius_,sigma_,&exceptionInfo);
2021  RestorePPChannelMask;
2022  replaceImage(newImage);
2023  ThrowPPException;
2024}
2025
2026void Magick::Image::border(const Geometry &geometry_)
2027{
2028  MagickCore::Image
2029    *newImage;
2030
2031  RectangleInfo
2032    borderInfo=geometry_;
2033
2034  GetPPException;
2035  newImage=BorderImage(constImage(),&borderInfo,image()->compose,
2036    &exceptionInfo);
2037  replaceImage(newImage);
2038  ThrowPPException;
2039}
2040
2041void Magick::Image::brightnessContrast(const double brightness_,
2042  const double contrast_)
2043{
2044  modifyImage();
2045  GetPPException;
2046  BrightnessContrastImage(image(),brightness_,contrast_,&exceptionInfo);
2047  ThrowPPException;
2048}
2049
2050void Magick::Image::brightnessContrastChannel(const ChannelType channel_,
2051  const double brightness_,const double contrast_)
2052{
2053  modifyImage();
2054  GetPPException;
2055  SetPPChannelMask(channel_);
2056  BrightnessContrastImage(image(),brightness_,contrast_,&exceptionInfo);
2057  RestorePPChannelMask;
2058  ThrowPPException;
2059}
2060
2061void Magick::Image::channel(const ChannelType channel_)
2062{
2063  MagickCore::Image
2064    *newImage;
2065
2066  GetPPException;
2067  newImage=SeparateImage(image(),channel_,&exceptionInfo);
2068  replaceImage(newImage);
2069  ThrowPPException;
2070}
2071
2072void Magick::Image::charcoal(const double radius_,const double sigma_)
2073{
2074  MagickCore::Image
2075    *newImage;
2076
2077  GetPPException;
2078  newImage=CharcoalImage(image(),radius_,sigma_,&exceptionInfo);
2079  replaceImage(newImage);
2080  ThrowPPException;
2081}
2082
2083void Magick::Image::chop(const Geometry &geometry_)
2084{
2085  MagickCore::Image
2086    *newImage;
2087
2088  RectangleInfo
2089    chopInfo=geometry_;
2090
2091  GetPPException;
2092  newImage=ChopImage(image(),&chopInfo,&exceptionInfo);
2093  replaceImage(newImage);
2094  ThrowPPException;
2095}
2096
2097void Magick::Image::chromaBluePrimary(const double x_,const double y_)
2098{
2099  modifyImage();
2100  image()->chromaticity.blue_primary.x=x_;
2101  image()->chromaticity.blue_primary.y=y_;
2102}
2103
2104void Magick::Image::chromaBluePrimary(double *x_,double *y_) const
2105{
2106  *x_=constImage()->chromaticity.blue_primary.x;
2107  *y_=constImage()->chromaticity.blue_primary.y;
2108}
2109
2110void Magick::Image::chromaGreenPrimary(const double x_,const double y_)
2111{
2112  modifyImage();
2113  image()->chromaticity.green_primary.x=x_;
2114  image()->chromaticity.green_primary.y=y_;
2115}
2116
2117void Magick::Image::chromaGreenPrimary(double *x_,double *y_) const
2118{
2119  *x_=constImage()->chromaticity.green_primary.x;
2120  *y_=constImage()->chromaticity.green_primary.y;
2121}
2122
2123void Magick::Image::chromaRedPrimary(const double x_,const double y_)
2124{
2125  modifyImage();
2126  image()->chromaticity.red_primary.x=x_;
2127  image()->chromaticity.red_primary.y=y_;
2128}
2129
2130void Magick::Image::chromaRedPrimary(double *x_,double *y_) const
2131{
2132  *x_=constImage()->chromaticity.red_primary.x;
2133  *y_=constImage()->chromaticity.red_primary.y;
2134}
2135
2136void Magick::Image::chromaWhitePoint(const double x_,const double y_)
2137{
2138  modifyImage();
2139  image()->chromaticity.white_point.x=x_;
2140  image()->chromaticity.white_point.y=y_;
2141}
2142
2143void Magick::Image::chromaWhitePoint(double *x_,double *y_) const
2144{
2145  *x_=constImage()->chromaticity.white_point.x;
2146  *y_=constImage()->chromaticity.white_point.y;
2147}
2148
2149void Magick::Image::cdl(const std::string &cdl_)
2150{
2151  modifyImage();
2152  GetPPException;
2153  (void) ColorDecisionListImage(image(),cdl_.c_str(),&exceptionInfo);
2154  ThrowPPException;
2155}
2156
2157void Magick::Image::clamp(void)
2158{
2159  modifyImage();
2160  GetPPException;
2161  ClampImage(image(),&exceptionInfo);
2162  ThrowPPException;
2163}
2164
2165void Magick::Image::clampChannel(const ChannelType channel_)
2166{
2167  modifyImage();
2168  GetPPException;
2169  SetPPChannelMask(channel_);
2170  ClampImage(image(),&exceptionInfo);
2171  RestorePPChannelMask;
2172  ThrowPPException;
2173}
2174
2175void Magick::Image::clip(void)
2176{
2177  modifyImage();
2178  GetPPException;
2179  ClipImage(image(),&exceptionInfo);
2180  ThrowPPException;
2181}
2182
2183void Magick::Image::clipPath(const std::string pathname_,const bool inside_)
2184{
2185  modifyImage();
2186  GetPPException;
2187  ClipImagePath(image(),pathname_.c_str(),(MagickBooleanType) inside_,
2188    &exceptionInfo);
2189  ThrowPPException;
2190}
2191
2192void Magick::Image::clut(const Image &clutImage_,
2193  const PixelInterpolateMethod method)
2194{
2195  modifyImage();
2196  GetPPException;
2197  ClutImage(image(),clutImage_.constImage(),method,&exceptionInfo);
2198  ThrowPPException;
2199}
2200
2201void Magick::Image::clutChannel(const ChannelType channel_,
2202  const Image &clutImage_,const PixelInterpolateMethod method)
2203{
2204  modifyImage();
2205  GetPPException;
2206  SetPPChannelMask(channel_);
2207  ClutImage(image(),clutImage_.constImage(),method,&exceptionInfo);
2208  RestorePPChannelMask;
2209  ThrowPPException;
2210}
2211
2212void Magick::Image::colorize(const unsigned int alpha_,const Color &penColor_)
2213{
2214  colorize(alpha_,alpha_,alpha_,penColor_);
2215}
2216
2217void Magick::Image::colorize(const unsigned int alphaRed_,
2218  const unsigned int alphaGreen_,const unsigned int alphaBlue_,
2219  const Color &penColor_)
2220{
2221  char
2222    blend[MaxTextExtent];
2223
2224  MagickCore::Image
2225    *newImage;
2226
2227  PixelInfo
2228    pixel,
2229    target;
2230
2231  if (!penColor_.isValid())
2232    throwExceptionExplicit(OptionError,"Pen color argument is invalid");
2233
2234  FormatLocaleString(blend,MaxTextExtent,"%u/%u/%u",alphaRed_,alphaGreen_,
2235    alphaBlue_);
2236
2237  GetPixelInfo(image(),&target);
2238  pixel=static_cast<PixelInfo>(penColor_);
2239  target.red=pixel.red;
2240  target.green=pixel.green;
2241  target.blue=pixel.blue;
2242  target.alpha=pixel.alpha;
2243  GetPPException;
2244  newImage=ColorizeImage(image(),blend,&target,&exceptionInfo);
2245  replaceImage(newImage);
2246  ThrowPPException;
2247}
2248
2249void Magick::Image::colorMap(const size_t index_,const Color &color_)
2250{
2251  MagickCore::Image
2252    *imageptr;
2253
2254  imageptr=image();
2255
2256  if (index_ > (MaxColormapSize-1))
2257    throwExceptionExplicit(OptionError,
2258      "Colormap index must be less than MaxColormapSize");
2259
2260  if (!color_.isValid())
2261    throwExceptionExplicit(OptionError,"Color argument is invalid");
2262
2263  modifyImage();
2264
2265  // Ensure that colormap size is large enough
2266  if (colorMapSize() < (index_+1))
2267    colorMapSize(index_+1);
2268
2269  // Set color at index in colormap
2270  (imageptr->colormap)[index_]=color_;
2271}
2272
2273Magick::Color Magick::Image::colorMap(const size_t index_) const
2274{
2275  if (!constImage()->colormap)
2276    {
2277      throwExceptionExplicit(OptionError,"Image does not contain a colormap");
2278      return(Color());
2279    }
2280
2281  if (index_ > constImage()->colors-1)
2282    throwExceptionExplicit(OptionError,"Index out of range");
2283
2284  return(Magick::Color((constImage()->colormap)[index_]));
2285}
2286
2287void Magick::Image::colorMatrix(const size_t order_,
2288  const double *color_matrix_)
2289{
2290  KernelInfo
2291    *kernel_info;
2292
2293  GetPPException;
2294  kernel_info=AcquireKernelInfo((const char *) NULL);
2295  kernel_info->width=order_;
2296  kernel_info->height=order_;
2297  kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order_,
2298    order_*sizeof(*kernel_info->values));
2299  if (kernel_info->values != (MagickRealType *) NULL)
2300    {
2301      MagickCore::Image
2302        *newImage;
2303
2304      for (ssize_t i=0; i < (ssize_t) (order_*order_); i++)
2305        kernel_info->values[i]=color_matrix_[i];
2306      newImage=ColorMatrixImage(image(),kernel_info,&exceptionInfo);
2307      replaceImage(newImage);
2308    }
2309  kernel_info=DestroyKernelInfo(kernel_info);
2310  ThrowPPException;
2311}
2312
2313bool Magick::Image::compare(const Image &reference_)
2314{
2315  bool
2316    status;
2317
2318  Image
2319    ref=reference_;
2320
2321  GetPPException;
2322  modifyImage();
2323  ref.modifyImage();
2324  status=static_cast<bool>(IsImagesEqual(image(),ref.image(),&exceptionInfo));
2325  ThrowPPException;
2326  return(status);
2327}
2328
2329double Magick::Image::compare(const Image &reference_,const MetricType metric_)
2330{
2331  double
2332    distortion=0.0;
2333
2334  GetPPException;
2335  GetImageDistortion(image(),reference_.constImage(),metric_,&distortion,
2336    &exceptionInfo);
2337  ThrowPPException;
2338  return(distortion);
2339}
2340
2341double Magick::Image::compareChannel(const ChannelType channel_,
2342  const Image &reference_,const MetricType metric_)
2343{
2344  double
2345    distortion=0.0;
2346
2347  GetPPException;
2348  SetPPChannelMask(channel_);
2349  GetImageDistortion(image(),reference_.constImage(),metric_,&distortion,
2350    &exceptionInfo);
2351  RestorePPChannelMask;
2352  ThrowPPException;
2353  return(distortion);
2354}
2355
2356Magick::Image Magick::Image::compare(const Image &reference_,
2357  const MetricType metric_,double *distortion)
2358{
2359  MagickCore::Image
2360    *newImage;
2361
2362  GetPPException;
2363  newImage=CompareImages(image(),reference_.constImage(),metric_,distortion,
2364    &exceptionInfo);
2365  ThrowPPException;
2366  if (newImage == (MagickCore::Image *) NULL)
2367    return(Magick::Image());
2368  else
2369    return(Magick::Image(newImage));
2370}
2371
2372Magick::Image Magick::Image::compareChannel(const ChannelType channel_,
2373  const Image &reference_,const MetricType metric_,double *distortion)
2374{
2375  MagickCore::Image
2376    *newImage;
2377
2378  GetPPException;
2379  SetPPChannelMask(channel_);
2380  newImage=CompareImages(image(),reference_.constImage(),metric_,distortion,
2381    &exceptionInfo);
2382  RestorePPChannelMask;
2383  ThrowPPException;
2384  if (newImage == (MagickCore::Image *) NULL)
2385    return(Magick::Image());
2386  else
2387    return(Magick::Image(newImage));
2388}
2389
2390void Magick::Image::composite(const Image &compositeImage_,
2391  const Geometry &offset_,const CompositeOperator compose_)
2392{
2393  size_t
2394    height=rows(),
2395    width=columns();
2396
2397  ssize_t
2398    x=offset_.xOff(),
2399    y=offset_.yOff();
2400
2401  ParseMetaGeometry(static_cast<std::string>(offset_).c_str(),&x,&y,&width,
2402    &height);
2403
2404  modifyImage();
2405  GetPPException;
2406  CompositeImage(image(),compositeImage_.constImage(),compose_,MagickFalse,
2407    x,y,&exceptionInfo);
2408  ThrowPPException;
2409}
2410
2411void Magick::Image::composite(const Image &compositeImage_,
2412  const GravityType gravity_,const CompositeOperator compose_)
2413{
2414  RectangleInfo
2415    geometry;
2416
2417  modifyImage();
2418  SetGeometry(compositeImage_.constImage(),&geometry);
2419  GravityAdjustGeometry(columns(),rows(),gravity_,&geometry);
2420
2421  GetPPException;
2422  CompositeImage(image(),compositeImage_.constImage(),compose_,MagickFalse,
2423    geometry.x,geometry.y,&exceptionInfo);
2424  ThrowPPException;
2425}
2426
2427void Magick::Image::composite(const Image &compositeImage_,
2428  const ssize_t xOffset_,const ssize_t yOffset_,
2429  const CompositeOperator compose_)
2430{
2431  // Image supplied as compositeImage is composited with current image and
2432  // results in updating current image.
2433  modifyImage();
2434  GetPPException;
2435  CompositeImage(image(),compositeImage_.constImage(),compose_,MagickFalse,
2436    xOffset_,yOffset_,&exceptionInfo);
2437  ThrowPPException;
2438}
2439
2440void Magick::Image::contrast(const size_t sharpen_)
2441{
2442  modifyImage();
2443  GetPPException;
2444  ContrastImage(image(),(MagickBooleanType) sharpen_,&exceptionInfo);
2445  ThrowPPException;
2446}
2447
2448void Magick::Image::contrastStretch(const double blackPoint_,
2449  const double whitePoint_)
2450{
2451  modifyImage();
2452  GetPPException;
2453  ContrastStretchImage(image(),blackPoint_,whitePoint_,&exceptionInfo);
2454  ThrowPPException;
2455}
2456
2457void Magick::Image::contrastStretchChannel(const ChannelType channel_,
2458  const double blackPoint_,const double whitePoint_)
2459{
2460  modifyImage();
2461  GetPPException;
2462  SetPPChannelMask(channel_);
2463  ContrastStretchImage(image(),blackPoint_,whitePoint_,&exceptionInfo);
2464  RestorePPChannelMask;
2465  ThrowPPException;
2466}
2467
2468void Magick::Image::convolve(const size_t order_,const double *kernel_)
2469{
2470  KernelInfo
2471    *kernel_info;
2472
2473  GetPPException;
2474  kernel_info=AcquireKernelInfo((const char *) NULL);
2475  kernel_info->width=order_;
2476  kernel_info->height=order_;
2477  kernel_info->values=(MagickRealType *) AcquireAlignedMemory(order_,
2478    order_*sizeof(*kernel_info->values));
2479  if (kernel_info->values != (MagickRealType *) NULL)
2480    {
2481      MagickCore::Image
2482        *newImage;
2483
2484      for (ssize_t i=0; i < (ssize_t) (order_*order_); i++)
2485        kernel_info->values[i]=kernel_[i];
2486      newImage=ConvolveImage(image(),kernel_info,&exceptionInfo);
2487      replaceImage(newImage);
2488    }
2489  kernel_info=DestroyKernelInfo(kernel_info);
2490  ThrowPPException;
2491}
2492
2493void Magick::Image::crop(const Geometry &geometry_)
2494{
2495  MagickCore::Image
2496    *newImage;
2497
2498  RectangleInfo
2499    cropInfo=geometry_;
2500
2501  GetPPException;
2502  newImage=CropImage(constImage(),&cropInfo,&exceptionInfo);
2503  replaceImage(newImage);
2504  ThrowPPException;
2505}
2506
2507void Magick::Image::cycleColormap(const ssize_t amount_)
2508{
2509  modifyImage();
2510  GetPPException;
2511  CycleColormapImage(image(),amount_,&exceptionInfo);
2512  ThrowPPException;
2513}
2514
2515void Magick::Image::decipher(const std::string &passphrase_)
2516{
2517  modifyImage();
2518  GetPPException;
2519  DecipherImage(image(),passphrase_.c_str(),&exceptionInfo);
2520  ThrowPPException;
2521}
2522
2523void Magick::Image::defineSet(const std::string &magick_,
2524  const std::string &key_,bool flag_)
2525{
2526  std::string
2527    definition;
2528
2529  modifyImage();
2530  definition=magick_ + ":" + key_;
2531  if (flag_)
2532    (void) SetImageOption(imageInfo(),definition.c_str(),"");
2533  else
2534    DeleteImageOption(imageInfo(),definition.c_str());
2535}
2536
2537bool Magick::Image::defineSet(const std::string &magick_,
2538  const std::string &key_ ) const
2539{
2540  const char
2541    *option;
2542
2543  std::string
2544    key;
2545
2546  key=magick_ + ":" + key_;
2547  option=GetImageOption(constImageInfo(),key.c_str());
2548  if (option)
2549    return(true);
2550  return(false);
2551}
2552
2553void Magick::Image::defineValue(const std::string &magick_,
2554  const std::string &key_,const std::string &value_)
2555{
2556  std::string
2557    format,
2558    option;
2559
2560  modifyImage();
2561  format=magick_ + ":" + key_;
2562  option=value_;
2563  (void) SetImageOption(imageInfo(),format.c_str(),option.c_str());
2564}
2565
2566std::string Magick::Image::defineValue(const std::string &magick_,
2567  const std::string &key_) const
2568{
2569  const char
2570    *option;
2571
2572  std::string
2573    definition;
2574
2575  definition=magick_ + ":" + key_;
2576  option=GetImageOption(constImageInfo(),definition.c_str());
2577  if (option)
2578    return(std::string(option));
2579  return(std::string());
2580}
2581
2582void Magick::Image::deskew(const double threshold_)
2583{
2584  MagickCore::Image
2585    *newImage;
2586
2587  GetPPException;
2588  newImage=DeskewImage(constImage(),threshold_,&exceptionInfo);
2589  replaceImage(newImage);
2590  ThrowPPException;
2591}
2592
2593void Magick::Image::despeckle(void)
2594{
2595  MagickCore::Image
2596    *newImage;
2597
2598  GetPPException;
2599  newImage=DespeckleImage(constImage(),&exceptionInfo);
2600  replaceImage(newImage);
2601  ThrowPPException;
2602}
2603
2604void Magick::Image::display(void)
2605{
2606  GetPPException;
2607  DisplayImages(imageInfo(),image(),&exceptionInfo);
2608  ThrowPPException;
2609}
2610
2611void Magick::Image::distort(const DistortImageMethod method_,
2612  const size_t numberArguments_,const double *arguments_,const bool bestfit_)
2613{
2614  MagickCore::Image
2615    *newImage;
2616
2617  GetPPException;
2618  newImage=DistortImage(constImage(), method_,numberArguments_,arguments_,
2619    bestfit_ == true ? MagickTrue : MagickFalse,&exceptionInfo);
2620  replaceImage(newImage);
2621  ThrowPPException;
2622}
2623
2624void Magick::Image::draw(const Magick::Drawable &drawable_)
2625{
2626  DrawingWand
2627    *wand;
2628
2629  modifyImage();
2630
2631  wand=DrawAllocateWand(options()->drawInfo(),image());
2632
2633  if(wand)
2634    {
2635      drawable_.operator()(wand);
2636
2637      DrawRender(wand);
2638
2639      ClonePPDrawException(wand);
2640      wand=DestroyDrawingWand(wand);
2641      ThrowPPDrawException;
2642    }
2643}
2644
2645void Magick::Image::draw(const std::list<Magick::Drawable> &drawable_)
2646{
2647  DrawingWand
2648    *wand;
2649
2650  modifyImage();
2651
2652  wand=DrawAllocateWand(options()->drawInfo(),image());
2653
2654  if(wand)
2655    {
2656      for (std::list<Magick::Drawable>::const_iterator p = drawable_.begin();
2657           p != drawable_.end(); p++ )
2658        {
2659          p->operator()(wand);
2660          if (DrawGetExceptionType(wand) != UndefinedException)
2661            break;
2662        }
2663
2664      if (DrawGetExceptionType(wand) == UndefinedException)
2665        DrawRender(wand);
2666
2667      ClonePPDrawException(wand);
2668      wand=DestroyDrawingWand(wand);
2669      ThrowPPDrawException;
2670    }
2671}
2672
2673void Magick::Image::edge(const double radius_)
2674{
2675  MagickCore::Image
2676    *newImage;
2677
2678  GetPPException;
2679  newImage=EdgeImage(constImage(),radius_,&exceptionInfo);
2680  replaceImage(newImage);
2681  ThrowPPException;
2682}
2683
2684void Magick::Image::emboss(const double radius_,const double sigma_)
2685{
2686  MagickCore::Image
2687    *newImage;
2688
2689  GetPPException;
2690  newImage=EmbossImage(constImage(),radius_,sigma_,&exceptionInfo);
2691  replaceImage(newImage);
2692  ThrowPPException;
2693}
2694
2695void Magick::Image::encipher(const std::string &passphrase_)
2696{
2697  modifyImage();
2698  GetPPException;
2699  EncipherImage(image(),passphrase_.c_str(),&exceptionInfo);
2700  ThrowPPException;
2701}
2702
2703void Magick::Image::enhance(void)
2704{
2705  MagickCore::Image
2706    *newImage;
2707
2708  GetPPException;
2709  newImage=EnhanceImage(constImage(),&exceptionInfo);
2710  replaceImage(newImage);
2711  ThrowPPException;
2712}
2713
2714void Magick::Image::equalize(void)
2715{
2716  modifyImage();
2717  GetPPException;
2718  EqualizeImage(image(),&exceptionInfo);
2719  ThrowPPException;
2720}
2721
2722void Magick::Image::erase(void)
2723{
2724  modifyImage();
2725  GetPPException;
2726  SetImageBackgroundColor(image(),&exceptionInfo);
2727  ThrowPPException;
2728}
2729
2730void Magick::Image::extent(const Geometry &geometry_ )
2731{
2732  MagickCore::Image
2733    *newImage;
2734
2735  RectangleInfo
2736    extentInfo=geometry_;
2737
2738  modifyImage();
2739  extentInfo.x=geometry_.xOff();
2740  extentInfo.y=geometry_.yOff();
2741  GetPPException;
2742  newImage=ExtentImage(image(),&extentInfo,&exceptionInfo);
2743  replaceImage(newImage);
2744  ThrowPPException;
2745}
2746
2747void Magick::Image::extent(const Geometry &geometry_,
2748  const Color &backgroundColor_)
2749{
2750  backgroundColor(backgroundColor_);
2751  extent(geometry_);
2752}
2753
2754void Magick::Image::extent(const Geometry &geometry_,
2755  const Color &backgroundColor_,const GravityType gravity_)
2756{
2757  backgroundColor(backgroundColor_);
2758  extent(geometry_,gravity_);
2759}
2760
2761void Magick::Image::extent(const Geometry &geometry_,
2762  const GravityType gravity_)
2763{
2764  RectangleInfo
2765    geometry;
2766
2767  SetGeometry(image(),&geometry);
2768  geometry.width=geometry_.width();
2769  geometry.height=geometry_.height();
2770  GravityAdjustGeometry(image()->columns,image()->rows,gravity_,&geometry);
2771  extent(geometry);
2772}
2773
2774void Magick::Image::flip(void)
2775{
2776  MagickCore::Image
2777    *newImage;
2778
2779  GetPPException;
2780  newImage=FlipImage(constImage(),&exceptionInfo);
2781  replaceImage(newImage);
2782  ThrowPPException;
2783}
2784
2785void Magick::Image::floodFillAlpha(const ssize_t x_,const ssize_t y_,
2786  const unsigned int alpha_,const PaintMethod method_)
2787{
2788  PixelInfo
2789    pixel,
2790    target;
2791
2792  modifyImage();
2793  GetPixelInfo(image(),&target);
2794  pixel=static_cast<PixelInfo>(pixelColor(x_,y_));
2795  target.red=pixel.red;
2796  target.green=pixel.green;
2797  target.blue=pixel.blue;
2798  target.alpha=alpha_;
2799
2800  GetPPException;
2801  FloodfillPaintImage(image(),options()->drawInfo(),&target,
2802    static_cast<ssize_t>(x_), static_cast<ssize_t>(y_),
2803    method_  == FloodfillMethod ? MagickFalse : MagickTrue,&exceptionInfo);
2804  ThrowPPException;
2805}
2806
2807void Magick::Image::floodFillColor(const Geometry &point_,
2808  const Magick::Color &fillColor_)
2809{
2810  floodFillTexture(point_,Image(Geometry(1,1),fillColor_));
2811}
2812
2813void Magick::Image::floodFillColor(const ssize_t x_,const ssize_t y_,
2814  const Magick::Color &fillColor_)
2815{
2816  floodFillTexture(x_,y_,Image(Geometry(1,1),fillColor_));
2817}
2818
2819void Magick::Image::floodFillColor(const Geometry &point_,
2820  const Magick::Color &fillColor_,const Magick::Color &borderColor_)
2821{
2822  floodFillTexture(point_,Image(Geometry(1,1),fillColor_),borderColor_);
2823}
2824
2825void Magick::Image::floodFillColor(const ssize_t x_,const ssize_t y_,
2826  const Magick::Color &fillColor_,const Magick::Color &borderColor_)
2827{
2828  floodFillTexture(x_,y_,Image(Geometry(1,1),fillColor_),borderColor_);
2829}
2830
2831void Magick::Image::floodFillTexture(const Magick::Geometry &point_,
2832  const Magick::Image &texture_)
2833{
2834  floodFillTexture(point_.xOff(),point_.yOff(),texture_);
2835}
2836
2837void Magick::Image::floodFillTexture(const ssize_t x_,const ssize_t y_,
2838  const Magick::Image &texture_)
2839{
2840  MagickCore::Image
2841    *fillPattern;
2842
2843  Quantum
2844    *p;
2845
2846  modifyImage();
2847
2848  // Set drawing fill pattern
2849  fillPattern=(MagickCore::Image *)NULL;
2850  if (options()->fillPattern() != (MagickCore::Image *)NULL)
2851    {
2852      GetPPException;
2853      fillPattern=CloneImage(options()->fillPattern(),0,0,MagickTrue,
2854        &exceptionInfo);
2855      ThrowPPException;
2856    }
2857  options()->fillPattern(texture_.constImage());
2858
2859  // Get pixel view
2860  Pixels pixels(*this);
2861  // Fill image
2862  p=pixels.get(x_,y_,1,1);
2863
2864  if (p)
2865    {
2866      PixelInfo
2867        target;
2868
2869      GetPixelInfo(constImage(),&target);
2870      target.red=GetPixelRed(constImage(),p);
2871      target.green=GetPixelGreen(constImage(),p);
2872      target.blue=GetPixelBlue(constImage(),p);
2873      GetPPException;
2874      FloodfillPaintImage(image(),options()->drawInfo(),&target,
2875        static_cast<ssize_t>(x_),static_cast<ssize_t>(y_),MagickFalse,
2876        &exceptionInfo);
2877      options()->fillPattern(fillPattern);
2878      ThrowPPException;
2879    }
2880  else
2881    options()->fillPattern(fillPattern);
2882}
2883
2884void Magick::Image::floodFillTexture(const Magick::Geometry &point_,
2885  const Magick::Image &texture_,const Magick::Color &borderColor_)
2886{
2887  floodFillTexture(point_.xOff(),point_.yOff(),texture_,borderColor_);
2888}
2889
2890void Magick::Image::floodFillTexture(const ssize_t x_,const ssize_t y_,
2891  const Magick::Image &texture_,const Magick::Color &borderColor_)
2892{
2893  MagickCore::Image
2894    *fillPattern;
2895
2896  PixelInfo
2897    target;
2898
2899  modifyImage();
2900
2901  // Set drawing fill pattern
2902  fillPattern=(MagickCore::Image *)NULL;
2903  if (options()->fillPattern() != (MagickCore::Image *)NULL)
2904    {
2905      GetPPException;
2906      fillPattern=CloneImage(options()->fillPattern(),0,0,MagickTrue,
2907        &exceptionInfo);
2908      ThrowPPException;
2909    }
2910  options()->fillPattern(texture_.constImage());
2911
2912  GetPixelInfo(constImage(),&target);
2913  target.red=static_cast<PixelInfo>(borderColor_).red;
2914  target.green=static_cast<PixelInfo>(borderColor_).green;
2915  target.blue=static_cast<PixelInfo>(borderColor_).blue;
2916  GetPPException;
2917  FloodfillPaintImage(image(),options()->drawInfo(),&target,
2918    static_cast<ssize_t>(x_),static_cast<ssize_t>(y_),MagickTrue,
2919    &exceptionInfo);
2920  options()->fillPattern(fillPattern);
2921  ThrowPPException;
2922}
2923
2924void Magick::Image::flop(void)
2925{
2926  MagickCore::Image
2927    *newImage;
2928
2929  GetPPException;
2930  newImage=FlopImage(constImage(),&exceptionInfo);
2931  replaceImage(newImage);
2932  ThrowPPException;
2933}
2934
2935void Magick::Image::fontTypeMetrics(const std::string &text_,
2936  TypeMetric *metrics)
2937{
2938  DrawInfo
2939    *drawInfo;
2940
2941  drawInfo=options()->drawInfo();
2942  drawInfo->text=const_cast<char *>(text_.c_str());
2943  GetPPException;
2944  GetTypeMetrics(image(),drawInfo,&(metrics->_typeMetric),&exceptionInfo);
2945  drawInfo->text=0;
2946  ThrowPPException;
2947}
2948
2949void Magick::Image::fontTypeMetricsMultiline(const std::string &text_,
2950  TypeMetric *metrics)
2951{
2952  DrawInfo
2953    *drawInfo;
2954
2955  drawInfo=options()->drawInfo();
2956  drawInfo->text=const_cast<char *>(text_.c_str());
2957  GetPPException;
2958  GetMultilineTypeMetrics(image(),drawInfo,&(metrics->_typeMetric),&exceptionInfo);
2959  drawInfo->text=0;
2960  ThrowPPException;
2961}
2962
2963void Magick::Image::frame(const Geometry &geometry_)
2964{
2965  FrameInfo
2966    info;
2967
2968  MagickCore::Image
2969    *newImage;
2970
2971  info.x=static_cast<ssize_t>(geometry_.width());
2972  info.y=static_cast<ssize_t>(geometry_.height());
2973  info.width=columns() + (static_cast<size_t>(info.x) << 1);
2974  info.height=rows() + (static_cast<size_t>(info.y) << 1);
2975  info.outer_bevel=geometry_.xOff();
2976  info.inner_bevel=geometry_.yOff();
2977
2978  GetPPException;
2979  newImage=FrameImage(constImage(),&info,image()->compose,&exceptionInfo);
2980  replaceImage(newImage);
2981  ThrowPPException;
2982}
2983
2984void Magick::Image::frame(const size_t width_,const size_t height_,
2985  const ssize_t outerBevel_,const ssize_t innerBevel_)
2986{
2987  FrameInfo
2988    info;
2989
2990  MagickCore::Image
2991    *newImage;
2992
2993  info.x=static_cast<ssize_t>(width_);
2994  info.y=static_cast<ssize_t>(height_);
2995  info.width=columns() + (static_cast<size_t>(info.x) << 1);
2996  info.height=rows() + (static_cast<size_t>(info.y) << 1);
2997  info.outer_bevel=static_cast<ssize_t>(outerBevel_);
2998  info.inner_bevel=static_cast<ssize_t>(innerBevel_);
2999
3000  GetPPException;
3001  newImage=FrameImage(constImage(),&info,image()->compose,&exceptionInfo);
3002  replaceImage(newImage);
3003  ThrowPPException;
3004}
3005
3006void Magick::Image::fx(const std::string expression_)
3007{
3008  MagickCore::Image
3009    *newImage;
3010
3011  GetPPException;
3012  newImage=FxImage(constImage(),expression_.c_str(),&exceptionInfo);
3013  replaceImage(newImage);
3014  ThrowPPException;
3015}
3016
3017void Magick::Image::fx(const std::string expression_,
3018  const Magick::ChannelType channel_)
3019{
3020  MagickCore::Image
3021    *newImage;
3022
3023  GetPPException;
3024  SetPPChannelMask(channel_);
3025  newImage=FxImage(constImage(),expression_.c_str(),&exceptionInfo);
3026  RestorePPChannelMask;
3027  replaceImage(newImage);
3028  ThrowPPException;
3029}
3030
3031void Magick::Image::gamma(const double gamma_)
3032{
3033  modifyImage();
3034  GetPPException;
3035  GammaImage(image(),gamma_,&exceptionInfo);
3036  ThrowPPException;
3037}
3038
3039void Magick::Image::gamma(const double gammaRed_,const double gammaGreen_,
3040  const double gammaBlue_)
3041{
3042  char
3043    gamma[MaxTextExtent + 1];
3044
3045  FormatLocaleString(gamma,MaxTextExtent,"%3.6f/%3.6f/%3.6f/",gammaRed_,
3046    gammaGreen_,gammaBlue_);
3047
3048  modifyImage();
3049  GetPPException;
3050  GammaImage(image(),atof(gamma),&exceptionInfo);
3051  ThrowPPException;
3052}
3053
3054void Magick::Image::gaussianBlur(const double width_,const double sigma_)
3055{
3056  MagickCore::Image
3057    *newImage;
3058
3059  GetPPException;
3060  newImage=GaussianBlurImage(constImage(),width_,sigma_,&exceptionInfo);
3061  replaceImage(newImage);
3062  ThrowPPException;
3063}
3064
3065void Magick::Image::gaussianBlurChannel(const ChannelType channel_,
3066  const double width_,const double sigma_)
3067{
3068  MagickCore::Image
3069    *newImage;
3070
3071  GetPPException;
3072  SetPPChannelMask(channel_);
3073  newImage=GaussianBlurImage(constImage(),width_,sigma_,&exceptionInfo);
3074  RestorePPChannelMask;
3075  replaceImage(newImage);
3076  ThrowPPException;
3077}
3078
3079const Magick::Quantum *Magick::Image::getConstPixels(const ssize_t x_,
3080  const ssize_t y_,const size_t columns_,const size_t rows_) const
3081{
3082  const Quantum
3083    *p;
3084
3085  GetPPException;
3086  p=(*GetVirtualPixels)(constImage(),x_, y_,columns_, rows_,&exceptionInfo);
3087  ThrowPPException;
3088  return(p);
3089}
3090
3091const void *Magick::Image::getConstMetacontent(void) const
3092{
3093  const void
3094    *result;
3095
3096  result=GetVirtualMetacontent(constImage());
3097
3098  if(!result)
3099    throwExceptionExplicit(OptionError,"Unable to retrieve meta content.");
3100
3101  return(result);
3102}
3103
3104void *Magick::Image::getMetacontent(void )
3105{
3106  void
3107    *result;
3108
3109  result=GetAuthenticMetacontent(image());
3110
3111  if(!result)
3112    throwExceptionExplicit(OptionError,"Unable to retrieve meta content.");
3113
3114  return(result);
3115}
3116
3117Magick::Quantum *Magick::Image::getPixels(const ssize_t x_,const ssize_t y_,
3118  const size_t columns_,const size_t rows_)
3119{
3120  Quantum
3121    *result;
3122
3123  modifyImage();
3124  GetPPException;
3125  result=(*GetAuthenticPixels)(image(),x_, y_,columns_,rows_,&exceptionInfo);
3126  ThrowPPException;
3127
3128  return(result);
3129}
3130
3131void  Magick::Image::haldClut(const Image &clutImage_)
3132{
3133  modifyImage();
3134  GetPPException;
3135  (void) HaldClutImage(image(),clutImage_.constImage(),&exceptionInfo);
3136  ThrowPPException;
3137}
3138
3139void Magick::Image::implode(const double factor_)
3140{
3141  MagickCore::Image
3142    *newImage;
3143
3144  GetPPException;
3145  newImage=ImplodeImage(constImage(),factor_,image()->interpolate,
3146    &exceptionInfo);
3147  replaceImage(newImage);
3148  ThrowPPException;
3149}
3150
3151void Magick::Image::inverseFourierTransform(const Image &phase_)
3152{
3153  inverseFourierTransform(phase_,true);
3154}
3155
3156void Magick::Image::inverseFourierTransform(const Image &phase_,
3157  const bool magnitude_)
3158{
3159  MagickCore::Image
3160    *newImage;
3161
3162  GetPPException;
3163  newImage=InverseFourierTransformImage(constImage(),phase_.constImage(),
3164    magnitude_ == true ? MagickTrue : MagickFalse,&exceptionInfo);
3165  replaceImage(newImage);
3166  ThrowPPException;
3167}
3168
3169void Magick::Image::level(const double blackPoint_,const double whitePoint_,
3170  const double gamma_)
3171{
3172  modifyImage();
3173  GetPPException;
3174  (void) LevelImage(image(),blackPoint_,whitePoint_,gamma_,&exceptionInfo);
3175  ThrowPPException;
3176}
3177
3178void Magick::Image::levelChannel(const ChannelType channel_,
3179  const double blackPoint_,const double whitePoint_,const double gamma_)
3180{
3181  modifyImage();
3182  GetPPException;
3183  SetPPChannelMask(channel_);
3184  (void) LevelImage(image(),blackPoint_,whitePoint_,gamma_,&exceptionInfo);
3185  RestorePPChannelMask;
3186  ThrowPPException;
3187}
3188
3189void Magick::Image::levelColors(const Color &blackColor_,
3190  const Color &whiteColor_,const bool invert_)
3191{
3192  PixelInfo
3193    black,
3194    pixel,
3195    white;
3196
3197  modifyImage();
3198
3199  GetPixelInfo(image(),&black);
3200  pixel=static_cast<PixelInfo>(blackColor_);
3201  black.red=pixel.red;
3202  black.green=pixel.green;
3203  black.blue=pixel.blue;
3204  black.alpha=pixel.alpha;
3205
3206  GetPixelInfo(image(),&white);
3207  pixel=static_cast<PixelInfo>(whiteColor_);
3208  white.red=pixel.red;
3209  white.green=pixel.green;
3210  white.blue=pixel.blue;
3211  white.alpha=pixel.alpha;
3212
3213  GetPPException;
3214  (void) LevelImageColors(image(),&black,&white,invert_ == true ?
3215    MagickTrue : MagickFalse,&exceptionInfo);
3216  ThrowPPException;
3217}
3218
3219void Magick::Image::levelColorsChannel(const ChannelType channel_,
3220  const Color &blackColor_,const Color &whiteColor_,const bool invert_)
3221{
3222  PixelInfo
3223    black,
3224    pixel,
3225    white;
3226
3227  modifyImage();
3228
3229  GetPixelInfo(image(),&black);
3230  pixel=static_cast<PixelInfo>(blackColor_);
3231  black.red=pixel.red;
3232  black.green=pixel.green;
3233  black.blue=pixel.blue;
3234  black.alpha=pixel.alpha;
3235
3236  GetPixelInfo(image(),&white);
3237  pixel=static_cast<PixelInfo>(whiteColor_);
3238  white.red=pixel.red;
3239  white.green=pixel.green;
3240  white.blue=pixel.blue;
3241  white.alpha=pixel.alpha;
3242
3243  GetPPException;
3244  SetPPChannelMask(channel_);
3245  (void) LevelImageColors(image(),&black,&white,invert_ == true ?
3246    MagickTrue : MagickFalse,&exceptionInfo);
3247  RestorePPChannelMask;
3248  ThrowPPException;
3249}
3250
3251void Magick::Image::linearStretch(const double blackPoint_,
3252  const double whitePoint_)
3253{
3254  modifyImage();
3255  GetPPException;
3256  LinearStretchImage(image(),blackPoint_,whitePoint_,&exceptionInfo);
3257  ThrowPPException;
3258}
3259
3260void Magick::Image::liquidRescale(const Geometry &geometry_)
3261{
3262  MagickCore::Image
3263    *newImage;
3264
3265  size_t
3266    height=rows(),
3267    width=columns();
3268
3269  ssize_t
3270    x=0,
3271    y=0;
3272
3273  ParseMetaGeometry(static_cast<std::string>(geometry_).c_str(),&x,&y,&width,
3274    &height);
3275
3276  GetPPException;
3277  newImage=LiquidRescaleImage(image(),width,height,x,y,&exceptionInfo);
3278  replaceImage(newImage);
3279  ThrowPPException;
3280}
3281
3282void Magick::Image::magnify(void)
3283{
3284  MagickCore::Image
3285    *newImage;
3286
3287  GetPPException;
3288  newImage=MagnifyImage(constImage(),&exceptionInfo);
3289  replaceImage(newImage);
3290  ThrowPPException;
3291}
3292
3293void Magick::Image::map(const Image &mapImage_,const bool dither_)
3294{
3295  modifyImage();
3296  GetPPException;
3297  options()->quantizeDither(dither_);
3298  RemapImage(options()->quantizeInfo(),image(),mapImage_.constImage(),
3299    &exceptionInfo);
3300  ThrowPPException;
3301}
3302
3303void Magick::Image::medianFilter(const double radius_)
3304{
3305  MagickCore::Image
3306    *newImage;
3307
3308  GetPPException;
3309  newImage=StatisticImage(image(),MedianStatistic,(size_t) radius_,
3310    (size_t) radius_,&exceptionInfo);
3311  replaceImage(newImage);
3312  ThrowPPException;
3313}
3314
3315void Magick::Image::minify(void)
3316{
3317  MagickCore::Image
3318    *newImage;
3319
3320  GetPPException;
3321  newImage=MinifyImage(constImage(),&exceptionInfo);
3322  replaceImage(newImage);
3323  ThrowPPException;
3324}
3325
3326void Magick::Image::modulate(const double brightness_,const double saturation_,
3327  const double hue_)
3328{
3329  char
3330    modulate[MaxTextExtent + 1];
3331
3332  FormatLocaleString(modulate,MaxTextExtent,"%3.6f,%3.6f,%3.6f",brightness_,
3333    saturation_,hue_);
3334
3335  modifyImage();
3336  GetPPException;
3337  ModulateImage(image(),modulate,&exceptionInfo);
3338  ThrowPPException;
3339}
3340
3341void Magick::Image::motionBlur(const double radius_,const double sigma_,
3342  const double angle_)
3343{
3344  MagickCore::Image
3345    *newImage;
3346
3347  GetPPException;
3348  newImage=MotionBlurImage(constImage(),radius_,sigma_,angle_,&exceptionInfo);
3349  replaceImage(newImage);
3350  ThrowPPException;
3351}
3352
3353void Magick::Image::negate(const bool grayscale_)
3354{
3355  modifyImage();
3356  GetPPException;
3357  NegateImage(image(),(MagickBooleanType) grayscale_,&exceptionInfo);
3358  ThrowPPException;
3359}
3360
3361void Magick::Image::negateChannel(const ChannelType channel_,
3362  const bool grayscale_)
3363{
3364  modifyImage();
3365  GetPPException;
3366  SetPPChannelMask(channel_);
3367  NegateImage(image(),(MagickBooleanType) grayscale_,&exceptionInfo);
3368  RestorePPChannelMask;
3369  ThrowPPException;
3370}
3371
3372void Magick::Image::normalize(void)
3373{
3374  modifyImage();
3375  GetPPException;
3376  NormalizeImage(image(),&exceptionInfo);
3377  ThrowPPException;
3378}
3379
3380void Magick::Image::oilPaint(const double radius_,const double sigma_)
3381{
3382  MagickCore::Image
3383    *newImage;
3384
3385  GetPPException;
3386  newImage=OilPaintImage(constImage(),radius_,sigma_,&exceptionInfo);
3387  replaceImage(newImage);
3388  ThrowPPException;
3389}
3390
3391void Magick::Image::opaque(const Color &opaqueColor_,const Color &penColor_)
3392{
3393  std::string
3394    opaqueColor,
3395    penColor;
3396
3397  PixelInfo
3398    opaque,
3399    pen;
3400
3401  if (!opaqueColor_.isValid())
3402    throwExceptionExplicit(OptionError,"Opaque color argument is invalid");
3403
3404  if (!penColor_.isValid())
3405    throwExceptionExplicit(OptionError,"Pen color argument is invalid");
3406
3407  modifyImage();
3408  opaqueColor=opaqueColor_;
3409  penColor=penColor_;
3410
3411  GetPPException;
3412  (void) QueryColorCompliance(opaqueColor.c_str(),AllCompliance,&opaque,
3413    &exceptionInfo);
3414  (void) QueryColorCompliance(penColor.c_str(),AllCompliance,&pen,
3415    &exceptionInfo);
3416  OpaquePaintImage(image(),&opaque,&pen,MagickFalse,&exceptionInfo);
3417  ThrowPPException;
3418}
3419
3420void Magick::Image::perceptible(const double epsilon_)
3421{
3422  modifyImage();
3423  GetPPException;
3424  PerceptibleImage(image(),epsilon_,&exceptionInfo);
3425  ThrowPPException;
3426}
3427
3428void Magick::Image::perceptibleChannel(const ChannelType channel_,
3429  const double epsilon_)
3430{
3431  modifyImage();
3432  GetPPException;
3433  SetPPChannelMask(channel_);
3434  PerceptibleImage(image(),epsilon_,&exceptionInfo);
3435  RestorePPChannelMask;
3436  ThrowPPException;
3437}
3438
3439void Magick::Image::ping(const std::string &imageSpec_)
3440{
3441  MagickCore::Image
3442    *newImage;
3443
3444  GetPPException;
3445  options()->fileName(imageSpec_);
3446  newImage=PingImage(imageInfo(),&exceptionInfo);
3447  replaceImage(newImage);
3448  ThrowPPException;
3449}
3450
3451void Magick::Image::ping(const Blob& blob_)
3452{
3453  MagickCore::Image
3454    *newImage;
3455
3456  GetPPException;
3457  newImage=PingBlob(imageInfo(),blob_.data(),blob_.length(),&exceptionInfo);
3458  replaceImage(newImage);
3459  ThrowPPException;
3460}
3461
3462void Magick::Image::pixelColor(const ssize_t x_,const ssize_t y_,
3463  const Color &color_)
3464{
3465  PixelInfo
3466    packet;
3467
3468  Quantum
3469    *pixel;
3470
3471  // Test arguments to ensure they are within the image.
3472  if (y_ > (ssize_t) rows() || x_ > (ssize_t) columns())
3473    throwExceptionExplicit(OptionError,"Access outside of image boundary");
3474
3475  modifyImage();
3476
3477  // Set image to DirectClass
3478  classType(DirectClass );
3479
3480  // Get pixel view
3481  Pixels pixels(*this);
3482    // Set pixel value
3483  pixel=pixels.get(x_, y_, 1, 1 );
3484  packet=color_;
3485  MagickCore::SetPixelInfoPixel(constImage(),&packet,pixel);
3486  // Tell ImageMagick that pixels have been updated
3487  pixels.sync();
3488}
3489
3490Magick::Color Magick::Image::pixelColor(const ssize_t x_,
3491  const ssize_t y_) const
3492{
3493  const Quantum
3494    *pixel;
3495
3496  pixel=getConstPixels(x_,y_,1,1);
3497  if (pixel)
3498    {
3499      PixelInfo
3500        packet;
3501
3502      MagickCore::GetPixelInfoPixel(constImage(),pixel,&packet);
3503      return(Color(packet));
3504    }
3505
3506  return(Color()); // invalid
3507}
3508
3509void Magick::Image::polaroid(const std::string &caption_,const double angle_,
3510  const PixelInterpolateMethod method_)
3511{
3512  MagickCore::Image
3513    *newImage;
3514
3515  GetPPException;
3516  newImage=PolaroidImage(constImage(),options()->drawInfo(),caption_.c_str(),
3517    angle_,method_,&exceptionInfo);
3518  replaceImage(newImage);
3519  ThrowPPException;
3520}
3521
3522void Magick::Image::posterize(const size_t levels_,const DitherMethod method_)
3523{
3524  modifyImage();
3525  GetPPException;
3526  PosterizeImage(image(),levels_,method_,&exceptionInfo);
3527  ThrowPPException;
3528}
3529
3530void Magick::Image::posterizeChannel(const ChannelType channel_,
3531  const size_t levels_,const DitherMethod method_)
3532{
3533  modifyImage();
3534  GetPPException;
3535  SetPPChannelMask(channel_);
3536  PosterizeImage(image(),levels_,method_,&exceptionInfo);
3537  RestorePPChannelMask;
3538  ThrowPPException;
3539}
3540
3541void Magick::Image::process(std::string name_,const ssize_t argc,
3542  const char **argv)
3543{
3544  modifyImage();
3545
3546  GetPPException;
3547  (void) InvokeDynamicImageFilter(name_.c_str(),&image(),argc,argv,
3548      &exceptionInfo);
3549  ThrowPPException;
3550}
3551
3552void Magick::Image::profile(const std::string name_,
3553  const Magick::Blob &profile_)
3554{
3555  modifyImage();
3556  GetPPException;
3557  (void) ProfileImage(image(),name_.c_str(),(unsigned char *)profile_.data(),
3558    profile_.length(),&exceptionInfo);
3559  ThrowPPException;
3560}
3561
3562Magick::Blob Magick::Image::profile(const std::string name_) const
3563{
3564  const StringInfo
3565    *profile;
3566
3567  profile=GetImageProfile(constImage(),name_.c_str());
3568
3569  if (profile == (StringInfo *) NULL)
3570    return(Blob());
3571  return(Blob((void*) GetStringInfoDatum(profile),GetStringInfoLength(
3572    profile)));
3573}
3574
3575void Magick::Image::quantize(const bool measureError_)
3576{
3577  modifyImage();
3578
3579  if (measureError_)
3580    options()->quantizeInfo()->measure_error=MagickTrue;
3581  else
3582    options()->quantizeInfo()->measure_error=MagickFalse;
3583
3584  GetPPException;
3585  QuantizeImage(options()->quantizeInfo(),image(),&exceptionInfo);
3586  ThrowPPException;
3587}
3588
3589void Magick::Image::quantumOperator(const ChannelType channel_,
3590  const MagickEvaluateOperator operator_,double rvalue_)
3591{
3592  GetPPException;
3593  SetPPChannelMask(channel_);
3594  EvaluateImage(image(),operator_,rvalue_,&exceptionInfo);
3595  RestorePPChannelMask;
3596  ThrowPPException;
3597}
3598
3599void Magick::Image::quantumOperator(const ssize_t x_,const ssize_t y_,
3600  const size_t columns_,const size_t rows_,const ChannelType channel_,
3601  const MagickEvaluateOperator operator_,const double rvalue_)
3602{
3603  RectangleInfo
3604    geometry;
3605
3606  MagickCore::Image
3607    *cropImage;
3608
3609  geometry.width = columns_;
3610  geometry.height = rows_;
3611  geometry.x = x_;
3612  geometry.y = y_;
3613
3614  GetPPException;
3615  cropImage=CropImage(image(),&geometry,&exceptionInfo);
3616  SetPPChannelMask(channel_);
3617  EvaluateImage(cropImage,operator_,rvalue_,&exceptionInfo);
3618  RestorePPChannelMask;
3619  (void) CompositeImage(image(),cropImage,image()->alpha_trait ==
3620    BlendPixelTrait ? OverCompositeOp : CopyCompositeOp,MagickFalse,
3621    geometry.x,geometry.y,&exceptionInfo );
3622  cropImage=DestroyImageList(cropImage);
3623  ThrowPPException;
3624}
3625
3626void Magick::Image::raise(const Geometry &geometry_,const bool raisedFlag_)
3627{
3628  RectangleInfo
3629    raiseInfo=geometry_;
3630
3631  GetPPException;
3632  modifyImage();
3633  RaiseImage(image(),&raiseInfo,raisedFlag_ == true ? MagickTrue : MagickFalse,
3634    &exceptionInfo);
3635  ThrowPPException;
3636}
3637
3638void Magick::Image::randomThreshold(const Geometry &thresholds_)
3639{
3640  GetPPException;
3641  (void) RandomThresholdImage(image(),static_cast<std::string>(
3642    thresholds_).c_str(),&exceptionInfo);
3643  ThrowPPException;
3644}
3645
3646void Magick::Image::randomThresholdChannel(const ChannelType channel_,
3647  const Geometry &thresholds_)
3648{
3649  modifyImage();
3650  GetPPException;
3651  SetPPChannelMask(channel_);
3652  (void) RandomThresholdImage(image(),static_cast<std::string>(
3653    thresholds_).c_str(),&exceptionInfo);
3654  RestorePPChannelMask;
3655  ThrowPPException;
3656}
3657
3658void Magick::Image::read(const Blob &blob_)
3659{
3660  MagickCore::Image
3661    *newImage;
3662
3663  GetPPException;
3664  newImage=BlobToImage(imageInfo(),static_cast<const void *>(blob_.data()),
3665    blob_.length(),&exceptionInfo);
3666  replaceImage(newImage);
3667  ThrowPPException;
3668}
3669
3670void Magick::Image::read(const Blob &blob_,const Geometry &size_)
3671{
3672  size(size_);
3673  read(blob_);
3674}
3675
3676void Magick::Image::read(const Blob &blob_,const Geometry &size_,
3677  const size_t depth_)
3678{
3679  size(size_);
3680  depth(depth_);
3681  read(blob_);
3682}
3683
3684void Magick::Image::read(const Blob &blob_,const Geometry &size_,
3685  const size_t depth_,const std::string &magick_)
3686{
3687  size(size_);
3688  depth(depth_);
3689  magick(magick_);
3690  // Set explicit image format
3691  fileName(magick_ + ':');
3692  read(blob_);
3693}
3694
3695void Magick::Image::read(const Blob &blob_,const Geometry &size_,
3696  const std::string &magick_)
3697{
3698  size(size_);
3699  magick(magick_);
3700  // Set explicit image format
3701  fileName(magick_ + ':');
3702  read(blob_);
3703}
3704
3705void Magick::Image::read(const Geometry &size_,const std::string &imageSpec_)
3706{
3707  size(size_);
3708  read(imageSpec_);
3709}
3710
3711void Magick::Image::read(const size_t width_,const size_t height_,
3712  const std::string &map_,const StorageType type_,const void *pixels_)
3713{
3714  MagickCore::Image
3715    *newImage;
3716
3717  GetPPException;
3718  newImage=ConstituteImage(width_,height_,map_.c_str(),type_, pixels_,
3719    &exceptionInfo);
3720  replaceImage(newImage);
3721  ThrowPPException;
3722}
3723
3724void Magick::Image::read(const std::string &imageSpec_)
3725{
3726  MagickCore::Image
3727    *newImage;
3728
3729  GetPPException;
3730  options()->fileName(imageSpec_);
3731  newImage=ReadImage(imageInfo(),&exceptionInfo);
3732
3733  // Ensure that multiple image frames were not read.
3734  if (newImage && newImage->next)
3735    {
3736      MagickCore::Image
3737         *next;
3738
3739      // Destroy any extra image frames
3740      next=newImage->next;
3741      newImage->next=0;
3742      next->previous=0;
3743      DestroyImageList(next);
3744    }
3745  replaceImage(newImage);
3746  ThrowPPException;
3747}
3748
3749void Magick::Image::readPixels(const Magick::QuantumType quantum_,
3750  const unsigned char *source_)
3751{
3752  QuantumInfo
3753    *quantum_info;
3754
3755  quantum_info=AcquireQuantumInfo(imageInfo(),image());
3756  GetPPException;
3757  ImportQuantumPixels(image(),(MagickCore::CacheView *) NULL,quantum_info,
3758    quantum_,source_,&exceptionInfo);
3759  quantum_info=DestroyQuantumInfo(quantum_info);
3760  ThrowPPException;
3761}
3762
3763void Magick::Image::reduceNoise(void)
3764{
3765  reduceNoise(3.0);
3766}
3767
3768void Magick::Image::reduceNoise(const double order_)
3769{
3770  MagickCore::Image
3771    *newImage;
3772
3773  GetPPException;
3774  newImage=StatisticImage(constImage(),NonpeakStatistic,(size_t) order_,
3775    (size_t) order_,&exceptionInfo);
3776  replaceImage(newImage);
3777  ThrowPPException;
3778}
3779
3780void Magick::Image::resample(const Geometry &geometry_)
3781{
3782  MagickCore::Image
3783    *newImage;
3784
3785  size_t
3786    height=rows(),
3787    width=columns();
3788
3789  ssize_t
3790    x=0,
3791    y=0;
3792
3793  // Calculate new size.  This code should be supported using binary arguments
3794  // in the ImageMagick library.
3795  ParseMetaGeometry(static_cast<std::string>(geometry_).c_str(),&x,&y,&width,
3796    &height);
3797
3798  GetPPException;
3799  newImage=ResampleImage(constImage(),width,height,image()->filter,
3800    &exceptionInfo);
3801  replaceImage(newImage);
3802  ThrowPPException;
3803}
3804
3805void Magick::Image::resize(const Geometry &geometry_)
3806{
3807  MagickCore::Image
3808    *newImage;
3809
3810  size_t
3811    height=rows(),
3812    width=columns();
3813
3814  ssize_t
3815    x=0,
3816    y=0;
3817
3818  // Calculate new size.  This code should be supported using binary arguments
3819  // in the ImageMagick library.
3820  ParseMetaGeometry(static_cast<std::string>(geometry_).c_str(),&x,&y,&width,
3821    &height);
3822
3823  GetPPException;
3824  newImage=ResizeImage(constImage(),width,height,image()->filter,
3825    &exceptionInfo);
3826  replaceImage(newImage);
3827  ThrowPPException;
3828}
3829
3830void Magick::Image::roll(const Geometry &roll_)
3831{
3832  MagickCore::Image
3833    *newImage;
3834
3835  ssize_t
3836    xOff=roll_.xOff(),
3837    yOff=roll_.yOff();
3838
3839  if (roll_.xNegative())
3840    xOff = 0 - xOff;
3841  if (roll_.yNegative())
3842    yOff = 0 - yOff;
3843
3844  GetPPException;
3845  newImage=RollImage(constImage(),xOff,yOff,&exceptionInfo);
3846  replaceImage(newImage);
3847  ThrowPPException;
3848}
3849
3850void Magick::Image::roll(const size_t columns_,const size_t rows_)
3851{
3852  MagickCore::Image
3853    *newImage;
3854
3855  GetPPException;
3856  newImage=RollImage(constImage(),static_cast<ssize_t>(columns_),
3857    static_cast<ssize_t>(rows_),&exceptionInfo);
3858  replaceImage(newImage);
3859  ThrowPPException;
3860}
3861
3862void Magick::Image::rotate(const double degrees_)
3863{
3864  MagickCore::Image
3865    *newImage;
3866
3867  GetPPException;
3868  newImage=RotateImage(constImage(),degrees_,&exceptionInfo);
3869  replaceImage(newImage);
3870  ThrowPPException;
3871}
3872
3873void Magick::Image::sample(const Geometry &geometry_)
3874{
3875  MagickCore::Image
3876    *newImage;
3877
3878  size_t
3879    height=rows(),
3880    width=columns();
3881
3882  ssize_t
3883    x=0,
3884    y=0;
3885
3886  ParseMetaGeometry(static_cast<std::string>(geometry_).c_str(),&x,&y,&width,
3887    &height);
3888
3889  GetPPException;
3890  newImage=SampleImage(constImage(),width,height,&exceptionInfo);
3891  replaceImage(newImage);
3892  ThrowPPException;
3893}
3894
3895Magick::Quantum *Magick::Image::setPixels(const ssize_t x_,const ssize_t y_,
3896  const size_t columns_,const size_t rows_)
3897{
3898  Quantum
3899    *result;
3900
3901  modifyImage();
3902  GetPPException;
3903  result=(*QueueAuthenticPixels)(image(),x_,y_,columns_,rows_,&exceptionInfo);
3904  ThrowPPException;
3905  return(result);
3906}
3907
3908void Magick::Image::scale(const Geometry &geometry_)
3909{
3910  MagickCore::Image
3911    *newImage;
3912
3913  size_t
3914    height=rows(),
3915    width=columns();
3916
3917  ssize_t
3918    x=0,
3919    y=0;
3920
3921  ParseMetaGeometry(static_cast<std::string>(geometry_).c_str(),&x,&y,&width,
3922    &height);
3923
3924  GetPPException;
3925  newImage=ScaleImage(constImage(),width,height,&exceptionInfo);
3926  replaceImage(newImage);
3927  ThrowPPException;
3928}
3929
3930void Magick::Image::segment(const double clusterThreshold_,
3931  const double smoothingThreshold_)
3932{
3933  modifyImage();
3934  GetPPException;
3935  SegmentImage(image(),options()->quantizeColorSpace(),
3936    (MagickBooleanType) options()->verbose(),clusterThreshold_,
3937    smoothingThreshold_,&exceptionInfo);
3938  SyncImage(image(),&exceptionInfo);
3939  ThrowPPException;
3940}
3941
3942void Magick::Image::shade(const double azimuth_,const double elevation_,
3943  const bool colorShading_)
3944{
3945  MagickCore::Image
3946    *newImage;
3947
3948  GetPPException;
3949  newImage=ShadeImage(constImage(),colorShading_ == true ?
3950    MagickTrue : MagickFalse,azimuth_,elevation_,&exceptionInfo);
3951  replaceImage(newImage);
3952  ThrowPPException;
3953}
3954
3955void Magick::Image::shadow(const double percent_opacity_,const double sigma_,
3956  const ssize_t x_,const ssize_t y_)
3957{
3958  MagickCore::Image
3959    *newImage;
3960
3961  GetPPException;
3962  newImage=ShadowImage(constImage(),percent_opacity_, sigma_,x_, y_,
3963    &exceptionInfo);
3964  replaceImage(newImage);
3965  ThrowPPException;
3966}
3967
3968void Magick::Image::sharpen(const double radius_,const double sigma_)
3969{
3970  MagickCore::Image
3971    *newImage;
3972
3973  GetPPException;
3974  newImage=SharpenImage(constImage(),radius_,sigma_,&exceptionInfo);
3975  replaceImage(newImage);
3976  ThrowPPException;
3977}
3978
3979void Magick::Image::sharpenChannel(const ChannelType channel_,
3980  const double radius_,const double sigma_)
3981{
3982  MagickCore::Image
3983    *newImage;
3984
3985  GetPPException;
3986  SetPPChannelMask(channel_);
3987  newImage=SharpenImage(constImage(),radius_,sigma_,&exceptionInfo);
3988  RestorePPChannelMask;
3989  replaceImage(newImage);
3990  ThrowPPException;
3991}
3992
3993void Magick::Image::shave(const Geometry &geometry_)
3994{
3995  MagickCore::Image
3996    *newImage;
3997
3998  RectangleInfo
3999    shaveInfo=geometry_;
4000
4001  GetPPException;
4002  newImage=ShaveImage(constImage(),&shaveInfo,&exceptionInfo);
4003  replaceImage(newImage);
4004  ThrowPPException;
4005}
4006
4007void Magick::Image::shear(const double xShearAngle_,const double yShearAngle_)
4008{
4009  MagickCore::Image
4010    *newImage;
4011
4012  GetPPException;
4013  newImage=ShearImage(constImage(),xShearAngle_,yShearAngle_,&exceptionInfo);
4014  replaceImage(newImage);
4015  ThrowPPException;
4016}
4017
4018void Magick::Image::sigmoidalContrast(const size_t sharpen_,
4019  const double contrast,const double midpoint)
4020{
4021  modifyImage();
4022  GetPPException;
4023  (void) SigmoidalContrastImage(image(),(MagickBooleanType) sharpen_,contrast,
4024    midpoint,&exceptionInfo);
4025  ThrowPPException;
4026}
4027
4028std::string Magick::Image::signature(const bool force_) const
4029{
4030  const char
4031    *property;
4032
4033  Lock(&_imgRef->_mutexLock);
4034
4035  // Re-calculate image signature if necessary
4036  GetPPException;
4037  if (force_ || !GetImageProperty(constImage(),"Signature",&exceptionInfo) ||
4038    constImage()->taint)
4039    SignatureImage(const_cast<MagickCore::Image *>(constImage()),
4040      &exceptionInfo);
4041
4042  property=GetImageProperty(constImage(),"Signature",&exceptionInfo);
4043  ThrowPPException;
4044
4045  return(std::string(property));
4046}
4047
4048void Magick::Image::solarize(const double factor_)
4049{
4050  modifyImage();
4051  GetPPException;
4052  SolarizeImage(image(),factor_,&exceptionInfo);
4053  ThrowPPException;
4054}
4055
4056void Magick::Image::sparseColor(const ChannelType channel_,
4057  const SparseColorMethod method_,const size_t numberArguments_,
4058  const double *arguments_)
4059{
4060  MagickCore::Image
4061    *newImage;
4062
4063  GetPPException;
4064  SetPPChannelMask(channel_);
4065  newImage=SparseColorImage(constImage(),method_,numberArguments_,arguments_,
4066    &exceptionInfo);
4067  RestorePPChannelMask;
4068  replaceImage(newImage);
4069  ThrowPPException;
4070}
4071
4072void Magick::Image::splice(const Geometry &geometry_)
4073{
4074  MagickCore::Image
4075    *newImage;
4076
4077  RectangleInfo
4078    spliceInfo=geometry_;
4079
4080  GetPPException;
4081  newImage=SpliceImage(constImage(),&spliceInfo,&exceptionInfo);
4082  replaceImage(newImage);
4083  ThrowPPException;
4084}
4085
4086void Magick::Image::spread(const size_t amount_)
4087{
4088  MagickCore::Image
4089    *newImage;
4090
4091  GetPPException;
4092  newImage=SpreadImage(constImage(),amount_,image()->interpolate,
4093    &exceptionInfo);
4094  replaceImage(newImage);
4095  ThrowPPException;
4096}
4097
4098void Magick::Image::statistics(ImageStatistics *statistics)
4099{
4100  double
4101    maximum,
4102    minimum;
4103
4104  GetPPException;
4105
4106  SetPPChannelMask(RedChannel);
4107  (void) GetImageRange(constImage(),&minimum,&maximum,&exceptionInfo);
4108  statistics->red.minimum=minimum;
4109  statistics->red.maximum=maximum;
4110  (void) GetImageMean(constImage(),&statistics->red.mean,
4111    &statistics->red.standard_deviation,&exceptionInfo);
4112  (void) GetImageKurtosis(constImage(),&statistics->red.kurtosis,
4113    &statistics->red.skewness,&exceptionInfo);
4114
4115  (void) SetImageChannelMask(image(),GreenChannel);
4116  (void) GetImageRange(constImage(),&minimum,&maximum,&exceptionInfo);
4117  statistics->green.minimum=minimum;
4118  statistics->green.maximum=maximum;
4119  (void) GetImageMean(constImage(),&statistics->green.mean,
4120    &statistics->green.standard_deviation,&exceptionInfo);
4121  (void) GetImageKurtosis(constImage(),&statistics->green.kurtosis,
4122    &statistics->green.skewness,&exceptionInfo);
4123
4124  (void) SetImageChannelMask(image(),GreenChannel);
4125  (void) GetImageRange(constImage(),&minimum,&maximum,&exceptionInfo);
4126  statistics->blue.minimum=minimum;
4127  statistics->blue.maximum=maximum;
4128  (void) GetImageMean(constImage(),&statistics->blue.mean,
4129    &statistics->blue.standard_deviation,&exceptionInfo);
4130  (void) GetImageKurtosis(constImage(),&statistics->blue.kurtosis,
4131    &statistics->blue.skewness,&exceptionInfo);
4132
4133  (void) SetImageChannelMask(image(),AlphaChannel);
4134  (void) GetImageRange(constImage(),&minimum,&maximum,&exceptionInfo);
4135  statistics->alpha.minimum=minimum;
4136  statistics->alpha.maximum=maximum;
4137  (void) GetImageMean(constImage(),&statistics->alpha.mean,
4138    &statistics->alpha.standard_deviation,&exceptionInfo);
4139  (void) GetImageKurtosis(constImage(),&statistics->alpha.kurtosis,
4140    &statistics->alpha.skewness,&exceptionInfo);
4141  RestorePPChannelMask;
4142  ThrowPPException;
4143}
4144
4145void Magick::Image::stegano(const Image &watermark_)
4146{
4147  MagickCore::Image
4148    *newImage;
4149
4150  GetPPException;
4151  newImage=SteganoImage(constImage(),watermark_.constImage(),&exceptionInfo);
4152  replaceImage(newImage);
4153  ThrowPPException;
4154}
4155
4156void Magick::Image::stereo(const Image &rightImage_)
4157{
4158  MagickCore::Image
4159    *newImage;
4160
4161  GetPPException;
4162  newImage=StereoImage(constImage(),rightImage_.constImage(),&exceptionInfo);
4163  replaceImage(newImage);
4164  ThrowPPException;
4165}
4166
4167void Magick::Image::strip(void)
4168{
4169  modifyImage();
4170  GetPPException;
4171  StripImage(image(),&exceptionInfo);
4172  ThrowPPException;
4173}
4174
4175void Magick::Image::swirl(const double degrees_)
4176{
4177  MagickCore::Image
4178    *newImage;
4179
4180  GetPPException;
4181  newImage=SwirlImage(constImage(),degrees_,image()->interpolate,
4182    &exceptionInfo);
4183  replaceImage(newImage);
4184  ThrowPPException;
4185}
4186
4187void Magick::Image::syncPixels(void)
4188{
4189  GetPPException;
4190  (*SyncAuthenticPixels)(image(),&exceptionInfo);
4191  ThrowPPException;
4192}
4193
4194void Magick::Image::texture(const Image &texture_)
4195{
4196  modifyImage();
4197  GetPPException;
4198  TextureImage(image(),texture_.constImage(),&exceptionInfo);
4199  ThrowPPException;
4200}
4201
4202void Magick::Image::threshold(const double threshold_)
4203{
4204  modifyImage();
4205  GetPPException;
4206  BilevelImage(image(),threshold_,&exceptionInfo);
4207  ThrowPPException;
4208}
4209
4210void Magick::Image::thumbnail(const Geometry &geometry_)
4211{
4212  MagickCore::Image
4213    *newImage;
4214
4215  size_t
4216    height=rows(),
4217    width=columns();
4218
4219  ssize_t
4220    x=0,
4221    y=0;
4222
4223  ParseMetaGeometry(static_cast<std::string>(geometry_).c_str(),&x,&y,&width,
4224    &height);
4225
4226  GetPPException;
4227  newImage=ThumbnailImage(constImage(),width,height,&exceptionInfo);
4228  replaceImage(newImage);
4229  ThrowPPException;
4230}
4231
4232void Magick::Image::transform(const Geometry &imageGeometry_)
4233{
4234  modifyImage();
4235  GetPPException;
4236  TransformImage(&(image()),0,std::string(imageGeometry_).c_str(),
4237    &exceptionInfo);
4238  ThrowPPException;
4239}
4240
4241void Magick::Image::transform(const Geometry &imageGeometry_,
4242  const Geometry &cropGeometry_)
4243{
4244  modifyImage();
4245  GetPPException;
4246  TransformImage(&(image()),std::string(cropGeometry_).c_str(),std::string(
4247    imageGeometry_).c_str(), &exceptionInfo);
4248  ThrowPPException;
4249}
4250
4251void Magick::Image::transformOrigin(const double x_,const double y_)
4252{
4253  modifyImage();
4254  options()->transformOrigin(x_,y_);
4255}
4256
4257void Magick::Image::transformReset(void)
4258{
4259  modifyImage();
4260  options()->transformReset();
4261}
4262
4263void Magick::Image::transformScale(const double sx_,const double sy_)
4264{
4265  modifyImage();
4266  options()->transformScale(sx_,sy_);
4267}
4268
4269void Magick::Image::transparent(const Color &color_)
4270{
4271  PixelInfo
4272    target;
4273
4274  std::string
4275    color;
4276
4277  if (!color_.isValid())
4278    throwExceptionExplicit(OptionError,"Color argument is invalid");
4279
4280  color=color_;
4281  GetPPException;
4282  (void) QueryColorCompliance(color.c_str(),AllCompliance,&target,
4283    &exceptionInfo);
4284  modifyImage();
4285  TransparentPaintImage(image(),&target,TransparentAlpha,MagickFalse,
4286    &exceptionInfo);
4287  ThrowPPException;
4288}
4289
4290void Magick::Image::transparentChroma(const Color &colorLow_,
4291  const Color &colorHigh_)
4292{
4293  std::string
4294    colorHigh,
4295    colorLow;
4296
4297  PixelInfo
4298    targetHigh,
4299    targetLow;
4300
4301  if (!colorLow_.isValid() || !colorHigh_.isValid())
4302    throwExceptionExplicit(OptionError,"Color argument is invalid");
4303
4304  colorLow=colorLow_;
4305  colorHigh=colorHigh_;
4306
4307  GetPPException;
4308  (void) QueryColorCompliance(colorLow.c_str(),AllCompliance,&targetLow,
4309    &exceptionInfo);
4310  (void) QueryColorCompliance(colorHigh.c_str(),AllCompliance,&targetHigh,
4311    &exceptionInfo);
4312  modifyImage();
4313  TransparentPaintImageChroma(image(),&targetLow,&targetHigh,TransparentAlpha,
4314    MagickFalse,&exceptionInfo);
4315  ThrowPPException;
4316}
4317
4318void Magick::Image::trim(void)
4319{
4320  MagickCore::Image
4321    *newImage;
4322
4323  GetPPException;
4324  newImage=TrimImage(constImage(),&exceptionInfo);
4325  replaceImage(newImage);
4326  ThrowPPException;
4327}
4328
4329void Magick::Image::unsharpmask(const double radius_,const double sigma_,
4330  const double amount_,const double threshold_)
4331{
4332  MagickCore::Image
4333    *newImage;
4334
4335  GetPPException;
4336  newImage=UnsharpMaskImage(constImage(),radius_,sigma_,amount_,threshold_,
4337    &exceptionInfo);
4338  replaceImage(newImage);
4339  ThrowPPException;
4340}
4341
4342void Magick::Image::unsharpmaskChannel(const ChannelType channel_,
4343  const double radius_,const double sigma_,const double amount_,
4344  const double threshold_)
4345{
4346  MagickCore::Image
4347    *newImage;
4348
4349  GetPPException;
4350  SetPPChannelMask(channel_);
4351  newImage=UnsharpMaskImage(constImage(),radius_,sigma_,amount_,threshold_,
4352    &exceptionInfo);
4353  RestorePPChannelMask;
4354  replaceImage(newImage);
4355  ThrowPPException;
4356}
4357
4358void Magick::Image::wave(const double amplitude_,const double wavelength_)
4359{
4360  MagickCore::Image
4361    *newImage;
4362
4363  GetPPException;
4364  newImage=WaveImage(constImage(),amplitude_,wavelength_,image()->interpolate,
4365    &exceptionInfo);
4366  replaceImage(newImage);
4367  ThrowPPException;
4368}
4369
4370void Magick::Image::whiteThreshold(const std::string &threshold_)
4371{
4372  modifyImage();
4373  GetPPException;
4374  WhiteThresholdImage(image(),threshold_.c_str(),&exceptionInfo);
4375  ThrowPPException;
4376}
4377
4378void Magick::Image::whiteThresholdChannel(const ChannelType channel_,
4379  const std::string &threshold_)
4380{
4381  modifyImage();
4382  GetPPException;
4383  SetPPChannelMask(channel_);
4384  WhiteThresholdImage(image(),threshold_.c_str(),&exceptionInfo);
4385  RestorePPChannelMask;
4386  ThrowPPException;
4387}
4388
4389void Magick::Image::write(Blob *blob_)
4390{
4391  size_t
4392    length=2048; // Efficient size for small images
4393
4394  void
4395    *data;
4396
4397  modifyImage();
4398  GetPPException;
4399  data=ImagesToBlob(constImageInfo(),image(),&length,&exceptionInfo);
4400  ThrowPPException;
4401  blob_->updateNoCopy(data,length,Blob::MallocAllocator);
4402}
4403
4404void Magick::Image::write(Blob *blob_,const std::string &magick_)
4405{
4406  size_t
4407    length=2048; // Efficient size for small images
4408
4409  void
4410    *data;
4411
4412  modifyImage();
4413  magick(magick_);
4414  GetPPException;
4415  data=ImagesToBlob(constImageInfo(),image(),&length,&exceptionInfo);
4416  ThrowPPException;
4417  blob_->updateNoCopy(data,length,Blob::MallocAllocator);
4418}
4419
4420void Magick::Image::write(Blob *blob_,const std::string &magick_,
4421  const size_t depth_)
4422{
4423  size_t
4424    length=2048; // Efficient size for small images
4425
4426  void
4427    *data;
4428
4429  modifyImage();
4430  magick(magick_);
4431  depth(depth_);
4432  GetPPException;
4433  data=ImagesToBlob(constImageInfo(),image(),&length,&exceptionInfo);
4434  ThrowPPException;
4435  blob_->updateNoCopy(data,length,Blob::MallocAllocator);
4436}
4437
4438void Magick::Image::write(const ssize_t x_,const ssize_t y_,
4439  const size_t columns_,const size_t rows_,const std::string &map_,
4440  const StorageType type_,void *pixels_)
4441{
4442  GetPPException;
4443  ExportImagePixels(image(),x_,y_,columns_,rows_,map_.c_str(),type_,pixels_,
4444    &exceptionInfo);
4445  ThrowPPException;
4446}
4447
4448void Magick::Image::write(const std::string &imageSpec_)
4449{
4450  modifyImage();
4451  fileName(imageSpec_);
4452  GetPPException;
4453  WriteImage(constImageInfo(),image(),&exceptionInfo);
4454  ThrowPPException;
4455}
4456
4457void Magick::Image::writePixels(const Magick::QuantumType quantum_,
4458  unsigned char *destination_)
4459{
4460  QuantumInfo
4461    *quantum_info;
4462
4463  quantum_info=AcquireQuantumInfo(imageInfo(),image());
4464  GetPPException;
4465  ExportQuantumPixels(image(),(MagickCore::CacheView *) NULL,quantum_info,
4466    quantum_,destination_, &exceptionInfo);
4467  quantum_info=DestroyQuantumInfo(quantum_info);
4468  ThrowPPException;
4469}
4470
4471void Magick::Image::zoom(const Geometry &geometry_)
4472{
4473  MagickCore::Image
4474    *newImage;
4475
4476  size_t
4477    height=rows(),
4478    width=columns();
4479
4480  ssize_t
4481    x=0,
4482    y=0;
4483
4484  ParseMetaGeometry(static_cast<std::string>(geometry_).c_str(),&x,&y,&width,
4485    &height);
4486
4487  GetPPException;
4488  newImage=ResizeImage(constImage(),width,height,image()->filter,&exceptionInfo);
4489  replaceImage(newImage);
4490  ThrowPPException;
4491}
4492
4493Magick::Image::Image(MagickCore::Image *image_)
4494  : _imgRef(new ImageRef(image_))
4495{
4496}
4497
4498MagickCore::Image *&Magick::Image::image(void)
4499{
4500  return(_imgRef->image());
4501}
4502
4503const MagickCore::Image *Magick::Image::constImage(void) const
4504{
4505  return(_imgRef->image());
4506}
4507
4508MagickCore::ImageInfo *Magick::Image::imageInfo(void)
4509{
4510  return(_imgRef->options()->imageInfo());
4511}
4512
4513const MagickCore::ImageInfo *Magick::Image::constImageInfo(void) const
4514{
4515  return(_imgRef->options()->imageInfo());
4516}
4517
4518Magick::Options *Magick::Image::options(void)
4519{
4520  return(_imgRef->options());
4521}
4522
4523const Magick::Options *Magick::Image::constOptions(void) const
4524{
4525  return(_imgRef->options());
4526}
4527
4528MagickCore::QuantizeInfo *Magick::Image::quantizeInfo(void)
4529{
4530  return(_imgRef->options()->quantizeInfo());
4531}
4532
4533const MagickCore::QuantizeInfo *Magick::Image::constQuantizeInfo(void) const
4534{
4535  return(_imgRef->options()->quantizeInfo());
4536}
4537
4538void Magick::Image::modifyImage(void)
4539{
4540  {
4541    Lock(&_imgRef->_mutexLock);
4542    if (_imgRef->_refCount == 1)
4543      {
4544        // De-register image and return
4545        _imgRef->id(-1);
4546        return;
4547      }
4548  }
4549
4550  GetPPException;
4551  replaceImage(CloneImage(image(),0,0,MagickTrue,&exceptionInfo));
4552  ThrowPPException;
4553}
4554
4555ssize_t Magick::Image::registerId(void)
4556{
4557  Lock(&_imgRef->_mutexLock);
4558  if ( _imgRef->id() < 0)
4559    {
4560      char
4561        id[MaxTextExtent];
4562
4563      GetPPException;
4564      _imgRef->id(_imgRef->id()+1);
4565      sprintf(id,"%.20g\n",(double) _imgRef->id());
4566      SetImageRegistry(ImageRegistryType,id,image(),&exceptionInfo);
4567      ThrowPPException;
4568    }
4569  return(_imgRef->id());
4570}
4571
4572MagickCore::Image *Magick::Image::replaceImage(MagickCore::Image *replacement_)
4573{
4574  MagickCore::Image
4575    *image;
4576
4577  if (replacement_)
4578    image = replacement_;
4579  else
4580    {
4581      GetPPException;
4582      image=AcquireImage(constImageInfo(),&exceptionInfo);
4583      ThrowPPException;
4584    }
4585
4586  {
4587    Lock(&_imgRef->_mutexLock);
4588
4589    if (_imgRef->_refCount == 1)
4590      {
4591        // We own the image, just replace it, and de-register
4592        _imgRef->id(-1);
4593        _imgRef->image(image);
4594      }
4595    else
4596      {
4597        // We don't own the image, dereference and replace with copy
4598        --_imgRef->_refCount;
4599        _imgRef=new ImageRef(image,constOptions());
4600      }
4601  }
4602
4603  return(_imgRef->_image);
4604}
4605
4606void Magick::Image::unregisterId(void)
4607{
4608  modifyImage();
4609  _imgRef->id(-1);
4610}
4611