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-2012 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)
231 assert(source != (ImageView *) NULL);
232 assert(source->signature == MagickSignature);
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 #pragma omp parallel for schedule(static) shared(progress,status) num_threads(source->number_threads)
246 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
249 id = GetOpenMPThreadId();
254 register const Quantum
255 *restrict duplex_pixels,
259 *restrict destination_pixels;
261 if (status == MagickFalse)
263 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
264 source->extent.width,1,source->exception);
265 if (pixels == (const Quantum *) NULL)
270 duplex_pixels=GetCacheViewVirtualPixels(duplex->view,duplex->extent.x,y,
271 duplex->extent.width,1,duplex->exception);
272 if (duplex_pixels == (const Quantum *) NULL)
277 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
278 destination->extent.x,y,destination->extent.width,1,
279 destination->exception);
280 if (destination_pixels == (Quantum *) NULL)
285 if (transfer(source,duplex,destination,y,id,context) == MagickFalse)
287 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
288 if (sync == MagickFalse)
290 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
295 #if defined(MAGICKCORE_OPENMP_SUPPORT)
296 #pragma omp critical (MagickCore_DuplexTransferImageViewIterator)
298 proceed=SetImageProgress(source_image,source->description,progress++,
299 source->extent.height);
300 if (proceed == MagickFalse)
308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
312 % 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 %
316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
318 % GetImageViewAuthenticMetacontent() returns the image view authentic
321 % The format of the GetImageViewAuthenticPixels method is:
323 % void *GetImageViewAuthenticMetacontent(
324 % const ImageView *image_view)
326 % A description of each parameter follows:
328 % o image_view: the image view.
331 MagickExport void *GetImageViewAuthenticMetacontent(
332 const ImageView *image_view)
334 assert(image_view != (ImageView *) NULL);
335 assert(image_view->signature == MagickSignature);
336 return(GetCacheViewAuthenticMetacontent(image_view->view));
340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
344 % 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 %
348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350 % GetImageViewAuthenticPixels() returns the image view authentic pixels.
352 % The format of the GetImageViewAuthenticPixels method is:
354 % Quantum *GetImageViewAuthenticPixels(const ImageView *image_view)
356 % A description of each parameter follows:
358 % o image_view: the image view.
361 MagickExport Quantum *GetImageViewAuthenticPixels(
362 const ImageView *image_view)
364 assert(image_view != (ImageView *) NULL);
365 assert(image_view->signature == MagickSignature);
366 return(GetCacheViewAuthenticPixelQueue(image_view->view));
370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374 % G e t I m a g e V i e w E x c e p t i o n %
378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
380 % GetImageViewException() returns the severity, reason, and description of any
381 % error that occurs when utilizing a image view.
383 % The format of the GetImageViewException method is:
385 % char *GetImageViewException(const PixelImage *image_view,
386 % ExceptionType *severity)
388 % A description of each parameter follows:
390 % o image_view: the pixel image_view.
392 % o severity: the severity of the error is returned here.
395 MagickExport char *GetImageViewException(const ImageView *image_view,
396 ExceptionType *severity)
401 assert(image_view != (const ImageView *) NULL);
402 assert(image_view->signature == MagickSignature);
403 assert(severity != (ExceptionType *) NULL);
404 *severity=image_view->exception->severity;
405 description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
406 sizeof(*description));
407 if (description == (char *) NULL)
408 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
410 if (image_view->exception->reason != (char *) NULL)
411 (void) CopyMagickString(description,GetLocaleExceptionMessage(
412 image_view->exception->severity,image_view->exception->reason),
414 if (image_view->exception->description != (char *) NULL)
416 (void) ConcatenateMagickString(description," (",MaxTextExtent);
417 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
418 image_view->exception->severity,image_view->exception->description),
420 (void) ConcatenateMagickString(description,")",MaxTextExtent);
426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
430 % G e t I m a g e V i e w E x t e n t %
434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
436 % GetImageViewExtent() returns the image view extent.
438 % The format of the GetImageViewExtent method is:
440 % RectangleInfo GetImageViewExtent(const ImageView *image_view)
442 % A description of each parameter follows:
444 % o image_view: the image view.
447 MagickExport RectangleInfo GetImageViewExtent(const ImageView *image_view)
449 assert(image_view != (ImageView *) NULL);
450 assert(image_view->signature == MagickSignature);
451 return(image_view->extent);
455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
459 % G e t I m a g e V i e w I m a g e %
463 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465 % GetImageViewImage() returns the image associated with the image view.
467 % The format of the GetImageViewImage method is:
469 % MagickCore *GetImageViewImage(const ImageView *image_view)
471 % A description of each parameter follows:
473 % o image_view: the image view.
476 MagickExport Image *GetImageViewImage(const ImageView *image_view)
478 assert(image_view != (ImageView *) NULL);
479 assert(image_view->signature == MagickSignature);
480 return(image_view->image);
484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
488 % G e t I m a g e V i e w I t e r a t o r %
492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
494 % GetImageViewIterator() iterates over the image view in parallel and calls
495 % your get method for each scanline of the view. The pixel extent is
496 % not confined to the image canvas-- that is you can include negative offsets
497 % or widths or heights that exceed the image dimension. Any updates to
498 % the pixels in your callback are ignored.
500 % The callback signature is:
502 % MagickBooleanType GetImageViewMethod(const ImageView *source,
503 % const ssize_t y,const int thread_id,void *context)
505 % Use this pragma if the view is not single threaded:
507 % #pragma omp critical
509 % to define a section of code in your callback get method that must be
510 % executed by a single thread at a time.
512 % The format of the GetImageViewIterator method is:
514 % MagickBooleanType GetImageViewIterator(ImageView *source,
515 % GetImageViewMethod get,void *context)
517 % A description of each parameter follows:
519 % o source: the source image view.
521 % o get: the get callback method.
523 % o context: the user defined context.
526 MagickExport MagickBooleanType GetImageViewIterator(ImageView *source,
527 GetImageViewMethod get,void *context)
541 assert(source != (ImageView *) NULL);
542 assert(source->signature == MagickSignature);
543 if (get == (GetImageViewMethod) NULL)
545 source_image=source->image;
548 #if defined(MAGICKCORE_OPENMP_SUPPORT)
549 #pragma omp parallel for schedule(static) shared(progress,status) num_threads(source->number_threads)
551 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
554 id = GetOpenMPThreadId();
556 register const Quantum
559 if (status == MagickFalse)
561 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
562 source->extent.width,1,source->exception);
563 if (pixels == (const Quantum *) NULL)
568 if (get(source,y,id,context) == MagickFalse)
570 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
575 #if defined(MAGICKCORE_OPENMP_SUPPORT)
576 #pragma omp critical (MagickCore_GetImageViewIterator)
578 proceed=SetImageProgress(source_image,source->description,progress++,
579 source->extent.height);
580 if (proceed == MagickFalse)
588 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
592 % 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 %
596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
598 % GetImageViewVirtualMetacontent() returns the image view virtual
601 % The format of the GetImageViewVirtualMetacontent method is:
603 % const void *GetImageViewVirtualMetacontent(
604 % const ImageView *image_view)
606 % A description of each parameter follows:
608 % o image_view: the image view.
611 MagickExport const void *GetImageViewVirtualMetacontent(
612 const ImageView *image_view)
614 assert(image_view != (ImageView *) NULL);
615 assert(image_view->signature == MagickSignature);
616 return(GetCacheViewVirtualMetacontent(image_view->view));
620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
624 % 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 %
628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
630 % GetImageViewVirtualPixels() returns the image view virtual pixels.
632 % The format of the GetImageViewVirtualPixels method is:
634 % const Quantum *GetImageViewVirtualPixels(const ImageView *image_view)
636 % A description of each parameter follows:
638 % o image_view: the image view.
641 MagickExport const Quantum *GetImageViewVirtualPixels(
642 const ImageView *image_view)
644 assert(image_view != (ImageView *) NULL);
645 assert(image_view->signature == MagickSignature);
646 return(GetCacheViewVirtualPixelQueue(image_view->view));
650 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
654 % I s I m a g e V i e w %
658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
660 % IsImageView() returns MagickTrue if the the parameter is verified as a image
663 % The format of the IsImageView method is:
665 % MagickBooleanType IsImageView(const ImageView *image_view)
667 % A description of each parameter follows:
669 % o image_view: the image view.
672 MagickExport MagickBooleanType IsImageView(const ImageView *image_view)
674 if (image_view == (const ImageView *) NULL)
676 if (image_view->signature != MagickSignature)
682 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
686 % N e w I m a g e V i e w %
690 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
692 % NewImageView() returns a image view required for all other methods in the
695 % The format of the NewImageView method is:
697 % ImageView *NewImageView(MagickCore *wand,ExceptionInfo *exception)
699 % A description of each parameter follows:
701 % o image: the image.
703 % o exception: return any errors or warnings in this structure.
706 MagickExport ImageView *NewImageView(Image *image,ExceptionInfo *exception)
711 assert(image != (Image *) NULL);
712 assert(image->signature == MagickSignature);
713 image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
714 if (image_view == (ImageView *) NULL)
715 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
716 (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
717 image_view->description=ConstantString("ImageView");
718 image_view->image=image;
719 image_view->view=AcquireVirtualCacheView(image_view->image,exception);
720 image_view->extent.width=image->columns;
721 image_view->extent.height=image->rows;
722 image_view->extent.x=0;
723 image_view->extent.y=0;
724 image_view->number_threads=GetOpenMPMaximumThreads();
725 image_view->exception=AcquireExceptionInfo();
726 image_view->debug=IsEventLogging();
727 image_view->signature=MagickSignature;
732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
736 % N e w I m a g e V i e w R e g i o n %
740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
742 % NewImageViewRegion() returns a image view required for all other methods
743 % in the Image View API.
745 % The format of the NewImageViewRegion method is:
747 % ImageView *NewImageViewRegion(MagickCore *wand,const ssize_t x,
748 % const ssize_t y,const size_t width,const size_t height,
749 % ExceptionInfo *exception)
751 % A description of each parameter follows:
753 % o wand: the magick wand.
755 % o x,y,columns,rows: These values define the perimeter of a extent of
758 % o exception: return any errors or warnings in this structure.
761 MagickExport ImageView *NewImageViewRegion(Image *image,const ssize_t x,
762 const ssize_t y,const size_t width,const size_t height,
763 ExceptionInfo *exception)
768 assert(image != (Image *) NULL);
769 assert(image->signature == MagickSignature);
770 image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
771 if (image_view == (ImageView *) NULL)
772 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
773 (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
774 image_view->description=ConstantString("ImageView");
775 image_view->view=AcquireVirtualCacheView(image_view->image,exception);
776 image_view->image=image;
777 image_view->extent.width=width;
778 image_view->extent.height=height;
779 image_view->extent.x=x;
780 image_view->extent.y=y;
781 image_view->number_threads=GetOpenMPMaximumThreads();
782 image_view->exception=AcquireExceptionInfo();
783 image_view->debug=IsEventLogging();
784 image_view->signature=MagickSignature;
789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
793 % S e t I m a g e V i e w D e s c r i p t i o n %
797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
799 % SetImageViewDescription() associates a description with an image view.
801 % The format of the SetImageViewDescription method is:
803 % void SetImageViewDescription(ImageView *image_view,
804 % const char *description)
806 % A description of each parameter follows:
808 % o image_view: the image view.
810 % o description: the image view description.
813 MagickExport void SetImageViewDescription(ImageView *image_view,
814 const char *description)
816 assert(image_view != (ImageView *) NULL);
817 assert(image_view->signature == MagickSignature);
818 image_view->description=ConstantString(description);
822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
826 % S e t I m a g e V i e w I t e r a t o r %
830 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
832 % SetImageViewIterator() iterates over the image view in parallel and calls
833 % your set method for each scanline of the view. The pixel extent is
834 % confined to the image canvas-- that is no negative offsets or widths or
835 % heights that exceed the image dimension. The pixels are initiallly
836 % undefined and any settings you make in the callback method are automagically
837 % synced back to your image.
839 % The callback signature is:
841 % MagickBooleanType SetImageViewMethod(ImageView *destination,
842 % const ssize_t y,const int thread_id,void *context)
844 % Use this pragma if the view is not single threaded:
846 % #pragma omp critical
848 % to define a section of code in your callback set method that must be
849 % executed by a single thread at a time.
851 % The format of the SetImageViewIterator method is:
853 % MagickBooleanType SetImageViewIterator(ImageView *destination,
854 % SetImageViewMethod set,void *context)
856 % A description of each parameter follows:
858 % o destination: the image view.
860 % o set: the set callback method.
862 % o context: the user defined context.
865 MagickExport MagickBooleanType SetImageViewIterator(ImageView *destination,
866 SetImageViewMethod set,void *context)
880 assert(destination != (ImageView *) NULL);
881 assert(destination->signature == MagickSignature);
882 if (set == (SetImageViewMethod) NULL)
884 destination_image=destination->image;
885 status=SetImageStorageClass(destination_image,DirectClass,
886 destination->exception);
887 if (status == MagickFalse)
891 #if defined(MAGICKCORE_OPENMP_SUPPORT)
892 #pragma omp parallel for schedule(static) shared(progress,status) num_threads(destination->number_threads)
894 for (y=destination->extent.y; y < (ssize_t) destination->extent.height; y++)
897 id = GetOpenMPThreadId();
905 if (status == MagickFalse)
907 pixels=GetCacheViewAuthenticPixels(destination->view,destination->extent.x,
908 y,destination->extent.width,1,destination->exception);
909 if (pixels == (Quantum *) NULL)
914 if (set(destination,y,id,context) == MagickFalse)
916 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
917 if (sync == MagickFalse)
919 if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
924 #if defined(MAGICKCORE_OPENMP_SUPPORT)
925 #pragma omp critical (MagickCore_SetImageViewIterator)
927 proceed=SetImageProgress(destination_image,destination->description,
928 progress++,destination->extent.height);
929 if (proceed == MagickFalse)
937 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
941 % S e t I m a g e V i e w T h r e a d s %
945 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
947 % SetImageViewThreads() sets the number of threads in a thread team.
949 % The format of the SetImageViewDescription method is:
951 % void SetImageViewThreads(ImageView *image_view,
952 % const size_t number_threads)
954 % A description of each parameter follows:
956 % o image_view: the image view.
958 % o number_threads: the number of threads in a thread team.
961 MagickExport void SetImageViewThreads(ImageView *image_view,
962 const size_t number_threads)
964 assert(image_view != (ImageView *) NULL);
965 assert(image_view->signature == MagickSignature);
966 image_view->number_threads=number_threads;
967 if (number_threads > GetOpenMPMaximumThreads())
968 image_view->number_threads=GetOpenMPMaximumThreads();
972 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
976 % 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 %
980 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
982 % TransferImageViewIterator() iterates over two image views in parallel and
983 % calls your transfer method for each scanline of the view. The source pixel
984 % extent is not confined to the image canvas-- that is you can include
985 % negative offsets or widths or heights that exceed the image dimension.
986 % However, the destination image view is confined to the image canvas-- that
987 % is no negative offsets or widths or heights that exceed the image dimension
990 % The callback signature is:
992 % MagickBooleanType TransferImageViewMethod(const ImageView *source,
993 % ImageView *destination,const ssize_t y,const int thread_id,
996 % Use this pragma if the view is not single threaded:
998 % #pragma omp critical
1000 % to define a section of code in your callback transfer method that must be
1001 % executed by a single thread at a time.
1003 % The format of the TransferImageViewIterator method is:
1005 % MagickBooleanType TransferImageViewIterator(ImageView *source,
1006 % ImageView *destination,TransferImageViewMethod transfer,void *context)
1008 % A description of each parameter follows:
1010 % o source: the source image view.
1012 % o destination: the destination image view.
1014 % o transfer: the transfer callback method.
1016 % o context: the user defined context.
1019 MagickExport MagickBooleanType TransferImageViewIterator(ImageView *source,
1020 ImageView *destination,TransferImageViewMethod transfer,void *context)
1035 assert(source != (ImageView *) NULL);
1036 assert(source->signature == MagickSignature);
1037 if (transfer == (TransferImageViewMethod) NULL)
1038 return(MagickFalse);
1039 source_image=source->image;
1040 destination_image=destination->image;
1041 status=SetImageStorageClass(destination_image,DirectClass,
1042 destination->exception);
1043 if (status == MagickFalse)
1044 return(MagickFalse);
1047 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1048 #pragma omp parallel for schedule(static) shared(progress,status) num_threads(source->number_threads)
1050 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1053 id = GetOpenMPThreadId();
1058 register const Quantum
1062 *restrict destination_pixels;
1064 if (status == MagickFalse)
1066 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
1067 source->extent.width,1,source->exception);
1068 if (pixels == (const Quantum *) NULL)
1073 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
1074 destination->extent.x,y,destination->extent.width,1,
1075 destination->exception);
1076 if (destination_pixels == (Quantum *) NULL)
1081 if (transfer(source,destination,y,id,context) == MagickFalse)
1083 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
1084 if (sync == MagickFalse)
1086 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1091 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1092 #pragma omp critical (MagickCore_TransferImageViewIterator)
1094 proceed=SetImageProgress(source_image,source->description,progress++,
1095 source->extent.height);
1096 if (proceed == MagickFalse)
1104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1108 % U p d a t e I m a g e V i e w I t e r a t o r %
1112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1114 % UpdateImageViewIterator() iterates over the image view in parallel and calls
1115 % your update method for each scanline of the view. The pixel extent is
1116 % confined to the image canvas-- that is no negative offsets or widths or
1117 % heights that exceed the image dimension are permitted. Updates to pixels
1118 % in your callback are automagically synced back to the image.
1120 % The callback signature is:
1122 % MagickBooleanType UpdateImageViewMethod(ImageView *source,
1123 % const ssize_t y,const int thread_id,void *context)
1125 % Use this pragma if the view is not single threaded:
1127 % #pragma omp critical
1129 % to define a section of code in your callback update method that must be
1130 % executed by a single thread at a time.
1132 % The format of the UpdateImageViewIterator method is:
1134 % MagickBooleanType UpdateImageViewIterator(ImageView *source,
1135 % UpdateImageViewMethod update,void *context)
1137 % A description of each parameter follows:
1139 % o source: the source image view.
1141 % o update: the update callback method.
1143 % o context: the user defined context.
1146 MagickExport MagickBooleanType UpdateImageViewIterator(ImageView *source,
1147 UpdateImageViewMethod update,void *context)
1161 assert(source != (ImageView *) NULL);
1162 assert(source->signature == MagickSignature);
1163 if (update == (UpdateImageViewMethod) NULL)
1164 return(MagickFalse);
1165 source_image=source->image;
1166 status=SetImageStorageClass(source_image,DirectClass,source->exception);
1167 if (status == MagickFalse)
1168 return(MagickFalse);
1171 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1172 #pragma omp parallel for schedule(static) shared(progress,status) num_threads(source->number_threads)
1174 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1177 id = GetOpenMPThreadId();
1182 if (status == MagickFalse)
1184 pixels=GetCacheViewAuthenticPixels(source->view,source->extent.x,y,
1185 source->extent.width,1,source->exception);
1186 if (pixels == (Quantum *) NULL)
1191 if (update(source,y,id,context) == MagickFalse)
1193 status=SyncCacheViewAuthenticPixels(source->view,source->exception);
1194 if (status == MagickFalse)
1196 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1201 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1202 #pragma omp critical (MagickCore_UpdateImageViewIterator)
1204 proceed=SetImageProgress(source_image,source->description,progress++,
1205 source->extent.height);
1206 if (proceed == MagickFalse)