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,
109 assert(image != (
const Image *) NULL);
110 assert(image->signature == MagickCoreSignature);
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);
195#define ChopImageTag "Chop/Image"
219 assert(image != (
const Image *) NULL);
220 assert(image->signature == MagickCoreSignature);
222 assert(exception->signature == MagickCoreSignature);
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,
440 assert(images != (
Image *) NULL);
441 assert(images->signature == MagickCoreSignature);
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);
545#define CropImageTag "Crop/Image"
573 assert(image != (
const Image *) NULL);
574 assert(image->signature == MagickCoreSignature);
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=CastDoubleToUnsigned((
double) page.width+page.x-
624 page.width=CastDoubleToUnsigned((
double) page.width-(bounding_box.x-
626 page.x-=bounding_box.x;
630 if ((page.y < 0) && (bounding_box.y >= 0))
632 page.height=CastDoubleToUnsigned((
double) page.height+page.y-
638 page.height=CastDoubleToUnsigned((
double) page.height-(bounding_box.y-
640 page.y-=bounding_box.y;
644 if ((page.x+(ssize_t) page.width) > (ssize_t) image->columns)
645 page.width=(size_t) ((ssize_t) image->columns-page.x);
646 if ((geometry->width != 0) && (page.width > geometry->width))
647 page.width=geometry->width;
648 if ((page.y+(ssize_t) page.height) > (ssize_t) image->rows)
649 page.height=(size_t) ((ssize_t) image->rows-page.y);
650 if ((geometry->height != 0) && (page.height > geometry->height))
651 page.height=geometry->height;
652 bounding_box.x+=page.x;
653 bounding_box.y+=page.y;
654 if ((page.width == 0) || (page.height == 0))
656 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
657 "GeometryDoesNotContainImage",
"`%s'",image->filename);
658 return((
Image *) NULL);
663 crop_image=CloneImage(image,page.width,page.height,MagickTrue,exception);
664 if (crop_image == (
Image *) NULL)
665 return((
Image *) NULL);
666 crop_image->page.width=image->page.width;
667 crop_image->page.height=image->page.height;
668 offset.x=bounding_box.x+(ssize_t) bounding_box.width;
669 offset.y=bounding_box.y+(ssize_t) bounding_box.height;
670 if ((offset.x > (ssize_t) image->page.width) ||
671 (offset.y > (ssize_t) image->page.height))
673 crop_image->page.width=bounding_box.width;
674 crop_image->page.height=bounding_box.height;
676 crop_image->page.x=bounding_box.x;
677 crop_image->page.y=bounding_box.y;
683 image_view=AcquireVirtualCacheView(image,exception);
684 crop_view=AcquireAuthenticCacheView(crop_image,exception);
685#if defined(MAGICKCORE_OPENMP_SUPPORT)
686 #pragma omp parallel for schedule(static) shared(status) \
687 magick_number_threads(image,crop_image,crop_image->rows,2)
689 for (y=0; y < (ssize_t) crop_image->rows; y++)
700 if (status == MagickFalse)
702 p=GetCacheViewVirtualPixels(image_view,page.x,page.y+y,crop_image->columns,
704 q=QueueCacheViewAuthenticPixels(crop_view,0,y,crop_image->columns,1,
706 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
711 for (x=0; x < (ssize_t) crop_image->columns; x++)
716 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
718 PixelChannel channel = GetPixelChannelChannel(image,i);
719 PixelTrait traits = GetPixelChannelTraits(image,channel);
720 PixelTrait crop_traits=GetPixelChannelTraits(crop_image,channel);
721 if ((traits == UndefinedPixelTrait) ||
722 (crop_traits == UndefinedPixelTrait))
724 SetPixelChannel(crop_image,channel,p[i],q);
726 p+=(ptrdiff_t) GetPixelChannels(image);
727 q+=(ptrdiff_t) GetPixelChannels(crop_image);
729 if (SyncCacheViewAuthenticPixels(crop_view,exception) == MagickFalse)
731 if (image->progress_monitor != (MagickProgressMonitor) NULL)
736#if defined(MAGICKCORE_OPENMP_SUPPORT)
740 proceed=SetImageProgress(image,CropImageTag,progress,image->rows);
741 if (proceed == MagickFalse)
745 crop_view=DestroyCacheView(crop_view);
746 image_view=DestroyCacheView(image_view);
747 crop_image->type=image->type;
748 if (status == MagickFalse)
749 crop_image=DestroyImage(crop_image);
781static inline ssize_t PixelRoundOffset(
double x)
786 if ((x-floor(x)) < (ceil(x)-x))
787 return(CastDoubleToLong(floor(x)));
788 return(CastDoubleToLong(ceil(x)));
791MagickExport
Image *CropImageToTiles(
const Image *image,
804 assert(image != (
Image *) NULL);
805 assert(image->signature == MagickCoreSignature);
806 if (IsEventLogging() != MagickFalse)
807 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
808 flags=ParseGravityGeometry(image,crop_geometry,&geometry,exception);
809 if ((flags & AreaValue) != 0)
825 crop_image=NewImageList();
826 width=image->columns;
828 if (geometry.width == 0)
830 if (geometry.height == 0)
832 if ((flags & AspectValue) == 0)
834 width=(size_t) ((ssize_t) width-(geometry.x < 0 ? -1 : 1)*geometry.x);
835 height=(size_t) ((ssize_t) height-(geometry.y < 0 ? -1 : 1)*
840 width=(size_t) ((ssize_t) width+(geometry.x < 0 ? -1 : 1)*geometry.x);
841 height=(size_t) ((ssize_t) height+(geometry.y < 0 ? -1 : 1)*
844 delta.x=(double) width/geometry.width;
845 delta.y=(double) height/geometry.height;
850 for (offset.y=0; offset.y < (
double) height; )
852 if ((flags & AspectValue) == 0)
854 crop.y=PixelRoundOffset((
double) (offset.y-
855 (geometry.y > 0 ? 0 : geometry.y)));
857 crop.height=(size_t) PixelRoundOffset((
double) (offset.y+
858 (geometry.y < 0 ? 0 : geometry.y)));
862 crop.y=PixelRoundOffset((
double) (offset.y-
863 (geometry.y > 0 ? geometry.y : 0)));
865 crop.height=(size_t) PixelRoundOffset((
double)
866 (offset.y+(geometry.y < -1 ? geometry.y : 0)));
868 crop.height=(size_t) ((ssize_t) crop.height-crop.y);
869 crop.y+=image->page.y;
870 for (offset.x=0; offset.x < (
double) width; )
872 if ((flags & AspectValue) == 0)
874 crop.x=PixelRoundOffset((
double) (offset.x-
875 (geometry.x > 0 ? 0 : geometry.x)));
877 crop.width=(size_t) PixelRoundOffset((
double) (offset.x+
878 (geometry.x < 0 ? 0 : geometry.x)));
882 crop.x=PixelRoundOffset((
double) (offset.x-
883 (geometry.x > 0 ? geometry.x : 0)));
885 crop.width=(size_t) PixelRoundOffset((
double) (offset.x+
886 (geometry.x < 0 ? geometry.x : 0)));
888 crop.width=(size_t) ((ssize_t) crop.width-crop.x);
889 crop.x+=image->page.x;
890 next=CropImage(image,&crop,exception);
891 if (next != (
Image *) NULL)
892 AppendImageToList(&crop_image,next);
895 ClearMagickException(exception);
898 if (((geometry.width == 0) && (geometry.height == 0)) ||
899 ((flags & XValue) != 0) || ((flags & YValue) != 0))
904 crop_image=CropImage(image,&geometry,exception);
905 if ((crop_image != (
Image *) NULL) && ((flags & AspectValue) != 0))
907 crop_image->page.width=geometry.width;
908 crop_image->page.height=geometry.height;
909 crop_image->page.x-=geometry.x;
910 crop_image->page.y-=geometry.y;
914 if ((image->columns > geometry.width) || (image->rows > geometry.height))
932 page.width=image->columns;
933 if (page.height == 0)
934 page.height=image->rows;
935 width=geometry.width;
938 height=geometry.height;
942 crop_image=NewImageList();
943 for (y=0; y < (ssize_t) page.height; y+=(ssize_t) height)
945 for (x=0; x < (ssize_t) page.width; x+=(ssize_t) width)
947 geometry.width=width;
948 geometry.height=height;
951 next=CropImage(image,&geometry,exception);
952 if (next == (
Image *) NULL)
954 AppendImageToList(&crop_image,next);
956 if (next == (
Image *) NULL)
961 return(CloneImage(image,0,0,MagickTrue,exception));
992MagickExport
Image *ExcerptImage(
const Image *image,
995#define ExcerptImageTag "Excerpt/Image"
1016 assert(image != (
const Image *) NULL);
1017 assert(image->signature == MagickCoreSignature);
1020 assert(exception->signature == MagickCoreSignature);
1021 if (IsEventLogging() != MagickFalse)
1022 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1023 excerpt_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
1025 if (excerpt_image == (
Image *) NULL)
1026 return((
Image *) NULL);
1032 image_view=AcquireVirtualCacheView(image,exception);
1033 excerpt_view=AcquireAuthenticCacheView(excerpt_image,exception);
1034#if defined(MAGICKCORE_OPENMP_SUPPORT)
1035 #pragma omp parallel for schedule(static) shared(progress,status) \
1036 magick_number_threads(image,excerpt_image,excerpt_image->rows,2)
1038 for (y=0; y < (ssize_t) excerpt_image->rows; y++)
1049 if (status == MagickFalse)
1051 p=GetCacheViewVirtualPixels(image_view,geometry->x,geometry->y+y,
1052 geometry->width,1,exception);
1053 q=GetCacheViewAuthenticPixels(excerpt_view,0,y,excerpt_image->columns,1,
1055 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1060 for (x=0; x < (ssize_t) excerpt_image->columns; x++)
1065 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1067 PixelChannel channel = GetPixelChannelChannel(image,i);
1068 PixelTrait traits = GetPixelChannelTraits(image,channel);
1069 PixelTrait excerpt_traits=GetPixelChannelTraits(excerpt_image,channel);
1070 if ((traits == UndefinedPixelTrait) ||
1071 (excerpt_traits == UndefinedPixelTrait))
1073 SetPixelChannel(excerpt_image,channel,p[i],q);
1075 p+=(ptrdiff_t) GetPixelChannels(image);
1076 q+=(ptrdiff_t) GetPixelChannels(excerpt_image);
1078 if (SyncCacheViewAuthenticPixels(excerpt_view,exception) == MagickFalse)
1080 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1085#if defined(MAGICKCORE_OPENMP_SUPPORT)
1089 proceed=SetImageProgress(image,ExcerptImageTag,progress,image->rows);
1090 if (proceed == MagickFalse)
1094 excerpt_view=DestroyCacheView(excerpt_view);
1095 image_view=DestroyCacheView(image_view);
1096 excerpt_image->type=image->type;
1097 if (status == MagickFalse)
1098 excerpt_image=DestroyImage(excerpt_image);
1099 return(excerpt_image);
1132MagickExport
Image *ExtentImage(
const Image *image,
1144 assert(image != (
const Image *) NULL);
1145 assert(image->signature == MagickCoreSignature);
1148 assert(exception->signature == MagickCoreSignature);
1149 if (IsEventLogging() != MagickFalse)
1150 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1151 extent_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
1153 if (extent_image == (
Image *) NULL)
1154 return((
Image *) NULL);
1155 status=SetImageBackgroundColor(extent_image,exception);
1156 if (status == MagickFalse)
1158 extent_image=DestroyImage(extent_image);
1159 return((
Image *) NULL);
1161 DisableCompositeClampUnlessSpecified(extent_image);
1162 status=CompositeImage(extent_image,image,image->compose,MagickTrue,
1163 -geometry->x,-geometry->y,exception);
1164 if (status != MagickFalse)
1165 Update8BIMClipPath(extent_image,image->columns,image->rows,geometry);
1166 return(extent_image);
1196#define FlipImageTag "Flip/Image"
1217 assert(image != (
const Image *) NULL);
1218 assert(image->signature == MagickCoreSignature);
1220 assert(exception->signature == MagickCoreSignature);
1221 if (IsEventLogging() != MagickFalse)
1222 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1223 flip_image=CloneImage(image,0,0,MagickTrue,exception);
1224 if (flip_image == (
Image *) NULL)
1225 return((
Image *) NULL);
1232 image_view=AcquireVirtualCacheView(image,exception);
1233 flip_view=AcquireAuthenticCacheView(flip_image,exception);
1234#if defined(MAGICKCORE_OPENMP_SUPPORT)
1235 #pragma omp parallel for schedule(static) shared(status) \
1236 magick_number_threads(image,flip_image,flip_image->rows,2)
1238 for (y=0; y < (ssize_t) flip_image->rows; y++)
1249 if (status == MagickFalse)
1251 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1252 q=QueueCacheViewAuthenticPixels(flip_view,0,((ssize_t) flip_image->rows-y-
1253 1),flip_image->columns,1,exception);
1254 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1259 for (x=0; x < (ssize_t) flip_image->columns; x++)
1264 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1266 PixelChannel channel = GetPixelChannelChannel(image,i);
1267 PixelTrait traits = GetPixelChannelTraits(image,channel);
1268 PixelTrait flip_traits=GetPixelChannelTraits(flip_image,channel);
1269 if ((traits == UndefinedPixelTrait) ||
1270 (flip_traits == UndefinedPixelTrait))
1272 SetPixelChannel(flip_image,channel,p[i],q);
1274 p+=(ptrdiff_t) GetPixelChannels(image);
1275 q+=(ptrdiff_t) GetPixelChannels(flip_image);
1277 if (SyncCacheViewAuthenticPixels(flip_view,exception) == MagickFalse)
1279 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1284#if defined(MAGICKCORE_OPENMP_SUPPORT)
1288 proceed=SetImageProgress(image,FlipImageTag,progress,image->rows);
1289 if (proceed == MagickFalse)
1293 flip_view=DestroyCacheView(flip_view);
1294 image_view=DestroyCacheView(image_view);
1295 flip_image->type=image->type;
1296 if (page.height != 0)
1297 page.y=((ssize_t) page.height-(ssize_t) flip_image->rows-page.y);
1298 flip_image->page=page;
1299 if (status == MagickFalse)
1300 flip_image=DestroyImage(flip_image);
1331#define FlopImageTag "Flop/Image"
1352 assert(image != (
const Image *) NULL);
1353 assert(image->signature == MagickCoreSignature);
1355 assert(exception->signature == MagickCoreSignature);
1356 if (IsEventLogging() != MagickFalse)
1357 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1358 flop_image=CloneImage(image,0,0,MagickTrue,exception);
1359 if (flop_image == (
Image *) NULL)
1360 return((
Image *) NULL);
1367 image_view=AcquireVirtualCacheView(image,exception);
1368 flop_view=AcquireAuthenticCacheView(flop_image,exception);
1369#if defined(MAGICKCORE_OPENMP_SUPPORT)
1370 #pragma omp parallel for schedule(static) shared(status) \
1371 magick_number_threads(image,flop_image,flop_image->rows,2)
1373 for (y=0; y < (ssize_t) flop_image->rows; y++)
1384 if (status == MagickFalse)
1386 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1387 q=QueueCacheViewAuthenticPixels(flop_view,0,y,flop_image->columns,1,
1389 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1394 q+=(ptrdiff_t) GetPixelChannels(flop_image)*flop_image->columns;
1395 for (x=0; x < (ssize_t) flop_image->columns; x++)
1400 q-=GetPixelChannels(flop_image);
1401 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1403 PixelChannel channel = GetPixelChannelChannel(image,i);
1404 PixelTrait traits = GetPixelChannelTraits(image,channel);
1405 PixelTrait flop_traits=GetPixelChannelTraits(flop_image,channel);
1406 if ((traits == UndefinedPixelTrait) ||
1407 (flop_traits == UndefinedPixelTrait))
1409 SetPixelChannel(flop_image,channel,p[i],q);
1411 p+=(ptrdiff_t) GetPixelChannels(image);
1413 if (SyncCacheViewAuthenticPixels(flop_view,exception) == MagickFalse)
1415 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1420#if defined(MAGICKCORE_OPENMP_SUPPORT)
1424 proceed=SetImageProgress(image,FlopImageTag,progress,image->rows);
1425 if (proceed == MagickFalse)
1429 flop_view=DestroyCacheView(flop_view);
1430 image_view=DestroyCacheView(image_view);
1431 flop_image->type=image->type;
1432 if (page.width != 0)
1433 page.x=((ssize_t) page.width-(ssize_t) flop_image->columns-page.x);
1434 flop_image->page=page;
1435 if (status == MagickFalse)
1436 flop_image=DestroyImage(flop_image);
1470static MagickBooleanType CopyImageRegion(
Image *destination,
const Image *source,
const size_t columns,
const size_t rows,
const ssize_t sx,
const ssize_t sy,
1486 source_view=AcquireVirtualCacheView(source,exception);
1487 destination_view=AcquireAuthenticCacheView(destination,exception);
1488#if defined(MAGICKCORE_OPENMP_SUPPORT)
1489 #pragma omp parallel for schedule(static) shared(status) \
1490 magick_number_threads(source,destination,rows,2)
1492 for (y=0; y < (ssize_t) rows; y++)
1509 if (status == MagickFalse)
1511 p=GetCacheViewVirtualPixels(source_view,sx,sy+y,columns,1,exception);
1512 q=GetCacheViewAuthenticPixels(destination_view,dx,dy+y,columns,1,exception);
1513 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1518 for (x=0; x < (ssize_t) columns; x++)
1523 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
1525 PixelChannel channel = GetPixelChannelChannel(source,i);
1526 PixelTrait source_traits=GetPixelChannelTraits(source,channel);
1527 PixelTrait destination_traits=GetPixelChannelTraits(destination,
1529 if ((source_traits == UndefinedPixelTrait) ||
1530 (destination_traits == UndefinedPixelTrait))
1532 SetPixelChannel(destination,channel,p[i],q);
1534 p+=(ptrdiff_t) GetPixelChannels(source);
1535 q+=(ptrdiff_t) GetPixelChannels(destination);
1537 sync=SyncCacheViewAuthenticPixels(destination_view,exception);
1538 if (sync == MagickFalse)
1541 destination_view=DestroyCacheView(destination_view);
1542 source_view=DestroyCacheView(source_view);
1546MagickExport
Image *RollImage(
const Image *image,
const ssize_t x_offset,
1549#define RollImageTag "Roll/Image"
1563 assert(image != (
const Image *) NULL);
1564 assert(image->signature == MagickCoreSignature);
1566 assert(exception->signature == MagickCoreSignature);
1567 if (IsEventLogging() != MagickFalse)
1568 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1569 roll_image=CloneImage(image,0,0,MagickTrue,exception);
1570 if (roll_image == (
Image *) NULL)
1571 return((
Image *) NULL);
1574 while (offset.x < 0)
1575 offset.x+=(ssize_t) image->columns;
1576 while (offset.x >= (ssize_t) image->columns)
1577 offset.x-=(ssize_t) image->columns;
1578 while (offset.y < 0)
1579 offset.y+=(ssize_t) image->rows;
1580 while (offset.y >= (ssize_t) image->rows)
1581 offset.y-=(ssize_t) image->rows;
1585 status=CopyImageRegion(roll_image,image,(
size_t) offset.x,
1586 (
size_t) offset.y,(ssize_t) image->columns-offset.x,(ssize_t) image->rows-
1587 offset.y,0,0,exception);
1588 (void) SetImageProgress(image,RollImageTag,0,3);
1589 status&=(MagickStatusType) CopyImageRegion(roll_image,image,(
size_t)
1590 ((ssize_t) image->columns-offset.x),(
size_t) offset.y,0,(ssize_t)
1591 image->rows-offset.y,offset.x,0,exception);
1592 (void) SetImageProgress(image,RollImageTag,1,3);
1593 status&=(MagickStatusType) CopyImageRegion(roll_image,image,(
size_t)
1594 offset.x,(
size_t) ((ssize_t) image->rows-offset.y),(ssize_t)
1595 image->columns-offset.x,0,0,offset.y,exception);
1596 (void) SetImageProgress(image,RollImageTag,2,3);
1597 status&=(MagickStatusType) CopyImageRegion(roll_image,image,(
size_t)
1598 ((ssize_t) image->columns-offset.x),(
size_t) ((ssize_t) image->rows-
1599 offset.y),0,0,offset.x,offset.y,exception);
1600 (void) SetImageProgress(image,RollImageTag,3,3);
1601 roll_image->type=image->type;
1602 if (status == MagickFalse)
1603 roll_image=DestroyImage(roll_image);
1641MagickExport
Image *ShaveImage(
const Image *image,
1650 assert(image != (
const Image *) NULL);
1651 assert(image->signature == MagickCoreSignature);
1652 if (IsEventLogging() != MagickFalse)
1653 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1654 if (((2*shave_info->width) >= image->columns) ||
1655 ((2*shave_info->height) >= image->rows))
1656 ThrowImageException(OptionWarning,
"GeometryDoesNotContainImage");
1657 SetGeometry(image,&geometry);
1658 geometry.width-=2*shave_info->width;
1659 geometry.height-=2*shave_info->height;
1660 geometry.x=(ssize_t) shave_info->width+image->page.x;
1661 geometry.y=(ssize_t) shave_info->height+image->page.y;
1662 shave_image=CropImage(image,&geometry,exception);
1663 if (shave_image == (
Image *) NULL)
1664 return((
Image *) NULL);
1665 shave_image->page.width-=2*shave_info->width;
1666 shave_image->page.height-=2*shave_info->height;
1667 shave_image->page.x-=(ssize_t) shave_info->width;
1668 shave_image->page.y-=(ssize_t) shave_info->height;
1669 return(shave_image);
1701MagickExport
Image *SpliceImage(
const Image *image,
1704#define SpliceImageTag "Splice/Image"
1729 assert(image != (
const Image *) NULL);
1730 assert(image->signature == MagickCoreSignature);
1731 if (IsEventLogging() != MagickFalse)
1732 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1735 assert(exception->signature == MagickCoreSignature);
1736 splice_geometry=(*geometry);
1737 splice_image=CloneImage(image,image->columns+splice_geometry.width,
1738 image->rows+splice_geometry.height,MagickTrue,exception);
1739 if (splice_image == (
Image *) NULL)
1740 return((
Image *) NULL);
1741 if (SetImageStorageClass(splice_image,DirectClass,exception) == MagickFalse)
1743 splice_image=DestroyImage(splice_image);
1744 return((
Image *) NULL);
1746 if ((IsPixelInfoGray(&splice_image->background_color) == MagickFalse) &&
1747 (IsGrayColorspace(splice_image->colorspace) != MagickFalse))
1748 (void) SetImageColorspace(splice_image,sRGBColorspace,exception);
1749 if ((splice_image->background_color.alpha_trait != UndefinedPixelTrait) &&
1750 (splice_image->alpha_trait == UndefinedPixelTrait))
1751 (void) SetImageAlpha(splice_image,OpaqueAlpha,exception);
1752 (void) SetImageBackgroundColor(splice_image,exception);
1756 switch (image->gravity)
1759 case UndefinedGravity:
1760 case NorthWestGravity:
1764 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1767 case NorthEastGravity:
1769 splice_geometry.x+=(ssize_t) splice_geometry.width;
1774 splice_geometry.y+=(ssize_t) splice_geometry.width/2;
1779 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1780 splice_geometry.y+=(ssize_t) splice_geometry.height/2;
1785 splice_geometry.x+=(ssize_t) splice_geometry.width;
1786 splice_geometry.y+=(ssize_t) splice_geometry.height/2;
1789 case SouthWestGravity:
1791 splice_geometry.y+=(ssize_t) splice_geometry.height;
1796 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1797 splice_geometry.y+=(ssize_t) splice_geometry.height;
1800 case SouthEastGravity:
1802 splice_geometry.x+=(ssize_t) splice_geometry.width;
1803 splice_geometry.y+=(ssize_t) splice_geometry.height;
1812 columns=MagickMin(splice_geometry.x,(ssize_t) splice_image->columns);
1813 image_view=AcquireVirtualCacheView(image,exception);
1814 splice_view=AcquireAuthenticCacheView(splice_image,exception);
1815#if defined(MAGICKCORE_OPENMP_SUPPORT)
1816 #pragma omp parallel for schedule(static) shared(progress,status) \
1817 magick_number_threads(image,splice_image,(size_t) splice_geometry.y,2)
1819 for (y=0; y < (ssize_t) splice_geometry.y; y++)
1830 if (status == MagickFalse)
1832 p=GetCacheViewVirtualPixels(image_view,0,y,splice_image->columns,1,
1834 q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
1836 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1841 for (x=0; x < columns; x++)
1846 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1848 PixelChannel channel = GetPixelChannelChannel(image,i);
1849 PixelTrait traits = GetPixelChannelTraits(image,channel);
1850 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1851 if ((traits == UndefinedPixelTrait) ||
1852 (splice_traits == UndefinedPixelTrait))
1854 SetPixelChannel(splice_image,channel,p[i],q);
1856 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1857 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1858 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1859 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1860 p+=(ptrdiff_t) GetPixelChannels(image);
1861 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1863 for ( ; x < (splice_geometry.x+(ssize_t) splice_geometry.width); x++)
1864 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1865 for ( ; x < (ssize_t) splice_image->columns; x++)
1870 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1872 PixelChannel channel = GetPixelChannelChannel(image,i);
1873 PixelTrait traits = GetPixelChannelTraits(image,channel);
1874 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1875 if ((traits == UndefinedPixelTrait) ||
1876 (splice_traits == UndefinedPixelTrait))
1878 SetPixelChannel(splice_image,channel,p[i],q);
1880 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1881 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1882 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1883 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1884 p+=(ptrdiff_t) GetPixelChannels(image);
1885 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1887 if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
1889 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1894#if defined(MAGICKCORE_OPENMP_SUPPORT)
1898 proceed=SetImageProgress(image,SpliceImageTag,progress,
1899 splice_image->rows);
1900 if (proceed == MagickFalse)
1904#if defined(MAGICKCORE_OPENMP_SUPPORT)
1905 #pragma omp parallel for schedule(static) shared(progress,status) \
1906 magick_number_threads(image,splice_image,splice_image->rows,2)
1908 for (y=splice_geometry.y+(ssize_t) splice_geometry.height; y < (ssize_t) splice_image->rows; y++)
1919 if (status == MagickFalse)
1921 if ((y < 0) || (y >= (ssize_t) splice_image->rows))
1923 p=GetCacheViewVirtualPixels(image_view,0,y-(ssize_t) splice_geometry.height,
1924 splice_image->columns,1,exception);
1925 q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
1927 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1932 for (x=0; x < columns; x++)
1937 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1939 PixelChannel channel = GetPixelChannelChannel(image,i);
1940 PixelTrait traits = GetPixelChannelTraits(image,channel);
1941 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1942 if ((traits == UndefinedPixelTrait) ||
1943 (splice_traits == UndefinedPixelTrait))
1945 SetPixelChannel(splice_image,channel,p[i],q);
1947 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1948 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1949 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1950 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1951 p+=(ptrdiff_t) GetPixelChannels(image);
1952 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1954 for ( ; x < (splice_geometry.x+(ssize_t) splice_geometry.width); x++)
1955 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1956 for ( ; x < (ssize_t) splice_image->columns; x++)
1961 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1963 PixelChannel channel = GetPixelChannelChannel(image,i);
1964 PixelTrait traits = GetPixelChannelTraits(image,channel);
1965 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1966 if ((traits == UndefinedPixelTrait) ||
1967 (splice_traits == UndefinedPixelTrait))
1969 SetPixelChannel(splice_image,channel,p[i],q);
1971 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1972 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1973 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1974 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1975 p+=(ptrdiff_t) GetPixelChannels(image);
1976 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1978 if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
1980 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1985#if defined(MAGICKCORE_OPENMP_SUPPORT)
1989 proceed=SetImageProgress(image,SpliceImageTag,progress,
1990 splice_image->rows);
1991 if (proceed == MagickFalse)
1995 splice_view=DestroyCacheView(splice_view);
1996 image_view=DestroyCacheView(image_view);
1997 if (status == MagickFalse)
1998 splice_image=DestroyImage(splice_image);
1999 return(splice_image);
2049MagickPrivate MagickBooleanType TransformImage(
Image **image,
2050 const char *crop_geometry,
const char *image_geometry,
ExceptionInfo *exception)
2059 assert(image != (
Image **) NULL);
2060 assert((*image)->signature == MagickCoreSignature);
2061 if (IsEventLogging() != MagickFalse)
2062 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",(*image)->filename);
2063 transform_image=(*image);
2064 if (crop_geometry != (
const char *) NULL)
2072 crop_image=CropImageToTiles(*image,crop_geometry,exception);
2073 if (crop_image == (
Image *) NULL)
2074 transform_image=CloneImage(*image,0,0,MagickTrue,exception);
2077 transform_image=DestroyImage(transform_image);
2078 transform_image=GetFirstImageInList(crop_image);
2080 *image=transform_image;
2082 if (image_geometry == (
const char *) NULL)
2087 (void) ParseRegionGeometry(transform_image,image_geometry,&geometry,
2089 if ((transform_image->columns == geometry.width) &&
2090 (transform_image->rows == geometry.height))
2092 resize_image=ResizeImage(transform_image,geometry.width,geometry.height,
2093 transform_image->filter,exception);
2094 if (resize_image == (
Image *) NULL)
2095 return(MagickFalse);
2096 transform_image=DestroyImage(transform_image);
2097 transform_image=resize_image;
2098 *image=transform_image;
2129#define TransposeImageTag "Transpose/Image"
2150 assert(image != (
const Image *) NULL);
2151 assert(image->signature == MagickCoreSignature);
2153 assert(exception->signature == MagickCoreSignature);
2154 if (IsEventLogging() != MagickFalse)
2155 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2156 transpose_image=CloneImage(image,image->rows,image->columns,MagickTrue,
2158 if (transpose_image == (
Image *) NULL)
2159 return((
Image *) NULL);
2165 image_view=AcquireVirtualCacheView(image,exception);
2166 transpose_view=AcquireAuthenticCacheView(transpose_image,exception);
2167#if defined(MAGICKCORE_OPENMP_SUPPORT)
2168 #pragma omp parallel for schedule(static) shared(progress,status) \
2169 magick_number_threads(image,transpose_image,image->rows,2)
2171 for (y=0; y < (ssize_t) image->rows; y++)
2182 if (status == MagickFalse)
2184 p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-y-1,
2185 image->columns,1,exception);
2186 q=QueueCacheViewAuthenticPixels(transpose_view,(ssize_t) image->rows-y-1,
2187 0,1,transpose_image->rows,exception);
2188 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
2193 for (x=0; x < (ssize_t) image->columns; x++)
2198 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2200 PixelChannel channel = GetPixelChannelChannel(image,i);
2201 PixelTrait traits = GetPixelChannelTraits(image,channel);
2202 PixelTrait transpose_traits=GetPixelChannelTraits(transpose_image,
2204 if ((traits == UndefinedPixelTrait) ||
2205 (transpose_traits == UndefinedPixelTrait))
2207 SetPixelChannel(transpose_image,channel,p[i],q);
2209 p+=(ptrdiff_t) GetPixelChannels(image);
2210 q+=(ptrdiff_t) GetPixelChannels(transpose_image);
2212 if (SyncCacheViewAuthenticPixels(transpose_view,exception) == MagickFalse)
2214 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2219#if defined(MAGICKCORE_OPENMP_SUPPORT)
2223 proceed=SetImageProgress(image,TransposeImageTag,progress,image->rows);
2224 if (proceed == MagickFalse)
2228 transpose_view=DestroyCacheView(transpose_view);
2229 image_view=DestroyCacheView(image_view);
2230 transpose_image->type=image->type;
2231 page=transpose_image->page;
2232 Swap(page.width,page.height);
2233 Swap(page.x,page.y);
2234 transpose_image->page=page;
2235 if (status == MagickFalse)
2236 transpose_image=DestroyImage(transpose_image);
2237 return(transpose_image);
2267#define TransverseImageTag "Transverse/Image"
2288 assert(image != (
const Image *) NULL);
2289 assert(image->signature == MagickCoreSignature);
2291 assert(exception->signature == MagickCoreSignature);
2292 if (IsEventLogging() != MagickFalse)
2293 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2294 transverse_image=CloneImage(image,image->rows,image->columns,MagickTrue,
2296 if (transverse_image == (
Image *) NULL)
2297 return((
Image *) NULL);
2303 image_view=AcquireVirtualCacheView(image,exception);
2304 transverse_view=AcquireAuthenticCacheView(transverse_image,exception);
2305#if defined(MAGICKCORE_OPENMP_SUPPORT)
2306 #pragma omp parallel for schedule(static) shared(progress,status) \
2307 magick_number_threads(image,transverse_image,image->rows,2)
2309 for (y=0; y < (ssize_t) image->rows; y++)
2323 if (status == MagickFalse)
2325 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
2326 q=QueueCacheViewAuthenticPixels(transverse_view,(ssize_t) image->rows-y-1,
2327 0,1,transverse_image->rows,exception);
2328 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
2333 q+=(ptrdiff_t) GetPixelChannels(transverse_image)*image->columns;
2334 for (x=0; x < (ssize_t) image->columns; x++)
2339 q-=GetPixelChannels(transverse_image);
2340 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2342 PixelChannel channel = GetPixelChannelChannel(image,i);
2343 PixelTrait traits = GetPixelChannelTraits(image,channel);
2344 PixelTrait transverse_traits=GetPixelChannelTraits(transverse_image,
2346 if ((traits == UndefinedPixelTrait) ||
2347 (transverse_traits == UndefinedPixelTrait))
2349 SetPixelChannel(transverse_image,channel,p[i],q);
2351 p+=(ptrdiff_t) GetPixelChannels(image);
2353 sync=SyncCacheViewAuthenticPixels(transverse_view,exception);
2354 if (sync == MagickFalse)
2356 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2361#if defined(MAGICKCORE_OPENMP_SUPPORT)
2365 proceed=SetImageProgress(image,TransverseImageTag,progress,image->rows);
2366 if (proceed == MagickFalse)
2370 transverse_view=DestroyCacheView(transverse_view);
2371 image_view=DestroyCacheView(image_view);
2372 transverse_image->type=image->type;
2373 page=transverse_image->page;
2374 Swap(page.width,page.height);
2375 Swap(page.x,page.y);
2376 if (page.width != 0)
2377 page.x=(ssize_t) page.width-(ssize_t) transverse_image->columns-page.x;
2378 if (page.height != 0)
2379 page.y=(ssize_t) page.height-(ssize_t) transverse_image->rows-page.y;
2380 transverse_image->page=page;
2381 if (status == MagickFalse)
2382 transverse_image=DestroyImage(transverse_image);
2383 return(transverse_image);
2424 assert(image != (
const Image *) NULL);
2425 assert(image->signature == MagickCoreSignature);
2426 if (IsEventLogging() != MagickFalse)
2427 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2428 geometry=GetImageBoundingBox(image,exception);
2429 if ((geometry.width == 0) || (geometry.height == 0))
2434 crop_image=CloneImage(image,1,1,MagickTrue,exception);
2435 if (crop_image == (
Image *) NULL)
2436 return((
Image *) NULL);
2437 crop_image->background_color.alpha_trait=BlendPixelTrait;
2438 crop_image->background_color.alpha=(MagickRealType) TransparentAlpha;
2439 (void) SetImageBackgroundColor(crop_image,exception);
2440 crop_image->page=image->page;
2441 crop_image->page.x=(-1);
2442 crop_image->page.y=(-1);
2446 artifact=GetImageArtifact(image,
"trim:minSize");
2447 if (artifact != (
const char *) NULL)
2448 (void) ParseAbsoluteGeometry(artifact,&page);
2449 if ((geometry.width < page.width) && (geometry.height < page.height))
2454 switch (image->gravity)
2458 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width)/2;
2459 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height)/2;
2462 case NorthWestGravity:
2464 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width);
2465 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height);
2470 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width)/2;
2471 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height);
2474 case NorthEastGravity:
2476 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height);
2481 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height)/2;
2484 case SouthEastGravity:
2488 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width)/2;
2491 case SouthWestGravity:
2493 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width);
2498 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width);
2499 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height)/2;
2505 geometry.width=page.width;
2506 geometry.height=page.height;
2508 geometry.x+=image->page.x;
2509 geometry.y+=image->page.y;
2510 trim_image=CropImage(image,&geometry,exception);
2511 if (trim_image != (
Image *) NULL)
2512 Update8BIMClipPath(trim_image,image->columns,image->rows,&geometry);