+2010-03-05 6.6.0-3 Cristy <quetzlzacatenango@image...>
+ * The -evaluate-sequence option behaves like -evaluate except it operates
+ on a sequence of images.
+
2010-03-05 6.6.0-2 Cristy <quetzlzacatenango@image...>
* Add support for the -maximum and -minimum options.
PackageName);
goto PerlException;
}
- image=AverageImages(image,exception);
+ image=EvaluateImages(image,MeanEvaluateOperator,exception);
if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
goto PerlException;
/*
# #
# #
# #
+# E v a l u a t e I m a g e s #
+# #
+# #
+# #
+###############################################################################
+#
+#
+void
+EvaluateImages(ref)
+ Image::Magick ref=NO_INIT
+ ALIAS:
+ EvaluateImages = 1
+ evaluateimages = 2
+ PPCODE:
+ {
+ AV
+ *av;
+
+ char
+ *attribute,
+ *p;
+
+ ExceptionInfo
+ *exception;
+
+ HV
+ *hv;
+
+ Image
+ *image;
+
+ MagickEvaluateOperator
+ op;
+
+ register long
+ i;
+
+ struct PackageInfo
+ *info;
+
+ SV
+ *perl_exception,
+ *reference,
+ *rv,
+ *sv;
+
+ exception=AcquireExceptionInfo();
+ perl_exception=newSVpv("",0);
+ if (sv_isobject(ST(0)) == 0)
+ {
+ ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
+ PackageName);
+ goto PerlException;
+ }
+ reference=SvRV(ST(0));
+ hv=SvSTASH(reference);
+ image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
+ if (image == (Image *) NULL)
+ {
+ ThrowPerlException(exception,OptionError,"NoImagesDefined",
+ PackageName);
+ goto PerlException;
+ }
+ op=MeanEvaluateOperator;
+ if (items == 2)
+ {
+ long
+ in;
+
+ in=ParseMagickOption(MagickEvaluateOptions,MagickFalse,(char *)
+ SvPV(ST(1),na));
+ if (in < 0)
+ {
+ ThrowPerlException(exception,OptionError,"UnrecognizedType",
+ SvPV(ST(i),na));
+ return;
+ }
+ op=(MagickEvaluateOperator) in;
+ }
+ else
+ for (i=2; i < items; i+=2)
+ {
+ attribute=(char *) SvPV(ST(i-1),na);
+ switch (*attribute)
+ {
+ case 'O':
+ case 'o':
+ {
+ if (LocaleCompare(attribute,"operator") == 0)
+ {
+ Image
+ *next;
+
+ long
+ in;
+
+ in=!SvPOK(ST(i)) ? SvIV(ST(i)) : ParseMagickOption(
+ MagickEvaluateOptions,MagickFalse,SvPV(ST(i),na));
+ if (in < 0)
+ {
+ ThrowPerlException(exception,OptionError,"UnrecognizedType",
+ SvPV(ST(i),na));
+ return;
+ }
+ op=(MagickEvaluateOperator) in;
+ break;
+ }
+ ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+ attribute);
+ break;
+ }
+ default:
+ {
+ ThrowPerlException(exception,OptionError,"UnrecognizedAttribute",
+ attribute);
+ break;
+ }
+ }
+ }
+ image=EvaluateImages(image,op,exception);
+ if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
+ goto PerlException;
+ /*
+ Create blessed Perl array for the returned image.
+ */
+ av=newAV();
+ ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
+ SvREFCNT_dec(av);
+ AddImageToRegistry(image);
+ rv=newRV(sv);
+ av_push(av,sv_bless(rv,hv));
+ SvREFCNT_dec(sv);
+ info=GetPackageInfo(aTHX_ (void *) av,info,exception);
+ (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
+ "evaluate-%.*s",(int) (MaxTextExtent-9),
+ ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
+ (void) CopyMagickString(image->filename,info->image_info->filename,
+ MaxTextExtent);
+ SetImageInfo(info->image_info,0,exception);
+ exception=DestroyExceptionInfo(exception);
+ SvREFCNT_dec(perl_exception);
+ XSRETURN(1);
+
+ PerlException:
+ InheritPerlException(exception,perl_exception);
+ exception=DestroyExceptionInfo(exception);
+ sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
+ SvPOK_on(perl_exception);
+ ST(0)=sv_2mortal(perl_exception);
+ XSRETURN(1);
+ }
+\f
+#
+###############################################################################
+# #
+# #
+# #
# F e a t u r e s #
# #
# #
# #
# #
# #
-# M a x i m u m #
-# #
-# #
-# #
-###############################################################################
-#
-#
-void
-Maximum(ref)
- Image::Magick ref=NO_INIT
- ALIAS:
- MaximumImage = 1
- maximum = 2
- maximumimage = 3
- PPCODE:
- {
- AV
- *av;
-
- char
- *p;
-
- ExceptionInfo
- *exception;
-
- HV
- *hv;
-
- Image
- *image;
-
- struct PackageInfo
- *info;
-
- SV
- *perl_exception,
- *reference,
- *rv,
- *sv;
-
- exception=AcquireExceptionInfo();
- perl_exception=newSVpv("",0);
- if (sv_isobject(ST(0)) == 0)
- {
- ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
- PackageName);
- goto PerlException;
- }
- reference=SvRV(ST(0));
- hv=SvSTASH(reference);
- image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
- if (image == (Image *) NULL)
- {
- ThrowPerlException(exception,OptionError,"NoImagesDefined",
- PackageName);
- goto PerlException;
- }
- image=MaximumImages(image,exception);
- if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
- goto PerlException;
- /*
- Create blessed Perl array for the returned image.
- */
- av=newAV();
- ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
- SvREFCNT_dec(av);
- AddImageToRegistry(image);
- rv=newRV(sv);
- av_push(av,sv_bless(rv,hv));
- SvREFCNT_dec(sv);
- info=GetPackageInfo(aTHX_ (void *) av,info,exception);
- (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
- "max-%.*s",(int) (MaxTextExtent-9),
- ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
- (void) CopyMagickString(image->filename,info->image_info->filename,
- MaxTextExtent);
- SetImageInfo(info->image_info,0,exception);
- exception=DestroyExceptionInfo(exception);
- SvREFCNT_dec(perl_exception);
- XSRETURN(1);
-
- PerlException:
- InheritPerlException(exception,perl_exception);
- exception=DestroyExceptionInfo(exception);
- sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
- SvPOK_on(perl_exception);
- ST(0)=sv_2mortal(perl_exception);
- XSRETURN(1);
- }
-\f
-#
-###############################################################################
-# #
-# #
-# #
-# M i n i m u m #
-# #
-# #
-# #
-###############################################################################
-#
-#
-void
-Minimum(ref)
- Image::Magick ref=NO_INIT
- ALIAS:
- MinimumImage = 1
- minimum = 2
- minimumimage = 3
- PPCODE:
- {
- AV
- *av;
-
- char
- *p;
-
- ExceptionInfo
- *exception;
-
- HV
- *hv;
-
- Image
- *image;
-
- struct PackageInfo
- *info;
-
- SV
- *perl_exception,
- *reference,
- *rv,
- *sv;
-
- exception=AcquireExceptionInfo();
- perl_exception=newSVpv("",0);
- if (sv_isobject(ST(0)) == 0)
- {
- ThrowPerlException(exception,OptionError,"ReferenceIsNotMyType",
- PackageName);
- goto PerlException;
- }
- reference=SvRV(ST(0));
- hv=SvSTASH(reference);
- image=SetupList(aTHX_ reference,&info,(SV ***) NULL,exception);
- if (image == (Image *) NULL)
- {
- ThrowPerlException(exception,OptionError,"NoImagesDefined",
- PackageName);
- goto PerlException;
- }
- image=MinimumImages(image,exception);
- if ((image == (Image *) NULL) || (exception->severity >= ErrorException))
- goto PerlException;
- /*
- Create blessed Perl array for the returned image.
- */
- av=newAV();
- ST(0)=sv_2mortal(sv_bless(newRV((SV *) av),hv));
- SvREFCNT_dec(av);
- AddImageToRegistry(image);
- rv=newRV(sv);
- av_push(av,sv_bless(rv,hv));
- SvREFCNT_dec(sv);
- info=GetPackageInfo(aTHX_ (void *) av,info,exception);
- (void) FormatMagickString(info->image_info->filename,MaxTextExtent,
- "minimum-%.*s",(int) (MaxTextExtent-9),
- ((p=strrchr(image->filename,'/')) ? p+1 : image->filename));
- (void) CopyMagickString(image->filename,info->image_info->filename,
- MaxTextExtent);
- SetImageInfo(info->image_info,0,exception);
- exception=DestroyExceptionInfo(exception);
- SvREFCNT_dec(perl_exception);
- XSRETURN(1);
-
- PerlException:
- InheritPerlException(exception,perl_exception);
- exception=DestroyExceptionInfo(exception);
- sv_setiv(perl_exception,(IV) SvCUR(perl_exception) != 0);
- SvPOK_on(perl_exception);
- ST(0)=sv_2mortal(perl_exception);
- XSRETURN(1);
- }
-\f
-#
-###############################################################################
-# #
-# #
-# #
# M o g r i f y #
# #
# #
#include "magick/semaphore.h"
#include "magick/segment.h"
#include "magick/splay-tree.h"
+#include "magick/statistic.h"
#include "magick/string_.h"
#include "magick/threshold.h"
#include "magick/transform.h"
% %
% %
% A c q u i r e I m a g e P i x e l s %
-% %
-% %
+% % % %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%
% Pixels accessed via the returned pointer represent a simple array of type
% PixelPacket. If the image type is CMYK or the storage class is PseudoClass,
-% call GetAuthenticIndexQueue() after invoking GetAuthenticPixels() to access the
-% black color component or to obtain the colormap indexes (of type IndexPacket)
-% corresponding to the region.
+% call GetAuthenticIndexQueue() after invoking GetAuthenticPixels() to access
+% the black color component or to obtain the colormap indexes (of type
+% IndexPacket) corresponding to the region.
%
% If you plan to modify the pixels, use GetAuthenticPixels() instead.
%
% %
% %
% %
-% A c q u i r e S t r i n g %
+% A l l o c a t e S t r i n g %
% %
% %
% %
% %
% %
% %
+% A v e r a g e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% AverageImages() takes a set of images and averages them together. Each
+% image in the set must have the same width and height. AverageImages()
+% returns a single image with each corresponding pixel component of each
+% image averaged. On failure, a NULL image is returned and exception
+% describes the reason for the failure.
+%
+% The format of the AverageImages method is:
+%
+% Image *AverageImages(Image *images,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: the image sequence.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+MagickExport Image *AverageImages(const Image *images,ExceptionInfo *exception)
+{
+ return(EvaluateImages(images,MeanEvaluateOperator,exception));
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% C h a n n e l I m a g e %
% %
% %
% %
% %
% %
+% M a x i m u m I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MaximumImages() returns the maximum intensity of an image sequence.
+%
+% The format of the MaxImages method is:
+%
+% Image *MaximumImages(Image *images,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o images: the image sequence.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+MagickExport Image *MaximumImages(const Image *images,ExceptionInfo *exception)
+{
+ return(EvaluateImages(images,MinEvaluateOperator,exception));
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M i n i m u m I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MinimumImages() returns the minimum intensity of an image sequence.
+%
+% The format of the MinimumImages method is:
+%
+% Image *MinimumImages(Image *images,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o images: the image sequence.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+MagickExport Image *MinimumImages(const Image *images,ExceptionInfo *exception)
+{
+ return(EvaluateImages(images,MinEvaluateOperator,exception));
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% M o s a i c I m a g e s %
% %
% %
*TranslateText(const ImageInfo *,Image *,const char *)
magick_attribute((deprecated));
+extern MagickExport Image
+ *AverageImages(const Image *,ExceptionInfo *),
+ *MaximumImages(const Image *,ExceptionInfo *),
+ *MinimumImages(const Image *,ExceptionInfo *);
+
extern MagickExport const ImageAttribute
*GetImageAttribute(const Image *,const char *),
*GetImageClippingPathAttribute(Image *) magick_attribute((deprecated)),
{ "-equalize", 0L, MagickFalse },
{ "+evaluate", 0L, MagickFalse },
{ "-evaluate", 2L, MagickFalse },
+ { "+evaluate-sequence", 0L, MagickFalse },
+ { "-evaluate-sequence", 1L, MagickFalse },
{ "+extent", 0L, MagickFalse },
{ "-extent", 1L, MagickFalse },
{ "+extract", 0L, MagickFalse },
{ "LeftShift", (long) LeftShiftEvaluateOperator, MagickFalse },
{ "Log", (long) LogEvaluateOperator, MagickFalse },
{ "Max", (long) MaxEvaluateOperator, MagickFalse },
+ { "Mean", (long) MeanEvaluateOperator, MagickFalse },
{ "Min", (long) MinEvaluateOperator, MagickFalse },
{ "MultiplicativeNoise", (long) MultiplicativeNoiseEvaluateOperator, MagickFalse },
{ "Multiply", (long) MultiplyEvaluateOperator, MagickFalse },
{ "debug", MagickTrue, MagickFalse },
{ "deconstruct", MagickTrue, MagickFalse },
{ "delete", MagickTrue, MagickFalse },
+ { "evaluate-seqence", MagickTrue, MagickFalse },
{ "fft", MagickTrue, MagickFalse },
{ "flatten", MagickTrue, MagickFalse },
{ "fx", MagickTrue, MagickFalse },
% %
% %
% %
-% A v e r a g e I m a g e s %
+% E v a l u a t e I m a g e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% AverageImages() takes a set of images and averages them together. Each
-% image in the set must have the same width and height. AverageImages()
-% returns a single image with each corresponding pixel component of each
-% image averaged. On failure, a NULL image is returned and exception
-% describes the reason for the failure.
+% EvaluateImage() applies a value to the image with an arithmetic, relational,
+% or logical operator to an image. Use these operations to lighten or darken
+% an image, to increase or decrease contrast in an image, or to produce the
+% "negative" of an image.
%
-% The format of the AverageImages method is:
+% The format of the EvaluateImageChannel method is:
%
-% Image *AverageImages(Image *images,ExceptionInfo *exception)
+% MagickBooleanType EvaluateImage(Image *image,
+% const MagickEvaluateOperator op,const double value,
+% ExceptionInfo *exception)
+% MagickBooleanType EvaluateImages(Image *images,
+% const MagickEvaluateOperator op,const double value,
+% ExceptionInfo *exception)
+% MagickBooleanType EvaluateImageChannel(Image *image,
+% const ChannelType channel,const MagickEvaluateOperator op,
+% const double value,ExceptionInfo *exception)
%
% A description of each parameter follows:
%
-% o image: the image sequence.
+% o image: the image.
+%
+% o channel: the channel.
+%
+% o op: A channel op.
+%
+% o value: A value value.
%
% o exception: return any errors or warnings in this structure.
%
return(pixels);
}
-MagickExport Image *AverageImages(const Image *images,ExceptionInfo *exception)
-{
-#define AverageImageTag "Average/Image"
-
- CacheView
- *average_view;
-
- const Image
- *next;
-
- Image
- *average_image;
-
- long
- progress,
- y;
-
- MagickBooleanType
- status;
-
- MagickPixelPacket
- **restrict average_pixels,
- zero;
-
- unsigned long
- number_images;
-
- /*
- Ensure the image are the same size.
- */
- assert(images != (Image *) NULL);
- assert(images->signature == MagickSignature);
- if (images->debug != MagickFalse)
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
- assert(exception != (ExceptionInfo *) NULL);
- assert(exception->signature == MagickSignature);
- for (next=images; next != (Image *) NULL; next=GetNextImageInList(next))
- if ((next->columns != images->columns) || (next->rows != images->rows))
- {
- (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
- "ImageWidthsOrHeightsDiffer","`%s'",images->filename);
- return((Image *) NULL);
- }
- /*
- Initialize average next attributes.
- */
- average_image=CloneImage(images,images->columns,images->rows,MagickTrue,
- exception);
- if (average_image == (Image *) NULL)
- return((Image *) NULL);
- if (SetImageStorageClass(average_image,DirectClass) == MagickFalse)
- {
- InheritException(exception,&average_image->exception);
- average_image=DestroyImage(average_image);
- return((Image *) NULL);
- }
- average_pixels=AcquirePixelThreadSet(images);
- if (average_pixels == (MagickPixelPacket **) NULL)
- {
- average_image=DestroyImage(average_image);
- (void) ThrowMagickException(exception,GetMagickModule(),
- ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
- return((Image *) NULL);
- }
- /*
- Average image pixels.
- */
- status=MagickTrue;
- progress=0;
- GetMagickPixelPacket(images,&zero);
- number_images=GetImageListLength(images);
- average_view=AcquireCacheView(average_image);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(dynamic) shared(progress,status)
-#endif
- for (y=0; y < (long) average_image->rows; y++)
- {
- CacheView
- *image_view;
-
- const Image
- *next;
-
- MagickPixelPacket
- pixel;
-
- register IndexPacket
- *restrict average_indexes;
-
- register long
- i,
- id,
- x;
-
- register MagickPixelPacket
- *average_pixel;
-
- register PixelPacket
- *restrict q;
-
- if (status == MagickFalse)
- continue;
- q=QueueCacheViewAuthenticPixels(average_view,0,y,average_image->columns,1,
- exception);
- if (q == (PixelPacket *) NULL)
- {
- status=MagickFalse;
- continue;
- }
- average_indexes=GetCacheViewAuthenticIndexQueue(average_view);
- pixel=zero;
- id=GetOpenMPThreadId();
- average_pixel=average_pixels[id];
- for (x=0; x < (long) average_image->columns; x++)
- average_pixel[x]=zero;
- next=images;
- for (i=0; i < (long) number_images; i++)
- {
- register const IndexPacket
- *indexes;
-
- register const PixelPacket
- *p;
-
- image_view=AcquireCacheView(next);
- p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
- if (p == (const PixelPacket *) NULL)
- {
- image_view=DestroyCacheView(image_view);
- break;
- }
- indexes=GetCacheViewVirtualIndexQueue(image_view);
- for (x=0; x < (long) next->columns; x++)
- {
- SetMagickPixelPacket(next,p,indexes+x,&pixel);
- average_pixel[x].red+=QuantumScale*pixel.red;
- average_pixel[x].green+=QuantumScale*pixel.green;
- average_pixel[x].blue+=QuantumScale*pixel.blue;
- average_pixel[x].opacity+=QuantumScale*pixel.opacity;
- if (average_image->colorspace == CMYKColorspace)
- average_pixel[x].index+=QuantumScale*pixel.index;
- p++;
- }
- image_view=DestroyCacheView(image_view);
- next=GetNextImageInList(next);
- }
- for (x=0; x < (long) average_image->columns; x++)
- {
- average_pixel[x].red=(MagickRealType) (QuantumRange*
- average_pixel[x].red/number_images);
- average_pixel[x].green=(MagickRealType) (QuantumRange*
- average_pixel[x].green/number_images);
- average_pixel[x].blue=(MagickRealType) (QuantumRange*
- average_pixel[x].blue/number_images);
- average_pixel[x].opacity=(MagickRealType) (QuantumRange*
- average_pixel[x].opacity/number_images);
- if (average_image->colorspace == CMYKColorspace)
- average_pixel[x].index=(MagickRealType) (QuantumRange*
- average_pixel[x].index/number_images);
- SetPixelPacket(average_image,&average_pixel[x],q,average_indexes+x);
- q++;
- }
- if (SyncCacheViewAuthenticPixels(average_view,exception) == MagickFalse)
- status=MagickFalse;
- if (images->progress_monitor != (MagickProgressMonitor) NULL)
- {
- MagickBooleanType
- proceed;
-
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_AverageImages)
-#endif
- proceed=SetImageProgress(images,AverageImageTag,progress++,
- average_image->rows);
- if (proceed == MagickFalse)
- status=MagickFalse;
- }
- }
- average_view=DestroyCacheView(average_view);
- average_pixels=DestroyPixelThreadSet(average_pixels);
- if (status == MagickFalse)
- average_image=DestroyImage(average_image);
- return(average_image);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
-% E v a l u a t e I m a g e %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% EvaluateImage() applies a value to the image with an arithmetic, relational,
-% or logical operator to an image. Use these operations to lighten or darken
-% an image, to increase or decrease contrast in an image, or to produce the
-% "negative" of an image.
-%
-% The format of the EvaluateImageChannel method is:
-%
-% MagickBooleanType EvaluateImage(Image *image,
-% const MagickEvaluateOperator op,const double value,
-% ExceptionInfo *exception)
-% MagickBooleanType EvaluateImageChannel(Image *image,
-% const ChannelType channel,const MagickEvaluateOperator op,
-% const double value,ExceptionInfo *exception)
-%
-% A description of each parameter follows:
-%
-% o image: the image.
-%
-% o channel: the channel.
-%
-% o op: A channel op.
-%
-% o value: A value value.
-%
-% o exception: return any errors or warnings in this structure.
-%
-*/
-
static inline double MagickMax(const double x,const double y)
{
if (x > y)
return(y);
}
-static Quantum ApplyEvaluateOperator(RandomInfo *random_info,Quantum pixel,
- const MagickEvaluateOperator op,const MagickRealType value)
+static MagickRealType ApplyEvaluateOperator(RandomInfo *random_info,
+ Quantum pixel,const MagickEvaluateOperator op,const MagickRealType value)
{
MagickRealType
result;
break;
}
}
- return(ClampToQuantum(result));
+ return(result);
}
MagickExport MagickBooleanType EvaluateImage(Image *image,
return(status);
}
+MagickExport Image *EvaluateImages(const Image *images,
+ const MagickEvaluateOperator op,ExceptionInfo *exception)
+{
+#define EvaluateImageTag "Evaluate/Image"
+
+ CacheView
+ *evaluate_view;
+
+ const Image
+ *next;
+
+ Image
+ *evaluate_image;
+
+ long
+ progress,
+ y;
+
+ MagickBooleanType
+ status;
+
+ MagickPixelPacket
+ **restrict evaluate_pixels,
+ zero;
+
+ RandomInfo
+ **restrict random_info;
+
+ unsigned long
+ number_images;
+
+ /*
+ Ensure the image are the same size.
+ */
+ assert(images != (Image *) NULL);
+ assert(images->signature == MagickSignature);
+ if (images->debug != MagickFalse)
+ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ for (next=images; next != (Image *) NULL; next=GetNextImageInList(next))
+ if ((next->columns != images->columns) || (next->rows != images->rows))
+ {
+ (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
+ "ImageWidthsOrHeightsDiffer","`%s'",images->filename);
+ return((Image *) NULL);
+ }
+ /*
+ Initialize evaluate next attributes.
+ */
+ evaluate_image=CloneImage(images,images->columns,images->rows,MagickTrue,
+ exception);
+ if (evaluate_image == (Image *) NULL)
+ return((Image *) NULL);
+ if (SetImageStorageClass(evaluate_image,DirectClass) == MagickFalse)
+ {
+ InheritException(exception,&evaluate_image->exception);
+ evaluate_image=DestroyImage(evaluate_image);
+ return((Image *) NULL);
+ }
+ evaluate_pixels=AcquirePixelThreadSet(images);
+ if (evaluate_pixels == (MagickPixelPacket **) NULL)
+ {
+ evaluate_image=DestroyImage(evaluate_image);
+ (void) ThrowMagickException(exception,GetMagickModule(),
+ ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
+ return((Image *) NULL);
+ }
+ /*
+ Evaluate image pixels.
+ */
+ status=MagickTrue;
+ progress=0;
+ GetMagickPixelPacket(images,&zero);
+ random_info=AcquireRandomInfoThreadSet();
+ number_images=GetImageListLength(images);
+ evaluate_view=AcquireCacheView(evaluate_image);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp parallel for schedule(dynamic) shared(progress,status)
+#endif
+ for (y=0; y < (long) evaluate_image->rows; y++)
+ {
+ CacheView
+ *image_view;
+
+ const Image
+ *next;
+
+ MagickPixelPacket
+ pixel;
+
+ register IndexPacket
+ *restrict evaluate_indexes;
+
+ register long
+ i,
+ id,
+ x;
+
+ register MagickPixelPacket
+ *evaluate_pixel;
+
+ register PixelPacket
+ *restrict q;
+
+ if (status == MagickFalse)
+ continue;
+ q=QueueCacheViewAuthenticPixels(evaluate_view,0,y,evaluate_image->columns,1,
+ exception);
+ if (q == (PixelPacket *) NULL)
+ {
+ status=MagickFalse;
+ continue;
+ }
+ evaluate_indexes=GetCacheViewAuthenticIndexQueue(evaluate_view);
+ pixel=zero;
+ id=GetOpenMPThreadId();
+ evaluate_pixel=evaluate_pixels[id];
+ for (x=0; x < (long) evaluate_image->columns; x++)
+ evaluate_pixel[x]=zero;
+ next=images;
+ for (i=0; i < (long) number_images; i++)
+ {
+ register const IndexPacket
+ *indexes;
+
+ register const PixelPacket
+ *p;
+
+ image_view=AcquireCacheView(next);
+ p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
+ if (p == (const PixelPacket *) NULL)
+ {
+ image_view=DestroyCacheView(image_view);
+ break;
+ }
+ indexes=GetCacheViewVirtualIndexQueue(image_view);
+ for (x=0; x < (long) next->columns; x++)
+ {
+ evaluate_pixel[x].red=ApplyEvaluateOperator(random_info[id],p->red,
+ op,evaluate_pixel[x].red);
+ evaluate_pixel[x].green=ApplyEvaluateOperator(random_info[id],p->green,
+ op,evaluate_pixel[x].green);
+ evaluate_pixel[x].blue=ApplyEvaluateOperator(random_info[id],p->blue,
+ op,evaluate_pixel[x].blue);
+ evaluate_pixel[x].opacity=ApplyEvaluateOperator(random_info[id],
+ p->opacity,op,evaluate_pixel[x].opacity);
+ if (evaluate_image->colorspace == CMYKColorspace)
+ evaluate_pixel[x].index=ApplyEvaluateOperator(random_info[id],
+ indexes[x],op,evaluate_pixel[x].index);
+ p++;
+ }
+ image_view=DestroyCacheView(image_view);
+ next=GetNextImageInList(next);
+ }
+ for (x=0; x < (long) evaluate_image->columns; x++)
+ {
+ q->red=ClampToQuantum(evaluate_pixel[x].red);
+ q->green=ClampToQuantum(evaluate_pixel[x].green);
+ q->blue=ClampToQuantum(evaluate_pixel[x].blue);
+ q->opacity=ClampToQuantum(evaluate_pixel[x].opacity);
+ if (evaluate_image->colorspace == CMYKColorspace)
+ evaluate_indexes[x]=ClampToQuantum(evaluate_pixel[x].index);
+ q++;
+ }
+ if (SyncCacheViewAuthenticPixels(evaluate_view,exception) == MagickFalse)
+ status=MagickFalse;
+ if (images->progress_monitor != (MagickProgressMonitor) NULL)
+ {
+ MagickBooleanType
+ proceed;
+
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp critical (MagickCore_EvaluateImages)
+#endif
+ proceed=SetImageProgress(images,EvaluateImageTag,progress++,
+ evaluate_image->rows);
+ if (proceed == MagickFalse)
+ status=MagickFalse;
+ }
+ }
+ evaluate_view=DestroyCacheView(evaluate_view);
+ evaluate_pixels=DestroyPixelThreadSet(evaluate_pixels);
+ random_info=DestroyRandomInfoThreadSet(random_info);
+ if (status == MagickFalse)
+ evaluate_image=DestroyImage(evaluate_image);
+ return(evaluate_image);
+}
+
MagickExport MagickBooleanType EvaluateImageChannel(Image *image,
const ChannelType channel,const MagickEvaluateOperator op,const double value,
ExceptionInfo *exception)
{
-#define EvaluateImageTag "Evaluate/Image "
-
CacheView
*image_view;
for (x=0; x < (long) image->columns; x++)
{
if ((channel & RedChannel) != 0)
- q->red=ApplyEvaluateOperator(random_info[id],q->red,op,value);
+ q->red=ClampToQuantum(ApplyEvaluateOperator(random_info[id],q->red,op,
+ value));
if ((channel & GreenChannel) != 0)
- q->green=ApplyEvaluateOperator(random_info[id],q->green,op,value);
+ q->green=ClampToQuantum(ApplyEvaluateOperator(random_info[id],q->green,
+ op,value));
if ((channel & BlueChannel) != 0)
- q->blue=ApplyEvaluateOperator(random_info[id],q->blue,op,value);
+ q->blue=ClampToQuantum(ApplyEvaluateOperator(random_info[id],q->blue,op,
+ value));
if ((channel & OpacityChannel) != 0)
{
if (image->matte == MagickFalse)
- q->opacity=ApplyEvaluateOperator(random_info[id],q->opacity,op,
- value);
+ q->opacity=ClampToQuantum(ApplyEvaluateOperator(random_info[id],
+ q->opacity,op,value));
else
- q->opacity=(Quantum) QuantumRange-ApplyEvaluateOperator(
- random_info[id],(Quantum) GetAlphaPixelComponent(q),op,value);
+ q->opacity=ClampToQuantum(QuantumRange-ApplyEvaluateOperator(
+ random_info[id],(Quantum) GetAlphaPixelComponent(q),op,value));
}
if (((channel & IndexChannel) != 0) && (indexes != (IndexPacket *) NULL))
- indexes[x]=(IndexPacket) ApplyEvaluateOperator(random_info[id],
- indexes[x],op,value);
+ indexes[x]=(IndexPacket) ClampToQuantum(ApplyEvaluateOperator(
+ random_info[id],indexes[x],op,value));
q++;
}
if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
}
return(channel_statistics);
}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
-% M a x i m u m I m a g e s %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% MaximumImages() returns the maximum intensity of an image sequence.
-%
-% The format of the MaxImages method is:
-%
-% Image *MaximumImages(Image *images,ExceptionInfo *exception)
-%
-% A description of each parameter follows:
-%
-% o images: the image sequence.
-%
-% o exception: return any errors or warnings in this structure.
-%
-*/
-MagickExport Image *MaximumImages(const Image *images,ExceptionInfo *exception)
-{
-#define MaximumImageTag "Maximum/Image"
-
- const Image
- *next;
-
- Image
- *maximum_image;
-
- MagickBooleanType
- status;
-
- register long
- i;
-
- unsigned long
- number_images;
-
- /*
- Ensure the image are the same size.
- */
- assert(images != (Image *) NULL);
- assert(images->signature == MagickSignature);
- if (images->debug != MagickFalse)
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
- assert(exception != (ExceptionInfo *) NULL);
- assert(exception->signature == MagickSignature);
- for (next=images; next != (Image *) NULL; next=GetNextImageInList(next))
- if ((next->columns != images->columns) || (next->rows != images->rows))
- {
- (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
- "ImageWidthsOrHeightsDiffer","`%s'",images->filename);
- return((Image *) NULL);
- }
- /*
- Initialize maximum itensity image.
- */
- maximum_image=CloneImage(images,0,0,MagickTrue,exception);
- if (maximum_image == (Image *) NULL)
- return((Image *) NULL);
- if (SetImageStorageClass(maximum_image,DirectClass) == MagickFalse)
- {
- InheritException(exception,&maximum_image->exception);
- maximum_image=DestroyImage(maximum_image);
- return((Image *) NULL);
- }
- /*
- Compute the maximum intensity of an image sequence.
- */
- i=0;
- number_images=GetImageListLength(images);
- for (next=images; next != (Image *) NULL; next=GetNextImageInList(next))
- {
- status=CompositeImage(maximum_image,LightenCompositeOp,next,0,0);
- if (status == MagickFalse)
- {
- InheritException(exception,&maximum_image->exception);
- maximum_image=DestroyImage(maximum_image);
- break;
- }
- if (images->progress_monitor != (MagickProgressMonitor) NULL)
- {
- MagickBooleanType
- proceed;
-
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_MaximumImages)
-#endif
- proceed=SetImageProgress(images,MaximumImageTag,i++,number_images);
- }
- }
- return(maximum_image);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
-% M i n i m u m I m a g e s %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% MinimumImages() returns the minimum intensity of an image sequence.
-%
-% The format of the MinimumImages method is:
-%
-% Image *MinimumImages(Image *images,ExceptionInfo *exception)
-%
-% A description of each parameter follows:
-%
-% o images: the image sequence.
-%
-% o exception: return any errors or warnings in this structure.
-%
-*/
-MagickExport Image *MinimumImages(const Image *images,ExceptionInfo *exception)
-{
-#define MinimumImageTag "Minimum/Image"
-
- const Image
- *next;
-
- Image
- *minimum_image;
-
- MagickBooleanType
- status;
-
- register long
- i;
-
- unsigned long
- number_images;
-
- /*
- Ensure the image are the same size.
- */
- assert(images != (Image *) NULL);
- assert(images->signature == MagickSignature);
- if (images->debug != MagickFalse)
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",images->filename);
- assert(exception != (ExceptionInfo *) NULL);
- assert(exception->signature == MagickSignature);
- for (next=images; next != (Image *) NULL; next=GetNextImageInList(next))
- if ((next->columns != images->columns) || (next->rows != images->rows))
- {
- (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
- "ImageWidthsOrHeightsDiffer","`%s'",images->filename);
- return((Image *) NULL);
- }
- /*
- Initialize minimum intensity image.
- */
- minimum_image=CloneImage(images,0,0,MagickTrue,exception);
- if (minimum_image == (Image *) NULL)
- return((Image *) NULL);
- if (SetImageStorageClass(minimum_image,DirectClass) == MagickFalse)
- {
- InheritException(exception,&minimum_image->exception);
- minimum_image=DestroyImage(minimum_image);
- return((Image *) NULL);
- }
- /*
- Compute the minimum intensity of an image sequence.
- */
- i=0;
- number_images=GetImageListLength(images);
- for (next=images; next != (Image *) NULL; next=GetNextImageInList(next))
- {
- status=CompositeImage(minimum_image,DarkenCompositeOp,next,0,0);
- if (status == MagickFalse)
- {
- InheritException(exception,&minimum_image->exception);
- minimum_image=DestroyImage(minimum_image);
- break;
- }
- if (images->progress_monitor != (MagickProgressMonitor) NULL)
- {
- MagickBooleanType
- proceed;
-
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp critical (MagickCore_MaxImages)
-#endif
- proceed=SetImageProgress(images,MinimumImageTag,i++,number_images);
- }
- }
- return(minimum_image);
-}
*GetImageChannelStatistics(const Image *,ExceptionInfo *);
extern MagickExport Image
- *AverageImages(const Image *,ExceptionInfo *),
- *MaximumImages(const Image *,ExceptionInfo *),
- *MinimumImages(const Image *,ExceptionInfo *);
+ *EvaluateImages(const Image *,const MagickEvaluateOperator,ExceptionInfo *);
extern MagickExport MagickBooleanType
EvaluateImage(Image *,const MagickEvaluateOperator,const double,
Image Sequence Operators:
\-affinity filename transform image colors to match this set of colors
\-append append an image sequence
- \-average average an image sequence
\-clut apply a color lookup table to the image
\-coalesce merge a sequence of images
\-combine combine a sequence of images
\-composite composite image
\-crop geometry cut out a rectangular region of the image
\-deconstruct break down an image sequence into constituent parts
+ \-evaluate-sequence operator
+ evaluate an arithmetic, relational, or logical expression
\-flatten flatten a sequence of images
\-fx expression apply mathematical expression to an image channel(s)
\-hald-clut apply a Hald color lookup table to the image
- \-maximum the maximum intensity of an image sequence
- \-minimum the minimum intensity of an image sequence
\-morph value morph an image sequence
\-mosaic create a mosaic from an image sequence
\-process arguments process the image with a custom image filter
Image Sequence Operators:
\-affinity filename transform image colors to match this set of colors
\-append append an image sequence
- \-average average an image sequence
\-clut apply a color lookup table to the image
\-coalesce merge a sequence of images
\-combine combine a sequence of images
\-composite composite image
\-crop geometry cut out a rectangular region of the image
\-deconstruct break down an image sequence into constituent parts
+ \-evaluate-sequence operator
+ evaluate an arithmetic, relational, or logical expression
\-flatten flatten a sequence of images
\-fx expression apply mathematical expression to an image channel(s)
\-hald-clut apply a Hald color lookup table to the image
- \-maximum the maximum intensity of an image sequence
- \-minimum the minimum intensity of an image sequence
\-morph value morph an image sequence
\-mosaic create a mosaic from an image sequence
\-process arguments process the image with a custom image filter
"-enhance apply a digital filter to enhance a noisy image",
"-equalize perform histogram equalization to an image",
"-evaluate operator value",
- " evaluate an expression over image values",
+ " evaluate an arithmetic, relational, or logical expression",
"-extent geometry set the image size",
"-extract geometry extract area from image",
"-fft implements the discrete Fourier transform (DFT)",
*sequence_operators[]=
{
"-append append an image sequence",
- "-average average an image sequence",
"-clut apply a color lookup table to the image",
"-coalesce merge a sequence of images",
"-combine combine a sequence of images",
"-composite composite image",
"-crop geometry cut out a rectangular region of the image",
"-deconstruct break down an image sequence into constituent parts",
+ "-evaluate-sequence operator",
+ " evaluate an arithmetic, relational, or logical expression",
"-flatten flatten a sequence of images",
"-fx expression apply mathematical expression to an image channel(s)",
"-hald-clut apply a Hald color lookup table to the image",
- "-max return the maximum intensity of an image sequence",
- "-min return the minimum intensity of an image sequence",
"-morph value morph an image sequence",
"-mosaic create a mosaic from an image sequence",
"-process arguments process the image with a custom image filter",
ThrowConvertInvalidArgumentException(option,argv[i]);
break;
}
+ if (LocaleCompare("evaluate-sequence",option+1) == 0)
+ {
+ long
+ op;
+
+ if (*option == '+')
+ break;
+ i++;
+ if (i == (long) argc)
+ ThrowConvertException(OptionError,"MissingArgument",option);
+ op=ParseMagickOption(MagickEvaluateOptions,MagickFalse,argv[i]);
+ if (op < 0)
+ ThrowConvertException(OptionError,"UnrecognizedEvaluateOperator",
+ argv[i]);
+ break;
+ }
if (LocaleCompare("extent",option+1) == 0)
{
if (*option == '+')
% %
% %
% %
+% M a g i c k A v e r a g e I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickAverageImages() average a set of images.
+%
+% The format of the MagickAverageImages method is:
+%
+% MagickWand *MagickAverageImages(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: the magick wand.
+%
+*/
+
+static MagickWand *CloneMagickWandFromImages(const MagickWand *wand,
+ Image *images)
+{
+ MagickWand
+ *clone_wand;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == WandSignature);
+ if (wand->debug != MagickFalse)
+ (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
+ clone_wand=(MagickWand *) AcquireAlignedMemory(1,sizeof(*clone_wand));
+ if (clone_wand == (MagickWand *) NULL)
+ ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
+ images->filename);
+ (void) ResetMagickMemory(clone_wand,0,sizeof(*clone_wand));
+ clone_wand->id=AcquireWandId();
+ (void) FormatMagickString(clone_wand->name,MaxTextExtent,"%s-%lu",
+ MagickWandId,clone_wand->id);
+ clone_wand->exception=AcquireExceptionInfo();
+ InheritException(clone_wand->exception,wand->exception);
+ clone_wand->image_info=CloneImageInfo(wand->image_info);
+ clone_wand->quantize_info=CloneQuantizeInfo(wand->quantize_info);
+ clone_wand->images=images;
+ clone_wand->debug=IsEventLogging();
+ if (clone_wand->debug != MagickFalse)
+ (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_wand->name);
+ clone_wand->signature=WandSignature;
+ return(clone_wand);
+}
+
+WandExport MagickWand *MagickAverageImages(MagickWand *wand)
+{
+ Image
+ *average_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == WandSignature);
+ if (wand->debug != MagickFalse)
+ (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
+ if (wand->images == (Image *) NULL)
+ return((MagickWand *) NULL);
+ average_image=EvaluateImages(wand->images,MeanEvaluateOperator,
+ wand->exception);
+ if (average_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandFromImages(wand,average_image));
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% M a g i c k C l i p P a t h I m a g e %
% %
% %
% o wand: the magick wand.
%
*/
-
-static MagickWand *CloneMagickWandFromImages(const MagickWand *wand,
- Image *images)
-{
- MagickWand
- *clone_wand;
-
- assert(wand != (MagickWand *) NULL);
- assert(wand->signature == WandSignature);
- if (wand->debug != MagickFalse)
- (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
- clone_wand=(MagickWand *) AcquireAlignedMemory(1,sizeof(*clone_wand));
- if (clone_wand == (MagickWand *) NULL)
- ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
- images->filename);
- (void) ResetMagickMemory(clone_wand,0,sizeof(*clone_wand));
- clone_wand->id=AcquireWandId();
- (void) FormatMagickString(clone_wand->name,MaxTextExtent,"%s-%lu",
- MagickWandId,clone_wand->id);
- clone_wand->exception=AcquireExceptionInfo();
- InheritException(clone_wand->exception,wand->exception);
- clone_wand->image_info=CloneImageInfo(wand->image_info);
- clone_wand->quantize_info=CloneQuantizeInfo(wand->quantize_info);
- clone_wand->images=images;
- clone_wand->debug=IsEventLogging();
- if (clone_wand->debug != MagickFalse)
- (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_wand->name);
- clone_wand->signature=WandSignature;
- return(clone_wand);
-}
-
WandExport MagickWand *MagickFlattenImages(MagickWand *wand)
{
Image
% %
% %
% %
+% M a g i c k M a x i m u m I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMaximumImages() returns the maximum intensity of an image sequence.
+%
+% The format of the MagickMaximumImages method is:
+%
+% MagickWand *MagickMaximumImages(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: the magick wand.
+%
+*/
+WandExport MagickWand *MagickMaximumImages(MagickWand *wand)
+{
+ Image
+ *maximum_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == WandSignature);
+ if (wand->debug != MagickFalse)
+ (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
+ if (wand->images == (Image *) NULL)
+ return((MagickWand *) NULL);
+ maximum_image=EvaluateImages(wand->images,MaxEvaluateOperator,
+ wand->exception);
+ if (maximum_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandFromImages(wand,maximum_image));
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% M a g i c k M i n i m u m I m a g e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% MagickMinimumImages() returns the minimum intensity of an image sequence.
+%
+% The format of the MagickMinimumImages method is:
+%
+% MagickWand *MagickMinimumImages(MagickWand *wand)
+%
+% A description of each parameter follows:
+%
+% o wand: the magick wand.
+%
+*/
+WandExport MagickWand *MagickMinimumImages(MagickWand *wand)
+{
+ Image
+ *minimum_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == WandSignature);
+ if (wand->debug != MagickFalse)
+ (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
+ if (wand->images == (Image *) NULL)
+ return((MagickWand *) NULL);
+ minimum_image=EvaluateImages(wand->images,MinEvaluateOperator,
+ wand->exception);
+ if (minimum_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandFromImages(wand,minimum_image));
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% M a g i c k M o s a i c I m a g e s %
% %
% %
const double) magick_attribute((deprecated));
extern WandExport MagickWand
+ *MagickAverageImages(MagickWand *),
*MagickFlattenImages(MagickWand *) magick_attribute((deprecated)),
+ *MagickMaximumImages(MagickWand *),
+ *MagickMinimumImages(MagickWand *),
*MagickMosaicImages(MagickWand *) magick_attribute((deprecated)),
*MagickRegionOfInterestImage(MagickWand *,const unsigned long,
const unsigned long,const long,const long) magick_attribute((deprecated));
%
% MagickBooleanType MagickEvaluateImage(MagickWand *wand,
% const MagickEvaluateOperator operator,const double value)
+% MagickBooleanType MagickEvaluateImages(MagickWand *wand,
+% const MagickEvaluateOperator operator)
% MagickBooleanType MagickEvaluateImageChannel(MagickWand *wand,
% const ChannelType channel,const MagickEvaluateOperator op,
% const double value)
return(status);
}
+WandExport MagickWand *MagickEvaluateImages(MagickWand *wand,
+ const MagickEvaluateOperator op)
+{
+ Image
+ *evaluate_image;
+
+ assert(wand != (MagickWand *) NULL);
+ assert(wand->signature == WandSignature);
+ if (wand->debug != MagickFalse)
+ (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
+ if (wand->images == (Image *) NULL)
+ return((MagickWand *) NULL);
+ evaluate_image=EvaluateImages(wand->images,op,wand->exception);
+ if (evaluate_image == (Image *) NULL)
+ return((MagickWand *) NULL);
+ return(CloneMagickWandFromImages(wand,evaluate_image));
+}
+
WandExport MagickBooleanType MagickEvaluateImageChannel(MagickWand *wand,
const ChannelType channel,const MagickEvaluateOperator op,const double value)
{
extern WandExport MagickWand
*MagickAppendImages(MagickWand *,const MagickBooleanType),
- *MagickAverageImages(MagickWand *),
*MagickCoalesceImages(MagickWand *),
*MagickCombineImages(MagickWand *,const ChannelType),
*MagickCompareImageChannels(MagickWand *,const MagickWand *,const ChannelType,
double *),
*MagickCompareImageLayers(MagickWand *,const ImageLayerMethod),
*MagickDeconstructImages(MagickWand *),
+ *MagickEvaluateImages(MagickWand *,const MagickEvaluateOperator),
*MagickFxImage(MagickWand *,const char *),
*MagickFxImageChannel(MagickWand *,const ChannelType,const char *),
*MagickGetImage(MagickWand *),
*MagickGetImageClipMask(MagickWand *),
*MagickGetImageRegion(MagickWand *,const unsigned long,const unsigned long,
const long,const long),
- *MagickMaximumImages(MagickWand *),
- *MagickMinimumImages(MagickWand *),
*MagickMergeImageLayers(MagickWand *,const ImageLayerMethod),
*MagickMorphImages(MagickWand *,const unsigned long),
*MagickMontageImage(MagickWand *,const DrawingWand *,const char *,
"-enhance apply a digital filter to enhance a noisy image",
"-equalize perform histogram equalization to an image",
"-evaluate operator value",
- " evaluate an expression over image values",
+ " evaluate an arithmetic, relational, or logical expression",
"-extent geometry set the image size",
"-extract geometry extract area from image",
"-fft implements the discrete Fourier transform (DFT)",
*sequence_operators[]=
{
"-append append an image sequence",
- "-average average an image sequence",
"-clut apply a color lookup table to the image",
"-coalesce merge a sequence of images",
"-combine combine a sequence of images",
"-composite composite image",
"-crop geometry cut out a rectangular region of the image",
"-deconstruct break down an image sequence into constituent parts",
+ "-evaluate-sequence operator",
+ " evaluate an arithmetic, relational, or logical expression",
"-flatten flatten a sequence of images",
"-fx expression apply mathematical expression to an image channel(s)",
"-hald-clut apply a Hald color lookup table to the image",
- "-maximum return the maximum intensity of an image sequence",
- "-minimum return the minimum intensity of an image sequence",
"-morph value morph an image sequence",
"-mosaic create a mosaic from an image sequence",
"-process arguments process the image with a custom image filter",
ThrowMogrifyInvalidArgumentException(option,argv[i]);
break;
}
+ if (LocaleCompare("evaluate-sequence",option+1) == 0)
+ {
+ long
+ op;
+
+ if (*option == '+')
+ break;
+ i++;
+ if (i == (long) argc)
+ ThrowMogrifyException(OptionError,"MissingArgument",option);
+ op=ParseMagickOption(MagickEvaluateOptions,MagickFalse,argv[i]);
+ if (op < 0)
+ ThrowMogrifyException(OptionError,"UnrecognizedEvaluateOperator",
+ argv[i]);
+ break;
+ }
if (LocaleCompare("extent",option+1) == 0)
{
if (*option == '+')
Image
*average_image;
+ /*
+ Average an image sequence (deprecated).
+ */
(void) SyncImagesSettings(image_info,*images);
- average_image=AverageImages(*images,exception);
+ average_image=EvaluateImages(*images,MeanEvaluateOperator,
+ exception);
if (average_image == (Image *) NULL)
{
status=MagickFalse;
}
break;
}
+ case 'e':
+ {
+ if (LocaleCompare("evaluate-sequence",option+1) == 0)
+ {
+ Image
+ *evaluate_image;
+
+ MagickEvaluateOperator
+ op;
+
+ (void) SyncImageSettings(image_info,*images);
+ op=(MagickEvaluateOperator) ParseMagickOption(MagickEvaluateOptions,
+ MagickFalse,argv[i+1]);
+ evaluate_image=EvaluateImages(*images,op,exception);
+ if (evaluate_image == (Image *) NULL)
+ {
+ status=MagickFalse;
+ break;
+ }
+ *images=DestroyImageList(*images);
+ *images=evaluate_image;
+ break;
+ }
+ break;
+ }
case 'f':
{
if (LocaleCompare("fft",option+1) == 0)
Image
*maximum_image;
+ /*
+ Maximum image sequence (deprecated).
+ */
(void) SyncImagesSettings(image_info,*images);
- maximum_image=MaximumImages(*images,exception);
+ maximum_image=EvaluateImages(*images,MaxEvaluateOperator,exception);
if (maximum_image == (Image *) NULL)
{
status=MagickFalse;
Image
*minimum_image;
+ /*
+ Minimum image sequence (deprecated).
+ */
(void) SyncImagesSettings(image_info,*images);
- minimum_image=MinimumImages(*images,exception);
+ minimum_image=EvaluateImages(*images,MinEvaluateOperator,exception);
if (minimum_image == (Image *) NULL)
{
status=MagickFalse;