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"
66 #define AccentuateModulate ScaleCharToQuantum(80)
67 #define HighlightModulate ScaleCharToQuantum(125)
68 #define ShadowModulate ScaleCharToQuantum(135)
69 #define DepthModulate ScaleCharToQuantum(185)
70 #define TroughModulate ScaleCharToQuantum(110)
102 MagickExport
Image *BorderImage(
const Image *image,
112 assert(image != (
const Image *) NULL);
113 assert(image->signature == MagickCoreSignature);
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);
168 #define FrameImageTag "Frame/Image"
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");
220 frame_image=CloneImage(image,frame_info->width,frame_info->height,MagickTrue,
222 if (frame_image == (
Image *) NULL)
223 return((
Image *) NULL);
224 if (SetImageStorageClass(frame_image,DirectClass) == MagickFalse)
226 InheritException(exception,&frame_image->exception);
227 frame_image=DestroyImage(frame_image);
228 return((
Image *) NULL);
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))
239 frame_image->page.width+=frame_image->columns-image->columns;
240 frame_image->page.height+=frame_image->rows-image->rows;
245 GetMagickPixelPacket(frame_image,&matte);
246 matte.colorspace=sRGBColorspace;
247 SetMagickPixelPacket(frame_image,&image->matte_color,(IndexPacket *) NULL,
249 GetMagickPixelPacket(frame_image,&border);
250 border.colorspace=sRGBColorspace;
251 SetMagickPixelPacket(frame_image,&image->border_color,(IndexPacket *) NULL,
253 GetMagickPixelPacket(frame_image,&accentuate);
254 accentuate.red=(MagickRealType) (QuantumScale*((QuantumRange-
255 AccentuateModulate)*matte.red+(QuantumRange*AccentuateModulate)));
256 accentuate.green=(MagickRealType) (QuantumScale*((QuantumRange-
257 AccentuateModulate)*matte.green+(QuantumRange*AccentuateModulate)));
258 accentuate.blue=(MagickRealType) (QuantumScale*((QuantumRange-
259 AccentuateModulate)*matte.blue+(QuantumRange*AccentuateModulate)));
260 accentuate.opacity=matte.opacity;
261 GetMagickPixelPacket(frame_image,&highlight);
262 highlight.red=(MagickRealType) (QuantumScale*((QuantumRange-
263 HighlightModulate)*matte.red+(QuantumRange*HighlightModulate)));
264 highlight.green=(MagickRealType) (QuantumScale*((QuantumRange-
265 HighlightModulate)*matte.green+(QuantumRange*HighlightModulate)));
266 highlight.blue=(MagickRealType) (QuantumScale*((QuantumRange-
267 HighlightModulate)*matte.blue+(QuantumRange*HighlightModulate)));
268 highlight.opacity=matte.opacity;
269 GetMagickPixelPacket(frame_image,&shadow);
270 shadow.red=QuantumScale*matte.red*ShadowModulate;
271 shadow.green=QuantumScale*matte.green*ShadowModulate;
272 shadow.blue=QuantumScale*matte.blue*ShadowModulate;
273 shadow.opacity=matte.opacity;
274 GetMagickPixelPacket(frame_image,&trough);
275 trough.red=QuantumScale*matte.red*TroughModulate;
276 trough.green=QuantumScale*matte.green*TroughModulate;
277 trough.blue=QuantumScale*matte.blue*TroughModulate;
278 trough.opacity=matte.opacity;
279 if (image->colorspace == CMYKColorspace)
281 ConvertRGBToCMYK(&matte);
282 ConvertRGBToCMYK(&border);
283 ConvertRGBToCMYK(&accentuate);
284 ConvertRGBToCMYK(&highlight);
285 ConvertRGBToCMYK(&shadow);
286 ConvertRGBToCMYK(&trough);
290 image_view=AcquireVirtualCacheView(image,exception);
291 frame_view=AcquireAuthenticCacheView(frame_image,exception);
292 height=(size_t) (frame_info->outer_bevel+(frame_info->y-bevel_width)+
293 frame_info->inner_bevel);
297 *magick_restrict frame_indexes;
308 q=QueueCacheViewAuthenticPixels(frame_view,0,0,frame_image->columns,
310 frame_indexes=GetCacheViewAuthenticIndexQueue(frame_view);
316 for (y=0; y < (ssize_t) frame_info->outer_bevel; y++)
318 for (x=0; x < (ssize_t) (frame_image->columns-y); x++)
321 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
323 SetPixelPacket(frame_image,&accentuate,q,frame_indexes);
327 for ( ; x < (ssize_t) frame_image->columns; x++)
329 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
334 for (y=0; y < (ssize_t) (frame_info->y-bevel_width); y++)
336 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
338 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
342 width=frame_image->columns-2*frame_info->outer_bevel;
343 for (x=0; x < (ssize_t) width; x++)
345 SetPixelPacket(frame_image,&matte,q,frame_indexes);
349 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
351 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
356 for (y=0; y < (ssize_t) frame_info->inner_bevel; y++)
358 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
360 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
364 for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
366 SetPixelPacket(frame_image,&matte,q,frame_indexes);
370 width=image->columns+((size_t) frame_info->inner_bevel << 1)-
372 for (x=0; x < (ssize_t) width; x++)
375 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
377 SetPixelPacket(frame_image,&trough,q,frame_indexes);
381 for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++)
383 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
387 width=frame_info->width-frame_info->x-image->columns-bevel_width;
388 for (x=0; x < (ssize_t) width; x++)
390 SetPixelPacket(frame_image,&matte,q,frame_indexes);
394 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
396 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
401 (void) SyncCacheViewAuthenticPixels(frame_view,exception);
407 #if defined(MAGICKCORE_OPENMP_SUPPORT)
408 #pragma omp parallel for schedule(static) shared(status) \
409 magick_number_threads(image,frame_image,image->rows,1)
411 for (y=0; y < (ssize_t) image->rows; y++)
414 *magick_restrict frame_indexes;
425 if (status == MagickFalse)
427 q=QueueCacheViewAuthenticPixels(frame_view,0,frame_info->y+y,
428 frame_image->columns,1,exception);
434 frame_indexes=GetCacheViewAuthenticIndexQueue(frame_view);
435 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
437 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
441 for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
443 SetPixelPacket(frame_image,&matte,q,frame_indexes);
447 for (x=0; x < (ssize_t) frame_info->inner_bevel; x++)
449 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
456 for (x=0; x < (ssize_t) image->columns; x++)
458 SetPixelPacket(frame_image,&border,q,frame_indexes);
462 for (x=0; x < (ssize_t) frame_info->inner_bevel; x++)
464 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
468 width=frame_info->width-frame_info->x-image->columns-bevel_width;
469 for (x=0; x < (ssize_t) width; x++)
471 SetPixelPacket(frame_image,&matte,q,frame_indexes);
475 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
477 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
481 if (SyncCacheViewAuthenticPixels(frame_view,exception) == MagickFalse)
483 if (image->progress_monitor != (MagickProgressMonitor) NULL)
488 #if defined(MAGICKCORE_OPENMP_SUPPORT)
492 proceed=SetImageProgress(image,FrameImageTag,progress,image->rows);
493 if (proceed == MagickFalse)
497 height=(size_t) (frame_info->inner_bevel+frame_info->height-
498 frame_info->y-image->rows-bevel_width+frame_info->outer_bevel);
502 *magick_restrict frame_indexes;
513 q=QueueCacheViewAuthenticPixels(frame_view,0,(ssize_t) (frame_image->rows-
514 height),frame_image->columns,height,exception);
520 frame_indexes=GetCacheViewAuthenticIndexQueue(frame_view);
521 for (y=frame_info->inner_bevel-1; y >= 0; y--)
523 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
525 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
529 for (x=0; x < (ssize_t) (frame_info->x-bevel_width); x++)
531 SetPixelPacket(frame_image,&matte,q,frame_indexes);
535 for (x=0; x < y; x++)
537 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
541 for ( ; x < (ssize_t) (image->columns+2*frame_info->inner_bevel); x++)
543 if (x >= (ssize_t) (image->columns+2*frame_info->inner_bevel-y))
544 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
546 SetPixelPacket(frame_image,&accentuate,q,frame_indexes);
550 width=frame_info->width-frame_info->x-image->columns-bevel_width;
551 for (x=0; x < (ssize_t) width; x++)
553 SetPixelPacket(frame_image,&matte,q,frame_indexes);
557 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
559 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
564 height=frame_info->height-frame_info->y-image->rows-bevel_width;
565 for (y=0; y < (ssize_t) height; y++)
567 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
569 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
573 width=frame_image->columns-2*frame_info->outer_bevel;
574 for (x=0; x < (ssize_t) width; x++)
576 SetPixelPacket(frame_image,&matte,q,frame_indexes);
580 for (x=0; x < (ssize_t) frame_info->outer_bevel; x++)
582 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
587 for (y=frame_info->outer_bevel-1; y >= 0; y--)
589 for (x=0; x < y; x++)
591 SetPixelPacket(frame_image,&highlight,q,frame_indexes);
595 for ( ; x < (ssize_t) frame_image->columns; x++)
597 if (x >= (ssize_t) (frame_image->columns-y))
598 SetPixelPacket(frame_image,&shadow,q,frame_indexes);
600 SetPixelPacket(frame_image,&trough,q,frame_indexes);
605 (void) SyncCacheViewAuthenticPixels(frame_view,exception);
608 frame_view=DestroyCacheView(frame_view);
609 image_view=DestroyCacheView(image_view);
610 x=(ssize_t) (frame_info->outer_bevel+(frame_info->x-bevel_width)+
611 frame_info->inner_bevel);
612 y=(ssize_t) (frame_info->outer_bevel+(frame_info->y-bevel_width)+
613 frame_info->inner_bevel);
614 if (status != MagickFalse)
615 status=CompositeImage(frame_image,image->compose,image,x,y);
616 if (status == MagickFalse)
617 frame_image=DestroyImage(frame_image);
652 MagickExport MagickBooleanType RaiseImage(
Image *image,
653 const RectangleInfo *raise_info,
const MagickBooleanType
raise)
655 #define AccentuateFactor ScaleCharToQuantum(135)
656 #define HighlightFactor ScaleCharToQuantum(190)
657 #define ShadowFactor ScaleCharToQuantum(190)
658 #define RaiseImageTag "Raise/Image"
659 #define TroughFactor ScaleCharToQuantum(135)
680 assert(image != (
Image *) NULL);
681 assert(image->signature == MagickCoreSignature);
683 if (IsEventLogging() != MagickFalse)
684 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
685 exception=(&image->exception);
686 if ((image->columns <= (raise_info->width << 1)) ||
687 (image->rows <= (raise_info->height << 1)))
688 ThrowBinaryException(OptionError,
"ImageSizeMustExceedBevelWidth",
690 foreground=QuantumRange;
691 background=(Quantum) 0;
692 if (
raise == MagickFalse)
694 foreground=(Quantum) 0;
695 background=QuantumRange;
697 if (SetImageStorageClass(image,DirectClass) == MagickFalse)
704 image_view=AcquireAuthenticCacheView(image,exception);
705 #if defined(MAGICKCORE_OPENMP_SUPPORT)
706 #pragma omp parallel for schedule(static) shared(status) \
707 magick_number_threads(image,image,raise_info->height,1)
709 for (y=0; y < (ssize_t) raise_info->height; y++)
717 if (status == MagickFalse)
719 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
725 for (x=0; x < y; x++)
727 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
728 GetPixelRed(q)*HighlightFactor+(MagickRealType) foreground*
729 (QuantumRange-HighlightFactor))));
730 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
731 GetPixelGreen(q)*HighlightFactor+(MagickRealType) foreground*
732 (QuantumRange-HighlightFactor))));
733 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
734 GetPixelBlue(q)*HighlightFactor+(MagickRealType) foreground*
735 (QuantumRange-HighlightFactor))));
738 for ( ; x < (ssize_t) (image->columns-y); x++)
740 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
741 GetPixelRed(q)*AccentuateFactor+(MagickRealType) foreground*
742 (QuantumRange-AccentuateFactor))));
743 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
744 GetPixelGreen(q)*AccentuateFactor+(MagickRealType) foreground*
745 (QuantumRange-AccentuateFactor))));
746 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
747 GetPixelBlue(q)*AccentuateFactor+(MagickRealType) foreground*
748 (QuantumRange-AccentuateFactor))));
751 for ( ; x < (ssize_t) image->columns; x++)
753 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
754 GetPixelRed(q)*ShadowFactor+(MagickRealType) background*
755 (QuantumRange-ShadowFactor))));
756 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
757 GetPixelGreen(q)*ShadowFactor+(MagickRealType) background*
758 (QuantumRange-ShadowFactor))));
759 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
760 GetPixelBlue(q)*ShadowFactor+(MagickRealType) background*
761 (QuantumRange-ShadowFactor))));
764 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
766 if (image->progress_monitor != (MagickProgressMonitor) NULL)
771 #if defined(MAGICKCORE_OPENMP_SUPPORT)
775 proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
776 if (proceed == MagickFalse)
780 #if defined(MAGICKCORE_OPENMP_SUPPORT)
781 #pragma omp parallel for schedule(static) shared(status) \
782 magick_number_threads(image,image,image->rows-2*raise_info->height,1)
784 for (y=(ssize_t) raise_info->height; y < (ssize_t) (image->rows-raise_info->height); y++)
792 if (status == MagickFalse)
794 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
800 for (x=0; x < (ssize_t) raise_info->width; x++)
802 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
803 GetPixelRed(q)*HighlightFactor+(MagickRealType) foreground*
804 (QuantumRange-HighlightFactor))));
805 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
806 GetPixelGreen(q)*HighlightFactor+(MagickRealType) foreground*
807 (QuantumRange-HighlightFactor))));
808 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
809 GetPixelBlue(q)*HighlightFactor+(MagickRealType) foreground*
810 (QuantumRange-HighlightFactor))));
813 for ( ; x < (ssize_t) (image->columns-raise_info->width); x++)
815 for ( ; x < (ssize_t) image->columns; x++)
817 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
818 GetPixelRed(q)*ShadowFactor+(MagickRealType) background*
819 (QuantumRange-ShadowFactor))));
820 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
821 GetPixelGreen(q)*ShadowFactor+(MagickRealType) background*
822 (QuantumRange-ShadowFactor))));
823 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
824 GetPixelBlue(q)*ShadowFactor+(MagickRealType) background*
825 (QuantumRange-ShadowFactor))));
828 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
830 if (image->progress_monitor != (MagickProgressMonitor) NULL)
835 #if defined(MAGICKCORE_OPENMP_SUPPORT)
839 proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
840 if (proceed == MagickFalse)
844 #if defined(MAGICKCORE_OPENMP_SUPPORT)
845 #pragma omp parallel for schedule(static) shared(status) \
846 magick_number_threads(image,image,image->rows-raise_info->height,1)
848 for (y=(ssize_t) (image->rows-raise_info->height); y < (ssize_t) image->rows; y++)
856 if (status == MagickFalse)
858 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
864 for (x=0; x < (ssize_t) (image->rows-y); x++)
866 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
867 GetPixelRed(q)*HighlightFactor+(MagickRealType) foreground*
868 (QuantumRange-HighlightFactor))));
869 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
870 GetPixelGreen(q)*HighlightFactor+(MagickRealType) foreground*
871 (QuantumRange-HighlightFactor))));
872 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
873 GetPixelBlue(q)*HighlightFactor+(MagickRealType) foreground*
874 (QuantumRange-HighlightFactor))));
877 for ( ; x < (ssize_t) (image->columns-(image->rows-y)); x++)
879 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
880 GetPixelRed(q)*TroughFactor+(MagickRealType) background*
881 (QuantumRange-TroughFactor))));
882 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
883 GetPixelGreen(q)*TroughFactor+(MagickRealType) background*
884 (QuantumRange-TroughFactor))));
885 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
886 GetPixelBlue(q)*TroughFactor+(MagickRealType) background*
887 (QuantumRange-TroughFactor))));
890 for ( ; x < (ssize_t) image->columns; x++)
892 SetPixelRed(q,ClampToQuantum(QuantumScale*((MagickRealType)
893 GetPixelRed(q)*ShadowFactor+(MagickRealType) background*
894 (QuantumRange-ShadowFactor))));
895 SetPixelGreen(q,ClampToQuantum(QuantumScale*((MagickRealType)
896 GetPixelGreen(q)*ShadowFactor+(MagickRealType) background*
897 (QuantumRange-ShadowFactor))));
898 SetPixelBlue(q,ClampToQuantum(QuantumScale*((MagickRealType)
899 GetPixelBlue(q)*ShadowFactor+(MagickRealType) background*
900 (QuantumRange-ShadowFactor))));
903 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
905 if (image->progress_monitor != (MagickProgressMonitor) NULL)
910 #if defined(MAGICKCORE_OPENMP_SUPPORT)
914 proceed=SetImageProgress(image,RaiseImageTag,progress,image->rows);
915 if (proceed == MagickFalse)
919 image_view=DestroyCacheView(image_view);