2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 % IIIII M M AAA GGGG EEEEE %
7 % I M M M AAAAA G GG EEE %
9 % IIIII M M A A GGGG EEEEE %
11 % V V IIIII EEEEE W W %
18 % MagickCore Image View Methods %
25 % Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization %
26 % dedicated to making software imaging solutions freely available. %
28 % You may not use this file except in compliance with the License. You may %
29 % obtain a copy of the License at %
31 % https://imagemagick.org/script/license.php %
33 % Unless required by applicable law or agreed to in writing, software %
34 % distributed under the License is distributed on an "AS IS" BASIS, %
35 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
36 % See the License for the specific language governing permissions and %
37 % limitations under the License. %
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48 #include "MagickCore/studio.h"
49 #include "MagickCore/MagickCore.h"
50 #include "MagickCore/exception-private.h"
51 #include "MagickCore/memory-private.h"
52 #include "MagickCore/monitor-private.h"
53 #include "MagickCore/thread-private.h"
83 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
87 % C l o n e I m a g e V i e w %
91 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93 % CloneImageView() makes a copy of the specified image view.
95 % The format of the CloneImageView method is:
97 % ImageView *CloneImageView(const ImageView *image_view)
99 % A description of each parameter follows:
101 % o image_view: the image view.
104 MagickExport ImageView *CloneImageView(const ImageView *image_view)
109 assert(image_view != (ImageView *) NULL);
110 assert(image_view->signature == MagickCoreSignature);
111 clone_view=(ImageView *) AcquireCriticalMemory(sizeof(*clone_view));
112 (void) memset(clone_view,0,sizeof(*clone_view));
113 clone_view->description=ConstantString(image_view->description);
114 clone_view->extent=image_view->extent;
115 clone_view->view=CloneCacheView(image_view->view);
116 clone_view->exception=AcquireExceptionInfo();
117 InheritException(clone_view->exception,image_view->exception);
118 clone_view->debug=image_view->debug;
119 clone_view->signature=MagickCoreSignature;
124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
128 % D e s t r o y I m a g e V i e w %
132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134 % DestroyImageView() deallocates memory associated with a image view.
136 % The format of the DestroyImageView method is:
138 % ImageView *DestroyImageView(ImageView *image_view)
140 % A description of each parameter follows:
142 % o image_view: the image view.
145 MagickExport ImageView *DestroyImageView(ImageView *image_view)
147 assert(image_view != (ImageView *) NULL);
148 assert(image_view->signature == MagickCoreSignature);
149 if (image_view->description != (char *) NULL)
150 image_view->description=DestroyString(image_view->description);
151 image_view->view=DestroyCacheView(image_view->view);
152 image_view->exception=DestroyExceptionInfo(image_view->exception);
153 image_view->signature=(~MagickCoreSignature);
154 image_view=(ImageView *) RelinquishMagickMemory(image_view);
159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
163 % D u p l e x T r a n s f e r I m a g e V i e w I t e r a t o r %
167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169 % DuplexTransferImageViewIterator() iterates over three image views in
170 % parallel and calls your transfer method for each scanline of the view. The
171 % source and duplex pixel extent is not confined to the image canvas-- that is
172 % you can include negative offsets or widths or heights that exceed the image
173 % dimension. However, the destination image view is confined to the image
174 % canvas-- that is no negative offsets or widths or heights that exceed the
175 % image dimension are permitted.
177 % The callback signature is:
179 % MagickBooleanType DuplexTransferImageViewMethod(const ImageView *source,
180 % const ImageView *duplex,ImageView *destination,const ssize_t y,
181 % const int thread_id,void *context)
183 % Use this pragma if the view is not single threaded:
185 % #pragma omp critical
187 % to define a section of code in your callback transfer method that must be
188 % executed by a single thread at a time.
190 % The format of the DuplexTransferImageViewIterator method is:
192 % MagickBooleanType DuplexTransferImageViewIterator(ImageView *source,
193 % ImageView *duplex,ImageView *destination,
194 % DuplexTransferImageViewMethod transfer,void *context)
196 % A description of each parameter follows:
198 % o source: the source image view.
200 % o duplex: the duplex image view.
202 % o destination: the destination image view.
204 % o transfer: the transfer callback method.
206 % o context: the user defined context.
209 MagickExport MagickBooleanType DuplexTransferImageViewIterator(
210 ImageView *source,ImageView *duplex,ImageView *destination,
211 DuplexTransferImageViewMethod transfer,void *context)
223 #if defined(MAGICKCORE_OPENMP_SUPPORT)
231 assert(source != (ImageView *) NULL);
232 assert(source->signature == MagickCoreSignature);
233 if (transfer == (DuplexTransferImageViewMethod) NULL)
235 source_image=source->image;
236 destination_image=destination->image;
237 status=SetImageStorageClass(destination_image,DirectClass,
238 destination->exception);
239 if (status == MagickFalse)
243 #if defined(MAGICKCORE_OPENMP_SUPPORT)
244 height=source->extent.height-source->extent.y;
245 #pragma omp parallel for schedule(static) shared(progress,status) \
246 magick_number_threads(source_image,destination_image,height,1)
248 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
251 id = GetOpenMPThreadId();
256 register const Quantum
257 *magick_restrict duplex_pixels,
258 *magick_restrict pixels;
261 *magick_restrict destination_pixels;
263 if (status == MagickFalse)
265 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
266 source->extent.width,1,source->exception);
267 if (pixels == (const Quantum *) NULL)
272 duplex_pixels=GetCacheViewVirtualPixels(duplex->view,duplex->extent.x,y,
273 duplex->extent.width,1,duplex->exception);
274 if (duplex_pixels == (const Quantum *) NULL)
279 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
280 destination->extent.x,y,destination->extent.width,1,
281 destination->exception);
282 if (destination_pixels == (Quantum *) NULL)
287 if (transfer(source,duplex,destination,y,id,context) == MagickFalse)
289 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
290 if (sync == MagickFalse)
292 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
297 #if defined(MAGICKCORE_OPENMP_SUPPORT)
298 #pragma omp critical (MagickCore_DuplexTransferImageViewIterator)
300 proceed=SetImageProgress(source_image,source->description,progress++,
301 source->extent.height);
302 if (proceed == MagickFalse)
310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
314 % G e t I m a g e V i e w A u t h e n t i c M e t a c o n t e n t %
318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
320 % GetImageViewAuthenticMetacontent() returns the image view authentic
323 % The format of the GetImageViewAuthenticPixels method is:
325 % void *GetImageViewAuthenticMetacontent(
326 % const ImageView *image_view)
328 % A description of each parameter follows:
330 % o image_view: the image view.
333 MagickExport void *GetImageViewAuthenticMetacontent(
334 const ImageView *image_view)
336 assert(image_view != (ImageView *) NULL);
337 assert(image_view->signature == MagickCoreSignature);
338 return(GetCacheViewAuthenticMetacontent(image_view->view));
342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
346 % G e t I m a g e V i e w A u t h e n t i c P i x e l s %
350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
352 % GetImageViewAuthenticPixels() returns the image view authentic pixels.
354 % The format of the GetImageViewAuthenticPixels method is:
356 % Quantum *GetImageViewAuthenticPixels(const ImageView *image_view)
358 % A description of each parameter follows:
360 % o image_view: the image view.
363 MagickExport Quantum *GetImageViewAuthenticPixels(
364 const ImageView *image_view)
366 assert(image_view != (ImageView *) NULL);
367 assert(image_view->signature == MagickCoreSignature);
368 return(GetCacheViewAuthenticPixelQueue(image_view->view));
372 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376 % G e t I m a g e V i e w E x c e p t i o n %
380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
382 % GetImageViewException() returns the severity, reason, and description of any
383 % error that occurs when utilizing a image view.
385 % The format of the GetImageViewException method is:
387 % char *GetImageViewException(const PixelImage *image_view,
388 % ExceptionType *severity)
390 % A description of each parameter follows:
392 % o image_view: the pixel image_view.
394 % o severity: the severity of the error is returned here.
397 MagickExport char *GetImageViewException(const ImageView *image_view,
398 ExceptionType *severity)
403 assert(image_view != (const ImageView *) NULL);
404 assert(image_view->signature == MagickCoreSignature);
405 assert(severity != (ExceptionType *) NULL);
406 *severity=image_view->exception->severity;
407 description=(char *) AcquireQuantumMemory(2UL*MagickPathExtent,
408 sizeof(*description));
409 if (description == (char *) NULL)
410 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
412 if (image_view->exception->reason != (char *) NULL)
413 (void) CopyMagickString(description,GetLocaleExceptionMessage(
414 image_view->exception->severity,image_view->exception->reason),
416 if (image_view->exception->description != (char *) NULL)
418 (void) ConcatenateMagickString(description," (",MagickPathExtent);
419 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
420 image_view->exception->severity,image_view->exception->description),
422 (void) ConcatenateMagickString(description,")",MagickPathExtent);
428 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432 % G e t I m a g e V i e w E x t e n t %
436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
438 % GetImageViewExtent() returns the image view extent.
440 % The format of the GetImageViewExtent method is:
442 % RectangleInfo GetImageViewExtent(const ImageView *image_view)
444 % A description of each parameter follows:
446 % o image_view: the image view.
449 MagickExport RectangleInfo GetImageViewExtent(const ImageView *image_view)
451 assert(image_view != (ImageView *) NULL);
452 assert(image_view->signature == MagickCoreSignature);
453 return(image_view->extent);
457 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
461 % G e t I m a g e V i e w I m a g e %
465 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
467 % GetImageViewImage() returns the image associated with the image view.
469 % The format of the GetImageViewImage method is:
471 % MagickCore *GetImageViewImage(const ImageView *image_view)
473 % A description of each parameter follows:
475 % o image_view: the image view.
478 MagickExport Image *GetImageViewImage(const ImageView *image_view)
480 assert(image_view != (ImageView *) NULL);
481 assert(image_view->signature == MagickCoreSignature);
482 return(image_view->image);
486 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
490 % G e t I m a g e V i e w I t e r a t o r %
494 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
496 % GetImageViewIterator() iterates over the image view in parallel and calls
497 % your get method for each scanline of the view. The pixel extent is
498 % not confined to the image canvas-- that is you can include negative offsets
499 % or widths or heights that exceed the image dimension. Any updates to
500 % the pixels in your callback are ignored.
502 % The callback signature is:
504 % MagickBooleanType GetImageViewMethod(const ImageView *source,
505 % const ssize_t y,const int thread_id,void *context)
507 % Use this pragma if the view is not single threaded:
509 % #pragma omp critical
511 % to define a section of code in your callback get method that must be
512 % executed by a single thread at a time.
514 % The format of the GetImageViewIterator method is:
516 % MagickBooleanType GetImageViewIterator(ImageView *source,
517 % GetImageViewMethod get,void *context)
519 % A description of each parameter follows:
521 % o source: the source image view.
523 % o get: the get callback method.
525 % o context: the user defined context.
528 MagickExport MagickBooleanType GetImageViewIterator(ImageView *source,
529 GetImageViewMethod get,void *context)
540 #if defined(MAGICKCORE_OPENMP_SUPPORT)
548 assert(source != (ImageView *) NULL);
549 assert(source->signature == MagickCoreSignature);
550 if (get == (GetImageViewMethod) NULL)
552 source_image=source->image;
555 #if defined(MAGICKCORE_OPENMP_SUPPORT)
556 height=source->extent.height-source->extent.y;
557 #pragma omp parallel for schedule(static) shared(progress,status) \
558 magick_number_threads(source_image,source_image,height,1)
560 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
563 id = GetOpenMPThreadId();
565 register const Quantum
568 if (status == MagickFalse)
570 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
571 source->extent.width,1,source->exception);
572 if (pixels == (const Quantum *) NULL)
577 if (get(source,y,id,context) == MagickFalse)
579 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
584 #if defined(MAGICKCORE_OPENMP_SUPPORT)
585 #pragma omp critical (MagickCore_GetImageViewIterator)
587 proceed=SetImageProgress(source_image,source->description,progress++,
588 source->extent.height);
589 if (proceed == MagickFalse)
597 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
601 % G e t I m a g e V i e w V i r t u a l M e t a c o n t e n t %
605 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
607 % GetImageViewVirtualMetacontent() returns the image view virtual
610 % The format of the GetImageViewVirtualMetacontent method is:
612 % const void *GetImageViewVirtualMetacontent(
613 % const ImageView *image_view)
615 % A description of each parameter follows:
617 % o image_view: the image view.
620 MagickExport const void *GetImageViewVirtualMetacontent(
621 const ImageView *image_view)
623 assert(image_view != (ImageView *) NULL);
624 assert(image_view->signature == MagickCoreSignature);
625 return(GetCacheViewVirtualMetacontent(image_view->view));
629 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
633 % G e t I m a g e V i e w V i r t u a l P i x e l s %
637 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
639 % GetImageViewVirtualPixels() returns the image view virtual pixels.
641 % The format of the GetImageViewVirtualPixels method is:
643 % const Quantum *GetImageViewVirtualPixels(const ImageView *image_view)
645 % A description of each parameter follows:
647 % o image_view: the image view.
650 MagickExport const Quantum *GetImageViewVirtualPixels(
651 const ImageView *image_view)
653 assert(image_view != (ImageView *) NULL);
654 assert(image_view->signature == MagickCoreSignature);
655 return(GetCacheViewVirtualPixelQueue(image_view->view));
659 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
663 % I s I m a g e V i e w %
667 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
669 % IsImageView() returns MagickTrue if the the parameter is verified as a image
672 % The format of the IsImageView method is:
674 % MagickBooleanType IsImageView(const ImageView *image_view)
676 % A description of each parameter follows:
678 % o image_view: the image view.
681 MagickExport MagickBooleanType IsImageView(const ImageView *image_view)
683 if (image_view == (const ImageView *) NULL)
685 if (image_view->signature != MagickCoreSignature)
691 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
695 % N e w I m a g e V i e w %
699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
701 % NewImageView() returns a image view required for all other methods in the
704 % The format of the NewImageView method is:
706 % ImageView *NewImageView(MagickCore *wand,ExceptionInfo *exception)
708 % A description of each parameter follows:
710 % o image: the image.
712 % o exception: return any errors or warnings in this structure.
715 MagickExport ImageView *NewImageView(Image *image,ExceptionInfo *exception)
720 assert(image != (Image *) NULL);
721 assert(image->signature == MagickCoreSignature);
722 image_view=(ImageView *) AcquireCriticalMemory(sizeof(*image_view));
723 (void) memset(image_view,0,sizeof(*image_view));
724 image_view->description=ConstantString("ImageView");
725 image_view->image=image;
726 image_view->view=AcquireVirtualCacheView(image_view->image,exception);
727 image_view->extent.width=image->columns;
728 image_view->extent.height=image->rows;
729 image_view->extent.x=0;
730 image_view->extent.y=0;
731 image_view->exception=AcquireExceptionInfo();
732 image_view->debug=IsEventLogging();
733 image_view->signature=MagickCoreSignature;
738 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
742 % N e w I m a g e V i e w R e g i o n %
746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
748 % NewImageViewRegion() returns a image view required for all other methods
749 % in the Image View API.
751 % The format of the NewImageViewRegion method is:
753 % ImageView *NewImageViewRegion(MagickCore *wand,const ssize_t x,
754 % const ssize_t y,const size_t width,const size_t height,
755 % ExceptionInfo *exception)
757 % A description of each parameter follows:
759 % o wand: the magick wand.
761 % o x,y,columns,rows: These values define the perimeter of a extent of
764 % o exception: return any errors or warnings in this structure.
767 MagickExport ImageView *NewImageViewRegion(Image *image,const ssize_t x,
768 const ssize_t y,const size_t width,const size_t height,
769 ExceptionInfo *exception)
774 assert(image != (Image *) NULL);
775 assert(image->signature == MagickCoreSignature);
776 image_view=(ImageView *) AcquireCriticalMemory(sizeof(*image_view));
777 (void) memset(image_view,0,sizeof(*image_view));
778 image_view->description=ConstantString("ImageView");
779 image_view->view=AcquireVirtualCacheView(image_view->image,exception);
780 image_view->image=image;
781 image_view->extent.width=width;
782 image_view->extent.height=height;
783 image_view->extent.x=x;
784 image_view->extent.y=y;
785 image_view->exception=AcquireExceptionInfo();
786 image_view->debug=IsEventLogging();
787 image_view->signature=MagickCoreSignature;
792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
796 % S e t I m a g e V i e w D e s c r i p t i o n %
800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802 % SetImageViewDescription() associates a description with an image view.
804 % The format of the SetImageViewDescription method is:
806 % void SetImageViewDescription(ImageView *image_view,
807 % const char *description)
809 % A description of each parameter follows:
811 % o image_view: the image view.
813 % o description: the image view description.
816 MagickExport void SetImageViewDescription(ImageView *image_view,
817 const char *description)
819 assert(image_view != (ImageView *) NULL);
820 assert(image_view->signature == MagickCoreSignature);
821 image_view->description=ConstantString(description);
825 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
829 % S e t I m a g e V i e w I t e r a t o r %
833 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
835 % SetImageViewIterator() iterates over the image view in parallel and calls
836 % your set method for each scanline of the view. The pixel extent is
837 % confined to the image canvas-- that is no negative offsets or widths or
838 % heights that exceed the image dimension. The pixels are initiallly
839 % undefined and any settings you make in the callback method are automagically
840 % synced back to your image.
842 % The callback signature is:
844 % MagickBooleanType SetImageViewMethod(ImageView *destination,
845 % const ssize_t y,const int thread_id,void *context)
847 % Use this pragma if the view is not single threaded:
849 % #pragma omp critical
851 % to define a section of code in your callback set method that must be
852 % executed by a single thread at a time.
854 % The format of the SetImageViewIterator method is:
856 % MagickBooleanType SetImageViewIterator(ImageView *destination,
857 % SetImageViewMethod set,void *context)
859 % A description of each parameter follows:
861 % o destination: the image view.
863 % o set: the set callback method.
865 % o context: the user defined context.
868 MagickExport MagickBooleanType SetImageViewIterator(ImageView *destination,
869 SetImageViewMethod set,void *context)
880 #if defined(MAGICKCORE_OPENMP_SUPPORT)
888 assert(destination != (ImageView *) NULL);
889 assert(destination->signature == MagickCoreSignature);
890 if (set == (SetImageViewMethod) NULL)
892 destination_image=destination->image;
893 status=SetImageStorageClass(destination_image,DirectClass,
894 destination->exception);
895 if (status == MagickFalse)
899 #if defined(MAGICKCORE_OPENMP_SUPPORT)
900 height=destination->extent.height-destination->extent.y;
901 #pragma omp parallel for schedule(static) shared(progress,status) \
902 magick_number_threads(destination_image,destination_image,height,1)
904 for (y=destination->extent.y; y < (ssize_t) destination->extent.height; y++)
907 id = GetOpenMPThreadId();
913 *magick_restrict pixels;
915 if (status == MagickFalse)
917 pixels=GetCacheViewAuthenticPixels(destination->view,destination->extent.x,
918 y,destination->extent.width,1,destination->exception);
919 if (pixels == (Quantum *) NULL)
924 if (set(destination,y,id,context) == MagickFalse)
926 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
927 if (sync == MagickFalse)
929 if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
934 #if defined(MAGICKCORE_OPENMP_SUPPORT)
935 #pragma omp critical (MagickCore_SetImageViewIterator)
937 proceed=SetImageProgress(destination_image,destination->description,
938 progress++,destination->extent.height);
939 if (proceed == MagickFalse)
947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
951 % T r a n s f e r I m a g e V i e w I t e r a t o r %
955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
957 % TransferImageViewIterator() iterates over two image views in parallel and
958 % calls your transfer method for each scanline of the view. The source pixel
959 % extent is not confined to the image canvas-- that is you can include
960 % negative offsets or widths or heights that exceed the image dimension.
961 % However, the destination image view is confined to the image canvas-- that
962 % is no negative offsets or widths or heights that exceed the image dimension
965 % The callback signature is:
967 % MagickBooleanType TransferImageViewMethod(const ImageView *source,
968 % ImageView *destination,const ssize_t y,const int thread_id,
971 % Use this pragma if the view is not single threaded:
973 % #pragma omp critical
975 % to define a section of code in your callback transfer method that must be
976 % executed by a single thread at a time.
978 % The format of the TransferImageViewIterator method is:
980 % MagickBooleanType TransferImageViewIterator(ImageView *source,
981 % ImageView *destination,TransferImageViewMethod transfer,void *context)
983 % A description of each parameter follows:
985 % o source: the source image view.
987 % o destination: the destination image view.
989 % o transfer: the transfer callback method.
991 % o context: the user defined context.
994 MagickExport MagickBooleanType TransferImageViewIterator(ImageView *source,
995 ImageView *destination,TransferImageViewMethod transfer,void *context)
1007 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1015 assert(source != (ImageView *) NULL);
1016 assert(source->signature == MagickCoreSignature);
1017 if (transfer == (TransferImageViewMethod) NULL)
1018 return(MagickFalse);
1019 source_image=source->image;
1020 destination_image=destination->image;
1021 status=SetImageStorageClass(destination_image,DirectClass,
1022 destination->exception);
1023 if (status == MagickFalse)
1024 return(MagickFalse);
1027 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1028 height=source->extent.height-source->extent.y;
1029 #pragma omp parallel for schedule(static) shared(progress,status) \
1030 magick_number_threads(source_image,destination_image,height,1)
1032 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1035 id = GetOpenMPThreadId();
1040 register const Quantum
1041 *magick_restrict pixels;
1044 *magick_restrict destination_pixels;
1046 if (status == MagickFalse)
1048 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
1049 source->extent.width,1,source->exception);
1050 if (pixels == (const Quantum *) NULL)
1055 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
1056 destination->extent.x,y,destination->extent.width,1,
1057 destination->exception);
1058 if (destination_pixels == (Quantum *) NULL)
1063 if (transfer(source,destination,y,id,context) == MagickFalse)
1065 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
1066 if (sync == MagickFalse)
1068 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1073 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1074 #pragma omp critical (MagickCore_TransferImageViewIterator)
1076 proceed=SetImageProgress(source_image,source->description,progress++,
1077 source->extent.height);
1078 if (proceed == MagickFalse)
1086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1090 % U p d a t e I m a g e V i e w I t e r a t o r %
1094 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1096 % UpdateImageViewIterator() iterates over the image view in parallel and calls
1097 % your update method for each scanline of the view. The pixel extent is
1098 % confined to the image canvas-- that is no negative offsets or widths or
1099 % heights that exceed the image dimension are permitted. Updates to pixels
1100 % in your callback are automagically synced back to the image.
1102 % The callback signature is:
1104 % MagickBooleanType UpdateImageViewMethod(ImageView *source,
1105 % const ssize_t y,const int thread_id,void *context)
1107 % Use this pragma if the view is not single threaded:
1109 % #pragma omp critical
1111 % to define a section of code in your callback update method that must be
1112 % executed by a single thread at a time.
1114 % The format of the UpdateImageViewIterator method is:
1116 % MagickBooleanType UpdateImageViewIterator(ImageView *source,
1117 % UpdateImageViewMethod update,void *context)
1119 % A description of each parameter follows:
1121 % o source: the source image view.
1123 % o update: the update callback method.
1125 % o context: the user defined context.
1128 MagickExport MagickBooleanType UpdateImageViewIterator(ImageView *source,
1129 UpdateImageViewMethod update,void *context)
1140 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1148 assert(source != (ImageView *) NULL);
1149 assert(source->signature == MagickCoreSignature);
1150 if (update == (UpdateImageViewMethod) NULL)
1151 return(MagickFalse);
1152 source_image=source->image;
1153 status=SetImageStorageClass(source_image,DirectClass,source->exception);
1154 if (status == MagickFalse)
1155 return(MagickFalse);
1158 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1159 height=source->extent.height-source->extent.y;
1160 #pragma omp parallel for schedule(static) shared(progress,status) \
1161 magick_number_threads(source_image,source_image,height,1)
1163 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1166 id = GetOpenMPThreadId();
1169 *magick_restrict pixels;
1171 if (status == MagickFalse)
1173 pixels=GetCacheViewAuthenticPixels(source->view,source->extent.x,y,
1174 source->extent.width,1,source->exception);
1175 if (pixels == (Quantum *) NULL)
1180 if (update(source,y,id,context) == MagickFalse)
1182 status=SyncCacheViewAuthenticPixels(source->view,source->exception);
1183 if (status == MagickFalse)
1185 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1190 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1191 #pragma omp critical (MagickCore_UpdateImageViewIterator)
1193 proceed=SetImageProgress(source_image,source->description,progress++,
1194 source->extent.height);
1195 if (proceed == MagickFalse)