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)
103MagickExport
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"
206 assert(image != (
Image *) NULL);
207 assert(image->signature == MagickCoreSignature);
208 assert(frame_info != (
FrameInfo *) NULL);
209 if (IsEventLogging() != MagickFalse)
210 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
211 if ((frame_info->outer_bevel < 0) || (frame_info->inner_bevel < 0))
212 ThrowImageException(OptionError,
"FrameIsLessThanImageSize");
213 bevel_width=(size_t) (frame_info->outer_bevel+frame_info->inner_bevel);
214 x_offset=(ssize_t) frame_info->width-frame_info->x-(ssize_t) bevel_width;
215 y_offset=(ssize_t) frame_info->height-frame_info->y-(ssize_t) bevel_width;
216 if ((x_offset < (ssize_t) image->columns) ||
217 (y_offset < (ssize_t) image->rows))
218 ThrowImageException(OptionError,
"FrameIsLessThanImageSize");
222 frame_image=CloneImage(image,frame_info->width,frame_info->height,MagickTrue,
224 if (frame_image == (
Image *) NULL)
225 return((
Image *) NULL);
226 if (SetImageStorageClass(frame_image,DirectClass,exception) == MagickFalse)
228 frame_image=DestroyImage(frame_image);
229 return((
Image *) NULL);
231 if ((IsPixelInfoGray(&frame_image->border_color) == MagickFalse) &&
232 (IsGrayColorspace(frame_image->colorspace) != MagickFalse))
233 (void) SetImageColorspace(frame_image,sRGBColorspace,exception);
234 if ((frame_image->matte_color.alpha_trait != UndefinedPixelTrait) &&
235 (frame_image->alpha_trait == UndefinedPixelTrait))
236 (void) SetImageAlpha(frame_image,OpaqueAlpha,exception);
237 frame_image->page=image->page;
238 if ((image->page.width != 0) && (image->page.height != 0))
240 frame_image->page.width+=frame_image->columns-image->columns;
241 frame_image->page.height+=frame_image->rows-image->rows;
246 matte=image->matte_color;
248 accentuate.red=(QuantumScale*(((double) QuantumRange-(double)
249 AccentuateModulate)*matte.red+((double) QuantumRange*(double)
250 AccentuateModulate)));
251 accentuate.green=(QuantumScale*(((double) QuantumRange-(double)
252 AccentuateModulate)*matte.green+((double) QuantumRange*(double)
253 AccentuateModulate)));
254 accentuate.blue=(QuantumScale*(((double) QuantumRange-(double)
255 AccentuateModulate)*matte.blue+((double) QuantumRange*(double)
256 AccentuateModulate)));
257 accentuate.black=(QuantumScale*(((double) QuantumRange-(double)
258 AccentuateModulate)*matte.black+((double) QuantumRange*(double)
259 AccentuateModulate)));
260 accentuate.alpha=matte.alpha;
262 highlight.red=(QuantumScale*(((double) QuantumRange-(double)
263 HighlightModulate)*matte.red+((double) QuantumRange*(double)
264 HighlightModulate)));
265 highlight.green=(QuantumScale*(((double) QuantumRange-(double)
266 HighlightModulate)*matte.green+((double) QuantumRange*(double)
267 HighlightModulate)));
268 highlight.blue=(QuantumScale*(((double) QuantumRange-(double)
269 HighlightModulate)*matte.blue+((double) QuantumRange*(double)
270 HighlightModulate)));
271 highlight.black=(QuantumScale*(((double) QuantumRange-(double)
272 HighlightModulate)*matte.black+((double) QuantumRange*(double)
273 HighlightModulate)));
274 highlight.alpha=matte.alpha;
276 shadow.red=QuantumScale*matte.red*(double) ShadowModulate;
277 shadow.green=QuantumScale*matte.green*(double) ShadowModulate;
278 shadow.blue=QuantumScale*matte.blue*(double) ShadowModulate;
279 shadow.black=QuantumScale*matte.black*(double) ShadowModulate;
280 shadow.alpha=matte.alpha;
282 trough.red=QuantumScale*matte.red*(double) TroughModulate;
283 trough.green=QuantumScale*matte.green*(double) TroughModulate;
284 trough.blue=QuantumScale*matte.blue*(double) TroughModulate;
285 trough.black=QuantumScale*matte.black*(double) TroughModulate;
286 trough.alpha=matte.alpha;
289 image_view=AcquireVirtualCacheView(image,exception);
290 frame_view=AcquireAuthenticCacheView(frame_image,exception);
291 height=(size_t) (frame_info->outer_bevel+(frame_info->y-(ssize_t)
292 bevel_width)+frame_info->inner_bevel);
307 q=QueueCacheViewAuthenticPixels(frame_view,0,0,frame_image->columns,
309 if (q != (Quantum *) NULL)
314 for (y=0; y < (ssize_t) frame_info->outer_bevel; y++)
316 for (x=0; x < ((ssize_t) frame_image->columns-y); x++)
319 SetPixelViaPixelInfo(frame_image,&highlight,q);
321 SetPixelViaPixelInfo(frame_image,&accentuate,q);
322 q+=GetPixelChannels(frame_image);
324 for ( ; x < (ssize_t) frame_image->columns; x++)
326 SetPixelViaPixelInfo(frame_image,&shadow,q);
327 q+=GetPixelChannels(frame_image);
330 for (y=0; y < (frame_info->y-(ssize_t) bevel_width); y++)
332 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
334 SetPixelViaPixelInfo(frame_image,&highlight,q);
335 q+=GetPixelChannels(frame_image);
337 width=frame_image->columns-2*(size_t) frame_info->outer_bevel;
338 for (x=0; x < (ssize_t) width; x++)
340 SetPixelViaPixelInfo(frame_image,&matte,q);
341 q+=GetPixelChannels(frame_image);
343 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
345 SetPixelViaPixelInfo(frame_image,&shadow,q);
346 q+=GetPixelChannels(frame_image);
349 for (y=0; y < (ssize_t) frame_info->inner_bevel; y++)
351 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
353 SetPixelViaPixelInfo(frame_image,&highlight,q);
354 q+=GetPixelChannels(frame_image);
356 for (x=0; x < (frame_info->x-(ssize_t) bevel_width); x++)
358 SetPixelViaPixelInfo(frame_image,&matte,q);
359 q+=GetPixelChannels(frame_image);
361 width=image->columns+((size_t) frame_info->inner_bevel << 1)-
363 for (x=0; x < (ssize_t) width; x++)
366 SetPixelViaPixelInfo(frame_image,&shadow,q);
368 SetPixelViaPixelInfo(frame_image,&trough,q);
369 q+=GetPixelChannels(frame_image);
371 for ( ; x < ((ssize_t) image->columns+2*frame_info->inner_bevel); x++)
373 SetPixelViaPixelInfo(frame_image,&highlight,q);
374 q+=GetPixelChannels(frame_image);
376 width=frame_info->width-(size_t) frame_info->x-
377 image->columns-bevel_width;
378 for (x=0; x < (ssize_t) width; x++)
380 SetPixelViaPixelInfo(frame_image,&matte,q);
381 q+=GetPixelChannels(frame_image);
383 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
385 SetPixelViaPixelInfo(frame_image,&shadow,q);
386 q+=GetPixelChannels(frame_image);
389 (void) SyncCacheViewAuthenticPixels(frame_view,exception);
395#if defined(MAGICKCORE_OPENMP_SUPPORT)
396 #pragma omp parallel for schedule(static) shared(progress,status) \
397 magick_number_threads(image,frame_image,image->rows,1)
399 for (y=0; y < (ssize_t) image->rows; y++)
413 if (status == MagickFalse)
415 q=QueueCacheViewAuthenticPixels(frame_view,0,frame_info->y+y,
416 frame_image->columns,1,exception);
417 if (q == (Quantum *) NULL)
422 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
424 SetPixelViaPixelInfo(frame_image,&highlight,q);
425 q+=GetPixelChannels(frame_image);
427 for (x=0; x < (frame_info->x-(ssize_t) bevel_width); x++)
429 SetPixelViaPixelInfo(frame_image,&matte,q);
430 q+=GetPixelChannels(frame_image);
432 for (x=0; x < (ssize_t) frame_info->inner_bevel; x++)
434 SetPixelViaPixelInfo(frame_image,&shadow,q);
435 q+=GetPixelChannels(frame_image);
440 for (x=0; x < (ssize_t) image->columns; x++)
442 SetPixelViaPixelInfo(frame_image,&frame_image->border_color,q);
443 q+=GetPixelChannels(frame_image);
445 for (x=0; x < (ssize_t) frame_info->inner_bevel; x++)
447 SetPixelViaPixelInfo(frame_image,&highlight,q);
448 q+=GetPixelChannels(frame_image);
450 width=frame_info->width-(size_t) frame_info->x-image->columns-bevel_width;
451 for (x=0; x < (ssize_t) width; x++)
453 SetPixelViaPixelInfo(frame_image,&matte,q);
454 q+=GetPixelChannels(frame_image);
456 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
458 SetPixelViaPixelInfo(frame_image,&shadow,q);
459 q+=GetPixelChannels(frame_image);
461 if (SyncCacheViewAuthenticPixels(frame_view,exception) == MagickFalse)
463 if (image->progress_monitor != (MagickProgressMonitor) NULL)
468#if defined(MAGICKCORE_OPENMP_SUPPORT)
472 proceed=SetImageProgress(image,FrameImageTag,progress,image->rows);
473 if (proceed == MagickFalse)
477 height=(size_t) (frame_info->inner_bevel+(ssize_t) frame_info->height-
478 frame_info->y-(ssize_t) image->rows-(ssize_t) bevel_width+
479 frame_info->outer_bevel);
494 q=QueueCacheViewAuthenticPixels(frame_view,0,(ssize_t) (frame_image->rows-
495 height),frame_image->columns,height,exception);
496 if (q != (Quantum *) NULL)
501 for (y=frame_info->inner_bevel-1; y >= 0; y--)
503 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
505 SetPixelViaPixelInfo(frame_image,&highlight,q);
506 q+=GetPixelChannels(frame_image);
508 for (x=0; x < (frame_info->x-(ssize_t) bevel_width); x++)
510 SetPixelViaPixelInfo(frame_image,&matte,q);
511 q+=GetPixelChannels(frame_image);
513 for (x=0; x < y; x++)
515 SetPixelViaPixelInfo(frame_image,&shadow,q);
516 q+=GetPixelChannels(frame_image);
518 for ( ; x < ((ssize_t) image->columns+2*frame_info->inner_bevel); x++)
520 if (x >= ((ssize_t) image->columns+2*frame_info->inner_bevel-y))
521 SetPixelViaPixelInfo(frame_image,&highlight,q);
523 SetPixelViaPixelInfo(frame_image,&accentuate,q);
524 q+=GetPixelChannels(frame_image);
526 width=(size_t) ((ssize_t) frame_info->width-frame_info->x-
527 (ssize_t) image->columns-(ssize_t) bevel_width);
528 for (x=0; x < (ssize_t) width; x++)
530 SetPixelViaPixelInfo(frame_image,&matte,q);
531 q+=GetPixelChannels(frame_image);
533 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
535 SetPixelViaPixelInfo(frame_image,&shadow,q);
536 q+=GetPixelChannels(frame_image);
539 height=(size_t) ((ssize_t) frame_info->height-frame_info->y-(ssize_t)
540 image->rows-(ssize_t) bevel_width);
541 for (y=0; y < (ssize_t) height; y++)
543 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
545 SetPixelViaPixelInfo(frame_image,&highlight,q);
546 q+=GetPixelChannels(frame_image);
548 width=(size_t) ((ssize_t) frame_image->columns-2*(ssize_t)
549 frame_info->outer_bevel);
550 for (x=0; x < (ssize_t) width; x++)
552 SetPixelViaPixelInfo(frame_image,&matte,q);
553 q+=GetPixelChannels(frame_image);
555 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
557 SetPixelViaPixelInfo(frame_image,&shadow,q);
558 q+=GetPixelChannels(frame_image);
561 for (y=frame_info->outer_bevel-1; y >= 0; y--)
563 for (x=0; x < y; x++)
565 SetPixelViaPixelInfo(frame_image,&highlight,q);
566 q+=GetPixelChannels(frame_image);
568 for ( ; x < (ssize_t) frame_image->columns; x++)
570 if (x >= ((ssize_t) frame_image->columns-y))
571 SetPixelViaPixelInfo(frame_image,&shadow,q);
573 SetPixelViaPixelInfo(frame_image,&trough,q);
574 q+=GetPixelChannels(frame_image);
577 (void) SyncCacheViewAuthenticPixels(frame_view,exception);
580 frame_view=DestroyCacheView(frame_view);
581 image_view=DestroyCacheView(image_view);
582 x_offset=frame_info->outer_bevel+(frame_info->x-(ssize_t) bevel_width)+
583 frame_info->inner_bevel;
584 y_offset=frame_info->outer_bevel+(frame_info->y-(ssize_t) bevel_width)+
585 frame_info->inner_bevel;
586 if (status != MagickFalse)
587 status=CompositeImage(frame_image,image,compose,MagickTrue,x_offset,
589 if (status == MagickFalse)
590 frame_image=DestroyImage(frame_image);
628MagickExport MagickBooleanType RaiseImage(
Image *image,
629 const RectangleInfo *raise_info,
const MagickBooleanType raise,
632#define AccentuateFactor ScaleCharToQuantum(135)
633#define HighlightFactor ScaleCharToQuantum(190)
634#define ShadowFactor ScaleCharToQuantum(190)
635#define RaiseImageTag "Raise/Image"
636#define TroughFactor ScaleCharToQuantum(135)
654 assert(image != (
Image *) NULL);
655 assert(image->signature == MagickCoreSignature);
657 if (IsEventLogging() != MagickFalse)
658 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
659 if ((image->columns <= (raise_info->width << 1)) ||
660 (image->rows <= (raise_info->height << 1)))
661 ThrowBinaryException(OptionError,
"ImageSizeMustExceedBevelWidth",
663 foreground=QuantumRange;
664 background=(Quantum) 0;
665 if (raise == MagickFalse)
667 foreground=(Quantum) 0;
668 background=QuantumRange;
670 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
677 image_view=AcquireAuthenticCacheView(image,exception);
678#if defined(MAGICKCORE_OPENMP_SUPPORT)
679 #pragma omp parallel for schedule(static) shared(progress,status) \
680 magick_number_threads(image,image,raise_info->height,1)
682 for (y=0; y < (ssize_t) raise_info->height; y++)
691 if (status == MagickFalse)
693 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
694 if (q == (Quantum *) NULL)
699 for (x=0; x < y; x++)
701 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
703 PixelChannel channel = GetPixelChannelChannel(image,i);
704 PixelTrait traits = GetPixelChannelTraits(image,channel);
705 if ((traits & UpdatePixelTrait) == 0)
707 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*(
double)
708 HighlightFactor+(
double) foreground*((
double) QuantumRange-(
double)
711 q+=GetPixelChannels(image);
713 for ( ; x < ((ssize_t) image->columns-y); x++)
715 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
717 PixelChannel channel = GetPixelChannelChannel(image,i);
718 PixelTrait traits = GetPixelChannelTraits(image,channel);
719 if ((traits & UpdatePixelTrait) == 0)
721 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*(
double)
722 AccentuateFactor+(
double) foreground*((
double) QuantumRange-(
double)
725 q+=GetPixelChannels(image);
727 for ( ; x < (ssize_t) image->columns; x++)
729 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
731 PixelChannel channel = GetPixelChannelChannel(image,i);
732 PixelTrait traits = GetPixelChannelTraits(image,channel);
733 if ((traits & UpdatePixelTrait) == 0)
735 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*(
double) ShadowFactor+
736 (
double) background*((
double) QuantumRange-(
double) ShadowFactor)));
738 q+=GetPixelChannels(image);
740 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
742 if (image->progress_monitor != (MagickProgressMonitor) NULL)
747#if defined(MAGICKCORE_OPENMP_SUPPORT)
751 proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
752 if (proceed == MagickFalse)
756#if defined(MAGICKCORE_OPENMP_SUPPORT)
757 #pragma omp parallel for schedule(static) shared(progress,status) \
758 magick_number_threads(image,image,image->rows-2*raise_info->height,1)
760 for (y=(ssize_t) raise_info->height; y < (ssize_t) (image->rows-raise_info->height); y++)
769 if (status == MagickFalse)
771 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
772 if (q == (Quantum *) NULL)
777 for (x=0; x < (ssize_t) raise_info->width; x++)
779 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
781 PixelChannel channel = GetPixelChannelChannel(image,i);
782 PixelTrait traits = GetPixelChannelTraits(image,channel);
783 if ((traits & UpdatePixelTrait) == 0)
785 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*(
double)
786 HighlightFactor+(
double) foreground*((
double) QuantumRange-(
double)
789 q+=GetPixelChannels(image);
791 for ( ; x < (ssize_t) (image->columns-raise_info->width); x++)
792 q+=GetPixelChannels(image);
793 for ( ; x < (ssize_t) image->columns; x++)
795 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
797 PixelChannel channel = GetPixelChannelChannel(image,i);
798 PixelTrait traits = GetPixelChannelTraits(image,channel);
799 if ((traits & UpdatePixelTrait) == 0)
801 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*(
double) ShadowFactor+
802 (
double) background*((
double) QuantumRange-(
double) ShadowFactor)));
804 q+=GetPixelChannels(image);
806 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
808 if (image->progress_monitor != (MagickProgressMonitor) NULL)
813#if defined(MAGICKCORE_OPENMP_SUPPORT)
817 proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
818 if (proceed == MagickFalse)
822#if defined(MAGICKCORE_OPENMP_SUPPORT)
823 #pragma omp parallel for schedule(static) shared(progress,status) \
824 magick_number_threads(image,image,image->rows-raise_info->height,1)
826 for (y=(ssize_t) (image->rows-raise_info->height); y < (ssize_t) image->rows; y++)
835 if (status == MagickFalse)
837 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
838 if (q == (Quantum *) NULL)
843 for (x=0; x < ((ssize_t) image->rows-y); x++)
845 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
847 PixelChannel channel = GetPixelChannelChannel(image,i);
848 PixelTrait traits = GetPixelChannelTraits(image,channel);
849 if ((traits & UpdatePixelTrait) == 0)
851 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*(
double)
852 HighlightFactor+(
double) foreground*((
double) QuantumRange-
853 (
double) HighlightFactor)));
855 q+=GetPixelChannels(image);
857 for ( ; x < ((ssize_t) image->columns-((ssize_t) image->rows-y)); x++)
859 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
861 PixelChannel channel = GetPixelChannelChannel(image,i);
862 PixelTrait traits = GetPixelChannelTraits(image,channel);
863 if ((traits & UpdatePixelTrait) == 0)
865 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*(
double) TroughFactor+
866 (
double) background*((
double) QuantumRange-(
double) TroughFactor)));
868 q+=GetPixelChannels(image);
870 for ( ; x < (ssize_t) image->columns; x++)
872 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
874 PixelChannel channel = GetPixelChannelChannel(image,i);
875 PixelTrait traits = GetPixelChannelTraits(image,channel);
876 if ((traits & UpdatePixelTrait) == 0)
878 q[i]=ClampToQuantum(QuantumScale*((
double) q[i]*(
double) ShadowFactor+
879 (
double) background*((
double) QuantumRange-(
double) ShadowFactor)));
881 q+=GetPixelChannels(image);
883 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
885 if (image->progress_monitor != (MagickProgressMonitor) NULL)
890#if defined(MAGICKCORE_OPENMP_SUPPORT)
894 proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
895 if (proceed == MagickFalse)
899 image_view=DestroyCacheView(image_view);