42#include "MagickCore/studio.h"
43#include "MagickCore/attribute.h"
44#include "MagickCore/artifact.h"
45#include "MagickCore/cache.h"
46#include "MagickCore/cache-view.h"
47#include "MagickCore/color.h"
48#include "MagickCore/color-private.h"
49#include "MagickCore/colorspace-private.h"
50#include "MagickCore/composite.h"
51#include "MagickCore/composite-private.h"
52#include "MagickCore/distort.h"
53#include "MagickCore/draw.h"
54#include "MagickCore/effect.h"
55#include "MagickCore/exception.h"
56#include "MagickCore/exception-private.h"
57#include "MagickCore/geometry.h"
58#include "MagickCore/image.h"
59#include "MagickCore/memory_.h"
60#include "MagickCore/layer.h"
61#include "MagickCore/list.h"
62#include "MagickCore/monitor.h"
63#include "MagickCore/monitor-private.h"
64#include "MagickCore/pixel-accessor.h"
65#include "MagickCore/profile-private.h"
66#include "MagickCore/property.h"
67#include "MagickCore/resource_.h"
68#include "MagickCore/resize.h"
69#include "MagickCore/statistic.h"
70#include "MagickCore/string_.h"
71#include "MagickCore/thread-private.h"
72#include "MagickCore/transform.h"
73#include "MagickCore/transform-private.h"
103MagickExport Image *AutoOrientImage(
const Image *image,
104 const OrientationType orientation,ExceptionInfo *exception)
109 assert(image != (
const Image *) NULL);
110 assert(image->signature == MagickCoreSignature);
111 assert(exception != (ExceptionInfo *) NULL);
112 assert(exception->signature == MagickCoreSignature);
113 orient_image=(Image *) NULL;
116 case UndefinedOrientation:
117 case TopLeftOrientation:
120 orient_image=CloneImage(image,0,0,MagickTrue,exception);
123 case TopRightOrientation:
125 orient_image=FlopImage(image,exception);
128 case BottomRightOrientation:
130 orient_image=RotateImage(image,180.0,exception);
133 case BottomLeftOrientation:
135 orient_image=FlipImage(image,exception);
138 case LeftTopOrientation:
140 orient_image=TransposeImage(image,exception);
143 case RightTopOrientation:
145 orient_image=RotateImage(image,90.0,exception);
148 case RightBottomOrientation:
150 orient_image=TransverseImage(image,exception);
153 case LeftBottomOrientation:
155 orient_image=RotateImage(image,270.0,exception);
159 if (orient_image != (Image *) NULL)
160 orient_image->orientation=TopLeftOrientation;
161 return(orient_image);
192MagickExport Image *ChopImage(
const Image *image,
const RectangleInfo *chop_info,
193 ExceptionInfo *exception)
195#define ChopImageTag "Chop/Image"
219 assert(image != (
const Image *) NULL);
220 assert(image->signature == MagickCoreSignature);
221 assert(exception != (ExceptionInfo *) NULL);
222 assert(exception->signature == MagickCoreSignature);
223 assert(chop_info != (RectangleInfo *) NULL);
224 if (IsEventLogging() != MagickFalse)
225 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
226 if (((chop_info->x+(ssize_t) chop_info->width) < 0) ||
227 ((chop_info->y+(ssize_t) chop_info->height) < 0) ||
228 (chop_info->x > (ssize_t) image->columns) ||
229 (chop_info->y > (ssize_t) image->rows))
230 ThrowImageException(OptionWarning,
"GeometryDoesNotContainImage");
232 if ((extent.x+(ssize_t) extent.width) > (ssize_t) image->columns)
233 extent.width=(size_t) ((ssize_t) image->columns-extent.x);
234 if ((extent.y+(ssize_t) extent.height) > (ssize_t) image->rows)
235 extent.height=(size_t) ((ssize_t) image->rows-extent.y);
238 extent.width-=(size_t) (-extent.x);
243 extent.height-=(size_t) (-extent.y);
246 if ((extent.width >= image->columns) || (extent.height >= image->rows))
247 ThrowImageException(OptionWarning,
"GeometryDoesNotContainImage");
248 chop_image=CloneImage(image,image->columns-extent.width,image->rows-
249 extent.height,MagickTrue,exception);
250 if (chop_image == (Image *) NULL)
251 return((Image *) NULL);
257 image_view=AcquireVirtualCacheView(image,exception);
258 chop_view=AcquireAuthenticCacheView(chop_image,exception);
259#if defined(MAGICKCORE_OPENMP_SUPPORT)
260 #pragma omp parallel for schedule(static) shared(status) \
261 magick_number_threads(image,chop_image,(size_t) extent.y,2)
263 for (y=0; y < (ssize_t) extent.y; y++)
274 if (status == MagickFalse)
276 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
277 q=QueueCacheViewAuthenticPixels(chop_view,0,y,chop_image->columns,1,
279 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
284 for (x=0; x < (ssize_t) image->columns; x++)
286 if ((x < extent.x) || (x >= (extent.x+(ssize_t) extent.width)))
291 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
293 PixelChannel channel = GetPixelChannelChannel(image,i);
294 PixelTrait traits = GetPixelChannelTraits(image,channel);
295 PixelTrait chop_traits=GetPixelChannelTraits(chop_image,channel);
296 if ((traits == UndefinedPixelTrait) ||
297 (chop_traits == UndefinedPixelTrait))
299 SetPixelChannel(chop_image,channel,p[i],q);
301 q+=(ptrdiff_t) GetPixelChannels(chop_image);
303 p+=(ptrdiff_t) GetPixelChannels(image);
305 if (SyncCacheViewAuthenticPixels(chop_view,exception) == MagickFalse)
307 if (image->progress_monitor != (MagickProgressMonitor) NULL)
312#if defined(MAGICKCORE_OPENMP_SUPPORT)
316 proceed=SetImageProgress(image,ChopImageTag,progress,image->rows);
317 if (proceed == MagickFalse)
324#if defined(MAGICKCORE_OPENMP_SUPPORT)
325 #pragma omp parallel for schedule(static) shared(progress,status) \
326 magick_number_threads(image,chop_image,image->rows-((size_t) extent.y+extent.height),2)
328 for (y=0; y < (ssize_t) (image->rows-((size_t) extent.y+extent.height)); y++)
339 if (status == MagickFalse)
341 p=GetCacheViewVirtualPixels(image_view,0,extent.y+(ssize_t) extent.height+y,
342 image->columns,1,exception);
343 q=QueueCacheViewAuthenticPixels(chop_view,0,extent.y+y,chop_image->columns,
345 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
350 for (x=0; x < (ssize_t) image->columns; x++)
352 if ((x < extent.x) || (x >= (extent.x+(ssize_t) extent.width)))
357 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
359 PixelChannel channel = GetPixelChannelChannel(image,i);
360 PixelTrait traits = GetPixelChannelTraits(image,channel);
361 PixelTrait chop_traits=GetPixelChannelTraits(chop_image,channel);
362 if ((traits == UndefinedPixelTrait) ||
363 (chop_traits == UndefinedPixelTrait))
365 SetPixelChannel(chop_image,channel,p[i],q);
367 q+=(ptrdiff_t) GetPixelChannels(chop_image);
369 p+=(ptrdiff_t) GetPixelChannels(image);
371 if (SyncCacheViewAuthenticPixels(chop_view,exception) == MagickFalse)
373 if (image->progress_monitor != (MagickProgressMonitor) NULL)
378#if defined(MAGICKCORE_OPENMP_SUPPORT)
382 proceed=SetImageProgress(image,ChopImageTag,progress,image->rows);
383 if (proceed == MagickFalse)
387 chop_view=DestroyCacheView(chop_view);
388 image_view=DestroyCacheView(image_view);
389 chop_image->type=image->type;
390 if (status == MagickFalse)
391 chop_image=DestroyImage(chop_image);
420MagickExport Image *ConsolidateCMYKImages(
const Image *images,
421 ExceptionInfo *exception)
440 assert(images != (Image *) NULL);
441 assert(images->signature == MagickCoreSignature);
442 assert(exception != (ExceptionInfo *) NULL);
443 assert(exception->signature == MagickCoreSignature);
444 if (IsEventLogging() != MagickFalse)
445 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",images->filename);
446 cmyk_images=NewImageList();
447 for (j=0; j < (ssize_t) GetImageListLength(images); j+=4)
452 assert(images != (Image *) NULL);
453 cmyk_image=CloneImage(images,0,0,MagickTrue,
455 if (cmyk_image == (Image *) NULL)
457 if (SetImageStorageClass(cmyk_image,DirectClass,exception) == MagickFalse)
459 (void) SetImageColorspace(cmyk_image,CMYKColorspace,exception);
460 for (i=0; i < 4; i++)
462 image_view=AcquireVirtualCacheView(images,exception);
463 cmyk_view=AcquireAuthenticCacheView(cmyk_image,exception);
464 for (y=0; y < (ssize_t) images->rows; y++)
475 p=GetCacheViewVirtualPixels(image_view,0,y,images->columns,1,exception);
476 q=QueueCacheViewAuthenticPixels(cmyk_view,0,y,cmyk_image->columns,1,
478 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
480 for (x=0; x < (ssize_t) images->columns; x++)
485 pixel=ClampToQuantum((
double) QuantumRange-
486 GetPixelIntensity(images,p));
489 case 0: SetPixelCyan(cmyk_image,pixel,q);
break;
490 case 1: SetPixelMagenta(cmyk_image,pixel,q);
break;
491 case 2: SetPixelYellow(cmyk_image,pixel,q);
break;
492 case 3: SetPixelBlack(cmyk_image,pixel,q);
break;
495 p+=(ptrdiff_t) GetPixelChannels(images);
496 q+=(ptrdiff_t) GetPixelChannels(cmyk_image);
498 if (SyncCacheViewAuthenticPixels(cmyk_view,exception) == MagickFalse)
501 cmyk_view=DestroyCacheView(cmyk_view);
502 image_view=DestroyCacheView(image_view);
503 images=GetNextImageInList(images);
504 if (images == (Image *) NULL)
507 AppendImageToList(&cmyk_images,cmyk_image);
542MagickExport Image *CropImage(
const Image *image,
const RectangleInfo *geometry,
543 ExceptionInfo *exception)
545#define CropImageTag "Crop/Image"
573 assert(image != (
const Image *) NULL);
574 assert(image->signature == MagickCoreSignature);
575 assert(geometry != (
const RectangleInfo *) NULL);
576 assert(exception != (ExceptionInfo *) NULL);
577 assert(exception->signature == MagickCoreSignature);
578 if (IsEventLogging() != MagickFalse)
579 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
580 bounding_box=image->page;
581 if ((bounding_box.width == 0) || (bounding_box.height == 0))
583 bounding_box.width=image->columns;
584 bounding_box.height=image->rows;
588 page.width=bounding_box.width;
589 if (page.height == 0)
590 page.height=bounding_box.height;
591 if ((((
double) bounding_box.x-page.x) >= (
double) page.width) ||
592 (((
double) bounding_box.y-page.y) >= (
double) page.height) ||
593 (((
double) page.x-bounding_box.x) > (
double) image->columns) ||
594 (((
double) page.y-bounding_box.y) > (
double) image->rows))
599 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
600 "GeometryDoesNotContainImage",
"(\"%.20gx%.20g%+.20g%+.20g\") `%s'",
601 (
double) geometry->width,(
double) geometry->height,
602 (
double) geometry->x,(
double) geometry->y,image->filename);
603 crop_image=CloneImage(image,1,1,MagickTrue,exception);
604 if (crop_image == (Image *) NULL)
605 return((Image *) NULL);
606 crop_image->background_color.alpha_trait=BlendPixelTrait;
607 crop_image->background_color.alpha=(MagickRealType) TransparentAlpha;
608 (void) SetImageBackgroundColor(crop_image,exception);
609 crop_image->page=bounding_box;
610 crop_image->page.x=(-1);
611 crop_image->page.y=(-1);
612 if (crop_image->dispose == BackgroundDispose)
613 crop_image->dispose=NoneDispose;
616 if ((page.x < 0) && (bounding_box.x >= 0))
618 page.width=CastDoubleToSizeT((
double) page.width+page.x-bounding_box.x);
623 page.width=CastDoubleToSizeT((
double) page.width-(bounding_box.x-page.x));
624 page.x-=bounding_box.x;
628 if ((page.y < 0) && (bounding_box.y >= 0))
630 page.height=CastDoubleToSizeT((
double) page.height+page.y-bounding_box.y);
635 page.height=CastDoubleToSizeT((
double) page.height-(bounding_box.y-
637 page.y-=bounding_box.y;
641 if ((page.x+(ssize_t) page.width) > (ssize_t) image->columns)
642 page.width=(size_t) ((ssize_t) image->columns-page.x);
643 if ((geometry->width != 0) && (page.width > geometry->width))
644 page.width=geometry->width;
645 if ((page.y+(ssize_t) page.height) > (ssize_t) image->rows)
646 page.height=CastDoubleToSizeT((
double) image->rows-page.y);
647 if ((geometry->height != 0) && (page.height > geometry->height))
648 page.height=geometry->height;
649 bounding_box.x+=page.x;
650 bounding_box.y+=page.y;
651 if ((page.width == 0) || (page.height == 0))
653 (void) ThrowMagickException(exception,GetMagickModule(),OptionWarning,
654 "GeometryDoesNotContainImage",
"`%s'",image->filename);
655 return((Image *) NULL);
660 crop_image=CloneImage(image,page.width,page.height,MagickTrue,exception);
661 if (crop_image == (Image *) NULL)
662 return((Image *) NULL);
663 crop_image->page.width=image->page.width;
664 crop_image->page.height=image->page.height;
665 offset.x=bounding_box.x+(ssize_t) bounding_box.width;
666 offset.y=bounding_box.y+(ssize_t) bounding_box.height;
667 if ((offset.x > (ssize_t) image->page.width) ||
668 (offset.y > (ssize_t) image->page.height))
670 crop_image->page.width=bounding_box.width;
671 crop_image->page.height=bounding_box.height;
673 crop_image->page.x=bounding_box.x;
674 crop_image->page.y=bounding_box.y;
680 image_view=AcquireVirtualCacheView(image,exception);
681 crop_view=AcquireAuthenticCacheView(crop_image,exception);
682#if defined(MAGICKCORE_OPENMP_SUPPORT)
683 #pragma omp parallel for schedule(static) shared(status) \
684 magick_number_threads(image,crop_image,crop_image->rows,2)
686 for (y=0; y < (ssize_t) crop_image->rows; y++)
697 if (status == MagickFalse)
699 p=GetCacheViewVirtualPixels(image_view,page.x,page.y+y,crop_image->columns,
701 q=QueueCacheViewAuthenticPixels(crop_view,0,y,crop_image->columns,1,
703 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
708 for (x=0; x < (ssize_t) crop_image->columns; x++)
713 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
715 PixelChannel channel = GetPixelChannelChannel(image,i);
716 PixelTrait traits = GetPixelChannelTraits(image,channel);
717 PixelTrait crop_traits=GetPixelChannelTraits(crop_image,channel);
718 if ((traits == UndefinedPixelTrait) ||
719 (crop_traits == UndefinedPixelTrait))
721 SetPixelChannel(crop_image,channel,p[i],q);
723 p+=(ptrdiff_t) GetPixelChannels(image);
724 q+=(ptrdiff_t) GetPixelChannels(crop_image);
726 if (SyncCacheViewAuthenticPixels(crop_view,exception) == MagickFalse)
728 if (image->progress_monitor != (MagickProgressMonitor) NULL)
733#if defined(MAGICKCORE_OPENMP_SUPPORT)
737 proceed=SetImageProgress(image,CropImageTag,progress,image->rows);
738 if (proceed == MagickFalse)
742 crop_view=DestroyCacheView(crop_view);
743 image_view=DestroyCacheView(image_view);
744 crop_image->type=image->type;
745 if (status == MagickFalse)
746 crop_image=DestroyImage(crop_image);
778static inline ssize_t PixelRoundOffset(
double x)
783 if ((x-floor(x)) < (ceil(x)-x))
784 return(CastDoubleToSsizeT(floor(x)));
785 return(CastDoubleToSsizeT(ceil(x)));
788MagickExport Image *CropImageToTiles(
const Image *image,
789 const char *crop_geometry,ExceptionInfo *exception)
801 assert(image != (Image *) NULL);
802 assert(image->signature == MagickCoreSignature);
803 if (IsEventLogging() != MagickFalse)
804 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
805 flags=ParseGravityGeometry(image,crop_geometry,&geometry,exception);
806 if ((flags & AreaValue) != 0)
822 crop_image=NewImageList();
823 width=image->columns;
825 if (geometry.width == 0)
827 if (geometry.height == 0)
829 if ((flags & AspectValue) == 0)
831 width=(size_t) ((ssize_t) width-(geometry.x < 0 ? -1 : 1)*geometry.x);
832 height=(size_t) ((ssize_t) height-(geometry.y < 0 ? -1 : 1)*
837 width=(size_t) ((ssize_t) width+(geometry.x < 0 ? -1 : 1)*geometry.x);
838 height=(size_t) ((ssize_t) height+(geometry.y < 0 ? -1 : 1)*
841 delta.x=(double) width/geometry.width;
842 delta.y=(double) height/geometry.height;
847 for (offset.y=0; offset.y < (
double) height; )
849 if ((flags & AspectValue) == 0)
851 crop.y=PixelRoundOffset((
double) (offset.y-
852 (geometry.y > 0 ? 0 : geometry.y)));
854 crop.height=(size_t) PixelRoundOffset((
double) (offset.y+
855 (geometry.y < 0 ? 0 : geometry.y)));
859 crop.y=PixelRoundOffset((
double) (offset.y-
860 (geometry.y > 0 ? geometry.y : 0)));
862 crop.height=(size_t) PixelRoundOffset((
double)
863 (offset.y+(geometry.y < -1 ? geometry.y : 0)));
865 crop.height=(size_t) ((ssize_t) crop.height-crop.y);
866 crop.y+=image->page.y;
867 for (offset.x=0; offset.x < (
double) width; )
869 if ((flags & AspectValue) == 0)
871 crop.x=PixelRoundOffset((
double) (offset.x-
872 (geometry.x > 0 ? 0 : geometry.x)));
874 crop.width=(size_t) PixelRoundOffset((
double) (offset.x+
875 (geometry.x < 0 ? 0 : geometry.x)));
879 crop.x=PixelRoundOffset((
double) (offset.x-
880 (geometry.x > 0 ? geometry.x : 0)));
882 crop.width=(size_t) PixelRoundOffset((
double) (offset.x+
883 (geometry.x < 0 ? geometry.x : 0)));
885 crop.width=(size_t) ((ssize_t) crop.width-crop.x);
886 crop.x+=image->page.x;
887 next=CropImage(image,&crop,exception);
888 if (next != (Image *) NULL)
889 AppendImageToList(&crop_image,next);
892 ClearMagickException(exception);
895 if (((geometry.width == 0) && (geometry.height == 0)) ||
896 ((flags & XValue) != 0) || ((flags & YValue) != 0))
901 crop_image=CropImage(image,&geometry,exception);
902 if ((crop_image != (Image *) NULL) && ((flags & AspectValue) != 0))
904 crop_image->page.width=geometry.width;
905 crop_image->page.height=geometry.height;
906 crop_image->page.x-=geometry.x;
907 crop_image->page.y-=geometry.y;
911 if ((image->columns > geometry.width) || (image->rows > geometry.height))
929 page.width=image->columns;
930 if (page.height == 0)
931 page.height=image->rows;
932 width=geometry.width;
935 height=geometry.height;
939 crop_image=NewImageList();
940 for (y=0; y < (ssize_t) page.height; y+=(ssize_t) height)
942 for (x=0; x < (ssize_t) page.width; x+=(ssize_t) width)
944 geometry.width=width;
945 geometry.height=height;
948 next=CropImage(image,&geometry,exception);
949 if (next == (Image *) NULL)
951 AppendImageToList(&crop_image,next);
953 if (next == (Image *) NULL)
958 return(CloneImage(image,0,0,MagickTrue,exception));
989MagickExport Image *ExcerptImage(
const Image *image,
990 const RectangleInfo *geometry,ExceptionInfo *exception)
992#define ExcerptImageTag "Excerpt/Image"
1013 assert(image != (
const Image *) NULL);
1014 assert(image->signature == MagickCoreSignature);
1015 assert(geometry != (
const RectangleInfo *) NULL);
1016 assert(exception != (ExceptionInfo *) NULL);
1017 assert(exception->signature == MagickCoreSignature);
1018 if (IsEventLogging() != MagickFalse)
1019 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1020 excerpt_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
1022 if (excerpt_image == (Image *) NULL)
1023 return((Image *) NULL);
1029 image_view=AcquireVirtualCacheView(image,exception);
1030 excerpt_view=AcquireAuthenticCacheView(excerpt_image,exception);
1031#if defined(MAGICKCORE_OPENMP_SUPPORT)
1032 #pragma omp parallel for schedule(static) shared(progress,status) \
1033 magick_number_threads(image,excerpt_image,excerpt_image->rows,2)
1035 for (y=0; y < (ssize_t) excerpt_image->rows; y++)
1046 if (status == MagickFalse)
1048 p=GetCacheViewVirtualPixels(image_view,geometry->x,geometry->y+y,
1049 geometry->width,1,exception);
1050 q=GetCacheViewAuthenticPixels(excerpt_view,0,y,excerpt_image->columns,1,
1052 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1057 for (x=0; x < (ssize_t) excerpt_image->columns; x++)
1062 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1064 PixelChannel channel = GetPixelChannelChannel(image,i);
1065 PixelTrait traits = GetPixelChannelTraits(image,channel);
1066 PixelTrait excerpt_traits=GetPixelChannelTraits(excerpt_image,channel);
1067 if ((traits == UndefinedPixelTrait) ||
1068 (excerpt_traits == UndefinedPixelTrait))
1070 SetPixelChannel(excerpt_image,channel,p[i],q);
1072 p+=(ptrdiff_t) GetPixelChannels(image);
1073 q+=(ptrdiff_t) GetPixelChannels(excerpt_image);
1075 if (SyncCacheViewAuthenticPixels(excerpt_view,exception) == MagickFalse)
1077 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1082#if defined(MAGICKCORE_OPENMP_SUPPORT)
1086 proceed=SetImageProgress(image,ExcerptImageTag,progress,image->rows);
1087 if (proceed == MagickFalse)
1091 excerpt_view=DestroyCacheView(excerpt_view);
1092 image_view=DestroyCacheView(image_view);
1093 excerpt_image->type=image->type;
1094 if (status == MagickFalse)
1095 excerpt_image=DestroyImage(excerpt_image);
1096 return(excerpt_image);
1129MagickExport Image *ExtentImage(
const Image *image,
1130 const RectangleInfo *geometry,ExceptionInfo *exception)
1141 assert(image != (
const Image *) NULL);
1142 assert(image->signature == MagickCoreSignature);
1143 assert(geometry != (
const RectangleInfo *) NULL);
1144 assert(exception != (ExceptionInfo *) NULL);
1145 assert(exception->signature == MagickCoreSignature);
1146 if (IsEventLogging() != MagickFalse)
1147 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1148 extent_image=CloneImage(image,geometry->width,geometry->height,MagickTrue,
1150 if (extent_image == (Image *) NULL)
1151 return((Image *) NULL);
1152 status=SetImageBackgroundColor(extent_image,exception);
1153 if (status == MagickFalse)
1155 extent_image=DestroyImage(extent_image);
1156 return((Image *) NULL);
1158 DisableCompositeClampUnlessSpecified(extent_image);
1159 status=CompositeImage(extent_image,image,image->compose,MagickTrue,
1160 -geometry->x,-geometry->y,exception);
1161 if (status != MagickFalse)
1162 Update8BIMClipPath(extent_image,image->columns,image->rows,geometry);
1163 return(extent_image);
1191MagickExport Image *FlipImage(
const Image *image,ExceptionInfo *exception)
1193#define FlipImageTag "Flip/Image"
1214 assert(image != (
const Image *) NULL);
1215 assert(image->signature == MagickCoreSignature);
1216 assert(exception != (ExceptionInfo *) NULL);
1217 assert(exception->signature == MagickCoreSignature);
1218 if (IsEventLogging() != MagickFalse)
1219 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1220 flip_image=CloneImage(image,0,0,MagickTrue,exception);
1221 if (flip_image == (Image *) NULL)
1222 return((Image *) NULL);
1229 image_view=AcquireVirtualCacheView(image,exception);
1230 flip_view=AcquireAuthenticCacheView(flip_image,exception);
1231#if defined(MAGICKCORE_OPENMP_SUPPORT)
1232 #pragma omp parallel for schedule(static) shared(status) \
1233 magick_number_threads(image,flip_image,flip_image->rows,2)
1235 for (y=0; y < (ssize_t) flip_image->rows; y++)
1246 if (status == MagickFalse)
1248 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1249 q=QueueCacheViewAuthenticPixels(flip_view,0,((ssize_t) flip_image->rows-y-
1250 1),flip_image->columns,1,exception);
1251 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1256 for (x=0; x < (ssize_t) flip_image->columns; x++)
1261 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1263 PixelChannel channel = GetPixelChannelChannel(image,i);
1264 PixelTrait traits = GetPixelChannelTraits(image,channel);
1265 PixelTrait flip_traits=GetPixelChannelTraits(flip_image,channel);
1266 if ((traits == UndefinedPixelTrait) ||
1267 (flip_traits == UndefinedPixelTrait))
1269 SetPixelChannel(flip_image,channel,p[i],q);
1271 p+=(ptrdiff_t) GetPixelChannels(image);
1272 q+=(ptrdiff_t) GetPixelChannels(flip_image);
1274 if (SyncCacheViewAuthenticPixels(flip_view,exception) == MagickFalse)
1276 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1281#if defined(MAGICKCORE_OPENMP_SUPPORT)
1285 proceed=SetImageProgress(image,FlipImageTag,progress,image->rows);
1286 if (proceed == MagickFalse)
1290 flip_view=DestroyCacheView(flip_view);
1291 image_view=DestroyCacheView(image_view);
1292 flip_image->type=image->type;
1293 if (page.height != 0)
1294 page.y=((ssize_t) page.height-(ssize_t) flip_image->rows-page.y);
1295 flip_image->page=page;
1296 if (status == MagickFalse)
1297 flip_image=DestroyImage(flip_image);
1326MagickExport Image *FlopImage(
const Image *image,ExceptionInfo *exception)
1328#define FlopImageTag "Flop/Image"
1349 assert(image != (
const Image *) NULL);
1350 assert(image->signature == MagickCoreSignature);
1351 assert(exception != (ExceptionInfo *) NULL);
1352 assert(exception->signature == MagickCoreSignature);
1353 if (IsEventLogging() != MagickFalse)
1354 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1355 flop_image=CloneImage(image,0,0,MagickTrue,exception);
1356 if (flop_image == (Image *) NULL)
1357 return((Image *) NULL);
1364 image_view=AcquireVirtualCacheView(image,exception);
1365 flop_view=AcquireAuthenticCacheView(flop_image,exception);
1366#if defined(MAGICKCORE_OPENMP_SUPPORT)
1367 #pragma omp parallel for schedule(static) shared(status) \
1368 magick_number_threads(image,flop_image,flop_image->rows,2)
1370 for (y=0; y < (ssize_t) flop_image->rows; y++)
1381 if (status == MagickFalse)
1383 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
1384 q=QueueCacheViewAuthenticPixels(flop_view,0,y,flop_image->columns,1,
1386 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1391 q+=(ptrdiff_t) GetPixelChannels(flop_image)*flop_image->columns;
1392 for (x=0; x < (ssize_t) flop_image->columns; x++)
1397 q-=GetPixelChannels(flop_image);
1398 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1400 PixelChannel channel = GetPixelChannelChannel(image,i);
1401 PixelTrait traits = GetPixelChannelTraits(image,channel);
1402 PixelTrait flop_traits=GetPixelChannelTraits(flop_image,channel);
1403 if ((traits == UndefinedPixelTrait) ||
1404 (flop_traits == UndefinedPixelTrait))
1406 SetPixelChannel(flop_image,channel,p[i],q);
1408 p+=(ptrdiff_t) GetPixelChannels(image);
1410 if (SyncCacheViewAuthenticPixels(flop_view,exception) == MagickFalse)
1412 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1417#if defined(MAGICKCORE_OPENMP_SUPPORT)
1421 proceed=SetImageProgress(image,FlopImageTag,progress,image->rows);
1422 if (proceed == MagickFalse)
1426 flop_view=DestroyCacheView(flop_view);
1427 image_view=DestroyCacheView(image_view);
1428 flop_image->type=image->type;
1429 if (page.width != 0)
1430 page.x=((ssize_t) page.width-(ssize_t) flop_image->columns-page.x);
1431 flop_image->page=page;
1432 if (status == MagickFalse)
1433 flop_image=DestroyImage(flop_image);
1467static MagickBooleanType CopyImageRegion(Image *destination,
const Image *source,
const size_t columns,
const size_t rows,
const ssize_t sx,
const ssize_t sy,
1468 const ssize_t dx,
const ssize_t dy,ExceptionInfo *exception)
1483 source_view=AcquireVirtualCacheView(source,exception);
1484 destination_view=AcquireAuthenticCacheView(destination,exception);
1485#if defined(MAGICKCORE_OPENMP_SUPPORT)
1486 #pragma omp parallel for schedule(static) shared(status) \
1487 magick_number_threads(source,destination,rows,2)
1489 for (y=0; y < (ssize_t) rows; y++)
1506 if (status == MagickFalse)
1508 p=GetCacheViewVirtualPixels(source_view,sx,sy+y,columns,1,exception);
1509 q=GetCacheViewAuthenticPixels(destination_view,dx,dy+y,columns,1,exception);
1510 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1515 for (x=0; x < (ssize_t) columns; x++)
1520 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
1522 PixelChannel channel = GetPixelChannelChannel(source,i);
1523 PixelTrait source_traits=GetPixelChannelTraits(source,channel);
1524 PixelTrait destination_traits=GetPixelChannelTraits(destination,
1526 if ((source_traits == UndefinedPixelTrait) ||
1527 (destination_traits == UndefinedPixelTrait))
1529 SetPixelChannel(destination,channel,p[i],q);
1531 p+=(ptrdiff_t) GetPixelChannels(source);
1532 q+=(ptrdiff_t) GetPixelChannels(destination);
1534 sync=SyncCacheViewAuthenticPixels(destination_view,exception);
1535 if (sync == MagickFalse)
1538 destination_view=DestroyCacheView(destination_view);
1539 source_view=DestroyCacheView(source_view);
1543MagickExport Image *RollImage(
const Image *image,
const ssize_t x_offset,
1544 const ssize_t y_offset,ExceptionInfo *exception)
1546#define RollImageTag "Roll/Image"
1560 assert(image != (
const Image *) NULL);
1561 assert(image->signature == MagickCoreSignature);
1562 assert(exception != (ExceptionInfo *) NULL);
1563 assert(exception->signature == MagickCoreSignature);
1564 if (IsEventLogging() != MagickFalse)
1565 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1566 roll_image=CloneImage(image,0,0,MagickTrue,exception);
1567 if (roll_image == (Image *) NULL)
1568 return((Image *) NULL);
1571 while (offset.x < 0)
1572 offset.x+=(ssize_t) image->columns;
1573 while (offset.x >= (ssize_t) image->columns)
1574 offset.x-=(ssize_t) image->columns;
1575 while (offset.y < 0)
1576 offset.y+=(ssize_t) image->rows;
1577 while (offset.y >= (ssize_t) image->rows)
1578 offset.y-=(ssize_t) image->rows;
1582 status=CopyImageRegion(roll_image,image,(
size_t) offset.x,
1583 (
size_t) offset.y,(ssize_t) image->columns-offset.x,(ssize_t) image->rows-
1584 offset.y,0,0,exception);
1585 (void) SetImageProgress(image,RollImageTag,0,3);
1586 status&=(MagickStatusType) CopyImageRegion(roll_image,image,(
size_t)
1587 ((ssize_t) image->columns-offset.x),(
size_t) offset.y,0,(ssize_t)
1588 image->rows-offset.y,offset.x,0,exception);
1589 (void) SetImageProgress(image,RollImageTag,1,3);
1590 status&=(MagickStatusType) CopyImageRegion(roll_image,image,(
size_t)
1591 offset.x,(
size_t) ((ssize_t) image->rows-offset.y),(ssize_t)
1592 image->columns-offset.x,0,0,offset.y,exception);
1593 (void) SetImageProgress(image,RollImageTag,2,3);
1594 status&=(MagickStatusType) CopyImageRegion(roll_image,image,(
size_t)
1595 ((ssize_t) image->columns-offset.x),(
size_t) ((ssize_t) image->rows-
1596 offset.y),0,0,offset.x,offset.y,exception);
1597 (void) SetImageProgress(image,RollImageTag,3,3);
1598 roll_image->type=image->type;
1599 if (status == MagickFalse)
1600 roll_image=DestroyImage(roll_image);
1638MagickExport Image *ShaveImage(
const Image *image,
1639 const RectangleInfo *shave_info,ExceptionInfo *exception)
1647 assert(image != (
const Image *) NULL);
1648 assert(image->signature == MagickCoreSignature);
1649 if (IsEventLogging() != MagickFalse)
1650 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1651 if (((2*shave_info->width) >= image->columns) ||
1652 ((2*shave_info->height) >= image->rows))
1653 ThrowImageException(OptionWarning,
"GeometryDoesNotContainImage");
1654 SetGeometry(image,&geometry);
1655 geometry.width-=2*shave_info->width;
1656 geometry.height-=2*shave_info->height;
1657 geometry.x=(ssize_t) shave_info->width+image->page.x;
1658 geometry.y=(ssize_t) shave_info->height+image->page.y;
1659 shave_image=CropImage(image,&geometry,exception);
1660 if (shave_image == (Image *) NULL)
1661 return((Image *) NULL);
1662 shave_image->page.width-=2*shave_info->width;
1663 shave_image->page.height-=2*shave_info->height;
1664 shave_image->page.x-=(ssize_t) shave_info->width;
1665 shave_image->page.y-=(ssize_t) shave_info->height;
1666 return(shave_image);
1698MagickExport Image *SpliceImage(
const Image *image,
1699 const RectangleInfo *geometry,ExceptionInfo *exception)
1701#define SpliceImageTag "Splice/Image"
1726 assert(image != (
const Image *) NULL);
1727 assert(image->signature == MagickCoreSignature);
1728 if (IsEventLogging() != MagickFalse)
1729 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1730 assert(geometry != (
const RectangleInfo *) NULL);
1731 assert(exception != (ExceptionInfo *) NULL);
1732 assert(exception->signature == MagickCoreSignature);
1733 splice_geometry=(*geometry);
1734 splice_image=CloneImage(image,image->columns+splice_geometry.width,
1735 image->rows+splice_geometry.height,MagickTrue,exception);
1736 if (splice_image == (Image *) NULL)
1737 return((Image *) NULL);
1738 if (SetImageStorageClass(splice_image,DirectClass,exception) == MagickFalse)
1740 splice_image=DestroyImage(splice_image);
1741 return((Image *) NULL);
1743 if ((IsPixelInfoGray(&splice_image->background_color) == MagickFalse) &&
1744 (IsGrayColorspace(splice_image->colorspace) != MagickFalse))
1745 (void) SetImageColorspace(splice_image,sRGBColorspace,exception);
1746 if ((splice_image->background_color.alpha_trait != UndefinedPixelTrait) &&
1747 (splice_image->alpha_trait == UndefinedPixelTrait))
1748 (void) SetImageAlpha(splice_image,OpaqueAlpha,exception);
1749 (void) SetImageBackgroundColor(splice_image,exception);
1753 switch (image->gravity)
1756 case UndefinedGravity:
1757 case NorthWestGravity:
1761 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1764 case NorthEastGravity:
1766 splice_geometry.x+=(ssize_t) splice_geometry.width;
1771 splice_geometry.y+=(ssize_t) splice_geometry.width/2;
1776 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1777 splice_geometry.y+=(ssize_t) splice_geometry.height/2;
1782 splice_geometry.x+=(ssize_t) splice_geometry.width;
1783 splice_geometry.y+=(ssize_t) splice_geometry.height/2;
1786 case SouthWestGravity:
1788 splice_geometry.y+=(ssize_t) splice_geometry.height;
1793 splice_geometry.x+=(ssize_t) splice_geometry.width/2;
1794 splice_geometry.y+=(ssize_t) splice_geometry.height;
1797 case SouthEastGravity:
1799 splice_geometry.x+=(ssize_t) splice_geometry.width;
1800 splice_geometry.y+=(ssize_t) splice_geometry.height;
1809 columns=MagickMin(splice_geometry.x,(ssize_t) splice_image->columns);
1810 image_view=AcquireVirtualCacheView(image,exception);
1811 splice_view=AcquireAuthenticCacheView(splice_image,exception);
1812#if defined(MAGICKCORE_OPENMP_SUPPORT)
1813 #pragma omp parallel for schedule(static) shared(progress,status) \
1814 magick_number_threads(image,splice_image,(size_t) splice_geometry.y,2)
1816 for (y=0; y < (ssize_t) splice_geometry.y; y++)
1827 if (status == MagickFalse)
1829 p=GetCacheViewVirtualPixels(image_view,0,y,splice_image->columns,1,
1831 q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
1833 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1838 for (x=0; x < columns; x++)
1843 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1845 PixelChannel channel = GetPixelChannelChannel(image,i);
1846 PixelTrait traits = GetPixelChannelTraits(image,channel);
1847 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1848 if ((traits == UndefinedPixelTrait) ||
1849 (splice_traits == UndefinedPixelTrait))
1851 SetPixelChannel(splice_image,channel,p[i],q);
1853 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1854 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1855 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1856 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1857 p+=(ptrdiff_t) GetPixelChannels(image);
1858 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1860 for ( ; x < (splice_geometry.x+(ssize_t) splice_geometry.width); x++)
1861 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1862 for ( ; x < (ssize_t) splice_image->columns; x++)
1867 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1869 PixelChannel channel = GetPixelChannelChannel(image,i);
1870 PixelTrait traits = GetPixelChannelTraits(image,channel);
1871 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1872 if ((traits == UndefinedPixelTrait) ||
1873 (splice_traits == UndefinedPixelTrait))
1875 SetPixelChannel(splice_image,channel,p[i],q);
1877 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1878 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1879 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1880 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1881 p+=(ptrdiff_t) GetPixelChannels(image);
1882 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1884 if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
1886 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1891#if defined(MAGICKCORE_OPENMP_SUPPORT)
1895 proceed=SetImageProgress(image,SpliceImageTag,progress,
1896 splice_image->rows);
1897 if (proceed == MagickFalse)
1901#if defined(MAGICKCORE_OPENMP_SUPPORT)
1902 #pragma omp parallel for schedule(static) shared(progress,status) \
1903 magick_number_threads(image,splice_image,splice_image->rows,2)
1905 for (y=splice_geometry.y+(ssize_t) splice_geometry.height; y < (ssize_t) splice_image->rows; y++)
1916 if (status == MagickFalse)
1918 if ((y < 0) || (y >= (ssize_t) splice_image->rows))
1920 p=GetCacheViewVirtualPixels(image_view,0,y-(ssize_t) splice_geometry.height,
1921 splice_image->columns,1,exception);
1922 q=QueueCacheViewAuthenticPixels(splice_view,0,y,splice_image->columns,1,
1924 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
1929 for (x=0; x < columns; x++)
1934 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1936 PixelChannel channel = GetPixelChannelChannel(image,i);
1937 PixelTrait traits = GetPixelChannelTraits(image,channel);
1938 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1939 if ((traits == UndefinedPixelTrait) ||
1940 (splice_traits == UndefinedPixelTrait))
1942 SetPixelChannel(splice_image,channel,p[i],q);
1944 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1945 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1946 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1947 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1948 p+=(ptrdiff_t) GetPixelChannels(image);
1949 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1951 for ( ; x < (splice_geometry.x+(ssize_t) splice_geometry.width); x++)
1952 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1953 for ( ; x < (ssize_t) splice_image->columns; x++)
1958 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
1960 PixelChannel channel = GetPixelChannelChannel(image,i);
1961 PixelTrait traits = GetPixelChannelTraits(image,channel);
1962 PixelTrait splice_traits=GetPixelChannelTraits(splice_image,channel);
1963 if ((traits == UndefinedPixelTrait) ||
1964 (splice_traits == UndefinedPixelTrait))
1966 SetPixelChannel(splice_image,channel,p[i],q);
1968 SetPixelRed(splice_image,GetPixelRed(image,p),q);
1969 SetPixelGreen(splice_image,GetPixelGreen(image,p),q);
1970 SetPixelBlue(splice_image,GetPixelBlue(image,p),q);
1971 SetPixelAlpha(splice_image,GetPixelAlpha(image,p),q);
1972 p+=(ptrdiff_t) GetPixelChannels(image);
1973 q+=(ptrdiff_t) GetPixelChannels(splice_image);
1975 if (SyncCacheViewAuthenticPixels(splice_view,exception) == MagickFalse)
1977 if (image->progress_monitor != (MagickProgressMonitor) NULL)
1982#if defined(MAGICKCORE_OPENMP_SUPPORT)
1986 proceed=SetImageProgress(image,SpliceImageTag,progress,
1987 splice_image->rows);
1988 if (proceed == MagickFalse)
1992 splice_view=DestroyCacheView(splice_view);
1993 image_view=DestroyCacheView(image_view);
1994 if (status == MagickFalse)
1995 splice_image=DestroyImage(splice_image);
1996 return(splice_image);
2046MagickPrivate MagickBooleanType TransformImage(Image **image,
2047 const char *crop_geometry,
const char *image_geometry,ExceptionInfo *exception)
2056 assert(image != (Image **) NULL);
2057 assert((*image)->signature == MagickCoreSignature);
2058 if (IsEventLogging() != MagickFalse)
2059 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",(*image)->filename);
2060 transform_image=(*image);
2061 if (crop_geometry != (
const char *) NULL)
2069 crop_image=CropImageToTiles(*image,crop_geometry,exception);
2070 if (crop_image == (Image *) NULL)
2071 transform_image=CloneImage(*image,0,0,MagickTrue,exception);
2074 transform_image=DestroyImage(transform_image);
2075 transform_image=GetFirstImageInList(crop_image);
2077 *image=transform_image;
2079 if (image_geometry == (
const char *) NULL)
2084 (void) ParseRegionGeometry(transform_image,image_geometry,&geometry,
2086 if ((transform_image->columns == geometry.width) &&
2087 (transform_image->rows == geometry.height))
2089 resize_image=ResizeImage(transform_image,geometry.width,geometry.height,
2090 transform_image->filter,exception);
2091 if (resize_image == (Image *) NULL)
2092 return(MagickFalse);
2093 transform_image=DestroyImage(transform_image);
2094 transform_image=resize_image;
2095 *image=transform_image;
2124MagickExport Image *TransposeImage(
const Image *image,ExceptionInfo *exception)
2126#define TransposeImageTag "Transpose/Image"
2147 assert(image != (
const Image *) NULL);
2148 assert(image->signature == MagickCoreSignature);
2149 assert(exception != (ExceptionInfo *) NULL);
2150 assert(exception->signature == MagickCoreSignature);
2151 if (IsEventLogging() != MagickFalse)
2152 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2153 transpose_image=CloneImage(image,image->rows,image->columns,MagickTrue,
2155 if (transpose_image == (Image *) NULL)
2156 return((Image *) NULL);
2162 image_view=AcquireVirtualCacheView(image,exception);
2163 transpose_view=AcquireAuthenticCacheView(transpose_image,exception);
2164#if defined(MAGICKCORE_OPENMP_SUPPORT)
2165 #pragma omp parallel for schedule(static) shared(progress,status) \
2166 magick_number_threads(image,transpose_image,image->rows,2)
2168 for (y=0; y < (ssize_t) image->rows; y++)
2179 if (status == MagickFalse)
2181 p=GetCacheViewVirtualPixels(image_view,0,(ssize_t) image->rows-y-1,
2182 image->columns,1,exception);
2183 q=QueueCacheViewAuthenticPixels(transpose_view,(ssize_t) image->rows-y-1,
2184 0,1,transpose_image->rows,exception);
2185 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
2190 for (x=0; x < (ssize_t) image->columns; x++)
2195 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2197 PixelChannel channel = GetPixelChannelChannel(image,i);
2198 PixelTrait traits = GetPixelChannelTraits(image,channel);
2199 PixelTrait transpose_traits=GetPixelChannelTraits(transpose_image,
2201 if ((traits == UndefinedPixelTrait) ||
2202 (transpose_traits == UndefinedPixelTrait))
2204 SetPixelChannel(transpose_image,channel,p[i],q);
2206 p+=(ptrdiff_t) GetPixelChannels(image);
2207 q+=(ptrdiff_t) GetPixelChannels(transpose_image);
2209 if (SyncCacheViewAuthenticPixels(transpose_view,exception) == MagickFalse)
2211 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2216#if defined(MAGICKCORE_OPENMP_SUPPORT)
2220 proceed=SetImageProgress(image,TransposeImageTag,progress,image->rows);
2221 if (proceed == MagickFalse)
2225 transpose_view=DestroyCacheView(transpose_view);
2226 image_view=DestroyCacheView(image_view);
2227 transpose_image->type=image->type;
2228 page=transpose_image->page;
2229 Swap(page.width,page.height);
2230 Swap(page.x,page.y);
2231 transpose_image->page=page;
2232 if (status == MagickFalse)
2233 transpose_image=DestroyImage(transpose_image);
2234 return(transpose_image);
2262MagickExport Image *TransverseImage(
const Image *image,ExceptionInfo *exception)
2264#define TransverseImageTag "Transverse/Image"
2285 assert(image != (
const Image *) NULL);
2286 assert(image->signature == MagickCoreSignature);
2287 assert(exception != (ExceptionInfo *) NULL);
2288 assert(exception->signature == MagickCoreSignature);
2289 if (IsEventLogging() != MagickFalse)
2290 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2291 transverse_image=CloneImage(image,image->rows,image->columns,MagickTrue,
2293 if (transverse_image == (Image *) NULL)
2294 return((Image *) NULL);
2300 image_view=AcquireVirtualCacheView(image,exception);
2301 transverse_view=AcquireAuthenticCacheView(transverse_image,exception);
2302#if defined(MAGICKCORE_OPENMP_SUPPORT)
2303 #pragma omp parallel for schedule(static) shared(progress,status) \
2304 magick_number_threads(image,transverse_image,image->rows,2)
2306 for (y=0; y < (ssize_t) image->rows; y++)
2320 if (status == MagickFalse)
2322 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
2323 q=QueueCacheViewAuthenticPixels(transverse_view,(ssize_t) image->rows-y-1,
2324 0,1,transverse_image->rows,exception);
2325 if ((p == (
const Quantum *) NULL) || (q == (Quantum *) NULL))
2330 q+=(ptrdiff_t) GetPixelChannels(transverse_image)*image->columns;
2331 for (x=0; x < (ssize_t) image->columns; x++)
2336 q-=GetPixelChannels(transverse_image);
2337 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
2339 PixelChannel channel = GetPixelChannelChannel(image,i);
2340 PixelTrait traits = GetPixelChannelTraits(image,channel);
2341 PixelTrait transverse_traits=GetPixelChannelTraits(transverse_image,
2343 if ((traits == UndefinedPixelTrait) ||
2344 (transverse_traits == UndefinedPixelTrait))
2346 SetPixelChannel(transverse_image,channel,p[i],q);
2348 p+=(ptrdiff_t) GetPixelChannels(image);
2350 sync=SyncCacheViewAuthenticPixels(transverse_view,exception);
2351 if (sync == MagickFalse)
2353 if (image->progress_monitor != (MagickProgressMonitor) NULL)
2358#if defined(MAGICKCORE_OPENMP_SUPPORT)
2362 proceed=SetImageProgress(image,TransverseImageTag,progress,image->rows);
2363 if (proceed == MagickFalse)
2367 transverse_view=DestroyCacheView(transverse_view);
2368 image_view=DestroyCacheView(image_view);
2369 transverse_image->type=image->type;
2370 page=transverse_image->page;
2371 Swap(page.width,page.height);
2372 Swap(page.x,page.y);
2373 if (page.width != 0)
2374 page.x=(ssize_t) page.width-(ssize_t) transverse_image->columns-page.x;
2375 if (page.height != 0)
2376 page.y=(ssize_t) page.height-(ssize_t) transverse_image->rows-page.y;
2377 transverse_image->page=page;
2378 if (status == MagickFalse)
2379 transverse_image=DestroyImage(transverse_image);
2380 return(transverse_image);
2409MagickExport Image *TrimImage(
const Image *image,ExceptionInfo *exception)
2421 assert(image != (
const Image *) NULL);
2422 assert(image->signature == MagickCoreSignature);
2423 if (IsEventLogging() != MagickFalse)
2424 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
2425 geometry=GetImageBoundingBox(image,exception);
2426 if ((geometry.width == 0) || (geometry.height == 0))
2431 crop_image=CloneImage(image,1,1,MagickTrue,exception);
2432 if (crop_image == (Image *) NULL)
2433 return((Image *) NULL);
2434 crop_image->background_color.alpha_trait=BlendPixelTrait;
2435 crop_image->background_color.alpha=(MagickRealType) TransparentAlpha;
2436 (void) SetImageBackgroundColor(crop_image,exception);
2437 crop_image->page=image->page;
2438 crop_image->page.x=(-1);
2439 crop_image->page.y=(-1);
2443 artifact=GetImageArtifact(image,
"trim:minSize");
2444 if (artifact != (
const char *) NULL)
2445 (void) ParseAbsoluteGeometry(artifact,&page);
2446 if ((geometry.width < page.width) && (geometry.height < page.height))
2451 switch (image->gravity)
2455 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width)/2;
2456 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height)/2;
2459 case NorthWestGravity:
2461 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width);
2462 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height);
2467 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width)/2;
2468 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height);
2471 case NorthEastGravity:
2473 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height);
2478 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height)/2;
2481 case SouthEastGravity:
2485 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width)/2;
2488 case SouthWestGravity:
2490 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width);
2495 geometry.x-=((ssize_t) page.width-(ssize_t) geometry.width);
2496 geometry.y-=((ssize_t) page.height-(ssize_t) geometry.height)/2;
2502 geometry.width=page.width;
2503 geometry.height=page.height;
2505 geometry.x+=image->page.x;
2506 geometry.y+=image->page.y;
2507 trim_image=CropImage(image,&geometry,exception);
2508 if (trim_image != (Image *) NULL)
2509 Update8BIMClipPath(trim_image,image->columns,image->rows,&geometry);