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-2011 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 % http://www.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/monitor-private.h"
52 #include "MagickCore/thread-private.h"
85 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
89 % C l o n e I m a g e V i e w %
93 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
95 % CloneImageView() makes a copy of the specified image view.
97 % The format of the CloneImageView method is:
99 % ImageView *CloneImageView(const ImageView *image_view)
101 % A description of each parameter follows:
103 % o image_view: the image view.
106 MagickExport ImageView *CloneImageView(const ImageView *image_view)
111 assert(image_view != (ImageView *) NULL);
112 assert(image_view->signature == MagickSignature);
113 clone_view=(ImageView *) AcquireMagickMemory(sizeof(*clone_view));
114 if (clone_view == (ImageView *) NULL)
115 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
116 (void) ResetMagickMemory(clone_view,0,sizeof(*clone_view));
117 clone_view->description=ConstantString(image_view->description);
118 clone_view->extent=image_view->extent;
119 clone_view->view=CloneCacheView(image_view->view);
120 clone_view->number_threads=image_view->number_threads;
121 clone_view->exception=AcquireExceptionInfo();
122 InheritException(clone_view->exception,image_view->exception);
123 clone_view->debug=image_view->debug;
124 clone_view->signature=MagickSignature;
129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
133 % D e s t r o y I m a g e V i e w %
137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139 % DestroyImageView() deallocates memory associated with a image view.
141 % The format of the DestroyImageView method is:
143 % ImageView *DestroyImageView(ImageView *image_view)
145 % A description of each parameter follows:
147 % o image_view: the image view.
150 MagickExport ImageView *DestroyImageView(ImageView *image_view)
152 assert(image_view != (ImageView *) NULL);
153 assert(image_view->signature == MagickSignature);
154 if (image_view->description != (char *) NULL)
155 image_view->description=DestroyString(image_view->description);
156 image_view->view=DestroyCacheView(image_view->view);
157 image_view->exception=DestroyExceptionInfo(image_view->exception);
158 image_view->signature=(~MagickSignature);
159 image_view=(ImageView *) RelinquishMagickMemory(image_view);
164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
168 % 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 %
172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
174 % DuplexTransferImageViewIterator() iterates over three image views in
175 % parallel and calls your transfer method for each scanline of the view. The
176 % source and duplex pixel extent is not confined to the image canvas-- that is
177 % you can include negative offsets or widths or heights that exceed the image
178 % dimension. However, the destination image view is confined to the image
179 % canvas-- that is no negative offsets or widths or heights that exceed the
180 % image dimension are permitted.
182 % The callback signature is:
184 % MagickBooleanType DuplexTransferImageViewMethod(const ImageView *source,
185 % const ImageView *duplex,ImageView *destination,const ssize_t y,
186 % const int thread_id,void *context)
188 % Use this pragma if the view is not single threaded:
190 % #pragma omp critical
192 % to define a section of code in your callback transfer method that must be
193 % executed by a single thread at a time.
195 % The format of the DuplexTransferImageViewIterator method is:
197 % MagickBooleanType DuplexTransferImageViewIterator(ImageView *source,
198 % ImageView *duplex,ImageView *destination,
199 % DuplexTransferImageViewMethod transfer,void *context)
201 % A description of each parameter follows:
203 % o source: the source image view.
205 % o duplex: the duplex image view.
207 % o destination: the destination image view.
209 % o transfer: the transfer callback method.
211 % o context: the user defined context.
214 MagickExport MagickBooleanType DuplexTransferImageViewIterator(
215 ImageView *source,ImageView *duplex,ImageView *destination,
216 DuplexTransferImageViewMethod transfer,void *context)
234 assert(source != (ImageView *) NULL);
235 assert(source->signature == MagickSignature);
236 if (transfer == (DuplexTransferImageViewMethod) NULL)
238 source_image=source->image;
239 destination_image=destination->image;
240 exception=destination->exception;
241 if (SetImageStorageClass(destination_image,DirectClass,exception) == MagickFalse)
245 #if defined(MAGICKCORE_OPENMP_SUPPORT)
246 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(source->number_threads)
248 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
251 id = GetOpenMPThreadId();
256 register const Quantum
257 *restrict duplex_pixels,
261 *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,exception);
281 if (destination_pixels == (Quantum *) NULL)
286 if (transfer(source,duplex,destination,y,id,context) == MagickFalse)
288 sync=SyncCacheViewAuthenticPixels(destination->view,exception);
289 if (sync == MagickFalse)
291 InheritException(destination->exception,GetCacheViewException(
295 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
300 #if defined(MAGICKCORE_OPENMP_SUPPORT)
301 #pragma omp critical (MagickCore_DuplexTransferImageViewIterator)
303 proceed=SetImageProgress(source_image,source->description,progress++,
304 source->extent.height);
305 if (proceed == MagickFalse)
313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317 % 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 %
321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
323 % GetImageViewAuthenticMetacontent() returns the image view authentic
326 % The format of the GetImageViewAuthenticPixels method is:
328 % void *GetImageViewAuthenticMetacontent(
329 % const ImageView *image_view)
331 % A description of each parameter follows:
333 % o image_view: the image view.
336 MagickExport void *GetImageViewAuthenticMetacontent(
337 const ImageView *image_view)
339 assert(image_view != (ImageView *) NULL);
340 assert(image_view->signature == MagickSignature);
341 return(GetCacheViewAuthenticMetacontent(image_view->view));
345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349 % 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 %
353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
355 % GetImageViewAuthenticPixels() returns the image view authentic pixels.
357 % The format of the GetImageViewAuthenticPixels method is:
359 % Quantum *GetImageViewAuthenticPixels(const ImageView *image_view)
361 % A description of each parameter follows:
363 % o image_view: the image view.
366 MagickExport Quantum *GetImageViewAuthenticPixels(
367 const ImageView *image_view)
369 assert(image_view != (ImageView *) NULL);
370 assert(image_view->signature == MagickSignature);
371 return(GetCacheViewAuthenticPixelQueue(image_view->view));
375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
379 % G e t I m a g e V i e w E x c e p t i o n %
383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385 % GetImageViewException() returns the severity, reason, and description of any
386 % error that occurs when utilizing a image view.
388 % The format of the GetImageViewException method is:
390 % char *GetImageViewException(const PixelImage *image_view,
391 % ExceptionType *severity)
393 % A description of each parameter follows:
395 % o image_view: the pixel image_view.
397 % o severity: the severity of the error is returned here.
400 MagickExport char *GetImageViewException(const ImageView *image_view,
401 ExceptionType *severity)
406 assert(image_view != (const ImageView *) NULL);
407 assert(image_view->signature == MagickSignature);
408 assert(severity != (ExceptionType *) NULL);
409 *severity=image_view->exception->severity;
410 description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
411 sizeof(*description));
412 if (description == (char *) NULL)
413 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
415 if (image_view->exception->reason != (char *) NULL)
416 (void) CopyMagickString(description,GetLocaleExceptionMessage(
417 image_view->exception->severity,image_view->exception->reason),
419 if (image_view->exception->description != (char *) NULL)
421 (void) ConcatenateMagickString(description," (",MaxTextExtent);
422 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
423 image_view->exception->severity,image_view->exception->description),
425 (void) ConcatenateMagickString(description,")",MaxTextExtent);
431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
435 % G e t I m a g e V i e w E x t e n t %
439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
441 % GetImageViewExtent() returns the image view extent.
443 % The format of the GetImageViewExtent method is:
445 % RectangleInfo GetImageViewExtent(const ImageView *image_view)
447 % A description of each parameter follows:
449 % o image_view: the image view.
452 MagickExport RectangleInfo GetImageViewExtent(const ImageView *image_view)
454 assert(image_view != (ImageView *) NULL);
455 assert(image_view->signature == MagickSignature);
456 return(image_view->extent);
460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
464 % G e t I m a g e V i e w I m a g e %
468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470 % GetImageViewImage() returns the image associated with the image view.
472 % The format of the GetImageViewImage method is:
474 % MagickCore *GetImageViewImage(const ImageView *image_view)
476 % A description of each parameter follows:
478 % o image_view: the image view.
481 MagickExport Image *GetImageViewImage(const ImageView *image_view)
483 assert(image_view != (ImageView *) NULL);
484 assert(image_view->signature == MagickSignature);
485 return(image_view->image);
489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
493 % G e t I m a g e V i e w I t e r a t o r %
497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
499 % GetImageViewIterator() iterates over the image view in parallel and calls
500 % your get method for each scanline of the view. The pixel extent is
501 % not confined to the image canvas-- that is you can include negative offsets
502 % or widths or heights that exceed the image dimension. Any updates to
503 % the pixels in your callback are ignored.
505 % The callback signature is:
507 % MagickBooleanType GetImageViewMethod(const ImageView *source,
508 % const ssize_t y,const int thread_id,void *context)
510 % Use this pragma if the view is not single threaded:
512 % #pragma omp critical
514 % to define a section of code in your callback get method that must be
515 % executed by a single thread at a time.
517 % The format of the GetImageViewIterator method is:
519 % MagickBooleanType GetImageViewIterator(ImageView *source,
520 % GetImageViewMethod get,void *context)
522 % A description of each parameter follows:
524 % o source: the source image view.
526 % o get: the get callback method.
528 % o context: the user defined context.
531 MagickExport MagickBooleanType GetImageViewIterator(ImageView *source,
532 GetImageViewMethod get,void *context)
546 assert(source != (ImageView *) NULL);
547 assert(source->signature == MagickSignature);
548 if (get == (GetImageViewMethod) NULL)
550 source_image=source->image;
553 #if defined(MAGICKCORE_OPENMP_SUPPORT)
554 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(source->number_threads)
556 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
559 id = GetOpenMPThreadId();
561 register const Quantum
564 if (status == MagickFalse)
566 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
567 source->extent.width,1,source->exception);
568 if (pixels == (const Quantum *) NULL)
573 if (get(source,y,id,context) == MagickFalse)
575 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
580 #if defined(MAGICKCORE_OPENMP_SUPPORT)
581 #pragma omp critical (MagickCore_GetImageViewIterator)
583 proceed=SetImageProgress(source_image,source->description,progress++,
584 source->extent.height);
585 if (proceed == MagickFalse)
593 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
597 % 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 %
601 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
603 % GetImageViewVirtualMetacontent() returns the image view virtual
606 % The format of the GetImageViewVirtualMetacontent method is:
608 % const void *GetImageViewVirtualMetacontent(
609 % const ImageView *image_view)
611 % A description of each parameter follows:
613 % o image_view: the image view.
616 MagickExport const void *GetImageViewVirtualMetacontent(
617 const ImageView *image_view)
619 assert(image_view != (ImageView *) NULL);
620 assert(image_view->signature == MagickSignature);
621 return(GetCacheViewVirtualMetacontent(image_view->view));
625 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629 % 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 %
633 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
635 % GetImageViewVirtualPixels() returns the image view virtual pixels.
637 % The format of the GetImageViewVirtualPixels method is:
639 % const Quantum *GetImageViewVirtualPixels(const ImageView *image_view)
641 % A description of each parameter follows:
643 % o image_view: the image view.
646 MagickExport const Quantum *GetImageViewVirtualPixels(
647 const ImageView *image_view)
649 assert(image_view != (ImageView *) NULL);
650 assert(image_view->signature == MagickSignature);
651 return(GetCacheViewVirtualPixelQueue(image_view->view));
655 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
659 % I s I m a g e V i e w %
663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
665 % IsImageView() returns MagickTrue if the the parameter is verified as a image
668 % The format of the IsImageView method is:
670 % MagickBooleanType IsImageView(const ImageView *image_view)
672 % A description of each parameter follows:
674 % o image_view: the image view.
677 MagickExport MagickBooleanType IsImageView(const ImageView *image_view)
679 if (image_view == (const ImageView *) NULL)
681 if (image_view->signature != MagickSignature)
687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
691 % N e w I m a g e V i e w %
695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
697 % NewImageView() returns a image view required for all other methods in the
700 % The format of the NewImageView method is:
702 % ImageView *NewImageView(MagickCore *wand)
704 % A description of each parameter follows:
709 MagickExport ImageView *NewImageView(Image *image)
714 assert(image != (Image *) NULL);
715 assert(image->signature == MagickSignature);
716 image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
717 if (image_view == (ImageView *) NULL)
718 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
719 (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
720 image_view->description=ConstantString("ImageView");
721 image_view->image=image;
722 image_view->view=AcquireCacheView(image_view->image);
723 image_view->extent.width=image->columns;
724 image_view->extent.height=image->rows;
725 image_view->extent.x=0;
726 image_view->extent.y=0;
727 image_view->number_threads=GetOpenMPMaximumThreads();
728 image_view->exception=AcquireExceptionInfo();
729 image_view->debug=IsEventLogging();
730 image_view->signature=MagickSignature;
735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
739 % N e w I m a g e V i e w R e g i o n %
743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
745 % NewImageViewRegion() returns a image view required for all other methods
746 % in the Image View API.
748 % The format of the NewImageViewRegion method is:
750 % ImageView *NewImageViewRegion(MagickCore *wand,const ssize_t x,
751 % const ssize_t y,const size_t width,const size_t height)
753 % A description of each parameter follows:
755 % o wand: the magick wand.
757 % o x,y,columns,rows: These values define the perimeter of a extent of
761 MagickExport ImageView *NewImageViewRegion(Image *image,const ssize_t x,
762 const ssize_t y,const size_t width,const size_t height)
767 assert(image != (Image *) NULL);
768 assert(image->signature == MagickSignature);
769 image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
770 if (image_view == (ImageView *) NULL)
771 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
772 (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
773 image_view->description=ConstantString("ImageView");
774 image_view->view=AcquireCacheView(image_view->image);
775 image_view->image=image;
776 image_view->extent.width=width;
777 image_view->extent.height=height;
778 image_view->extent.x=x;
779 image_view->extent.y=y;
780 image_view->number_threads=GetOpenMPMaximumThreads();
781 image_view->exception=AcquireExceptionInfo();
782 image_view->debug=IsEventLogging();
783 image_view->signature=MagickSignature;
788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
792 % S e t I m a g e V i e w D e s c r i p t i o n %
796 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
798 % SetImageViewDescription() associates a description with an image view.
800 % The format of the SetImageViewDescription method is:
802 % void SetImageViewDescription(ImageView *image_view,
803 % const char *description)
805 % A description of each parameter follows:
807 % o image_view: the image view.
809 % o description: the image view description.
812 MagickExport void SetImageViewDescription(ImageView *image_view,
813 const char *description)
815 assert(image_view != (ImageView *) NULL);
816 assert(image_view->signature == MagickSignature);
817 image_view->description=ConstantString(description);
821 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
825 % S e t I m a g e V i e w I t e r a t o r %
829 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
831 % SetImageViewIterator() iterates over the image view in parallel and calls
832 % your set method for each scanline of the view. The pixel extent is
833 % confined to the image canvas-- that is no negative offsets or widths or
834 % heights that exceed the image dimension. The pixels are initiallly
835 % undefined and any settings you make in the callback method are automagically
836 % synced back to your image.
838 % The callback signature is:
840 % MagickBooleanType SetImageViewMethod(ImageView *destination,
841 % const ssize_t y,const int thread_id,void *context)
843 % Use this pragma if the view is not single threaded:
845 % #pragma omp critical
847 % to define a section of code in your callback set method that must be
848 % executed by a single thread at a time.
850 % The format of the SetImageViewIterator method is:
852 % MagickBooleanType SetImageViewIterator(ImageView *destination,
853 % SetImageViewMethod set,void *context)
855 % A description of each parameter follows:
857 % o destination: the image view.
859 % o set: the set callback method.
861 % o context: the user defined context.
864 MagickExport MagickBooleanType SetImageViewIterator(ImageView *destination,
865 SetImageViewMethod set,void *context)
882 assert(destination != (ImageView *) NULL);
883 assert(destination->signature == MagickSignature);
884 if (set == (SetImageViewMethod) NULL)
886 destination_image=destination->image;
887 exception=destination->exception;
888 if (SetImageStorageClass(destination_image,DirectClass,exception) == MagickFalse)
892 #if defined(MAGICKCORE_OPENMP_SUPPORT)
893 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(destination->number_threads)
895 for (y=destination->extent.y; y < (ssize_t) destination->extent.height; y++)
898 id = GetOpenMPThreadId();
906 if (status == MagickFalse)
908 pixels=GetCacheViewAuthenticPixels(destination->view,destination->extent.x,
909 y,destination->extent.width,1,exception);
910 if (pixels == (Quantum *) NULL)
912 InheritException(destination->exception,GetCacheViewException(
917 if (set(destination,y,id,context) == MagickFalse)
919 sync=SyncCacheViewAuthenticPixels(destination->view,exception);
920 if (sync == MagickFalse)
922 InheritException(destination->exception,GetCacheViewException(
926 if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
931 #if defined(MAGICKCORE_OPENMP_SUPPORT)
932 #pragma omp critical (MagickCore_SetImageViewIterator)
934 proceed=SetImageProgress(destination_image,destination->description,
935 progress++,destination->extent.height);
936 if (proceed == MagickFalse)
944 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
948 % S e t I m a g e V i e w T h r e a d s %
952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
954 % SetImageViewThreads() sets the number of threads in a thread team.
956 % The format of the SetImageViewDescription method is:
958 % void SetImageViewThreads(ImageView *image_view,
959 % const size_t number_threads)
961 % A description of each parameter follows:
963 % o image_view: the image view.
965 % o number_threads: the number of threads in a thread team.
968 MagickExport void SetImageViewThreads(ImageView *image_view,
969 const size_t number_threads)
971 assert(image_view != (ImageView *) NULL);
972 assert(image_view->signature == MagickSignature);
973 image_view->number_threads=number_threads;
974 if (number_threads > GetOpenMPMaximumThreads())
975 image_view->number_threads=GetOpenMPMaximumThreads();
979 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983 % 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 %
987 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
989 % TransferImageViewIterator() iterates over two image views in parallel and
990 % calls your transfer method for each scanline of the view. The source pixel
991 % extent is not confined to the image canvas-- that is you can include
992 % negative offsets or widths or heights that exceed the image dimension.
993 % However, the destination image view is confined to the image canvas-- that
994 % is no negative offsets or widths or heights that exceed the image dimension
997 % The callback signature is:
999 % MagickBooleanType TransferImageViewMethod(const ImageView *source,
1000 % ImageView *destination,const ssize_t y,const int thread_id,
1003 % Use this pragma if the view is not single threaded:
1005 % #pragma omp critical
1007 % to define a section of code in your callback transfer method that must be
1008 % executed by a single thread at a time.
1010 % The format of the TransferImageViewIterator method is:
1012 % MagickBooleanType TransferImageViewIterator(ImageView *source,
1013 % ImageView *destination,TransferImageViewMethod transfer,void *context)
1015 % A description of each parameter follows:
1017 % o source: the source image view.
1019 % o destination: the destination image view.
1021 % o transfer: the transfer callback method.
1023 % o context: the user defined context.
1026 MagickExport MagickBooleanType TransferImageViewIterator(ImageView *source,
1027 ImageView *destination,TransferImageViewMethod transfer,void *context)
1045 assert(source != (ImageView *) NULL);
1046 assert(source->signature == MagickSignature);
1047 if (transfer == (TransferImageViewMethod) NULL)
1048 return(MagickFalse);
1049 source_image=source->image;
1050 destination_image=destination->image;
1051 exception=destination->exception;
1052 if (SetImageStorageClass(destination_image,DirectClass,exception) == MagickFalse)
1053 return(MagickFalse);
1056 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1057 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(source->number_threads)
1059 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1062 id = GetOpenMPThreadId();
1067 register const Quantum
1071 *restrict destination_pixels;
1073 if (status == MagickFalse)
1075 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
1076 source->extent.width,1,source->exception);
1077 if (pixels == (const Quantum *) NULL)
1082 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
1083 destination->extent.x,y,destination->extent.width,1,exception);
1084 if (destination_pixels == (Quantum *) NULL)
1089 if (transfer(source,destination,y,id,context) == MagickFalse)
1091 sync=SyncCacheViewAuthenticPixels(destination->view,exception);
1092 if (sync == MagickFalse)
1094 InheritException(destination->exception,GetCacheViewException(
1098 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1103 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1104 #pragma omp critical (MagickCore_TransferImageViewIterator)
1106 proceed=SetImageProgress(source_image,source->description,progress++,
1107 source->extent.height);
1108 if (proceed == MagickFalse)
1116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1120 % U p d a t e I m a g e V i e w I t e r a t o r %
1124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1126 % UpdateImageViewIterator() iterates over the image view in parallel and calls
1127 % your update method for each scanline of the view. The pixel extent is
1128 % confined to the image canvas-- that is no negative offsets or widths or
1129 % heights that exceed the image dimension are permitted. Updates to pixels
1130 % in your callback are automagically synced back to the image.
1132 % The callback signature is:
1134 % MagickBooleanType UpdateImageViewMethod(ImageView *source,
1135 % const ssize_t y,const int thread_id,void *context)
1137 % Use this pragma if the view is not single threaded:
1139 % #pragma omp critical
1141 % to define a section of code in your callback update method that must be
1142 % executed by a single thread at a time.
1144 % The format of the UpdateImageViewIterator method is:
1146 % MagickBooleanType UpdateImageViewIterator(ImageView *source,
1147 % UpdateImageViewMethod update,void *context)
1149 % A description of each parameter follows:
1151 % o source: the source image view.
1153 % o update: the update callback method.
1155 % o context: the user defined context.
1158 MagickExport MagickBooleanType UpdateImageViewIterator(ImageView *source,
1159 UpdateImageViewMethod update,void *context)
1176 assert(source != (ImageView *) NULL);
1177 assert(source->signature == MagickSignature);
1178 if (update == (UpdateImageViewMethod) NULL)
1179 return(MagickFalse);
1180 source_image=source->image;
1181 exception=source->exception;
1182 if (SetImageStorageClass(source_image,DirectClass,exception) == MagickFalse)
1183 return(MagickFalse);
1186 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1187 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(source->number_threads)
1189 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1192 id = GetOpenMPThreadId();
1197 if (status == MagickFalse)
1199 pixels=GetCacheViewAuthenticPixels(source->view,source->extent.x,y,
1200 source->extent.width,1,exception);
1201 if (pixels == (Quantum *) NULL)
1203 InheritException(source->exception,GetCacheViewException(source->view));
1207 if (update(source,y,id,context) == MagickFalse)
1209 if (SyncCacheViewAuthenticPixels(source->view,exception) == MagickFalse)
1211 InheritException(source->exception,GetCacheViewException(source->view));
1214 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1219 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1220 #pragma omp critical (MagickCore_UpdateImageViewIterator)
1222 proceed=SetImageProgress(source_image,source->description,progress++,
1223 source->extent.height);
1224 if (proceed == MagickFalse)