/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % DDDD EEEEE CCCC OOO RRRR AAA TTTTT EEEEE % % D D E C O O R R A A T E % % D D EEE C O O RRRR AAAAA T EEE % % D D E C O O R R A A T E % % DDDD EEEEE CCCC OOO R R A A T EEEEE % % % % % % MagickCore Image Decoration Methods % % % % Software Design % % Cristy % % July 1992 % % % % % % Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization % % dedicated to making software imaging solutions freely available. % % % % You may not use this file except in compliance with the License. You may % % obtain a copy of the License at % % % % https://imagemagick.org/script/license.php % % % % Unless required by applicable law or agreed to in writing, software % % distributed under the License is distributed on an "AS IS" BASIS, % % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % % See the License for the specific language governing permissions and % % limitations under the License. % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % */ /* Include declarations. */ #include "MagickCore/studio.h" #include "MagickCore/cache-view.h" #include "MagickCore/color-private.h" #include "MagickCore/colorspace-private.h" #include "MagickCore/composite.h" #include "MagickCore/decorate.h" #include "MagickCore/exception.h" #include "MagickCore/exception-private.h" #include "MagickCore/image.h" #include "MagickCore/memory_.h" #include "MagickCore/monitor.h" #include "MagickCore/monitor-private.h" #include "MagickCore/pixel-accessor.h" #include "MagickCore/quantum.h" #include "MagickCore/quantum-private.h" #include "MagickCore/resource_.h" #include "MagickCore/thread-private.h" #include "MagickCore/transform.h" /* Define declarations. */ #define AccentuateModulate ScaleCharToQuantum(80) #define HighlightModulate ScaleCharToQuantum(125) #define ShadowModulate ScaleCharToQuantum(135) #define DepthModulate ScaleCharToQuantum(185) #define TroughModulate ScaleCharToQuantum(110) /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % B o r d e r I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % BorderImage() surrounds the image with a border of the color defined by % the bordercolor member of the image structure. The width and height % of the border are defined by the corresponding members of the border_info % structure. % % The format of the BorderImage method is: % % Image *BorderImage(const Image *image,const RectangleInfo *border_info, % const CompositeOperator compose,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: the image. % % o border_info: define the width and height of the border. % % o compose: the composite operator. % % o exception: return any errors or warnings in this structure. % */ MagickExport Image *BorderImage(const Image *image, const RectangleInfo *border_info,const CompositeOperator compose, ExceptionInfo *exception) { Image *border_image, *clone_image; FrameInfo frame_info; assert(image != (const Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(border_info != (RectangleInfo *) NULL); frame_info.width=image->columns+(border_info->width << 1); frame_info.height=image->rows+(border_info->height << 1); frame_info.x=(ssize_t) border_info->width; frame_info.y=(ssize_t) border_info->height; frame_info.inner_bevel=0; frame_info.outer_bevel=0; clone_image=CloneImage(image,0,0,MagickTrue,exception); if (clone_image == (Image *) NULL) return((Image *) NULL); clone_image->matte_color=image->border_color; border_image=FrameImage(clone_image,&frame_info,compose,exception); clone_image=DestroyImage(clone_image); if (border_image != (Image *) NULL) border_image->matte_color=image->matte_color; return(border_image); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % F r a m e I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % FrameImage() adds a simulated three-dimensional border around the image. % The color of the border is defined by the matte_color member of image. % Members width and height of frame_info specify the border width of the % vertical and horizontal sides of the frame. Members inner and outer % indicate the width of the inner and outer shadows of the frame. % % The format of the FrameImage method is: % % Image *FrameImage(const Image *image,const FrameInfo *frame_info, % const CompositeOperator compose,ExceptionInfo *exception) % % A description of each parameter follows: % % o image: the image. % % o frame_info: Define the width and height of the frame and its bevels. % % o compose: the composite operator. % % o exception: return any errors or warnings in this structure. % */ MagickExport Image *FrameImage(const Image *image,const FrameInfo *frame_info, const CompositeOperator compose,ExceptionInfo *exception) { #define FrameImageTag "Frame/Image" CacheView *image_view, *frame_view; Image *frame_image; MagickBooleanType status; MagickOffsetType progress; PixelInfo accentuate, highlight, matte, shadow, trough; ssize_t x; size_t bevel_width, height, width; ssize_t y; /* Check frame geometry. */ assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(frame_info != (FrameInfo *) NULL); if ((frame_info->outer_bevel < 0) || (frame_info->inner_bevel < 0)) ThrowImageException(OptionError,"FrameIsLessThanImageSize"); bevel_width=(size_t) (frame_info->outer_bevel+frame_info->inner_bevel); x=(ssize_t) frame_info->width-frame_info->x-bevel_width; y=(ssize_t) frame_info->height-frame_info->y-bevel_width; if ((x < (ssize_t) image->columns) || (y < (ssize_t) image->rows)) ThrowImageException(OptionError,"FrameIsLessThanImageSize"); /* Initialize framed image attributes. */ frame_image=CloneImage(image,frame_info->width,frame_info->height,MagickTrue, exception); if (frame_image == (Image *) NULL) return((Image *) NULL); if (SetImageStorageClass(frame_image,DirectClass,exception) == MagickFalse) { frame_image=DestroyImage(frame_image); return((Image *) NULL); } if ((IsPixelInfoGray(&frame_image->border_color) == MagickFalse) && (IsGrayColorspace(frame_image->colorspace) != MagickFalse)) (void) SetImageColorspace(frame_image,sRGBColorspace,exception); if ((frame_image->matte_color.alpha_trait != UndefinedPixelTrait) && (frame_image->alpha_trait == UndefinedPixelTrait)) (void) SetImageAlpha(frame_image,OpaqueAlpha,exception); frame_image->page=image->page; if ((image->page.width != 0) && (image->page.height != 0)) { frame_image->page.width+=frame_image->columns-image->columns; frame_image->page.height+=frame_image->rows-image->rows; } /* Initialize 3D effects color. */ matte=image->matte_color; accentuate=matte; accentuate.red=(double) (QuantumScale*((QuantumRange- AccentuateModulate)*matte.red+(QuantumRange*AccentuateModulate))); accentuate.green=(double) (QuantumScale*((QuantumRange- AccentuateModulate)*matte.green+(QuantumRange*AccentuateModulate))); accentuate.blue=(double) (QuantumScale*((QuantumRange- AccentuateModulate)*matte.blue+(QuantumRange*AccentuateModulate))); accentuate.black=(double) (QuantumScale*((QuantumRange- AccentuateModulate)*matte.black+(QuantumRange*AccentuateModulate))); accentuate.alpha=matte.alpha; highlight=matte; highlight.red=(double) (QuantumScale*((QuantumRange- HighlightModulate)*matte.red+(QuantumRange*HighlightModulate))); highlight.green=(double) (QuantumScale*((QuantumRange- HighlightModulate)*matte.green+(QuantumRange*HighlightModulate))); highlight.blue=(double) (QuantumScale*((QuantumRange- HighlightModulate)*matte.blue+(QuantumRange*HighlightModulate))); highlight.black=(double) (QuantumScale*((QuantumRange- HighlightModulate)*matte.black+(QuantumRange*HighlightModulate))); highlight.alpha=matte.alpha; shadow=matte; shadow.red=QuantumScale*matte.red*ShadowModulate; shadow.green=QuantumScale*matte.green*ShadowModulate; shadow.blue=QuantumScale*matte.blue*ShadowModulate; shadow.black=QuantumScale*matte.black*ShadowModulate; shadow.alpha=matte.alpha; trough=matte; trough.red=QuantumScale*matte.red*TroughModulate; trough.green=QuantumScale*matte.green*TroughModulate; trough.blue=QuantumScale*matte.blue*TroughModulate; trough.black=QuantumScale*matte.black*TroughModulate; trough.alpha=matte.alpha; status=MagickTrue; progress=0; image_view=AcquireVirtualCacheView(image,exception); frame_view=AcquireAuthenticCacheView(frame_image,exception); height=(size_t) (frame_info->outer_bevel+(frame_info->y-bevel_width)+ frame_info->inner_bevel); if (height != 0) { ssize_t x; Quantum *magick_restrict q; /* Draw top of ornamental border. */ q=QueueCacheViewAuthenticPixels(frame_view,0,0,frame_image->columns, height,exception); if (q != (Quantum *) NULL) { /* Draw top of ornamental border. */ for (y=0; y < (ssize_t) frame_info->outer_bevel; y++) { for (x=0; x < (ssize_t) (frame_image->columns-y); x++) { if (x < y) SetPixelViaPixelInfo(frame_image,&highlight,q); else SetPixelViaPixelInfo(frame_image,&accentuate,q); q+=GetPixelChannels(frame_image); } for ( ; x < (ssize_t) frame_image->columns; x++) { SetPixelViaPixelInfo(frame_image,&shadow,q); q+=GetPixelChannels(frame_image); } } for (y=0; y < (ssize_t) (frame_info->y-bevel_width); y++) { for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) { SetPixelViaPixelInfo(frame_image,&highlight,q); q+=GetPixelChannels(frame_image); } width=frame_image->columns-2*frame_info->outer_bevel; for (x=0; x < (ssize_t) width; x++) { SetPixelViaPixelInfo(frame_image,&matte,q); q+=GetPixelChannels(frame_image); } for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) { SetPixelViaPixelInfo(frame_image,&shadow,q); q+=GetPixelChannels(frame_image); } } for (y=0; y < (ssize_t) frame_info->inner_bevel; y++) { for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) { SetPixelViaPixelInfo(frame_image,&highlight,q); q+=GetPixelChannels(frame_image); } for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++) { SetPixelViaPixelInfo(frame_image,&matte,q); q+=GetPixelChannels(frame_image); } width=image->columns+((size_t) frame_info->inner_bevel << 1)- y; for (x=0; x < (ssize_t) width; x++) { if (x < y) SetPixelViaPixelInfo(frame_image,&shadow,q); else SetPixelViaPixelInfo(frame_image,&trough,q); q+=GetPixelChannels(frame_image); } for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++) { SetPixelViaPixelInfo(frame_image,&highlight,q); q+=GetPixelChannels(frame_image); } width=frame_info->width-frame_info->x-image->columns-bevel_width; for (x=0; x < (ssize_t) width; x++) { SetPixelViaPixelInfo(frame_image,&matte,q); q+=GetPixelChannels(frame_image); } for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) { SetPixelViaPixelInfo(frame_image,&shadow,q); q+=GetPixelChannels(frame_image); } } (void) SyncCacheViewAuthenticPixels(frame_view,exception); } } /* Draw sides of ornamental border. */ #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) shared(progress,status) \ magick_number_threads(image,frame_image,image->rows,1) #endif for (y=0; y < (ssize_t) image->rows; y++) { ssize_t x; Quantum *magick_restrict q; size_t width; /* Initialize scanline with matte color. */ if (status == MagickFalse) continue; q=QueueCacheViewAuthenticPixels(frame_view,0,frame_info->y+y, frame_image->columns,1,exception); if (q == (Quantum *) NULL) { status=MagickFalse; continue; } for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) { SetPixelViaPixelInfo(frame_image,&highlight,q); q+=GetPixelChannels(frame_image); } for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++) { SetPixelViaPixelInfo(frame_image,&matte,q); q+=GetPixelChannels(frame_image); } for (x=0; x < (ssize_t) frame_info->inner_bevel; x++) { SetPixelViaPixelInfo(frame_image,&shadow,q); q+=GetPixelChannels(frame_image); } /* Set frame interior pixels. */ for (x=0; x < (ssize_t) image->columns; x++) { SetPixelViaPixelInfo(frame_image,&frame_image->border_color,q); q+=GetPixelChannels(frame_image); } for (x=0; x < (ssize_t) frame_info->inner_bevel; x++) { SetPixelViaPixelInfo(frame_image,&highlight,q); q+=GetPixelChannels(frame_image); } width=frame_info->width-frame_info->x-image->columns-bevel_width; for (x=0; x < (ssize_t) width; x++) { SetPixelViaPixelInfo(frame_image,&matte,q); q+=GetPixelChannels(frame_image); } for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) { SetPixelViaPixelInfo(frame_image,&shadow,q); q+=GetPixelChannels(frame_image); } if (SyncCacheViewAuthenticPixels(frame_view,exception) == MagickFalse) status=MagickFalse; if (image->progress_monitor != (MagickProgressMonitor) NULL) { MagickBooleanType proceed; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp atomic #endif progress++; proceed=SetImageProgress(image,FrameImageTag,progress,image->rows); if (proceed == MagickFalse) status=MagickFalse; } } height=(size_t) (frame_info->inner_bevel+frame_info->height- frame_info->y-image->rows-bevel_width+frame_info->outer_bevel); if (height != 0) { ssize_t x; Quantum *magick_restrict q; /* Draw bottom of ornamental border. */ q=QueueCacheViewAuthenticPixels(frame_view,0,(ssize_t) (frame_image->rows- height),frame_image->columns,height,exception); if (q != (Quantum *) NULL) { /* Draw bottom of ornamental border. */ for (y=frame_info->inner_bevel-1; y >= 0; y--) { for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) { SetPixelViaPixelInfo(frame_image,&highlight,q); q+=GetPixelChannels(frame_image); } for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++) { SetPixelViaPixelInfo(frame_image,&matte,q); q+=GetPixelChannels(frame_image); } for (x=0; x < y; x++) { SetPixelViaPixelInfo(frame_image,&shadow,q); q+=GetPixelChannels(frame_image); } for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++) { if (x >= (ssize_t) (image->columns+2*frame_info->inner_bevel-y)) SetPixelViaPixelInfo(frame_image,&highlight,q); else SetPixelViaPixelInfo(frame_image,&accentuate,q); q+=GetPixelChannels(frame_image); } width=frame_info->width-frame_info->x-image->columns-bevel_width; for (x=0; x < (ssize_t) width; x++) { SetPixelViaPixelInfo(frame_image,&matte,q); q+=GetPixelChannels(frame_image); } for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) { SetPixelViaPixelInfo(frame_image,&shadow,q); q+=GetPixelChannels(frame_image); } } height=frame_info->height-frame_info->y-image->rows-bevel_width; for (y=0; y < (ssize_t) height; y++) { for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) { SetPixelViaPixelInfo(frame_image,&highlight,q); q+=GetPixelChannels(frame_image); } width=frame_image->columns-2*frame_info->outer_bevel; for (x=0; x < (ssize_t) width; x++) { SetPixelViaPixelInfo(frame_image,&matte,q); q+=GetPixelChannels(frame_image); } for (x=0; x < (ssize_t) frame_info->outer_bevel; x++) { SetPixelViaPixelInfo(frame_image,&shadow,q); q+=GetPixelChannels(frame_image); } } for (y=frame_info->outer_bevel-1; y >= 0; y--) { for (x=0; x < y; x++) { SetPixelViaPixelInfo(frame_image,&highlight,q); q+=GetPixelChannels(frame_image); } for ( ; x < (ssize_t) frame_image->columns; x++) { if (x >= (ssize_t) (frame_image->columns-y)) SetPixelViaPixelInfo(frame_image,&shadow,q); else SetPixelViaPixelInfo(frame_image,&trough,q); q+=GetPixelChannels(frame_image); } } (void) SyncCacheViewAuthenticPixels(frame_view,exception); } } frame_view=DestroyCacheView(frame_view); image_view=DestroyCacheView(image_view); x=(ssize_t) (frame_info->outer_bevel+(frame_info->x-bevel_width)+ frame_info->inner_bevel); y=(ssize_t) (frame_info->outer_bevel+(frame_info->y-bevel_width)+ frame_info->inner_bevel); if (status != MagickFalse) status=CompositeImage(frame_image,image,compose,MagickTrue,x,y, exception); if (status == MagickFalse) frame_image=DestroyImage(frame_image); return(frame_image); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % R a i s e I m a g e % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % RaiseImage() creates a simulated three-dimensional button-like effect % by lightening and darkening the edges of the image. Members width and % height of raise_info define the width of the vertical and horizontal % edge of the effect. % % The format of the RaiseImage method is: % % MagickBooleanType RaiseImage(const Image *image, % const RectangleInfo *raise_info,const MagickBooleanType raise, % ExceptionInfo *exception) % % A description of each parameter follows: % % o image: the image. % % o raise_info: Define the width and height of the raise area. % % o raise: A value other than zero creates a 3-D raise effect, % otherwise it has a lowered effect. % % o exception: return any errors or warnings in this structure. % */ MagickExport MagickBooleanType RaiseImage(Image *image, const RectangleInfo *raise_info,const MagickBooleanType raise, ExceptionInfo *exception) { #define AccentuateFactor ScaleCharToQuantum(135) #define HighlightFactor ScaleCharToQuantum(190) #define ShadowFactor ScaleCharToQuantum(190) #define RaiseImageTag "Raise/Image" #define TroughFactor ScaleCharToQuantum(135) CacheView *image_view; MagickBooleanType status; MagickOffsetType progress; Quantum foreground, background; ssize_t y; assert(image != (Image *) NULL); assert(image->signature == MagickCoreSignature); if (image->debug != MagickFalse) (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); assert(raise_info != (RectangleInfo *) NULL); if ((image->columns <= (raise_info->width << 1)) || (image->rows <= (raise_info->height << 1))) ThrowBinaryException(OptionError,"ImageSizeMustExceedBevelWidth", image->filename); foreground=QuantumRange; background=(Quantum) 0; if (raise == MagickFalse) { foreground=(Quantum) 0; background=QuantumRange; } if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) return(MagickFalse); /* Raise image. */ status=MagickTrue; progress=0; image_view=AcquireAuthenticCacheView(image,exception); #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) shared(progress,status) \ magick_number_threads(image,image,raise_info->height,1) #endif for (y=0; y < (ssize_t) raise_info->height; y++) { ssize_t i, x; Quantum *magick_restrict q; 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 < y; x++) { for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); if ((traits & UpdatePixelTrait) == 0) continue; q[i]=ClampToQuantum(QuantumScale*((double) q[i]*HighlightFactor+(double) foreground*(QuantumRange-HighlightFactor))); } q+=GetPixelChannels(image); } for ( ; x < (ssize_t) (image->columns-y); x++) { for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); if ((traits & UpdatePixelTrait) == 0) continue; q[i]=ClampToQuantum(QuantumScale*((double) q[i]*AccentuateFactor+ (double) foreground*(QuantumRange-AccentuateFactor))); } q+=GetPixelChannels(image); } for ( ; x < (ssize_t) image->columns; x++) { for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); if ((traits & UpdatePixelTrait) == 0) continue; q[i]=ClampToQuantum(QuantumScale*((double) q[i]*ShadowFactor+(double) background*(QuantumRange-ShadowFactor))); } q+=GetPixelChannels(image); } if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) status=MagickFalse; if (image->progress_monitor != (MagickProgressMonitor) NULL) { MagickBooleanType proceed; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp atomic #endif progress++; proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows); if (proceed == MagickFalse) status=MagickFalse; } } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) shared(progress,status) \ magick_number_threads(image,image,image->rows-2*raise_info->height,1) #endif for (y=(ssize_t) raise_info->height; y < (ssize_t) (image->rows-raise_info->height); y++) { ssize_t i, x; Quantum *magick_restrict q; 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) raise_info->width; x++) { for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); if ((traits & UpdatePixelTrait) == 0) continue; q[i]=ClampToQuantum(QuantumScale*((double) q[i]*HighlightFactor+(double) foreground*(QuantumRange-HighlightFactor))); } q+=GetPixelChannels(image); } for ( ; x < (ssize_t) (image->columns-raise_info->width); x++) q+=GetPixelChannels(image); for ( ; x < (ssize_t) image->columns; x++) { for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); if ((traits & UpdatePixelTrait) == 0) continue; q[i]=ClampToQuantum(QuantumScale*((double) q[i]*ShadowFactor+(double) background*(QuantumRange-ShadowFactor))); } q+=GetPixelChannels(image); } if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) status=MagickFalse; if (image->progress_monitor != (MagickProgressMonitor) NULL) { MagickBooleanType proceed; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp atomic #endif progress++; proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows); if (proceed == MagickFalse) status=MagickFalse; } } #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp parallel for schedule(static) shared(progress,status) \ magick_number_threads(image,image,image->rows-raise_info->height,1) #endif for (y=(ssize_t) (image->rows-raise_info->height); y < (ssize_t) image->rows; y++) { ssize_t i, x; Quantum *magick_restrict q; 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->rows-y); x++) { for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); if ((traits & UpdatePixelTrait) == 0) continue; q[i]=ClampToQuantum(QuantumScale*((double) q[i]*HighlightFactor+(double) foreground*(QuantumRange-HighlightFactor))); } q+=GetPixelChannels(image); } for ( ; x < (ssize_t) (image->columns-(image->rows-y)); x++) { for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); if ((traits & UpdatePixelTrait) == 0) continue; q[i]=ClampToQuantum(QuantumScale*((double) q[i]*TroughFactor+ (double) background*(QuantumRange-TroughFactor))); } q+=GetPixelChannels(image); } for ( ; x < (ssize_t) image->columns; x++) { for (i=0; i < (ssize_t) GetPixelChannels(image); i++) { PixelChannel channel = GetPixelChannelChannel(image,i); PixelTrait traits = GetPixelChannelTraits(image,channel); if ((traits & UpdatePixelTrait) == 0) continue; q[i]=ClampToQuantum(QuantumScale*((double) q[i]*ShadowFactor+(double) background*(QuantumRange-ShadowFactor))); } q+=GetPixelChannels(image); } if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse) status=MagickFalse; if (image->progress_monitor != (MagickProgressMonitor) NULL) { MagickBooleanType proceed; #if defined(MAGICKCORE_OPENMP_SUPPORT) #pragma omp atomic #endif progress++; proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows); if (proceed == MagickFalse) status=MagickFalse; } } image_view=DestroyCacheView(image_view); return(status); }