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/distort.h"
52 #include "MagickCore/draw.h"
53 #include "MagickCore/effect.h"
54 #include "MagickCore/exception.h"
55 #include "MagickCore/exception-private.h"
56 #include "MagickCore/geometry.h"
57 #include "MagickCore/image.h"
58 #include "MagickCore/memory_.h"
59 #include "MagickCore/layer.h"
60 #include "MagickCore/list.h"
61 #include "MagickCore/monitor.h"
62 #include "MagickCore/monitor-private.h"
63 #include "MagickCore/pixel-accessor.h"
64 #include "MagickCore/profile-private.h"
65 #include "MagickCore/property.h"
66 #include "MagickCore/resource_.h"
67 #include "MagickCore/resize.h"
68 #include "MagickCore/statistic.h"
69 #include "MagickCore/string_.h"
70 #include "MagickCore/thread-private.h"
71 #include "MagickCore/transform.h"
72 #include "MagickCore/transform-private.h"
102 MagickExport
Image *AutoOrientImage(
const Image *image,
108 assert(image != (
const Image *) NULL);
109 assert(image->signature == MagickCoreSignature);
111 assert(exception->signature == MagickCoreSignature);
112 orient_image=(
Image *) NULL;
115 case UndefinedOrientation:
116 case TopLeftOrientation:
119 orient_image=CloneImage(image,0,0,MagickTrue,exception);
122 case TopRightOrientation:
124 orient_image=FlopImage(image,exception);
127 case BottomRightOrientation:
129 orient_image=RotateImage(image,180.0,exception);
132 case BottomLeftOrientation:
134 orient_image=FlipImage(image,exception);
137 case LeftTopOrientation:
139 orient_image=TransposeImage(image,exception);
142 case RightTopOrientation:
144 orient_image=RotateImage(image,90.0,exception);
147 case RightBottomOrientation:
149 orient_image=TransverseImage(image,exception);
152 case LeftBottomOrientation:
154 orient_image=RotateImage(image,270.0,exception);
158 if (orient_image != (
Image *) NULL)
159 orient_image->orientation=TopLeftOrientation;
160 return(orient_image);
194 #define ChopImageTag "Chop/Image"
218 assert(image != (
const Image *) NULL);
219 assert(image->signature == MagickCoreSignature);
221 assert(exception->signature == MagickCoreSignature);
223 if (IsEventLogging() != MagickFalse)
224 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
225 if (((chop_info->x+(ssize_t) chop_info->width) < 0) ||
226 ((chop_info->y+(ssize_t) chop_info->height) < 0) ||
227 (chop_info->x > (ssize_t) image->columns) ||
228 (chop_info->y > (ssize_t) image->rows))
229 ThrowImageException(OptionWarning,
"GeometryDoesNotContainImage");
231 if ((extent.x+(ssize_t) extent.width) > (ssize_t) image->columns)
232 extent.width=(size_t) ((ssize_t) image->columns-extent.x);
233 if ((extent.y+(ssize_t) extent.height) > (ssize_t) image->rows)
234 extent.height=(size_t) ((ssize_t) image->rows-extent.y);
237 extent.width-=(size_t) (-extent.x);
242 extent.height-=(size_t) (-extent.y);
245 chop_image=CloneImage(image,image->columns-extent.width,image->rows-
246 extent.height,MagickTrue,exception);
247 if (chop_image == (
Image *) NULL)
248 return((
Image *) NULL);
254 image_view=AcquireVirtualCacheView(image,exception);
255 chop_view=AcquireAuthenticCacheView(chop_image,exception);
256 #if defined(MAGICKCORE_OPENMP_SUPPORT)
257 #pragma omp parallel for schedule(static) shared(status) \
258 magick_number_threads(image,chop_image,extent.y,1)
260 for (y=0; y < (ssize_t) extent.y; y++)
271 if (status == MagickFalse)
273 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
274 q=QueueCacheViewAuthenticPixels(chop_view,0,y,chop_image->columns,1,
276 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
281 for (x=0; x < (ssize_t) image->columns; x++)
283 if ((x < extent.x) || (x >= (ssize_t) (extent.x+extent.width)))
288 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
290 PixelChannel channel = GetPixelChannelChannel(image,i);
291 PixelTrait traits = GetPixelChannelTraits(image,channel);
292 PixelTrait chop_traits=GetPixelChannelTraits(chop_image,channel);
293 if ((traits == UndefinedPixelTrait) ||
294 (chop_traits == UndefinedPixelTrait))
296 SetPixelChannel(chop_image,channel,p[i],q);
298 q+=GetPixelChannels(chop_image);
300 p+=GetPixelChannels(image);
302 if (SyncCacheViewAuthenticPixels(chop_view,exception) == MagickFalse)
304 if (image->progress_monitor != (MagickProgressMonitor) NULL)
309 #if defined(MAGICKCORE_OPENMP_SUPPORT)
313 proceed=SetImageProgress(image,ChopImageTag,progress,image->rows);
314 if (proceed == MagickFalse)
321 #if defined(MAGICKCORE_OPENMP_SUPPORT)
322 #pragma omp parallel for schedule(static) shared(progress,status) \
323 magick_number_threads(image,chop_image,image->rows-(extent.y+extent.height),1)
325 for (y=0; y < (ssize_t) (image->rows-(extent.y+extent.height)); y++)
336 if (status == MagickFalse)
338 p=GetCacheViewVirtualPixels(image_view,0,extent.y+extent.height+y,
339 image->columns,1,exception);
340 q=QueueCacheViewAuthenticPixels(chop_view,0,extent.y+y,chop_image->columns,
342 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
347 for (x=0; x < (ssize_t) image->columns; x++)
349 if ((x < extent.x) || (x >= (ssize_t) (extent.x+extent.width)))
354 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
356 PixelChannel channel = GetPixelChannelChannel(image,i);
357 PixelTrait traits = GetPixelChannelTraits(image,channel);
358 PixelTrait chop_traits=GetPixelChannelTraits(chop_image,channel);
359 if ((traits == UndefinedPixelTrait) ||
360 (chop_traits == UndefinedPixelTrait))
362 SetPixelChannel(chop_image,channel,p[i],q);
364 q+=GetPixelChannels(chop_image);
366 p+=GetPixelChannels(image);
368 if (SyncCacheViewAuthenticPixels(chop_view,exception) == MagickFalse)
370 if (image->progress_monitor != (MagickProgressMonitor) NULL)
375 #if defined(MAGICKCORE_OPENMP_SUPPORT)
379 proceed=SetImageProgress(image,ChopImageTag,progress,image->rows);
380 if (proceed == MagickFalse)
384 chop_view=DestroyCacheView(chop_view);
385 image_view=DestroyCacheView(image_view);
386 chop_image->type=image->type;
387 if (status == MagickFalse)
388 chop_image=DestroyImage(chop_image);
417 MagickExport
Image *ConsolidateCMYKImages(
const Image *images,
437 assert(images != (
Image *) NULL);
438 assert(images->signature == MagickCoreSignature);
440 assert(exception->signature == MagickCoreSignature);
441 if (IsEventLogging() != MagickFalse)
442 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
443 cmyk_images=NewImageList();
444 for (j=0; j < (ssize_t) GetImageListLength(images); j+=4)
449 assert(images != (
Image *) NULL);
450 cmyk_image=CloneImage(images,0,0,MagickTrue,
452 if (cmyk_image == (
Image *) NULL)
454 if (SetImageStorageClass(cmyk_image,DirectClass,exception) == MagickFalse)
456 (void) SetImageColorspace(cmyk_image,CMYKColorspace,exception);
457 for (i=0; i < 4; i++)
459 image_view=AcquireVirtualCacheView(images,exception);
460 cmyk_view=AcquireAuthenticCacheView(cmyk_image,exception);
461 for (y=0; y < (ssize_t) images->rows; y++)
472 p=GetCacheViewVirtualPixels(image_view,0,y,images->columns,1,exception);
473 q=QueueCacheViewAuthenticPixels(cmyk_view,0,y,cmyk_image->columns,1,
475 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
477 for (x=0; x < (ssize_t) images->columns; x++)
482 pixel=ClampToQuantum(QuantumRange-GetPixelIntensity(images,p));
485 case 0: SetPixelCyan(cmyk_image,pixel,q);
break;
486 case 1: SetPixelMagenta(cmyk_image,pixel,q);
break;
487 case 2: SetPixelYellow(cmyk_image,pixel,q);
break;
488 case 3: SetPixelBlack(cmyk_image,pixel,q);
break;
491 p+=GetPixelChannels(images);
492 q+=GetPixelChannels(cmyk_image);
494 if (SyncCacheViewAuthenticPixels(cmyk_view,exception) == MagickFalse)
497 cmyk_view=DestroyCacheView(cmyk_view);
498 image_view=DestroyCacheView(image_view);
499 images=GetNextImageInList(images);
500 if (images == (
Image *) NULL)
503 AppendImageToList(&cmyk_images,cmyk_image);
541 #define CropImageTag "Crop/Image"
569 assert(image != (
const Image *) NULL);
570 assert(image->signature == MagickCoreSignature);
573 assert(exception->signature == MagickCoreSignature);
574 if (IsEventLogging() != MagickFalse)
575 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
576 bounding_box=image->page;
577 if ((bounding_box.width == 0) || (bounding_box.height == 0))
579 bounding_box.width=image->columns;
580 bounding_box.height=image->rows;
584 page.width=bounding_box.width;
585 if (page.height == 0)
586 page.height=bounding_box.height;
587 if (((bounding_box.x-page.x) >= (ssize_t) page.width) ||
588 ((bounding_box.y-page.y) >= (ssize_t) page.height) ||
589 ((page.x-bounding_box.x) > (ssize_t) image->columns) ||
590 ((page.y-bounding_box.y) > (ssize_t) image->rows))
595 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
596 "GeometryDoesNotContainImage",
"(\"%.20gx%.20g%+.20g%+.20g\") `%s'",
597 (double) geometry->width,(
double) geometry->height,
598 (double) geometry->x,(
double) geometry->y,image->filename);
599 crop_image=CloneImage(image,1,1,MagickTrue,exception);
600 if (crop_image == (
Image *) NULL)
601 return((
Image *) NULL);
602 crop_image->background_color.alpha_trait=BlendPixelTrait;
603 crop_image->background_color.alpha=(MagickRealType) TransparentAlpha;
604 (void) SetImageBackgroundColor(crop_image,exception);
605 crop_image->page=bounding_box;
606 crop_image->page.x=(-1);
607 crop_image->page.y=(-1);
608 if (crop_image->dispose == BackgroundDispose)
609 crop_image->dispose=NoneDispose;
612 if ((page.x < 0) && (bounding_box.x >= 0))
614 page.width+=page.x-bounding_box.x;
619 page.width-=bounding_box.x-page.x;
620 page.x-=bounding_box.x;
624 if ((page.y < 0) && (bounding_box.y >= 0))
626 page.height+=page.y-bounding_box.y;
631 page.height-=bounding_box.y-page.y;
632 page.y-=bounding_box.y;
636 if ((page.x+(ssize_t) page.width) > (ssize_t) image->columns)
637 page.width=image->columns-page.x;
638 if ((geometry->width != 0) && (page.width > geometry->width))
639 page.width=geometry->width;
640 if ((page.y+(ssize_t) page.height) > (ssize_t) image->rows)
641 page.height=image->rows-page.y;
642 if ((geometry->height != 0) && (page.height > geometry->height))
643 page.height=geometry->height;
644 bounding_box.x+=page.x;
645 bounding_box.y+=page.y;
646 if ((page.width == 0) || (page.height == 0))
648 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
649 "GeometryDoesNotContainImage",
"`%s'",image->filename);
650 return((
Image *) NULL);
655 crop_image=CloneImage(image,page.width,page.height,MagickTrue,exception);
656 if (crop_image == (
Image *) NULL)
657 return((
Image *) NULL);
658 crop_image->page.width=image->page.width;
659 crop_image->page.height=image->page.height;
660 offset.x=(ssize_t) (bounding_box.x+bounding_box.width);
661 offset.y=(ssize_t) (bounding_box.y+bounding_box.height);
662 if ((offset.x > (ssize_t) image->page.width) ||
663 (offset.y > (ssize_t) image->page.height))
665 crop_image->page.width=bounding_box.width;
666 crop_image->page.height=bounding_box.height;
668 crop_image->page.x=bounding_box.x;
669 crop_image->page.y=bounding_box.y;
675 image_view=AcquireVirtualCacheView(image,exception);
676 crop_view=AcquireAuthenticCacheView(crop_image,exception);
677 #if defined(MAGICKCORE_OPENMP_SUPPORT)
678 #pragma omp parallel for schedule(static) shared(status) \
679 magick_number_threads(image,crop_image,crop_image->rows,1)
681 for (y=0; y < (ssize_t) crop_image->rows; y++)
692 if (status == MagickFalse)
694 p=GetCacheViewVirtualPixels(image_view,page.x,page.y+y,crop_image->columns,
696 q=QueueCacheViewAuthenticPixels(crop_view,0,y,crop_image->columns,1,
698 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
703 for (x=0; x < (ssize_t) crop_image->columns; x++)
708 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
710 PixelChannel channel = GetPixelChannelChannel(image,i);
711 PixelTrait traits = GetPixelChannelTraits(image,channel);
712 PixelTrait crop_traits=GetPixelChannelTraits(crop_image,channel);
713 if ((traits == UndefinedPixelTrait) ||
714 (crop_traits == UndefinedPixelTrait))
716 SetPixelChannel(crop_image,channel,p[i],q);
718 p+=GetPixelChannels(image);
719 q+=GetPixelChannels(crop_image);
721 if (SyncCacheViewAuthenticPixels(crop_view,exception) == MagickFalse)
723 if (image->progress_monitor != (MagickProgressMonitor) NULL)
728 #if defined(MAGICKCORE_OPENMP_SUPPORT)
732 proceed=SetImageProgress(image,CropImageTag,progress,image->rows);
733 if (proceed == MagickFalse)
737 crop_view=DestroyCacheView(crop_view);
738 image_view=DestroyCacheView(image_view);
739 crop_image->type=image->type;
740 if (status == MagickFalse)
741 crop_image=DestroyImage(crop_image);
773 static inline ssize_t PixelRoundOffset(
double x)
778 if ((x-floor(x)) < (ceil(x)-x))
779 return(CastDoubleToLong(floor(x)));
780 return(CastDoubleToLong(ceil(x)));
783 MagickExport
Image *CropImageToTiles(
const Image *image,
796 assert(image != (
Image *) NULL);
797 assert(image->signature == MagickCoreSignature);
798 if (IsEventLogging() != MagickFalse)
799 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
800 flags=ParseGravityGeometry(image,crop_geometry,&geometry,exception);
801 if ((flags & AreaValue) != 0)
817 crop_image=NewImageList();
818 width=image->columns;
820 if (geometry.width == 0)
822 if (geometry.height == 0)
824 if ((flags & AspectValue) == 0)
826 width-=(geometry.x < 0 ? -1 : 1)*geometry.x;
827 height-=(geometry.y < 0 ? -1 : 1)*geometry.y;
831 width+=(geometry.x < 0 ? -1 : 1)*geometry.x;
832 height+=(geometry.y < 0 ? -1 : 1)*geometry.y;
834 delta.x=(double) width/geometry.width;
835 delta.y=(
double) height/geometry.height;
840 for (offset.y=0; offset.y < (
double) height; )
842 if ((flags & AspectValue) == 0)
844 crop.y=PixelRoundOffset((
double) (offset.y-
845 (geometry.y > 0 ? 0 : geometry.y)));
847 crop.height=(size_t) PixelRoundOffset((
double) (offset.y+
848 (geometry.y < 0 ? 0 : geometry.y)));
852 crop.y=PixelRoundOffset((
double) (offset.y-
853 (geometry.y > 0 ? geometry.y : 0)));
855 crop.height=(size_t) PixelRoundOffset((
double)
856 (offset.y+(geometry.y < -1 ? geometry.y : 0)));
859 crop.y+=image->page.y;
860 for (offset.x=0; offset.x < (
double) width; )
862 if ((flags & AspectValue) == 0)
864 crop.x=PixelRoundOffset((
double) (offset.x-
865 (geometry.x > 0 ? 0 : geometry.x)));
867 crop.width=(size_t) PixelRoundOffset((
double) (offset.x+
868 (geometry.x < 0 ? 0 : geometry.x)));
872 crop.x=PixelRoundOffset((
double) (offset.x-
873 (geometry.x > 0 ? geometry.x : 0)));
875 crop.width=(size_t) PixelRoundOffset((
double) (offset.x+
876 (geometry.x < 0 ? geometry.x : 0)));
879 crop.x+=image->page.x;
880 next=CropImage(image,&crop,exception);
881 if (next != (
Image *) NULL)
882 AppendImageToList(&crop_image,next);
885 ClearMagickException(exception);
888 if (((geometry.width == 0) && (geometry.height == 0)) ||
889 ((flags & XValue) != 0) || ((flags & YValue) != 0))
894 crop_image=CropImage(image,&geometry,exception);
895 if ((crop_image != (
Image *) NULL) && ((flags & AspectValue) != 0))
897 crop_image->page.width=geometry.width;
898 crop_image->page.height=geometry.height;
899 crop_image->page.x-=geometry.x;
900 crop_image->page.y-=geometry.y;
904 if ((image->columns > geometry.width) || (image->rows > geometry.height))
922 page.width=image->columns;
923 if (page.height == 0)
924 page.height=image->rows;
925 width=geometry.width;
928 height=geometry.height;
932 crop_image=NewImageList();
933 for (y=0; y < (ssize_t) page.height; y+=(ssize_t) height)
935 for (x=0; x < (ssize_t) page.width; x+=(ssize_t) width)
937 geometry.width=width;
938 geometry.height=height;
941 next=CropImage(image,&geometry,exception);
942 if (next == (
Image *) NULL)
944 AppendImageToList(&crop_image,next);
946 if (next == (
Image *) NULL)
951 return(CloneImage(image,0,0,MagickTrue,exception));
982 MagickExport
Image *ExcerptImage(
const Image *image,
985 #define ExcerptImageTag "Excerpt/Image"
1006 assert(image != (
const Image *) NULL);
1007 assert(image->signature == MagickCoreSignature);
1010 assert(exception->signature == MagickCoreSignature);
1011 if (IsEventLogging() != MagickFalse)
1012 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1013 excerpt_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
1015 if (excerpt_image == (
Image *) NULL)
1016 return((
Image *) NULL);
1022 image_view=AcquireVirtualCacheView(image,exception);
1023 excerpt_view=AcquireAuthenticCacheView(excerpt_image,exception);
1024 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1025 #pragma omp parallel for schedule(static) shared(progress,status) \
1026 magick_number_threads(image,excerpt_image,excerpt_image->rows,1)
1028 for (y=0; y < (ssize_t) excerpt_image->rows; y++)
1039 if (status == MagickFalse)
1041 p=GetCacheViewVirtualPixels(image_view,geometry->x,geometry->y+y,
1042 geometry->width,1,exception);
1043 q=GetCacheViewAuthenticPixels(excerpt_view,0,y,excerpt_image->columns,1,
1045 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1050 for (x=0; x < (ssize_t) excerpt_image->columns; x++)
1055 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1057 PixelChannel channel = GetPixelChannelChannel(image,i);
1058 PixelTrait traits = GetPixelChannelTraits(image,channel);
1059 PixelTrait excerpt_traits=GetPixelChannelTraits(excerpt_image,channel);
1060 if ((traits == UndefinedPixelTrait) ||
1061 (excerpt_traits == UndefinedPixelTrait))
1063 SetPixelChannel(excerpt_image,channel,p[i],q);
1065 p+=GetPixelChannels(image);
1066 q+=GetPixelChannels(excerpt_image);
1068 if (SyncCacheViewAuthenticPixels(excerpt_view,exception) == MagickFalse)
1070 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1075 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1079 proceed=SetImageProgress(image,ExcerptImageTag,progress,image->rows);
1080 if (proceed == MagickFalse)
1084 excerpt_view=DestroyCacheView(excerpt_view);
1085 image_view=DestroyCacheView(image_view);
1086 excerpt_image->type=image->type;
1087 if (status == MagickFalse)
1088 excerpt_image=DestroyImage(excerpt_image);
1089 return(excerpt_image);
1122 MagickExport
Image *ExtentImage(
const Image *image,
1134 assert(image != (
const Image *) NULL);
1135 assert(image->signature == MagickCoreSignature);
1138 assert(exception->signature == MagickCoreSignature);
1139 if (IsEventLogging() != MagickFalse)
1140 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1141 extent_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
1143 if (extent_image == (
Image *) NULL)
1144 return((
Image *) NULL);
1145 status=SetImageBackgroundColor(extent_image,exception);
1146 if (status == MagickFalse)
1148 extent_image=DestroyImage(extent_image);
1149 return((
Image *) NULL);
1151 status=CompositeImage(extent_image,image,image->compose,MagickTrue,
1152 -geometry->x,-geometry->y,exception);
1153 if (status != MagickFalse)
1154 Update8BIMClipPath(extent_image,image->columns,image->rows,geometry);
1155 return(extent_image);
1185 #define FlipImageTag "Flip/Image"
1206 assert(image != (
const Image *) NULL);
1207 assert(image->signature == MagickCoreSignature);
1209 assert(exception->signature == MagickCoreSignature);
1210 if (IsEventLogging() != MagickFalse)
1211 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1212 flip_image=CloneImage(image,0,0,MagickTrue,exception);
1213 if (flip_image == (
Image *) NULL)
1214 return((
Image *) NULL);
1221 image_view=AcquireVirtualCacheView(image,exception);
1222 flip_view=AcquireAuthenticCacheView(flip_image,exception);
1223 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1224 #pragma omp parallel for schedule(static) shared(status) \
1225 magick_number_threads(image,flip_image,flip_image->rows,1)
1227 for (y=0; y < (ssize_t) flip_image->rows; y++)
1238 if (status == MagickFalse)
1240 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1241 q=QueueCacheViewAuthenticPixels(flip_view,0,(ssize_t) (flip_image->rows-y-
1242 1),flip_image->columns,1,exception);
1243 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1248 for (x=0; x < (ssize_t) flip_image->columns; x++)
1253 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1255 PixelChannel channel = GetPixelChannelChannel(image,i);
1256 PixelTrait traits = GetPixelChannelTraits(image,channel);
1257 PixelTrait flip_traits=GetPixelChannelTraits(flip_image,channel);
1258 if ((traits == UndefinedPixelTrait) ||
1259 (flip_traits == UndefinedPixelTrait))
1261 SetPixelChannel(flip_image,channel,p[i],q);
1263 p+=GetPixelChannels(image);
1264 q+=GetPixelChannels(flip_image);
1266 if (SyncCacheViewAuthenticPixels(flip_view,exception) == MagickFalse)
1268 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1273 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1277 proceed=SetImageProgress(image,FlipImageTag,progress,image->rows);
1278 if (proceed == MagickFalse)
1282 flip_view=DestroyCacheView(flip_view);
1283 image_view=DestroyCacheView(image_view);
1284 flip_image->type=image->type;
1285 if (page.height != 0)
1286 page.y=(ssize_t) (page.height-flip_image->rows-page.y);
1287 flip_image->page=page;
1288 if (status == MagickFalse)
1289 flip_image=DestroyImage(flip_image);
1320 #define FlopImageTag "Flop/Image"
1341 assert(image != (
const Image *) NULL);
1342 assert(image->signature == MagickCoreSignature);
1344 assert(exception->signature == MagickCoreSignature);
1345 if (IsEventLogging() != MagickFalse)
1346 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1347 flop_image=CloneImage(image,0,0,MagickTrue,exception);
1348 if (flop_image == (
Image *) NULL)
1349 return((
Image *) NULL);
1356 image_view=AcquireVirtualCacheView(image,exception);
1357 flop_view=AcquireAuthenticCacheView(flop_image,exception);
1358 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1359 #pragma omp parallel for schedule(static) shared(status) \
1360 magick_number_threads(image,flop_image,flop_image->rows,1)
1362 for (y=0; y < (ssize_t) flop_image->rows; y++)
1373 if (status == MagickFalse)
1375 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1376 q=QueueCacheViewAuthenticPixels(flop_view,0,y,flop_image->columns,1,
1378 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1383 q+=GetPixelChannels(flop_image)*flop_image->columns;
1384 for (x=0; x < (ssize_t) flop_image->columns; x++)
1389 q-=GetPixelChannels(flop_image);
1390 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1392 PixelChannel channel = GetPixelChannelChannel(image,i);
1393 PixelTrait traits = GetPixelChannelTraits(image,channel);
1394 PixelTrait flop_traits=GetPixelChannelTraits(flop_image,channel);
1395 if ((traits == UndefinedPixelTrait) ||
1396 (flop_traits == UndefinedPixelTrait))
1398 SetPixelChannel(flop_image,channel,p[i],q);
1400 p+=GetPixelChannels(image);
1402 if (SyncCacheViewAuthenticPixels(flop_view,exception) == MagickFalse)
1404 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1409 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1413 proceed=SetImageProgress(image,FlopImageTag,progress,image->rows);
1414 if (proceed == MagickFalse)
1418 flop_view=DestroyCacheView(flop_view);
1419 image_view=DestroyCacheView(image_view);
1420 flop_image->type=image->type;
1421 if (page.width != 0)
1422 page.x=(ssize_t) (page.width-flop_image->columns-page.x);
1423 flop_image->page=page;
1424 if (status == MagickFalse)
1425 flop_image=DestroyImage(flop_image);
1459 static MagickBooleanType CopyImageRegion(
Image *destination,
const Image *source,
const size_t columns,
const size_t rows,
const ssize_t sx,
const ssize_t sy,
1475 source_view=AcquireVirtualCacheView(source,exception);
1476 destination_view=AcquireAuthenticCacheView(destination,exception);
1477 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1478 #pragma omp parallel for schedule(static) shared(status) \
1479 magick_number_threads(source,destination,rows,1)
1481 for (y=0; y < (ssize_t) rows; y++)
1498 if (status == MagickFalse)
1500 p=GetCacheViewVirtualPixels(source_view,sx,sy+y,columns,1,exception);
1501 q=GetCacheViewAuthenticPixels(destination_view,dx,dy+y,columns,1,exception);
1502 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1507 for (x=0; x < (ssize_t) columns; x++)
1512 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
1514 PixelChannel channel = GetPixelChannelChannel(source,i);
1515 PixelTrait source_traits=GetPixelChannelTraits(source,channel);
1516 PixelTrait destination_traits=GetPixelChannelTraits(destination,
1518 if ((source_traits == UndefinedPixelTrait) ||
1519 (destination_traits == UndefinedPixelTrait))
1521 SetPixelChannel(destination,channel,p[i],q);
1523 p+=GetPixelChannels(source);
1524 q+=GetPixelChannels(destination);
1526 sync=SyncCacheViewAuthenticPixels(destination_view,exception);
1527 if (sync == MagickFalse)
1530 destination_view=DestroyCacheView(destination_view);
1531 source_view=DestroyCacheView(source_view);
1535 MagickExport
Image *RollImage(
const Image *image,
const ssize_t x_offset,
1538 #define RollImageTag "Roll/Image"
1552 assert(image != (
const Image *) NULL);
1553 assert(image->signature == MagickCoreSignature);
1555 assert(exception->signature == MagickCoreSignature);
1556 if (IsEventLogging() != MagickFalse)
1557 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1558 roll_image=CloneImage(image,0,0,MagickTrue,exception);
1559 if (roll_image == (
Image *) NULL)
1560 return((
Image *) NULL);
1563 while (offset.x < 0)
1564 offset.x+=(ssize_t) image->columns;
1565 while (offset.x >= (ssize_t) image->columns)
1566 offset.x-=(ssize_t) image->columns;
1567 while (offset.y < 0)
1568 offset.y+=(ssize_t) image->rows;
1569 while (offset.y >= (ssize_t) image->rows)
1570 offset.y-=(ssize_t) image->rows;
1574 status=CopyImageRegion(roll_image,image,(
size_t) offset.x,
1575 (
size_t) offset.y,(ssize_t) image->columns-offset.x,(ssize_t) image->rows-
1576 offset.y,0,0,exception);
1577 (void) SetImageProgress(image,RollImageTag,0,3);
1578 status&=CopyImageRegion(roll_image,image,image->columns-offset.x,
1579 (
size_t) offset.y,0,(ssize_t) image->rows-offset.y,offset.x,0,
1581 (void) SetImageProgress(image,RollImageTag,1,3);
1582 status&=CopyImageRegion(roll_image,image,(
size_t) offset.x,image->rows-
1583 offset.y,(ssize_t) image->columns-offset.x,0,0,offset.y,exception);
1584 (void) SetImageProgress(image,RollImageTag,2,3);
1585 status&=CopyImageRegion(roll_image,image,image->columns-offset.x,image->rows-
1586 offset.y,0,0,offset.x,offset.y,exception);
1587 (void) SetImageProgress(image,RollImageTag,3,3);
1588 roll_image->type=image->type;
1589 if (status == MagickFalse)
1590 roll_image=DestroyImage(roll_image);
1628 MagickExport
Image *ShaveImage(
const Image *image,
1637 assert(image != (
const Image *) NULL);
1638 assert(image->signature == MagickCoreSignature);
1639 if (IsEventLogging() != MagickFalse)
1640 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1641 if (((2*shave_info->width) >= image->columns) ||
1642 ((2*shave_info->height) >= image->rows))
1643 ThrowImageException(OptionWarning,
"GeometryDoesNotContainImage");
1644 SetGeometry(image,&geometry);
1645 geometry.width-=2*shave_info->width;
1646 geometry.height-=2*shave_info->height;
1647 geometry.x=(ssize_t) shave_info->width+image->page.x;
1648 geometry.y=(ssize_t) shave_info->height+image->page.y;
1649 shave_image=CropImage(image,&geometry,exception);
1650 if (shave_image == (
Image *) NULL)
1651 return((
Image *) NULL);
1652 shave_image->page.width-=2*shave_info->width;
1653 shave_image->page.height-=2*shave_info->height;
1654 shave_image->page.x-=(ssize_t) shave_info->width;
1655 shave_image->page.y-=(ssize_t) shave_info->height;
1656 return(shave_image);
1688 MagickExport
Image *SpliceImage(
const Image *image,
1691 #define SpliceImageTag "Splice/Image"
1716 assert(image != (
const Image *) NULL);
1717 assert(image->signature == MagickCoreSignature);
1718 if (IsEventLogging() != MagickFalse)
1719 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1722 assert(exception->signature == MagickCoreSignature);
1723 splice_geometry=(*geometry);
1724 splice_image=CloneImage(image,image->columns+splice_geometry.width,
1725 image->rows+splice_geometry.height,MagickTrue,exception);
1726 if (splice_image == (
Image *) NULL)
1727 return((
Image *) NULL);
1728 if (SetImageStorageClass(splice_image,DirectClass,exception) == MagickFalse)
1730 splice_image=DestroyImage(splice_image);
1731 return((
Image *) NULL);
1733 if ((IsPixelInfoGray(&splice_image->background_color) == MagickFalse) &&
1734 (IsGrayColorspace(splice_image->colorspace) != MagickFalse))
1735 (void) SetImageColorspace(splice_image,sRGBColorspace,exception);
1736 if ((splice_image->background_color.alpha_trait != UndefinedPixelTrait) &&
1737 (splice_image->alpha_trait == UndefinedPixelTrait))
1738 (void) SetImageAlpha(splice_image,OpaqueAlpha,exception);
1739 (void) SetImageBackgroundColor(splice_image,exception);
1743 switch (image->gravity)
1746 case UndefinedGravity:
1747 case NorthWestGravity:
1751 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1754 case NorthEastGravity:
1756 splice_geometry.x+=(ssize_t) splice_geometry.width;
1761 splice_geometry.y+=(ssize_t) splice_geometry.width/2;
1766 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1767 splice_geometry.y+=(ssize_t) splice_geometry.height/2;
1772 splice_geometry.x+=(ssize_t) splice_geometry.width;
1773 splice_geometry.y+=(ssize_t) splice_geometry.height/2;
1776 case SouthWestGravity:
1778 splice_geometry.y+=(ssize_t) splice_geometry.height;
1783 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1784 splice_geometry.y+=(ssize_t) splice_geometry.height;
1787 case SouthEastGravity:
1789 splice_geometry.x+=(ssize_t) splice_geometry.width;
1790 splice_geometry.y+=(ssize_t) splice_geometry.height;
1799 columns=MagickMin(splice_geometry.x,(ssize_t) splice_image->columns);
1800 image_view=AcquireVirtualCacheView(image,exception);
1801 splice_view=AcquireAuthenticCacheView(splice_image,exception);
1802 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1803 #pragma omp parallel for schedule(static) shared(progress,status) \
1804 magick_number_threads(image,splice_image,splice_geometry.y,1)
1806 for (y=0; y < (ssize_t) splice_geometry.y; y++)
1817 if (status == MagickFalse)
1819 p=GetCacheViewVirtualPixels(image_view,0,y,splice_image->columns,1,
1821 q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
1823 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1828 for (x=0; x < columns; x++)
1833 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1835 PixelChannel channel = GetPixelChannelChannel(image,i);
1836 PixelTrait traits = GetPixelChannelTraits(image,channel);
1837 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1838 if ((traits == UndefinedPixelTrait) ||
1839 (splice_traits == UndefinedPixelTrait))
1841 SetPixelChannel(splice_image,channel,p[i],q);
1843 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1844 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1845 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1846 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1847 p+=GetPixelChannels(image);
1848 q+=GetPixelChannels(splice_image);
1850 for ( ; x < (ssize_t) (splice_geometry.x+splice_geometry.width); x++)
1851 q+=GetPixelChannels(splice_image);
1852 for ( ; x < (ssize_t) splice_image->columns; x++)
1857 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1859 PixelChannel channel = GetPixelChannelChannel(image,i);
1860 PixelTrait traits = GetPixelChannelTraits(image,channel);
1861 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1862 if ((traits == UndefinedPixelTrait) ||
1863 (splice_traits == UndefinedPixelTrait))
1865 SetPixelChannel(splice_image,channel,p[i],q);
1867 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1868 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1869 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1870 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1871 p+=GetPixelChannels(image);
1872 q+=GetPixelChannels(splice_image);
1874 if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
1876 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1881 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1885 proceed=SetImageProgress(image,SpliceImageTag,progress,
1886 splice_image->rows);
1887 if (proceed == MagickFalse)
1891 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1892 #pragma omp parallel for schedule(static) shared(progress,status) \
1893 magick_number_threads(image,splice_image,splice_image->rows,2)
1895 for (y=(ssize_t) (splice_geometry.y+splice_geometry.height);
1896 y < (ssize_t) splice_image->rows; y++)
1907 if (status == MagickFalse)
1909 if ((y < 0) || (y >= (ssize_t)splice_image->rows))
1911 p=GetCacheViewVirtualPixels(image_view,0,y-(ssize_t) splice_geometry.height,
1912 splice_image->columns,1,exception);
1913 q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
1915 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1920 for (x=0; x < columns; x++)
1925 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1927 PixelChannel channel = GetPixelChannelChannel(image,i);
1928 PixelTrait traits = GetPixelChannelTraits(image,channel);
1929 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1930 if ((traits == UndefinedPixelTrait) ||
1931 (splice_traits == UndefinedPixelTrait))
1933 SetPixelChannel(splice_image,channel,p[i],q);
1935 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1936 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1937 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1938 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1939 p+=GetPixelChannels(image);
1940 q+=GetPixelChannels(splice_image);
1942 for ( ; x < (ssize_t) (splice_geometry.x+splice_geometry.width); x++)
1943 q+=GetPixelChannels(splice_image);
1944 for ( ; x < (ssize_t) splice_image->columns; x++)
1949 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1951 PixelChannel channel = GetPixelChannelChannel(image,i);
1952 PixelTrait traits = GetPixelChannelTraits(image,channel);
1953 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1954 if ((traits == UndefinedPixelTrait) ||
1955 (splice_traits == UndefinedPixelTrait))
1957 SetPixelChannel(splice_image,channel,p[i],q);
1959 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1960 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1961 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1962 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1963 p+=GetPixelChannels(image);
1964 q+=GetPixelChannels(splice_image);
1966 if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
1968 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1973 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1977 proceed=SetImageProgress(image,SpliceImageTag,progress,
1978 splice_image->rows);
1979 if (proceed == MagickFalse)
1983 splice_view=DestroyCacheView(splice_view);
1984 image_view=DestroyCacheView(image_view);
1985 if (status == MagickFalse)
1986 splice_image=DestroyImage(splice_image);
1987 return(splice_image);
2037 MagickPrivate MagickBooleanType TransformImage(
Image **image,
2038 const char *crop_geometry,
const char *image_geometry,
ExceptionInfo *exception)
2047 assert(image != (
Image **) NULL);
2048 assert((*image)->signature == MagickCoreSignature);
2049 if (IsEventLogging() != MagickFalse)
2050 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",(*image)->filename);
2051 transform_image=(*image);
2052 if (crop_geometry != (
const char *) NULL)
2060 crop_image=CropImageToTiles(*image,crop_geometry,exception);
2061 if (crop_image == (
Image *) NULL)
2062 transform_image=CloneImage(*image,0,0,MagickTrue,exception);
2065 transform_image=DestroyImage(transform_image);
2066 transform_image=GetFirstImageInList(crop_image);
2068 *image=transform_image;
2070 if (image_geometry == (
const char *) NULL)
2075 (void) ParseRegionGeometry(transform_image,image_geometry,&geometry,
2077 if ((transform_image->columns == geometry.width) &&
2078 (transform_image->rows == geometry.height))
2080 resize_image=ResizeImage(transform_image,geometry.width,geometry.height,
2081 transform_image->filter,exception);
2082 if (resize_image == (
Image *) NULL)
2083 return(MagickFalse);
2084 transform_image=DestroyImage(transform_image);
2085 transform_image=resize_image;
2086 *image=transform_image;
2117 #define TransposeImageTag "Transpose/Image"
2138 assert(image != (
const Image *) NULL);
2139 assert(image->signature == MagickCoreSignature);
2141 assert(exception->signature == MagickCoreSignature);
2142 if (IsEventLogging() != MagickFalse)
2143 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2144 transpose_image=CloneImage(image,image->rows,image->columns,MagickTrue,
2146 if (transpose_image == (
Image *) NULL)
2147 return((
Image *) NULL);
2153 image_view=AcquireVirtualCacheView(image,exception);
2154 transpose_view=AcquireAuthenticCacheView(transpose_image,exception);
2155 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2156 #pragma omp parallel for schedule(static) shared(progress,status) \
2157 magick_number_threads(image,transpose_image,image->rows,1)
2159 for (y=0; y < (ssize_t) image->rows; y++)
2170 if (status == MagickFalse)
2172 p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-y-1,
2173 image->columns,1,exception);
2174 q=QueueCacheViewAuthenticPixels(transpose_view,(ssize_t) (image->rows-y-1),
2175 0,1,transpose_image->rows,exception);
2176 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
2181 for (x=0; x < (ssize_t) image->columns; x++)
2186 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2188 PixelChannel channel = GetPixelChannelChannel(image,i);
2189 PixelTrait traits = GetPixelChannelTraits(image,channel);
2190 PixelTrait transpose_traits=GetPixelChannelTraits(transpose_image,
2192 if ((traits == UndefinedPixelTrait) ||
2193 (transpose_traits == UndefinedPixelTrait))
2195 SetPixelChannel(transpose_image,channel,p[i],q);
2197 p+=GetPixelChannels(image);
2198 q+=GetPixelChannels(transpose_image);
2200 if (SyncCacheViewAuthenticPixels(transpose_view,exception) == MagickFalse)
2202 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2207 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2211 proceed=SetImageProgress(image,TransposeImageTag,progress,image->rows);
2212 if (proceed == MagickFalse)
2216 transpose_view=DestroyCacheView(transpose_view);
2217 image_view=DestroyCacheView(image_view);
2218 transpose_image->type=image->type;
2219 page=transpose_image->page;
2220 Swap(page.width,page.height);
2221 Swap(page.x,page.y);
2222 transpose_image->page=page;
2223 if (status == MagickFalse)
2224 transpose_image=DestroyImage(transpose_image);
2225 return(transpose_image);
2255 #define TransverseImageTag "Transverse/Image"
2276 assert(image != (
const Image *) NULL);
2277 assert(image->signature == MagickCoreSignature);
2279 assert(exception->signature == MagickCoreSignature);
2280 if (IsEventLogging() != MagickFalse)
2281 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2282 transverse_image=CloneImage(image,image->rows,image->columns,MagickTrue,
2284 if (transverse_image == (
Image *) NULL)
2285 return((
Image *) NULL);
2291 image_view=AcquireVirtualCacheView(image,exception);
2292 transverse_view=AcquireAuthenticCacheView(transverse_image,exception);
2293 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2294 #pragma omp parallel for schedule(static) shared(progress,status) \
2295 magick_number_threads(image,transverse_image,image->rows,1)
2297 for (y=0; y < (ssize_t) image->rows; y++)
2311 if (status == MagickFalse)
2313 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
2314 q=QueueCacheViewAuthenticPixels(transverse_view,(ssize_t) (image->rows-y-1),
2315 0,1,transverse_image->rows,exception);
2316 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
2321 q+=GetPixelChannels(transverse_image)*image->columns;
2322 for (x=0; x < (ssize_t) image->columns; x++)
2327 q-=GetPixelChannels(transverse_image);
2328 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2330 PixelChannel channel = GetPixelChannelChannel(image,i);
2331 PixelTrait traits = GetPixelChannelTraits(image,channel);
2332 PixelTrait transverse_traits=GetPixelChannelTraits(transverse_image,
2334 if ((traits == UndefinedPixelTrait) ||
2335 (transverse_traits == UndefinedPixelTrait))
2337 SetPixelChannel(transverse_image,channel,p[i],q);
2339 p+=GetPixelChannels(image);
2341 sync=SyncCacheViewAuthenticPixels(transverse_view,exception);
2342 if (sync == MagickFalse)
2344 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2349 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2353 proceed=SetImageProgress(image,TransverseImageTag,progress,image->rows);
2354 if (proceed == MagickFalse)
2358 transverse_view=DestroyCacheView(transverse_view);
2359 image_view=DestroyCacheView(image_view);
2360 transverse_image->type=image->type;
2361 page=transverse_image->page;
2362 Swap(page.width,page.height);
2363 Swap(page.x,page.y);
2364 if (page.width != 0)
2365 page.x=(ssize_t) (page.width-transverse_image->columns-page.x);
2366 if (page.height != 0)
2367 page.y=(ssize_t) (page.height-transverse_image->rows-page.y);
2368 transverse_image->page=page;
2369 if (status == MagickFalse)
2370 transverse_image=DestroyImage(transverse_image);
2371 return(transverse_image);
2412 assert(image != (
const Image *) NULL);
2413 assert(image->signature == MagickCoreSignature);
2414 if (IsEventLogging() != MagickFalse)
2415 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2416 geometry=GetImageBoundingBox(image,exception);
2417 if ((geometry.width == 0) || (geometry.height == 0))
2422 crop_image=CloneImage(image,1,1,MagickTrue,exception);
2423 if (crop_image == (
Image *) NULL)
2424 return((
Image *) NULL);
2425 crop_image->background_color.alpha_trait=BlendPixelTrait;
2426 crop_image->background_color.alpha=(MagickRealType) TransparentAlpha;
2427 (void) SetImageBackgroundColor(crop_image,exception);
2428 crop_image->page=image->page;
2429 crop_image->page.x=(-1);
2430 crop_image->page.y=(-1);
2434 artifact=GetImageArtifact(image,
"trim:minSize");
2435 if (artifact != (
const char *) NULL)
2436 (void) ParseAbsoluteGeometry(artifact,&page);
2437 if ((geometry.width < page.width) && (geometry.height < page.height))
2442 switch (image->gravity)
2446 geometry.x-=((ssize_t) page.width-geometry.width)/2;
2447 geometry.y-=((ssize_t) page.height-geometry.height)/2;
2450 case NorthWestGravity:
2452 geometry.x-=((ssize_t) page.width-geometry.width);
2453 geometry.y-=((ssize_t) page.height-geometry.height);
2458 geometry.x-=((ssize_t) page.width-geometry.width)/2;
2459 geometry.y-=((ssize_t) page.height-geometry.height);
2462 case NorthEastGravity:
2464 geometry.y-=((ssize_t) page.height-geometry.height);
2469 geometry.y-=((ssize_t) page.height-geometry.height)/2;
2472 case SouthEastGravity:
2476 geometry.x-=((ssize_t) page.width-geometry.width)/2;
2479 case SouthWestGravity:
2481 geometry.x-=((ssize_t) page.width-geometry.width);
2486 geometry.x-=((ssize_t) page.width-geometry.width);
2487 geometry.y-=((ssize_t) page.height-geometry.height)/2;
2493 geometry.width=page.width;
2494 geometry.height=page.height;
2496 geometry.x+=image->page.x;
2497 geometry.y+=image->page.y;
2498 trim_image=CropImage(image,&geometry,exception);
2499 if (trim_image != (
Image *) NULL)
2500 Update8BIMClipPath(trim_image,image->columns,image->rows,&geometry);