MagickCore  6.7.5
decorate.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %            DDDD   EEEEE   CCCC   OOO   RRRR    AAA   TTTTT  EEEEE           %
00007 %            D   D  E      C      O   O  R   R  A   A    T    E               %
00008 %            D   D  EEE    C      O   O  RRRR   AAAAA    T    EEE             %
00009 %            D   D  E      C      O   O  R R    A   A    T    E               %
00010 %            DDDD   EEEEE   CCCC   OOO   R  R   A   A    T    EEEEE           %
00011 %                                                                             %
00012 %                                                                             %
00013 %                     MagickCore Image Decoration Methods                     %
00014 %                                                                             %
00015 %                                Software Design                              %
00016 %                                  John Cristy                                %
00017 %                                   July 1992                                 %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 %
00038 */
00039 
00040 /*
00041   Include declarations.
00042 */
00043 #include "MagickCore/studio.h"
00044 #include "MagickCore/cache-view.h"
00045 #include "MagickCore/color-private.h"
00046 #include "MagickCore/colorspace-private.h"
00047 #include "MagickCore/composite.h"
00048 #include "MagickCore/decorate.h"
00049 #include "MagickCore/exception.h"
00050 #include "MagickCore/exception-private.h"
00051 #include "MagickCore/image.h"
00052 #include "MagickCore/memory_.h"
00053 #include "MagickCore/monitor.h"
00054 #include "MagickCore/monitor-private.h"
00055 #include "MagickCore/pixel-accessor.h"
00056 #include "MagickCore/quantum.h"
00057 #include "MagickCore/quantum-private.h"
00058 #include "MagickCore/thread-private.h"
00059 #include "MagickCore/transform.h"
00060 
00061 /*
00062   Define declarations.
00063 */
00064 #define AccentuateModulate  ScaleCharToQuantum(80)
00065 #define HighlightModulate  ScaleCharToQuantum(125)
00066 #define ShadowModulate  ScaleCharToQuantum(135)
00067 #define DepthModulate  ScaleCharToQuantum(185)
00068 #define TroughModulate  ScaleCharToQuantum(110)
00069 
00070 /*
00071 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00072 %                                                                             %
00073 %                                                                             %
00074 %                                                                             %
00075 %   B o r d e r I m a g e                                                     %
00076 %                                                                             %
00077 %                                                                             %
00078 %                                                                             %
00079 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00080 %
00081 %  BorderImage() surrounds the image with a border of the color defined by
00082 %  the bordercolor member of the image structure.  The width and height
00083 %  of the border are defined by the corresponding members of the border_info
00084 %  structure.
00085 %
00086 %  The format of the BorderImage method is:
00087 %
00088 %      Image *BorderImage(const Image *image,const RectangleInfo *border_info,
00089 %        const CompositeOperator compose,ExceptionInfo *exception)
00090 %
00091 %  A description of each parameter follows:
00092 %
00093 %    o image: the image.
00094 %
00095 %    o border_info:  define the width and height of the border.
00096 %
00097 %    o compose:  the composite operator.
00098 %
00099 %    o exception: return any errors or warnings in this structure.
00100 %
00101 */
00102 MagickExport Image *BorderImage(const Image *image,
00103   const RectangleInfo *border_info,const CompositeOperator compose,
00104   ExceptionInfo *exception)
00105 {
00106   Image
00107     *border_image,
00108     *clone_image;
00109 
00110   FrameInfo
00111     frame_info;
00112 
00113   assert(image != (const Image *) NULL);
00114   assert(image->signature == MagickSignature);
00115   if (image->debug != MagickFalse)
00116     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00117   assert(border_info != (RectangleInfo *) NULL);
00118   frame_info.width=image->columns+(border_info->width << 1);
00119   frame_info.height=image->rows+(border_info->height << 1);
00120   frame_info.x=(ssize_t) border_info->width;
00121   frame_info.y=(ssize_t) border_info->height;
00122   frame_info.inner_bevel=0;
00123   frame_info.outer_bevel=0;
00124   clone_image=CloneImage(image,0,0,MagickTrue,exception);
00125   if (clone_image == (Image *) NULL)
00126     return((Image *) NULL);
00127   clone_image->matte_color=image->border_color;
00128   border_image=FrameImage(clone_image,&frame_info,compose,exception);
00129   clone_image=DestroyImage(clone_image);
00130   if (border_image != (Image *) NULL)
00131     border_image->matte_color=image->matte_color;
00132   return(border_image);
00133 }
00134 
00135 /*
00136 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00137 %                                                                             %
00138 %                                                                             %
00139 %                                                                             %
00140 %   F r a m e I m a g e                                                       %
00141 %                                                                             %
00142 %                                                                             %
00143 %                                                                             %
00144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00145 %
00146 %  FrameImage() adds a simulated three-dimensional border around the image.
00147 %  The color of the border is defined by the matte_color member of image.
00148 %  Members width and height of frame_info specify the border width of the
00149 %  vertical and horizontal sides of the frame.  Members inner and outer
00150 %  indicate the width of the inner and outer shadows of the frame.
00151 %
00152 %  The format of the FrameImage method is:
00153 %
00154 %      Image *FrameImage(const Image *image,const FrameInfo *frame_info,
00155 %        const CompositeOperator compose,ExceptionInfo *exception)
00156 %
00157 %  A description of each parameter follows:
00158 %
00159 %    o image: the image.
00160 %
00161 %    o frame_info: Define the width and height of the frame and its bevels.
00162 %
00163 %    o compose: the composite operator.
00164 %
00165 %    o exception: return any errors or warnings in this structure.
00166 %
00167 */
00168 MagickExport Image *FrameImage(const Image *image,const FrameInfo *frame_info,
00169   const CompositeOperator compose,ExceptionInfo *exception)
00170 {
00171 #define FrameImageTag  "Frame/Image"
00172 
00173   CacheView
00174     *image_view,
00175     *frame_view;
00176 
00177   Image
00178     *frame_image;
00179 
00180   MagickBooleanType
00181     status;
00182 
00183   MagickOffsetType
00184     progress;
00185 
00186   PixelInfo
00187     accentuate,
00188     highlight,
00189     interior,
00190     matte,
00191     shadow,
00192     trough;
00193 
00194   register ssize_t
00195     x;
00196 
00197   size_t
00198     bevel_width,
00199     height,
00200     width;
00201 
00202   ssize_t
00203     y;
00204 
00205   /*
00206     Check frame geometry.
00207   */
00208   assert(image != (Image *) NULL);
00209   assert(image->signature == MagickSignature);
00210   if (image->debug != MagickFalse)
00211     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00212   assert(frame_info != (FrameInfo *) NULL);
00213   if ((frame_info->outer_bevel < 0) || (frame_info->inner_bevel < 0))
00214     ThrowImageException(OptionError,"FrameIsLessThanImageSize");
00215   bevel_width=(size_t) (frame_info->outer_bevel+frame_info->inner_bevel);
00216   width=frame_info->width-frame_info->x-bevel_width;
00217   height=frame_info->height-frame_info->y-bevel_width;
00218   if ((width < image->columns) || (height < image->rows))
00219     ThrowImageException(OptionError,"FrameIsLessThanImageSize");
00220   /*
00221     Initialize framed image attributes.
00222   */
00223   frame_image=CloneImage(image,frame_info->width,frame_info->height,MagickTrue,
00224     exception);
00225   if (frame_image == (Image *) NULL)
00226     return((Image *) NULL);
00227   if (SetImageStorageClass(frame_image,DirectClass,exception) == MagickFalse)
00228     {
00229       frame_image=DestroyImage(frame_image);
00230       return((Image *) NULL);
00231     }
00232   if ((frame_image->border_color.matte != MagickFalse) &&
00233       (frame_image->matte == MagickFalse))
00234     (void) SetImageAlpha(frame_image,OpaqueAlpha,exception);
00235   frame_image->page=image->page;
00236   if ((image->page.width != 0) && (image->page.height != 0))
00237     {
00238       frame_image->page.width+=frame_image->columns-image->columns;
00239       frame_image->page.height+=frame_image->rows-image->rows;
00240     }
00241   /*
00242     Initialize 3D effects color.
00243   */
00244   interior=image->border_color;
00245   matte=image->matte_color;
00246   accentuate=matte;
00247   accentuate.red=(MagickRealType) (QuantumScale*((QuantumRange-
00248     AccentuateModulate)*matte.red+(QuantumRange*AccentuateModulate)));
00249   accentuate.green=(MagickRealType) (QuantumScale*((QuantumRange-
00250     AccentuateModulate)*matte.green+(QuantumRange*AccentuateModulate)));
00251   accentuate.blue=(MagickRealType) (QuantumScale*((QuantumRange-
00252     AccentuateModulate)*matte.blue+(QuantumRange*AccentuateModulate)));
00253   accentuate.black=(MagickRealType) (QuantumScale*((QuantumRange-
00254     AccentuateModulate)*matte.black+(QuantumRange*AccentuateModulate)));
00255   accentuate.alpha=matte.alpha;
00256   highlight=matte;
00257   highlight.red=(MagickRealType) (QuantumScale*((QuantumRange-
00258     HighlightModulate)*matte.red+(QuantumRange*HighlightModulate)));
00259   highlight.green=(MagickRealType) (QuantumScale*((QuantumRange-
00260     HighlightModulate)*matte.green+(QuantumRange*HighlightModulate)));
00261   highlight.blue=(MagickRealType) (QuantumScale*((QuantumRange-
00262     HighlightModulate)*matte.blue+(QuantumRange*HighlightModulate)));
00263   highlight.black=(MagickRealType) (QuantumScale*((QuantumRange-
00264     HighlightModulate)*matte.black+(QuantumRange*HighlightModulate)));
00265   highlight.alpha=matte.alpha;
00266   shadow=matte;
00267   shadow.red=QuantumScale*matte.red*ShadowModulate;
00268   shadow.green=QuantumScale*matte.green*ShadowModulate;
00269   shadow.blue=QuantumScale*matte.blue*ShadowModulate;
00270   shadow.black=QuantumScale*matte.black*ShadowModulate;
00271   shadow.alpha=matte.alpha;
00272   trough=matte;
00273   trough.red=QuantumScale*matte.red*TroughModulate;
00274   trough.green=QuantumScale*matte.green*TroughModulate;
00275   trough.blue=QuantumScale*matte.blue*TroughModulate;
00276   trough.black=QuantumScale*matte.black*TroughModulate;
00277   trough.alpha=matte.alpha;
00278   status=MagickTrue;
00279   progress=0;
00280   image_view=AcquireCacheView(image);
00281   frame_view=AcquireCacheView(frame_image);
00282   height=(size_t) (frame_info->outer_bevel+(frame_info->y-bevel_width)+
00283     frame_info->inner_bevel);
00284   if (height != 0)
00285     {
00286       register ssize_t
00287         x;
00288 
00289       register Quantum
00290         *restrict q;
00291 
00292       /*
00293         Draw top of ornamental border.
00294       */
00295       q=QueueCacheViewAuthenticPixels(frame_view,0,0,frame_image->columns,
00296         height,exception);
00297       if (q != (Quantum *) NULL)
00298         {
00299           /*
00300             Draw top of ornamental border.
00301           */
00302           for (y=0; y < (ssize_t) frame_info->outer_bevel; y++)
00303           {
00304             for (x=0; x < (ssize_t) (frame_image->columns-y); x++)
00305             {
00306               if (x < y)
00307                 SetPixelInfoPixel(frame_image,&highlight,q);
00308               else
00309                 SetPixelInfoPixel(frame_image,&accentuate,q);
00310               q+=GetPixelChannels(frame_image);
00311             }
00312             for ( ; x < (ssize_t) frame_image->columns; x++)
00313             {
00314               SetPixelInfoPixel(frame_image,&shadow,q);
00315               q+=GetPixelChannels(frame_image);
00316             }
00317           }
00318           for (y=0; y < (ssize_t) (frame_info->y-bevel_width); y++)
00319           {
00320             for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
00321             {
00322               SetPixelInfoPixel(frame_image,&highlight,q);
00323               q+=GetPixelChannels(frame_image);
00324             }
00325             width=frame_image->columns-2*frame_info->outer_bevel;
00326             for (x=0; x < (ssize_t) width; x++)
00327             {
00328               SetPixelInfoPixel(frame_image,&matte,q);
00329               q+=GetPixelChannels(frame_image);
00330             }
00331             for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
00332             {
00333               SetPixelInfoPixel(frame_image,&shadow,q);
00334               q+=GetPixelChannels(frame_image);
00335             }
00336           }
00337           for (y=0; y < (ssize_t) frame_info->inner_bevel; y++)
00338           {
00339             for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
00340             {
00341               SetPixelInfoPixel(frame_image,&highlight,q);
00342               q+=GetPixelChannels(frame_image);
00343             }
00344             for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
00345             {
00346               SetPixelInfoPixel(frame_image,&matte,q);
00347               q+=GetPixelChannels(frame_image);
00348             }
00349             width=image->columns+((size_t) frame_info->inner_bevel << 1)-
00350               y;
00351             for (x=0; x < (ssize_t) width; x++)
00352             {
00353               if (x < y)
00354                 SetPixelInfoPixel(frame_image,&shadow,q);
00355               else
00356                 SetPixelInfoPixel(frame_image,&trough,q);
00357               q+=GetPixelChannels(frame_image);
00358             }
00359             for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++)
00360             {
00361               SetPixelInfoPixel(frame_image,&highlight,q);
00362               q+=GetPixelChannels(frame_image);
00363             }
00364             width=frame_info->width-frame_info->x-image->columns-bevel_width;
00365             for (x=0; x < (ssize_t) width; x++)
00366             {
00367               SetPixelInfoPixel(frame_image,&matte,q);
00368               q+=GetPixelChannels(frame_image);
00369             }
00370             for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
00371             {
00372               SetPixelInfoPixel(frame_image,&shadow,q);
00373               q+=GetPixelChannels(frame_image);
00374             }
00375           }
00376           (void) SyncCacheViewAuthenticPixels(frame_view,exception);
00377         }
00378     }
00379   /*
00380     Draw sides of ornamental border.
00381   */
00382 #if defined(MAGICKCORE_OPENMP_SUPPORT) 
00383   #pragma omp parallel for schedule(static) shared(progress,status)
00384 #endif
00385   for (y=0; y < (ssize_t) image->rows; y++)
00386   {
00387     register ssize_t
00388       x;
00389 
00390     register Quantum
00391       *restrict q;
00392 
00393     size_t
00394       width;
00395 
00396     /*
00397       Initialize scanline with matte color.
00398     */
00399     if (status == MagickFalse)
00400       continue;
00401     q=QueueCacheViewAuthenticPixels(frame_view,0,frame_info->y+y,
00402       frame_image->columns,1,exception);
00403     if (q == (Quantum *) NULL)
00404       {
00405         status=MagickFalse;
00406         continue;
00407       }
00408     for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
00409     {
00410       SetPixelInfoPixel(frame_image,&highlight,q);
00411       q+=GetPixelChannels(frame_image);
00412     }
00413     for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
00414     {
00415       SetPixelInfoPixel(frame_image,&matte,q);
00416       q+=GetPixelChannels(frame_image);
00417     }
00418     for (x=0; x < (ssize_t) frame_info->inner_bevel; x++)
00419     {
00420       SetPixelInfoPixel(frame_image,&shadow,q);
00421       q+=GetPixelChannels(frame_image);
00422     }
00423     /*
00424       Set frame interior to interior color.
00425     */
00426     if ((compose != CopyCompositeOp) && ((compose != OverCompositeOp) ||
00427         (image->matte != MagickFalse)))
00428       for (x=0; x < (ssize_t) image->columns; x++)
00429       {
00430         SetPixelInfoPixel(frame_image,&interior,q);
00431         q+=GetPixelChannels(frame_image);
00432       }
00433     else
00434       {
00435         register const Quantum
00436           *p;
00437 
00438         p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
00439         if (p == (const Quantum *) NULL)
00440           {
00441             status=MagickFalse;
00442             continue;
00443           }
00444         for (x=0; x < (ssize_t) image->columns; x++)
00445         {
00446           if ((GetPixelRedTraits(image) & UpdatePixelTrait) != 0)
00447             SetPixelRed(frame_image,GetPixelRed(image,p),q);
00448           if ((GetPixelGreenTraits(image) & UpdatePixelTrait) != 0)
00449             SetPixelGreen(frame_image,GetPixelGreen(image,p),q);
00450           if ((GetPixelBlueTraits(image) & UpdatePixelTrait) != 0)
00451             SetPixelBlue(frame_image,GetPixelBlue(image,p),q);
00452           if ((GetPixelBlackTraits(image) & UpdatePixelTrait) != 0)
00453             SetPixelBlack(frame_image,GetPixelBlack(image,p),q);
00454           if ((GetPixelAlphaTraits(image) & UpdatePixelTrait) != 0)
00455             SetPixelAlpha(frame_image,GetPixelAlpha(image,p),q);
00456           p+=GetPixelChannels(image);
00457           q+=GetPixelChannels(frame_image);
00458         }
00459       }
00460     for (x=0; x < (ssize_t) frame_info->inner_bevel; x++)
00461     {
00462       SetPixelInfoPixel(frame_image,&highlight,q);
00463       q+=GetPixelChannels(frame_image);
00464     }
00465     width=frame_info->width-frame_info->x-image->columns-bevel_width;
00466     for (x=0; x < (ssize_t) width; x++)
00467     {
00468       SetPixelInfoPixel(frame_image,&matte,q);
00469       q+=GetPixelChannels(frame_image);
00470     }
00471     for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
00472     {
00473       SetPixelInfoPixel(frame_image,&shadow,q);
00474       q+=GetPixelChannels(frame_image);
00475     }
00476     if (SyncCacheViewAuthenticPixels(frame_view,exception) == MagickFalse)
00477       status=MagickFalse;
00478     if (image->progress_monitor != (MagickProgressMonitor) NULL)
00479       {
00480         MagickBooleanType
00481           proceed;
00482 
00483 #if defined(MAGICKCORE_OPENMP_SUPPORT) 
00484         #pragma omp critical (MagickCore_FrameImage)
00485 #endif
00486         proceed=SetImageProgress(image,FrameImageTag,progress++,image->rows);
00487         if (proceed == MagickFalse)
00488           status=MagickFalse;
00489       }
00490   }
00491   height=(size_t) (frame_info->inner_bevel+frame_info->height-
00492     frame_info->y-image->rows-bevel_width+frame_info->outer_bevel);
00493   if (height != 0)
00494     {
00495       register ssize_t
00496         x;
00497 
00498       register Quantum
00499         *restrict q;
00500 
00501       /*
00502         Draw bottom of ornamental border.
00503       */
00504       q=QueueCacheViewAuthenticPixels(frame_view,0,(ssize_t) (frame_image->rows-
00505         height),frame_image->columns,height,exception);
00506       if (q != (Quantum *) NULL)
00507         {
00508           /*
00509             Draw bottom of ornamental border.
00510           */
00511           for (y=frame_info->inner_bevel-1; y >= 0; y--)
00512           {
00513             for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
00514             {
00515               SetPixelInfoPixel(frame_image,&highlight,q);
00516               q+=GetPixelChannels(frame_image);
00517             }
00518             for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
00519             {
00520               SetPixelInfoPixel(frame_image,&matte,q);
00521               q+=GetPixelChannels(frame_image);
00522             }
00523             for (x=0; x < y; x++)
00524             {
00525               SetPixelInfoPixel(frame_image,&shadow,q);
00526               q+=GetPixelChannels(frame_image);
00527             }
00528             for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++)
00529             {
00530               if (x >= (ssize_t) (image->columns+2*frame_info->inner_bevel-y))
00531                 SetPixelInfoPixel(frame_image,&highlight,q);
00532               else
00533                 SetPixelInfoPixel(frame_image,&accentuate,q);
00534               q+=GetPixelChannels(frame_image);
00535             }
00536             width=frame_info->width-frame_info->x-image->columns-bevel_width;
00537             for (x=0; x < (ssize_t) width; x++)
00538             {
00539               SetPixelInfoPixel(frame_image,&matte,q);
00540               q+=GetPixelChannels(frame_image);
00541             }
00542             for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
00543             {
00544               SetPixelInfoPixel(frame_image,&shadow,q);
00545               q+=GetPixelChannels(frame_image);
00546             }
00547           }
00548           height=frame_info->height-frame_info->y-image->rows-bevel_width;
00549           for (y=0; y < (ssize_t) height; y++)
00550           {
00551             for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
00552             {
00553               SetPixelInfoPixel(frame_image,&highlight,q);
00554               q+=GetPixelChannels(frame_image);
00555             }
00556             width=frame_image->columns-2*frame_info->outer_bevel;
00557             for (x=0; x < (ssize_t) width; x++)
00558             {
00559               SetPixelInfoPixel(frame_image,&matte,q);
00560               q+=GetPixelChannels(frame_image);
00561             }
00562             for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
00563             {
00564               SetPixelInfoPixel(frame_image,&shadow,q);
00565               q+=GetPixelChannels(frame_image);
00566             }
00567           }
00568           for (y=frame_info->outer_bevel-1; y >= 0; y--)
00569           {
00570             for (x=0; x < y; x++)
00571             {
00572               SetPixelInfoPixel(frame_image,&highlight,q);
00573               q+=GetPixelChannels(frame_image);
00574             }
00575             for ( ; x < (ssize_t) frame_image->columns; x++)
00576             {
00577               if (x >= (ssize_t) (frame_image->columns-y))
00578                 SetPixelInfoPixel(frame_image,&shadow,q);
00579               else
00580                 SetPixelInfoPixel(frame_image,&trough,q);
00581               q+=GetPixelChannels(frame_image);
00582             }
00583           }
00584           (void) SyncCacheViewAuthenticPixels(frame_view,exception);
00585         }
00586     }
00587   frame_view=DestroyCacheView(frame_view);
00588   image_view=DestroyCacheView(image_view);
00589   if ((compose != CopyCompositeOp) && ((compose != OverCompositeOp) ||
00590       (image->matte != MagickFalse)))
00591     {
00592       x=(ssize_t) (frame_info->outer_bevel+(frame_info->x-bevel_width)+
00593         frame_info->inner_bevel);
00594       y=(ssize_t) (frame_info->outer_bevel+(frame_info->y-bevel_width)+
00595         frame_info->inner_bevel);
00596       (void) CompositeImage(frame_image,compose,image,x,y,exception);
00597     }
00598   return(frame_image);
00599 }
00600 
00601 /*
00602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00603 %                                                                             %
00604 %                                                                             %
00605 %                                                                             %
00606 %   R a i s e I m a g e                                                       %
00607 %                                                                             %
00608 %                                                                             %
00609 %                                                                             %
00610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00611 %
00612 %  RaiseImage() creates a simulated three-dimensional button-like effect
00613 %  by lightening and darkening the edges of the image.  Members width and
00614 %  height of raise_info define the width of the vertical and horizontal
00615 %  edge of the effect.
00616 %
00617 %  The format of the RaiseImage method is:
00618 %
00619 %      MagickBooleanType RaiseImage(const Image *image,
00620 %        const RectangleInfo *raise_info,const MagickBooleanType raise,
00621 %        ExceptionInfo *exception)
00622 %
00623 %  A description of each parameter follows:
00624 %
00625 %    o image: the image.
00626 %
00627 %    o raise_info: Define the width and height of the raise area.
00628 %
00629 %    o raise: A value other than zero creates a 3-D raise effect,
00630 %      otherwise it has a lowered effect.
00631 %
00632 %    o exception: return any errors or warnings in this structure.
00633 %
00634 */
00635 MagickExport MagickBooleanType RaiseImage(Image *image,
00636   const RectangleInfo *raise_info,const MagickBooleanType raise,
00637   ExceptionInfo *exception)
00638 {
00639 #define AccentuateFactor  ScaleCharToQuantum(135)
00640 #define HighlightFactor  ScaleCharToQuantum(190)
00641 #define ShadowFactor  ScaleCharToQuantum(190)
00642 #define RaiseImageTag  "Raise/Image"
00643 #define TroughFactor  ScaleCharToQuantum(135)
00644 
00645   CacheView
00646     *image_view;
00647 
00648   MagickBooleanType
00649     status;
00650 
00651   MagickOffsetType
00652     progress;
00653 
00654   Quantum
00655     foreground,
00656     background;
00657 
00658   ssize_t
00659     y;
00660 
00661   assert(image != (Image *) NULL);
00662   assert(image->signature == MagickSignature);
00663   if (image->debug != MagickFalse)
00664     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00665   assert(raise_info != (RectangleInfo *) NULL);
00666   if ((image->columns <= (raise_info->width << 1)) ||
00667       (image->rows <= (raise_info->height << 1)))
00668     ThrowBinaryException(OptionError,"ImageSizeMustExceedBevelWidth",
00669       image->filename);
00670   foreground=(Quantum) QuantumRange;
00671   background=(Quantum) 0;
00672   if (raise == MagickFalse)
00673     {
00674       foreground=(Quantum) 0;
00675       background=(Quantum) QuantumRange;
00676     }
00677   if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
00678     return(MagickFalse);
00679   /*
00680     Raise image.
00681   */
00682   status=MagickTrue;
00683   progress=0;
00684   image_view=AcquireCacheView(image);
00685 #if defined(MAGICKCORE_OPENMP_SUPPORT) 
00686   #pragma omp parallel for schedule(static) shared(progress,status)
00687 #endif
00688   for (y=0; y < (ssize_t) raise_info->height; y++)
00689   {
00690     register ssize_t
00691       i,
00692       x;
00693 
00694     register Quantum
00695       *restrict q;
00696 
00697     if (status == MagickFalse)
00698       continue;
00699     q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
00700     if (q == (Quantum *) NULL)
00701       {
00702         status=MagickFalse;
00703         continue;
00704       }
00705     for (x=0; x < y; x++)
00706     {
00707       if (GetPixelMask(image,q) != 0)
00708         {
00709           q+=GetPixelChannels(image);
00710           continue;
00711         }
00712       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
00713       {
00714         PixelChannel
00715           channel;
00716 
00717         PixelTrait
00718           traits;
00719 
00720         channel=GetPixelChannelMapChannel(image,i);
00721         traits=GetPixelChannelMapTraits(image,channel);
00722         if ((traits & UpdatePixelTrait) == 0)
00723           continue;
00724         q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]*HighlightFactor+
00725           (MagickRealType) foreground*(QuantumRange-HighlightFactor)));
00726       }
00727       q+=GetPixelChannels(image);
00728     }
00729     for ( ; x < (ssize_t) (image->columns-y); x++)
00730     {
00731       if (GetPixelMask(image,q) != 0)
00732         {
00733           q+=GetPixelChannels(image);
00734           continue;
00735         }
00736       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
00737       {
00738         PixelChannel
00739           channel;
00740 
00741         PixelTrait
00742           traits;
00743 
00744         channel=GetPixelChannelMapChannel(image,i);
00745         traits=GetPixelChannelMapTraits(image,channel);
00746         if ((traits & UpdatePixelTrait) == 0)
00747           continue;
00748         q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]*
00749           AccentuateFactor+(MagickRealType) foreground*(QuantumRange-
00750           AccentuateFactor)));
00751       }
00752       q+=GetPixelChannels(image);
00753     }
00754     for ( ; x < (ssize_t) image->columns; x++)
00755     {
00756       if (GetPixelMask(image,q) != 0)
00757         {
00758           q+=GetPixelChannels(image);
00759           continue;
00760         }
00761       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
00762       {
00763         PixelChannel
00764           channel;
00765 
00766         PixelTrait
00767           traits;
00768 
00769         channel=GetPixelChannelMapChannel(image,i);
00770         traits=GetPixelChannelMapTraits(image,channel);
00771         if ((traits & UpdatePixelTrait) == 0)
00772           continue;
00773         q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]*ShadowFactor+
00774           (MagickRealType) background*(QuantumRange-ShadowFactor)));
00775       }
00776       q+=GetPixelChannels(image);
00777     }
00778     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
00779       status=MagickFalse;
00780     if (image->progress_monitor != (MagickProgressMonitor) NULL)
00781       {
00782         MagickBooleanType
00783           proceed;
00784 
00785         proceed=SetImageProgress(image,RaiseImageTag,progress++,image->rows);
00786         if (proceed == MagickFalse)
00787           status=MagickFalse;
00788       }
00789   }
00790 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00791   #pragma omp parallel for schedule(static) shared(progress,status)
00792 #endif
00793   for (y=(ssize_t) raise_info->height; y < (ssize_t) (image->rows-raise_info->height); y++)
00794   {
00795     register ssize_t
00796       i,
00797       x;
00798 
00799     register Quantum
00800       *restrict q;
00801 
00802     if (status == MagickFalse)
00803       continue;
00804     q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
00805     if (q == (Quantum *) NULL)
00806       {
00807         status=MagickFalse;
00808         continue;
00809       }
00810     for (x=0; x < (ssize_t) raise_info->width; x++)
00811     {
00812       if (GetPixelMask(image,q) != 0)
00813         {
00814           q+=GetPixelChannels(image);
00815           continue;
00816         }
00817       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
00818       {
00819         PixelChannel
00820           channel;
00821 
00822         PixelTrait
00823           traits;
00824 
00825         channel=GetPixelChannelMapChannel(image,i);
00826         traits=GetPixelChannelMapTraits(image,channel);
00827         if ((traits & UpdatePixelTrait) == 0)
00828           continue;
00829         q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]*HighlightFactor+
00830           (MagickRealType) foreground*(QuantumRange-HighlightFactor)));
00831       }
00832       q+=GetPixelChannels(image);
00833     }
00834     for ( ; x < (ssize_t) (image->columns-raise_info->width); x++)
00835       q+=GetPixelChannels(image);
00836     for ( ; x < (ssize_t) image->columns; x++)
00837     {
00838       if (GetPixelMask(image,q) != 0)
00839         {
00840           q+=GetPixelChannels(image);
00841           continue;
00842         }
00843       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
00844       {
00845         PixelChannel
00846           channel;
00847 
00848         PixelTrait
00849           traits;
00850 
00851         channel=GetPixelChannelMapChannel(image,i);
00852         traits=GetPixelChannelMapTraits(image,channel);
00853         if ((traits & UpdatePixelTrait) == 0)
00854           continue;
00855         q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]*ShadowFactor+
00856           (MagickRealType) background*(QuantumRange-ShadowFactor)));
00857       }
00858       q+=GetPixelChannels(image);
00859     }
00860     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
00861       status=MagickFalse;
00862     if (image->progress_monitor != (MagickProgressMonitor) NULL)
00863       {
00864         MagickBooleanType
00865           proceed;
00866 
00867         proceed=SetImageProgress(image,RaiseImageTag,progress++,image->rows);
00868         if (proceed == MagickFalse)
00869           status=MagickFalse;
00870       }
00871   }
00872 #if defined(MAGICKCORE_OPENMP_SUPPORT) 
00873   #pragma omp parallel for schedule(static) shared(progress,status)
00874 #endif
00875   for (y=(ssize_t) (image->rows-raise_info->height); y < (ssize_t) image->rows; y++)
00876   {
00877     register ssize_t
00878       i,
00879       x;
00880 
00881     register Quantum
00882       *restrict q;
00883 
00884     if (status == MagickFalse)
00885       continue;
00886     q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
00887     if (q == (Quantum *) NULL)
00888       {
00889         status=MagickFalse;
00890         continue;
00891       }
00892     for (x=0; x < (ssize_t) (image->rows-y); x++)
00893     {
00894       if (GetPixelMask(image,q) != 0)
00895         {
00896           q+=GetPixelChannels(image);
00897           continue;
00898         }
00899       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
00900       {
00901         PixelChannel
00902           channel;
00903 
00904         PixelTrait
00905           traits;
00906 
00907         channel=GetPixelChannelMapChannel(image,i);
00908         traits=GetPixelChannelMapTraits(image,channel);
00909         if ((traits & UpdatePixelTrait) == 0)
00910           continue;
00911         q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]*HighlightFactor+
00912           (MagickRealType) foreground*(QuantumRange-HighlightFactor)));
00913       }
00914       q+=GetPixelChannels(image);
00915     }
00916     for ( ; x < (ssize_t) (image->columns-(image->rows-y)); x++)
00917     {
00918       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
00919       {
00920         PixelChannel
00921           channel;
00922 
00923         PixelTrait
00924           traits;
00925 
00926         channel=GetPixelChannelMapChannel(image,i);
00927         traits=GetPixelChannelMapTraits(image,channel);
00928         if ((traits & UpdatePixelTrait) == 0)
00929           continue;
00930         q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]*TroughFactor+
00931           (MagickRealType) background*(QuantumRange-TroughFactor)));
00932       }
00933       q+=GetPixelChannels(image);
00934     }
00935     for ( ; x < (ssize_t) image->columns; x++)
00936     {
00937       if (GetPixelMask(image,q) != 0)
00938         {
00939           q+=GetPixelChannels(image);
00940           continue;
00941         }
00942       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
00943       {
00944         PixelChannel
00945           channel;
00946 
00947         PixelTrait
00948           traits;
00949 
00950         channel=GetPixelChannelMapChannel(image,i);
00951         traits=GetPixelChannelMapTraits(image,channel);
00952         if ((traits & UpdatePixelTrait) == 0)
00953           continue;
00954         q[i]=ClampToQuantum(QuantumScale*((MagickRealType) q[i]*ShadowFactor+
00955           (MagickRealType) background*(QuantumRange-ShadowFactor)));
00956       }
00957       q+=GetPixelChannels(image);
00958     }
00959     if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
00960       status=MagickFalse;
00961     if (image->progress_monitor != (MagickProgressMonitor) NULL)
00962       {
00963         MagickBooleanType
00964           proceed;
00965 
00966 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00967         #pragma omp critical (MagickCore_RaiseImage)
00968 #endif
00969         proceed=SetImageProgress(image,RaiseImageTag,progress++,image->rows);
00970         if (proceed == MagickFalse)
00971           status=MagickFalse;
00972       }
00973   }
00974   image_view=DestroyCacheView(image_view);
00975   return(status);
00976 }