43 #include "MagickCore/studio.h"
44 #include "MagickCore/cache-view.h"
45 #include "MagickCore/color-private.h"
46 #include "MagickCore/colorspace-private.h"
47 #include "MagickCore/composite.h"
48 #include "MagickCore/decorate.h"
49 #include "MagickCore/exception.h"
50 #include "MagickCore/exception-private.h"
51 #include "MagickCore/image.h"
52 #include "MagickCore/memory_.h"
53 #include "MagickCore/monitor.h"
54 #include "MagickCore/monitor-private.h"
55 #include "MagickCore/pixel-accessor.h"
56 #include "MagickCore/quantum.h"
57 #include "MagickCore/quantum-private.h"
58 #include "MagickCore/resource_.h"
59 #include "MagickCore/thread-private.h"
60 #include "MagickCore/transform.h"
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)
103 MagickExport
Image *BorderImage(
const Image *image,
104 const RectangleInfo *border_info,
const CompositeOperator compose,
114 assert(image != (
const Image *) NULL);
115 assert(image->signature == MagickCoreSignature);
117 if (IsEventLogging() != MagickFalse)
118 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
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);
172 #define FrameImageTag "Frame/Image"
208 assert(image != (
Image *) NULL);
209 assert(image->signature == MagickCoreSignature);
210 assert(frame_info != (
FrameInfo *) NULL);
211 if (IsEventLogging() != MagickFalse)
212 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
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");
224 frame_image=CloneImage(image,frame_info->width,frame_info->height,MagickTrue,
226 if (frame_image == (
Image *) NULL)
227 return((
Image *) NULL);
228 if (SetImageStorageClass(frame_image,DirectClass,exception) == MagickFalse)
230 frame_image=DestroyImage(frame_image);
231 return((
Image *) NULL);
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))
242 frame_image->page.width+=frame_image->columns-image->columns;
243 frame_image->page.height+=frame_image->rows-image->rows;
248 matte=image->matte_color;
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;
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;
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;
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;
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);
301 q=QueueCacheViewAuthenticPixels(frame_view,0,0,frame_image->columns,
303 if (q != (Quantum *) NULL)
308 for (y=0; y < (ssize_t) frame_info->outer_bevel; y++)
310 for (x=0; x < (ssize_t) (frame_image->columns-y); x++)
313 SetPixelViaPixelInfo(frame_image,&highlight,q);
315 SetPixelViaPixelInfo(frame_image,&accentuate,q);
316 q+=GetPixelChannels(frame_image);
318 for ( ; x < (ssize_t) frame_image->columns; x++)
320 SetPixelViaPixelInfo(frame_image,&shadow,q);
321 q+=GetPixelChannels(frame_image);
324 for (y=0; y < (ssize_t) (frame_info->y-bevel_width); y++)
326 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
328 SetPixelViaPixelInfo(frame_image,&highlight,q);
329 q+=GetPixelChannels(frame_image);
331 width=frame_image->columns-2*frame_info->outer_bevel;
332 for (x=0; x < (ssize_t) width; x++)
334 SetPixelViaPixelInfo(frame_image,&matte,q);
335 q+=GetPixelChannels(frame_image);
337 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
339 SetPixelViaPixelInfo(frame_image,&shadow,q);
340 q+=GetPixelChannels(frame_image);
343 for (y=0; y < (ssize_t) frame_info->inner_bevel; y++)
345 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
347 SetPixelViaPixelInfo(frame_image,&highlight,q);
348 q+=GetPixelChannels(frame_image);
350 for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
352 SetPixelViaPixelInfo(frame_image,&matte,q);
353 q+=GetPixelChannels(frame_image);
355 width=image->columns+((size_t) frame_info->inner_bevel << 1)-
357 for (x=0; x < (ssize_t) width; x++)
360 SetPixelViaPixelInfo(frame_image,&shadow,q);
362 SetPixelViaPixelInfo(frame_image,&trough,q);
363 q+=GetPixelChannels(frame_image);
365 for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++)
367 SetPixelViaPixelInfo(frame_image,&highlight,q);
368 q+=GetPixelChannels(frame_image);
370 width=frame_info->width-frame_info->x-image->columns-bevel_width;
371 for (x=0; x < (ssize_t) width; x++)
373 SetPixelViaPixelInfo(frame_image,&matte,q);
374 q+=GetPixelChannels(frame_image);
376 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
378 SetPixelViaPixelInfo(frame_image,&shadow,q);
379 q+=GetPixelChannels(frame_image);
382 (void) SyncCacheViewAuthenticPixels(frame_view,exception);
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)
392 for (y=0; y < (ssize_t) image->rows; y++)
406 if (status == MagickFalse)
408 q=QueueCacheViewAuthenticPixels(frame_view,0,frame_info->y+y,
409 frame_image->columns,1,exception);
410 if (q == (Quantum *) NULL)
415 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
417 SetPixelViaPixelInfo(frame_image,&highlight,q);
418 q+=GetPixelChannels(frame_image);
420 for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
422 SetPixelViaPixelInfo(frame_image,&matte,q);
423 q+=GetPixelChannels(frame_image);
425 for (x=0; x < (ssize_t) frame_info->inner_bevel; x++)
427 SetPixelViaPixelInfo(frame_image,&shadow,q);
428 q+=GetPixelChannels(frame_image);
433 for (x=0; x < (ssize_t) image->columns; x++)
435 SetPixelViaPixelInfo(frame_image,&frame_image->border_color,q);
436 q+=GetPixelChannels(frame_image);
438 for (x=0; x < (ssize_t) frame_info->inner_bevel; x++)
440 SetPixelViaPixelInfo(frame_image,&highlight,q);
441 q+=GetPixelChannels(frame_image);
443 width=frame_info->width-frame_info->x-image->columns-bevel_width;
444 for (x=0; x < (ssize_t) width; x++)
446 SetPixelViaPixelInfo(frame_image,&matte,q);
447 q+=GetPixelChannels(frame_image);
449 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
451 SetPixelViaPixelInfo(frame_image,&shadow,q);
452 q+=GetPixelChannels(frame_image);
454 if (SyncCacheViewAuthenticPixels(frame_view,exception) == MagickFalse)
456 if (image->progress_monitor != (MagickProgressMonitor) NULL)
461 #if defined(MAGICKCORE_OPENMP_SUPPORT)
465 proceed=SetImageProgress(image,FrameImageTag,progress,image->rows);
466 if (proceed == MagickFalse)
470 height=(size_t) (frame_info->inner_bevel+frame_info->height-
471 frame_info->y-image->rows-bevel_width+frame_info->outer_bevel);
486 q=QueueCacheViewAuthenticPixels(frame_view,0,(ssize_t) (frame_image->rows-
487 height),frame_image->columns,height,exception);
488 if (q != (Quantum *) NULL)
493 for (y=frame_info->inner_bevel-1; y >= 0; y--)
495 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
497 SetPixelViaPixelInfo(frame_image,&highlight,q);
498 q+=GetPixelChannels(frame_image);
500 for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
502 SetPixelViaPixelInfo(frame_image,&matte,q);
503 q+=GetPixelChannels(frame_image);
505 for (x=0; x < y; x++)
507 SetPixelViaPixelInfo(frame_image,&shadow,q);
508 q+=GetPixelChannels(frame_image);
510 for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++)
512 if (x >= (ssize_t) (image->columns+2*frame_info->inner_bevel-y))
513 SetPixelViaPixelInfo(frame_image,&highlight,q);
515 SetPixelViaPixelInfo(frame_image,&accentuate,q);
516 q+=GetPixelChannels(frame_image);
518 width=frame_info->width-frame_info->x-image->columns-bevel_width;
519 for (x=0; x < (ssize_t) width; x++)
521 SetPixelViaPixelInfo(frame_image,&matte,q);
522 q+=GetPixelChannels(frame_image);
524 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
526 SetPixelViaPixelInfo(frame_image,&shadow,q);
527 q+=GetPixelChannels(frame_image);
530 height=frame_info->height-frame_info->y-image->rows-bevel_width;
531 for (y=0; y < (ssize_t) height; y++)
533 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
535 SetPixelViaPixelInfo(frame_image,&highlight,q);
536 q+=GetPixelChannels(frame_image);
538 width=frame_image->columns-2*frame_info->outer_bevel;
539 for (x=0; x < (ssize_t) width; x++)
541 SetPixelViaPixelInfo(frame_image,&matte,q);
542 q+=GetPixelChannels(frame_image);
544 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
546 SetPixelViaPixelInfo(frame_image,&shadow,q);
547 q+=GetPixelChannels(frame_image);
550 for (y=frame_info->outer_bevel-1; y >= 0; y--)
552 for (x=0; x < y; x++)
554 SetPixelViaPixelInfo(frame_image,&highlight,q);
555 q+=GetPixelChannels(frame_image);
557 for ( ; x < (ssize_t) frame_image->columns; x++)
559 if (x >= (ssize_t) (frame_image->columns-y))
560 SetPixelViaPixelInfo(frame_image,&shadow,q);
562 SetPixelViaPixelInfo(frame_image,&trough,q);
563 q+=GetPixelChannels(frame_image);
566 (void) SyncCacheViewAuthenticPixels(frame_view,exception);
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,
578 if (status == MagickFalse)
579 frame_image=DestroyImage(frame_image);
617 MagickExport MagickBooleanType RaiseImage(
Image *image,
618 const RectangleInfo *raise_info,
const MagickBooleanType
raise,
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)
643 assert(image != (
Image *) NULL);
644 assert(image->signature == MagickCoreSignature);
646 if (IsEventLogging() != MagickFalse)
647 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
648 if ((image->columns <= (raise_info->width << 1)) ||
649 (image->rows <= (raise_info->height << 1)))
650 ThrowBinaryException(OptionError,
"ImageSizeMustExceedBevelWidth",
652 foreground=QuantumRange;
653 background=(Quantum) 0;
654 if (
raise == MagickFalse)
656 foreground=(Quantum) 0;
657 background=QuantumRange;
659 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
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)
671 for (y=0; y < (ssize_t) raise_info->height; y++)
680 if (status == MagickFalse)
682 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
683 if (q == (Quantum *) NULL)
688 for (x=0; x < y; x++)
690 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
692 PixelChannel channel = GetPixelChannelChannel(image,i);
693 PixelTrait traits = GetPixelChannelTraits(image,channel);
694 if ((traits & UpdatePixelTrait) == 0)
696 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*HighlightFactor+(
double)
697 foreground*(QuantumRange-HighlightFactor)));
699 q+=GetPixelChannels(image);
701 for ( ; x < (ssize_t) (image->columns-y); x++)
703 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
705 PixelChannel channel = GetPixelChannelChannel(image,i);
706 PixelTrait traits = GetPixelChannelTraits(image,channel);
707 if ((traits & UpdatePixelTrait) == 0)
709 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*AccentuateFactor+
710 (
double) foreground*(QuantumRange-AccentuateFactor)));
712 q+=GetPixelChannels(image);
714 for ( ; x < (ssize_t) image->columns; x++)
716 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
718 PixelChannel channel = GetPixelChannelChannel(image,i);
719 PixelTrait traits = GetPixelChannelTraits(image,channel);
720 if ((traits & UpdatePixelTrait) == 0)
722 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*ShadowFactor+(
double)
723 background*(QuantumRange-ShadowFactor)));
725 q+=GetPixelChannels(image);
727 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
729 if (image->progress_monitor != (MagickProgressMonitor) NULL)
734 #if defined(MAGICKCORE_OPENMP_SUPPORT)
738 proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
739 if (proceed == MagickFalse)
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)
747 for (y=(ssize_t) raise_info->height; y < (ssize_t) (image->rows-raise_info->height); y++)
756 if (status == MagickFalse)
758 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
759 if (q == (Quantum *) NULL)
764 for (x=0; x < (ssize_t) raise_info->width; x++)
766 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
768 PixelChannel channel = GetPixelChannelChannel(image,i);
769 PixelTrait traits = GetPixelChannelTraits(image,channel);
770 if ((traits & UpdatePixelTrait) == 0)
772 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*HighlightFactor+(
double)
773 foreground*(QuantumRange-HighlightFactor)));
775 q+=GetPixelChannels(image);
777 for ( ; x < (ssize_t) (image->columns-raise_info->width); x++)
778 q+=GetPixelChannels(image);
779 for ( ; x < (ssize_t) image->columns; x++)
781 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
783 PixelChannel channel = GetPixelChannelChannel(image,i);
784 PixelTrait traits = GetPixelChannelTraits(image,channel);
785 if ((traits & UpdatePixelTrait) == 0)
787 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*ShadowFactor+(
double)
788 background*(QuantumRange-ShadowFactor)));
790 q+=GetPixelChannels(image);
792 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
794 if (image->progress_monitor != (MagickProgressMonitor) NULL)
799 #if defined(MAGICKCORE_OPENMP_SUPPORT)
803 proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
804 if (proceed == MagickFalse)
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)
812 for (y=(ssize_t) (image->rows-raise_info->height); y < (ssize_t) image->rows; y++)
821 if (status == MagickFalse)
823 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
824 if (q == (Quantum *) NULL)
829 for (x=0; x < (ssize_t) (image->rows-y); x++)
831 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
833 PixelChannel channel = GetPixelChannelChannel(image,i);
834 PixelTrait traits = GetPixelChannelTraits(image,channel);
835 if ((traits & UpdatePixelTrait) == 0)
837 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*HighlightFactor+(
double)
838 foreground*(QuantumRange-HighlightFactor)));
840 q+=GetPixelChannels(image);
842 for ( ; x < (ssize_t) (image->columns-(image->rows-y)); x++)
844 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
846 PixelChannel channel = GetPixelChannelChannel(image,i);
847 PixelTrait traits = GetPixelChannelTraits(image,channel);
848 if ((traits & UpdatePixelTrait) == 0)
850 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*TroughFactor+
851 (
double) background*(QuantumRange-TroughFactor)));
853 q+=GetPixelChannels(image);
855 for ( ; x < (ssize_t) image->columns; x++)
857 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
859 PixelChannel channel = GetPixelChannelChannel(image,i);
860 PixelTrait traits = GetPixelChannelTraits(image,channel);
861 if ((traits & UpdatePixelTrait) == 0)
863 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*ShadowFactor+(
double)
864 background*(QuantumRange-ShadowFactor)));
866 q+=GetPixelChannels(image);
868 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
870 if (image->progress_monitor != (MagickProgressMonitor) NULL)
875 #if defined(MAGICKCORE_OPENMP_SUPPORT)
879 proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
880 if (proceed == MagickFalse)
884 image_view=DestroyCacheView(image_view);