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)
26 Magick::Options::Options(void)
27 : _imageInfo(static_cast<ImageInfo*>(AcquireMagickMemory(
29 _quantizeInfo(static_cast<QuantizeInfo*>(AcquireMagickMemory(
30 sizeof(QuantizeInfo)))),
31 _drawInfo(static_cast<DrawInfo*>(AcquireMagickMemory(sizeof(DrawInfo))))
33 // Initialize image info with defaults
34 GetImageInfo(_imageInfo);
36 // Initialize quantization info
37 GetQuantizeInfo(_quantizeInfo);
39 // Initialize drawing info
40 GetDrawInfo(_imageInfo,_drawInfo);
43 Magick::Options::Options(const Magick::Options& options_)
44 : _imageInfo(CloneImageInfo(options_._imageInfo )),
45 _quantizeInfo(CloneQuantizeInfo(options_._quantizeInfo)),
46 _drawInfo(CloneDrawInfo(_imageInfo,options_._drawInfo))
50 Magick::Options::~Options()
53 _imageInfo=DestroyImageInfo(_imageInfo);
55 // Destroy quantization info
56 _quantizeInfo=DestroyQuantizeInfo(_quantizeInfo);
58 // Destroy drawing info
59 _drawInfo=DestroyDrawInfo(_drawInfo);
62 void Magick::Options::antiAlias(bool flag_)
64 _drawInfo->text_antialias=static_cast<MagickBooleanType>(
65 flag_ ? MagickTrue : MagickFalse);
68 bool Magick::Options::antiAlias(void) const
70 return(static_cast<bool>(_drawInfo->text_antialias));
73 void Magick::Options::adjoin(bool flag_)
75 _imageInfo->adjoin=static_cast<MagickBooleanType>(
76 flag_ ? MagickTrue : MagickFalse);
79 bool Magick::Options::adjoin(void) const
81 return(static_cast<bool>(_imageInfo->adjoin));
84 void Magick::Options::backgroundColor(const Magick::Color &color_)
86 _imageInfo->background_color=color_;
89 Magick::Color Magick::Options::backgroundColor(void) const
91 return(Magick::Color(_imageInfo->background_color));
94 void Magick::Options::backgroundTexture(const std::string &backgroundTexture_)
96 if (backgroundTexture_.length() == 0)
97 _imageInfo->texture=(char *) RelinquishMagickMemory(_imageInfo->texture);
99 Magick::CloneString(&_imageInfo->texture,backgroundTexture_);
102 std::string Magick::Options::backgroundTexture(void) const
104 if (_imageInfo->texture)
105 return(std::string(_imageInfo->texture));
107 return(std::string());
110 void Magick::Options::borderColor(const Color &color_)
112 _imageInfo->border_color=color_;
113 _drawInfo->border_color=color_;
116 Magick::Color Magick::Options::borderColor(void) const
118 return(Magick::Color(_imageInfo->border_color));
121 void Magick::Options::boxColor(const Magick::Color &boxColor_)
123 _drawInfo->undercolor=boxColor_;
126 Magick::Color Magick::Options::boxColor(void) const
128 return(Magick::Color(_drawInfo->undercolor));
131 void Magick::Options::colorspaceType(Magick::ColorspaceType colorspace_)
133 _imageInfo->colorspace=colorspace_;
136 Magick::ColorspaceType Magick::Options::colorspaceType(void) const
138 return(static_cast<Magick::ColorspaceType>(_imageInfo->colorspace));
141 void Magick::Options::compressType(CompressionType compressType_)
143 _imageInfo->compression=compressType_;
146 Magick::CompressionType Magick::Options::compressType(void) const
148 return(static_cast<Magick::CompressionType>(_imageInfo->compression));
151 void Magick::Options::colorFuzz(double fuzz_)
153 _imageInfo->fuzz=fuzz_;
156 double Magick::Options::colorFuzz(void) const
158 return(_imageInfo->fuzz);
161 void Magick::Options::debug(bool flag_)
164 SetLogEventMask("All");
166 SetLogEventMask("None");
169 bool Magick::Options::debug(void) const
171 if (IsEventLogging())
176 void Magick::Options::density(const Magick::Geometry &density_)
178 if ( !density_.isValid() )
179 _imageInfo->density=(char *) RelinquishMagickMemory(_imageInfo->density);
181 Magick::CloneString(&_imageInfo->density,density_);
184 Magick::Geometry Magick::Options::density(void) const
186 if (_imageInfo->density)
187 return(Geometry(_imageInfo->density));
192 void Magick::Options::depth(size_t depth_)
194 _imageInfo->depth=depth_;
197 size_t Magick::Options::depth(void) const
199 return(_imageInfo->depth);
202 void Magick::Options::endian(Magick::EndianType endian_)
204 _imageInfo->endian=endian_;
207 Magick::EndianType Magick::Options::endian(void) const
209 return(_imageInfo->endian);
212 void Magick::Options::file(FILE *file_)
214 SetImageInfoFile(_imageInfo,file_);
217 FILE *Magick::Options::file(void) const
219 return(GetImageInfoFile(_imageInfo));
222 void Magick::Options::fileName(const std::string &fileName_)
224 fileName_.copy(_imageInfo->filename,MaxTextExtent-1);
225 if (fileName_.length() > MaxTextExtent-1)
226 _imageInfo->filename[MaxTextExtent-1]=0;
228 _imageInfo->filename[fileName_.length()]=0;
231 std::string Magick::Options::fileName(void) const
233 return(std::string(_imageInfo->filename));
236 void Magick::Options::fillColor(const Magick::Color &fillColor_)
238 _drawInfo->fill=fillColor_;
239 if (fillColor_ == Magick::Color())
240 fillPattern((const MagickCore::Image*) NULL);
243 Magick::Color Magick::Options::fillColor(void) const
245 return(_drawInfo->fill);
248 void Magick::Options::fillPattern(const MagickCore::Image *fillPattern_)
250 if (_drawInfo->fill_pattern)
251 _drawInfo->fill_pattern=DestroyImageList(_drawInfo->fill_pattern);
256 _drawInfo->fill_pattern=CloneImage(const_cast<MagickCore::Image*>(
257 fillPattern_),0,0,static_cast<MagickBooleanType>(MagickTrue),
263 const MagickCore::Image *Magick::Options::fillPattern(void) const
265 return(_drawInfo->fill_pattern);
268 void Magick::Options::fillRule(const Magick::FillRule &fillRule_)
270 _drawInfo->fill_rule=fillRule_;
273 Magick::FillRule Magick::Options::fillRule(void) const
275 return(_drawInfo->fill_rule);
278 void Magick::Options::font(const std::string &font_)
280 if (font_.length() == 0)
282 _imageInfo->font=(char *) RelinquishMagickMemory(_imageInfo->font);
283 _drawInfo->font=(char *) RelinquishMagickMemory(_drawInfo->font);
287 Magick::CloneString(&_imageInfo->font,font_);
288 Magick::CloneString(&_drawInfo->font,font_);
292 std::string Magick::Options::font(void) const
294 if (_imageInfo->font)
295 return(std::string(_imageInfo->font));
297 return(std::string());
300 void Magick::Options::fontPointsize(double pointSize_)
302 _imageInfo->pointsize=pointSize_;
303 _drawInfo->pointsize=pointSize_;
306 double Magick::Options::fontPointsize(void) const
308 return(_imageInfo->pointsize);
311 std::string Magick::Options::format(void) const
317 if (*_imageInfo->magick != '\0' )
318 magick_info = GetMagickInfo(_imageInfo->magick,&exceptionInfo);
321 if ((magick_info != 0) && (*magick_info->description != '\0'))
322 return(std::string( magick_info->description));
324 return(std::string());
327 void Magick::Options::interlaceType(Magick::InterlaceType interlace_)
329 _imageInfo->interlace=interlace_;
332 Magick::InterlaceType Magick::Options::interlaceType(void) const
334 return(static_cast<Magick::InterlaceType>(_imageInfo->interlace));
337 void Magick::Options::magick(const std::string &magick_)
339 FormatLocaleString(_imageInfo->filename,MaxTextExtent,"%.1024s:",
342 SetImageInfo(_imageInfo,1,&exceptionInfo);
343 if (*_imageInfo->magick == '\0')
344 throwExceptionExplicit(OptionWarning, "Unrecognized image format",
346 (void) DestroyExceptionInfo(&exceptionInfo);
349 std::string Magick::Options::magick(void) const
351 if (_imageInfo->magick && *_imageInfo->magick)
352 return(std::string(_imageInfo->magick));
354 return(std::string());
357 void Magick::Options::matteColor(const Magick::Color &matteColor_)
359 _imageInfo->matte_color=matteColor_;
362 Magick::Color Magick::Options::matteColor(void) const
364 return(Magick::Color(_imageInfo->matte_color));
367 void Magick::Options::monochrome(bool monochromeFlag_)
369 _imageInfo->monochrome=(MagickBooleanType) monochromeFlag_;
372 bool Magick::Options::monochrome(void) const
374 return(static_cast<bool>(_imageInfo->monochrome));
377 void Magick::Options::page(const Magick::Geometry &pageSize_)
379 if (!pageSize_.isValid())
380 _imageInfo->page=(char *) RelinquishMagickMemory(_imageInfo->page);
382 Magick::CloneString(&_imageInfo->page,pageSize_);
385 Magick::Geometry Magick::Options::page(void) const
387 if (_imageInfo->page)
388 return(Geometry(_imageInfo->page));
393 void Magick::Options::quality(size_t quality_)
395 _imageInfo->quality=quality_;
398 size_t Magick::Options::quality(void) const
400 return(_imageInfo->quality);
403 void Magick::Options::quantizeColors(size_t colors_)
405 _quantizeInfo->number_colors=colors_;
408 size_t Magick::Options::quantizeColors(void) const
410 return(_quantizeInfo->number_colors);
413 void Magick::Options::quantizeColorSpace(Magick::ColorspaceType colorSpace_)
415 _quantizeInfo->colorspace=colorSpace_;
418 Magick::ColorspaceType Magick::Options::quantizeColorSpace(void) const
420 return(static_cast<Magick::ColorspaceType>(_quantizeInfo->colorspace));
423 void Magick::Options::quantizeDither(bool ditherFlag_)
425 _imageInfo->dither=(MagickBooleanType) ditherFlag_;
426 _quantizeInfo->dither_method=ditherFlag_ ? RiemersmaDitherMethod :
430 bool Magick::Options::quantizeDither(void) const
432 return(static_cast<bool>(_imageInfo->dither));
435 void Magick::Options::quantizeDitherMethod(DitherMethod ditherMethod_)
437 _quantizeInfo->dither_method=ditherMethod_;
440 MagickCore::DitherMethod Magick::Options::quantizeDitherMethod(void) const
442 return(_quantizeInfo->dither_method);
445 void Magick::Options::quantizeTreeDepth(size_t treeDepth_)
447 _quantizeInfo->tree_depth=treeDepth_;
450 size_t Magick::Options::quantizeTreeDepth(void) const
452 return(_quantizeInfo->tree_depth);
455 void Magick::Options::resolutionUnits(Magick::ResolutionType resolutionUnits_)
457 _imageInfo->units=resolutionUnits_;
460 Magick::ResolutionType Magick::Options::resolutionUnits(void) const
462 return(static_cast<Magick::ResolutionType>(_imageInfo->units));
465 void Magick::Options::samplingFactor(const std::string &samplingFactor_)
467 if (samplingFactor_.length() == 0)
468 _imageInfo->sampling_factor=(char *) RelinquishMagickMemory(
469 _imageInfo->sampling_factor);
471 Magick::CloneString(&_imageInfo->sampling_factor,samplingFactor_);
474 std::string Magick::Options::samplingFactor(void) const
476 if (_imageInfo->sampling_factor)
477 return(std::string(_imageInfo->sampling_factor));
479 return(std::string());
482 void Magick::Options::size(const Geometry &geometry_)
484 _imageInfo->size=(char *) RelinquishMagickMemory(_imageInfo->size);
486 if (geometry_.isValid())
487 Magick::CloneString(&_imageInfo->size,geometry_);
490 Magick::Geometry Magick::Options::size(void) const
492 if (_imageInfo->size)
493 return(Geometry(_imageInfo->size));
498 void Magick::Options::strokeAntiAlias(bool flag_)
500 flag_ ? _drawInfo->stroke_antialias=MagickTrue :
501 _drawInfo->stroke_antialias=MagickFalse;
504 bool Magick::Options::strokeAntiAlias(void) const
506 return(_drawInfo->stroke_antialias != 0 ? true : false);
509 void Magick::Options::strokeColor(const Magick::Color &strokeColor_)
511 _drawInfo->stroke=strokeColor_;
514 Magick::Color Magick::Options::strokeColor(void) const
516 return(_drawInfo->stroke);
519 void Magick::Options::strokeDashArray(const double *strokeDashArray_)
521 _drawInfo->dash_pattern=(double *) RelinquishMagickMemory(
522 _drawInfo->dash_pattern);
528 // Count elements in dash array
529 for (x=0; strokeDashArray_[x]; x++) ;
531 _drawInfo->dash_pattern=static_cast<double*>(AcquireMagickMemory((x+1)*
534 memcpy(_drawInfo->dash_pattern,strokeDashArray_,(x+1)*sizeof(double));
538 const double *Magick::Options::strokeDashArray(void) const
540 return(_drawInfo->dash_pattern);
543 void Magick::Options::strokeDashOffset(double strokeDashOffset_)
545 _drawInfo->dash_offset=strokeDashOffset_;
548 double Magick::Options::strokeDashOffset(void) const
550 return(_drawInfo->dash_offset);
553 void Magick::Options::strokeLineCap(Magick::LineCap lineCap_)
555 _drawInfo->linecap=lineCap_;
558 Magick::LineCap Magick::Options::strokeLineCap(void) const
560 return(_drawInfo->linecap);
563 void Magick::Options::strokeLineJoin(Magick::LineJoin lineJoin_)
565 _drawInfo->linejoin=lineJoin_;
568 Magick::LineJoin Magick::Options::strokeLineJoin(void) const
570 return(_drawInfo->linejoin);
573 void Magick::Options::strokeMiterLimit(size_t miterLimit_)
575 _drawInfo->miterlimit=miterLimit_;
578 size_t Magick::Options::strokeMiterLimit(void) const
580 return(_drawInfo->miterlimit);
583 void Magick::Options::strokePattern(const MagickCore::Image *strokePattern_)
585 if (_drawInfo->stroke_pattern)
586 _drawInfo->stroke_pattern=DestroyImageList(_drawInfo->stroke_pattern);
591 _drawInfo->stroke_pattern=CloneImage( const_cast<MagickCore::Image*>(
592 strokePattern_),0,0,MagickTrue,&exceptionInfo);
597 const MagickCore::Image *Magick::Options::strokePattern(void) const
599 return(_drawInfo->stroke_pattern);
602 void Magick::Options::strokeWidth(double strokeWidth_)
604 _drawInfo->stroke_width=strokeWidth_;
607 double Magick::Options::strokeWidth(void) const
609 return(_drawInfo->stroke_width);
612 void Magick::Options::subImage(size_t subImage_)
614 _imageInfo->scene=subImage_;
617 size_t Magick::Options::subImage(void) const
619 return(_imageInfo->scene);
622 void Magick::Options::subRange(size_t subRange_)
624 _imageInfo->number_scenes=subRange_;
627 size_t Magick::Options::subRange(void) const
629 return(_imageInfo->number_scenes);
632 void Magick::Options::textDirection(DirectionType direction_)
634 _drawInfo->direction=direction_;
637 Magick::DirectionType Magick::Options::textDirection() const
639 return(_drawInfo->direction);
642 void Magick::Options::textEncoding(const std::string &encoding_)
644 CloneString(&_drawInfo->encoding,encoding_.c_str());
647 std::string Magick::Options::textEncoding(void) const
649 if (_drawInfo->encoding && *_drawInfo->encoding)
650 return(std::string(_drawInfo->encoding));
652 return(std::string());
655 void Magick::Options::textGravity(GravityType gravity_)
657 _drawInfo->gravity=gravity_;
660 Magick::GravityType Magick::Options::textGravity() const
662 return(_drawInfo->gravity);
665 void Magick::Options::textInterlineSpacing(double spacing_)
667 _drawInfo->interline_spacing=spacing_;
670 double Magick::Options::textInterlineSpacing(void) const
672 return(_drawInfo->interline_spacing);
675 void Magick::Options::textInterwordSpacing(double spacing_)
677 _drawInfo->interword_spacing=spacing_;
680 double Magick::Options::textInterwordSpacing(void) const
682 return(_drawInfo->interword_spacing);
685 void Magick::Options::textKerning(double kerning_)
687 _drawInfo->kerning=kerning_;
690 double Magick::Options::textKerning(void) const
692 return(_drawInfo->kerning);
695 void Magick::Options::transformOrigin(double tx_,double ty_)
699 current=_drawInfo->affine;
711 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
712 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
713 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
714 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
715 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
716 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
719 void Magick::Options::transformReset(void)
721 _drawInfo->affine.sx=1.0;
722 _drawInfo->affine.rx=0.0;
723 _drawInfo->affine.ry=0.0;
724 _drawInfo->affine.sy=1.0;
725 _drawInfo->affine.tx=0.0;
726 _drawInfo->affine.ty=0.0;
729 void Magick::Options::transformRotation(double angle_)
733 current=_drawInfo->affine;
742 affine.sx=cos(DegreesToRadians(fmod(angle_,360.0)));
743 affine.rx=(-sin(DegreesToRadians(fmod(angle_,360.0))));
744 affine.ry=sin(DegreesToRadians(fmod(angle_,360.0)));
745 affine.sy=cos(DegreesToRadians(fmod(angle_,360.0)));
747 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
748 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
749 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
750 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
751 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
752 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
755 void Magick::Options::transformScale(double sx_,double sy_)
759 current=_drawInfo->affine;
771 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
772 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
773 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
774 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
775 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
776 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
779 void Magick::Options::transformSkewX(double skewx_)
783 current=_drawInfo->affine;
793 affine.ry=tan(DegreesToRadians(fmod(skewx_,360.0)));
796 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
797 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
798 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
799 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
800 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
801 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
804 void Magick::Options::transformSkewY(double skewy_)
808 current=_drawInfo->affine;
818 affine.rx=tan(DegreesToRadians(fmod(skewy_,360.0)));
821 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
822 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
823 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
824 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
825 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
826 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
829 void Magick::Options::type(const Magick::ImageType type_)
831 _imageInfo->type=type_;
834 Magick::ImageType Magick::Options::type(void) const
836 return(_imageInfo->type);
839 void Magick::Options::verbose(bool verboseFlag_)
841 _imageInfo->verbose=(MagickBooleanType) verboseFlag_;
844 bool Magick::Options::verbose(void) const
846 return(static_cast<bool>(_imageInfo->verbose));
849 void Magick::Options::view(const std::string &view_)
851 if (view_.length() == 0)
852 _imageInfo->view=(char *) RelinquishMagickMemory(_imageInfo->view);
854 Magick::CloneString(&_imageInfo->view, view_);
857 std::string Magick::Options::view(void) const
859 if (_imageInfo->view)
860 return(std::string(_imageInfo->view));
862 return(std::string());
865 void Magick::Options::x11Display(const std::string &display_)
867 if (display_.length() == 0)
868 _imageInfo->server_name=(char *) RelinquishMagickMemory(
869 _imageInfo->server_name);
871 Magick::CloneString(&_imageInfo->server_name,display_);
874 std::string Magick::Options::x11Display(void) const
876 if (_imageInfo->server_name)
877 return(std::string( _imageInfo->server_name));
879 return(std::string());
882 MagickCore::DrawInfo *Magick::Options::drawInfo(void)
887 MagickCore::ImageInfo *Magick::Options::imageInfo(void)
892 MagickCore::QuantizeInfo *Magick::Options::quantizeInfo(void)
894 return(_quantizeInfo);
897 Magick::Options::Options(const MagickCore::ImageInfo* imageInfo_,
898 const MagickCore::QuantizeInfo* quantizeInfo_,
899 const MagickCore::DrawInfo* drawInfo_)
904 _imageInfo=CloneImageInfo(imageInfo_);
905 _quantizeInfo=CloneQuantizeInfo(quantizeInfo_);
906 _drawInfo=CloneDrawInfo(imageInfo_,drawInfo_);