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-2008 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 "magick/studio.h"
00044 #include "magick/cache-view.h"
00045 #include "magick/color-private.h"
00046 #include "magick/colorspace-private.h"
00047 #include "magick/composite.h"
00048 #include "magick/decorate.h"
00049 #include "magick/exception.h"
00050 #include "magick/exception-private.h"
00051 #include "magick/image.h"
00052 #include "magick/memory_.h"
00053 #include "magick/monitor.h"
00054 #include "magick/monitor-private.h"
00055 #include "magick/pixel-private.h"
00056 #include "magick/quantum.h"
00057 
00058 /*
00059   Define declarations.
00060 */
00061 #define AccentuateModulate  ScaleCharToQuantum(80)
00062 #define HighlightModulate  ScaleCharToQuantum(125)
00063 #define ShadowModulate  ScaleCharToQuantum(135)
00064 #define DepthModulate  ScaleCharToQuantum(185)
00065 #define TroughModulate  ScaleCharToQuantum(110)
00066 
00067 /*
00068 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00069 %                                                                             %
00070 %                                                                             %
00071 %                                                                             %
00072 %   B o r d e r I m a g e                                                     %
00073 %                                                                             %
00074 %                                                                             %
00075 %                                                                             %
00076 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00077 %
00078 %  BorderImage() surrounds the image with a border of the color defined by
00079 %  the bordercolor member of the image structure.  The width and height
00080 %  of the border are defined by the corresponding members of the border_info
00081 %  structure.
00082 %
00083 %  The format of the BorderImage method is:
00084 %
00085 %      Image *BorderImage(const Image *image,const RectangleInfo *border_info,
00086 %        ExceptionInfo *exception)
00087 %
00088 %  A description of each parameter follows:
00089 %
00090 %    o image: the image.
00091 %
00092 %    o border_info:  Define the width and height of the border.
00093 %
00094 %    o exception: return any errors or warnings in this structure.
00095 %
00096 */
00097 MagickExport Image *BorderImage(const Image *image,
00098   const RectangleInfo *border_info,ExceptionInfo *exception)
00099 {
00100   Image
00101     *border_image,
00102     *clone_image;
00103 
00104   FrameInfo
00105     frame_info;
00106 
00107   assert(image != (const Image *) NULL);
00108   assert(image->signature == MagickSignature);
00109   if (image->debug != MagickFalse)
00110     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00111   assert(border_info != (RectangleInfo *) NULL);
00112   frame_info.width=image->columns+(border_info->width << 1);
00113   frame_info.height=image->rows+(border_info->height << 1);
00114   frame_info.x=(long) border_info->width;
00115   frame_info.y=(long) border_info->height;
00116   frame_info.inner_bevel=0;
00117   frame_info.outer_bevel=0;
00118   clone_image=CloneImage(image,0,0,MagickTrue,exception);
00119   if (clone_image == (Image *) NULL)
00120     return((Image *) NULL);
00121   clone_image->matte_color=image->border_color;
00122   border_image=FrameImage(clone_image,&frame_info,exception);
00123   clone_image=DestroyImage(clone_image);
00124   if (border_image != (Image *) NULL)
00125     border_image->matte_color=image->matte_color;
00126   return(border_image);
00127 }
00128 
00129 /*
00130 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00131 %                                                                             %
00132 %                                                                             %
00133 %                                                                             %
00134 %   F r a m e I m a g e                                                       %
00135 %                                                                             %
00136 %                                                                             %
00137 %                                                                             %
00138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00139 %
00140 %  FrameImage() adds a simulated three-dimensional border around the image.
00141 %  The color of the border is defined by the matte_color member of image.
00142 %  Members width and height of frame_info specify the border width of the
00143 %  vertical and horizontal sides of the frame.  Members inner and outer
00144 %  indicate the width of the inner and outer shadows of the frame.
00145 %
00146 %  The format of the FrameImage method is:
00147 %
00148 %      Image *FrameImage(const Image *image,const FrameInfo *frame_info,
00149 %        ExceptionInfo *exception)
00150 %
00151 %  A description of each parameter follows:
00152 %
00153 %    o image: the image.
00154 %
00155 %    o frame_info: Define the width and height of the frame and its bevels.
00156 %
00157 %    o exception: return any errors or warnings in this structure.
00158 %
00159 */
00160 MagickExport Image *FrameImage(const Image *image,const FrameInfo *frame_info,
00161   ExceptionInfo *exception)
00162 {
00163 #define FrameImageTag  "Frame/Image"
00164 
00165   Image
00166     *frame_image;
00167 
00168   long
00169     progress,
00170     y;
00171 
00172   MagickBooleanType
00173     status;
00174 
00175   MagickPixelPacket
00176     accentuate,
00177     border,
00178     highlight,
00179     interior,
00180     matte,
00181     shadow,
00182     trough;
00183 
00184   register IndexPacket
00185     *frame_indexes;
00186 
00187   register long
00188     x;
00189 
00190   register PixelPacket
00191     *q;
00192 
00193   unsigned long
00194     bevel_width,
00195     height,
00196     width;
00197 
00198   ViewInfo
00199     **frame_view;
00200 
00201   /*
00202     Check frame geometry.
00203   */
00204   assert(image != (Image *) NULL);
00205   assert(image->signature == MagickSignature);
00206   if (image->debug != MagickFalse)
00207     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00208   assert(frame_info != (FrameInfo *) NULL);
00209   bevel_width=(unsigned long) (frame_info->outer_bevel+frame_info->inner_bevel);
00210   width=frame_info->width-frame_info->x-bevel_width;
00211   height=frame_info->height-frame_info->y-bevel_width;
00212   if ((width < image->columns) || (height < image->rows))
00213     ThrowImageException(OptionError,"FrameIsLessThanImageSize");
00214   /*
00215     Initialize framed image attributes.
00216   */
00217   frame_image=CloneImage(image,frame_info->width,frame_info->height,MagickTrue,
00218     exception);
00219   if (frame_image == (Image *) NULL)
00220     return((Image *) NULL);
00221   if (SetImageStorageClass(frame_image,DirectClass) == MagickFalse)
00222     {
00223       InheritException(exception,&frame_image->exception);
00224       frame_image=DestroyImage(frame_image);
00225       return((Image *) NULL);
00226     }
00227   if (frame_image->matte_color.opacity != OpaqueOpacity)
00228     frame_image->matte=MagickTrue;
00229   frame_image->page=image->page;
00230   if ((image->page.width != 0) && (image->page.height != 0))
00231     {
00232       frame_image->page.width+=frame_image->columns-image->columns;
00233       frame_image->page.height+=frame_image->rows-image->rows;
00234     }
00235   /*
00236     Initialize 3D effects color.
00237   */
00238   GetMagickPixelPacket(frame_image,&interior);
00239   SetMagickPixelPacket(frame_image,&image->border_color,(IndexPacket *) NULL,
00240     &interior);
00241   GetMagickPixelPacket(frame_image,&matte);
00242   matte.colorspace=RGBColorspace;
00243   SetMagickPixelPacket(frame_image,&image->matte_color,(IndexPacket *) NULL,
00244     &matte);
00245   GetMagickPixelPacket(frame_image,&border);
00246   border.colorspace=RGBColorspace;
00247   SetMagickPixelPacket(frame_image,&image->border_color,(IndexPacket *) NULL,
00248     &border);
00249   GetMagickPixelPacket(frame_image,&accentuate);
00250   accentuate.red=(MagickRealType) (QuantumScale*((QuantumRange-
00251     AccentuateModulate)*matte.red+(QuantumRange*AccentuateModulate)));
00252   accentuate.green=(MagickRealType) (QuantumScale*((QuantumRange-
00253     AccentuateModulate)*matte.green+(QuantumRange*AccentuateModulate)));
00254   accentuate.blue=(MagickRealType) (QuantumScale*((QuantumRange-
00255     AccentuateModulate)*matte.blue+(QuantumRange*AccentuateModulate)));
00256   accentuate.opacity=matte.opacity;
00257   GetMagickPixelPacket(frame_image,&highlight);
00258   highlight.red=(MagickRealType) (QuantumScale*((QuantumRange-
00259     HighlightModulate)*matte.red+(QuantumRange*HighlightModulate)));
00260   highlight.green=(MagickRealType) (QuantumScale*((QuantumRange-
00261     HighlightModulate)*matte.green+(QuantumRange*HighlightModulate)));
00262   highlight.blue=(MagickRealType) (QuantumScale*((QuantumRange-
00263     HighlightModulate)*matte.blue+(QuantumRange*HighlightModulate)));
00264   highlight.opacity=matte.opacity;
00265   GetMagickPixelPacket(frame_image,&shadow);
00266   shadow.red=QuantumScale*matte.red*ShadowModulate;
00267   shadow.green=QuantumScale*matte.green*ShadowModulate;
00268   shadow.blue=QuantumScale*matte.blue*ShadowModulate;
00269   shadow.opacity=matte.opacity;
00270   GetMagickPixelPacket(frame_image,&trough);
00271   trough.red=QuantumScale*matte.red*TroughModulate;
00272   trough.green=QuantumScale*matte.green*TroughModulate;
00273   trough.blue=QuantumScale*matte.blue*TroughModulate;
00274   trough.opacity=matte.opacity;
00275   if (image->colorspace == CMYKColorspace)
00276     {
00277       ConvertRGBToCMYK(&interior);
00278       ConvertRGBToCMYK(&matte);
00279       ConvertRGBToCMYK(&border);
00280       ConvertRGBToCMYK(&accentuate);
00281       ConvertRGBToCMYK(&highlight);
00282       ConvertRGBToCMYK(&shadow);
00283       ConvertRGBToCMYK(&trough);
00284     }
00285   status=MagickTrue;
00286   progress=0;
00287   frame_view=AcquireCacheViewThreadSet(frame_image);
00288   height=(unsigned long) (frame_info->outer_bevel+(frame_info->y-bevel_width)+
00289     frame_info->inner_bevel);
00290   q=QueueCacheViewAuthenticPixels(frame_view[0],0,0,frame_image->columns,height,
00291     exception);
00292   frame_indexes=GetCacheViewAuthenticIndexes(frame_view[0]);
00293   if (q != (PixelPacket *) NULL)
00294     {
00295       /*
00296         Draw top of ornamental border.
00297       */
00298       for (y=0; y < (long) frame_info->outer_bevel; y++)
00299       {
00300         for (x=0; x < (long) (frame_image->columns-y); x++)
00301         {
00302           if (x < y)
00303             SetPixelPacket(frame_image,&highlight,q,frame_indexes);
00304           else
00305             SetPixelPacket(frame_image,&accentuate,q,frame_indexes);
00306           q++;
00307           frame_indexes++;
00308         }
00309         for ( ; x < (long) frame_image->columns; x++)
00310         {
00311           SetPixelPacket(frame_image,&shadow,q,frame_indexes);
00312           q++;
00313           frame_indexes++;
00314         }
00315       }
00316       for (y=0; y < (long) (frame_info->y-bevel_width); y++)
00317       {
00318         for (x=0; x < (long) frame_info->outer_bevel; x++)
00319         {
00320           SetPixelPacket(frame_image,&highlight,q,frame_indexes);
00321           q++;
00322           frame_indexes++;
00323         }
00324         width=frame_image->columns-2*frame_info->outer_bevel;
00325         for (x=0; x < (long) width; x++)
00326         {
00327           SetPixelPacket(frame_image,&matte,q,frame_indexes);
00328           q++;
00329           frame_indexes++;
00330         }
00331         for (x=0; x < (long) frame_info->outer_bevel; x++)
00332         {
00333           SetPixelPacket(frame_image,&shadow,q,frame_indexes);
00334           q++;
00335           frame_indexes++;
00336         }
00337       }
00338       for (y=0; y < (long) frame_info->inner_bevel; y++)
00339       {
00340         for (x=0; x < (long) frame_info->outer_bevel; x++)
00341         {
00342           SetPixelPacket(frame_image,&highlight,q,frame_indexes);
00343           q++;
00344           frame_indexes++;
00345         }
00346         for (x=0; x < (long) (frame_info->x-bevel_width); x++)
00347         {
00348           SetPixelPacket(frame_image,&matte,q,frame_indexes);
00349           q++;
00350           frame_indexes++;
00351         }
00352         width=image->columns+((unsigned long) frame_info->inner_bevel << 1)-y;
00353         for (x=0; x < (long) width; x++)
00354         {
00355           if (x < y)
00356             SetPixelPacket(frame_image,&shadow,q,frame_indexes);
00357           else
00358             SetPixelPacket(frame_image,&trough,q,frame_indexes);
00359           q++;
00360           frame_indexes++;
00361         }
00362         for ( ; x < (long) (image->columns+2*frame_info->inner_bevel); x++)
00363         {
00364           SetPixelPacket(frame_image,&highlight,q,frame_indexes);
00365           q++;
00366           frame_indexes++;
00367         }
00368         width=frame_info->width-frame_info->x-image->columns-bevel_width;
00369         for (x=0; x < (long) width; x++)
00370         {
00371           SetPixelPacket(frame_image,&matte,q,frame_indexes);
00372           q++;
00373           frame_indexes++;
00374         }
00375         for (x=0; x < (long) frame_info->outer_bevel; x++)
00376         {
00377           SetPixelPacket(frame_image,&shadow,q,frame_indexes);
00378           q++;
00379           frame_indexes++;
00380         }
00381       }
00382       (void) SyncCacheViewAuthenticPixels(frame_view[0],exception);
00383     }
00384   /*
00385     Draw sides of ornamental border.
00386   */
00387 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00388   #pragma omp parallel for schedule(dynamic,8) shared(progress,status)
00389 #endif
00390   for (y=0; y < (long) image->rows; y++)
00391   {
00392     register IndexPacket
00393       *frame_indexes;
00394 
00395     register long
00396       id,
00397       x;
00398 
00399     register PixelPacket
00400       *q;
00401 
00402     /*
00403       Initialize scanline with matte color.
00404     */
00405     if (status == MagickFalse)
00406       continue;
00407     id=GetCacheViewThreadId();
00408     q=QueueCacheViewAuthenticPixels(frame_view[id],0,frame_info->y+y,
00409       frame_image->columns,1,exception);
00410     if (q == (PixelPacket *) NULL)
00411       {
00412         status=MagickFalse;
00413         continue;
00414       }
00415     frame_indexes=GetCacheViewAuthenticIndexes(frame_view[id]);
00416     for (x=0; x < (long) frame_info->outer_bevel; x++)
00417     {
00418       SetPixelPacket(frame_image,&highlight,q,frame_indexes);
00419       q++;
00420       frame_indexes++;
00421     }
00422     for (x=0; x < (long) (frame_info->x-bevel_width); x++)
00423     {
00424       SetPixelPacket(frame_image,&matte,q,frame_indexes);
00425       q++;
00426       frame_indexes++;
00427     }
00428     for (x=0; x < (long) frame_info->inner_bevel; x++)
00429     {
00430       SetPixelPacket(frame_image,&shadow,q,frame_indexes);
00431       q++;
00432       frame_indexes++;
00433     }
00434     /*
00435       Set frame interior to interior color.
00436     */
00437     for (x=0; x < (long) image->columns; x++)
00438     {
00439       SetPixelPacket(frame_image,&interior,q,frame_indexes);
00440       q++;
00441       frame_indexes++;
00442     }
00443     for (x=0; x < (long) frame_info->inner_bevel; x++)
00444     {
00445       SetPixelPacket(frame_image,&highlight,q,frame_indexes);
00446       q++;
00447       frame_indexes++;
00448     }
00449     width=frame_info->width-frame_info->x-image->columns-bevel_width;
00450     for (x=0; x < (long) width; x++)
00451     {
00452       SetPixelPacket(frame_image,&matte,q,frame_indexes);
00453       q++;
00454       frame_indexes++;
00455     }
00456     for (x=0; x < (long) frame_info->outer_bevel; x++)
00457     {
00458       SetPixelPacket(frame_image,&shadow,q,frame_indexes);
00459       q++;
00460       frame_indexes++;
00461     }
00462     if (SyncCacheViewAuthenticPixels(frame_view[id],exception) == MagickFalse)
00463       status=MagickFalse;
00464     if (image->progress_monitor != (MagickProgressMonitor) NULL)
00465       {
00466         MagickBooleanType
00467           proceed;
00468 
00469 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00470   #pragma omp critical
00471 #endif
00472         proceed=SetImageProgress(image,FrameImageTag,progress++,image->rows);
00473         if (proceed == MagickFalse)
00474           status=MagickFalse;
00475       }
00476   }
00477   height=(unsigned long) (frame_info->inner_bevel+frame_info->height-
00478     frame_info->y-image->rows-bevel_width+frame_info->outer_bevel);
00479   q=QueueCacheViewAuthenticPixels(frame_view[0],0,(long) (frame_image->rows-
00480     height),frame_image->columns,height,exception);
00481   if (q != (PixelPacket *) NULL)
00482     {
00483       /*
00484         Draw bottom of ornamental border.
00485       */
00486       frame_indexes=GetCacheViewAuthenticIndexQueue(frame_view[0]);
00487       for (y=frame_info->inner_bevel-1; y >= 0; y--)
00488       {
00489         for (x=0; x < (long) frame_info->outer_bevel; x++)
00490         {
00491           SetPixelPacket(frame_image,&highlight,q,frame_indexes);
00492           q++;
00493           frame_indexes++;
00494         }
00495         for (x=0; x < (long) (frame_info->x-bevel_width); x++)
00496         {
00497           SetPixelPacket(frame_image,&matte,q,frame_indexes);
00498           q++;
00499           frame_indexes++;
00500         }
00501         for (x=0; x < y; x++)
00502         {
00503           SetPixelPacket(frame_image,&shadow,q,frame_indexes);
00504           q++;
00505           frame_indexes++;
00506         }
00507         for ( ; x < (long) (image->columns+2*frame_info->inner_bevel); x++)
00508         {
00509           if (x >= (long) (image->columns+2*frame_info->inner_bevel-y))
00510             SetPixelPacket(frame_image,&highlight,q,frame_indexes);
00511           else
00512             SetPixelPacket(frame_image,&accentuate,q,frame_indexes);
00513           q++;
00514           frame_indexes++;
00515         }
00516         width=frame_info->width-frame_info->x-image->columns-bevel_width;
00517         for (x=0; x < (long) width; x++)
00518         {
00519           SetPixelPacket(frame_image,&matte,q,frame_indexes);
00520           q++;
00521           frame_indexes++;
00522         }
00523         for (x=0; x < (long) frame_info->outer_bevel; x++)
00524         {
00525           SetPixelPacket(frame_image,&shadow,q,frame_indexes);
00526           q++;
00527           frame_indexes++;
00528         }
00529       }
00530       height=frame_info->height-frame_info->y-image->rows-bevel_width;
00531       for (y=0; y < (long) height; y++)
00532       {
00533         for (x=0; x < (long) frame_info->outer_bevel; x++)
00534         {
00535           SetPixelPacket(frame_image,&highlight,q,frame_indexes);
00536           q++;
00537           frame_indexes++;
00538         }
00539         width=frame_image->columns-2*frame_info->outer_bevel;
00540         for (x=0; x < (long) width; x++)
00541         {
00542           SetPixelPacket(frame_image,&matte,q,frame_indexes);
00543           q++;
00544           frame_indexes++;
00545         }
00546         for (x=0; x < (long) frame_info->outer_bevel; x++)
00547         {
00548           SetPixelPacket(frame_image,&shadow,q,frame_indexes);
00549           q++;
00550           frame_indexes++;
00551         }
00552       }
00553       for (y=frame_info->outer_bevel-1; y >= 0; y--)
00554       {
00555         for (x=0; x < y; x++)
00556         {
00557           SetPixelPacket(frame_image,&highlight,q,frame_indexes);
00558           q++;
00559           frame_indexes++;
00560         }
00561         for ( ; x < (long) frame_image->columns; x++)
00562         {
00563           if (x >= (long) (frame_image->columns-y))
00564             SetPixelPacket(frame_image,&shadow,q,frame_indexes);
00565           else
00566             SetPixelPacket(frame_image,&trough,q,frame_indexes);
00567           q++;
00568           frame_indexes++;
00569         }
00570       }
00571       (void) SyncCacheViewAuthenticPixels(frame_view[0],exception);
00572     }
00573   frame_view=DestroyCacheViewThreadSet(frame_view);
00574   x=(long) (frame_info->outer_bevel+(frame_info->x-bevel_width)+
00575     frame_info->inner_bevel);
00576   y=(long) (frame_info->outer_bevel+(frame_info->y-bevel_width)+
00577     frame_info->inner_bevel);
00578   (void) CompositeImage(frame_image,image->compose,image,x,y);
00579   return(frame_image);
00580 }
00581 
00582 /*
00583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00584 %                                                                             %
00585 %                                                                             %
00586 %                                                                             %
00587 %   R a i s e I m a g e                                                       %
00588 %                                                                             %
00589 %                                                                             %
00590 %                                                                             %
00591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00592 %
00593 %  RaiseImage() creates a simulated three-dimensional button-like effect
00594 %  by lightening and darkening the edges of the image.  Members width and
00595 %  height of raise_info define the width of the vertical and horizontal
00596 %  edge of the effect.
00597 %
00598 %  The format of the RaiseImage method is:
00599 %
00600 %      MagickBooleanType RaiseImage(const Image *image,
00601 %        const RectangleInfo *raise_info,const MagickBooleanType raise)
00602 %
00603 %  A description of each parameter follows:
00604 %
00605 %    o image: the image.
00606 %
00607 %    o raise_info: Define the width and height of the raise area.
00608 %
00609 %    o raise: A value other than zero creates a 3-D raise effect,
00610 %      otherwise it has a lowered effect.
00611 %
00612 */
00613 MagickExport MagickBooleanType RaiseImage(Image *image,
00614   const RectangleInfo *raise_info,const MagickBooleanType raise)
00615 {
00616 #define AccentuateFactor  ScaleCharToQuantum(135)
00617 #define HighlightFactor  ScaleCharToQuantum(190)
00618 #define ShadowFactor  ScaleCharToQuantum(190)
00619 #define RaiseImageTag  "Raise/Image"
00620 #define TroughFactor  ScaleCharToQuantum(135)
00621 
00622   ExceptionInfo
00623     *exception;
00624 
00625   long
00626     progress,
00627     y;
00628 
00629   MagickBooleanType
00630     status;
00631 
00632   Quantum
00633     foreground,
00634     background;
00635 
00636   ViewInfo
00637     **image_view;
00638 
00639   assert(image != (Image *) NULL);
00640   assert(image->signature == MagickSignature);
00641   if (image->debug != MagickFalse)
00642     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00643   assert(raise_info != (RectangleInfo *) NULL);
00644   if ((image->columns <= (raise_info->width << 1)) ||
00645       (image->rows <= (raise_info->height << 1)))
00646     ThrowBinaryException(OptionError,"ImageSizeMustExceedBevelWidth",
00647       image->filename);
00648   foreground=(Quantum) QuantumRange;
00649   background=(Quantum) 0;
00650   if (raise == MagickFalse)
00651     {
00652       foreground=(Quantum) 0;
00653       background=(Quantum) QuantumRange;
00654     }
00655   if (SetImageStorageClass(image,DirectClass) == MagickFalse)
00656     return(MagickFalse);
00657   /*
00658     Raise image.
00659   */
00660   status=MagickTrue;
00661   progress=0;
00662   exception=(&image->exception);
00663   image_view=AcquireCacheViewThreadSet(image);
00664 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00665   #pragma omp parallel for schedule(dynamic,8) shared(progress,status)
00666 #endif
00667   for (y=0; y < (long) raise_info->height; y++)
00668   {
00669     register long
00670       id,
00671       x;
00672 
00673     register PixelPacket
00674       *q;
00675 
00676     if (status == MagickFalse)
00677       continue;
00678     id=GetCacheViewThreadId();
00679     q=GetCacheViewAuthenticPixels(image_view[id],0,y,image->columns,1,
00680       exception);
00681     if (q == (PixelPacket *) NULL)
00682       {
00683         status=MagickFalse;
00684         continue;
00685       }
00686     for (x=0; x < y; x++)
00687     {
00688       q->red=RoundToQuantum(QuantumScale*((MagickRealType) q->red*
00689         HighlightFactor+(MagickRealType) foreground*(QuantumRange-
00690         HighlightFactor)));
00691       q->green=RoundToQuantum(QuantumScale*((MagickRealType) q->green*
00692         HighlightFactor+(MagickRealType) foreground*(QuantumRange-
00693         HighlightFactor)));
00694       q->blue=RoundToQuantum(QuantumScale*((MagickRealType) q->blue*
00695         HighlightFactor+(MagickRealType) foreground*(QuantumRange-
00696         HighlightFactor)));
00697       q++;
00698     }
00699     for ( ; x < (long) (image->columns-y); x++)
00700     {
00701       q->red=RoundToQuantum(QuantumScale*((MagickRealType) q->red*
00702         AccentuateFactor+(MagickRealType) foreground*(QuantumRange-
00703         AccentuateFactor)));
00704       q->green=RoundToQuantum(QuantumScale*((MagickRealType) q->green*
00705         AccentuateFactor+(MagickRealType) foreground*(QuantumRange-
00706         AccentuateFactor)));
00707       q->blue=RoundToQuantum(QuantumScale*((MagickRealType) q->blue*
00708         AccentuateFactor+(MagickRealType) foreground*(QuantumRange-
00709         AccentuateFactor)));
00710       q++;
00711     }
00712     for ( ; x < (long) image->columns; x++)
00713     {
00714       q->red=RoundToQuantum(QuantumScale*((MagickRealType) q->red*ShadowFactor+
00715         (MagickRealType) background*(QuantumRange-ShadowFactor)));
00716       q->green=RoundToQuantum(QuantumScale*((MagickRealType) q->green*
00717         ShadowFactor+(MagickRealType) background*(QuantumRange-ShadowFactor)));
00718       q->blue=RoundToQuantum(QuantumScale*((MagickRealType) q->blue*
00719         ShadowFactor+(MagickRealType) background*(QuantumRange-ShadowFactor)));
00720       q++;
00721     }
00722     if (SyncCacheViewAuthenticPixels(image_view[id],exception) == MagickFalse)
00723       status=MagickFalse;
00724     if (image->progress_monitor != (MagickProgressMonitor) NULL)
00725       {
00726         MagickBooleanType
00727           proceed;
00728 
00729         proceed=SetImageProgress(image,RaiseImageTag,progress++,image->rows);
00730         if (proceed == MagickFalse)
00731           status=MagickFalse;
00732       }
00733   }
00734 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00735   #pragma omp parallel for schedule(dynamic,8) shared(progress,status)
00736 #endif
00737   for (y=(long) raise_info->height; y < (long) (image->rows-raise_info->height); y++)
00738   {
00739     register long
00740       id,
00741       x;
00742 
00743     register PixelPacket
00744       *q;
00745 
00746     if (status == MagickFalse)
00747       continue;
00748     id=GetCacheViewThreadId();
00749     q=GetCacheViewAuthenticPixels(image_view[id],0,y,image->columns,1,
00750       exception);
00751     if (q == (PixelPacket *) NULL)
00752       {
00753         status=MagickFalse;
00754         continue;
00755       }
00756     for (x=0; x < (long) raise_info->width; x++)
00757     {
00758       q->red=RoundToQuantum(QuantumScale*((MagickRealType) q->red*
00759         HighlightFactor+(MagickRealType) foreground*(QuantumRange-
00760         HighlightFactor)));
00761       q->green=RoundToQuantum(QuantumScale*((MagickRealType) q->green*
00762         HighlightFactor+(MagickRealType) foreground*(QuantumRange-
00763         HighlightFactor)));
00764       q->blue=RoundToQuantum(QuantumScale*((MagickRealType) q->blue*
00765         HighlightFactor+(MagickRealType) foreground*(QuantumRange-
00766         HighlightFactor)));
00767       q++;
00768     }
00769     for ( ; x < (long) (image->columns-raise_info->width); x++)
00770       q++;
00771     for ( ; x < (long) image->columns; x++)
00772     {
00773       q->red=RoundToQuantum(QuantumScale*((MagickRealType) q->red*ShadowFactor+
00774         (MagickRealType) background*(QuantumRange-ShadowFactor)));
00775       q->green=RoundToQuantum(QuantumScale*((MagickRealType) q->green*
00776         ShadowFactor+(MagickRealType) background*(QuantumRange-ShadowFactor)));
00777       q->blue=RoundToQuantum(QuantumScale*((MagickRealType) q->blue*
00778         ShadowFactor+(MagickRealType) background*(QuantumRange-ShadowFactor)));
00779       q++;
00780     }
00781     if (SyncCacheViewAuthenticPixels(image_view[id],exception) == MagickFalse)
00782       status=MagickFalse;
00783     if (image->progress_monitor != (MagickProgressMonitor) NULL)
00784       {
00785         MagickBooleanType
00786           proceed;
00787 
00788         proceed=SetImageProgress(image,RaiseImageTag,progress++,image->rows);
00789         if (proceed == MagickFalse)
00790           status=MagickFalse;
00791       }
00792   }
00793 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00794   #pragma omp parallel for schedule(dynamic,8) shared(progress,status)
00795 #endif
00796   for (y=(long) (image->rows-raise_info->height); y < (long) image->rows; y++)
00797   {
00798     register long
00799       id,
00800       x;
00801 
00802     register PixelPacket
00803       *q;
00804 
00805     if (status == MagickFalse)
00806       continue;
00807     id=GetCacheViewThreadId();
00808     q=GetCacheViewAuthenticPixels(image_view[id],0,y,image->columns,1,
00809       exception);
00810     if (q == (PixelPacket *) NULL)
00811       {
00812         status=MagickFalse;
00813         continue;
00814       }
00815     for (x=0; x < (long) (image->rows-y); x++)
00816     {
00817       q->red=RoundToQuantum(QuantumScale*((MagickRealType) q->red*
00818         HighlightFactor+(MagickRealType) foreground*(QuantumRange-
00819         HighlightFactor)));
00820       q->green=RoundToQuantum(QuantumScale*((MagickRealType) q->green*
00821         HighlightFactor+(MagickRealType) foreground*(QuantumRange-
00822         HighlightFactor)));
00823       q->blue=RoundToQuantum(QuantumScale*((MagickRealType) q->blue*
00824         HighlightFactor+(MagickRealType) foreground*(QuantumRange-
00825         HighlightFactor)));
00826       q++;
00827     }
00828     for ( ; x < (long) (image->columns-(image->rows-y)); x++)
00829     {
00830       q->red=RoundToQuantum(QuantumScale*((MagickRealType) q->red*TroughFactor+
00831         (MagickRealType) background*(QuantumRange-TroughFactor)));
00832       q->green=RoundToQuantum(QuantumScale*((MagickRealType) q->green*
00833         TroughFactor+(MagickRealType) background*(QuantumRange-TroughFactor)));
00834       q->blue=RoundToQuantum(QuantumScale*((MagickRealType) q->blue*
00835         TroughFactor+(MagickRealType) background*(QuantumRange-TroughFactor)));
00836       q++;
00837     }
00838     for ( ; x < (long) image->columns; x++)
00839     {
00840       q->red=RoundToQuantum(QuantumScale*((MagickRealType) q->red*ShadowFactor+
00841         (MagickRealType) background*(QuantumRange-ShadowFactor)));
00842       q->green=RoundToQuantum(QuantumScale*((MagickRealType) q->green*
00843         ShadowFactor+(MagickRealType) background*(QuantumRange-ShadowFactor)));
00844       q->blue=RoundToQuantum(QuantumScale*((MagickRealType) q->blue*
00845         ShadowFactor+(MagickRealType) background*(QuantumRange-ShadowFactor)));
00846       q++;
00847     }
00848     if (SyncCacheViewAuthenticPixels(image_view[id],exception) == MagickFalse)
00849       status=MagickFalse;
00850     if (image->progress_monitor != (MagickProgressMonitor) NULL)
00851       {
00852         MagickBooleanType
00853           proceed;
00854 
00855 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00856   #pragma omp critical
00857 #endif
00858         proceed=SetImageProgress(image,RaiseImageTag,progress++,image->rows);
00859         if (proceed == MagickFalse)
00860           status=MagickFalse;
00861       }
00862   }
00863   image_view=DestroyCacheViewThreadSet(image_view);
00864   return(status);
00865 }

Generated on Thu Nov 20 21:54:43 2008 for MagickCore by  doxygen 1.5.7.1