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);
663 return(combine_image);
690MagickExport MagickBooleanType GetImageAlphaChannel(
const Image *image)
692 assert(image != (
const Image *) NULL);
693 if (IsEventLogging() != MagickFalse)
694 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
695 assert(image->signature == MagickCoreSignature);
696 return(image->alpha_trait != UndefinedPixelTrait ? MagickTrue : MagickFalse);
727MagickExport Image *SeparateImage(
const Image *image,
728 const ChannelType channel_type,ExceptionInfo *exception)
730#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
731#define SeparateImageTag "Separate/Image"
752 assert(image != (Image *) NULL);
753 assert(image->signature == MagickCoreSignature);
754 if (IsEventLogging() != MagickFalse)
755 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
756 assert(exception != (ExceptionInfo *) NULL);
757 assert(exception->signature == MagickCoreSignature);
758 separate_image=CloneImage(image,0,0,MagickTrue,exception);
759 if (separate_image == (Image *) NULL)
760 return((Image *) NULL);
761 if (SetImageStorageClass(separate_image,DirectClass,exception) == MagickFalse)
763 separate_image=DestroyImage(separate_image);
764 return((Image *) NULL);
766 separate_image->alpha_trait=UndefinedPixelTrait;
767 (void) SetImageColorspace(separate_image,GRAYColorspace,exception);
768 separate_image->gamma=image->gamma;
774 image_view=AcquireVirtualCacheView(image,exception);
775 separate_view=AcquireAuthenticCacheView(separate_image,exception);
776#if defined(MAGICKCORE_OPENMP_SUPPORT)
777 #pragma omp parallel for schedule(static) shared(progress,status) \
778 magick_number_threads(image,image,image->rows,2)
780 for (y=0; y < (ssize_t) image->rows; y++)
791 if (status == MagickFalse)
793 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
794 q=QueueCacheViewAuthenticPixels(separate_view,0,y,separate_image->columns,1,
796 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
801 for (x=0; x < (ssize_t) image->columns; x++)
806 SetPixelChannel(separate_image,GrayPixelChannel,(Quantum) 0,q);
807 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
809 PixelChannel channel = GetPixelChannelChannel(image,i);
810 PixelTrait traits = GetPixelChannelTraits(image,channel);
811 if ((traits == UndefinedPixelTrait) ||
812 (GetChannelBit(channel_type,channel) == 0))
814 SetPixelChannel(separate_image,GrayPixelChannel,p[i],q);
816 p+=(ptrdiff_t) GetPixelChannels(image);
817 q+=(ptrdiff_t) GetPixelChannels(separate_image);
819 if (SyncCacheViewAuthenticPixels(separate_view,exception) == MagickFalse)
821 if (image->progress_monitor != (MagickProgressMonitor) NULL)
826#if defined(MAGICKCORE_OPENMP_SUPPORT)
830 proceed=SetImageProgress(image,SeparateImageTag,progress,image->rows);
831 if (proceed == MagickFalse)
835 separate_view=DestroyCacheView(separate_view);
836 image_view=DestroyCacheView(image_view);
837 (void) SetImageChannelMask(separate_image,AllChannels);
838 if (status == MagickFalse)
839 separate_image=DestroyImage(separate_image);
840 return(separate_image);
868MagickExport Image *SeparateImages(
const Image *image,ExceptionInfo *exception)
877 assert(image != (Image *) NULL);
878 assert(image->signature == MagickCoreSignature);
879 if (IsEventLogging() != MagickFalse)
880 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
881 images=NewImageList();
882 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
884 PixelChannel channel = GetPixelChannelChannel(image,i);
885 PixelTrait traits = GetPixelChannelTraits(image,channel);
886 if ((traits == UndefinedPixelTrait) || ((traits & UpdatePixelTrait) == 0))
888 separate_image=SeparateImage(image,(ChannelType)
889 (MagickLLConstant(1) << channel),exception);
890 if (separate_image != (Image *) NULL)
891 AppendImageToList(&images,separate_image);
893 if (images == (Image *) NULL)
894 images=SeparateImage(image,UndefinedChannel,exception);
931static inline void FlattenPixelInfo(
const Image *image,
const PixelInfo *p,
932 const double alpha,
const Quantum *q,
const double beta,Quantum *composite)
945 Sa=QuantumScale*alpha;
946 Da=QuantumScale*beta,
947 gamma=Sa*(-Da)+Sa+Da;
948 gamma=MagickSafeReciprocal(gamma);
949 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
951 PixelChannel channel = GetPixelChannelChannel(image,i);
952 PixelTrait traits = GetPixelChannelTraits(image,channel);
953 if (traits == UndefinedPixelTrait)
957 case RedPixelChannel:
959 composite[i]=ClampToQuantum(gamma*MagickOver_((
double) q[i],beta,
960 (
double) p->red,alpha));
963 case GreenPixelChannel:
965 composite[i]=ClampToQuantum(gamma*MagickOver_((
double) q[i],beta,
966 (
double) p->green,alpha));
969 case BluePixelChannel:
971 composite[i]=ClampToQuantum(gamma*MagickOver_((
double) q[i],beta,
972 (
double) p->blue,alpha));
975 case BlackPixelChannel:
977 composite[i]=ClampToQuantum(gamma*MagickOver_((
double) q[i],beta,
978 (
double) p->black,alpha));
981 case AlphaPixelChannel:
983 composite[i]=ClampToQuantum((
double) QuantumRange*(Sa*(-Da)+Sa+Da));
992MagickExport MagickBooleanType SetImageAlphaChannel(Image *image,
993 const AlphaChannelOption alpha_type,ExceptionInfo *exception)
1004 assert(image != (Image *) NULL);
1005 if (IsEventLogging() != MagickFalse)
1006 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
1007 assert(image->signature == MagickCoreSignature);
1011 case ActivateAlphaChannel:
1013 if ((image->alpha_trait & BlendPixelTrait) != 0)
1015 image->alpha_trait=BlendPixelTrait;
1018 case AssociateAlphaChannel:
1023 status=SetImageStorageClass(image,DirectClass,exception);
1024 if (status == MagickFalse)
1026 image_view=AcquireAuthenticCacheView(image,exception);
1027#if defined(MAGICKCORE_OPENMP_SUPPORT)
1028 #pragma omp parallel for schedule(static) shared(status) \
1029 magick_number_threads(image,image,image->rows,2)
1031 for (y=0; y < (ssize_t) image->rows; y++)
1039 if (status == MagickFalse)
1041 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1043 if (q == (Quantum *) NULL)
1048 for (x=0; x < (ssize_t) image->columns; x++)
1056 gamma=QuantumScale*(double) GetPixelAlpha(image,q);
1057 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1059 PixelChannel channel = GetPixelChannelChannel(image,i);
1060 PixelTrait traits = GetPixelChannelTraits(image,channel);
1061 if (channel == AlphaPixelChannel)
1063 if ((traits & UpdatePixelTrait) == 0)
1065 q[i]=ClampToQuantum(gamma*(
double) q[i]);
1067 q+=(ptrdiff_t) GetPixelChannels(image);
1069 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1072 image_view=DestroyCacheView(image_view);
1073 image->alpha_trait=CopyPixelTrait;
1076 case BackgroundAlphaChannel:
1081 if ((image->alpha_trait & BlendPixelTrait) == 0)
1083 status=SetImageStorageClass(image,DirectClass,exception);
1084 if (status == MagickFalse)
1086 image_view=AcquireAuthenticCacheView(image,exception);
1087#if defined(MAGICKCORE_OPENMP_SUPPORT)
1088 #pragma omp parallel for schedule(static) shared(status) \
1089 magick_number_threads(image,image,image->rows,2)
1091 for (y=0; y < (ssize_t) image->rows; y++)
1099 if (status == MagickFalse)
1101 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1103 if (q == (Quantum *) NULL)
1108 for (x=0; x < (ssize_t) image->columns; x++)
1110 if (GetPixelAlpha(image,q) == TransparentAlpha)
1112 SetPixelViaPixelInfo(image,&image->background_color,q);
1113 SetPixelChannel(image,AlphaPixelChannel,TransparentAlpha,q);
1115 q+=(ptrdiff_t) GetPixelChannels(image);
1117 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1120 image_view=DestroyCacheView(image_view);
1123 case CopyAlphaChannel:
1125 image->alpha_trait=UpdatePixelTrait;
1126 status=CompositeImage(image,image,IntensityCompositeOp,MagickTrue,0,0,
1130 case DeactivateAlphaChannel:
1132 if ((image->alpha_trait & BlendPixelTrait) == 0)
1133 status=SetImageAlpha(image,OpaqueAlpha,exception);
1134 image->alpha_trait=CopyPixelTrait;
1137 case DisassociateAlphaChannel:
1142 status=SetImageStorageClass(image,DirectClass,exception);
1143 if (status == MagickFalse)
1145 image->alpha_trait=BlendPixelTrait;
1146 image_view=AcquireAuthenticCacheView(image,exception);
1147#if defined(MAGICKCORE_OPENMP_SUPPORT)
1148 #pragma omp parallel for schedule(static) shared(status) \
1149 magick_number_threads(image,image,image->rows,2)
1151 for (y=0; y < (ssize_t) image->rows; y++)
1159 if (status == MagickFalse)
1161 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1163 if (q == (Quantum *) NULL)
1168 for (x=0; x < (ssize_t) image->columns; x++)
1177 Sa=QuantumScale*(double) GetPixelAlpha(image,q);
1178 gamma=MagickSafeReciprocal(Sa);
1179 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1181 PixelChannel channel = GetPixelChannelChannel(image,i);
1182 PixelTrait traits = GetPixelChannelTraits(image,channel);
1183 if (channel == AlphaPixelChannel)
1185 if ((traits & UpdatePixelTrait) == 0)
1187 q[i]=ClampToQuantum(gamma*(
double) q[i]);
1189 q+=(ptrdiff_t) GetPixelChannels(image);
1191 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1194 image_view=DestroyCacheView(image_view);
1195 image->alpha_trait=UndefinedPixelTrait;
1198 case DiscreteAlphaChannel:
1200 if ((image->alpha_trait & BlendPixelTrait) == 0)
1201 status=SetImageAlpha(image,OpaqueAlpha,exception);
1202 image->alpha_trait=UpdatePixelTrait;
1205 case ExtractAlphaChannel:
1207 status=CompositeImage(image,image,AlphaCompositeOp,MagickTrue,0,0,
1209 image->alpha_trait=UndefinedPixelTrait;
1212 case OffAlphaChannel:
1214 if ((image->alpha_trait & BlendPixelTrait) == 0)
1216 image->alpha_trait=UndefinedPixelTrait;
1219 case OffIfOpaqueAlphaChannel:
1222 opaque = MagickTrue;
1227 if ((image->alpha_trait & BlendPixelTrait) == 0)
1229 image_view=AcquireVirtualCacheView(image,exception);
1230#if defined(MAGICKCORE_OPENMP_SUPPORT)
1231 #pragma omp parallel for schedule(static) shared(opaque,status) \
1232 magick_number_threads(image,image,image->rows,2)
1234 for (y=0; y < (ssize_t) image->rows; y++)
1242 if ((status == MagickFalse) || (opaque == MagickFalse))
1244 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1245 if (p == (
const Quantum *) NULL)
1250 for (x=0; x < (ssize_t) image->columns; x++)
1252 if (GetPixelAlpha(image,p) != OpaqueAlpha)
1257 p+=(ptrdiff_t) GetPixelChannels(image);
1260 image_view=DestroyCacheView(image_view);
1261 if (opaque != MagickFalse)
1262 image->alpha_trait=UndefinedPixelTrait;
1265 case OnAlphaChannel:
1267 if ((image->alpha_trait & BlendPixelTrait) == 0)
1268 status=SetImageAlpha(image,OpaqueAlpha,exception);
1269 image->alpha_trait=BlendPixelTrait;
1272 case OpaqueAlphaChannel:
1274 status=SetImageAlpha(image,OpaqueAlpha,exception);
1277 case RemoveAlphaChannel:
1282 if ((image->alpha_trait & BlendPixelTrait) == 0)
1284 status=SetImageStorageClass(image,DirectClass,exception);
1285 if (status == MagickFalse)
1287 image_view=AcquireAuthenticCacheView(image,exception);
1288#if defined(MAGICKCORE_OPENMP_SUPPORT)
1289 #pragma omp parallel for schedule(static) shared(status) \
1290 magick_number_threads(image,image,image->rows,2)
1292 for (y=0; y < (ssize_t) image->rows; y++)
1300 if (status == MagickFalse)
1302 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1304 if (q == (Quantum *) NULL)
1309 for (x=0; x < (ssize_t) image->columns; x++)
1311 FlattenPixelInfo(image,&image->background_color,
1312 image->background_color.alpha,q,(
double) GetPixelAlpha(image,q),q);
1313 q+=(ptrdiff_t) GetPixelChannels(image);
1315 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1318 image_view=DestroyCacheView(image_view);
1319 image->alpha_trait=image->background_color.alpha_trait;
1322 case SetAlphaChannel:
1324 if ((image->alpha_trait & BlendPixelTrait) == 0)
1325 status=SetImageAlpha(image,OpaqueAlpha,exception);
1328 case ShapeAlphaChannel:
1336 ConformPixelInfo(image,&image->background_color,&background,exception);
1337 background.alpha_trait=BlendPixelTrait;
1338 image->alpha_trait=BlendPixelTrait;
1339 status=SetImageStorageClass(image,DirectClass,exception);
1340 if (status == MagickFalse)
1342 image_view=AcquireAuthenticCacheView(image,exception);
1343#if defined(MAGICKCORE_OPENMP_SUPPORT)
1344 #pragma omp parallel for schedule(static) shared(status) \
1345 magick_number_threads(image,image,image->rows,2)
1347 for (y=0; y < (ssize_t) image->rows; y++)
1358 if (status == MagickFalse)
1360 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,
1362 if (q == (Quantum *) NULL)
1368 for (x=0; x < (ssize_t) image->columns; x++)
1370 pixel.alpha=GetPixelIntensity(image,q);
1371 SetPixelViaPixelInfo(image,&pixel,q);
1372 q+=(ptrdiff_t) GetPixelChannels(image);
1374 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
1377 image_view=DestroyCacheView(image_view);
1380 case TransparentAlphaChannel:
1382 status=SetImageAlpha(image,TransparentAlpha,exception);
1385 case UndefinedAlphaChannel:
1388 if (status == MagickFalse)
1390 (void) SetPixelChannelMask(image,image->channel_mask);
1391 return(SyncImagePixelCache(image,exception));