MagickCore 6.9.13
Loading...
Searching...
No Matches
decorate.c
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 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 "magick/studio.h"
44#include "magick/cache-view.h"
45#include "magick/channel.h"
46#include "magick/color-private.h"
47#include "magick/colorspace-private.h"
48#include "magick/composite.h"
49#include "magick/decorate.h"
50#include "magick/exception.h"
51#include "magick/exception-private.h"
52#include "magick/image.h"
53#include "magick/memory_.h"
54#include "magick/monitor.h"
55#include "magick/monitor-private.h"
56#include "magick/pixel-accessor.h"
57#include "magick/pixel-private.h"
58#include "magick/quantum.h"
59#include "magick/resource_.h"
60#include "magick/thread-private.h"
61#include "magick/transform.h"
62
63/*
64 Define declarations.
65*/
66#define AccentuateModulate ((MagickRealType) ScaleCharToQuantum(80))
67#define HighlightModulate ((MagickRealType) ScaleCharToQuantum(125))
68#define ShadowModulate ((MagickRealType) ScaleCharToQuantum(135))
69#define DepthModulate ((MagickRealType) ScaleCharToQuantum(185))
70#define TroughModulate ((MagickRealType) ScaleCharToQuantum(110))
71
72/*
73%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
74% %
75% %
76% %
77% B o r d e r I m a g e %
78% %
79% %
80% %
81%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82%
83% BorderImage() surrounds the image with a border of the color defined by
84% the bordercolor member of the image structure. The width and height
85% of the border are defined by the corresponding members of the border_info
86% structure.
87%
88% The format of the BorderImage method is:
89%
90% Image *BorderImage(const Image *image,const RectangleInfo *border_info,
91% ExceptionInfo *exception)
92%
93% A description of each parameter follows:
94%
95% o image: the image.
96%
97% o border_info: Define the width and height of the border.
98%
99% o exception: return any errors or warnings in this structure.
100%
101*/
102MagickExport Image *BorderImage(const Image *image,
103 const RectangleInfo *border_info,ExceptionInfo *exception)
104{
105 Image
106 *border_image,
107 *clone_image;
108
110 frame_info;
111
112 assert(image != (const Image *) NULL);
113 assert(image->signature == MagickCoreSignature);
114 assert(border_info != (RectangleInfo *) NULL);
115 if (IsEventLogging() != MagickFalse)
116 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
117 frame_info.width=image->columns+(border_info->width << 1);
118 frame_info.height=image->rows+(border_info->height << 1);
119 frame_info.x=(ssize_t) border_info->width;
120 frame_info.y=(ssize_t) border_info->height;
121 frame_info.inner_bevel=0;
122 frame_info.outer_bevel=0;
123 clone_image=CloneImage(image,0,0,MagickTrue,exception);
124 if (clone_image == (Image *) NULL)
125 return((Image *) NULL);
126 clone_image->matte_color=image->border_color;
127 border_image=FrameImage(clone_image,&frame_info,exception);
128 clone_image=DestroyImage(clone_image);
129 if (border_image != (Image *) NULL)
130 border_image->matte_color=image->matte_color;
131 return(border_image);
132}
133
134/*
135%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136% %
137% %
138% %
139% F r a m e I m a g e %
140% %
141% %
142% %
143%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
144%
145% FrameImage() adds a simulated three-dimensional border around the image.
146% The color of the border is defined by the matte_color member of image.
147% Members width and height of frame_info specify the border width of the
148% vertical and horizontal sides of the frame. Members inner and outer
149% indicate the width of the inner and outer shadows of the frame.
150%
151% The format of the FrameImage method is:
152%
153% Image *FrameImage(const Image *image,const FrameInfo *frame_info,
154% ExceptionInfo *exception)
155%
156% A description of each parameter follows:
157%
158% o image: the image.
159%
160% o frame_info: Define the width and height of the frame and its bevels.
161%
162% o exception: return any errors or warnings in this structure.
163%
164*/
165MagickExport Image *FrameImage(const Image *image,const FrameInfo *frame_info,
166 ExceptionInfo *exception)
167{
168#define FrameImageTag "Frame/Image"
169
171 *image_view,
172 *frame_view;
173
174 Image
175 *frame_image;
176
177 MagickBooleanType
178 status;
179
180 MagickOffsetType
181 progress;
182
184 accentuate,
185 border,
186 highlight,
187 matte,
188 shadow,
189 trough;
190
191 ssize_t
192 x;
193
194 size_t
195 bevel_width,
196 height,
197 width;
198
199 ssize_t
200 y;
201
202 /*
203 Check frame geometry.
204 */
205 assert(image != (Image *) NULL);
206 assert(image->signature == MagickCoreSignature);
207 assert(frame_info != (FrameInfo *) NULL);
208 if (IsEventLogging() != MagickFalse)
209 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
210 if ((frame_info->outer_bevel < 0) || (frame_info->inner_bevel < 0))
211 ThrowImageException(OptionError,"FrameIsLessThanImageSize");
212 bevel_width=(size_t) (frame_info->outer_bevel+frame_info->inner_bevel);
213 x=(ssize_t) frame_info->width-frame_info->x-bevel_width;
214 y=(ssize_t) frame_info->height-frame_info->y-bevel_width;
215 if ((x < (ssize_t) image->columns) || (y < (ssize_t) image->rows))
216 ThrowImageException(OptionError,"FrameIsLessThanImageSize");
217 /*
218 Initialize framed image attributes.
219 */
220 frame_image=CloneImage(image,frame_info->width,frame_info->height,MagickTrue,
221 exception);
222 if (frame_image == (Image *) NULL)
223 return((Image *) NULL);
224 if (SetImageStorageClass(frame_image,DirectClass) == MagickFalse)
225 {
226 InheritException(exception,&frame_image->exception);
227 frame_image=DestroyImage(frame_image);
228 return((Image *) NULL);
229 }
230 if ((IsPixelGray(&frame_image->border_color) == MagickFalse) &&
231 (IsGrayColorspace(frame_image->colorspace) != MagickFalse))
232 (void) SetImageColorspace(frame_image,sRGBColorspace);
233 if ((frame_image->border_color.opacity != OpaqueOpacity) &&
234 (frame_image->matte == MagickFalse))
235 (void) SetImageAlphaChannel(frame_image,OpaqueAlphaChannel);
236 frame_image->page=image->page;
237 if ((image->page.width != 0) && (image->page.height != 0))
238 {
239 frame_image->page.width+=frame_image->columns-image->columns;
240 frame_image->page.height+=frame_image->rows-image->rows;
241 }
242 /*
243 Initialize 3D effects color.
244 */
245 GetMagickPixelPacket(frame_image,&matte);
246 matte.colorspace=sRGBColorspace;
247 SetMagickPixelPacket(frame_image,&image->matte_color,(IndexPacket *) NULL,
248 &matte);
249 GetMagickPixelPacket(frame_image,&border);
250 border.colorspace=sRGBColorspace;
251 SetMagickPixelPacket(frame_image,&image->border_color,(IndexPacket *) NULL,
252 &border);
253 GetMagickPixelPacket(frame_image,&accentuate);
254 accentuate.red=(MagickRealType) (QuantumScale*(((MagickRealType)
255 QuantumRange-(MagickRealType) AccentuateModulate)*matte.red+
256 ((MagickRealType) QuantumRange*(MagickRealType) AccentuateModulate)));
257 accentuate.green=(MagickRealType) (QuantumScale*(((MagickRealType)
258 QuantumRange-(MagickRealType) AccentuateModulate)*matte.green+
259 ((MagickRealType) QuantumRange*(MagickRealType) AccentuateModulate)));
260 accentuate.blue=(MagickRealType) (QuantumScale*(((MagickRealType)
261 QuantumRange-(MagickRealType) AccentuateModulate)*matte.blue+
262 ((MagickRealType) QuantumRange*(MagickRealType) AccentuateModulate)));
263 accentuate.opacity=matte.opacity;
264 GetMagickPixelPacket(frame_image,&highlight);
265 highlight.red=(MagickRealType) (QuantumScale*(((MagickRealType)
266 QuantumRange-(MagickRealType) HighlightModulate)*matte.red+
267 ((MagickRealType) QuantumRange*(MagickRealType) HighlightModulate)));
268 highlight.green=(MagickRealType) (QuantumScale*(((MagickRealType)
269 QuantumRange-(MagickRealType) HighlightModulate)*matte.green+
270 ((MagickRealType) QuantumRange*(MagickRealType) HighlightModulate)));
271 highlight.blue=(MagickRealType) (QuantumScale*(((MagickRealType)
272 QuantumRange-(MagickRealType) HighlightModulate)*matte.blue+
273 ((MagickRealType) QuantumRange*(MagickRealType) HighlightModulate)));
274 highlight.opacity=matte.opacity;
275 GetMagickPixelPacket(frame_image,&shadow);
276 shadow.red=QuantumScale*matte.red*(MagickRealType) ShadowModulate;
277 shadow.green=QuantumScale*matte.green*(MagickRealType) ShadowModulate;
278 shadow.blue=QuantumScale*matte.blue*(MagickRealType) ShadowModulate;
279 shadow.opacity=matte.opacity;
280 GetMagickPixelPacket(frame_image,&trough);
281 trough.red=QuantumScale*matte.red*(MagickRealType) TroughModulate;
282 trough.green=QuantumScale*matte.green*(MagickRealType) TroughModulate;
283 trough.blue=QuantumScale*matte.blue*(MagickRealType) TroughModulate;
284 trough.opacity=matte.opacity;
285 if (image->colorspace == CMYKColorspace)
286 {
287 ConvertRGBToCMYK(&matte);
288 ConvertRGBToCMYK(&border);
289 ConvertRGBToCMYK(&accentuate);
290 ConvertRGBToCMYK(&highlight);
291 ConvertRGBToCMYK(&shadow);
292 ConvertRGBToCMYK(&trough);
293 }
294 status=MagickTrue;
295 progress=0;
296 image_view=AcquireVirtualCacheView(image,exception);
297 frame_view=AcquireAuthenticCacheView(frame_image,exception);
298 height=(size_t) (frame_info->outer_bevel+(frame_info->y-bevel_width)+
299 frame_info->inner_bevel);
300 if (height != 0)
301 {
302 IndexPacket
303 *magick_restrict frame_indexes;
304
305 ssize_t
306 x;
307
309 *magick_restrict q;
310
311 /*
312 Draw top of ornamental border.
313 */
314 q=QueueCacheViewAuthenticPixels(frame_view,0,0,frame_image->columns,
315 height,exception);
316 frame_indexes=GetCacheViewAuthenticIndexQueue(frame_view);
317 if (q != (PixelPacket *) NULL)
318 {
319 /*
320 Draw top of ornamental border.
321 */
322 for (y=0; y < (ssize_t) frame_info->outer_bevel; y++)
323 {
324 for (x=0; x < (ssize_t) (frame_image->columns-y); x++)
325 {
326 if (x < y)
327 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
328 else
329 SetPixelPacket(frame_image,&accentuate,q,frame_indexes);
330 q++;
331 frame_indexes++;
332 }
333 for ( ; x < (ssize_t) frame_image->columns; x++)
334 {
335 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
336 q++;
337 frame_indexes++;
338 }
339 }
340 for (y=0; y < (ssize_t) (frame_info->y-bevel_width); y++)
341 {
342 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
343 {
344 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
345 q++;
346 frame_indexes++;
347 }
348 width=frame_image->columns-2*frame_info->outer_bevel;
349 for (x=0; x < (ssize_t) width; x++)
350 {
351 SetPixelPacket(frame_image,&matte,q,frame_indexes);
352 q++;
353 frame_indexes++;
354 }
355 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
356 {
357 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
358 q++;
359 frame_indexes++;
360 }
361 }
362 for (y=0; y < (ssize_t) frame_info->inner_bevel; y++)
363 {
364 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
365 {
366 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
367 q++;
368 frame_indexes++;
369 }
370 for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
371 {
372 SetPixelPacket(frame_image,&matte,q,frame_indexes);
373 q++;
374 frame_indexes++;
375 }
376 width=image->columns+((size_t) frame_info->inner_bevel << 1)-
377 y;
378 for (x=0; x < (ssize_t) width; x++)
379 {
380 if (x < y)
381 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
382 else
383 SetPixelPacket(frame_image,&trough,q,frame_indexes);
384 q++;
385 frame_indexes++;
386 }
387 for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++)
388 {
389 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
390 q++;
391 frame_indexes++;
392 }
393 width=frame_info->width-frame_info->x-image->columns-bevel_width;
394 for (x=0; x < (ssize_t) width; x++)
395 {
396 SetPixelPacket(frame_image,&matte,q,frame_indexes);
397 q++;
398 frame_indexes++;
399 }
400 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
401 {
402 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
403 q++;
404 frame_indexes++;
405 }
406 }
407 (void) SyncCacheViewAuthenticPixels(frame_view,exception);
408 }
409 }
410 /*
411 Draw sides of ornamental border.
412 */
413#if defined(MAGICKCORE_OPENMP_SUPPORT)
414 #pragma omp parallel for schedule(static) shared(status) \
415 magick_number_threads(image,frame_image,image->rows,1)
416#endif
417 for (y=0; y < (ssize_t) image->rows; y++)
418 {
419 IndexPacket
420 *magick_restrict frame_indexes;
421
422 ssize_t
423 x;
424
426 *magick_restrict q;
427
428 /*
429 Initialize scanline with matte color.
430 */
431 if (status == MagickFalse)
432 continue;
433 q=QueueCacheViewAuthenticPixels(frame_view,0,frame_info->y+y,
434 frame_image->columns,1,exception);
435 if (q == (PixelPacket *) NULL)
436 {
437 status=MagickFalse;
438 continue;
439 }
440 frame_indexes=GetCacheViewAuthenticIndexQueue(frame_view);
441 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
442 {
443 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
444 q++;
445 frame_indexes++;
446 }
447 for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
448 {
449 SetPixelPacket(frame_image,&matte,q,frame_indexes);
450 q++;
451 frame_indexes++;
452 }
453 for (x=0; x < (ssize_t) frame_info->inner_bevel; x++)
454 {
455 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
456 q++;
457 frame_indexes++;
458 }
459 /*
460 Set frame interior pixels.
461 */
462 for (x=0; x < (ssize_t) image->columns; x++)
463 {
464 SetPixelPacket(frame_image,&border,q,frame_indexes);
465 q++;
466 frame_indexes++;
467 }
468 for (x=0; x < (ssize_t) frame_info->inner_bevel; x++)
469 {
470 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
471 q++;
472 frame_indexes++;
473 }
474 width=frame_info->width-frame_info->x-image->columns-bevel_width;
475 for (x=0; x < (ssize_t) width; x++)
476 {
477 SetPixelPacket(frame_image,&matte,q,frame_indexes);
478 q++;
479 frame_indexes++;
480 }
481 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
482 {
483 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
484 q++;
485 frame_indexes++;
486 }
487 if (SyncCacheViewAuthenticPixels(frame_view,exception) == MagickFalse)
488 status=MagickFalse;
489 if (image->progress_monitor != (MagickProgressMonitor) NULL)
490 {
491 MagickBooleanType
492 proceed;
493
494#if defined(MAGICKCORE_OPENMP_SUPPORT)
495 #pragma omp atomic
496#endif
497 progress++;
498 proceed=SetImageProgress(image,FrameImageTag,progress,image->rows);
499 if (proceed == MagickFalse)
500 status=MagickFalse;
501 }
502 }
503 height=(size_t) (frame_info->inner_bevel+frame_info->height-
504 frame_info->y-image->rows-bevel_width+frame_info->outer_bevel);
505 if (height != 0)
506 {
507 IndexPacket
508 *magick_restrict frame_indexes;
509
510 ssize_t
511 x;
512
514 *magick_restrict q;
515
516 /*
517 Draw bottom of ornamental border.
518 */
519 q=QueueCacheViewAuthenticPixels(frame_view,0,(ssize_t) (frame_image->rows-
520 height),frame_image->columns,height,exception);
521 if (q != (PixelPacket *) NULL)
522 {
523 /*
524 Draw bottom of ornamental border.
525 */
526 frame_indexes=GetCacheViewAuthenticIndexQueue(frame_view);
527 for (y=frame_info->inner_bevel-1; y >= 0; y--)
528 {
529 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
530 {
531 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
532 q++;
533 frame_indexes++;
534 }
535 for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
536 {
537 SetPixelPacket(frame_image,&matte,q,frame_indexes);
538 q++;
539 frame_indexes++;
540 }
541 for (x=0; x < y; x++)
542 {
543 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
544 q++;
545 frame_indexes++;
546 }
547 for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++)
548 {
549 if (x >= (ssize_t) (image->columns+2*frame_info->inner_bevel-y))
550 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
551 else
552 SetPixelPacket(frame_image,&accentuate,q,frame_indexes);
553 q++;
554 frame_indexes++;
555 }
556 width=frame_info->width-frame_info->x-image->columns-bevel_width;
557 for (x=0; x < (ssize_t) width; x++)
558 {
559 SetPixelPacket(frame_image,&matte,q,frame_indexes);
560 q++;
561 frame_indexes++;
562 }
563 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
564 {
565 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
566 q++;
567 frame_indexes++;
568 }
569 }
570 height=frame_info->height-frame_info->y-image->rows-bevel_width;
571 for (y=0; y < (ssize_t) height; y++)
572 {
573 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
574 {
575 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
576 q++;
577 frame_indexes++;
578 }
579 width=frame_image->columns-2*frame_info->outer_bevel;
580 for (x=0; x < (ssize_t) width; x++)
581 {
582 SetPixelPacket(frame_image,&matte,q,frame_indexes);
583 q++;
584 frame_indexes++;
585 }
586 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
587 {
588 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
589 q++;
590 frame_indexes++;
591 }
592 }
593 for (y=frame_info->outer_bevel-1; y >= 0; y--)
594 {
595 for (x=0; x < y; x++)
596 {
597 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
598 q++;
599 frame_indexes++;
600 }
601 for ( ; x < (ssize_t) frame_image->columns; x++)
602 {
603 if (x >= (ssize_t) (frame_image->columns-y))
604 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
605 else
606 SetPixelPacket(frame_image,&trough,q,frame_indexes);
607 q++;
608 frame_indexes++;
609 }
610 }
611 (void) SyncCacheViewAuthenticPixels(frame_view,exception);
612 }
613 }
614 frame_view=DestroyCacheView(frame_view);
615 image_view=DestroyCacheView(image_view);
616 x=(ssize_t) (frame_info->outer_bevel+(frame_info->x-bevel_width)+
617 frame_info->inner_bevel);
618 y=(ssize_t) (frame_info->outer_bevel+(frame_info->y-bevel_width)+
619 frame_info->inner_bevel);
620 if (status != MagickFalse)
621 status=CompositeImage(frame_image,image->compose,image,x,y);
622 if (status == MagickFalse)
623 frame_image=DestroyImage(frame_image);
624 return(frame_image);
625}
626
627/*
628%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629% %
630% %
631% %
632% R a i s e I m a g e %
633% %
634% %
635% %
636%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
637%
638% RaiseImage() creates a simulated three-dimensional button-like effect
639% by lightening and darkening the edges of the image. Members width and
640% height of raise_info define the width of the vertical and horizontal
641% edge of the effect.
642%
643% The format of the RaiseImage method is:
644%
645% MagickBooleanType RaiseImage(const Image *image,
646% const RectangleInfo *raise_info,const MagickBooleanType raise)
647%
648% A description of each parameter follows:
649%
650% o image: the image.
651%
652% o raise_info: Define the width and height of the raise area.
653%
654% o raise: A value other than zero creates a 3-D raise effect,
655% otherwise it has a lowered effect.
656%
657*/
658MagickExport MagickBooleanType RaiseImage(Image *image,
659 const RectangleInfo *raise_info,const MagickBooleanType raise)
660{
661#define AccentuateFactor ((MagickRealType) ScaleCharToQuantum(135))
662#define HighlightFactor ((MagickRealType) ScaleCharToQuantum(190))
663#define ShadowFactor ((MagickRealType) ScaleCharToQuantum(190))
664#define RaiseImageTag "Raise/Image"
665#define TroughFactor ((MagickRealType) ScaleCharToQuantum(135))
666
668 *image_view;
669
671 *exception;
672
673 MagickBooleanType
674 status;
675
676 MagickOffsetType
677 progress;
678
679 Quantum
680 foreground,
681 background;
682
683 ssize_t
684 y;
685
686 assert(image != (Image *) NULL);
687 assert(image->signature == MagickCoreSignature);
688 assert(raise_info != (RectangleInfo *) NULL);
689 if (IsEventLogging() != MagickFalse)
690 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
691 exception=(&image->exception);
692 if ((image->columns <= (raise_info->width << 1)) ||
693 (image->rows <= (raise_info->height << 1)))
694 ThrowBinaryException(OptionError,"ImageSizeMustExceedBevelWidth",
695 image->filename);
696 foreground=QuantumRange;
697 background=(Quantum) 0;
698 if (raise == MagickFalse)
699 {
700 foreground=(Quantum) 0;
701 background=QuantumRange;
702 }
703 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
704 return(MagickFalse);
705 /*
706 Raise image.
707 */
708 status=MagickTrue;
709 progress=0;
710 image_view=AcquireAuthenticCacheView(image,exception);
711#if defined(MAGICKCORE_OPENMP_SUPPORT)
712 #pragma omp parallel for schedule(static) shared(status) \
713 magick_number_threads(image,image,raise_info->height,1)
714#endif
715 for (y=0; y < (ssize_t) raise_info->height; y++)
716 {
717 ssize_t
718 x;
719
721 *magick_restrict q;
722
723 if (status == MagickFalse)
724 continue;
725 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
726 if (q == (PixelPacket *) NULL)
727 {
728 status=MagickFalse;
729 continue;
730 }
731 for (x=0; x < y; x++)
732 {
733 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
734 GetPixelRed(q)*HighlightFactor+(MagickRealType) foreground*
735 ((MagickRealType) QuantumRange-HighlightFactor))));
736 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
737 GetPixelGreen(q)*HighlightFactor+(MagickRealType) foreground*
738 ((MagickRealType) QuantumRange-HighlightFactor))));
739 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
740 GetPixelBlue(q)*HighlightFactor+(MagickRealType) foreground*
741 ((MagickRealType) QuantumRange-HighlightFactor))));
742 q++;
743 }
744 for ( ; x < (ssize_t) (image->columns-y); x++)
745 {
746 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
747 GetPixelRed(q)*AccentuateFactor+(MagickRealType) foreground*
748 ((MagickRealType) QuantumRange-AccentuateFactor))));
749 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
750 GetPixelGreen(q)*AccentuateFactor+(MagickRealType) foreground*
751 ((MagickRealType) QuantumRange-AccentuateFactor))));
752 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
753 GetPixelBlue(q)*AccentuateFactor+(MagickRealType) foreground*
754 ((MagickRealType) QuantumRange-AccentuateFactor))));
755 q++;
756 }
757 for ( ; x < (ssize_t) image->columns; x++)
758 {
759 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
760 GetPixelRed(q)*ShadowFactor+(MagickRealType) background*
761 ((MagickRealType) QuantumRange-ShadowFactor))));
762 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
763 GetPixelGreen(q)*ShadowFactor+(MagickRealType) background*
764 ((MagickRealType) QuantumRange-ShadowFactor))));
765 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
766 GetPixelBlue(q)*ShadowFactor+(MagickRealType) background*
767 ((MagickRealType) QuantumRange-ShadowFactor))));
768 q++;
769 }
770 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
771 status=MagickFalse;
772 if (image->progress_monitor != (MagickProgressMonitor) NULL)
773 {
774 MagickBooleanType
775 proceed;
776
777#if defined(MAGICKCORE_OPENMP_SUPPORT)
778 #pragma omp atomic
779#endif
780 progress++;
781 proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
782 if (proceed == MagickFalse)
783 status=MagickFalse;
784 }
785 }
786#if defined(MAGICKCORE_OPENMP_SUPPORT)
787 #pragma omp parallel for schedule(static) shared(status) \
788 magick_number_threads(image,image,image->rows-2*raise_info->height,1)
789#endif
790 for (y=(ssize_t) raise_info->height; y < (ssize_t) (image->rows-raise_info->height); y++)
791 {
792 ssize_t
793 x;
794
796 *magick_restrict q;
797
798 if (status == MagickFalse)
799 continue;
800 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
801 if (q == (PixelPacket *) NULL)
802 {
803 status=MagickFalse;
804 continue;
805 }
806 for (x=0; x < (ssize_t) raise_info->width; x++)
807 {
808 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
809 GetPixelRed(q)*HighlightFactor+(MagickRealType) foreground*
810 ((MagickRealType) QuantumRange-HighlightFactor))));
811 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
812 GetPixelGreen(q)*HighlightFactor+(MagickRealType) foreground*
813 ((MagickRealType) QuantumRange-HighlightFactor))));
814 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
815 GetPixelBlue(q)*HighlightFactor+(MagickRealType) foreground*
816 ((MagickRealType) QuantumRange-HighlightFactor))));
817 q++;
818 }
819 for ( ; x < (ssize_t) (image->columns-raise_info->width); x++)
820 q++;
821 for ( ; x < (ssize_t) image->columns; x++)
822 {
823 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
824 GetPixelRed(q)*ShadowFactor+(MagickRealType) background*
825 ((MagickRealType) QuantumRange-ShadowFactor))));
826 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
827 GetPixelGreen(q)*ShadowFactor+(MagickRealType) background*
828 ((MagickRealType) QuantumRange-ShadowFactor))));
829 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
830 GetPixelBlue(q)*ShadowFactor+(MagickRealType) background*
831 ((MagickRealType) QuantumRange-ShadowFactor))));
832 q++;
833 }
834 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
835 status=MagickFalse;
836 if (image->progress_monitor != (MagickProgressMonitor) NULL)
837 {
838 MagickBooleanType
839 proceed;
840
841#if defined(MAGICKCORE_OPENMP_SUPPORT)
842 #pragma omp atomic
843#endif
844 progress++;
845 proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
846 if (proceed == MagickFalse)
847 status=MagickFalse;
848 }
849 }
850#if defined(MAGICKCORE_OPENMP_SUPPORT)
851 #pragma omp parallel for schedule(static) shared(status) \
852 magick_number_threads(image,image,image->rows-raise_info->height,1)
853#endif
854 for (y=(ssize_t) (image->rows-raise_info->height); y < (ssize_t) image->rows; y++)
855 {
856 ssize_t
857 x;
858
860 *magick_restrict q;
861
862 if (status == MagickFalse)
863 continue;
864 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
865 if (q == (PixelPacket *) NULL)
866 {
867 status=MagickFalse;
868 continue;
869 }
870 for (x=0; x < (ssize_t) (image->rows-y); x++)
871 {
872 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
873 GetPixelRed(q)*HighlightFactor+(MagickRealType) foreground*
874 ((MagickRealType) QuantumRange-HighlightFactor))));
875 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
876 GetPixelGreen(q)*HighlightFactor+(MagickRealType) foreground*
877 ((MagickRealType) QuantumRange-HighlightFactor))));
878 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
879 GetPixelBlue(q)*HighlightFactor+(MagickRealType) foreground*
880 ((MagickRealType) QuantumRange-HighlightFactor))));
881 q++;
882 }
883 for ( ; x < (ssize_t) (image->columns-(image->rows-y)); x++)
884 {
885 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
886 GetPixelRed(q)*TroughFactor+(MagickRealType) background*
887 ((MagickRealType) QuantumRange-TroughFactor))));
888 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
889 GetPixelGreen(q)*TroughFactor+(MagickRealType) background*
890 ((MagickRealType) QuantumRange-TroughFactor))));
891 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
892 GetPixelBlue(q)*TroughFactor+(MagickRealType) background*
893 ((MagickRealType) QuantumRange-TroughFactor))));
894 q++;
895 }
896 for ( ; x < (ssize_t) image->columns; x++)
897 {
898 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
899 GetPixelRed(q)*ShadowFactor+(MagickRealType) background*
900 ((MagickRealType) QuantumRange-ShadowFactor))));
901 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
902 GetPixelGreen(q)*ShadowFactor+(MagickRealType) background*
903 ((MagickRealType) QuantumRange-ShadowFactor))));
904 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
905 GetPixelBlue(q)*ShadowFactor+(MagickRealType) background*
906 ((MagickRealType) QuantumRange-ShadowFactor))));
907 q++;
908 }
909 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
910 status=MagickFalse;
911 if (image->progress_monitor != (MagickProgressMonitor) NULL)
912 {
913 MagickBooleanType
914 proceed;
915
916#if defined(MAGICKCORE_OPENMP_SUPPORT)
917 #pragma omp atomic
918#endif
919 progress++;
920 proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
921 if (proceed == MagickFalse)
922 status=MagickFalse;
923 }
924 }
925 image_view=DestroyCacheView(image_view);
926 return(status);
927}