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-2010 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 "magick/studio.h"
49 #include "magick/MagickCore.h"
50 #include "magick/exception-private.h"
51 #include "magick/monitor-private.h"
52 #include "magick/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)
235 assert(source != (ImageView *) NULL);
236 assert(source->signature == MagickSignature);
237 if (transfer == (DuplexTransferImageViewMethod) NULL)
239 source_image=source->image;
240 duplex_image=duplex->image;
241 destination_image=destination->image;
242 if (SetImageStorageClass(destination_image,DirectClass) == MagickFalse)
246 exception=destination->exception;
247 #if defined(MAGICKCORE_OPENMP_SUPPORT)
248 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(source->number_threads)
250 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
253 id = GetOpenMPThreadId();
258 register const IndexPacket
259 *restrict duplex_indexes,
262 register const PixelPacket
263 *restrict duplex_pixels,
267 *restrict destination_indexes;
270 *restrict destination_pixels;
272 if (status == MagickFalse)
274 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
275 source->extent.width,1,source->exception);
276 if (pixels == (const PixelPacket *) NULL)
281 indexes=GetCacheViewVirtualIndexQueue(source->view);
282 duplex_pixels=GetCacheViewVirtualPixels(duplex->view,duplex->extent.x,y,
283 duplex->extent.width,1,duplex->exception);
284 if (duplex_pixels == (const PixelPacket *) NULL)
289 duplex_indexes=GetCacheViewVirtualIndexQueue(duplex->view);
290 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
291 destination->extent.x,y,destination->extent.width,1,exception);
292 if (destination_pixels == (PixelPacket *) NULL)
297 destination_indexes=GetCacheViewAuthenticIndexQueue(destination->view);
298 if (transfer(source,duplex,destination,y,id,context) == MagickFalse)
300 sync=SyncCacheViewAuthenticPixels(destination->view,exception);
301 if (sync == MagickFalse)
303 InheritException(destination->exception,GetCacheViewException(
307 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
312 #if defined(MAGICKCORE_OPENMP_SUPPORT)
313 #pragma omp critical (MagickCore_DuplexTransferImageViewIterator)
315 proceed=SetImageProgress(source_image,source->description,progress++,
316 source->extent.height);
317 if (proceed == MagickFalse)
325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329 % G e t I m a g e V i e w A u t h e n t i c I n d e x e s %
333 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
335 % GetImageViewAuthenticIndexes() returns the image view authentic indexes.
337 % The format of the GetImageViewAuthenticPixels method is:
339 % IndexPacket *GetImageViewAuthenticIndexes(const ImageView *image_view)
341 % A description of each parameter follows:
343 % o image_view: the image view.
346 MagickExport IndexPacket *GetImageViewAuthenticIndexes(
347 const ImageView *image_view)
349 assert(image_view != (ImageView *) NULL);
350 assert(image_view->signature == MagickSignature);
351 return(GetCacheViewAuthenticIndexQueue(image_view->view));
355 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
359 % 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 %
363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
365 % GetImageViewAuthenticPixels() returns the image view authentic pixels.
367 % The format of the GetImageViewAuthenticPixels method is:
369 % PixelPacket *GetImageViewAuthenticPixels(const ImageView *image_view)
371 % A description of each parameter follows:
373 % o image_view: the image view.
376 MagickExport PixelPacket *GetImageViewAuthenticPixels(
377 const ImageView *image_view)
379 assert(image_view != (ImageView *) NULL);
380 assert(image_view->signature == MagickSignature);
381 return(GetCacheViewAuthenticPixelQueue(image_view->view));
385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
389 % G e t I m a g e V i e w E x c e p t i o n %
393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
395 % GetImageViewException() returns the severity, reason, and description of any
396 % error that occurs when utilizing a image view.
398 % The format of the GetImageViewException method is:
400 % char *GetImageViewException(const PixelImage *image_view,
401 % ExceptionType *severity)
403 % A description of each parameter follows:
405 % o image_view: the pixel image_view.
407 % o severity: the severity of the error is returned here.
410 MagickExport char *GetImageViewException(const ImageView *image_view,
411 ExceptionType *severity)
416 assert(image_view != (const ImageView *) NULL);
417 assert(image_view->signature == MagickSignature);
418 assert(severity != (ExceptionType *) NULL);
419 *severity=image_view->exception->severity;
420 description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
421 sizeof(*description));
422 if (description == (char *) NULL)
423 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
425 if (image_view->exception->reason != (char *) NULL)
426 (void) CopyMagickString(description,GetLocaleExceptionMessage(
427 image_view->exception->severity,image_view->exception->reason),
429 if (image_view->exception->description != (char *) NULL)
431 (void) ConcatenateMagickString(description," (",MaxTextExtent);
432 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
433 image_view->exception->severity,image_view->exception->description),
435 (void) ConcatenateMagickString(description,")",MaxTextExtent);
441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
445 % G e t I m a g e V i e w E x t e n t %
449 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
451 % GetImageViewExtent() returns the image view extent.
453 % The format of the GetImageViewExtent method is:
455 % RectangleInfo GetImageViewExtent(const ImageView *image_view)
457 % A description of each parameter follows:
459 % o image_view: the image view.
462 MagickExport RectangleInfo GetImageViewExtent(const ImageView *image_view)
464 assert(image_view != (ImageView *) NULL);
465 assert(image_view->signature == MagickSignature);
466 return(image_view->extent);
470 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
474 % G e t I m a g e V i e w I m a g e %
478 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
480 % GetImageViewImage() returns the image associated with the image view.
482 % The format of the GetImageViewImage method is:
484 % MagickCore *GetImageViewImage(const ImageView *image_view)
486 % A description of each parameter follows:
488 % o image_view: the image view.
491 MagickExport Image *GetImageViewImage(const ImageView *image_view)
493 assert(image_view != (ImageView *) NULL);
494 assert(image_view->signature == MagickSignature);
495 return(image_view->image);
499 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
503 % G e t I m a g e V i e w I t e r a t o r %
507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
509 % GetImageViewIterator() iterates over the image view in parallel and calls
510 % your get method for each scanline of the view. The pixel extent is
511 % not confined to the image canvas-- that is you can include negative offsets
512 % or widths or heights that exceed the image dimension. Any updates to
513 % the pixels in your callback are ignored.
515 % The callback signature is:
517 % MagickBooleanType GetImageViewMethod(const ImageView *source,
518 % const ssize_t y,const int thread_id,void *context)
520 % Use this pragma if the view is not single threaded:
522 % #pragma omp critical
524 % to define a section of code in your callback get method that must be
525 % executed by a single thread at a time.
527 % The format of the GetImageViewIterator method is:
529 % MagickBooleanType GetImageViewIterator(ImageView *source,
530 % GetImageViewMethod get,void *context)
532 % A description of each parameter follows:
534 % o source: the source image view.
536 % o get: the get callback method.
538 % o context: the user defined context.
541 MagickExport MagickBooleanType GetImageViewIterator(ImageView *source,
542 GetImageViewMethod get,void *context)
556 assert(source != (ImageView *) NULL);
557 assert(source->signature == MagickSignature);
558 if (get == (GetImageViewMethod) NULL)
560 source_image=source->image;
563 #if defined(MAGICKCORE_OPENMP_SUPPORT)
564 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(source->number_threads)
566 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
569 id = GetOpenMPThreadId();
571 register const IndexPacket
574 register const PixelPacket
577 if (status == MagickFalse)
579 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
580 source->extent.width,1,source->exception);
581 if (pixels == (const PixelPacket *) NULL)
586 indexes=GetCacheViewVirtualIndexQueue(source->view);
587 if (get(source,y,id,context) == MagickFalse)
589 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
594 #if defined(MAGICKCORE_OPENMP_SUPPORT)
595 #pragma omp critical (MagickCore_GetImageViewIterator)
597 proceed=SetImageProgress(source_image,source->description,progress++,
598 source->extent.height);
599 if (proceed == MagickFalse)
607 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611 % G e t I m a g e V i e w V i r t u a l I n d e x e s %
615 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
617 % GetImageViewVirtualIndexes() returns the image view virtual indexes.
619 % The format of the GetImageViewVirtualIndexes method is:
621 % const IndexPacket *GetImageViewVirtualIndexes(
622 % const ImageView *image_view)
624 % A description of each parameter follows:
626 % o image_view: the image view.
629 MagickExport const IndexPacket *GetImageViewVirtualIndexes(
630 const ImageView *image_view)
632 assert(image_view != (ImageView *) NULL);
633 assert(image_view->signature == MagickSignature);
634 return(GetCacheViewVirtualIndexQueue(image_view->view));
638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
642 % 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 %
646 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
648 % GetImageViewVirtualPixels() returns the image view virtual pixels.
650 % The format of the GetImageViewVirtualPixels method is:
652 % const PixelPacket *GetImageViewVirtualPixels(const ImageView *image_view)
654 % A description of each parameter follows:
656 % o image_view: the image view.
659 MagickExport const PixelPacket *GetImageViewVirtualPixels(
660 const ImageView *image_view)
662 assert(image_view != (ImageView *) NULL);
663 assert(image_view->signature == MagickSignature);
664 return(GetCacheViewVirtualPixelQueue(image_view->view));
668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
672 % I s I m a g e V i e w %
676 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
678 % IsImageView() returns MagickTrue if the the parameter is verified as a image
681 % The format of the IsImageView method is:
683 % MagickBooleanType IsImageView(const ImageView *image_view)
685 % A description of each parameter follows:
687 % o image_view: the image view.
690 MagickExport MagickBooleanType IsImageView(const ImageView *image_view)
692 if (image_view == (const ImageView *) NULL)
694 if (image_view->signature != MagickSignature)
700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
704 % N e w I m a g e V i e w %
708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
710 % NewImageView() returns a image view required for all other methods in the
713 % The format of the NewImageView method is:
715 % ImageView *NewImageView(MagickCore *wand)
717 % A description of each parameter follows:
722 MagickExport ImageView *NewImageView(Image *image)
727 assert(image != (Image *) NULL);
728 assert(image->signature == MagickSignature);
729 image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
730 if (image_view == (ImageView *) NULL)
731 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
732 (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
733 image_view->description=ConstantString("ImageView");
734 image_view->image=image;
735 image_view->view=AcquireCacheView(image_view->image);
736 image_view->extent.width=image->columns;
737 image_view->extent.height=image->rows;
738 image_view->extent.x=0;
739 image_view->extent.y=0;
740 image_view->number_threads=GetOpenMPMaximumThreads();
741 image_view->exception=AcquireExceptionInfo();
742 image_view->debug=IsEventLogging();
743 image_view->signature=MagickSignature;
748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
752 % N e w I m a g e V i e w R e g i o n %
756 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
758 % NewImageViewRegion() returns a image view required for all other methods
759 % in the Image View API.
761 % The format of the NewImageViewRegion method is:
763 % ImageView *NewImageViewRegion(MagickCore *wand,const ssize_t x,
764 % const ssize_t y,const size_t width,const size_t height)
766 % A description of each parameter follows:
768 % o wand: the magick wand.
770 % o x,y,columns,rows: These values define the perimeter of a extent of
774 MagickExport ImageView *NewImageViewRegion(Image *image,const ssize_t x,
775 const ssize_t y,const size_t width,const size_t height)
780 assert(image != (Image *) NULL);
781 assert(image->signature == MagickSignature);
782 image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
783 if (image_view == (ImageView *) NULL)
784 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
785 (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
786 image_view->description=ConstantString("ImageView");
787 image_view->view=AcquireCacheView(image_view->image);
788 image_view->image=image;
789 image_view->extent.width=width;
790 image_view->extent.height=height;
791 image_view->extent.x=x;
792 image_view->extent.y=y;
793 image_view->number_threads=GetOpenMPMaximumThreads();
794 image_view->exception=AcquireExceptionInfo();
795 image_view->debug=IsEventLogging();
796 image_view->signature=MagickSignature;
801 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
805 % S e t I m a g e V i e w D e s c r i p t i o n %
809 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
811 % SetImageViewDescription() associates a description with an image view.
813 % The format of the SetImageViewDescription method is:
815 % void SetImageViewDescription(ImageView *image_view,
816 % const char *description)
818 % A description of each parameter follows:
820 % o image_view: the image view.
822 % o description: the image view description.
825 MagickExport void SetImageViewDescription(ImageView *image_view,
826 const char *description)
828 assert(image_view != (ImageView *) NULL);
829 assert(image_view->signature == MagickSignature);
830 image_view->description=ConstantString(description);
834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
838 % S e t I m a g e V i e w I t e r a t o r %
842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
844 % SetImageViewIterator() iterates over the image view in parallel and calls
845 % your set method for each scanline of the view. The pixel extent is
846 % confined to the image canvas-- that is no negative offsets or widths or
847 % heights that exceed the image dimension. The pixels are initiallly
848 % undefined and any settings you make in the callback method are automagically
849 % synced back to your image.
851 % The callback signature is:
853 % MagickBooleanType SetImageViewMethod(ImageView *destination,
854 % const ssize_t y,const int thread_id,void *context)
856 % Use this pragma if the view is not single threaded:
858 % #pragma omp critical
860 % to define a section of code in your callback set method that must be
861 % executed by a single thread at a time.
863 % The format of the SetImageViewIterator method is:
865 % MagickBooleanType SetImageViewIterator(ImageView *destination,
866 % SetImageViewMethod set,void *context)
868 % A description of each parameter follows:
870 % o destination: the image view.
872 % o set: the set callback method.
874 % o context: the user defined context.
877 MagickExport MagickBooleanType SetImageViewIterator(ImageView *destination,
878 SetImageViewMethod set,void *context)
895 assert(destination != (ImageView *) NULL);
896 assert(destination->signature == MagickSignature);
897 if (set == (SetImageViewMethod) NULL)
899 destination_image=destination->image;
900 if (SetImageStorageClass(destination_image,DirectClass) == MagickFalse)
904 exception=destination->exception;
905 #if defined(MAGICKCORE_OPENMP_SUPPORT)
906 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(destination->number_threads)
908 for (y=destination->extent.y; y < (ssize_t) destination->extent.height; y++)
911 id = GetOpenMPThreadId();
922 if (status == MagickFalse)
924 pixels=GetCacheViewAuthenticPixels(destination->view,destination->extent.x,
925 y,destination->extent.width,1,exception);
926 if (pixels == (PixelPacket *) NULL)
928 InheritException(destination->exception,GetCacheViewException(
933 indexes=GetCacheViewAuthenticIndexQueue(destination->view);
934 if (set(destination,y,id,context) == MagickFalse)
936 sync=SyncCacheViewAuthenticPixels(destination->view,exception);
937 if (sync == MagickFalse)
939 InheritException(destination->exception,GetCacheViewException(
943 if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
948 #if defined(MAGICKCORE_OPENMP_SUPPORT)
949 #pragma omp critical (MagickCore_SetImageViewIterator)
951 proceed=SetImageProgress(destination_image,destination->description,
952 progress++,destination->extent.height);
953 if (proceed == MagickFalse)
961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
965 % S e t I m a g e V i e w T h r e a d s %
969 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
971 % SetImageViewThreads() sets the number of threads in a thread team.
973 % The format of the SetImageViewDescription method is:
975 % void SetImageViewThreads(ImageView *image_view,
976 % const size_t number_threads)
978 % A description of each parameter follows:
980 % o image_view: the image view.
982 % o number_threads: the number of threads in a thread team.
985 MagickExport void SetImageViewThreads(ImageView *image_view,
986 const size_t number_threads)
988 assert(image_view != (ImageView *) NULL);
989 assert(image_view->signature == MagickSignature);
990 image_view->number_threads=number_threads;
991 if (number_threads > GetOpenMPMaximumThreads())
992 image_view->number_threads=GetOpenMPMaximumThreads();
996 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1000 % 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 %
1004 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1006 % TransferImageViewIterator() iterates over two image views in parallel and
1007 % calls your transfer method for each scanline of the view. The source pixel
1008 % extent is not confined to the image canvas-- that is you can include
1009 % negative offsets or widths or heights that exceed the image dimension.
1010 % However, the destination image view is confined to the image canvas-- that
1011 % is no negative offsets or widths or heights that exceed the image dimension
1014 % The callback signature is:
1016 % MagickBooleanType TransferImageViewMethod(const ImageView *source,
1017 % ImageView *destination,const ssize_t y,const int thread_id,
1020 % Use this pragma if the view is not single threaded:
1022 % #pragma omp critical
1024 % to define a section of code in your callback transfer method that must be
1025 % executed by a single thread at a time.
1027 % The format of the TransferImageViewIterator method is:
1029 % MagickBooleanType TransferImageViewIterator(ImageView *source,
1030 % ImageView *destination,TransferImageViewMethod transfer,void *context)
1032 % A description of each parameter follows:
1034 % o source: the source image view.
1036 % o destination: the destination image view.
1038 % o transfer: the transfer callback method.
1040 % o context: the user defined context.
1043 MagickExport MagickBooleanType TransferImageViewIterator(ImageView *source,
1044 ImageView *destination,TransferImageViewMethod transfer,void *context)
1062 assert(source != (ImageView *) NULL);
1063 assert(source->signature == MagickSignature);
1064 if (transfer == (TransferImageViewMethod) NULL)
1065 return(MagickFalse);
1066 source_image=source->image;
1067 destination_image=destination->image;
1068 if (SetImageStorageClass(destination_image,DirectClass) == MagickFalse)
1069 return(MagickFalse);
1072 exception=destination->exception;
1073 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1074 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(source->number_threads)
1076 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1079 id = GetOpenMPThreadId();
1084 register const IndexPacket
1087 register const PixelPacket
1090 register IndexPacket
1091 *restrict destination_indexes;
1093 register PixelPacket
1094 *restrict destination_pixels;
1096 if (status == MagickFalse)
1098 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
1099 source->extent.width,1,source->exception);
1100 if (pixels == (const PixelPacket *) NULL)
1105 indexes=GetCacheViewVirtualIndexQueue(source->view);
1106 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
1107 destination->extent.x,y,destination->extent.width,1,exception);
1108 if (destination_pixels == (PixelPacket *) NULL)
1113 destination_indexes=GetCacheViewAuthenticIndexQueue(destination->view);
1114 if (transfer(source,destination,y,id,context) == MagickFalse)
1116 sync=SyncCacheViewAuthenticPixels(destination->view,exception);
1117 if (sync == MagickFalse)
1119 InheritException(destination->exception,GetCacheViewException(
1123 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1128 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1129 #pragma omp critical (MagickCore_TransferImageViewIterator)
1131 proceed=SetImageProgress(source_image,source->description,progress++,
1132 source->extent.height);
1133 if (proceed == MagickFalse)
1141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1145 % U p d a t e I m a g e V i e w I t e r a t o r %
1149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1151 % UpdateImageViewIterator() iterates over the image view in parallel and calls
1152 % your update method for each scanline of the view. The pixel extent is
1153 % confined to the image canvas-- that is no negative offsets or widths or
1154 % heights that exceed the image dimension are permitted. Updates to pixels
1155 % in your callback are automagically synced back to the image.
1157 % The callback signature is:
1159 % MagickBooleanType UpdateImageViewMethod(ImageView *source,
1160 % const ssize_t y,const int thread_id,void *context)
1162 % Use this pragma if the view is not single threaded:
1164 % #pragma omp critical
1166 % to define a section of code in your callback update method that must be
1167 % executed by a single thread at a time.
1169 % The format of the UpdateImageViewIterator method is:
1171 % MagickBooleanType UpdateImageViewIterator(ImageView *source,
1172 % UpdateImageViewMethod update,void *context)
1174 % A description of each parameter follows:
1176 % o source: the source image view.
1178 % o update: the update callback method.
1180 % o context: the user defined context.
1183 MagickExport MagickBooleanType UpdateImageViewIterator(ImageView *source,
1184 UpdateImageViewMethod update,void *context)
1201 assert(source != (ImageView *) NULL);
1202 assert(source->signature == MagickSignature);
1203 if (update == (UpdateImageViewMethod) NULL)
1204 return(MagickFalse);
1205 source_image=source->image;
1206 if (SetImageStorageClass(source_image,DirectClass) == MagickFalse)
1207 return(MagickFalse);
1210 exception=source->exception;
1211 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1212 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(source->number_threads)
1214 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1217 id = GetOpenMPThreadId();
1219 register IndexPacket
1222 register PixelPacket
1225 if (status == MagickFalse)
1227 pixels=GetCacheViewAuthenticPixels(source->view,source->extent.x,y,
1228 source->extent.width,1,exception);
1229 if (pixels == (PixelPacket *) NULL)
1231 InheritException(source->exception,GetCacheViewException(source->view));
1235 indexes=GetCacheViewAuthenticIndexQueue(source->view);
1236 if (update(source,y,id,context) == MagickFalse)
1238 if (SyncCacheViewAuthenticPixels(source->view,exception) == MagickFalse)
1240 InheritException(source->exception,GetCacheViewException(source->view));
1243 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1248 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1249 #pragma omp critical (MagickCore_UpdateImageViewIterator)
1251 proceed=SetImageProgress(source_image,source->description,progress++,
1252 source->extent.height);
1253 if (proceed == MagickFalse)