Include declarations.
*/
#include "MagickCore/studio.h"
+#include "MagickCore/cache-private.h"
#include "MagickCore/colorspace-private.h"
+#include "MagickCore/composite-private.h"
+#include "MagickCore/enhance.h"
#include "MagickCore/image.h"
#include "MagickCore/list.h"
#include "MagickCore/log.h"
#include "MagickCore/monitor-private.h"
#include "MagickCore/option.h"
#include "MagickCore/pixel-accessor.h"
+#include "MagickCore/pixel-private.h"
#include "MagickCore/resource_.h"
#include "MagickCore/string-private.h"
#include "MagickCore/thread-private.h"
% %
% %
% %
+% G e t I m a g e A l p h a C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% GetImageAlphaChannel() returns MagickFalse if the image alpha channel is
+% not activated. That is, the image is RGB rather than RGBA or CMYK rather
+% than CMYKA.
+%
+% The format of the GetImageAlphaChannel method is:
+%
+% MagickBooleanType GetImageAlphaChannel(const Image *image)
+%
+% A description of each parameter follows:
+%
+% o image: the image.
+%
+*/
+MagickExport MagickBooleanType GetImageAlphaChannel(const Image *image)
+{
+ assert(image != (const Image *) NULL);
+ if (image->debug != MagickFalse)
+ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+ assert(image->signature == MagickSignature);
+ return(image->alpha_trait == BlendPixelTrait ? MagickTrue : MagickFalse);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
% S e p a r a t e I m a g e %
% %
% %
images=SeparateImage(image,UndefinedChannel,exception);
return(images);
}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+% S e t I m a g e A l p h a C h a n n e l %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% SetImageAlphaChannel() activates, deactivates, resets, or sets the alpha
+% channel.
+%
+% The format of the SetImageAlphaChannel method is:
+%
+% MagickBooleanType SetImageAlphaChannel(Image *image,
+% const AlphaChannelOption alpha_type,ExceptionInfo *exception)
+%
+% A description of each parameter follows:
+%
+% o image: the image.
+%
+% o alpha_type: The alpha channel type: ActivateAlphaChannel,
+% CopyAlphaChannel, DeactivateAlphaChannel, ExtractAlphaChannel,
+% OpaqueAlphaChannel, SetAlphaChannel, ShapeAlphaChannel, and
+% TransparentAlphaChannel.
+%
+% o exception: return any errors or warnings in this structure.
+%
+*/
+
+static inline void FlattenPixelInfo(const Image *image,const PixelInfo *p,
+ const double alpha,const Quantum *q,const double beta,
+ Quantum *composite)
+{
+ double
+ Da,
+ gamma,
+ Sa;
+
+ register ssize_t
+ i;
+
+ /*
+ Compose pixel p over pixel q with the given alpha.
+ */
+ Sa=QuantumScale*alpha;
+ Da=QuantumScale*beta,
+ gamma=Sa*(-Da)+Sa+Da;
+ gamma=PerceptibleReciprocal(gamma);
+ for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
+ {
+ PixelChannel channel=GetPixelChannelChannel(image,i);
+ PixelTrait traits=GetPixelChannelTraits(image,channel);
+ if (traits == UndefinedPixelTrait)
+ continue;
+ switch (channel)
+ {
+ case RedPixelChannel:
+ {
+ composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
+ (double) p->red,alpha));
+ break;
+ }
+ case GreenPixelChannel:
+ {
+ composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
+ (double) p->green,alpha));
+ break;
+ }
+ case BluePixelChannel:
+ {
+ composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
+ (double) p->blue,alpha));
+ break;
+ }
+ case BlackPixelChannel:
+ {
+ composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
+ (double) p->black,alpha));
+ break;
+ }
+ case AlphaPixelChannel:
+ {
+ composite[i]=ClampToQuantum(QuantumRange*(Sa*(-Da)+Sa+Da));
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
+ const AlphaChannelOption alpha_type,ExceptionInfo *exception)
+{
+ MagickBooleanType
+ status;
+
+ assert(image != (Image *) NULL);
+ if (image->debug != MagickFalse)
+ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
+ assert(image->signature == MagickSignature);
+ status=MagickTrue;
+ switch (alpha_type)
+ {
+ case ActivateAlphaChannel:
+ {
+ image->alpha_trait=BlendPixelTrait;
+ break;
+ }
+ case BackgroundAlphaChannel:
+ {
+ CacheView
+ *image_view;
+
+ ssize_t
+ y;
+
+ /*
+ Set transparent pixels to background color.
+ */
+ if (image->alpha_trait != BlendPixelTrait)
+ break;
+ if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
+ break;
+ image_view=AcquireAuthenticCacheView(image,exception);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp parallel for schedule(static,4) shared(status) \
+ magick_threads(image,image,image->rows,1)
+#endif
+ for (y=0; y < (ssize_t) image->rows; y++)
+ {
+ register Quantum
+ *restrict q;
+
+ register ssize_t
+ x;
+
+ if (status == MagickFalse)
+ continue;
+ q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
+ exception);
+ if (q == (Quantum *) NULL)
+ {
+ status=MagickFalse;
+ continue;
+ }
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ if (GetPixelAlpha(image,q) == TransparentAlpha)
+ {
+ SetPixelInfoPixel(image,&image->background_color,q);
+ SetPixelChannel(image,AlphaPixelChannel,TransparentAlpha,q);
+ }
+ q+=GetPixelChannels(image);
+ }
+ if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
+ status=MagickFalse;
+ }
+ image_view=DestroyCacheView(image_view);
+ return(status);
+ }
+ case CopyAlphaChannel:
+ case ShapeAlphaChannel:
+ {
+ /*
+ Copy pixel intensity to the alpha channel.
+ */
+ status=CompositeImage(image,image,IntensityCompositeOp,MagickTrue,0,0,
+ exception);
+ if (alpha_type == ShapeAlphaChannel)
+ (void) LevelImageColors(image,&image->background_color,
+ &image->background_color,MagickTrue,exception);
+ break;
+ }
+ case DeactivateAlphaChannel:
+ {
+ image->alpha_trait=CopyPixelTrait;
+ break;
+ }
+ case ExtractAlphaChannel:
+ {
+ status=CompositeImage(image,image,AlphaCompositeOp,MagickTrue,0,0,
+ exception);
+ image->alpha_trait=CopyPixelTrait;
+ break;
+ }
+ case OpaqueAlphaChannel:
+ {
+ status=SetImageAlpha(image,OpaqueAlpha,exception);
+ break;
+ }
+ case RemoveAlphaChannel:
+ {
+ CacheView
+ *image_view;
+
+ ssize_t
+ y;
+
+ /*
+ Remove transparency.
+ */
+ if (image->alpha_trait != BlendPixelTrait)
+ break;
+ if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
+ break;
+ image_view=AcquireAuthenticCacheView(image,exception);
+#if defined(MAGICKCORE_OPENMP_SUPPORT)
+ #pragma omp parallel for schedule(static,4) shared(status) \
+ magick_threads(image,image,image->rows,1)
+#endif
+ for (y=0; y < (ssize_t) image->rows; y++)
+ {
+ register Quantum
+ *restrict q;
+
+ register ssize_t
+ x;
+
+ if (status == MagickFalse)
+ continue;
+ q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
+ exception);
+ if (q == (Quantum *) NULL)
+ {
+ status=MagickFalse;
+ continue;
+ }
+ for (x=0; x < (ssize_t) image->columns; x++)
+ {
+ FlattenPixelInfo(image,&image->background_color,
+ image->background_color.alpha,q,(double)
+ GetPixelAlpha(image,q),q);
+ q+=GetPixelChannels(image);
+ }
+ if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
+ status=MagickFalse;
+ }
+ image_view=DestroyCacheView(image_view);
+ image->alpha_trait=image->background_color.alpha_trait;
+ return(status);
+ }
+ case SetAlphaChannel:
+ {
+ if (image->alpha_trait != BlendPixelTrait)
+ status=SetImageAlpha(image,OpaqueAlpha,exception);
+ break;
+ }
+ case TransparentAlphaChannel:
+ {
+ status=SetImageAlpha(image,TransparentAlpha,exception);
+ break;
+ }
+ case UndefinedAlphaChannel:
+ break;
+ }
+ if (status == MagickFalse)
+ return(status);
+ return(SyncImagePixelCache(image,exception));
+}
% %
% %
% %
-% G e t I m a g e A l p h a C h a n n e l %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% GetImageAlphaChannel() returns MagickFalse if the image alpha channel is
-% not activated. That is, the image is RGB rather than RGBA or CMYK rather
-% than CMYKA.
-%
-% The format of the GetImageAlphaChannel method is:
-%
-% MagickBooleanType GetImageAlphaChannel(const Image *image)
-%
-% A description of each parameter follows:
-%
-% o image: the image.
-%
-*/
-MagickExport MagickBooleanType GetImageAlphaChannel(const Image *image)
-{
- assert(image != (const Image *) NULL);
- if (image->debug != MagickFalse)
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
- assert(image->signature == MagickSignature);
- return(image->alpha_trait == BlendPixelTrait ? MagickTrue : MagickFalse);
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
% G e t I m a g e I n f o %
% %
% %
% %
% %
% %
-% S e t I m a g e A l p h a C h a n n e l %
-% %
-% %
-% %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%
-% SetImageAlphaChannel() activates, deactivates, resets, or sets the alpha
-% channel.
-%
-% The format of the SetImageAlphaChannel method is:
-%
-% MagickBooleanType SetImageAlphaChannel(Image *image,
-% const AlphaChannelOption alpha_type,ExceptionInfo *exception)
-%
-% A description of each parameter follows:
-%
-% o image: the image.
-%
-% o alpha_type: The alpha channel type: ActivateAlphaChannel,
-% CopyAlphaChannel, DeactivateAlphaChannel, ExtractAlphaChannel,
-% OpaqueAlphaChannel, SetAlphaChannel, ShapeAlphaChannel, and
-% TransparentAlphaChannel.
-%
-% o exception: return any errors or warnings in this structure.
-%
-*/
-
-static inline void FlattenPixelInfo(const Image *image,const PixelInfo *p,
- const double alpha,const Quantum *q,const double beta,
- Quantum *composite)
-{
- double
- Da,
- gamma,
- Sa;
-
- register ssize_t
- i;
-
- /*
- Compose pixel p over pixel q with the given alpha.
- */
- Sa=QuantumScale*alpha;
- Da=QuantumScale*beta,
- gamma=Sa*(-Da)+Sa+Da;
- gamma=PerceptibleReciprocal(gamma);
- for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
- {
- PixelChannel channel=GetPixelChannelChannel(image,i);
- PixelTrait traits=GetPixelChannelTraits(image,channel);
- if (traits == UndefinedPixelTrait)
- continue;
- switch (channel)
- {
- case RedPixelChannel:
- {
- composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
- (double) p->red,alpha));
- break;
- }
- case GreenPixelChannel:
- {
- composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
- (double) p->green,alpha));
- break;
- }
- case BluePixelChannel:
- {
- composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
- (double) p->blue,alpha));
- break;
- }
- case BlackPixelChannel:
- {
- composite[i]=ClampToQuantum(gamma*MagickOver_((double) q[i],beta,
- (double) p->black,alpha));
- break;
- }
- case AlphaPixelChannel:
- {
- composite[i]=ClampToQuantum(QuantumRange*(Sa*(-Da)+Sa+Da));
- break;
- }
- default:
- break;
- }
- }
-}
-
-MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
- const AlphaChannelOption alpha_type,ExceptionInfo *exception)
-{
- MagickBooleanType
- status;
-
- assert(image != (Image *) NULL);
- if (image->debug != MagickFalse)
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
- assert(image->signature == MagickSignature);
- status=MagickTrue;
- switch (alpha_type)
- {
- case ActivateAlphaChannel:
- {
- image->alpha_trait=BlendPixelTrait;
- break;
- }
- case BackgroundAlphaChannel:
- {
- CacheView
- *image_view;
-
- ssize_t
- y;
-
- /*
- Set transparent pixels to background color.
- */
- if (image->alpha_trait != BlendPixelTrait)
- break;
- if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
- break;
- image_view=AcquireAuthenticCacheView(image,exception);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(status) \
- magick_threads(image,image,image->rows,1)
-#endif
- for (y=0; y < (ssize_t) image->rows; y++)
- {
- register Quantum
- *restrict q;
-
- register ssize_t
- x;
-
- if (status == MagickFalse)
- continue;
- q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
- exception);
- if (q == (Quantum *) NULL)
- {
- status=MagickFalse;
- continue;
- }
- for (x=0; x < (ssize_t) image->columns; x++)
- {
- if (GetPixelAlpha(image,q) == TransparentAlpha)
- {
- SetPixelInfoPixel(image,&image->background_color,q);
- SetPixelChannel(image,AlphaPixelChannel,TransparentAlpha,q);
- }
- q+=GetPixelChannels(image);
- }
- if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
- status=MagickFalse;
- }
- image_view=DestroyCacheView(image_view);
- return(status);
- }
- case CopyAlphaChannel:
- case ShapeAlphaChannel:
- {
- /*
- Copy pixel intensity to the alpha channel.
- */
- status=CompositeImage(image,image,IntensityCompositeOp,MagickTrue,0,0,
- exception);
- if (alpha_type == ShapeAlphaChannel)
- (void) LevelImageColors(image,&image->background_color,
- &image->background_color,MagickTrue,exception);
- break;
- }
- case DeactivateAlphaChannel:
- {
- image->alpha_trait=CopyPixelTrait;
- break;
- }
- case ExtractAlphaChannel:
- {
- status=CompositeImage(image,image,AlphaCompositeOp,MagickTrue,0,0,
- exception);
- image->alpha_trait=CopyPixelTrait;
- break;
- }
- case OpaqueAlphaChannel:
- {
- status=SetImageAlpha(image,OpaqueAlpha,exception);
- break;
- }
- case RemoveAlphaChannel:
- {
- CacheView
- *image_view;
-
- ssize_t
- y;
-
- /*
- Remove transparency.
- */
- if (image->alpha_trait != BlendPixelTrait)
- break;
- if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
- break;
- image_view=AcquireAuthenticCacheView(image,exception);
-#if defined(MAGICKCORE_OPENMP_SUPPORT)
- #pragma omp parallel for schedule(static,4) shared(status) \
- magick_threads(image,image,image->rows,1)
-#endif
- for (y=0; y < (ssize_t) image->rows; y++)
- {
- register Quantum
- *restrict q;
-
- register ssize_t
- x;
-
- if (status == MagickFalse)
- continue;
- q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
- exception);
- if (q == (Quantum *) NULL)
- {
- status=MagickFalse;
- continue;
- }
- for (x=0; x < (ssize_t) image->columns; x++)
- {
- FlattenPixelInfo(image,&image->background_color,
- image->background_color.alpha,q,(double)
- GetPixelAlpha(image,q),q);
- q+=GetPixelChannels(image);
- }
- if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
- status=MagickFalse;
- }
- image_view=DestroyCacheView(image_view);
- image->alpha_trait=image->background_color.alpha_trait;
- return(status);
- }
- case SetAlphaChannel:
- {
- if (image->alpha_trait != BlendPixelTrait)
- status=SetImageAlpha(image,OpaqueAlpha,exception);
- break;
- }
- case TransparentAlphaChannel:
- {
- status=SetImageAlpha(image,TransparentAlpha,exception);
- break;
- }
- case UndefinedAlphaChannel:
- break;
- }
- if (status == MagickFalse)
- return(status);
- return(SyncImagePixelCache(image,exception));
-}
-\f
-/*
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% %
-% %
-% %
% S e t I m a g e B a c k g r o u n d C o l o r %
% %
% %
extern MagickExport MagickBooleanType
ClipImage(Image *,ExceptionInfo *),
ClipImagePath(Image *,const char *,const MagickBooleanType,ExceptionInfo *),
- GetImageAlphaChannel(const Image *),
IsTaintImage(const Image *),
IsHighDynamicRangeImage(const Image *,ExceptionInfo *),
IsImageObject(const Image *),
ModifyImage(Image **,ExceptionInfo *),
ResetImagePage(Image *,const char *),
SetImageAlpha(Image *,const Quantum,ExceptionInfo *),
- SetImageAlphaChannel(Image *,const AlphaChannelOption,ExceptionInfo *),
SetImageBackgroundColor(Image *,ExceptionInfo *),
SetImageColor(Image *,const PixelInfo *,ExceptionInfo *),
SetImageExtent(Image *,const size_t,const size_t,ExceptionInfo *),