From: cristy Date: Thu, 26 Jan 2012 23:50:21 +0000 (+0000) Subject: (no commit message) X-Git-Tag: 7.0.1-0~6305 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e39ed0bb9bf07c361de6992cd4df8999e3500ac4;p=imagemagick --- diff --git a/MagickCore/image.c b/MagickCore/image.c index 7f96174a3..da9bda095 100644 --- a/MagickCore/image.c +++ b/MagickCore/image.c @@ -2410,6 +2410,75 @@ MagickExport Image *SeparateImages(const Image *image,ExceptionInfo *exception) % o exception: return any errors or warnings in this structure. % */ + +static inline void FlattenPixelInfo(const Image *image,const PixelInfo *p, + const MagickRealType alpha,const Quantum *q,const MagickRealType beta, + Quantum *composite) +{ + MagickRealType + 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=1.0/(gamma <= MagickEpsilon ? 1.0 : gamma); + for (i=0; i < (ssize_t) GetPixelChannels(image); i++) + { + PixelChannel + channel; + + PixelTrait + traits; + + channel=GetPixelChannelMapChannel(image,i); + traits=GetPixelChannelMapTraits(image,channel); + if (traits == UndefinedPixelTrait) + continue; + switch (channel) + { + case RedPixelChannel: + { + composite[i]=ClampToQuantum(gamma*MagickOver_((MagickRealType) q[i], + beta,(MagickRealType) p->red,alpha)); + break; + } + case GreenPixelChannel: + { + composite[i]=ClampToQuantum(gamma*MagickOver_((MagickRealType) q[i], + beta,(MagickRealType) p->green,alpha)); + break; + } + case BluePixelChannel: + { + composite[i]=ClampToQuantum(gamma*MagickOver_((MagickRealType) q[i], + beta,(MagickRealType) p->blue,alpha)); + break; + } + case BlackPixelChannel: + { + composite[i]=ClampToQuantum(gamma*MagickOver_((MagickRealType) q[i], + beta,(MagickRealType) p->black,alpha)); + break; + } + case AlphaPixelChannel: + { + composite[i]=ClampToQuantum(QuantumRange*(Sa*(-Da)+Sa+Da)); + break; + } + default: + break; + } + } +} + MagickExport MagickBooleanType SetImageAlphaChannel(Image *image, const AlphaChannelType alpha_type,ExceptionInfo *exception) { @@ -2433,19 +2502,16 @@ MagickExport MagickBooleanType SetImageAlphaChannel(Image *image, CacheView *image_view; - PixelInfo - background; - ssize_t y; /* Set transparent pixels to background color. */ - image->matte=MagickTrue; + if (image->matte == MagickFalse) + break; if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) break; - background=image->background_color; image_view=AcquireCacheView(image); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static,4) shared(status) @@ -2470,7 +2536,7 @@ MagickExport MagickBooleanType SetImageAlphaChannel(Image *image, for (x=0; x < (ssize_t) image->columns; x++) { if (GetPixelAlpha(image,q) == TransparentAlpha) - SetPixelInfoPixel(image,&background,q); + SetPixelInfoPixel(image,&image->background_color,q); q+=GetPixelChannels(image); } if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) @@ -2479,13 +2545,8 @@ MagickExport MagickBooleanType SetImageAlphaChannel(Image *image, image_view=DestroyCacheView(image_view); return(status); } - case DeactivateAlphaChannel: - { - image->matte=MagickFalse; - break; - } - case ShapeAlphaChannel: case CopyAlphaChannel: + case ShapeAlphaChannel: { /* Copy pixel intensity to the alpha channel. @@ -2496,6 +2557,11 @@ MagickExport MagickBooleanType SetImageAlphaChannel(Image *image, &image->background_color,MagickTrue,exception); break; } + case DeactivateAlphaChannel: + { + image->matte=MagickFalse; + break; + } case ExtractAlphaChannel: { status=CompositeImage(image,AlphaCompositeOp,image,0,0,exception); @@ -2507,10 +2573,54 @@ MagickExport MagickBooleanType SetImageAlphaChannel(Image *image, status=SetImageAlpha(image,OpaqueAlpha,exception); break; } - case TransparentAlphaChannel: + case FlattenAlphaChannel: { - status=SetImageAlpha(image,TransparentAlpha,exception); - break; + CacheView + *image_view; + + ssize_t + y; + + /* + Flatten image pixels over the background pixels. + */ + if (image->matte == MagickFalse) + break; + if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) + break; + image_view=AcquireCacheView(image); +#if defined(MAGICKCORE_OPENMP_SUPPORT) + #pragma omp parallel for schedule(static,4) shared(status) +#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,(MagickRealType) + GetPixelAlpha(image,q),q); + q+=GetPixelChannels(image); + } + if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) + status=MagickFalse; + } + image_view=DestroyCacheView(image_view); + return(status); } case SetAlphaChannel: { @@ -2518,6 +2628,11 @@ MagickExport MagickBooleanType SetImageAlphaChannel(Image *image, status=SetImageAlpha(image,OpaqueAlpha,exception); break; } + case TransparentAlphaChannel: + { + status=SetImageAlpha(image,TransparentAlpha,exception); + break; + } case UndefinedAlphaChannel: break; } diff --git a/MagickCore/image.h b/MagickCore/image.h index b6f0c39eb..d4403b8bb 100644 --- a/MagickCore/image.h +++ b/MagickCore/image.h @@ -38,7 +38,8 @@ typedef enum OpaqueAlphaChannel, SetAlphaChannel, ShapeAlphaChannel, - TransparentAlphaChannel + TransparentAlphaChannel, + FlattenAlphaChannel } AlphaChannelType; typedef enum diff --git a/MagickCore/option.c b/MagickCore/option.c index 17bdf6878..4024c49d5 100644 --- a/MagickCore/option.c +++ b/MagickCore/option.c @@ -98,6 +98,7 @@ static const OptionInfo { "Copy", CopyAlphaChannel, UndefinedOptionFlag, MagickFalse }, { "Deactivate", DeactivateAlphaChannel, UndefinedOptionFlag, MagickFalse }, { "Extract", ExtractAlphaChannel, UndefinedOptionFlag, MagickFalse }, + { "Flatten", FlattenAlphaChannel, UndefinedOptionFlag, MagickFalse }, { "Off", DeactivateAlphaChannel, UndefinedOptionFlag, MagickFalse }, { "On", ActivateAlphaChannel, UndefinedOptionFlag, MagickFalse }, { "Opaque", OpaqueAlphaChannel, UndefinedOptionFlag, MagickFalse },