MagickCore  7.1.0
decorate.c
Go to the documentation of this file.
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % DDDD EEEEE CCCC OOO RRRR AAA TTTTT EEEEE %
7 % D D E C O O R R A A T E %
8 % D D EEE C O O RRRR AAAAA T EEE %
9 % D D E C O O R R A A T E %
10 % DDDD EEEEE CCCC OOO R R A A T EEEEE %
11 % %
12 % %
13 % MagickCore Image Decoration Methods %
14 % %
15 % Software Design %
16 % Cristy %
17 % July 1992 %
18 % %
19 % %
20 % Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
22 % %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
25 % %
26 % https://imagemagick.org/script/license.php %
27 % %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
33 % %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 %
38 */
39 
40 /*
41  Include declarations.
42 */
43 #include "MagickCore/studio.h"
44 #include "MagickCore/cache-view.h"
47 #include "MagickCore/composite.h"
48 #include "MagickCore/decorate.h"
49 #include "MagickCore/exception.h"
51 #include "MagickCore/image.h"
52 #include "MagickCore/memory_.h"
53 #include "MagickCore/monitor.h"
56 #include "MagickCore/quantum.h"
58 #include "MagickCore/resource_.h"
60 #include "MagickCore/transform.h"
61 
62 /*
63  Define declarations.
64 */
65 #define AccentuateModulate ScaleCharToQuantum(80)
66 #define HighlightModulate ScaleCharToQuantum(125)
67 #define ShadowModulate ScaleCharToQuantum(135)
68 #define DepthModulate ScaleCharToQuantum(185)
69 #define TroughModulate ScaleCharToQuantum(110)
70 
71 /*
72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
73 % %
74 % %
75 % %
76 % B o r d e r I m a g e %
77 % %
78 % %
79 % %
80 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81 %
82 % BorderImage() surrounds the image with a border of the color defined by
83 % the bordercolor member of the image structure. The width and height
84 % of the border are defined by the corresponding members of the border_info
85 % structure.
86 %
87 % The format of the BorderImage method is:
88 %
89 % Image *BorderImage(const Image *image,const RectangleInfo *border_info,
90 % const CompositeOperator compose,ExceptionInfo *exception)
91 %
92 % A description of each parameter follows:
93 %
94 % o image: the image.
95 %
96 % o border_info: define the width and height of the border.
97 %
98 % o compose: the composite operator.
99 %
100 % o exception: return any errors or warnings in this structure.
101 %
102 */
104  const RectangleInfo *border_info,const CompositeOperator compose,
105  ExceptionInfo *exception)
106 {
107  Image
108  *border_image,
109  *clone_image;
110 
111  FrameInfo
112  frame_info;
113 
114  assert(image != (const Image *) NULL);
115  assert(image->signature == MagickCoreSignature);
116  if (image->debug != MagickFalse)
117  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
118  assert(border_info != (RectangleInfo *) NULL);
119  frame_info.width=image->columns+(border_info->width << 1);
120  frame_info.height=image->rows+(border_info->height << 1);
121  frame_info.x=(ssize_t) border_info->width;
122  frame_info.y=(ssize_t) border_info->height;
123  frame_info.inner_bevel=0;
124  frame_info.outer_bevel=0;
125  clone_image=CloneImage(image,0,0,MagickTrue,exception);
126  if (clone_image == (Image *) NULL)
127  return((Image *) NULL);
128  clone_image->matte_color=image->border_color;
129  border_image=FrameImage(clone_image,&frame_info,compose,exception);
130  clone_image=DestroyImage(clone_image);
131  if (border_image != (Image *) NULL)
132  border_image->matte_color=image->matte_color;
133  return(border_image);
134 }
135 
136 /*
137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138 % %
139 % %
140 % %
141 % F r a m e I m a g e %
142 % %
143 % %
144 % %
145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 %
147 % FrameImage() adds a simulated three-dimensional border around the image.
148 % The color of the border is defined by the matte_color member of image.
149 % Members width and height of frame_info specify the border width of the
150 % vertical and horizontal sides of the frame. Members inner and outer
151 % indicate the width of the inner and outer shadows of the frame.
152 %
153 % The format of the FrameImage method is:
154 %
155 % Image *FrameImage(const Image *image,const FrameInfo *frame_info,
156 % const CompositeOperator compose,ExceptionInfo *exception)
157 %
158 % A description of each parameter follows:
159 %
160 % o image: the image.
161 %
162 % o frame_info: Define the width and height of the frame and its bevels.
163 %
164 % o compose: the composite operator.
165 %
166 % o exception: return any errors or warnings in this structure.
167 %
168 */
169 MagickExport Image *FrameImage(const Image *image,const FrameInfo *frame_info,
170  const CompositeOperator compose,ExceptionInfo *exception)
171 {
172 #define FrameImageTag "Frame/Image"
173 
174  CacheView
175  *image_view,
176  *frame_view;
177 
178  Image
179  *frame_image;
180 
182  status;
183 
185  progress;
186 
187  PixelInfo
188  accentuate,
189  highlight,
190  matte,
191  shadow,
192  trough;
193 
194  ssize_t
195  x_offset,
196  y_offset;
197 
198  size_t
199  bevel_width,
200  height;
201 
202  ssize_t
203  y;
204 
205  /*
206  Check frame geometry.
207  */
208  assert(image != (Image *) NULL);
209  assert(image->signature == MagickCoreSignature);
210  if (image->debug != MagickFalse)
211  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
212  assert(frame_info != (FrameInfo *) NULL);
213  if ((frame_info->outer_bevel < 0) || (frame_info->inner_bevel < 0))
214  ThrowImageException(OptionError,"FrameIsLessThanImageSize");
215  bevel_width=(size_t) (frame_info->outer_bevel+frame_info->inner_bevel);
216  x_offset=(ssize_t) frame_info->width-frame_info->x-bevel_width;
217  y_offset=(ssize_t) frame_info->height-frame_info->y-bevel_width;
218  if ((x_offset < (ssize_t) image->columns) ||
219  (y_offset < (ssize_t) image->rows))
220  ThrowImageException(OptionError,"FrameIsLessThanImageSize");
221  /*
222  Initialize framed image attributes.
223  */
224  frame_image=CloneImage(image,frame_info->width,frame_info->height,MagickTrue,
225  exception);
226  if (frame_image == (Image *) NULL)
227  return((Image *) NULL);
228  if (SetImageStorageClass(frame_image,DirectClass,exception) == MagickFalse)
229  {
230  frame_image=DestroyImage(frame_image);
231  return((Image *) NULL);
232  }
233  if ((IsPixelInfoGray(&frame_image->border_color) == MagickFalse) &&
234  (IsGrayColorspace(frame_image->colorspace) != MagickFalse))
235  (void) SetImageColorspace(frame_image,sRGBColorspace,exception);
236  if ((frame_image->matte_color.alpha_trait != UndefinedPixelTrait) &&
237  (frame_image->alpha_trait == UndefinedPixelTrait))
238  (void) SetImageAlpha(frame_image,OpaqueAlpha,exception);
239  frame_image->page=image->page;
240  if ((image->page.width != 0) && (image->page.height != 0))
241  {
242  frame_image->page.width+=frame_image->columns-image->columns;
243  frame_image->page.height+=frame_image->rows-image->rows;
244  }
245  /*
246  Initialize 3D effects color.
247  */
248  matte=image->matte_color;
249  accentuate=matte;
250  accentuate.red=(QuantumScale*((QuantumRange-(double) AccentuateModulate)*
251  matte.red+(QuantumRange*(double) AccentuateModulate)));
252  accentuate.green=(QuantumScale*((QuantumRange-(double) AccentuateModulate)*
253  matte.green+(QuantumRange*(double) AccentuateModulate)));
254  accentuate.blue=(QuantumScale*((QuantumRange-(double) AccentuateModulate)*
255  matte.blue+(QuantumRange*(double) AccentuateModulate)));
256  accentuate.black=(QuantumScale*((QuantumRange-(double) AccentuateModulate)*
257  matte.black+(QuantumRange*(double) AccentuateModulate)));
258  accentuate.alpha=matte.alpha;
259  highlight=matte;
260  highlight.red=(QuantumScale*((QuantumRange-(double) HighlightModulate)*
261  matte.red+(QuantumRange*(double) HighlightModulate)));
262  highlight.green=(QuantumScale*((QuantumRange-(double) HighlightModulate)*
263  matte.green+(QuantumRange*(double) HighlightModulate)));
264  highlight.blue=(QuantumScale*((QuantumRange-(double) HighlightModulate)*
265  matte.blue+(QuantumRange*(double) HighlightModulate)));
266  highlight.black=(QuantumScale*((QuantumRange-(double) HighlightModulate)*
267  matte.black+(QuantumRange*(double) HighlightModulate)));
268  highlight.alpha=matte.alpha;
269  shadow=matte;
270  shadow.red=QuantumScale*matte.red*ShadowModulate;
271  shadow.green=QuantumScale*matte.green*ShadowModulate;
272  shadow.blue=QuantumScale*matte.blue*ShadowModulate;
273  shadow.black=QuantumScale*matte.black*ShadowModulate;
274  shadow.alpha=matte.alpha;
275  trough=matte;
276  trough.red=QuantumScale*matte.red*TroughModulate;
277  trough.green=QuantumScale*matte.green*TroughModulate;
278  trough.blue=QuantumScale*matte.blue*TroughModulate;
279  trough.black=QuantumScale*matte.black*TroughModulate;
280  trough.alpha=matte.alpha;
281  status=MagickTrue;
282  progress=0;
283  image_view=AcquireVirtualCacheView(image,exception);
284  frame_view=AcquireAuthenticCacheView(frame_image,exception);
285  height=(size_t) (frame_info->outer_bevel+(frame_info->y-bevel_width)+
286  frame_info->inner_bevel);
287  if (height != 0)
288  {
289  size_t
290  width;
291 
292  ssize_t
293  x;
294 
295  Quantum
296  *magick_restrict q;
297 
298  /*
299  Draw top of ornamental border.
300  */
301  q=QueueCacheViewAuthenticPixels(frame_view,0,0,frame_image->columns,
302  height,exception);
303  if (q != (Quantum *) NULL)
304  {
305  /*
306  Draw top of ornamental border.
307  */
308  for (y=0; y < (ssize_t) frame_info->outer_bevel; y++)
309  {
310  for (x=0; x < (ssize_t) (frame_image->columns-y); x++)
311  {
312  if (x < y)
313  SetPixelViaPixelInfo(frame_image,&highlight,q);
314  else
315  SetPixelViaPixelInfo(frame_image,&accentuate,q);
316  q+=GetPixelChannels(frame_image);
317  }
318  for ( ; x < (ssize_t) frame_image->columns; x++)
319  {
320  SetPixelViaPixelInfo(frame_image,&shadow,q);
321  q+=GetPixelChannels(frame_image);
322  }
323  }
324  for (y=0; y < (ssize_t) (frame_info->y-bevel_width); y++)
325  {
326  for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
327  {
328  SetPixelViaPixelInfo(frame_image,&highlight,q);
329  q+=GetPixelChannels(frame_image);
330  }
331  width=frame_image->columns-2*frame_info->outer_bevel;
332  for (x=0; x < (ssize_t) width; x++)
333  {
334  SetPixelViaPixelInfo(frame_image,&matte,q);
335  q+=GetPixelChannels(frame_image);
336  }
337  for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
338  {
339  SetPixelViaPixelInfo(frame_image,&shadow,q);
340  q+=GetPixelChannels(frame_image);
341  }
342  }
343  for (y=0; y < (ssize_t) frame_info->inner_bevel; y++)
344  {
345  for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
346  {
347  SetPixelViaPixelInfo(frame_image,&highlight,q);
348  q+=GetPixelChannels(frame_image);
349  }
350  for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
351  {
352  SetPixelViaPixelInfo(frame_image,&matte,q);
353  q+=GetPixelChannels(frame_image);
354  }
355  width=image->columns+((size_t) frame_info->inner_bevel << 1)-
356  y;
357  for (x=0; x < (ssize_t) width; x++)
358  {
359  if (x < y)
360  SetPixelViaPixelInfo(frame_image,&shadow,q);
361  else
362  SetPixelViaPixelInfo(frame_image,&trough,q);
363  q+=GetPixelChannels(frame_image);
364  }
365  for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++)
366  {
367  SetPixelViaPixelInfo(frame_image,&highlight,q);
368  q+=GetPixelChannels(frame_image);
369  }
370  width=frame_info->width-frame_info->x-image->columns-bevel_width;
371  for (x=0; x < (ssize_t) width; x++)
372  {
373  SetPixelViaPixelInfo(frame_image,&matte,q);
374  q+=GetPixelChannels(frame_image);
375  }
376  for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
377  {
378  SetPixelViaPixelInfo(frame_image,&shadow,q);
379  q+=GetPixelChannels(frame_image);
380  }
381  }
382  (void) SyncCacheViewAuthenticPixels(frame_view,exception);
383  }
384  }
385  /*
386  Draw sides of ornamental border.
387  */
388 #if defined(MAGICKCORE_OPENMP_SUPPORT)
389  #pragma omp parallel for schedule(static) shared(progress,status) \
390  magick_number_threads(image,frame_image,image->rows,1)
391 #endif
392  for (y=0; y < (ssize_t) image->rows; y++)
393  {
394  ssize_t
395  x;
396 
397  Quantum
398  *magick_restrict q;
399 
400  size_t
401  width;
402 
403  /*
404  Initialize scanline with matte color.
405  */
406  if (status == MagickFalse)
407  continue;
408  q=QueueCacheViewAuthenticPixels(frame_view,0,frame_info->y+y,
409  frame_image->columns,1,exception);
410  if (q == (Quantum *) NULL)
411  {
412  status=MagickFalse;
413  continue;
414  }
415  for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
416  {
417  SetPixelViaPixelInfo(frame_image,&highlight,q);
418  q+=GetPixelChannels(frame_image);
419  }
420  for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
421  {
422  SetPixelViaPixelInfo(frame_image,&matte,q);
423  q+=GetPixelChannels(frame_image);
424  }
425  for (x=0; x < (ssize_t) frame_info->inner_bevel; x++)
426  {
427  SetPixelViaPixelInfo(frame_image,&shadow,q);
428  q+=GetPixelChannels(frame_image);
429  }
430  /*
431  Set frame interior pixels.
432  */
433  for (x=0; x < (ssize_t) image->columns; x++)
434  {
435  SetPixelViaPixelInfo(frame_image,&frame_image->border_color,q);
436  q+=GetPixelChannels(frame_image);
437  }
438  for (x=0; x < (ssize_t) frame_info->inner_bevel; x++)
439  {
440  SetPixelViaPixelInfo(frame_image,&highlight,q);
441  q+=GetPixelChannels(frame_image);
442  }
443  width=frame_info->width-frame_info->x-image->columns-bevel_width;
444  for (x=0; x < (ssize_t) width; x++)
445  {
446  SetPixelViaPixelInfo(frame_image,&matte,q);
447  q+=GetPixelChannels(frame_image);
448  }
449  for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
450  {
451  SetPixelViaPixelInfo(frame_image,&shadow,q);
452  q+=GetPixelChannels(frame_image);
453  }
454  if (SyncCacheViewAuthenticPixels(frame_view,exception) == MagickFalse)
455  status=MagickFalse;
456  if (image->progress_monitor != (MagickProgressMonitor) NULL)
457  {
459  proceed;
460 
461 #if defined(MAGICKCORE_OPENMP_SUPPORT)
462  #pragma omp atomic
463 #endif
464  progress++;
465  proceed=SetImageProgress(image,FrameImageTag,progress,image->rows);
466  if (proceed == MagickFalse)
467  status=MagickFalse;
468  }
469  }
470  height=(size_t) (frame_info->inner_bevel+frame_info->height-
471  frame_info->y-image->rows-bevel_width+frame_info->outer_bevel);
472  if (height != 0)
473  {
474  size_t
475  width;
476 
477  ssize_t
478  x;
479 
480  Quantum
481  *magick_restrict q;
482 
483  /*
484  Draw bottom of ornamental border.
485  */
486  q=QueueCacheViewAuthenticPixels(frame_view,0,(ssize_t) (frame_image->rows-
487  height),frame_image->columns,height,exception);
488  if (q != (Quantum *) NULL)
489  {
490  /*
491  Draw bottom of ornamental border.
492  */
493  for (y=frame_info->inner_bevel-1; y >= 0; y--)
494  {
495  for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
496  {
497  SetPixelViaPixelInfo(frame_image,&highlight,q);
498  q+=GetPixelChannels(frame_image);
499  }
500  for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
501  {
502  SetPixelViaPixelInfo(frame_image,&matte,q);
503  q+=GetPixelChannels(frame_image);
504  }
505  for (x=0; x < y; x++)
506  {
507  SetPixelViaPixelInfo(frame_image,&shadow,q);
508  q+=GetPixelChannels(frame_image);
509  }
510  for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++)
511  {
512  if (x >= (ssize_t) (image->columns+2*frame_info->inner_bevel-y))
513  SetPixelViaPixelInfo(frame_image,&highlight,q);
514  else
515  SetPixelViaPixelInfo(frame_image,&accentuate,q);
516  q+=GetPixelChannels(frame_image);
517  }
518  width=frame_info->width-frame_info->x-image->columns-bevel_width;
519  for (x=0; x < (ssize_t) width; x++)
520  {
521  SetPixelViaPixelInfo(frame_image,&matte,q);
522  q+=GetPixelChannels(frame_image);
523  }
524  for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
525  {
526  SetPixelViaPixelInfo(frame_image,&shadow,q);
527  q+=GetPixelChannels(frame_image);
528  }
529  }
530  height=frame_info->height-frame_info->y-image->rows-bevel_width;
531  for (y=0; y < (ssize_t) height; y++)
532  {
533  for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
534  {
535  SetPixelViaPixelInfo(frame_image,&highlight,q);
536  q+=GetPixelChannels(frame_image);
537  }
538  width=frame_image->columns-2*frame_info->outer_bevel;
539  for (x=0; x < (ssize_t) width; x++)
540  {
541  SetPixelViaPixelInfo(frame_image,&matte,q);
542  q+=GetPixelChannels(frame_image);
543  }
544  for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
545  {
546  SetPixelViaPixelInfo(frame_image,&shadow,q);
547  q+=GetPixelChannels(frame_image);
548  }
549  }
550  for (y=frame_info->outer_bevel-1; y >= 0; y--)
551  {
552  for (x=0; x < y; x++)
553  {
554  SetPixelViaPixelInfo(frame_image,&highlight,q);
555  q+=GetPixelChannels(frame_image);
556  }
557  for ( ; x < (ssize_t) frame_image->columns; x++)
558  {
559  if (x >= (ssize_t) (frame_image->columns-y))
560  SetPixelViaPixelInfo(frame_image,&shadow,q);
561  else
562  SetPixelViaPixelInfo(frame_image,&trough,q);
563  q+=GetPixelChannels(frame_image);
564  }
565  }
566  (void) SyncCacheViewAuthenticPixels(frame_view,exception);
567  }
568  }
569  frame_view=DestroyCacheView(frame_view);
570  image_view=DestroyCacheView(image_view);
571  x_offset=(ssize_t) (frame_info->outer_bevel+(frame_info->x-bevel_width)+
572  frame_info->inner_bevel);
573  y_offset=(ssize_t) (frame_info->outer_bevel+(frame_info->y-bevel_width)+
574  frame_info->inner_bevel);
575  if (status != MagickFalse)
576  status=CompositeImage(frame_image,image,compose,MagickTrue,x_offset,
577  y_offset,exception);
578  if (status == MagickFalse)
579  frame_image=DestroyImage(frame_image);
580  return(frame_image);
581 }
582 
583 /*
584 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
585 % %
586 % %
587 % %
588 % R a i s e I m a g e %
589 % %
590 % %
591 % %
592 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
593 %
594 % RaiseImage() creates a simulated three-dimensional button-like effect
595 % by lightening and darkening the edges of the image. Members width and
596 % height of raise_info define the width of the vertical and horizontal
597 % edge of the effect.
598 %
599 % The format of the RaiseImage method is:
600 %
601 % MagickBooleanType RaiseImage(const Image *image,
602 % const RectangleInfo *raise_info,const MagickBooleanType raise,
603 % ExceptionInfo *exception)
604 %
605 % A description of each parameter follows:
606 %
607 % o image: the image.
608 %
609 % o raise_info: Define the width and height of the raise area.
610 %
611 % o raise: A value other than zero creates a 3-D raise effect,
612 % otherwise it has a lowered effect.
613 %
614 % o exception: return any errors or warnings in this structure.
615 %
616 */
618  const RectangleInfo *raise_info,const MagickBooleanType raise,
619  ExceptionInfo *exception)
620 {
621 #define AccentuateFactor ScaleCharToQuantum(135)
622 #define HighlightFactor ScaleCharToQuantum(190)
623 #define ShadowFactor ScaleCharToQuantum(190)
624 #define RaiseImageTag "Raise/Image"
625 #define TroughFactor ScaleCharToQuantum(135)
626 
627  CacheView
628  *image_view;
629 
631  status;
632 
634  progress;
635 
636  Quantum
637  foreground,
638  background;
639 
640  ssize_t
641  y;
642 
643  assert(image != (Image *) NULL);
644  assert(image->signature == MagickCoreSignature);
645  if (image->debug != MagickFalse)
646  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
647  assert(raise_info != (RectangleInfo *) NULL);
648  if ((image->columns <= (raise_info->width << 1)) ||
649  (image->rows <= (raise_info->height << 1)))
650  ThrowBinaryException(OptionError,"ImageSizeMustExceedBevelWidth",
651  image->filename);
652  foreground=QuantumRange;
653  background=(Quantum) 0;
654  if (raise == MagickFalse)
655  {
656  foreground=(Quantum) 0;
657  background=QuantumRange;
658  }
659  if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
660  return(MagickFalse);
661  /*
662  Raise image.
663  */
664  status=MagickTrue;
665  progress=0;
666  image_view=AcquireAuthenticCacheView(image,exception);
667 #if defined(MAGICKCORE_OPENMP_SUPPORT)
668  #pragma omp parallel for schedule(static) shared(progress,status) \
669  magick_number_threads(image,image,raise_info->height,1)
670 #endif
671  for (y=0; y < (ssize_t) raise_info->height; y++)
672  {
673  ssize_t
674  i,
675  x;
676 
677  Quantum
678  *magick_restrict q;
679 
680  if (status == MagickFalse)
681  continue;
682  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
683  if (q == (Quantum *) NULL)
684  {
685  status=MagickFalse;
686  continue;
687  }
688  for (x=0; x < y; x++)
689  {
690  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
691  {
692  PixelChannel channel = GetPixelChannelChannel(image,i);
693  PixelTrait traits = GetPixelChannelTraits(image,channel);
694  if ((traits & UpdatePixelTrait) == 0)
695  continue;
696  q[i]=ClampToQuantum(QuantumScale*((double) q[i]*HighlightFactor+(double)
697  foreground*(QuantumRange-HighlightFactor)));
698  }
699  q+=GetPixelChannels(image);
700  }
701  for ( ; x < (ssize_t) (image->columns-y); x++)
702  {
703  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
704  {
705  PixelChannel channel = GetPixelChannelChannel(image,i);
706  PixelTrait traits = GetPixelChannelTraits(image,channel);
707  if ((traits & UpdatePixelTrait) == 0)
708  continue;
709  q[i]=ClampToQuantum(QuantumScale*((double) q[i]*AccentuateFactor+
710  (double) foreground*(QuantumRange-AccentuateFactor)));
711  }
712  q+=GetPixelChannels(image);
713  }
714  for ( ; x < (ssize_t) image->columns; x++)
715  {
716  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
717  {
718  PixelChannel channel = GetPixelChannelChannel(image,i);
719  PixelTrait traits = GetPixelChannelTraits(image,channel);
720  if ((traits & UpdatePixelTrait) == 0)
721  continue;
722  q[i]=ClampToQuantum(QuantumScale*((double) q[i]*ShadowFactor+(double)
723  background*(QuantumRange-ShadowFactor)));
724  }
725  q+=GetPixelChannels(image);
726  }
727  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
728  status=MagickFalse;
729  if (image->progress_monitor != (MagickProgressMonitor) NULL)
730  {
732  proceed;
733 
734 #if defined(MAGICKCORE_OPENMP_SUPPORT)
735  #pragma omp atomic
736 #endif
737  progress++;
738  proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
739  if (proceed == MagickFalse)
740  status=MagickFalse;
741  }
742  }
743 #if defined(MAGICKCORE_OPENMP_SUPPORT)
744  #pragma omp parallel for schedule(static) shared(progress,status) \
745  magick_number_threads(image,image,image->rows-2*raise_info->height,1)
746 #endif
747  for (y=(ssize_t) raise_info->height; y < (ssize_t) (image->rows-raise_info->height); y++)
748  {
749  ssize_t
750  i,
751  x;
752 
753  Quantum
754  *magick_restrict q;
755 
756  if (status == MagickFalse)
757  continue;
758  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
759  if (q == (Quantum *) NULL)
760  {
761  status=MagickFalse;
762  continue;
763  }
764  for (x=0; x < (ssize_t) raise_info->width; x++)
765  {
766  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
767  {
768  PixelChannel channel = GetPixelChannelChannel(image,i);
769  PixelTrait traits = GetPixelChannelTraits(image,channel);
770  if ((traits & UpdatePixelTrait) == 0)
771  continue;
772  q[i]=ClampToQuantum(QuantumScale*((double) q[i]*HighlightFactor+(double)
773  foreground*(QuantumRange-HighlightFactor)));
774  }
775  q+=GetPixelChannels(image);
776  }
777  for ( ; x < (ssize_t) (image->columns-raise_info->width); x++)
778  q+=GetPixelChannels(image);
779  for ( ; x < (ssize_t) image->columns; x++)
780  {
781  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
782  {
783  PixelChannel channel = GetPixelChannelChannel(image,i);
784  PixelTrait traits = GetPixelChannelTraits(image,channel);
785  if ((traits & UpdatePixelTrait) == 0)
786  continue;
787  q[i]=ClampToQuantum(QuantumScale*((double) q[i]*ShadowFactor+(double)
788  background*(QuantumRange-ShadowFactor)));
789  }
790  q+=GetPixelChannels(image);
791  }
792  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
793  status=MagickFalse;
794  if (image->progress_monitor != (MagickProgressMonitor) NULL)
795  {
797  proceed;
798 
799 #if defined(MAGICKCORE_OPENMP_SUPPORT)
800  #pragma omp atomic
801 #endif
802  progress++;
803  proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
804  if (proceed == MagickFalse)
805  status=MagickFalse;
806  }
807  }
808 #if defined(MAGICKCORE_OPENMP_SUPPORT)
809  #pragma omp parallel for schedule(static) shared(progress,status) \
810  magick_number_threads(image,image,image->rows-raise_info->height,1)
811 #endif
812  for (y=(ssize_t) (image->rows-raise_info->height); y < (ssize_t) image->rows; y++)
813  {
814  ssize_t
815  i,
816  x;
817 
818  Quantum
819  *magick_restrict q;
820 
821  if (status == MagickFalse)
822  continue;
823  q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
824  if (q == (Quantum *) NULL)
825  {
826  status=MagickFalse;
827  continue;
828  }
829  for (x=0; x < (ssize_t) (image->rows-y); x++)
830  {
831  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
832  {
833  PixelChannel channel = GetPixelChannelChannel(image,i);
834  PixelTrait traits = GetPixelChannelTraits(image,channel);
835  if ((traits & UpdatePixelTrait) == 0)
836  continue;
837  q[i]=ClampToQuantum(QuantumScale*((double) q[i]*HighlightFactor+(double)
838  foreground*(QuantumRange-HighlightFactor)));
839  }
840  q+=GetPixelChannels(image);
841  }
842  for ( ; x < (ssize_t) (image->columns-(image->rows-y)); x++)
843  {
844  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
845  {
846  PixelChannel channel = GetPixelChannelChannel(image,i);
847  PixelTrait traits = GetPixelChannelTraits(image,channel);
848  if ((traits & UpdatePixelTrait) == 0)
849  continue;
850  q[i]=ClampToQuantum(QuantumScale*((double) q[i]*TroughFactor+
851  (double) background*(QuantumRange-TroughFactor)));
852  }
853  q+=GetPixelChannels(image);
854  }
855  for ( ; x < (ssize_t) image->columns; x++)
856  {
857  for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
858  {
859  PixelChannel channel = GetPixelChannelChannel(image,i);
860  PixelTrait traits = GetPixelChannelTraits(image,channel);
861  if ((traits & UpdatePixelTrait) == 0)
862  continue;
863  q[i]=ClampToQuantum(QuantumScale*((double) q[i]*ShadowFactor+(double)
864  background*(QuantumRange-ShadowFactor)));
865  }
866  q+=GetPixelChannels(image);
867  }
868  if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
869  status=MagickFalse;
870  if (image->progress_monitor != (MagickProgressMonitor) NULL)
871  {
873  proceed;
874 
875 #if defined(MAGICKCORE_OPENMP_SUPPORT)
876  #pragma omp atomic
877 #endif
878  progress++;
879  proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
880  if (proceed == MagickFalse)
881  status=MagickFalse;
882  }
883  }
884  image_view=DestroyCacheView(image_view);
885  return(status);
886 }
size_t rows
Definition: image.h:172
#define magick_restrict
Definition: MagickCore.h:41
PixelInfo matte_color
Definition: image.h:357
MagickExport CacheView * DestroyCacheView(CacheView *cache_view)
Definition: cache-view.c:252
#define FrameImageTag
MagickExport Image * FrameImage(const Image *image, const FrameInfo *frame_info, const CompositeOperator compose, ExceptionInfo *exception)
Definition: decorate.c:169
MagickProgressMonitor progress_monitor
Definition: image.h:303
PixelTrait alpha_trait
Definition: pixel.h:181
#define RaiseImageTag
MagickExport MagickBooleanType RaiseImage(Image *image, const RectangleInfo *raise_info, const MagickBooleanType raise, ExceptionInfo *exception)
Definition: decorate.c:617
PixelInfo border_color
Definition: image.h:179
#define OpaqueAlpha
Definition: image.h:25
ssize_t outer_bevel
Definition: decorate.h:34
MagickRealType red
Definition: pixel.h:193
MagickExport MagickBooleanType SetImageAlpha(Image *image, const Quantum alpha, ExceptionInfo *exception)
Definition: image.c:2335
static PixelTrait GetPixelChannelTraits(const Image *magick_restrict image, const PixelChannel channel)
static void SetPixelViaPixelInfo(const Image *magick_restrict image, const PixelInfo *magick_restrict pixel_info, Quantum *magick_restrict pixel)
static MagickBooleanType IsGrayColorspace(const ColorspaceType colorspace)
#define ShadowFactor
MagickRealType alpha
Definition: pixel.h:193
MagickExport MagickBooleanType CompositeImage(Image *image, const Image *composite, const CompositeOperator compose, const MagickBooleanType clip_to_self, const ssize_t x_offset, const ssize_t y_offset, ExceptionInfo *exception)
Definition: composite.c:528
size_t width
Definition: geometry.h:131
#define ThrowBinaryException(severity, tag, context)
Definition: log.h:52
ssize_t MagickOffsetType
Definition: magick-type.h:133
static Quantum ClampToQuantum(const MagickRealType quantum)
Definition: quantum.h:85
Definition: image.h:151
#define AccentuateModulate
Definition: decorate.c:65
#define MagickCoreSignature
MagickExport Quantum * GetCacheViewAuthenticPixels(CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
Definition: cache-view.c:299
MagickBooleanType
Definition: magick-type.h:165
RectangleInfo page
Definition: image.h:212
ssize_t y
Definition: decorate.h:34
PixelTrait alpha_trait
Definition: image.h:280
MagickRealType blue
Definition: pixel.h:193
MagickExport Quantum * QueueCacheViewAuthenticPixels(CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
Definition: cache-view.c:977
#define TroughModulate
Definition: decorate.c:69
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1660
size_t signature
Definition: image.h:354
#define QuantumScale
Definition: magick-type.h:119
size_t columns
Definition: image.h:172
MagickBooleanType(* MagickProgressMonitor)(const char *, const MagickOffsetType, const MagickSizeType, void *)
Definition: monitor.h:26
size_t height
Definition: geometry.h:131
MagickExport MagickBooleanType SetImageStorageClass(Image *image, const ClassType storage_class, ExceptionInfo *exception)
Definition: image.c:2614
ssize_t x
Definition: decorate.h:34
PixelChannel
Definition: pixel.h:70
static size_t GetPixelChannels(const Image *magick_restrict image)
char filename[MagickPathExtent]
Definition: image.h:319
#define GetMagickModule()
Definition: log.h:28
#define ThrowImageException(severity, tag)
static PixelChannel GetPixelChannelChannel(const Image *magick_restrict image, const ssize_t offset)
MagickExport CacheView * AcquireVirtualCacheView(const Image *image, ExceptionInfo *exception)
Definition: cache-view.c:149
#define HighlightModulate
Definition: decorate.c:66
ssize_t inner_bevel
Definition: decorate.h:34
unsigned short Quantum
Definition: magick-type.h:86
static MagickBooleanType IsPixelInfoGray(const PixelInfo *magick_restrict pixel)
MagickExport Image * BorderImage(const Image *image, const RectangleInfo *border_info, const CompositeOperator compose, ExceptionInfo *exception)
Definition: decorate.c:103
MagickExport MagickBooleanType SetImageColorspace(Image *image, const ColorspaceType colorspace, ExceptionInfo *exception)
Definition: colorspace.c:1420
MagickRealType black
Definition: pixel.h:193
size_t height
Definition: decorate.h:30
size_t width
Definition: decorate.h:30
MagickRealType green
Definition: pixel.h:193
#define TroughFactor
#define AccentuateFactor
CompositeOperator
Definition: composite.h:25
#define MagickExport
MagickExport MagickBooleanType SyncCacheViewAuthenticPixels(CacheView *magick_restrict cache_view, ExceptionInfo *exception)
Definition: cache-view.c:1100
MagickExport CacheView * AcquireAuthenticCacheView(const Image *image, ExceptionInfo *exception)
Definition: cache-view.c:112
#define ShadowModulate
Definition: decorate.c:67
PixelTrait
Definition: pixel.h:137
MagickExport Image * DestroyImage(Image *image)
Definition: image.c:1177
MagickExport Image * CloneImage(const Image *image, const size_t columns, const size_t rows, const MagickBooleanType detach, ExceptionInfo *exception)
Definition: image.c:788
ColorspaceType colorspace
Definition: image.h:157
#define HighlightFactor
#define QuantumRange
Definition: magick-type.h:87
MagickExport MagickBooleanType SetImageProgress(const Image *image, const char *tag, const MagickOffsetType offset, const MagickSizeType extent)
Definition: monitor.c:136
MagickBooleanType debug
Definition: image.h:334