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 "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)
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 if (SetImageStorageClass(destination_image,DirectClass) == MagickFalse)
244 exception=destination->exception;
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 PixelPacket
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 PixelPacket *) NULL)
272 duplex_pixels=GetCacheViewVirtualPixels(duplex->view,duplex->extent.x,y,
273 duplex->extent.width,1,duplex->exception);
274 if (duplex_pixels == (const PixelPacket *) NULL)
279 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
280 destination->extent.x,y,destination->extent.width,1,exception);
281 if (destination_pixels == (PixelPacket *) 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 I n d e x e s %
321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
323 % GetImageViewAuthenticIndexes() returns the image view authentic indexes.
325 % The format of the GetImageViewAuthenticPixels method is:
327 % IndexPacket *GetImageViewAuthenticIndexes(const ImageView *image_view)
329 % A description of each parameter follows:
331 % o image_view: the image view.
334 MagickExport IndexPacket *GetImageViewAuthenticIndexes(
335 const ImageView *image_view)
337 assert(image_view != (ImageView *) NULL);
338 assert(image_view->signature == MagickSignature);
339 return(GetCacheViewAuthenticIndexQueue(image_view->view));
343 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347 % 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 %
351 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353 % GetImageViewAuthenticPixels() returns the image view authentic pixels.
355 % The format of the GetImageViewAuthenticPixels method is:
357 % PixelPacket *GetImageViewAuthenticPixels(const ImageView *image_view)
359 % A description of each parameter follows:
361 % o image_view: the image view.
364 MagickExport PixelPacket *GetImageViewAuthenticPixels(
365 const ImageView *image_view)
367 assert(image_view != (ImageView *) NULL);
368 assert(image_view->signature == MagickSignature);
369 return(GetCacheViewAuthenticPixelQueue(image_view->view));
373 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
377 % G e t I m a g e V i e w E x c e p t i o n %
381 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
383 % GetImageViewException() returns the severity, reason, and description of any
384 % error that occurs when utilizing a image view.
386 % The format of the GetImageViewException method is:
388 % char *GetImageViewException(const PixelImage *image_view,
389 % ExceptionType *severity)
391 % A description of each parameter follows:
393 % o image_view: the pixel image_view.
395 % o severity: the severity of the error is returned here.
398 MagickExport char *GetImageViewException(const ImageView *image_view,
399 ExceptionType *severity)
404 assert(image_view != (const ImageView *) NULL);
405 assert(image_view->signature == MagickSignature);
406 assert(severity != (ExceptionType *) NULL);
407 *severity=image_view->exception->severity;
408 description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
409 sizeof(*description));
410 if (description == (char *) NULL)
411 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
413 if (image_view->exception->reason != (char *) NULL)
414 (void) CopyMagickString(description,GetLocaleExceptionMessage(
415 image_view->exception->severity,image_view->exception->reason),
417 if (image_view->exception->description != (char *) NULL)
419 (void) ConcatenateMagickString(description," (",MaxTextExtent);
420 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
421 image_view->exception->severity,image_view->exception->description),
423 (void) ConcatenateMagickString(description,")",MaxTextExtent);
429 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
433 % G e t I m a g e V i e w E x t e n t %
437 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
439 % GetImageViewExtent() returns the image view extent.
441 % The format of the GetImageViewExtent method is:
443 % RectangleInfo GetImageViewExtent(const ImageView *image_view)
445 % A description of each parameter follows:
447 % o image_view: the image view.
450 MagickExport RectangleInfo GetImageViewExtent(const ImageView *image_view)
452 assert(image_view != (ImageView *) NULL);
453 assert(image_view->signature == MagickSignature);
454 return(image_view->extent);
458 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
462 % G e t I m a g e V i e w I m a g e %
466 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
468 % GetImageViewImage() returns the image associated with the image view.
470 % The format of the GetImageViewImage method is:
472 % MagickCore *GetImageViewImage(const ImageView *image_view)
474 % A description of each parameter follows:
476 % o image_view: the image view.
479 MagickExport Image *GetImageViewImage(const ImageView *image_view)
481 assert(image_view != (ImageView *) NULL);
482 assert(image_view->signature == MagickSignature);
483 return(image_view->image);
487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
491 % G e t I m a g e V i e w I t e r a t o r %
495 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
497 % GetImageViewIterator() iterates over the image view in parallel and calls
498 % your get method for each scanline of the view. The pixel extent is
499 % not confined to the image canvas-- that is you can include negative offsets
500 % or widths or heights that exceed the image dimension. Any updates to
501 % the pixels in your callback are ignored.
503 % The callback signature is:
505 % MagickBooleanType GetImageViewMethod(const ImageView *source,
506 % const ssize_t y,const int thread_id,void *context)
508 % Use this pragma if the view is not single threaded:
510 % #pragma omp critical
512 % to define a section of code in your callback get method that must be
513 % executed by a single thread at a time.
515 % The format of the GetImageViewIterator method is:
517 % MagickBooleanType GetImageViewIterator(ImageView *source,
518 % GetImageViewMethod get,void *context)
520 % A description of each parameter follows:
522 % o source: the source image view.
524 % o get: the get callback method.
526 % o context: the user defined context.
529 MagickExport MagickBooleanType GetImageViewIterator(ImageView *source,
530 GetImageViewMethod get,void *context)
544 assert(source != (ImageView *) NULL);
545 assert(source->signature == MagickSignature);
546 if (get == (GetImageViewMethod) NULL)
548 source_image=source->image;
551 #if defined(MAGICKCORE_OPENMP_SUPPORT)
552 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(source->number_threads)
554 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
557 id = GetOpenMPThreadId();
559 register const PixelPacket
562 if (status == MagickFalse)
564 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
565 source->extent.width,1,source->exception);
566 if (pixels == (const PixelPacket *) NULL)
571 if (get(source,y,id,context) == MagickFalse)
573 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
578 #if defined(MAGICKCORE_OPENMP_SUPPORT)
579 #pragma omp critical (MagickCore_GetImageViewIterator)
581 proceed=SetImageProgress(source_image,source->description,progress++,
582 source->extent.height);
583 if (proceed == MagickFalse)
591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
595 % 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 %
599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
601 % GetImageViewVirtualIndexes() returns the image view virtual indexes.
603 % The format of the GetImageViewVirtualIndexes method is:
605 % const IndexPacket *GetImageViewVirtualIndexes(
606 % const ImageView *image_view)
608 % A description of each parameter follows:
610 % o image_view: the image view.
613 MagickExport const IndexPacket *GetImageViewVirtualIndexes(
614 const ImageView *image_view)
616 assert(image_view != (ImageView *) NULL);
617 assert(image_view->signature == MagickSignature);
618 return(GetCacheViewVirtualIndexQueue(image_view->view));
622 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
626 % 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 %
630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
632 % GetImageViewVirtualPixels() returns the image view virtual pixels.
634 % The format of the GetImageViewVirtualPixels method is:
636 % const PixelPacket *GetImageViewVirtualPixels(const ImageView *image_view)
638 % A description of each parameter follows:
640 % o image_view: the image view.
643 MagickExport const PixelPacket *GetImageViewVirtualPixels(
644 const ImageView *image_view)
646 assert(image_view != (ImageView *) NULL);
647 assert(image_view->signature == MagickSignature);
648 return(GetCacheViewVirtualPixelQueue(image_view->view));
652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
656 % I s I m a g e V i e w %
660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
662 % IsImageView() returns MagickTrue if the the parameter is verified as a image
665 % The format of the IsImageView method is:
667 % MagickBooleanType IsImageView(const ImageView *image_view)
669 % A description of each parameter follows:
671 % o image_view: the image view.
674 MagickExport MagickBooleanType IsImageView(const ImageView *image_view)
676 if (image_view == (const ImageView *) NULL)
678 if (image_view->signature != MagickSignature)
684 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
688 % N e w I m a g e V i e w %
692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
694 % NewImageView() returns a image view required for all other methods in the
697 % The format of the NewImageView method is:
699 % ImageView *NewImageView(MagickCore *wand)
701 % A description of each parameter follows:
706 MagickExport ImageView *NewImageView(Image *image)
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=AcquireCacheView(image_view->image);
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)
750 % A description of each parameter follows:
752 % o wand: the magick wand.
754 % o x,y,columns,rows: These values define the perimeter of a extent of
758 MagickExport ImageView *NewImageViewRegion(Image *image,const ssize_t x,
759 const ssize_t y,const size_t width,const size_t height)
764 assert(image != (Image *) NULL);
765 assert(image->signature == MagickSignature);
766 image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
767 if (image_view == (ImageView *) NULL)
768 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
769 (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
770 image_view->description=ConstantString("ImageView");
771 image_view->view=AcquireCacheView(image_view->image);
772 image_view->image=image;
773 image_view->extent.width=width;
774 image_view->extent.height=height;
775 image_view->extent.x=x;
776 image_view->extent.y=y;
777 image_view->number_threads=GetOpenMPMaximumThreads();
778 image_view->exception=AcquireExceptionInfo();
779 image_view->debug=IsEventLogging();
780 image_view->signature=MagickSignature;
785 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
789 % S e t I m a g e V i e w D e s c r i p t i o n %
793 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795 % SetImageViewDescription() associates a description with an image view.
797 % The format of the SetImageViewDescription method is:
799 % void SetImageViewDescription(ImageView *image_view,
800 % const char *description)
802 % A description of each parameter follows:
804 % o image_view: the image view.
806 % o description: the image view description.
809 MagickExport void SetImageViewDescription(ImageView *image_view,
810 const char *description)
812 assert(image_view != (ImageView *) NULL);
813 assert(image_view->signature == MagickSignature);
814 image_view->description=ConstantString(description);
818 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
822 % S e t I m a g e V i e w I t e r a t o r %
826 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
828 % SetImageViewIterator() iterates over the image view in parallel and calls
829 % your set method for each scanline of the view. The pixel extent is
830 % confined to the image canvas-- that is no negative offsets or widths or
831 % heights that exceed the image dimension. The pixels are initiallly
832 % undefined and any settings you make in the callback method are automagically
833 % synced back to your image.
835 % The callback signature is:
837 % MagickBooleanType SetImageViewMethod(ImageView *destination,
838 % const ssize_t y,const int thread_id,void *context)
840 % Use this pragma if the view is not single threaded:
842 % #pragma omp critical
844 % to define a section of code in your callback set method that must be
845 % executed by a single thread at a time.
847 % The format of the SetImageViewIterator method is:
849 % MagickBooleanType SetImageViewIterator(ImageView *destination,
850 % SetImageViewMethod set,void *context)
852 % A description of each parameter follows:
854 % o destination: the image view.
856 % o set: the set callback method.
858 % o context: the user defined context.
861 MagickExport MagickBooleanType SetImageViewIterator(ImageView *destination,
862 SetImageViewMethod set,void *context)
879 assert(destination != (ImageView *) NULL);
880 assert(destination->signature == MagickSignature);
881 if (set == (SetImageViewMethod) NULL)
883 destination_image=destination->image;
884 if (SetImageStorageClass(destination_image,DirectClass) == MagickFalse)
888 exception=destination->exception;
889 #if defined(MAGICKCORE_OPENMP_SUPPORT)
890 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(destination->number_threads)
892 for (y=destination->extent.y; y < (ssize_t) destination->extent.height; y++)
895 id = GetOpenMPThreadId();
903 if (status == MagickFalse)
905 pixels=GetCacheViewAuthenticPixels(destination->view,destination->extent.x,
906 y,destination->extent.width,1,exception);
907 if (pixels == (PixelPacket *) NULL)
909 InheritException(destination->exception,GetCacheViewException(
914 if (set(destination,y,id,context) == MagickFalse)
916 sync=SyncCacheViewAuthenticPixels(destination->view,exception);
917 if (sync == MagickFalse)
919 InheritException(destination->exception,GetCacheViewException(
923 if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
928 #if defined(MAGICKCORE_OPENMP_SUPPORT)
929 #pragma omp critical (MagickCore_SetImageViewIterator)
931 proceed=SetImageProgress(destination_image,destination->description,
932 progress++,destination->extent.height);
933 if (proceed == MagickFalse)
941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945 % S e t I m a g e V i e w T h r e a d s %
949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
951 % SetImageViewThreads() sets the number of threads in a thread team.
953 % The format of the SetImageViewDescription method is:
955 % void SetImageViewThreads(ImageView *image_view,
956 % const size_t number_threads)
958 % A description of each parameter follows:
960 % o image_view: the image view.
962 % o number_threads: the number of threads in a thread team.
965 MagickExport void SetImageViewThreads(ImageView *image_view,
966 const size_t number_threads)
968 assert(image_view != (ImageView *) NULL);
969 assert(image_view->signature == MagickSignature);
970 image_view->number_threads=number_threads;
971 if (number_threads > GetOpenMPMaximumThreads())
972 image_view->number_threads=GetOpenMPMaximumThreads();
976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
980 % 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 %
984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
986 % TransferImageViewIterator() iterates over two image views in parallel and
987 % calls your transfer method for each scanline of the view. The source pixel
988 % extent is not confined to the image canvas-- that is you can include
989 % negative offsets or widths or heights that exceed the image dimension.
990 % However, the destination image view is confined to the image canvas-- that
991 % is no negative offsets or widths or heights that exceed the image dimension
994 % The callback signature is:
996 % MagickBooleanType TransferImageViewMethod(const ImageView *source,
997 % ImageView *destination,const ssize_t y,const int thread_id,
1000 % Use this pragma if the view is not single threaded:
1002 % #pragma omp critical
1004 % to define a section of code in your callback transfer method that must be
1005 % executed by a single thread at a time.
1007 % The format of the TransferImageViewIterator method is:
1009 % MagickBooleanType TransferImageViewIterator(ImageView *source,
1010 % ImageView *destination,TransferImageViewMethod transfer,void *context)
1012 % A description of each parameter follows:
1014 % o source: the source image view.
1016 % o destination: the destination image view.
1018 % o transfer: the transfer callback method.
1020 % o context: the user defined context.
1023 MagickExport MagickBooleanType TransferImageViewIterator(ImageView *source,
1024 ImageView *destination,TransferImageViewMethod transfer,void *context)
1042 assert(source != (ImageView *) NULL);
1043 assert(source->signature == MagickSignature);
1044 if (transfer == (TransferImageViewMethod) NULL)
1045 return(MagickFalse);
1046 source_image=source->image;
1047 destination_image=destination->image;
1048 if (SetImageStorageClass(destination_image,DirectClass) == MagickFalse)
1049 return(MagickFalse);
1052 exception=destination->exception;
1053 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1054 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(source->number_threads)
1056 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1059 id = GetOpenMPThreadId();
1064 register const PixelPacket
1067 register PixelPacket
1068 *restrict destination_pixels;
1070 if (status == MagickFalse)
1072 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
1073 source->extent.width,1,source->exception);
1074 if (pixels == (const PixelPacket *) NULL)
1079 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
1080 destination->extent.x,y,destination->extent.width,1,exception);
1081 if (destination_pixels == (PixelPacket *) NULL)
1086 if (transfer(source,destination,y,id,context) == MagickFalse)
1088 sync=SyncCacheViewAuthenticPixels(destination->view,exception);
1089 if (sync == MagickFalse)
1091 InheritException(destination->exception,GetCacheViewException(
1095 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1100 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1101 #pragma omp critical (MagickCore_TransferImageViewIterator)
1103 proceed=SetImageProgress(source_image,source->description,progress++,
1104 source->extent.height);
1105 if (proceed == MagickFalse)
1113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1117 % U p d a t e I m a g e V i e w I t e r a t o r %
1121 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1123 % UpdateImageViewIterator() iterates over the image view in parallel and calls
1124 % your update method for each scanline of the view. The pixel extent is
1125 % confined to the image canvas-- that is no negative offsets or widths or
1126 % heights that exceed the image dimension are permitted. Updates to pixels
1127 % in your callback are automagically synced back to the image.
1129 % The callback signature is:
1131 % MagickBooleanType UpdateImageViewMethod(ImageView *source,
1132 % const ssize_t y,const int thread_id,void *context)
1134 % Use this pragma if the view is not single threaded:
1136 % #pragma omp critical
1138 % to define a section of code in your callback update method that must be
1139 % executed by a single thread at a time.
1141 % The format of the UpdateImageViewIterator method is:
1143 % MagickBooleanType UpdateImageViewIterator(ImageView *source,
1144 % UpdateImageViewMethod update,void *context)
1146 % A description of each parameter follows:
1148 % o source: the source image view.
1150 % o update: the update callback method.
1152 % o context: the user defined context.
1155 MagickExport MagickBooleanType UpdateImageViewIterator(ImageView *source,
1156 UpdateImageViewMethod update,void *context)
1173 assert(source != (ImageView *) NULL);
1174 assert(source->signature == MagickSignature);
1175 if (update == (UpdateImageViewMethod) NULL)
1176 return(MagickFalse);
1177 source_image=source->image;
1178 if (SetImageStorageClass(source_image,DirectClass) == MagickFalse)
1179 return(MagickFalse);
1182 exception=source->exception;
1183 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1184 #pragma omp parallel for schedule(static,1) shared(progress,status) num_threads(source->number_threads)
1186 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1189 id = GetOpenMPThreadId();
1191 register PixelPacket
1194 if (status == MagickFalse)
1196 pixels=GetCacheViewAuthenticPixels(source->view,source->extent.x,y,
1197 source->extent.width,1,exception);
1198 if (pixels == (PixelPacket *) NULL)
1200 InheritException(source->exception,GetCacheViewException(source->view));
1204 if (update(source,y,id,context) == MagickFalse)
1206 if (SyncCacheViewAuthenticPixels(source->view,exception) == MagickFalse)
1208 InheritException(source->exception,GetCacheViewException(source->view));
1211 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1216 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1217 #pragma omp critical (MagickCore_UpdateImageViewIterator)
1219 proceed=SetImageProgress(source_image,source->description,progress++,
1220 source->extent.height);
1221 if (proceed == MagickFalse)