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