43#include "MagickCore/studio.h"
44#include "MagickCore/cache-private.h"
45#include "MagickCore/channel.h"
46#include "MagickCore/colorspace-private.h"
47#include "MagickCore/composite-private.h"
48#include "MagickCore/enhance.h"
49#include "MagickCore/image.h"
50#include "MagickCore/list.h"
51#include "MagickCore/log.h"
52#include "MagickCore/monitor.h"
53#include "MagickCore/monitor-private.h"
54#include "MagickCore/option.h"
55#include "MagickCore/pixel-accessor.h"
56#include "MagickCore/resource_.h"
57#include "MagickCore/string-private.h"
58#include "MagickCore/thread-private.h"
59#include "MagickCore/token.h"
60#include "MagickCore/utility.h"
61#include "MagickCore/version.h"
116static MagickBooleanType ChannelImage(Image *destination_image,
117 const PixelChannel destination_channel,
const ChannelFx channel_op,
118 const Image *source_image,
const PixelChannel source_channel,
119 const Quantum pixel,ExceptionInfo *exception)
138 height=MagickMin(source_image->rows,destination_image->rows);
139 width=MagickMin(source_image->columns,destination_image->columns);
140 source_view=AcquireVirtualCacheView(source_image,exception);
141 destination_view=AcquireAuthenticCacheView(destination_image,exception);
142#if defined(MAGICKCORE_OPENMP_SUPPORT)
143 #pragma omp parallel for schedule(static) shared(status) \
144 magick_number_threads(source_image,source_image,height,4)
146 for (y=0; y < (ssize_t) height; y++)
161 if (status == MagickFalse)
163 p=GetCacheViewVirtualPixels(source_view,0,y,source_image->columns,1,
165 q=GetCacheViewAuthenticPixels(destination_view,0,y,
166 destination_image->columns,1,exception);
167 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
172 destination_traits=GetPixelChannelTraits(destination_image,
173 destination_channel);
174 source_traits=GetPixelChannelTraits(source_image,source_channel);
175 if ((destination_traits == UndefinedPixelTrait) ||
176 (source_traits == UndefinedPixelTrait))
178 for (x=0; x < (ssize_t) width; x++)
180 if (channel_op == AssignChannelOp)
181 SetPixelChannel(destination_image,destination_channel,pixel,q);
183 SetPixelChannel(destination_image,destination_channel,
184 GetPixelChannel(source_image,source_channel,p),q);
185 p+=(ptrdiff_t) GetPixelChannels(source_image);
186 q+=(ptrdiff_t) GetPixelChannels(destination_image);
188 if (SyncCacheViewAuthenticPixels(destination_view,exception) == MagickFalse)
191 destination_view=DestroyCacheView(destination_view);
192 source_view=DestroyCacheView(source_view);
196MagickExport Image *ChannelFxImage(
const Image *image,
const char *expression,
197 ExceptionInfo *exception)
199#define ChannelFxImageTag "ChannelFx/Image"
202 channel_op = ExtractChannelOp;
208 token[MagickPathExtent] =
"";
227 destination_channel = RedPixelChannel;
232 assert(image != (Image *) NULL);
233 assert(image->signature == MagickCoreSignature);
234 if (IsEventLogging() != MagickFalse)
235 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
236 assert(exception != (ExceptionInfo *) NULL);
237 assert(exception->signature == MagickCoreSignature);
240 destination_image=CloneImage(image,0,0,MagickTrue,exception);
241 if (destination_image == (Image *) NULL)
242 return((Image *) NULL);
243 if (expression == (
const char *) NULL)
244 return(destination_image);
245 status=SetImageStorageClass(destination_image,DirectClass,exception);
246 if (status == MagickFalse)
248 destination_image=GetLastImageInList(destination_image);
249 return((Image *) NULL);
251 channel_mask=destination_image->channel_mask;
252 (void) GetNextToken(p,&p,MagickPathExtent,token);
253 while (*token !=
'\0')
268 (void) GetNextToken(p,&p,MagickPathExtent,token);
273 if (GetNextImageInList(source_image) != (Image *) NULL)
274 source_image=GetNextImageInList(source_image);
275 (void) GetNextToken(p,&p,MagickPathExtent,token);
283 (void) SetPixelChannelMask(destination_image,channel_mask);
284 if ((channel_op == ExtractChannelOp) && (channels == 1))
286 (void) SetPixelMetaChannels(destination_image,0,exception);
287 (void) SetImageColorspace(destination_image,GRAYColorspace,
290 canvas=CloneImage(source_image,0,0,MagickTrue,exception);
291 if (canvas == (Image *) NULL)
293 destination_image=DestroyImageList(destination_image);
294 return(destination_image);
296 AppendImageToList(&destination_image,canvas);
297 destination_image=GetLastImageInList(destination_image);
298 status=SetImageStorageClass(destination_image,DirectClass,exception);
299 if (status == MagickFalse)
301 destination_image=GetLastImageInList(destination_image);
302 return((Image *) NULL);
304 (void) GetNextToken(p,&p,MagickPathExtent,token);
306 destination_channel=RedPixelChannel;
307 channel_mask=destination_image->channel_mask;
313 i=ParsePixelChannelOption(token);
314 source_channel=(PixelChannel) i;
315 traits=GetPixelChannelTraits(source_image,source_channel);
316 if (traits == UndefinedPixelTrait)
318 (void) ThrowMagickException(exception,GetMagickModule(),
319 CorruptImageError,
"MissingImageChannel",
"`%s'",token);
320 destination_image=DestroyImageList(destination_image);
321 return(destination_image);
323 channel_op=ExtractChannelOp;
324 (void) GetNextToken(p,&p,MagickPathExtent,token);
327 channel_op=ExchangeChannelOp;
328 (void) GetNextToken(p,&p,MagickPathExtent,token);
332 if (channel_op != ExchangeChannelOp)
333 channel_op=AssignChannelOp;
334 (void) GetNextToken(p,&p,MagickPathExtent,token);
338 if (channel_op != ExchangeChannelOp)
339 channel_op=TransferChannelOp;
340 (void) GetNextToken(p,&p,MagickPathExtent,token);
344 case AssignChannelOp:
345 case ExchangeChannelOp:
346 case TransferChannelOp:
348 if (channel_op == AssignChannelOp)
349 pixel=StringToDoubleInterval(token,(
double) QuantumRange+1.0);
352 i=ParsePixelChannelOption(token);
353 if (LocaleCompare(token,
"alpha") == 0)
354 destination_image->alpha_trait=BlendPixelTrait;
357 (void) ThrowMagickException(exception,GetMagickModule(),
358 OptionError,
"UnrecognizedChannelType",
"`%s'",token);
359 destination_image=DestroyImageList(destination_image);
360 return(destination_image);
363 destination_channel=(PixelChannel) i;
364 if (image->colorspace != UndefinedColorspace)
365 switch (destination_channel)
367 case RedPixelChannel:
368 case GreenPixelChannel:
369 case BluePixelChannel:
370 case BlackPixelChannel:
371 case AlphaPixelChannel:
372 case IndexPixelChannel:
374 case CompositeMaskPixelChannel:
376 destination_image->channels=(ChannelType)
377 (destination_image->channels | CompositeMaskChannel);
380 case ReadMaskPixelChannel:
382 destination_image->channels=(ChannelType)
383 (destination_image->channels | ReadMaskChannel);
386 case WriteMaskPixelChannel:
388 destination_image->channels=(ChannelType)
389 (destination_image->channels | WriteMaskChannel);
392 case MetaPixelChannels:
395 traits=GetPixelChannelTraits(destination_image,
396 destination_channel);
397 if (traits != UndefinedPixelTrait)
399 (void) SetPixelMetaChannels(destination_image,
400 GetPixelMetaChannels(destination_image)+1,exception);
401 traits=GetPixelChannelTraits(destination_image,
402 destination_channel);
403 if (traits == UndefinedPixelTrait)
405 (void) ThrowMagickException(exception,GetMagickModule(),
406 CorruptImageError,
"MissingImageChannel",
"`%s'",token);
407 destination_image=DestroyImageList(destination_image);
408 return(destination_image);
413 channel_mask=(ChannelType) (channel_mask |
414 (MagickLLConstant(1) << ParseChannelOption(token)));
415 (void) GetNextToken(p,&p,MagickPathExtent,token);
421 status=ChannelImage(destination_image,destination_channel,channel_op,
422 source_image,source_channel,ClampToQuantum(pixel),exception);
423 if (status == MagickFalse)
425 destination_image=DestroyImageList(destination_image);
429 if (channel_op == ExchangeChannelOp)
431 status=ChannelImage(destination_image,source_channel,channel_op,
432 source_image,destination_channel,ClampToQuantum(pixel),exception);
433 if (status == MagickFalse)
435 destination_image=DestroyImageList(destination_image);
442 case ExtractChannelOp:
444 channel_mask=(ChannelType) (channel_mask |
445 (MagickLLConstant(1) << destination_channel));
446 destination_channel=(PixelChannel) (destination_channel+1);
452 status=SetImageProgress(source_image,ChannelFxImageTag,p-expression,
454 if (status == MagickFalse)
457 if (destination_image == (Image *) NULL)
458 return(destination_image);
459 (void) SetPixelChannelMask(destination_image,channel_mask);
460 if ((channel_op == ExtractChannelOp) && (channels == 1))
462 (void) SetPixelMetaChannels(destination_image,0,exception);
463 (void) SetImageColorspace(destination_image,GRAYColorspace,exception);
465 return(GetFirstImageInList(destination_image));
498MagickExport Image *CombineImages(
const Image *image,
499 const ColorspaceType colorspace,ExceptionInfo *exception)
501#define CombineImageTag "Combine/Image"
524 assert(image != (
const Image *) NULL);
525 assert(image->signature == MagickCoreSignature);
526 if (IsEventLogging() != MagickFalse)
527 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
528 assert(exception != (ExceptionInfo *) NULL);
529 assert(exception->signature == MagickCoreSignature);
530 combine_image=CloneImage(image,0,0,MagickTrue,exception);
531 if (combine_image == (Image *) NULL)
532 return((Image *) NULL);
533 if (SetImageStorageClass(combine_image,DirectClass,exception) == MagickFalse)
535 combine_image=DestroyImage(combine_image);
536 return((Image *) NULL);
538 if (colorspace != UndefinedColorspace)
539 (void) SetImageColorspace(combine_image,colorspace,exception);
541 if (fabs(image->gamma-1.0) <= MagickEpsilon)
542 (void) SetImageColorspace(combine_image,RGBColorspace,exception);
544 (
void) SetImageColorspace(combine_image,sRGBColorspace,exception);
545 number_channels=GetImageListLength(image);
546 switch (combine_image->colorspace)
548 case UndefinedColorspace:
551 if (number_channels > 3)
552 combine_image->alpha_trait=BlendPixelTrait;
553 if (number_channels > 4)
554 SetPixelMetaChannels(combine_image,number_channels-4,exception);
557 case LinearGRAYColorspace:
560 if (number_channels > 1)
561 combine_image->alpha_trait=BlendPixelTrait;
562 if (number_channels > 2)
563 SetPixelMetaChannels(combine_image,number_channels-2,exception);
568 if (number_channels > 4)
569 combine_image->alpha_trait=BlendPixelTrait;
570 if (number_channels > 5)
571 SetPixelMetaChannels(combine_image,number_channels-5,exception);
582 combine_view=AcquireAuthenticCacheView(combine_image,exception);
583#if defined(MAGICKCORE_OPENMP_SUPPORT)
584 #pragma omp parallel for schedule(static) shared(progress,status) \
585 magick_number_threads(combine_image,combine_image,combine_image->rows,4)
587 for (y=0; y < (ssize_t) combine_image->rows; y++)
605 if (status == MagickFalse)
607 pixels=GetCacheViewAuthenticPixels(combine_view,0,y,combine_image->columns,
609 if (pixels == (Quantum *) NULL)
615 for (i=0; i < (ssize_t) GetPixelChannels(combine_image); i++)
620 PixelChannel channel = GetPixelChannelChannel(combine_image,i);
621 PixelTrait traits = GetPixelChannelTraits(combine_image,channel);
622 if (traits == UndefinedPixelTrait)
624 if (next == (Image *) NULL)
626 image_view=AcquireVirtualCacheView(next,exception);
627 p=GetCacheViewVirtualPixels(image_view,0,y,next->columns,1,exception);
628 if (p == (
const Quantum *) NULL)
631 for (x=0; x < (ssize_t) combine_image->columns; x++)
633 if (x < (ssize_t) next->columns)
635 q[i]=(Quantum) GetPixelIntensity(next,p);
636 p+=(ptrdiff_t) GetPixelChannels(next);
638 q+=(ptrdiff_t) GetPixelChannels(combine_image);
640 image_view=DestroyCacheView(image_view);
641 next=GetNextImageInList(next);
643 if (SyncCacheViewAuthenticPixels(combine_view,exception) == MagickFalse)
645 if (image->progress_monitor != (MagickProgressMonitor) NULL)
650#if defined(MAGICKCORE_OPENMP_SUPPORT)
654 proceed=SetImageProgress(image,CombineImageTag,progress,
655 combine_image->rows);
656 if (proceed == MagickFalse)
660 combine_view=DestroyCacheView(combine_view);
661 if (status == MagickFalse)
662 combine_image=DestroyImage(combine_image);
664 combine_image->type=UndefinedType;
665 return(combine_image);
692MagickExport MagickBooleanType GetImageAlphaChannel(
const Image *image)
694 assert(image != (
const Image *) NULL);
695 if (IsEventLogging() != MagickFalse)
696 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
697 assert(image->signature == MagickCoreSignature);
698 return(image->alpha_trait != UndefinedPixelTrait ? MagickTrue : MagickFalse);
729MagickExport Image *SeparateImage(
const Image *image,
730 const ChannelType channel_type,ExceptionInfo *exception)
732#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
733#define SeparateImageTag "Separate/Image"
754 assert(image != (Image *) NULL);
755 assert(image->signature == MagickCoreSignature);
756 if (IsEventLogging() != MagickFalse)
757 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
758 assert(exception != (ExceptionInfo *) NULL);
759 assert(exception->signature == MagickCoreSignature);
760 separate_image=CloneImage(image,0,0,MagickTrue,exception);
761 if (separate_image == (Image *) NULL)
762 return((Image *) NULL);
763 if (SetImageStorageClass(separate_image,DirectClass,exception) == MagickFalse)
765 separate_image=DestroyImage(separate_image);
766 return((Image *) NULL);
768 separate_image->alpha_trait=UndefinedPixelTrait;
769 (void) SetImageColorspace(separate_image,GRAYColorspace,exception);
770 separate_image->gamma=image->gamma;
776 image_view=AcquireVirtualCacheView(image,exception);
777 separate_view=AcquireAuthenticCacheView(separate_image,exception);
778#if defined(MAGICKCORE_OPENMP_SUPPORT)
779 #pragma omp parallel for schedule(static) shared(progress,status) \
780 magick_number_threads(image,image,image->rows,2)
782 for (y=0; y < (ssize_t) image->rows; y++)
793 if (status == MagickFalse)
795 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
796 q=QueueCacheViewAuthenticPixels(separate_view,0,y,separate_image->columns,1,
798 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
803 for (x=0; x < (ssize_t) image->columns; x++)
808 SetPixelChannel(separate_image,GrayPixelChannel,(Quantum) 0,q);
809 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
811 PixelChannel channel = GetPixelChannelChannel(image,i);
812 PixelTrait traits = GetPixelChannelTraits(image,channel);
813 if ((traits == UndefinedPixelTrait) ||
814 (GetChannelBit(channel_type,channel) == 0))
816 SetPixelChannel(separate_image,GrayPixelChannel,p[i],q);
818 p+=(ptrdiff_t) GetPixelChannels(image);
819 q+=(ptrdiff_t) GetPixelChannels(separate_image);
821 if (SyncCacheViewAuthenticPixels(separate_view,exception) == MagickFalse)
823 if (image->progress_monitor != (MagickProgressMonitor) NULL)
828#if defined(MAGICKCORE_OPENMP_SUPPORT)
832 proceed=SetImageProgress(image,SeparateImageTag,progress,image->rows);
833 if (proceed == MagickFalse)
837 separate_view=DestroyCacheView(separate_view);
838 image_view=DestroyCacheView(image_view);
839 (void) SetImageChannelMask(separate_image,AllChannels);
840 if (status == MagickFalse)
841 separate_image=DestroyImage(separate_image);
842 return(separate_image);
870MagickExport Image *SeparateImages(
const Image *image,ExceptionInfo *exception)
879 assert(image != (Image *) NULL);
880 assert(image->signature == MagickCoreSignature);
881 if (IsEventLogging() != MagickFalse)
882 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
883 images=NewImageList();
884 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
886 PixelChannel channel = GetPixelChannelChannel(image,i);
887 PixelTrait traits = GetPixelChannelTraits(image,channel);
888 if ((traits == UndefinedPixelTrait) || ((traits & UpdatePixelTrait) == 0))
890 separate_image=SeparateImage(image,(ChannelType)
891 (MagickLLConstant(1) << channel),exception);
892 if (separate_image != (Image *) NULL)
893 AppendImageToList(&images,separate_image);
895 if (images == (Image *) NULL)
896 images=SeparateImage(image,UndefinedChannel,exception);
933static inline void FlattenPixelInfo(
const Image *image,
const PixelInfo *p,
934 const double alpha,
const Quantum *q,
const double beta,Quantum *composite)
947 Sa=QuantumScale*alpha;
948 Da=QuantumScale*beta,
949 gamma=Sa*(-Da)+Sa+Da;
950 gamma=MagickSafeReciprocal(gamma);
951 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
953 PixelChannel channel = GetPixelChannelChannel(image,i);
954 PixelTrait traits = GetPixelChannelTraits(image,channel);
955 if (traits == UndefinedPixelTrait)
959 case RedPixelChannel:
961 composite[i]=ClampToQuantum(gamma*MagickOver_((
double) q[i],beta,
962 (
double) p->red,alpha));
965 case GreenPixelChannel:
967 composite[i]=ClampToQuantum(gamma*MagickOver_((
double) q[i],beta,
968 (
double) p->green,alpha));
971 case BluePixelChannel:
973 composite[i]=ClampToQuantum(gamma*MagickOver_((
double) q[i],beta,
974 (
double) p->blue,alpha));
977 case BlackPixelChannel:
979 composite[i]=ClampToQuantum(gamma*MagickOver_((
double) q[i],beta,
980 (
double) p->black,alpha));
983 case AlphaPixelChannel:
985 composite[i]=ClampToQuantum((
double) QuantumRange*(Sa*(-Da)+Sa+Da));
994MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
995 const AlphaChannelOption alpha_type,ExceptionInfo *exception)
1006 assert(image != (Image *) NULL);
1007 if (IsEventLogging() != MagickFalse)
1008 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
1009 assert(image->signature == MagickCoreSignature);
1013 case ActivateAlphaChannel:
1015 if ((image->alpha_trait & BlendPixelTrait) != 0)
1017 image->alpha_trait=BlendPixelTrait;
1020 case AssociateAlphaChannel:
1025 status=SetImageStorageClass(image,DirectClass,exception);
1026 if (status == MagickFalse)
1028 image_view=AcquireAuthenticCacheView(image,exception);
1029#if defined(MAGICKCORE_OPENMP_SUPPORT)
1030 #pragma omp parallel for schedule(static) shared(status) \
1031 magick_number_threads(image,image,image->rows,2)
1033 for (y=0; y < (ssize_t) image->rows; y++)
1041 if (status == MagickFalse)
1043 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1045 if (q == (Quantum *) NULL)
1050 for (x=0; x < (ssize_t) image->columns; x++)
1058 gamma=QuantumScale*(double) GetPixelAlpha(image,q);
1059 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1061 PixelChannel channel = GetPixelChannelChannel(image,i);
1062 PixelTrait traits = GetPixelChannelTraits(image,channel);
1063 if (channel == AlphaPixelChannel)
1065 if ((traits & UpdatePixelTrait) == 0)
1067 q[i]=ClampToQuantum(gamma*(
double) q[i]);
1069 q+=(ptrdiff_t) GetPixelChannels(image);
1071 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1074 image_view=DestroyCacheView(image_view);
1075 image->alpha_trait=CopyPixelTrait;
1078 case BackgroundAlphaChannel:
1083 if ((image->alpha_trait & BlendPixelTrait) == 0)
1085 status=SetImageStorageClass(image,DirectClass,exception);
1086 if (status == MagickFalse)
1088 image_view=AcquireAuthenticCacheView(image,exception);
1089#if defined(MAGICKCORE_OPENMP_SUPPORT)
1090 #pragma omp parallel for schedule(static) shared(status) \
1091 magick_number_threads(image,image,image->rows,2)
1093 for (y=0; y < (ssize_t) image->rows; y++)
1101 if (status == MagickFalse)
1103 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1105 if (q == (Quantum *) NULL)
1110 for (x=0; x < (ssize_t) image->columns; x++)
1112 if (GetPixelAlpha(image,q) == TransparentAlpha)
1114 SetPixelViaPixelInfo(image,&image->background_color,q);
1115 SetPixelChannel(image,AlphaPixelChannel,TransparentAlpha,q);
1117 q+=(ptrdiff_t) GetPixelChannels(image);
1119 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1122 image_view=DestroyCacheView(image_view);
1125 case CopyAlphaChannel:
1127 image->alpha_trait=UpdatePixelTrait;
1128 status=CompositeImage(image,image,IntensityCompositeOp,MagickTrue,0,0,
1132 case DeactivateAlphaChannel:
1134 if ((image->alpha_trait & BlendPixelTrait) == 0)
1135 status=SetImageAlpha(image,OpaqueAlpha,exception);
1136 image->alpha_trait=CopyPixelTrait;
1139 case DisassociateAlphaChannel:
1144 status=SetImageStorageClass(image,DirectClass,exception);
1145 if (status == MagickFalse)
1147 image->alpha_trait=BlendPixelTrait;
1148 image_view=AcquireAuthenticCacheView(image,exception);
1149#if defined(MAGICKCORE_OPENMP_SUPPORT)
1150 #pragma omp parallel for schedule(static) shared(status) \
1151 magick_number_threads(image,image,image->rows,2)
1153 for (y=0; y < (ssize_t) image->rows; y++)
1161 if (status == MagickFalse)
1163 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1165 if (q == (Quantum *) NULL)
1170 for (x=0; x < (ssize_t) image->columns; x++)
1179 Sa=QuantumScale*(double) GetPixelAlpha(image,q);
1180 gamma=MagickSafeReciprocal(Sa);
1181 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1183 PixelChannel channel = GetPixelChannelChannel(image,i);
1184 PixelTrait traits = GetPixelChannelTraits(image,channel);
1185 if (channel == AlphaPixelChannel)
1187 if ((traits & UpdatePixelTrait) == 0)
1189 q[i]=ClampToQuantum(gamma*(
double) q[i]);
1191 q+=(ptrdiff_t) GetPixelChannels(image);
1193 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1196 image_view=DestroyCacheView(image_view);
1197 image->alpha_trait=UndefinedPixelTrait;
1200 case DiscreteAlphaChannel:
1202 if ((image->alpha_trait & BlendPixelTrait) == 0)
1203 status=SetImageAlpha(image,OpaqueAlpha,exception);
1204 image->alpha_trait=UpdatePixelTrait;
1207 case ExtractAlphaChannel:
1209 status=CompositeImage(image,image,AlphaCompositeOp,MagickTrue,0,0,
1211 image->alpha_trait=UndefinedPixelTrait;
1214 case OffAlphaChannel:
1216 if ((image->alpha_trait & BlendPixelTrait) == 0)
1218 image->alpha_trait=UndefinedPixelTrait;
1221 case OffIfOpaqueAlphaChannel:
1224 opaque = MagickTrue;
1229 if ((image->alpha_trait & BlendPixelTrait) == 0)
1231 image_view=AcquireVirtualCacheView(image,exception);
1232#if defined(MAGICKCORE_OPENMP_SUPPORT)
1233 #pragma omp parallel for schedule(static) shared(opaque,status) \
1234 magick_number_threads(image,image,image->rows,2)
1236 for (y=0; y < (ssize_t) image->rows; y++)
1244 if ((status == MagickFalse) || (opaque == MagickFalse))
1246 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1247 if (p == (
const Quantum *) NULL)
1252 for (x=0; x < (ssize_t) image->columns; x++)
1254 if (GetPixelAlpha(image,p) != OpaqueAlpha)
1259 p+=(ptrdiff_t) GetPixelChannels(image);
1262 image_view=DestroyCacheView(image_view);
1263 if (opaque != MagickFalse)
1264 image->alpha_trait=UndefinedPixelTrait;
1267 case OnAlphaChannel:
1269 if ((image->alpha_trait & BlendPixelTrait) == 0)
1270 status=SetImageAlpha(image,OpaqueAlpha,exception);
1271 image->alpha_trait=BlendPixelTrait;
1274 case OpaqueAlphaChannel:
1276 status=SetImageAlpha(image,OpaqueAlpha,exception);
1279 case RemoveAlphaChannel:
1284 if ((image->alpha_trait & BlendPixelTrait) == 0)
1286 status=SetImageStorageClass(image,DirectClass,exception);
1287 if (status == MagickFalse)
1289 image_view=AcquireAuthenticCacheView(image,exception);
1290#if defined(MAGICKCORE_OPENMP_SUPPORT)
1291 #pragma omp parallel for schedule(static) shared(status) \
1292 magick_number_threads(image,image,image->rows,2)
1294 for (y=0; y < (ssize_t) image->rows; y++)
1302 if (status == MagickFalse)
1304 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1306 if (q == (Quantum *) NULL)
1311 for (x=0; x < (ssize_t) image->columns; x++)
1313 FlattenPixelInfo(image,&image->background_color,
1314 image->background_color.alpha,q,(
double) GetPixelAlpha(image,q),q);
1315 q+=(ptrdiff_t) GetPixelChannels(image);
1317 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1320 image_view=DestroyCacheView(image_view);
1321 image->alpha_trait=image->background_color.alpha_trait;
1324 case SetAlphaChannel:
1326 if ((image->alpha_trait & BlendPixelTrait) == 0)
1327 status=SetImageAlpha(image,OpaqueAlpha,exception);
1330 case ShapeAlphaChannel:
1338 ConformPixelInfo(image,&image->background_color,&background,exception);
1339 background.alpha_trait=BlendPixelTrait;
1340 image->alpha_trait=BlendPixelTrait;
1341 status=SetImageStorageClass(image,DirectClass,exception);
1342 if (status == MagickFalse)
1344 image_view=AcquireAuthenticCacheView(image,exception);
1345#if defined(MAGICKCORE_OPENMP_SUPPORT)
1346 #pragma omp parallel for schedule(static) shared(status) \
1347 magick_number_threads(image,image,image->rows,2)
1349 for (y=0; y < (ssize_t) image->rows; y++)
1360 if (status == MagickFalse)
1362 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1364 if (q == (Quantum *) NULL)
1370 for (x=0; x < (ssize_t) image->columns; x++)
1372 pixel.alpha=GetPixelIntensity(image,q);
1373 SetPixelViaPixelInfo(image,&pixel,q);
1374 q+=(ptrdiff_t) GetPixelChannels(image);
1376 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1379 image_view=DestroyCacheView(image_view);
1382 case TransparentAlphaChannel:
1384 status=SetImageAlpha(image,TransparentAlpha,exception);
1387 case UndefinedAlphaChannel:
1390 if (status == MagickFalse)
1392 (void) SetPixelChannelMask(image,image->channel_mask);
1393 return(SyncImagePixelCache(image,exception));