1 // This may look like C code, but it is really -*- C++ -*-
3 // Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2003
5 // Implementation of Options
7 // A wrapper around DrawInfo, ImageInfo, and QuantizeInfo
10 #define MAGICKCORE_IMPLEMENTATION 1
11 #define MAGICK_PLUSPLUS_IMPLEMENTATION 1
13 #include "Magick++/Include.h"
19 #include "Magick++/Options.h"
20 #include "Magick++/Functions.h"
21 #include "Magick++/Exception.h"
23 #define MagickPI 3.14159265358979323846264338327950288419716939937510
24 #define DegreesToRadians(x) (MagickPI*(x)/180.0)
25 #define GetPPException \
28 GetExceptionInfo(&exceptionInfo)
29 #define ThrowPPException \
30 throwException(exceptionInfo); \
31 (void) DestroyExceptionInfo(&exceptionInfo)
33 Magick::Options::Options(void)
34 : _imageInfo(static_cast<ImageInfo*>(AcquireMagickMemory(
36 _quantizeInfo(static_cast<QuantizeInfo*>(AcquireMagickMemory(
37 sizeof(QuantizeInfo)))),
38 _drawInfo(static_cast<DrawInfo*>(AcquireMagickMemory(sizeof(DrawInfo))))
40 // Initialize image info with defaults
41 GetImageInfo(_imageInfo);
43 // Initialize quantization info
44 GetQuantizeInfo(_quantizeInfo);
46 // Initialize drawing info
47 GetDrawInfo(_imageInfo,_drawInfo);
50 Magick::Options::Options(const Magick::Options& options_)
51 : _imageInfo(CloneImageInfo(options_._imageInfo )),
52 _quantizeInfo(CloneQuantizeInfo(options_._quantizeInfo)),
53 _drawInfo(CloneDrawInfo(_imageInfo,options_._drawInfo))
57 Magick::Options::~Options()
60 _imageInfo=DestroyImageInfo(_imageInfo);
62 // Destroy quantization info
63 _quantizeInfo=DestroyQuantizeInfo(_quantizeInfo);
65 // Destroy drawing info
66 _drawInfo=DestroyDrawInfo(_drawInfo);
69 void Magick::Options::antiAlias(bool flag_)
71 _drawInfo->text_antialias=static_cast<MagickBooleanType>(
72 flag_ ? MagickTrue : MagickFalse);
75 bool Magick::Options::antiAlias(void) const
77 return(static_cast<bool>(_drawInfo->text_antialias));
80 void Magick::Options::adjoin(bool flag_)
82 _imageInfo->adjoin=static_cast<MagickBooleanType>(
83 flag_ ? MagickTrue : MagickFalse);
86 bool Magick::Options::adjoin(void) const
88 return(static_cast<bool>(_imageInfo->adjoin));
91 void Magick::Options::backgroundColor(const Magick::Color &color_)
93 _imageInfo->background_color=color_;
96 Magick::Color Magick::Options::backgroundColor(void) const
98 return(Magick::Color(_imageInfo->background_color));
101 void Magick::Options::backgroundTexture(const std::string &backgroundTexture_)
103 if (backgroundTexture_.length() == 0)
104 _imageInfo->texture=(char *) RelinquishMagickMemory(_imageInfo->texture);
106 Magick::CloneString(&_imageInfo->texture,backgroundTexture_);
109 std::string Magick::Options::backgroundTexture(void) const
111 if (_imageInfo->texture)
112 return(std::string(_imageInfo->texture));
114 return(std::string());
117 void Magick::Options::borderColor(const Color &color_)
119 _imageInfo->border_color=color_;
120 _drawInfo->border_color=color_;
123 Magick::Color Magick::Options::borderColor(void) const
125 return(Magick::Color(_imageInfo->border_color));
128 void Magick::Options::boxColor(const Magick::Color &boxColor_)
130 _drawInfo->undercolor=boxColor_;
133 Magick::Color Magick::Options::boxColor(void) const
135 return(Magick::Color(_drawInfo->undercolor));
138 void Magick::Options::colorspaceType(Magick::ColorspaceType colorspace_)
140 _imageInfo->colorspace=colorspace_;
143 Magick::ColorspaceType Magick::Options::colorspaceType(void) const
145 return(static_cast<Magick::ColorspaceType>(_imageInfo->colorspace));
148 void Magick::Options::compressType(CompressionType compressType_)
150 _imageInfo->compression=compressType_;
153 Magick::CompressionType Magick::Options::compressType(void) const
155 return(static_cast<Magick::CompressionType>(_imageInfo->compression));
158 void Magick::Options::colorFuzz(double fuzz_)
160 _imageInfo->fuzz=fuzz_;
163 double Magick::Options::colorFuzz(void) const
165 return(_imageInfo->fuzz);
168 void Magick::Options::debug(bool flag_)
171 SetLogEventMask("All");
173 SetLogEventMask("None");
176 bool Magick::Options::debug(void) const
178 if (IsEventLogging())
183 void Magick::Options::density(const Magick::Geometry &density_)
185 if ( !density_.isValid() )
186 _imageInfo->density=(char *) RelinquishMagickMemory(_imageInfo->density);
188 Magick::CloneString(&_imageInfo->density,density_);
191 Magick::Geometry Magick::Options::density(void) const
193 if (_imageInfo->density)
194 return(Geometry(_imageInfo->density));
199 void Magick::Options::depth(size_t depth_)
201 _imageInfo->depth=depth_;
204 size_t Magick::Options::depth(void) const
206 return(_imageInfo->depth);
209 void Magick::Options::endian(Magick::EndianType endian_)
211 _imageInfo->endian=endian_;
214 Magick::EndianType Magick::Options::endian(void) const
216 return(_imageInfo->endian);
219 void Magick::Options::file(FILE *file_)
221 SetImageInfoFile(_imageInfo,file_);
224 FILE *Magick::Options::file(void) const
226 return(GetImageInfoFile(_imageInfo));
229 void Magick::Options::fileName(const std::string &fileName_)
231 fileName_.copy(_imageInfo->filename,MaxTextExtent-1);
232 if (fileName_.length() > MaxTextExtent-1)
233 _imageInfo->filename[MaxTextExtent-1]=0;
235 _imageInfo->filename[fileName_.length()]=0;
238 std::string Magick::Options::fileName(void) const
240 return(std::string(_imageInfo->filename));
243 void Magick::Options::fillColor(const Magick::Color &fillColor_)
245 _drawInfo->fill=fillColor_;
246 if (fillColor_ == Magick::Color())
247 fillPattern((const MagickCore::Image*) NULL);
250 Magick::Color Magick::Options::fillColor(void) const
252 return(_drawInfo->fill);
255 void Magick::Options::fillPattern(const MagickCore::Image *fillPattern_)
257 if (_drawInfo->fill_pattern)
258 _drawInfo->fill_pattern=DestroyImageList(_drawInfo->fill_pattern);
263 _drawInfo->fill_pattern=CloneImage(const_cast<MagickCore::Image*>(
264 fillPattern_),0,0,static_cast<MagickBooleanType>(MagickTrue),
270 const MagickCore::Image *Magick::Options::fillPattern(void) const
272 return(_drawInfo->fill_pattern);
275 void Magick::Options::fillRule(const Magick::FillRule &fillRule_)
277 _drawInfo->fill_rule=fillRule_;
280 Magick::FillRule Magick::Options::fillRule(void) const
282 return(_drawInfo->fill_rule);
285 void Magick::Options::font(const std::string &font_)
287 if (font_.length() == 0)
289 _imageInfo->font=(char *) RelinquishMagickMemory(_imageInfo->font);
290 _drawInfo->font=(char *) RelinquishMagickMemory(_drawInfo->font);
294 Magick::CloneString(&_imageInfo->font,font_);
295 Magick::CloneString(&_drawInfo->font,font_);
299 std::string Magick::Options::font(void) const
301 if (_imageInfo->font)
302 return(std::string(_imageInfo->font));
304 return(std::string());
307 void Magick::Options::fontPointsize(double pointSize_)
309 _imageInfo->pointsize=pointSize_;
310 _drawInfo->pointsize=pointSize_;
313 double Magick::Options::fontPointsize(void) const
315 return(_imageInfo->pointsize);
318 std::string Magick::Options::format(void) const
324 if (*_imageInfo->magick != '\0' )
325 magick_info = GetMagickInfo(_imageInfo->magick,&exceptionInfo);
328 if ((magick_info != 0) && (*magick_info->description != '\0'))
329 return(std::string( magick_info->description));
331 return(std::string());
334 void Magick::Options::interlaceType(Magick::InterlaceType interlace_)
336 _imageInfo->interlace=interlace_;
339 Magick::InterlaceType Magick::Options::interlaceType(void) const
341 return(static_cast<Magick::InterlaceType>(_imageInfo->interlace));
344 void Magick::Options::magick(const std::string &magick_)
346 FormatLocaleString(_imageInfo->filename,MaxTextExtent,"%.1024s:",
349 SetImageInfo(_imageInfo,1,&exceptionInfo);
350 if (*_imageInfo->magick == '\0')
351 throwExceptionExplicit(OptionWarning, "Unrecognized image format",
353 (void) DestroyExceptionInfo(&exceptionInfo);
356 std::string Magick::Options::magick(void) const
358 if (_imageInfo->magick && *_imageInfo->magick)
359 return(std::string(_imageInfo->magick));
361 return(std::string());
364 void Magick::Options::matteColor(const Magick::Color &matteColor_)
366 _imageInfo->matte_color=matteColor_;
369 Magick::Color Magick::Options::matteColor(void) const
371 return(Magick::Color(_imageInfo->matte_color));
374 void Magick::Options::monochrome(bool monochromeFlag_)
376 _imageInfo->monochrome=(MagickBooleanType) monochromeFlag_;
379 bool Magick::Options::monochrome(void) const
381 return(static_cast<bool>(_imageInfo->monochrome));
384 void Magick::Options::page(const Magick::Geometry &pageSize_)
386 if (!pageSize_.isValid())
387 _imageInfo->page=(char *) RelinquishMagickMemory(_imageInfo->page);
389 Magick::CloneString(&_imageInfo->page,pageSize_);
392 Magick::Geometry Magick::Options::page(void) const
394 if (_imageInfo->page)
395 return(Geometry(_imageInfo->page));
400 void Magick::Options::quality(size_t quality_)
402 _imageInfo->quality=quality_;
405 size_t Magick::Options::quality(void) const
407 return(_imageInfo->quality);
410 void Magick::Options::quantizeColors(size_t colors_)
412 _quantizeInfo->number_colors=colors_;
415 size_t Magick::Options::quantizeColors(void) const
417 return(_quantizeInfo->number_colors);
420 void Magick::Options::quantizeColorSpace(Magick::ColorspaceType colorSpace_)
422 _quantizeInfo->colorspace=colorSpace_;
425 Magick::ColorspaceType Magick::Options::quantizeColorSpace(void) const
427 return(static_cast<Magick::ColorspaceType>(_quantizeInfo->colorspace));
430 void Magick::Options::quantizeDither(bool ditherFlag_)
432 _imageInfo->dither=(MagickBooleanType) ditherFlag_;
433 _quantizeInfo->dither_method=ditherFlag_ ? RiemersmaDitherMethod :
437 bool Magick::Options::quantizeDither(void) const
439 return(static_cast<bool>(_imageInfo->dither));
442 void Magick::Options::quantizeTreeDepth(size_t treeDepth_)
444 _quantizeInfo->tree_depth=treeDepth_;
447 size_t Magick::Options::quantizeTreeDepth(void) const
449 return(_quantizeInfo->tree_depth);
452 void Magick::Options::resolutionUnits(Magick::ResolutionType resolutionUnits_)
454 _imageInfo->units=resolutionUnits_;
457 Magick::ResolutionType Magick::Options::resolutionUnits(void) const
459 return(static_cast<Magick::ResolutionType>(_imageInfo->units));
462 void Magick::Options::samplingFactor(const std::string &samplingFactor_)
464 if (samplingFactor_.length() == 0)
465 _imageInfo->sampling_factor=(char *) RelinquishMagickMemory(
466 _imageInfo->sampling_factor);
468 Magick::CloneString(&_imageInfo->sampling_factor,samplingFactor_);
471 std::string Magick::Options::samplingFactor(void) const
473 if (_imageInfo->sampling_factor)
474 return(std::string(_imageInfo->sampling_factor));
476 return(std::string());
479 void Magick::Options::size(const Geometry &geometry_)
481 _imageInfo->size=(char *) RelinquishMagickMemory(_imageInfo->size);
483 if (geometry_.isValid())
484 Magick::CloneString(&_imageInfo->size,geometry_);
487 Magick::Geometry Magick::Options::size(void) const
489 if (_imageInfo->size)
490 return(Geometry(_imageInfo->size));
495 void Magick::Options::strokeAntiAlias(bool flag_)
497 flag_ ? _drawInfo->stroke_antialias=MagickTrue :
498 _drawInfo->stroke_antialias=MagickFalse;
501 bool Magick::Options::strokeAntiAlias(void) const
503 return(_drawInfo->stroke_antialias != 0 ? true : false);
506 void Magick::Options::strokeColor(const Magick::Color &strokeColor_)
508 _drawInfo->stroke=strokeColor_;
511 Magick::Color Magick::Options::strokeColor(void) const
513 return(_drawInfo->stroke);
516 void Magick::Options::strokeDashArray(const double *strokeDashArray_)
518 _drawInfo->dash_pattern=(double *) RelinquishMagickMemory(
519 _drawInfo->dash_pattern);
525 // Count elements in dash array
526 for (x=0; strokeDashArray_[x]; x++) ;
528 _drawInfo->dash_pattern=static_cast<double*>(AcquireMagickMemory((x+1)*
531 memcpy(_drawInfo->dash_pattern,strokeDashArray_,(x+1)*sizeof(double));
535 const double *Magick::Options::strokeDashArray(void) const
537 return(_drawInfo->dash_pattern);
540 void Magick::Options::strokeDashOffset(double strokeDashOffset_)
542 _drawInfo->dash_offset=strokeDashOffset_;
545 double Magick::Options::strokeDashOffset(void) const
547 return(_drawInfo->dash_offset);
550 void Magick::Options::strokeLineCap(Magick::LineCap lineCap_)
552 _drawInfo->linecap=lineCap_;
555 Magick::LineCap Magick::Options::strokeLineCap(void) const
557 return(_drawInfo->linecap);
560 void Magick::Options::strokeLineJoin(Magick::LineJoin lineJoin_)
562 _drawInfo->linejoin=lineJoin_;
565 Magick::LineJoin Magick::Options::strokeLineJoin(void) const
567 return(_drawInfo->linejoin);
570 void Magick::Options::strokeMiterLimit(size_t miterLimit_)
572 _drawInfo->miterlimit=miterLimit_;
575 size_t Magick::Options::strokeMiterLimit(void) const
577 return(_drawInfo->miterlimit);
580 void Magick::Options::strokePattern(const MagickCore::Image *strokePattern_)
582 if (_drawInfo->stroke_pattern)
583 _drawInfo->stroke_pattern=DestroyImageList(_drawInfo->stroke_pattern);
588 _drawInfo->stroke_pattern=CloneImage( const_cast<MagickCore::Image*>(
589 strokePattern_),0,0,MagickTrue,&exceptionInfo);
594 const MagickCore::Image *Magick::Options::strokePattern(void) const
596 return(_drawInfo->stroke_pattern);
599 void Magick::Options::strokeWidth(double strokeWidth_)
601 _drawInfo->stroke_width=strokeWidth_;
604 double Magick::Options::strokeWidth(void) const
606 return(_drawInfo->stroke_width);
609 void Magick::Options::subImage(size_t subImage_)
611 _imageInfo->scene=subImage_;
614 size_t Magick::Options::subImage(void) const
616 return(_imageInfo->scene);
619 void Magick::Options::subRange(size_t subRange_)
621 _imageInfo->number_scenes=subRange_;
624 size_t Magick::Options::subRange(void) const
626 return(_imageInfo->number_scenes);
629 void Magick::Options::textDirection(DirectionType direction_)
631 _drawInfo->direction=direction_;
634 Magick::DirectionType Magick::Options::textDirection() const
636 return(_drawInfo->direction);
639 void Magick::Options::textEncoding(const std::string &encoding_)
641 CloneString(&_drawInfo->encoding,encoding_.c_str());
644 std::string Magick::Options::textEncoding(void) const
646 if (_drawInfo->encoding && *_drawInfo->encoding)
647 return(std::string(_drawInfo->encoding));
649 return(std::string());
652 void Magick::Options::textGravity(GravityType gravity_)
654 _drawInfo->gravity=gravity_;
657 Magick::GravityType Magick::Options::textGravity() const
659 return(_drawInfo->gravity);
662 void Magick::Options::textInterlineSpacing(double spacing_)
664 _drawInfo->interline_spacing=spacing_;
667 double Magick::Options::textInterlineSpacing(void) const
669 return(_drawInfo->interline_spacing);
672 void Magick::Options::textInterwordSpacing(double spacing_)
674 _drawInfo->interword_spacing=spacing_;
677 double Magick::Options::textInterwordSpacing(void) const
679 return(_drawInfo->interword_spacing);
682 void Magick::Options::textKerning(double kerning_)
684 _drawInfo->kerning=kerning_;
687 double Magick::Options::textKerning(void) const
689 return(_drawInfo->kerning);
692 void Magick::Options::transformOrigin(double tx_,double ty_)
696 current=_drawInfo->affine;
708 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
709 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
710 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
711 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
712 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
713 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
716 void Magick::Options::transformReset(void)
718 _drawInfo->affine.sx=1.0;
719 _drawInfo->affine.rx=0.0;
720 _drawInfo->affine.ry=0.0;
721 _drawInfo->affine.sy=1.0;
722 _drawInfo->affine.tx=0.0;
723 _drawInfo->affine.ty=0.0;
726 void Magick::Options::transformRotation(double angle_)
730 current=_drawInfo->affine;
739 affine.sx=cos(DegreesToRadians(fmod(angle_,360.0)));
740 affine.rx=(-sin(DegreesToRadians(fmod(angle_,360.0))));
741 affine.ry=sin(DegreesToRadians(fmod(angle_,360.0)));
742 affine.sy=cos(DegreesToRadians(fmod(angle_,360.0)));
744 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
745 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
746 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
747 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
748 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
749 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
752 void Magick::Options::transformScale(double sx_,double sy_)
756 current=_drawInfo->affine;
768 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
769 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
770 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
771 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
772 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
773 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
776 void Magick::Options::transformSkewX(double skewx_)
780 current=_drawInfo->affine;
790 affine.ry=tan(DegreesToRadians(fmod(skewx_,360.0)));
793 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
794 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
795 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
796 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
797 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
798 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
801 void Magick::Options::transformSkewY(double skewy_)
805 current=_drawInfo->affine;
815 affine.rx=tan(DegreesToRadians(fmod(skewy_,360.0)));
818 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
819 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
820 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
821 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
822 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
823 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
826 void Magick::Options::type(const Magick::ImageType type_)
828 _imageInfo->type=type_;
831 Magick::ImageType Magick::Options::type(void) const
833 return(_imageInfo->type);
836 void Magick::Options::verbose(bool verboseFlag_)
838 _imageInfo->verbose=(MagickBooleanType) verboseFlag_;
841 bool Magick::Options::verbose(void) const
843 return(static_cast<bool>(_imageInfo->verbose));
846 void Magick::Options::view(const std::string &view_)
848 if (view_.length() == 0)
849 _imageInfo->view=(char *) RelinquishMagickMemory(_imageInfo->view);
851 Magick::CloneString(&_imageInfo->view, view_);
854 std::string Magick::Options::view(void) const
856 if (_imageInfo->view)
857 return(std::string(_imageInfo->view));
859 return(std::string());
862 void Magick::Options::x11Display(const std::string &display_)
864 if (display_.length() == 0)
865 _imageInfo->server_name=(char *) RelinquishMagickMemory(
866 _imageInfo->server_name);
868 Magick::CloneString(&_imageInfo->server_name,display_);
871 std::string Magick::Options::x11Display(void) const
873 if (_imageInfo->server_name)
874 return(std::string( _imageInfo->server_name));
876 return(std::string());
879 MagickCore::DrawInfo *Magick::Options::drawInfo(void)
884 MagickCore::ImageInfo *Magick::Options::imageInfo(void)
889 MagickCore::QuantizeInfo *Magick::Options::quantizeInfo(void)
891 return(_quantizeInfo);
894 Magick::Options::Options(const MagickCore::ImageInfo* imageInfo_,
895 const MagickCore::QuantizeInfo* quantizeInfo_,
896 const MagickCore::DrawInfo* drawInfo_)
901 _imageInfo=CloneImageInfo(imageInfo_);
902 _quantizeInfo=CloneQuantizeInfo(quantizeInfo_);
903 _drawInfo=CloneDrawInfo(imageInfo_,drawInfo_);