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 DegreesToRadians(x) (MagickPI*(x)/180.0)
24 #define GetPPException \
27 GetExceptionInfo(&exceptionInfo)
28 #define ThrowPPException \
29 throwException(exceptionInfo); \
30 (void) DestroyExceptionInfo(&exceptionInfo)
32 Magick::Options::Options(void)
33 : _imageInfo(static_cast<ImageInfo*>(AcquireMagickMemory(
35 _quantizeInfo(static_cast<QuantizeInfo*>(AcquireMagickMemory(
36 sizeof(QuantizeInfo)))),
37 _drawInfo(static_cast<DrawInfo*>(AcquireMagickMemory(sizeof(DrawInfo))))
39 // Initialize image info with defaults
40 GetImageInfo(_imageInfo);
42 // Initialize quantization info
43 GetQuantizeInfo(_quantizeInfo);
45 // Initialize drawing info
46 GetDrawInfo(_imageInfo,_drawInfo);
49 Magick::Options::Options(const Magick::Options& options_)
50 : _imageInfo(CloneImageInfo(options_._imageInfo )),
51 _quantizeInfo(CloneQuantizeInfo(options_._quantizeInfo)),
52 _drawInfo(CloneDrawInfo(_imageInfo,options_._drawInfo))
56 Magick::Options::~Options()
59 _imageInfo=DestroyImageInfo(_imageInfo);
61 // Destroy quantization info
62 _quantizeInfo=DestroyQuantizeInfo(_quantizeInfo);
64 // Destroy drawing info
65 _drawInfo=DestroyDrawInfo(_drawInfo);
68 void Magick::Options::antiAlias(bool flag_)
70 _drawInfo->text_antialias=static_cast<MagickBooleanType>(
71 flag_ ? MagickTrue : MagickFalse);
74 bool Magick::Options::antiAlias(void) const
76 return(static_cast<bool>(_drawInfo->text_antialias));
79 void Magick::Options::adjoin(bool flag_)
81 _imageInfo->adjoin=static_cast<MagickBooleanType>(
82 flag_ ? MagickTrue : MagickFalse);
85 bool Magick::Options::adjoin(void) const
87 return(static_cast<bool>(_imageInfo->adjoin));
90 void Magick::Options::backgroundColor(const Magick::Color &color_)
92 _imageInfo->background_color=color_;
95 Magick::Color Magick::Options::backgroundColor(void) const
97 return(Magick::Color(_imageInfo->background_color));
100 void Magick::Options::backgroundTexture(const std::string &backgroundTexture_)
102 if (backgroundTexture_.length() == 0)
103 _imageInfo->texture=(char *) RelinquishMagickMemory(_imageInfo->texture);
105 Magick::CloneString(&_imageInfo->texture,backgroundTexture_);
108 std::string Magick::Options::backgroundTexture(void) const
110 if (_imageInfo->texture)
111 return(std::string(_imageInfo->texture));
113 return(std::string());
116 void Magick::Options::borderColor(const Color &color_)
118 _imageInfo->border_color=color_;
119 _drawInfo->border_color=color_;
122 Magick::Color Magick::Options::borderColor(void) const
124 return(Magick::Color(_imageInfo->border_color));
127 void Magick::Options::boxColor(const Magick::Color &boxColor_)
129 _drawInfo->undercolor=boxColor_;
132 Magick::Color Magick::Options::boxColor(void) const
134 return(Magick::Color(_drawInfo->undercolor));
137 void Magick::Options::colorspaceType(Magick::ColorspaceType colorspace_)
139 _imageInfo->colorspace=colorspace_;
142 Magick::ColorspaceType Magick::Options::colorspaceType(void) const
144 return(static_cast<Magick::ColorspaceType>(_imageInfo->colorspace));
147 void Magick::Options::compressType(CompressionType compressType_)
149 _imageInfo->compression=compressType_;
152 Magick::CompressionType Magick::Options::compressType(void) const
154 return(static_cast<Magick::CompressionType>(_imageInfo->compression));
157 void Magick::Options::colorFuzz(double fuzz_)
159 _imageInfo->fuzz=fuzz_;
162 double Magick::Options::colorFuzz(void) const
164 return(_imageInfo->fuzz);
167 void Magick::Options::debug(bool flag_)
170 SetLogEventMask("All");
172 SetLogEventMask("None");
175 bool Magick::Options::debug(void) const
177 if (IsEventLogging())
182 void Magick::Options::density(const Magick::Geometry &density_)
184 if ( !density_.isValid() )
185 _imageInfo->density=(char *) RelinquishMagickMemory(_imageInfo->density);
187 Magick::CloneString(&_imageInfo->density,density_);
190 Magick::Geometry Magick::Options::density(void) const
192 if (_imageInfo->density)
193 return(Geometry(_imageInfo->density));
198 void Magick::Options::depth(size_t depth_)
200 _imageInfo->depth=depth_;
203 size_t Magick::Options::depth(void) const
205 return(_imageInfo->depth);
208 void Magick::Options::endian(Magick::EndianType endian_)
210 _imageInfo->endian=endian_;
213 Magick::EndianType Magick::Options::endian(void) const
215 return(_imageInfo->endian);
218 void Magick::Options::file(FILE *file_)
220 SetImageInfoFile(_imageInfo,file_);
223 FILE *Magick::Options::file(void) const
225 return(GetImageInfoFile(_imageInfo));
228 void Magick::Options::fileName(const std::string &fileName_)
230 fileName_.copy(_imageInfo->filename,MaxTextExtent-1);
231 if (fileName_.length() > MaxTextExtent-1)
232 _imageInfo->filename[MaxTextExtent-1]=0;
234 _imageInfo->filename[fileName_.length()]=0;
237 std::string Magick::Options::fileName(void) const
239 return(std::string(_imageInfo->filename));
242 void Magick::Options::fillColor(const Magick::Color &fillColor_)
244 _drawInfo->fill=fillColor_;
245 if (fillColor_ == Magick::Color())
246 fillPattern((const MagickCore::Image*) NULL);
249 Magick::Color Magick::Options::fillColor(void) const
251 return(_drawInfo->fill);
254 void Magick::Options::fillPattern(const MagickCore::Image *fillPattern_)
256 if (_drawInfo->fill_pattern)
257 _drawInfo->fill_pattern=DestroyImageList(_drawInfo->fill_pattern);
262 _drawInfo->fill_pattern=CloneImage(const_cast<MagickCore::Image*>(
263 fillPattern_),0,0,static_cast<MagickBooleanType>(MagickTrue),
269 const MagickCore::Image *Magick::Options::fillPattern(void) const
271 return(_drawInfo->fill_pattern);
274 void Magick::Options::fillRule(const Magick::FillRule &fillRule_)
276 _drawInfo->fill_rule=fillRule_;
279 Magick::FillRule Magick::Options::fillRule(void) const
281 return(_drawInfo->fill_rule);
284 void Magick::Options::font(const std::string &font_)
286 if (font_.length() == 0)
288 _imageInfo->font=(char *) RelinquishMagickMemory(_imageInfo->font);
289 _drawInfo->font=(char *) RelinquishMagickMemory(_drawInfo->font);
293 Magick::CloneString(&_imageInfo->font,font_);
294 Magick::CloneString(&_drawInfo->font,font_);
298 std::string Magick::Options::font(void) const
300 if (_imageInfo->font)
301 return(std::string(_imageInfo->font));
303 return(std::string());
306 void Magick::Options::fontPointsize(double pointSize_)
308 _imageInfo->pointsize=pointSize_;
309 _drawInfo->pointsize=pointSize_;
312 double Magick::Options::fontPointsize(void) const
314 return(_imageInfo->pointsize);
317 std::string Magick::Options::format(void) const
323 if (*_imageInfo->magick != '\0' )
324 magick_info = GetMagickInfo(_imageInfo->magick,&exceptionInfo);
327 if ((magick_info != 0) && (*magick_info->description != '\0'))
328 return(std::string( magick_info->description));
330 return(std::string());
333 void Magick::Options::interlaceType(Magick::InterlaceType interlace_)
335 _imageInfo->interlace=interlace_;
338 Magick::InterlaceType Magick::Options::interlaceType(void) const
340 return(static_cast<Magick::InterlaceType>(_imageInfo->interlace));
343 void Magick::Options::magick(const std::string &magick_)
345 FormatLocaleString(_imageInfo->filename,MaxTextExtent,"%.1024s:",
348 SetImageInfo(_imageInfo,1,&exceptionInfo);
349 if (*_imageInfo->magick == '\0')
350 throwExceptionExplicit(OptionWarning, "Unrecognized image format",
352 (void) DestroyExceptionInfo(&exceptionInfo);
355 std::string Magick::Options::magick(void) const
357 if (_imageInfo->magick && *_imageInfo->magick)
358 return(std::string(_imageInfo->magick));
360 return(std::string());
363 void Magick::Options::matteColor(const Magick::Color &matteColor_)
365 _imageInfo->matte_color=matteColor_;
368 Magick::Color Magick::Options::matteColor(void) const
370 return(Magick::Color(_imageInfo->matte_color));
373 void Magick::Options::monochrome(bool monochromeFlag_)
375 _imageInfo->monochrome=(MagickBooleanType) monochromeFlag_;
378 bool Magick::Options::monochrome(void) const
380 return(static_cast<bool>(_imageInfo->monochrome));
383 void Magick::Options::page(const Magick::Geometry &pageSize_)
385 if (!pageSize_.isValid())
386 _imageInfo->page=(char *) RelinquishMagickMemory(_imageInfo->page);
388 Magick::CloneString(&_imageInfo->page,pageSize_);
391 Magick::Geometry Magick::Options::page(void) const
393 if (_imageInfo->page)
394 return(Geometry(_imageInfo->page));
399 void Magick::Options::quality(size_t quality_)
401 _imageInfo->quality=quality_;
404 size_t Magick::Options::quality(void) const
406 return(_imageInfo->quality);
409 void Magick::Options::quantizeColors(size_t colors_)
411 _quantizeInfo->number_colors=colors_;
414 size_t Magick::Options::quantizeColors(void) const
416 return(_quantizeInfo->number_colors);
419 void Magick::Options::quantizeColorSpace(Magick::ColorspaceType colorSpace_)
421 _quantizeInfo->colorspace=colorSpace_;
424 Magick::ColorspaceType Magick::Options::quantizeColorSpace(void) const
426 return(static_cast<Magick::ColorspaceType>(_quantizeInfo->colorspace));
429 void Magick::Options::quantizeDither(bool ditherFlag_)
431 _imageInfo->dither=(MagickBooleanType) ditherFlag_;
432 _quantizeInfo->dither_method=ditherFlag_ ? RiemersmaDitherMethod :
436 bool Magick::Options::quantizeDither(void) const
438 return(static_cast<bool>(_imageInfo->dither));
441 void Magick::Options::quantizeTreeDepth(size_t treeDepth_)
443 _quantizeInfo->tree_depth=treeDepth_;
446 size_t Magick::Options::quantizeTreeDepth(void) const
448 return(_quantizeInfo->tree_depth);
451 void Magick::Options::resolutionUnits(Magick::ResolutionType resolutionUnits_)
453 _imageInfo->units=resolutionUnits_;
456 Magick::ResolutionType Magick::Options::resolutionUnits(void) const
458 return(static_cast<Magick::ResolutionType>(_imageInfo->units));
461 void Magick::Options::samplingFactor(const std::string &samplingFactor_)
463 if (samplingFactor_.length() == 0)
464 _imageInfo->sampling_factor=(char *) RelinquishMagickMemory(
465 _imageInfo->sampling_factor);
467 Magick::CloneString(&_imageInfo->sampling_factor,samplingFactor_);
470 std::string Magick::Options::samplingFactor(void) const
472 if (_imageInfo->sampling_factor)
473 return(std::string(_imageInfo->sampling_factor));
475 return(std::string());
478 void Magick::Options::size(const Geometry &geometry_)
480 _imageInfo->size=(char *) RelinquishMagickMemory(_imageInfo->size);
482 if (geometry_.isValid())
483 Magick::CloneString(&_imageInfo->size,geometry_);
486 Magick::Geometry Magick::Options::size(void) const
488 if (_imageInfo->size)
489 return(Geometry(_imageInfo->size));
494 void Magick::Options::strokeAntiAlias(bool flag_)
496 flag_ ? _drawInfo->stroke_antialias=MagickTrue :
497 _drawInfo->stroke_antialias=MagickFalse;
500 bool Magick::Options::strokeAntiAlias(void) const
502 return(_drawInfo->stroke_antialias != 0 ? true : false);
505 void Magick::Options::strokeColor(const Magick::Color &strokeColor_)
507 _drawInfo->stroke=strokeColor_;
510 Magick::Color Magick::Options::strokeColor(void) const
512 return(_drawInfo->stroke);
515 void Magick::Options::strokeDashArray(const double *strokeDashArray_)
517 _drawInfo->dash_pattern=(double *) RelinquishMagickMemory(
518 _drawInfo->dash_pattern);
524 // Count elements in dash array
525 for (x=0; strokeDashArray_[x]; x++) ;
527 _drawInfo->dash_pattern=static_cast<double*>(AcquireMagickMemory((x+1)*
530 memcpy(_drawInfo->dash_pattern,strokeDashArray_,(x+1)*sizeof(double));
534 const double *Magick::Options::strokeDashArray(void) const
536 return(_drawInfo->dash_pattern);
539 void Magick::Options::strokeDashOffset(double strokeDashOffset_)
541 _drawInfo->dash_offset=strokeDashOffset_;
544 double Magick::Options::strokeDashOffset(void) const
546 return(_drawInfo->dash_offset);
549 void Magick::Options::strokeLineCap(Magick::LineCap lineCap_)
551 _drawInfo->linecap=lineCap_;
554 Magick::LineCap Magick::Options::strokeLineCap(void) const
556 return(_drawInfo->linecap);
559 void Magick::Options::strokeLineJoin(Magick::LineJoin lineJoin_)
561 _drawInfo->linejoin=lineJoin_;
564 Magick::LineJoin Magick::Options::strokeLineJoin(void) const
566 return(_drawInfo->linejoin);
569 void Magick::Options::strokeMiterLimit(size_t miterLimit_)
571 _drawInfo->miterlimit=miterLimit_;
574 size_t Magick::Options::strokeMiterLimit(void) const
576 return(_drawInfo->miterlimit);
579 void Magick::Options::strokePattern(const MagickCore::Image *strokePattern_)
581 if (_drawInfo->stroke_pattern)
582 _drawInfo->stroke_pattern=DestroyImageList(_drawInfo->stroke_pattern);
587 _drawInfo->stroke_pattern=CloneImage( const_cast<MagickCore::Image*>(
588 strokePattern_),0,0,MagickTrue,&exceptionInfo);
593 const MagickCore::Image *Magick::Options::strokePattern(void) const
595 return(_drawInfo->stroke_pattern);
598 void Magick::Options::strokeWidth(double strokeWidth_)
600 _drawInfo->stroke_width=strokeWidth_;
603 double Magick::Options::strokeWidth(void) const
605 return(_drawInfo->stroke_width);
608 void Magick::Options::subImage(size_t subImage_)
610 _imageInfo->scene=subImage_;
613 size_t Magick::Options::subImage(void) const
615 return(_imageInfo->scene);
618 void Magick::Options::subRange(size_t subRange_)
620 _imageInfo->number_scenes=subRange_;
623 size_t Magick::Options::subRange(void) const
625 return(_imageInfo->number_scenes);
628 void Magick::Options::textEncoding(const std::string &encoding_)
630 CloneString(&_drawInfo->encoding, encoding_.c_str());
633 std::string Magick::Options::textEncoding(void) const
635 if (_drawInfo->encoding && *_drawInfo->encoding)
636 return(std::string(_drawInfo->encoding));
638 return(std::string());
641 void Magick::Options::textInterlineSpacing(double spacing_)
643 _drawInfo->interline_spacing=spacing_;
646 double Magick::Options::textInterlineSpacing(void) const
648 return(_drawInfo->interline_spacing);
651 void Magick::Options::textInterwordSpacing(double spacing_)
653 _drawInfo->interword_spacing=spacing_;
656 double Magick::Options::textInterwordSpacing(void) const
658 return(_drawInfo->interword_spacing);
661 void Magick::Options::textKerning(double kerning_)
663 _drawInfo->kerning=kerning_;
666 double Magick::Options::textKerning(void) const
668 return(_drawInfo->kerning);
671 void Magick::Options::transformOrigin(double tx_,double ty_)
675 current=_drawInfo->affine;
687 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
688 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
689 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
690 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
691 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
692 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
695 void Magick::Options::transformReset(void)
697 _drawInfo->affine.sx=1.0;
698 _drawInfo->affine.rx=0.0;
699 _drawInfo->affine.ry=0.0;
700 _drawInfo->affine.sy=1.0;
701 _drawInfo->affine.tx=0.0;
702 _drawInfo->affine.ty=0.0;
705 void Magick::Options::transformRotation(double angle_)
709 current=_drawInfo->affine;
718 affine.sx=cos(DegreesToRadians(fmod(angle_,360.0)));
719 affine.rx=(-sin(DegreesToRadians(fmod(angle_,360.0))));
720 affine.ry=sin(DegreesToRadians(fmod(angle_,360.0)));
721 affine.sy=cos(DegreesToRadians(fmod(angle_,360.0)));
723 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
724 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
725 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
726 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
727 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
728 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
731 void Magick::Options::transformScale(double sx_,double sy_)
735 current=_drawInfo->affine;
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::transformSkewX(double skewx_)
759 current=_drawInfo->affine;
769 affine.ry=tan(DegreesToRadians(fmod(skewx_,360.0)));
772 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
773 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
774 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
775 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
776 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
777 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
780 void Magick::Options::transformSkewY(double skewy_)
784 current=_drawInfo->affine;
794 affine.rx=tan(DegreesToRadians(fmod(skewy_,360.0)));
797 _drawInfo->affine.sx=current.sx*affine.sx+current.ry*affine.rx;
798 _drawInfo->affine.rx=current.rx*affine.sx+current.sy*affine.rx;
799 _drawInfo->affine.ry=current.sx*affine.ry+current.ry*affine.sy;
800 _drawInfo->affine.sy=current.rx*affine.ry+current.sy*affine.sy;
801 _drawInfo->affine.tx=current.sx*affine.tx+current.ry*affine.ty+current.tx;
802 _drawInfo->affine.ty=current.rx*affine.tx+current.sy*affine.ty+current.ty;
805 void Magick::Options::type(const Magick::ImageType type_)
807 _imageInfo->type=type_;
810 Magick::ImageType Magick::Options::type(void) const
812 return(_imageInfo->type);
815 void Magick::Options::verbose(bool verboseFlag_)
817 _imageInfo->verbose=(MagickBooleanType) verboseFlag_;
820 bool Magick::Options::verbose(void) const
822 return(static_cast<bool>(_imageInfo->verbose));
825 void Magick::Options::view(const std::string &view_)
827 if (view_.length() == 0)
828 _imageInfo->view=(char *) RelinquishMagickMemory(_imageInfo->view);
830 Magick::CloneString(&_imageInfo->view, view_);
833 std::string Magick::Options::view(void) const
835 if (_imageInfo->view)
836 return(std::string(_imageInfo->view));
838 return(std::string());
841 void Magick::Options::x11Display(const std::string &display_)
843 if (display_.length() == 0)
844 _imageInfo->server_name=(char *) RelinquishMagickMemory(
845 _imageInfo->server_name);
847 Magick::CloneString(&_imageInfo->server_name,display_);
850 std::string Magick::Options::x11Display(void) const
852 if (_imageInfo->server_name)
853 return(std::string( _imageInfo->server_name));
855 return(std::string());
858 MagickCore::DrawInfo *Magick::Options::drawInfo(void)
863 MagickCore::ImageInfo *Magick::Options::imageInfo(void)
868 MagickCore::QuantizeInfo *Magick::Options::quantizeInfo(void)
870 return(_quantizeInfo);
873 Magick::Options::Options(const MagickCore::ImageInfo* imageInfo_,
874 const MagickCore::QuantizeInfo* quantizeInfo_,
875 const MagickCore::DrawInfo* drawInfo_)
880 _imageInfo=CloneImageInfo(imageInfo_);
881 _quantizeInfo=CloneQuantizeInfo(quantizeInfo_);
882 _drawInfo=CloneDrawInfo(imageInfo_,drawInfo_);