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=(size_t) ((ssize_t) page.width+page.x-bounding_box.x);
623 page.width=(size_t) ((ssize_t) 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=(size_t) ((ssize_t) page.height+page.y-bounding_box.y);
635 page.height=(size_t) ((ssize_t) page.height-(bounding_box.y-page.y));
636 page.y-=bounding_box.y;
640 if ((page.x+(ssize_t) page.width) > (ssize_t) image->columns)
641 page.width=(size_t) ((ssize_t) image->columns-page.x);
642 if ((geometry->width != 0) && (page.width > geometry->width))
643 page.width=geometry->width;
644 if ((page.y+(ssize_t) page.height) > (ssize_t) image->rows)
645 page.height=(size_t) ((ssize_t) image->rows-page.y);
646 if ((geometry->height != 0) && (page.height > geometry->height))
647 page.height=geometry->height;
648 bounding_box.x+=page.x;
649 bounding_box.y+=page.y;
650 if ((page.width == 0) || (page.height == 0))
652 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
653 "GeometryDoesNotContainImage",
"`%s'",image->filename);
654 return((
Image *) NULL);
659 crop_image=CloneImage(image,page.width,page.height,MagickTrue,exception);
660 if (crop_image == (
Image *) NULL)
661 return((
Image *) NULL);
662 crop_image->page.width=image->page.width;
663 crop_image->page.height=image->page.height;
664 offset.x=bounding_box.x+(ssize_t) bounding_box.width;
665 offset.y=bounding_box.y+(ssize_t) bounding_box.height;
666 if ((offset.x > (ssize_t) image->page.width) ||
667 (offset.y > (ssize_t) image->page.height))
669 crop_image->page.width=bounding_box.width;
670 crop_image->page.height=bounding_box.height;
672 crop_image->page.x=bounding_box.x;
673 crop_image->page.y=bounding_box.y;
679 image_view=AcquireVirtualCacheView(image,exception);
680 crop_view=AcquireAuthenticCacheView(crop_image,exception);
681#if defined(MAGICKCORE_OPENMP_SUPPORT)
682 #pragma omp parallel for schedule(static) shared(status) \
683 magick_number_threads(image,crop_image,crop_image->rows,2)
685 for (y=0; y < (ssize_t) crop_image->rows; y++)
696 if (status == MagickFalse)
698 p=GetCacheViewVirtualPixels(image_view,page.x,page.y+y,crop_image->columns,
700 q=QueueCacheViewAuthenticPixels(crop_view,0,y,crop_image->columns,1,
702 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
707 for (x=0; x < (ssize_t) crop_image->columns; x++)
712 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
714 PixelChannel channel = GetPixelChannelChannel(image,i);
715 PixelTrait traits = GetPixelChannelTraits(image,channel);
716 PixelTrait crop_traits=GetPixelChannelTraits(crop_image,channel);
717 if ((traits == UndefinedPixelTrait) ||
718 (crop_traits == UndefinedPixelTrait))
720 SetPixelChannel(crop_image,channel,p[i],q);
722 p+=(ptrdiff_t) GetPixelChannels(image);
723 q+=(ptrdiff_t) GetPixelChannels(crop_image);
725 if (SyncCacheViewAuthenticPixels(crop_view,exception) == MagickFalse)
727 if (image->progress_monitor != (MagickProgressMonitor) NULL)
732#if defined(MAGICKCORE_OPENMP_SUPPORT)
736 proceed=SetImageProgress(image,CropImageTag,progress,image->rows);
737 if (proceed == MagickFalse)
741 crop_view=DestroyCacheView(crop_view);
742 image_view=DestroyCacheView(image_view);
743 crop_image->type=image->type;
744 if (status == MagickFalse)
745 crop_image=DestroyImage(crop_image);
777static inline ssize_t PixelRoundOffset(
double x)
782 if ((x-floor(x)) < (ceil(x)-x))
783 return(CastDoubleToLong(floor(x)));
784 return(CastDoubleToLong(ceil(x)));
787MagickExport
Image *CropImageToTiles(
const Image *image,
800 assert(image != (
Image *) NULL);
801 assert(image->signature == MagickCoreSignature);
802 if (IsEventLogging() != MagickFalse)
803 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
804 flags=ParseGravityGeometry(image,crop_geometry,&geometry,exception);
805 if ((flags & AreaValue) != 0)
821 crop_image=NewImageList();
822 width=image->columns;
824 if (geometry.width == 0)
826 if (geometry.height == 0)
828 if ((flags & AspectValue) == 0)
830 width=(size_t) ((ssize_t) width-(geometry.x < 0 ? -1 : 1)*geometry.x);
831 height=(size_t) ((ssize_t) height-(geometry.y < 0 ? -1 : 1)*
836 width=(size_t) ((ssize_t) width+(geometry.x < 0 ? -1 : 1)*geometry.x);
837 height=(size_t) ((ssize_t) height+(geometry.y < 0 ? -1 : 1)*
840 delta.x=(double) width/geometry.width;
841 delta.y=(double) height/geometry.height;
846 for (offset.y=0; offset.y < (
double) height; )
848 if ((flags & AspectValue) == 0)
850 crop.y=PixelRoundOffset((
double) (offset.y-
851 (geometry.y > 0 ? 0 : geometry.y)));
853 crop.height=(size_t) PixelRoundOffset((
double) (offset.y+
854 (geometry.y < 0 ? 0 : geometry.y)));
858 crop.y=PixelRoundOffset((
double) (offset.y-
859 (geometry.y > 0 ? geometry.y : 0)));
861 crop.height=(size_t) PixelRoundOffset((
double)
862 (offset.y+(geometry.y < -1 ? geometry.y : 0)));
864 crop.height=(size_t) ((ssize_t) crop.height-crop.y);
865 crop.y+=image->page.y;
866 for (offset.x=0; offset.x < (
double) width; )
868 if ((flags & AspectValue) == 0)
870 crop.x=PixelRoundOffset((
double) (offset.x-
871 (geometry.x > 0 ? 0 : geometry.x)));
873 crop.width=(size_t) PixelRoundOffset((
double) (offset.x+
874 (geometry.x < 0 ? 0 : geometry.x)));
878 crop.x=PixelRoundOffset((
double) (offset.x-
879 (geometry.x > 0 ? geometry.x : 0)));
881 crop.width=(size_t) PixelRoundOffset((
double) (offset.x+
882 (geometry.x < 0 ? geometry.x : 0)));
884 crop.width=(size_t) ((ssize_t) crop.width-crop.x);
885 crop.x+=image->page.x;
886 next=CropImage(image,&crop,exception);
887 if (next != (
Image *) NULL)
888 AppendImageToList(&crop_image,next);
891 ClearMagickException(exception);
894 if (((geometry.width == 0) && (geometry.height == 0)) ||
895 ((flags & XValue) != 0) || ((flags & YValue) != 0))
900 crop_image=CropImage(image,&geometry,exception);
901 if ((crop_image != (
Image *) NULL) && ((flags & AspectValue) != 0))
903 crop_image->page.width=geometry.width;
904 crop_image->page.height=geometry.height;
905 crop_image->page.x-=geometry.x;
906 crop_image->page.y-=geometry.y;
910 if ((image->columns > geometry.width) || (image->rows > geometry.height))
928 page.width=image->columns;
929 if (page.height == 0)
930 page.height=image->rows;
931 width=geometry.width;
934 height=geometry.height;
938 crop_image=NewImageList();
939 for (y=0; y < (ssize_t) page.height; y+=(ssize_t) height)
941 for (x=0; x < (ssize_t) page.width; x+=(ssize_t) width)
943 geometry.width=width;
944 geometry.height=height;
947 next=CropImage(image,&geometry,exception);
948 if (next == (
Image *) NULL)
950 AppendImageToList(&crop_image,next);
952 if (next == (
Image *) NULL)
957 return(CloneImage(image,0,0,MagickTrue,exception));
988MagickExport
Image *ExcerptImage(
const Image *image,
991#define ExcerptImageTag "Excerpt/Image"
1012 assert(image != (
const Image *) NULL);
1013 assert(image->signature == MagickCoreSignature);
1016 assert(exception->signature == MagickCoreSignature);
1017 if (IsEventLogging() != MagickFalse)
1018 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1019 excerpt_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
1021 if (excerpt_image == (
Image *) NULL)
1022 return((
Image *) NULL);
1028 image_view=AcquireVirtualCacheView(image,exception);
1029 excerpt_view=AcquireAuthenticCacheView(excerpt_image,exception);
1030#if defined(MAGICKCORE_OPENMP_SUPPORT)
1031 #pragma omp parallel for schedule(static) shared(progress,status) \
1032 magick_number_threads(image,excerpt_image,excerpt_image->rows,2)
1034 for (y=0; y < (ssize_t) excerpt_image->rows; y++)
1045 if (status == MagickFalse)
1047 p=GetCacheViewVirtualPixels(image_view,geometry->x,geometry->y+y,
1048 geometry->width,1,exception);
1049 q=GetCacheViewAuthenticPixels(excerpt_view,0,y,excerpt_image->columns,1,
1051 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1056 for (x=0; x < (ssize_t) excerpt_image->columns; x++)
1061 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1063 PixelChannel channel = GetPixelChannelChannel(image,i);
1064 PixelTrait traits = GetPixelChannelTraits(image,channel);
1065 PixelTrait excerpt_traits=GetPixelChannelTraits(excerpt_image,channel);
1066 if ((traits == UndefinedPixelTrait) ||
1067 (excerpt_traits == UndefinedPixelTrait))
1069 SetPixelChannel(excerpt_image,channel,p[i],q);
1071 p+=(ptrdiff_t) GetPixelChannels(image);
1072 q+=(ptrdiff_t) GetPixelChannels(excerpt_image);
1074 if (SyncCacheViewAuthenticPixels(excerpt_view,exception) == MagickFalse)
1076 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1081#if defined(MAGICKCORE_OPENMP_SUPPORT)
1085 proceed=SetImageProgress(image,ExcerptImageTag,progress,image->rows);
1086 if (proceed == MagickFalse)
1090 excerpt_view=DestroyCacheView(excerpt_view);
1091 image_view=DestroyCacheView(image_view);
1092 excerpt_image->type=image->type;
1093 if (status == MagickFalse)
1094 excerpt_image=DestroyImage(excerpt_image);
1095 return(excerpt_image);
1128MagickExport
Image *ExtentImage(
const Image *image,
1140 assert(image != (
const Image *) NULL);
1141 assert(image->signature == MagickCoreSignature);
1144 assert(exception->signature == MagickCoreSignature);
1145 if (IsEventLogging() != MagickFalse)
1146 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1147 extent_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
1149 if (extent_image == (
Image *) NULL)
1150 return((
Image *) NULL);
1151 status=SetImageBackgroundColor(extent_image,exception);
1152 if (status == MagickFalse)
1154 extent_image=DestroyImage(extent_image);
1155 return((
Image *) NULL);
1157 DisableCompositeClampUnlessSpecified(extent_image);
1158 status=CompositeImage(extent_image,image,image->compose,MagickTrue,
1159 -geometry->x,-geometry->y,exception);
1160 if (status != MagickFalse)
1161 Update8BIMClipPath(extent_image,image->columns,image->rows,geometry);
1162 return(extent_image);
1192#define FlipImageTag "Flip/Image"
1213 assert(image != (
const Image *) NULL);
1214 assert(image->signature == MagickCoreSignature);
1216 assert(exception->signature == MagickCoreSignature);
1217 if (IsEventLogging() != MagickFalse)
1218 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1219 flip_image=CloneImage(image,0,0,MagickTrue,exception);
1220 if (flip_image == (
Image *) NULL)
1221 return((
Image *) NULL);
1228 image_view=AcquireVirtualCacheView(image,exception);
1229 flip_view=AcquireAuthenticCacheView(flip_image,exception);
1230#if defined(MAGICKCORE_OPENMP_SUPPORT)
1231 #pragma omp parallel for schedule(static) shared(status) \
1232 magick_number_threads(image,flip_image,flip_image->rows,2)
1234 for (y=0; y < (ssize_t) flip_image->rows; y++)
1245 if (status == MagickFalse)
1247 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1248 q=QueueCacheViewAuthenticPixels(flip_view,0,((ssize_t) flip_image->rows-y-
1249 1),flip_image->columns,1,exception);
1250 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1255 for (x=0; x < (ssize_t) flip_image->columns; x++)
1260 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1262 PixelChannel channel = GetPixelChannelChannel(image,i);
1263 PixelTrait traits = GetPixelChannelTraits(image,channel);
1264 PixelTrait flip_traits=GetPixelChannelTraits(flip_image,channel);
1265 if ((traits == UndefinedPixelTrait) ||
1266 (flip_traits == UndefinedPixelTrait))
1268 SetPixelChannel(flip_image,channel,p[i],q);
1270 p+=(ptrdiff_t) GetPixelChannels(image);
1271 q+=(ptrdiff_t) GetPixelChannels(flip_image);
1273 if (SyncCacheViewAuthenticPixels(flip_view,exception) == MagickFalse)
1275 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1280#if defined(MAGICKCORE_OPENMP_SUPPORT)
1284 proceed=SetImageProgress(image,FlipImageTag,progress,image->rows);
1285 if (proceed == MagickFalse)
1289 flip_view=DestroyCacheView(flip_view);
1290 image_view=DestroyCacheView(image_view);
1291 flip_image->type=image->type;
1292 if (page.height != 0)
1293 page.y=((ssize_t) page.height-(ssize_t) flip_image->rows-page.y);
1294 flip_image->page=page;
1295 if (status == MagickFalse)
1296 flip_image=DestroyImage(flip_image);
1327#define FlopImageTag "Flop/Image"
1348 assert(image != (
const Image *) NULL);
1349 assert(image->signature == MagickCoreSignature);
1351 assert(exception->signature == MagickCoreSignature);
1352 if (IsEventLogging() != MagickFalse)
1353 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1354 flop_image=CloneImage(image,0,0,MagickTrue,exception);
1355 if (flop_image == (
Image *) NULL)
1356 return((
Image *) NULL);
1363 image_view=AcquireVirtualCacheView(image,exception);
1364 flop_view=AcquireAuthenticCacheView(flop_image,exception);
1365#if defined(MAGICKCORE_OPENMP_SUPPORT)
1366 #pragma omp parallel for schedule(static) shared(status) \
1367 magick_number_threads(image,flop_image,flop_image->rows,2)
1369 for (y=0; y < (ssize_t) flop_image->rows; y++)
1380 if (status == MagickFalse)
1382 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1383 q=QueueCacheViewAuthenticPixels(flop_view,0,y,flop_image->columns,1,
1385 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1390 q+=(ptrdiff_t) GetPixelChannels(flop_image)*flop_image->columns;
1391 for (x=0; x < (ssize_t) flop_image->columns; x++)
1396 q-=GetPixelChannels(flop_image);
1397 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1399 PixelChannel channel = GetPixelChannelChannel(image,i);
1400 PixelTrait traits = GetPixelChannelTraits(image,channel);
1401 PixelTrait flop_traits=GetPixelChannelTraits(flop_image,channel);
1402 if ((traits == UndefinedPixelTrait) ||
1403 (flop_traits == UndefinedPixelTrait))
1405 SetPixelChannel(flop_image,channel,p[i],q);
1407 p+=(ptrdiff_t) GetPixelChannels(image);
1409 if (SyncCacheViewAuthenticPixels(flop_view,exception) == MagickFalse)
1411 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1416#if defined(MAGICKCORE_OPENMP_SUPPORT)
1420 proceed=SetImageProgress(image,FlopImageTag,progress,image->rows);
1421 if (proceed == MagickFalse)
1425 flop_view=DestroyCacheView(flop_view);
1426 image_view=DestroyCacheView(image_view);
1427 flop_image->type=image->type;
1428 if (page.width != 0)
1429 page.x=((ssize_t) page.width-(ssize_t) flop_image->columns-page.x);
1430 flop_image->page=page;
1431 if (status == MagickFalse)
1432 flop_image=DestroyImage(flop_image);
1466static MagickBooleanType CopyImageRegion(
Image *destination,
const Image *source,
const size_t columns,
const size_t rows,
const ssize_t sx,
const ssize_t sy,
1482 source_view=AcquireVirtualCacheView(source,exception);
1483 destination_view=AcquireAuthenticCacheView(destination,exception);
1484#if defined(MAGICKCORE_OPENMP_SUPPORT)
1485 #pragma omp parallel for schedule(static) shared(status) \
1486 magick_number_threads(source,destination,rows,2)
1488 for (y=0; y < (ssize_t) rows; y++)
1505 if (status == MagickFalse)
1507 p=GetCacheViewVirtualPixels(source_view,sx,sy+y,columns,1,exception);
1508 q=GetCacheViewAuthenticPixels(destination_view,dx,dy+y,columns,1,exception);
1509 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1514 for (x=0; x < (ssize_t) columns; x++)
1519 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
1521 PixelChannel channel = GetPixelChannelChannel(source,i);
1522 PixelTrait source_traits=GetPixelChannelTraits(source,channel);
1523 PixelTrait destination_traits=GetPixelChannelTraits(destination,
1525 if ((source_traits == UndefinedPixelTrait) ||
1526 (destination_traits == UndefinedPixelTrait))
1528 SetPixelChannel(destination,channel,p[i],q);
1530 p+=(ptrdiff_t) GetPixelChannels(source);
1531 q+=(ptrdiff_t) GetPixelChannels(destination);
1533 sync=SyncCacheViewAuthenticPixels(destination_view,exception);
1534 if (sync == MagickFalse)
1537 destination_view=DestroyCacheView(destination_view);
1538 source_view=DestroyCacheView(source_view);
1542MagickExport
Image *RollImage(
const Image *image,
const ssize_t x_offset,
1545#define RollImageTag "Roll/Image"
1559 assert(image != (
const Image *) NULL);
1560 assert(image->signature == MagickCoreSignature);
1562 assert(exception->signature == MagickCoreSignature);
1563 if (IsEventLogging() != MagickFalse)
1564 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1565 roll_image=CloneImage(image,0,0,MagickTrue,exception);
1566 if (roll_image == (
Image *) NULL)
1567 return((
Image *) NULL);
1570 while (offset.x < 0)
1571 offset.x+=(ssize_t) image->columns;
1572 while (offset.x >= (ssize_t) image->columns)
1573 offset.x-=(ssize_t) image->columns;
1574 while (offset.y < 0)
1575 offset.y+=(ssize_t) image->rows;
1576 while (offset.y >= (ssize_t) image->rows)
1577 offset.y-=(ssize_t) image->rows;
1581 status=CopyImageRegion(roll_image,image,(
size_t) offset.x,
1582 (
size_t) offset.y,(ssize_t) image->columns-offset.x,(ssize_t) image->rows-
1583 offset.y,0,0,exception);
1584 (void) SetImageProgress(image,RollImageTag,0,3);
1585 status&=(MagickStatusType) CopyImageRegion(roll_image,image,(
size_t)
1586 ((ssize_t) image->columns-offset.x),(
size_t) offset.y,0,(ssize_t)
1587 image->rows-offset.y,offset.x,0,exception);
1588 (void) SetImageProgress(image,RollImageTag,1,3);
1589 status&=(MagickStatusType) CopyImageRegion(roll_image,image,(
size_t)
1590 offset.x,(
size_t) ((ssize_t) image->rows-offset.y),(ssize_t)
1591 image->columns-offset.x,0,0,offset.y,exception);
1592 (void) SetImageProgress(image,RollImageTag,2,3);
1593 status&=(MagickStatusType) CopyImageRegion(roll_image,image,(
size_t)
1594 ((ssize_t) image->columns-offset.x),(
size_t) ((ssize_t) image->rows-
1595 offset.y),0,0,offset.x,offset.y,exception);
1596 (void) SetImageProgress(image,RollImageTag,3,3);
1597 roll_image->type=image->type;
1598 if (status == MagickFalse)
1599 roll_image=DestroyImage(roll_image);
1637MagickExport
Image *ShaveImage(
const Image *image,
1646 assert(image != (
const Image *) NULL);
1647 assert(image->signature == MagickCoreSignature);
1648 if (IsEventLogging() != MagickFalse)
1649 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1650 if (((2*shave_info->width) >= image->columns) ||
1651 ((2*shave_info->height) >= image->rows))
1652 ThrowImageException(OptionWarning,
"GeometryDoesNotContainImage");
1653 SetGeometry(image,&geometry);
1654 geometry.width-=2*shave_info->width;
1655 geometry.height-=2*shave_info->height;
1656 geometry.x=(ssize_t) shave_info->width+image->page.x;
1657 geometry.y=(ssize_t) shave_info->height+image->page.y;
1658 shave_image=CropImage(image,&geometry,exception);
1659 if (shave_image == (
Image *) NULL)
1660 return((
Image *) NULL);
1661 shave_image->page.width-=2*shave_info->width;
1662 shave_image->page.height-=2*shave_info->height;
1663 shave_image->page.x-=(ssize_t) shave_info->width;
1664 shave_image->page.y-=(ssize_t) shave_info->height;
1665 return(shave_image);
1697MagickExport
Image *SpliceImage(
const Image *image,
1700#define SpliceImageTag "Splice/Image"
1725 assert(image != (
const Image *) NULL);
1726 assert(image->signature == MagickCoreSignature);
1727 if (IsEventLogging() != MagickFalse)
1728 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1731 assert(exception->signature == MagickCoreSignature);
1732 splice_geometry=(*geometry);
1733 splice_image=CloneImage(image,image->columns+splice_geometry.width,
1734 image->rows+splice_geometry.height,MagickTrue,exception);
1735 if (splice_image == (
Image *) NULL)
1736 return((
Image *) NULL);
1737 if (SetImageStorageClass(splice_image,DirectClass,exception) == MagickFalse)
1739 splice_image=DestroyImage(splice_image);
1740 return((
Image *) NULL);
1742 if ((IsPixelInfoGray(&splice_image->background_color) == MagickFalse) &&
1743 (IsGrayColorspace(splice_image->colorspace) != MagickFalse))
1744 (void) SetImageColorspace(splice_image,sRGBColorspace,exception);
1745 if ((splice_image->background_color.alpha_trait != UndefinedPixelTrait) &&
1746 (splice_image->alpha_trait == UndefinedPixelTrait))
1747 (void) SetImageAlpha(splice_image,OpaqueAlpha,exception);
1748 (void) SetImageBackgroundColor(splice_image,exception);
1752 switch (image->gravity)
1755 case UndefinedGravity:
1756 case NorthWestGravity:
1760 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1763 case NorthEastGravity:
1765 splice_geometry.x+=(ssize_t) splice_geometry.width;
1770 splice_geometry.y+=(ssize_t) splice_geometry.width/2;
1775 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1776 splice_geometry.y+=(ssize_t) splice_geometry.height/2;
1781 splice_geometry.x+=(ssize_t) splice_geometry.width;
1782 splice_geometry.y+=(ssize_t) splice_geometry.height/2;
1785 case SouthWestGravity:
1787 splice_geometry.y+=(ssize_t) splice_geometry.height;
1792 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1793 splice_geometry.y+=(ssize_t) splice_geometry.height;
1796 case SouthEastGravity:
1798 splice_geometry.x+=(ssize_t) splice_geometry.width;
1799 splice_geometry.y+=(ssize_t) splice_geometry.height;
1808 columns=MagickMin(splice_geometry.x,(ssize_t) splice_image->columns);
1809 image_view=AcquireVirtualCacheView(image,exception);
1810 splice_view=AcquireAuthenticCacheView(splice_image,exception);
1811#if defined(MAGICKCORE_OPENMP_SUPPORT)
1812 #pragma omp parallel for schedule(static) shared(progress,status) \
1813 magick_number_threads(image,splice_image,(size_t) splice_geometry.y,2)
1815 for (y=0; y < (ssize_t) splice_geometry.y; y++)
1826 if (status == MagickFalse)
1828 p=GetCacheViewVirtualPixels(image_view,0,y,splice_image->columns,1,
1830 q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
1832 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1837 for (x=0; x < columns; x++)
1842 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1844 PixelChannel channel = GetPixelChannelChannel(image,i);
1845 PixelTrait traits = GetPixelChannelTraits(image,channel);
1846 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1847 if ((traits == UndefinedPixelTrait) ||
1848 (splice_traits == UndefinedPixelTrait))
1850 SetPixelChannel(splice_image,channel,p[i],q);
1852 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1853 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1854 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1855 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1856 p+=(ptrdiff_t) GetPixelChannels(image);
1857 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1859 for ( ; x < (splice_geometry.x+(ssize_t) splice_geometry.width); x++)
1860 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1861 for ( ; x < (ssize_t) splice_image->columns; x++)
1866 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1868 PixelChannel channel = GetPixelChannelChannel(image,i);
1869 PixelTrait traits = GetPixelChannelTraits(image,channel);
1870 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1871 if ((traits == UndefinedPixelTrait) ||
1872 (splice_traits == UndefinedPixelTrait))
1874 SetPixelChannel(splice_image,channel,p[i],q);
1876 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1877 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1878 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1879 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1880 p+=(ptrdiff_t) GetPixelChannels(image);
1881 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1883 if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
1885 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1890#if defined(MAGICKCORE_OPENMP_SUPPORT)
1894 proceed=SetImageProgress(image,SpliceImageTag,progress,
1895 splice_image->rows);
1896 if (proceed == MagickFalse)
1900#if defined(MAGICKCORE_OPENMP_SUPPORT)
1901 #pragma omp parallel for schedule(static) shared(progress,status) \
1902 magick_number_threads(image,splice_image,splice_image->rows,2)
1904 for (y=splice_geometry.y+(ssize_t) splice_geometry.height; y < (ssize_t) splice_image->rows; y++)
1915 if (status == MagickFalse)
1917 if ((y < 0) || (y >= (ssize_t) splice_image->rows))
1919 p=GetCacheViewVirtualPixels(image_view,0,y-(ssize_t) splice_geometry.height,
1920 splice_image->columns,1,exception);
1921 q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
1923 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1928 for (x=0; x < columns; x++)
1933 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1935 PixelChannel channel = GetPixelChannelChannel(image,i);
1936 PixelTrait traits = GetPixelChannelTraits(image,channel);
1937 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1938 if ((traits == UndefinedPixelTrait) ||
1939 (splice_traits == UndefinedPixelTrait))
1941 SetPixelChannel(splice_image,channel,p[i],q);
1943 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1944 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1945 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1946 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1947 p+=(ptrdiff_t) GetPixelChannels(image);
1948 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1950 for ( ; x < (splice_geometry.x+(ssize_t) splice_geometry.width); x++)
1951 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1952 for ( ; x < (ssize_t) splice_image->columns; x++)
1957 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1959 PixelChannel channel = GetPixelChannelChannel(image,i);
1960 PixelTrait traits = GetPixelChannelTraits(image,channel);
1961 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1962 if ((traits == UndefinedPixelTrait) ||
1963 (splice_traits == UndefinedPixelTrait))
1965 SetPixelChannel(splice_image,channel,p[i],q);
1967 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1968 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1969 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1970 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1971 p+=(ptrdiff_t) GetPixelChannels(image);
1972 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1974 if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
1976 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1981#if defined(MAGICKCORE_OPENMP_SUPPORT)
1985 proceed=SetImageProgress(image,SpliceImageTag,progress,
1986 splice_image->rows);
1987 if (proceed == MagickFalse)
1991 splice_view=DestroyCacheView(splice_view);
1992 image_view=DestroyCacheView(image_view);
1993 if (status == MagickFalse)
1994 splice_image=DestroyImage(splice_image);
1995 return(splice_image);
2045MagickPrivate MagickBooleanType TransformImage(
Image **image,
2046 const char *crop_geometry,
const char *image_geometry,
ExceptionInfo *exception)
2055 assert(image != (
Image **) NULL);
2056 assert((*image)->signature == MagickCoreSignature);
2057 if (IsEventLogging() != MagickFalse)
2058 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",(*image)->filename);
2059 transform_image=(*image);
2060 if (crop_geometry != (
const char *) NULL)
2068 crop_image=CropImageToTiles(*image,crop_geometry,exception);
2069 if (crop_image == (
Image *) NULL)
2070 transform_image=CloneImage(*image,0,0,MagickTrue,exception);
2073 transform_image=DestroyImage(transform_image);
2074 transform_image=GetFirstImageInList(crop_image);
2076 *image=transform_image;
2078 if (image_geometry == (
const char *) NULL)
2083 (void) ParseRegionGeometry(transform_image,image_geometry,&geometry,
2085 if ((transform_image->columns == geometry.width) &&
2086 (transform_image->rows == geometry.height))
2088 resize_image=ResizeImage(transform_image,geometry.width,geometry.height,
2089 transform_image->filter,exception);
2090 if (resize_image == (
Image *) NULL)
2091 return(MagickFalse);
2092 transform_image=DestroyImage(transform_image);
2093 transform_image=resize_image;
2094 *image=transform_image;
2125#define TransposeImageTag "Transpose/Image"
2146 assert(image != (
const Image *) NULL);
2147 assert(image->signature == MagickCoreSignature);
2149 assert(exception->signature == MagickCoreSignature);
2150 if (IsEventLogging() != MagickFalse)
2151 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2152 transpose_image=CloneImage(image,image->rows,image->columns,MagickTrue,
2154 if (transpose_image == (
Image *) NULL)
2155 return((
Image *) NULL);
2161 image_view=AcquireVirtualCacheView(image,exception);
2162 transpose_view=AcquireAuthenticCacheView(transpose_image,exception);
2163#if defined(MAGICKCORE_OPENMP_SUPPORT)
2164 #pragma omp parallel for schedule(static) shared(progress,status) \
2165 magick_number_threads(image,transpose_image,image->rows,2)
2167 for (y=0; y < (ssize_t) image->rows; y++)
2178 if (status == MagickFalse)
2180 p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-y-1,
2181 image->columns,1,exception);
2182 q=QueueCacheViewAuthenticPixels(transpose_view,(ssize_t) image->rows-y-1,
2183 0,1,transpose_image->rows,exception);
2184 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
2189 for (x=0; x < (ssize_t) image->columns; x++)
2194 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2196 PixelChannel channel = GetPixelChannelChannel(image,i);
2197 PixelTrait traits = GetPixelChannelTraits(image,channel);
2198 PixelTrait transpose_traits=GetPixelChannelTraits(transpose_image,
2200 if ((traits == UndefinedPixelTrait) ||
2201 (transpose_traits == UndefinedPixelTrait))
2203 SetPixelChannel(transpose_image,channel,p[i],q);
2205 p+=(ptrdiff_t) GetPixelChannels(image);
2206 q+=(ptrdiff_t) GetPixelChannels(transpose_image);
2208 if (SyncCacheViewAuthenticPixels(transpose_view,exception) == MagickFalse)
2210 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2215#if defined(MAGICKCORE_OPENMP_SUPPORT)
2219 proceed=SetImageProgress(image,TransposeImageTag,progress,image->rows);
2220 if (proceed == MagickFalse)
2224 transpose_view=DestroyCacheView(transpose_view);
2225 image_view=DestroyCacheView(image_view);
2226 transpose_image->type=image->type;
2227 page=transpose_image->page;
2228 Swap(page.width,page.height);
2229 Swap(page.x,page.y);
2230 transpose_image->page=page;
2231 if (status == MagickFalse)
2232 transpose_image=DestroyImage(transpose_image);
2233 return(transpose_image);
2263#define TransverseImageTag "Transverse/Image"
2284 assert(image != (
const Image *) NULL);
2285 assert(image->signature == MagickCoreSignature);
2287 assert(exception->signature == MagickCoreSignature);
2288 if (IsEventLogging() != MagickFalse)
2289 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2290 transverse_image=CloneImage(image,image->rows,image->columns,MagickTrue,
2292 if (transverse_image == (
Image *) NULL)
2293 return((
Image *) NULL);
2299 image_view=AcquireVirtualCacheView(image,exception);
2300 transverse_view=AcquireAuthenticCacheView(transverse_image,exception);
2301#if defined(MAGICKCORE_OPENMP_SUPPORT)
2302 #pragma omp parallel for schedule(static) shared(progress,status) \
2303 magick_number_threads(image,transverse_image,image->rows,2)
2305 for (y=0; y < (ssize_t) image->rows; y++)
2319 if (status == MagickFalse)
2321 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
2322 q=QueueCacheViewAuthenticPixels(transverse_view,(ssize_t) image->rows-y-1,
2323 0,1,transverse_image->rows,exception);
2324 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
2329 q+=(ptrdiff_t) GetPixelChannels(transverse_image)*image->columns;
2330 for (x=0; x < (ssize_t) image->columns; x++)
2335 q-=GetPixelChannels(transverse_image);
2336 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2338 PixelChannel channel = GetPixelChannelChannel(image,i);
2339 PixelTrait traits = GetPixelChannelTraits(image,channel);
2340 PixelTrait transverse_traits=GetPixelChannelTraits(transverse_image,
2342 if ((traits == UndefinedPixelTrait) ||
2343 (transverse_traits == UndefinedPixelTrait))
2345 SetPixelChannel(transverse_image,channel,p[i],q);
2347 p+=(ptrdiff_t) GetPixelChannels(image);
2349 sync=SyncCacheViewAuthenticPixels(transverse_view,exception);
2350 if (sync == MagickFalse)
2352 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2357#if defined(MAGICKCORE_OPENMP_SUPPORT)
2361 proceed=SetImageProgress(image,TransverseImageTag,progress,image->rows);
2362 if (proceed == MagickFalse)
2366 transverse_view=DestroyCacheView(transverse_view);
2367 image_view=DestroyCacheView(image_view);
2368 transverse_image->type=image->type;
2369 page=transverse_image->page;
2370 Swap(page.width,page.height);
2371 Swap(page.x,page.y);
2372 if (page.width != 0)
2373 page.x=(ssize_t) page.width-(ssize_t) transverse_image->columns-page.x;
2374 if (page.height != 0)
2375 page.y=(ssize_t) page.height-(ssize_t) transverse_image->rows-page.y;
2376 transverse_image->page=page;
2377 if (status == MagickFalse)
2378 transverse_image=DestroyImage(transverse_image);
2379 return(transverse_image);
2420 assert(image != (
const Image *) NULL);
2421 assert(image->signature == MagickCoreSignature);
2422 if (IsEventLogging() != MagickFalse)
2423 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2424 geometry=GetImageBoundingBox(image,exception);
2425 if ((geometry.width == 0) || (geometry.height == 0))
2430 crop_image=CloneImage(image,1,1,MagickTrue,exception);
2431 if (crop_image == (
Image *) NULL)
2432 return((
Image *) NULL);
2433 crop_image->background_color.alpha_trait=BlendPixelTrait;
2434 crop_image->background_color.alpha=(MagickRealType) TransparentAlpha;
2435 (void) SetImageBackgroundColor(crop_image,exception);
2436 crop_image->page=image->page;
2437 crop_image->page.x=(-1);
2438 crop_image->page.y=(-1);
2442 artifact=GetImageArtifact(image,
"trim:minSize");
2443 if (artifact != (
const char *) NULL)
2444 (void) ParseAbsoluteGeometry(artifact,&page);
2445 if ((geometry.width < page.width) && (geometry.height < page.height))
2450 switch (image->gravity)
2454 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width)/2;
2455 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height)/2;
2458 case NorthWestGravity:
2460 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width);
2461 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height);
2466 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width)/2;
2467 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height);
2470 case NorthEastGravity:
2472 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height);
2477 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height)/2;
2480 case SouthEastGravity:
2484 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width)/2;
2487 case SouthWestGravity:
2489 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width);
2494 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width);
2495 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height)/2;
2501 geometry.width=page.width;
2502 geometry.height=page.height;
2504 geometry.x+=image->page.x;
2505 geometry.y+=image->page.y;
2506 trim_image=CropImage(image,&geometry,exception);
2507 if (trim_image != (
Image *) NULL)
2508 Update8BIMClipPath(trim_image,image->columns,image->rows,&geometry);