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