42#include "MagickCore/studio.h"
43#include "MagickCore/attribute.h"
44#include "MagickCore/artifact.h"
45#include "MagickCore/cache.h"
46#include "MagickCore/cache-view.h"
47#include "MagickCore/color.h"
48#include "MagickCore/color-private.h"
49#include "MagickCore/colorspace-private.h"
50#include "MagickCore/composite.h"
51#include "MagickCore/composite-private.h"
52#include "MagickCore/distort.h"
53#include "MagickCore/draw.h"
54#include "MagickCore/effect.h"
55#include "MagickCore/exception.h"
56#include "MagickCore/exception-private.h"
57#include "MagickCore/geometry.h"
58#include "MagickCore/image.h"
59#include "MagickCore/memory_.h"
60#include "MagickCore/layer.h"
61#include "MagickCore/list.h"
62#include "MagickCore/monitor.h"
63#include "MagickCore/monitor-private.h"
64#include "MagickCore/pixel-accessor.h"
65#include "MagickCore/profile-private.h"
66#include "MagickCore/property.h"
67#include "MagickCore/resource_.h"
68#include "MagickCore/resize.h"
69#include "MagickCore/statistic.h"
70#include "MagickCore/string_.h"
71#include "MagickCore/thread-private.h"
72#include "MagickCore/transform.h"
73#include "MagickCore/transform-private.h"
103MagickExport Image *AutoOrientImage(
const Image *image,
104 const OrientationType orientation,ExceptionInfo *exception)
109 assert(image != (
const Image *) NULL);
110 assert(image->signature == MagickCoreSignature);
111 assert(exception != (ExceptionInfo *) NULL);
112 assert(exception->signature == MagickCoreSignature);
113 orient_image=(Image *) NULL;
116 case UndefinedOrientation:
117 case TopLeftOrientation:
120 orient_image=CloneImage(image,0,0,MagickTrue,exception);
123 case TopRightOrientation:
125 orient_image=FlopImage(image,exception);
128 case BottomRightOrientation:
130 orient_image=RotateImage(image,180.0,exception);
133 case BottomLeftOrientation:
135 orient_image=FlipImage(image,exception);
138 case LeftTopOrientation:
140 orient_image=TransposeImage(image,exception);
143 case RightTopOrientation:
145 orient_image=RotateImage(image,90.0,exception);
148 case RightBottomOrientation:
150 orient_image=TransverseImage(image,exception);
153 case LeftBottomOrientation:
155 orient_image=RotateImage(image,270.0,exception);
159 if (orient_image != (Image *) NULL)
160 orient_image->orientation=TopLeftOrientation;
161 return(orient_image);
192MagickExport Image *ChopImage(
const Image *image,
const RectangleInfo *chop_info,
193 ExceptionInfo *exception)
195#define ChopImageTag "Chop/Image"
219 assert(image != (
const Image *) NULL);
220 assert(image->signature == MagickCoreSignature);
221 assert(exception != (ExceptionInfo *) NULL);
222 assert(exception->signature == MagickCoreSignature);
223 assert(chop_info != (RectangleInfo *) NULL);
224 if (IsEventLogging() != MagickFalse)
225 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
226 if (((chop_info->x+(ssize_t) chop_info->width) < 0) ||
227 ((chop_info->y+(ssize_t) chop_info->height) < 0) ||
228 (chop_info->x > (ssize_t) image->columns) ||
229 (chop_info->y > (ssize_t) image->rows))
230 ThrowImageException(OptionWarning,
"GeometryDoesNotContainImage");
232 if ((extent.x+(ssize_t) extent.width) > (ssize_t) image->columns)
233 extent.width=(size_t) ((ssize_t) image->columns-extent.x);
234 if ((extent.y+(ssize_t) extent.height) > (ssize_t) image->rows)
235 extent.height=(size_t) ((ssize_t) image->rows-extent.y);
238 extent.width-=(size_t) (-extent.x);
243 extent.height-=(size_t) (-extent.y);
246 if ((extent.width >= image->columns) || (extent.height >= image->rows))
247 ThrowImageException(OptionWarning,
"GeometryDoesNotContainImage");
248 chop_image=CloneImage(image,image->columns-extent.width,image->rows-
249 extent.height,MagickTrue,exception);
250 if (chop_image == (Image *) NULL)
251 return((Image *) NULL);
257 image_view=AcquireVirtualCacheView(image,exception);
258 chop_view=AcquireAuthenticCacheView(chop_image,exception);
259#if defined(MAGICKCORE_OPENMP_SUPPORT)
260 #pragma omp parallel for schedule(static) shared(status) \
261 magick_number_threads(image,chop_image,(size_t) extent.y,2)
263 for (y=0; y < (ssize_t) extent.y; y++)
274 if (status == MagickFalse)
276 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
277 q=QueueCacheViewAuthenticPixels(chop_view,0,y,chop_image->columns,1,
279 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
284 for (x=0; x < (ssize_t) image->columns; x++)
286 if ((x < extent.x) || (x >= (extent.x+(ssize_t) extent.width)))
291 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
293 PixelChannel channel = GetPixelChannelChannel(image,i);
294 PixelTrait traits = GetPixelChannelTraits(image,channel);
295 PixelTrait chop_traits=GetPixelChannelTraits(chop_image,channel);
296 if ((traits == UndefinedPixelTrait) ||
297 (chop_traits == UndefinedPixelTrait))
299 SetPixelChannel(chop_image,channel,p[i],q);
301 q+=(ptrdiff_t) GetPixelChannels(chop_image);
303 p+=(ptrdiff_t) GetPixelChannels(image);
305 if (SyncCacheViewAuthenticPixels(chop_view,exception) == MagickFalse)
307 if (image->progress_monitor != (MagickProgressMonitor) NULL)
312#if defined(MAGICKCORE_OPENMP_SUPPORT)
316 proceed=SetImageProgress(image,ChopImageTag,progress,image->rows);
317 if (proceed == MagickFalse)
324#if defined(MAGICKCORE_OPENMP_SUPPORT)
325 #pragma omp parallel for schedule(static) shared(progress,status) \
326 magick_number_threads(image,chop_image,image->rows-((size_t) extent.y+extent.height),2)
328 for (y=0; y < (ssize_t) (image->rows-((size_t) extent.y+extent.height)); y++)
339 if (status == MagickFalse)
341 p=GetCacheViewVirtualPixels(image_view,0,extent.y+(ssize_t) extent.height+y,
342 image->columns,1,exception);
343 q=QueueCacheViewAuthenticPixels(chop_view,0,extent.y+y,chop_image->columns,
345 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
350 for (x=0; x < (ssize_t) image->columns; x++)
352 if ((x < extent.x) || (x >= (extent.x+(ssize_t) extent.width)))
357 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
359 PixelChannel channel = GetPixelChannelChannel(image,i);
360 PixelTrait traits = GetPixelChannelTraits(image,channel);
361 PixelTrait chop_traits=GetPixelChannelTraits(chop_image,channel);
362 if ((traits == UndefinedPixelTrait) ||
363 (chop_traits == UndefinedPixelTrait))
365 SetPixelChannel(chop_image,channel,p[i],q);
367 q+=(ptrdiff_t) GetPixelChannels(chop_image);
369 p+=(ptrdiff_t) GetPixelChannels(image);
371 if (SyncCacheViewAuthenticPixels(chop_view,exception) == MagickFalse)
373 if (image->progress_monitor != (MagickProgressMonitor) NULL)
378#if defined(MAGICKCORE_OPENMP_SUPPORT)
382 proceed=SetImageProgress(image,ChopImageTag,progress,image->rows);
383 if (proceed == MagickFalse)
387 chop_view=DestroyCacheView(chop_view);
388 image_view=DestroyCacheView(image_view);
389 chop_image->type=image->type;
390 if (status == MagickFalse)
391 chop_image=DestroyImage(chop_image);
420MagickExport Image *ConsolidateCMYKImages(
const Image *images,
421 ExceptionInfo *exception)
440 assert(images != (Image *) NULL);
441 assert(images->signature == MagickCoreSignature);
442 assert(exception != (ExceptionInfo *) NULL);
443 assert(exception->signature == MagickCoreSignature);
444 if (IsEventLogging() != MagickFalse)
445 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
446 cmyk_images=NewImageList();
447 for (j=0; j < (ssize_t) GetImageListLength(images); j+=4)
452 assert(images != (Image *) NULL);
453 cmyk_image=CloneImage(images,0,0,MagickTrue,
455 if (cmyk_image == (Image *) NULL)
457 if (SetImageStorageClass(cmyk_image,DirectClass,exception) == MagickFalse)
459 (void) SetImageColorspace(cmyk_image,CMYKColorspace,exception);
460 for (i=0; i < 4; i++)
462 image_view=AcquireVirtualCacheView(images,exception);
463 cmyk_view=AcquireAuthenticCacheView(cmyk_image,exception);
464 for (y=0; y < (ssize_t) images->rows; y++)
475 p=GetCacheViewVirtualPixels(image_view,0,y,images->columns,1,exception);
476 q=QueueCacheViewAuthenticPixels(cmyk_view,0,y,cmyk_image->columns,1,
478 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
480 for (x=0; x < (ssize_t) images->columns; x++)
485 pixel=ClampToQuantum((
double) QuantumRange-
486 GetPixelIntensity(images,p));
489 case 0: SetPixelCyan(cmyk_image,pixel,q);
break;
490 case 1: SetPixelMagenta(cmyk_image,pixel,q);
break;
491 case 2: SetPixelYellow(cmyk_image,pixel,q);
break;
492 case 3: SetPixelBlack(cmyk_image,pixel,q);
break;
495 p+=(ptrdiff_t) GetPixelChannels(images);
496 q+=(ptrdiff_t) GetPixelChannels(cmyk_image);
498 if (SyncCacheViewAuthenticPixels(cmyk_view,exception) == MagickFalse)
501 cmyk_view=DestroyCacheView(cmyk_view);
502 image_view=DestroyCacheView(image_view);
503 images=GetNextImageInList(images);
504 if (images == (Image *) NULL)
507 AppendImageToList(&cmyk_images,cmyk_image);
542MagickExport Image *CropImage(
const Image *image,
const RectangleInfo *geometry,
543 ExceptionInfo *exception)
545#define CropImageTag "Crop/Image"
573 assert(image != (
const Image *) NULL);
574 assert(image->signature == MagickCoreSignature);
575 assert(geometry != (
const RectangleInfo *) NULL);
576 assert(exception != (ExceptionInfo *) NULL);
577 assert(exception->signature == MagickCoreSignature);
578 if (IsEventLogging() != MagickFalse)
579 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
580 bounding_box=image->page;
581 if ((bounding_box.width == 0) || (bounding_box.height == 0))
583 bounding_box.width=image->columns;
584 bounding_box.height=image->rows;
588 page.width=bounding_box.width;
589 if (page.height == 0)
590 page.height=bounding_box.height;
591 if ((((
double) bounding_box.x-page.x) >= (
double) page.width) ||
592 (((
double) bounding_box.y-page.y) >= (
double) page.height) ||
593 (((
double) page.x-bounding_box.x) > (
double) image->columns) ||
594 (((
double) page.y-bounding_box.y) > (
double) image->rows))
599 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
600 "GeometryDoesNotContainImage",
"(\"%.20gx%.20g%+.20g%+.20g\") `%s'",
601 (
double) geometry->width,(
double) geometry->height,
602 (
double) geometry->x,(
double) geometry->y,image->filename);
603 crop_image=CloneImage(image,1,1,MagickTrue,exception);
604 if (crop_image == (Image *) NULL)
605 return((Image *) NULL);
606 crop_image->background_color.alpha_trait=BlendPixelTrait;
607 crop_image->background_color.alpha=(MagickRealType) TransparentAlpha;
608 (void) SetImageBackgroundColor(crop_image,exception);
609 crop_image->page=bounding_box;
610 crop_image->page.x=(-1);
611 crop_image->page.y=(-1);
612 if (crop_image->dispose == BackgroundDispose)
613 crop_image->dispose=NoneDispose;
616 if ((page.x < 0) && (bounding_box.x >= 0))
618 page.width=CastDoubleToSizeT((
double) page.width+page.x-bounding_box.x);
623 page.width=CastDoubleToSizeT((
double) page.width-(bounding_box.x-page.x));
624 page.x-=bounding_box.x;
628 if ((page.y < 0) && (bounding_box.y >= 0))
630 page.height=CastDoubleToSizeT((
double) page.height+page.y-bounding_box.y);
635 page.height=CastDoubleToSizeT((
double) page.height-(bounding_box.y-
637 page.y-=bounding_box.y;
641 if ((page.x+(ssize_t) page.width) > (ssize_t) image->columns)
642 page.width=(size_t) ((ssize_t) image->columns-page.x);
643 if ((geometry->width != 0) && (page.width > geometry->width))
644 page.width=geometry->width;
645 if ((page.y+(ssize_t) page.height) > (ssize_t) image->rows)
646 page.height=CastDoubleToSizeT((
double) image->rows-page.y);
647 if ((geometry->height != 0) && (page.height > geometry->height))
648 page.height=geometry->height;
649 bounding_box.x+=page.x;
650 bounding_box.y+=page.y;
651 if ((page.width == 0) || (page.height == 0))
653 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
654 "GeometryDoesNotContainImage",
"`%s'",image->filename);
655 return((Image *) NULL);
660 crop_image=CloneImage(image,page.width,page.height,MagickTrue,exception);
661 if (crop_image == (Image *) NULL)
662 return((Image *) NULL);
663 crop_image->page.width=image->page.width;
664 crop_image->page.height=image->page.height;
665 offset.x=bounding_box.x+(ssize_t) bounding_box.width;
666 offset.y=bounding_box.y+(ssize_t) bounding_box.height;
667 if ((offset.x > (ssize_t) image->page.width) ||
668 (offset.y > (ssize_t) image->page.height))
670 crop_image->page.width=bounding_box.width;
671 crop_image->page.height=bounding_box.height;
673 crop_image->page.x=bounding_box.x;
674 crop_image->page.y=bounding_box.y;
680 image_view=AcquireVirtualCacheView(image,exception);
681 crop_view=AcquireAuthenticCacheView(crop_image,exception);
682#if defined(MAGICKCORE_OPENMP_SUPPORT)
683 #pragma omp parallel for schedule(static) shared(status) \
684 magick_number_threads(image,crop_image,crop_image->rows,2)
686 for (y=0; y < (ssize_t) crop_image->rows; y++)
697 if (status == MagickFalse)
699 p=GetCacheViewVirtualPixels(image_view,page.x,page.y+y,crop_image->columns,
701 q=QueueCacheViewAuthenticPixels(crop_view,0,y,crop_image->columns,1,
703 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
708 for (x=0; x < (ssize_t) crop_image->columns; x++)
713 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
715 PixelChannel channel = GetPixelChannelChannel(image,i);
716 PixelTrait traits = GetPixelChannelTraits(image,channel);
717 PixelTrait crop_traits=GetPixelChannelTraits(crop_image,channel);
718 if ((traits == UndefinedPixelTrait) ||
719 (crop_traits == UndefinedPixelTrait))
721 SetPixelChannel(crop_image,channel,p[i],q);
723 p+=(ptrdiff_t) GetPixelChannels(image);
724 q+=(ptrdiff_t) GetPixelChannels(crop_image);
726 if (SyncCacheViewAuthenticPixels(crop_view,exception) == MagickFalse)
728 if (image->progress_monitor != (MagickProgressMonitor) NULL)
733#if defined(MAGICKCORE_OPENMP_SUPPORT)
737 proceed=SetImageProgress(image,CropImageTag,progress,image->rows);
738 if (proceed == MagickFalse)
742 crop_view=DestroyCacheView(crop_view);
743 image_view=DestroyCacheView(image_view);
744 crop_image->type=image->type;
745 if (status != MagickFalse)
748 transform[MagickPathExtent];
750 (void) FormatLocaleString(transform,MagickPathExtent,
751 "crop %.20gx%.20g %.20gx%.20g%+.20g%+.20g",
752 (
double) image->columns,(
double) image->rows,(
double) page.width,
753 (
double) page.height,(
double) page.x,(
double) page.y);
754 AppendImageProfileProperty(crop_image,
"hdrgm",
"hdrgm:Transform",
755 transform,exception);
757 if (status == MagickFalse)
758 crop_image=DestroyImage(crop_image);
790static inline ssize_t PixelRoundOffset(
double x)
795 if ((x-floor(x)) < (ceil(x)-x))
796 return(CastDoubleToSsizeT(floor(x)));
797 return(CastDoubleToSsizeT(ceil(x)));
800MagickExport Image *CropImageToTiles(
const Image *image,
801 const char *crop_geometry,ExceptionInfo *exception)
813 assert(image != (Image *) NULL);
814 assert(image->signature == MagickCoreSignature);
815 if (IsEventLogging() != MagickFalse)
816 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
817 flags=ParseGravityGeometry(image,crop_geometry,&geometry,exception);
818 if ((flags & AreaValue) != 0)
834 crop_image=NewImageList();
835 width=image->columns;
837 if (geometry.width == 0)
839 if (geometry.height == 0)
841 if ((flags & AspectValue) == 0)
843 width=(size_t) ((ssize_t) width-(geometry.x < 0 ? -1 : 1)*geometry.x);
844 height=(size_t) ((ssize_t) height-(geometry.y < 0 ? -1 : 1)*
849 width=(size_t) ((ssize_t) width+(geometry.x < 0 ? -1 : 1)*geometry.x);
850 height=(size_t) ((ssize_t) height+(geometry.y < 0 ? -1 : 1)*
853 delta.x=(double) width/geometry.width;
854 delta.y=(double) height/geometry.height;
859 for (offset.y=0; offset.y < (
double) height; )
861 if ((flags & AspectValue) == 0)
863 crop.y=PixelRoundOffset((
double) (offset.y-
864 (geometry.y > 0 ? 0 : geometry.y)));
866 crop.height=(size_t) PixelRoundOffset((
double) (offset.y+
867 (geometry.y < 0 ? 0 : geometry.y)));
871 crop.y=PixelRoundOffset((
double) (offset.y-
872 (geometry.y > 0 ? geometry.y : 0)));
874 crop.height=(size_t) PixelRoundOffset((
double)
875 (offset.y+(geometry.y < -1 ? geometry.y : 0)));
877 crop.height=(size_t) ((ssize_t) crop.height-crop.y);
878 crop.y+=image->page.y;
879 for (offset.x=0; offset.x < (
double) width; )
881 if ((flags & AspectValue) == 0)
883 crop.x=PixelRoundOffset((
double) (offset.x-
884 (geometry.x > 0 ? 0 : geometry.x)));
886 crop.width=(size_t) PixelRoundOffset((
double) (offset.x+
887 (geometry.x < 0 ? 0 : geometry.x)));
891 crop.x=PixelRoundOffset((
double) (offset.x-
892 (geometry.x > 0 ? geometry.x : 0)));
894 crop.width=(size_t) PixelRoundOffset((
double) (offset.x+
895 (geometry.x < 0 ? geometry.x : 0)));
897 crop.width=(size_t) ((ssize_t) crop.width-crop.x);
898 crop.x+=image->page.x;
899 next=CropImage(image,&crop,exception);
900 if (next != (Image *) NULL)
901 AppendImageToList(&crop_image,next);
904 ClearMagickException(exception);
907 if (((geometry.width == 0) && (geometry.height == 0)) ||
908 ((flags & XValue) != 0) || ((flags & YValue) != 0))
913 crop_image=CropImage(image,&geometry,exception);
914 if ((crop_image != (Image *) NULL) && ((flags & AspectValue) != 0))
916 crop_image->page.width=geometry.width;
917 crop_image->page.height=geometry.height;
918 crop_image->page.x-=geometry.x;
919 crop_image->page.y-=geometry.y;
923 if ((image->columns > geometry.width) || (image->rows > geometry.height))
941 page.width=image->columns;
942 if (page.height == 0)
943 page.height=image->rows;
944 width=geometry.width;
947 height=geometry.height;
951 crop_image=NewImageList();
952 for (y=0; y < (ssize_t) page.height; y+=(ssize_t) height)
954 for (x=0; x < (ssize_t) page.width; x+=(ssize_t) width)
956 geometry.width=width;
957 geometry.height=height;
960 next=CropImage(image,&geometry,exception);
961 if (next == (Image *) NULL)
963 AppendImageToList(&crop_image,next);
965 if (next == (Image *) NULL)
970 return(CloneImage(image,0,0,MagickTrue,exception));
1001MagickExport Image *ExcerptImage(
const Image *image,
1002 const RectangleInfo *geometry,ExceptionInfo *exception)
1004#define ExcerptImageTag "Excerpt/Image"
1025 assert(image != (
const Image *) NULL);
1026 assert(image->signature == MagickCoreSignature);
1027 assert(geometry != (
const RectangleInfo *) NULL);
1028 assert(exception != (ExceptionInfo *) NULL);
1029 assert(exception->signature == MagickCoreSignature);
1030 if (IsEventLogging() != MagickFalse)
1031 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1032 excerpt_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
1034 if (excerpt_image == (Image *) NULL)
1035 return((Image *) NULL);
1041 image_view=AcquireVirtualCacheView(image,exception);
1042 excerpt_view=AcquireAuthenticCacheView(excerpt_image,exception);
1043#if defined(MAGICKCORE_OPENMP_SUPPORT)
1044 #pragma omp parallel for schedule(static) shared(progress,status) \
1045 magick_number_threads(image,excerpt_image,excerpt_image->rows,2)
1047 for (y=0; y < (ssize_t) excerpt_image->rows; y++)
1058 if (status == MagickFalse)
1060 p=GetCacheViewVirtualPixels(image_view,geometry->x,geometry->y+y,
1061 geometry->width,1,exception);
1062 q=GetCacheViewAuthenticPixels(excerpt_view,0,y,excerpt_image->columns,1,
1064 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1069 for (x=0; x < (ssize_t) excerpt_image->columns; x++)
1074 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1076 PixelChannel channel = GetPixelChannelChannel(image,i);
1077 PixelTrait traits = GetPixelChannelTraits(image,channel);
1078 PixelTrait excerpt_traits=GetPixelChannelTraits(excerpt_image,channel);
1079 if ((traits == UndefinedPixelTrait) ||
1080 (excerpt_traits == UndefinedPixelTrait))
1082 SetPixelChannel(excerpt_image,channel,p[i],q);
1084 p+=(ptrdiff_t) GetPixelChannels(image);
1085 q+=(ptrdiff_t) GetPixelChannels(excerpt_image);
1087 if (SyncCacheViewAuthenticPixels(excerpt_view,exception) == MagickFalse)
1089 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1094#if defined(MAGICKCORE_OPENMP_SUPPORT)
1098 proceed=SetImageProgress(image,ExcerptImageTag,progress,image->rows);
1099 if (proceed == MagickFalse)
1103 excerpt_view=DestroyCacheView(excerpt_view);
1104 image_view=DestroyCacheView(image_view);
1105 excerpt_image->type=image->type;
1106 if (status == MagickFalse)
1107 excerpt_image=DestroyImage(excerpt_image);
1108 return(excerpt_image);
1141MagickExport Image *ExtentImage(
const Image *image,
1142 const RectangleInfo *geometry,ExceptionInfo *exception)
1153 assert(image != (
const Image *) NULL);
1154 assert(image->signature == MagickCoreSignature);
1155 assert(geometry != (
const RectangleInfo *) NULL);
1156 assert(exception != (ExceptionInfo *) NULL);
1157 assert(exception->signature == MagickCoreSignature);
1158 if (IsEventLogging() != MagickFalse)
1159 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1160 extent_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
1162 if (extent_image == (Image *) NULL)
1163 return((Image *) NULL);
1164 status=SetImageBackgroundColor(extent_image,exception);
1165 if (status == MagickFalse)
1167 extent_image=DestroyImage(extent_image);
1168 return((Image *) NULL);
1170 DisableCompositeClampUnlessSpecified(extent_image);
1171 status=CompositeImage(extent_image,image,image->compose,MagickTrue,
1172 -geometry->x,-geometry->y,exception);
1173 if (status != MagickFalse)
1174 Update8BIMClipPath(extent_image,image->columns,image->rows,geometry);
1175 return(extent_image);
1203MagickExport Image *FlipImage(
const Image *image,ExceptionInfo *exception)
1205#define FlipImageTag "Flip/Image"
1226 assert(image != (
const Image *) NULL);
1227 assert(image->signature == MagickCoreSignature);
1228 assert(exception != (ExceptionInfo *) NULL);
1229 assert(exception->signature == MagickCoreSignature);
1230 if (IsEventLogging() != MagickFalse)
1231 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1232 flip_image=CloneImage(image,0,0,MagickTrue,exception);
1233 if (flip_image == (Image *) NULL)
1234 return((Image *) NULL);
1241 image_view=AcquireVirtualCacheView(image,exception);
1242 flip_view=AcquireAuthenticCacheView(flip_image,exception);
1243#if defined(MAGICKCORE_OPENMP_SUPPORT)
1244 #pragma omp parallel for schedule(static) shared(status) \
1245 magick_number_threads(image,flip_image,flip_image->rows,2)
1247 for (y=0; y < (ssize_t) flip_image->rows; y++)
1258 if (status == MagickFalse)
1260 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1261 q=QueueCacheViewAuthenticPixels(flip_view,0,((ssize_t) flip_image->rows-y-
1262 1),flip_image->columns,1,exception);
1263 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1268 for (x=0; x < (ssize_t) flip_image->columns; x++)
1273 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1275 PixelChannel channel = GetPixelChannelChannel(image,i);
1276 PixelTrait traits = GetPixelChannelTraits(image,channel);
1277 PixelTrait flip_traits = GetPixelChannelTraits(flip_image,channel);
1278 if ((traits == UndefinedPixelTrait) ||
1279 (flip_traits == UndefinedPixelTrait))
1281 SetPixelChannel(flip_image,channel,p[i],q);
1283 p+=(ptrdiff_t) GetPixelChannels(image);
1284 q+=(ptrdiff_t) GetPixelChannels(flip_image);
1286 if (SyncCacheViewAuthenticPixels(flip_view,exception) == MagickFalse)
1288 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1293#if defined(MAGICKCORE_OPENMP_SUPPORT)
1297 proceed=SetImageProgress(image,FlipImageTag,progress,image->rows);
1298 if (proceed == MagickFalse)
1302 flip_view=DestroyCacheView(flip_view);
1303 image_view=DestroyCacheView(image_view);
1304 flip_image->type=image->type;
1305 if (page.height != 0)
1306 page.y=((ssize_t) page.height-(ssize_t) flip_image->rows-page.y);
1307 flip_image->page=page;
1308 if (status != MagickFalse)
1311 transform[MagickPathExtent];
1313 (void) FormatLocaleString(transform,MagickPathExtent,
1314 "flip %.20gx%.20g",(
double) image->columns,(
double) image->rows);
1315 AppendImageProfileProperty(flip_image,
"hdrgm",
"hdrgm:Transform",
1316 transform,exception);
1318 if (status == MagickFalse)
1319 flip_image=DestroyImage(flip_image);
1348MagickExport Image *FlopImage(
const Image *image,ExceptionInfo *exception)
1350#define FlopImageTag "Flop/Image"
1371 assert(image != (
const Image *) NULL);
1372 assert(image->signature == MagickCoreSignature);
1373 assert(exception != (ExceptionInfo *) NULL);
1374 assert(exception->signature == MagickCoreSignature);
1375 if (IsEventLogging() != MagickFalse)
1376 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1377 flop_image=CloneImage(image,0,0,MagickTrue,exception);
1378 if (flop_image == (Image *) NULL)
1379 return((Image *) NULL);
1386 image_view=AcquireVirtualCacheView(image,exception);
1387 flop_view=AcquireAuthenticCacheView(flop_image,exception);
1388#if defined(MAGICKCORE_OPENMP_SUPPORT)
1389 #pragma omp parallel for schedule(static) shared(status) \
1390 magick_number_threads(image,flop_image,flop_image->rows,2)
1392 for (y=0; y < (ssize_t) flop_image->rows; y++)
1403 if (status == MagickFalse)
1405 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1406 q=QueueCacheViewAuthenticPixels(flop_view,0,y,flop_image->columns,1,
1408 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1413 q+=(ptrdiff_t) GetPixelChannels(flop_image)*flop_image->columns;
1414 for (x=0; x < (ssize_t) flop_image->columns; x++)
1419 q-=GetPixelChannels(flop_image);
1420 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1422 PixelChannel channel = GetPixelChannelChannel(image,i);
1423 PixelTrait traits = GetPixelChannelTraits(image,channel);
1424 PixelTrait flop_traits=GetPixelChannelTraits(flop_image,channel);
1425 if ((traits == UndefinedPixelTrait) ||
1426 (flop_traits == UndefinedPixelTrait))
1428 SetPixelChannel(flop_image,channel,p[i],q);
1430 p+=(ptrdiff_t) GetPixelChannels(image);
1432 if (SyncCacheViewAuthenticPixels(flop_view,exception) == MagickFalse)
1434 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1439#if defined(MAGICKCORE_OPENMP_SUPPORT)
1443 proceed=SetImageProgress(image,FlopImageTag,progress,image->rows);
1444 if (proceed == MagickFalse)
1448 flop_view=DestroyCacheView(flop_view);
1449 image_view=DestroyCacheView(image_view);
1450 flop_image->type=image->type;
1451 if (page.width != 0)
1452 page.x=((ssize_t) page.width-(ssize_t) flop_image->columns-page.x);
1453 flop_image->page=page;
1454 if (status != MagickFalse)
1457 transform[MagickPathExtent];
1459 (void) FormatLocaleString(transform,MagickPathExtent,
1460 "flop %.20gx%.20g",(
double) image->columns,(
double) image->rows);
1461 AppendImageProfileProperty(flop_image,
"hdrgm",
"hdrgm:Transform",
1462 transform,exception);
1464 if (status == MagickFalse)
1465 flop_image=DestroyImage(flop_image);
1499static MagickBooleanType CopyImageRegion(Image *destination,
const Image *source,
const size_t columns,
const size_t rows,
const ssize_t sx,
const ssize_t sy,
1500 const ssize_t dx,
const ssize_t dy,ExceptionInfo *exception)
1515 source_view=AcquireVirtualCacheView(source,exception);
1516 destination_view=AcquireAuthenticCacheView(destination,exception);
1517#if defined(MAGICKCORE_OPENMP_SUPPORT)
1518 #pragma omp parallel for schedule(static) shared(status) \
1519 magick_number_threads(source,destination,rows,2)
1521 for (y=0; y < (ssize_t) rows; y++)
1538 if (status == MagickFalse)
1540 p=GetCacheViewVirtualPixels(source_view,sx,sy+y,columns,1,exception);
1541 q=GetCacheViewAuthenticPixels(destination_view,dx,dy+y,columns,1,exception);
1542 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1547 for (x=0; x < (ssize_t) columns; x++)
1552 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
1554 PixelChannel channel = GetPixelChannelChannel(source,i);
1555 PixelTrait source_traits=GetPixelChannelTraits(source,channel);
1556 PixelTrait destination_traits=GetPixelChannelTraits(destination,
1558 if ((source_traits == UndefinedPixelTrait) ||
1559 (destination_traits == UndefinedPixelTrait))
1561 SetPixelChannel(destination,channel,p[i],q);
1563 p+=(ptrdiff_t) GetPixelChannels(source);
1564 q+=(ptrdiff_t) GetPixelChannels(destination);
1566 sync=SyncCacheViewAuthenticPixels(destination_view,exception);
1567 if (sync == MagickFalse)
1570 destination_view=DestroyCacheView(destination_view);
1571 source_view=DestroyCacheView(source_view);
1575MagickExport Image *RollImage(
const Image *image,
const ssize_t x_offset,
1576 const ssize_t y_offset,ExceptionInfo *exception)
1578#define RollImageTag "Roll/Image"
1592 assert(image != (
const Image *) NULL);
1593 assert(image->signature == MagickCoreSignature);
1594 assert(exception != (ExceptionInfo *) NULL);
1595 assert(exception->signature == MagickCoreSignature);
1596 if (IsEventLogging() != MagickFalse)
1597 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1598 roll_image=CloneImage(image,0,0,MagickTrue,exception);
1599 if (roll_image == (Image *) NULL)
1600 return((Image *) NULL);
1603 while (offset.x < 0)
1604 offset.x+=(ssize_t) image->columns;
1605 while (offset.x >= (ssize_t) image->columns)
1606 offset.x-=(ssize_t) image->columns;
1607 while (offset.y < 0)
1608 offset.y+=(ssize_t) image->rows;
1609 while (offset.y >= (ssize_t) image->rows)
1610 offset.y-=(ssize_t) image->rows;
1614 status=CopyImageRegion(roll_image,image,(
size_t) offset.x,
1615 (
size_t) offset.y,(ssize_t) image->columns-offset.x,(ssize_t) image->rows-
1616 offset.y,0,0,exception);
1617 (void) SetImageProgress(image,RollImageTag,0,3);
1618 status&=(MagickStatusType) CopyImageRegion(roll_image,image,(
size_t)
1619 ((ssize_t) image->columns-offset.x),(
size_t) offset.y,0,(ssize_t)
1620 image->rows-offset.y,offset.x,0,exception);
1621 (void) SetImageProgress(image,RollImageTag,1,3);
1622 status&=(MagickStatusType) CopyImageRegion(roll_image,image,(
size_t)
1623 offset.x,(
size_t) ((ssize_t) image->rows-offset.y),(ssize_t)
1624 image->columns-offset.x,0,0,offset.y,exception);
1625 (void) SetImageProgress(image,RollImageTag,2,3);
1626 status&=(MagickStatusType) CopyImageRegion(roll_image,image,(
size_t)
1627 ((ssize_t) image->columns-offset.x),(
size_t) ((ssize_t) image->rows-
1628 offset.y),0,0,offset.x,offset.y,exception);
1629 (void) SetImageProgress(image,RollImageTag,3,3);
1630 roll_image->type=image->type;
1631 if (status == MagickFalse)
1632 roll_image=DestroyImage(roll_image);
1670MagickExport Image *ShaveImage(
const Image *image,
1671 const RectangleInfo *shave_info,ExceptionInfo *exception)
1679 assert(image != (
const Image *) NULL);
1680 assert(image->signature == MagickCoreSignature);
1681 if (IsEventLogging() != MagickFalse)
1682 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1683 if (((2*shave_info->width) >= image->columns) ||
1684 ((2*shave_info->height) >= image->rows))
1685 ThrowImageException(OptionWarning,
"GeometryDoesNotContainImage");
1686 SetGeometry(image,&geometry);
1687 geometry.width-=2*shave_info->width;
1688 geometry.height-=2*shave_info->height;
1689 geometry.x=(ssize_t) shave_info->width+image->page.x;
1690 geometry.y=(ssize_t) shave_info->height+image->page.y;
1691 shave_image=CropImage(image,&geometry,exception);
1692 if (shave_image == (Image *) NULL)
1693 return((Image *) NULL);
1694 shave_image->page.width-=2*shave_info->width;
1695 shave_image->page.height-=2*shave_info->height;
1696 shave_image->page.x-=(ssize_t) shave_info->width;
1697 shave_image->page.y-=(ssize_t) shave_info->height;
1698 return(shave_image);
1730MagickExport Image *SpliceImage(
const Image *image,
1731 const RectangleInfo *geometry,ExceptionInfo *exception)
1733#define SpliceImageTag "Splice/Image"
1758 assert(image != (
const Image *) NULL);
1759 assert(image->signature == MagickCoreSignature);
1760 if (IsEventLogging() != MagickFalse)
1761 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1762 assert(geometry != (
const RectangleInfo *) NULL);
1763 assert(exception != (ExceptionInfo *) NULL);
1764 assert(exception->signature == MagickCoreSignature);
1765 splice_geometry=(*geometry);
1766 splice_image=CloneImage(image,image->columns+splice_geometry.width,
1767 image->rows+splice_geometry.height,MagickTrue,exception);
1768 if (splice_image == (Image *) NULL)
1769 return((Image *) NULL);
1770 if (SetImageStorageClass(splice_image,DirectClass,exception) == MagickFalse)
1772 splice_image=DestroyImage(splice_image);
1773 return((Image *) NULL);
1775 if ((IsPixelInfoGray(&splice_image->background_color) == MagickFalse) &&
1776 (IsGrayColorspace(splice_image->colorspace) != MagickFalse))
1777 (void) SetImageColorspace(splice_image,sRGBColorspace,exception);
1778 if ((splice_image->background_color.alpha_trait != UndefinedPixelTrait) &&
1779 (splice_image->alpha_trait == UndefinedPixelTrait))
1780 (void) SetImageAlpha(splice_image,OpaqueAlpha,exception);
1781 (void) SetImageBackgroundColor(splice_image,exception);
1785 switch (image->gravity)
1788 case UndefinedGravity:
1789 case NorthWestGravity:
1793 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1796 case NorthEastGravity:
1798 splice_geometry.x+=(ssize_t) splice_geometry.width;
1803 splice_geometry.y+=(ssize_t) splice_geometry.width/2;
1808 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1809 splice_geometry.y+=(ssize_t) splice_geometry.height/2;
1814 splice_geometry.x+=(ssize_t) splice_geometry.width;
1815 splice_geometry.y+=(ssize_t) splice_geometry.height/2;
1818 case SouthWestGravity:
1820 splice_geometry.y+=(ssize_t) splice_geometry.height;
1825 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1826 splice_geometry.y+=(ssize_t) splice_geometry.height;
1829 case SouthEastGravity:
1831 splice_geometry.x+=(ssize_t) splice_geometry.width;
1832 splice_geometry.y+=(ssize_t) splice_geometry.height;
1841 columns=MagickMin(splice_geometry.x,(ssize_t) splice_image->columns);
1842 image_view=AcquireVirtualCacheView(image,exception);
1843 splice_view=AcquireAuthenticCacheView(splice_image,exception);
1844#if defined(MAGICKCORE_OPENMP_SUPPORT)
1845 #pragma omp parallel for schedule(static) shared(progress,status) \
1846 magick_number_threads(image,splice_image,(size_t) splice_geometry.y,2)
1848 for (y=0; y < (ssize_t) splice_geometry.y; y++)
1859 if (status == MagickFalse)
1861 p=GetCacheViewVirtualPixels(image_view,0,y,splice_image->columns,1,
1863 q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
1865 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1870 for (x=0; x < columns; x++)
1875 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1877 PixelChannel channel = GetPixelChannelChannel(image,i);
1878 PixelTrait traits = GetPixelChannelTraits(image,channel);
1879 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1880 if ((traits == UndefinedPixelTrait) ||
1881 (splice_traits == UndefinedPixelTrait))
1883 SetPixelChannel(splice_image,channel,p[i],q);
1885 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1886 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1887 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1888 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1889 p+=(ptrdiff_t) GetPixelChannels(image);
1890 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1892 for ( ; x < (splice_geometry.x+(ssize_t) splice_geometry.width); x++)
1893 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1894 for ( ; x < (ssize_t) splice_image->columns; x++)
1899 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1901 PixelChannel channel = GetPixelChannelChannel(image,i);
1902 PixelTrait traits = GetPixelChannelTraits(image,channel);
1903 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1904 if ((traits == UndefinedPixelTrait) ||
1905 (splice_traits == UndefinedPixelTrait))
1907 SetPixelChannel(splice_image,channel,p[i],q);
1909 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1910 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1911 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1912 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1913 p+=(ptrdiff_t) GetPixelChannels(image);
1914 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1916 if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
1918 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1923#if defined(MAGICKCORE_OPENMP_SUPPORT)
1927 proceed=SetImageProgress(image,SpliceImageTag,progress,
1928 splice_image->rows);
1929 if (proceed == MagickFalse)
1933#if defined(MAGICKCORE_OPENMP_SUPPORT)
1934 #pragma omp parallel for schedule(static) shared(progress,status) \
1935 magick_number_threads(image,splice_image,splice_image->rows,2)
1937 for (y=splice_geometry.y+(ssize_t) splice_geometry.height; y < (ssize_t) splice_image->rows; y++)
1948 if (status == MagickFalse)
1950 if ((y < 0) || (y >= (ssize_t) splice_image->rows))
1952 p=GetCacheViewVirtualPixels(image_view,0,y-(ssize_t) splice_geometry.height,
1953 splice_image->columns,1,exception);
1954 q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
1956 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1961 for (x=0; x < columns; x++)
1966 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1968 PixelChannel channel = GetPixelChannelChannel(image,i);
1969 PixelTrait traits = GetPixelChannelTraits(image,channel);
1970 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1971 if ((traits == UndefinedPixelTrait) ||
1972 (splice_traits == UndefinedPixelTrait))
1974 SetPixelChannel(splice_image,channel,p[i],q);
1976 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1977 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1978 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1979 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1980 p+=(ptrdiff_t) GetPixelChannels(image);
1981 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1983 for ( ; x < (splice_geometry.x+(ssize_t) splice_geometry.width); x++)
1984 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1985 for ( ; x < (ssize_t) splice_image->columns; x++)
1990 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1992 PixelChannel channel = GetPixelChannelChannel(image,i);
1993 PixelTrait traits = GetPixelChannelTraits(image,channel);
1994 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1995 if ((traits == UndefinedPixelTrait) ||
1996 (splice_traits == UndefinedPixelTrait))
1998 SetPixelChannel(splice_image,channel,p[i],q);
2000 SetPixelRed(splice_image,GetPixelRed(image,p),q);
2001 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
2002 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
2003 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
2004 p+=(ptrdiff_t) GetPixelChannels(image);
2005 q+=(ptrdiff_t) GetPixelChannels(splice_image);
2007 if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
2009 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2014#if defined(MAGICKCORE_OPENMP_SUPPORT)
2018 proceed=SetImageProgress(image,SpliceImageTag,progress,
2019 splice_image->rows);
2020 if (proceed == MagickFalse)
2024 splice_view=DestroyCacheView(splice_view);
2025 image_view=DestroyCacheView(image_view);
2026 if (status == MagickFalse)
2027 splice_image=DestroyImage(splice_image);
2028 return(splice_image);
2078MagickPrivate MagickBooleanType TransformImage(Image **image,
2079 const char *crop_geometry,
const char *image_geometry,ExceptionInfo *exception)
2088 assert(image != (Image **) NULL);
2089 assert((*image)->signature == MagickCoreSignature);
2090 if (IsEventLogging() != MagickFalse)
2091 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",(*image)->filename);
2092 transform_image=(*image);
2093 if (crop_geometry != (
const char *) NULL)
2101 crop_image=CropImageToTiles(*image,crop_geometry,exception);
2102 if (crop_image == (Image *) NULL)
2103 transform_image=CloneImage(*image,0,0,MagickTrue,exception);
2106 transform_image=DestroyImage(transform_image);
2107 transform_image=GetFirstImageInList(crop_image);
2109 *image=transform_image;
2111 if (transform_image == (Image *) NULL)
2112 return(MagickFalse);
2116 if (image_geometry == (
const char *) NULL)
2118 (void) ParseRegionGeometry(transform_image,image_geometry,&geometry,
2120 if ((transform_image->columns == geometry.width) &&
2121 (transform_image->rows == geometry.height))
2123 resize_image=ResizeImage(transform_image,geometry.width,geometry.height,
2124 transform_image->filter,exception);
2125 if (resize_image == (Image *) NULL)
2126 return(MagickFalse);
2127 transform_image=DestroyImage(transform_image);
2128 transform_image=resize_image;
2129 *image=transform_image;
2158MagickExport Image *TransposeImage(
const Image *image,ExceptionInfo *exception)
2160#define TransposeImageTag "Transpose/Image"
2181 assert(image != (
const Image *) NULL);
2182 assert(image->signature == MagickCoreSignature);
2183 assert(exception != (ExceptionInfo *) NULL);
2184 assert(exception->signature == MagickCoreSignature);
2185 if (IsEventLogging() != MagickFalse)
2186 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2187 transpose_image=CloneImage(image,image->rows,image->columns,MagickTrue,
2189 if (transpose_image == (Image *) NULL)
2190 return((Image *) NULL);
2196 image_view=AcquireVirtualCacheView(image,exception);
2197 transpose_view=AcquireAuthenticCacheView(transpose_image,exception);
2198#if defined(MAGICKCORE_OPENMP_SUPPORT)
2199 #pragma omp parallel for schedule(static) shared(progress,status) \
2200 magick_number_threads(image,transpose_image,image->rows,2)
2202 for (y=0; y < (ssize_t) image->rows; y++)
2213 if (status == MagickFalse)
2215 p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-y-1,
2216 image->columns,1,exception);
2217 q=QueueCacheViewAuthenticPixels(transpose_view,(ssize_t) image->rows-y-1,
2218 0,1,transpose_image->rows,exception);
2219 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
2224 for (x=0; x < (ssize_t) image->columns; x++)
2229 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2231 PixelChannel channel = GetPixelChannelChannel(image,i);
2232 PixelTrait traits = GetPixelChannelTraits(image,channel);
2233 PixelTrait transpose_traits=GetPixelChannelTraits(transpose_image,
2235 if ((traits == UndefinedPixelTrait) ||
2236 (transpose_traits == UndefinedPixelTrait))
2238 SetPixelChannel(transpose_image,channel,p[i],q);
2240 p+=(ptrdiff_t) GetPixelChannels(image);
2241 q+=(ptrdiff_t) GetPixelChannels(transpose_image);
2243 if (SyncCacheViewAuthenticPixels(transpose_view,exception) == MagickFalse)
2245 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2250#if defined(MAGICKCORE_OPENMP_SUPPORT)
2254 proceed=SetImageProgress(image,TransposeImageTag,progress,image->rows);
2255 if (proceed == MagickFalse)
2259 transpose_view=DestroyCacheView(transpose_view);
2260 image_view=DestroyCacheView(image_view);
2261 transpose_image->type=image->type;
2262 page=transpose_image->page;
2263 Swap(page.width,page.height);
2264 Swap(page.x,page.y);
2265 transpose_image->page=page;
2266 if (status != MagickFalse)
2269 transform[MagickPathExtent];
2271 (void) FormatLocaleString(transform,MagickPathExtent,
2272 "transpose %.20gx%.20g",(
double) image->columns,
2273 (
double) image->rows);
2274 AppendImageProfileProperty(transpose_image,
"hdrgm",
"hdrgm:Transform",
2275 transform,exception);
2277 if (status == MagickFalse)
2278 transpose_image=DestroyImage(transpose_image);
2279 return(transpose_image);
2307MagickExport Image *TransverseImage(
const Image *image,ExceptionInfo *exception)
2309#define TransverseImageTag "Transverse/Image"
2330 assert(image != (
const Image *) NULL);
2331 assert(image->signature == MagickCoreSignature);
2332 assert(exception != (ExceptionInfo *) NULL);
2333 assert(exception->signature == MagickCoreSignature);
2334 if (IsEventLogging() != MagickFalse)
2335 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2336 transverse_image=CloneImage(image,image->rows,image->columns,MagickTrue,
2338 if (transverse_image == (Image *) NULL)
2339 return((Image *) NULL);
2345 image_view=AcquireVirtualCacheView(image,exception);
2346 transverse_view=AcquireAuthenticCacheView(transverse_image,exception);
2347#if defined(MAGICKCORE_OPENMP_SUPPORT)
2348 #pragma omp parallel for schedule(static) shared(progress,status) \
2349 magick_number_threads(image,transverse_image,image->rows,2)
2351 for (y=0; y < (ssize_t) image->rows; y++)
2365 if (status == MagickFalse)
2367 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
2368 q=QueueCacheViewAuthenticPixels(transverse_view,(ssize_t) image->rows-y-1,
2369 0,1,transverse_image->rows,exception);
2370 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
2375 q+=(ptrdiff_t) GetPixelChannels(transverse_image)*image->columns;
2376 for (x=0; x < (ssize_t) image->columns; x++)
2381 q-=GetPixelChannels(transverse_image);
2382 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2384 PixelChannel channel = GetPixelChannelChannel(image,i);
2385 PixelTrait traits = GetPixelChannelTraits(image,channel);
2386 PixelTrait transverse_traits=GetPixelChannelTraits(transverse_image,
2388 if ((traits == UndefinedPixelTrait) ||
2389 (transverse_traits == UndefinedPixelTrait))
2391 SetPixelChannel(transverse_image,channel,p[i],q);
2393 p+=(ptrdiff_t) GetPixelChannels(image);
2395 sync=SyncCacheViewAuthenticPixels(transverse_view,exception);
2396 if (sync == MagickFalse)
2398 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2403#if defined(MAGICKCORE_OPENMP_SUPPORT)
2407 proceed=SetImageProgress(image,TransverseImageTag,progress,image->rows);
2408 if (proceed == MagickFalse)
2412 transverse_view=DestroyCacheView(transverse_view);
2413 image_view=DestroyCacheView(image_view);
2414 transverse_image->type=image->type;
2415 page=transverse_image->page;
2416 Swap(page.width,page.height);
2417 Swap(page.x,page.y);
2418 if (page.width != 0)
2419 page.x=(ssize_t) page.width-(ssize_t) transverse_image->columns-page.x;
2420 if (page.height != 0)
2421 page.y=(ssize_t) page.height-(ssize_t) transverse_image->rows-page.y;
2422 transverse_image->page=page;
2423 if (status != MagickFalse)
2426 transform[MagickPathExtent];
2428 (void) FormatLocaleString(transform,MagickPathExtent,
2429 "transverse %.20gx%.20g",(
double) image->columns,
2430 (
double) image->rows);
2431 AppendImageProfileProperty(transverse_image,
"hdrgm",
"hdrgm:Transform",
2432 transform,exception);
2434 if (status == MagickFalse)
2435 transverse_image=DestroyImage(transverse_image);
2436 return(transverse_image);
2465MagickExport Image *TrimImage(
const Image *image,ExceptionInfo *exception)
2477 assert(image != (
const Image *) NULL);
2478 assert(image->signature == MagickCoreSignature);
2479 if (IsEventLogging() != MagickFalse)
2480 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2481 geometry=GetImageBoundingBox(image,exception);
2482 if ((geometry.width == 0) || (geometry.height == 0))
2487 crop_image=CloneImage(image,1,1,MagickTrue,exception);
2488 if (crop_image == (Image *) NULL)
2489 return((Image *) NULL);
2490 crop_image->background_color.alpha_trait=BlendPixelTrait;
2491 crop_image->background_color.alpha=(MagickRealType) TransparentAlpha;
2492 (void) SetImageBackgroundColor(crop_image,exception);
2493 crop_image->page=image->page;
2494 crop_image->page.x=(-1);
2495 crop_image->page.y=(-1);
2499 artifact=GetImageArtifact(image,
"trim:minSize");
2500 if (artifact != (
const char *) NULL)
2501 (void) ParseAbsoluteGeometry(artifact,&page);
2502 if ((geometry.width < page.width) && (geometry.height < page.height))
2507 switch (image->gravity)
2511 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width)/2;
2512 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height)/2;
2515 case NorthWestGravity:
2517 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width);
2518 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height);
2523 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width)/2;
2524 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height);
2527 case NorthEastGravity:
2529 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height);
2534 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height)/2;
2537 case SouthEastGravity:
2541 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width)/2;
2544 case SouthWestGravity:
2546 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width);
2551 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width);
2552 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height)/2;
2558 geometry.width=page.width;
2559 geometry.height=page.height;
2561 geometry.x+=image->page.x;
2562 geometry.y+=image->page.y;
2563 trim_image=CropImage(image,&geometry,exception);
2564 if (trim_image != (Image *) NULL)
2565 Update8BIMClipPath(trim_image,image->columns,image->rows,&geometry);