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