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-2014 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"
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
86 % C l o n e I m a g e V i e w %
90 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92 % CloneImageView() makes a copy of the specified image view.
94 % The format of the CloneImageView method is:
96 % ImageView *CloneImageView(const ImageView *image_view)
98 % A description of each parameter follows:
100 % o image_view: the image view.
103 MagickExport ImageView *CloneImageView(const ImageView *image_view)
108 assert(image_view != (ImageView *) NULL);
109 assert(image_view->signature == MagickSignature);
110 clone_view=(ImageView *) AcquireMagickMemory(sizeof(*clone_view));
111 if (clone_view == (ImageView *) NULL)
112 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
113 (void) ResetMagickMemory(clone_view,0,sizeof(*clone_view));
114 clone_view->description=ConstantString(image_view->description);
115 clone_view->extent=image_view->extent;
116 clone_view->view=CloneCacheView(image_view->view);
117 clone_view->exception=AcquireExceptionInfo();
118 InheritException(clone_view->exception,image_view->exception);
119 clone_view->debug=image_view->debug;
120 clone_view->signature=MagickSignature;
125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129 % D e s t r o y I m a g e V i e w %
133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
135 % DestroyImageView() deallocates memory associated with a image view.
137 % The format of the DestroyImageView method is:
139 % ImageView *DestroyImageView(ImageView *image_view)
141 % A description of each parameter follows:
143 % o image_view: the image view.
146 MagickExport ImageView *DestroyImageView(ImageView *image_view)
148 assert(image_view != (ImageView *) NULL);
149 assert(image_view->signature == MagickSignature);
150 if (image_view->description != (char *) NULL)
151 image_view->description=DestroyString(image_view->description);
152 image_view->view=DestroyCacheView(image_view->view);
153 image_view->exception=DestroyExceptionInfo(image_view->exception);
154 image_view->signature=(~MagickSignature);
155 image_view=(ImageView *) RelinquishMagickMemory(image_view);
160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164 % 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 %
168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170 % DuplexTransferImageViewIterator() iterates over three image views in
171 % parallel and calls your transfer method for each scanline of the view. The
172 % source and duplex pixel extent is not confined to the image canvas-- that is
173 % you can include negative offsets or widths or heights that exceed the image
174 % dimension. However, the destination image view is confined to the image
175 % canvas-- that is no negative offsets or widths or heights that exceed the
176 % image dimension are permitted.
178 % The callback signature is:
180 % MagickBooleanType DuplexTransferImageViewMethod(const ImageView *source,
181 % const ImageView *duplex,ImageView *destination,const ssize_t y,
182 % const int thread_id,void *context)
184 % Use this pragma if the view is not single threaded:
186 % #pragma omp critical
188 % to define a section of code in your callback transfer method that must be
189 % executed by a single thread at a time.
191 % The format of the DuplexTransferImageViewIterator method is:
193 % MagickBooleanType DuplexTransferImageViewIterator(ImageView *source,
194 % ImageView *duplex,ImageView *destination,
195 % DuplexTransferImageViewMethod transfer,void *context)
197 % A description of each parameter follows:
199 % o source: the source image view.
201 % o duplex: the duplex image view.
203 % o destination: the destination image view.
205 % o transfer: the transfer callback method.
207 % o context: the user defined context.
210 MagickExport MagickBooleanType DuplexTransferImageViewIterator(
211 ImageView *source,ImageView *duplex,ImageView *destination,
212 DuplexTransferImageViewMethod transfer,void *context)
224 #if defined(MAGICKCORE_OPENMP_SUPPORT)
232 assert(source != (ImageView *) NULL);
233 assert(source->signature == MagickSignature);
234 if (transfer == (DuplexTransferImageViewMethod) NULL)
236 source_image=source->image;
237 destination_image=destination->image;
238 status=SetImageStorageClass(destination_image,DirectClass,
239 destination->exception);
240 if (status == MagickFalse)
244 #if defined(MAGICKCORE_OPENMP_SUPPORT)
245 height=source->extent.height-source->extent.y;
246 #pragma omp parallel for schedule(static,4) shared(progress,status) \
247 magick_threads(source_image,destination_image,height,1)
249 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
252 id = GetOpenMPThreadId();
257 register const Quantum
258 *restrict duplex_pixels,
262 *restrict destination_pixels;
264 if (status == MagickFalse)
266 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
267 source->extent.width,1,source->exception);
268 if (pixels == (const Quantum *) NULL)
273 duplex_pixels=GetCacheViewVirtualPixels(duplex->view,duplex->extent.x,y,
274 duplex->extent.width,1,duplex->exception);
275 if (duplex_pixels == (const Quantum *) NULL)
280 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
281 destination->extent.x,y,destination->extent.width,1,
282 destination->exception);
283 if (destination_pixels == (Quantum *) NULL)
288 if (transfer(source,duplex,destination,y,id,context) == MagickFalse)
290 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
291 if (sync == MagickFalse)
293 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
298 #if defined(MAGICKCORE_OPENMP_SUPPORT)
299 #pragma omp critical (MagickCore_DuplexTransferImageViewIterator)
301 proceed=SetImageProgress(source_image,source->description,progress++,
302 source->extent.height);
303 if (proceed == MagickFalse)
311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
315 % 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 %
319 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
321 % GetImageViewAuthenticMetacontent() returns the image view authentic
324 % The format of the GetImageViewAuthenticPixels method is:
326 % void *GetImageViewAuthenticMetacontent(
327 % const ImageView *image_view)
329 % A description of each parameter follows:
331 % o image_view: the image view.
334 MagickExport void *GetImageViewAuthenticMetacontent(
335 const ImageView *image_view)
337 assert(image_view != (ImageView *) NULL);
338 assert(image_view->signature == MagickSignature);
339 return(GetCacheViewAuthenticMetacontent(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 % Quantum *GetImageViewAuthenticPixels(const ImageView *image_view)
359 % A description of each parameter follows:
361 % o image_view: the image view.
364 MagickExport Quantum *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)
541 #if defined(MAGICKCORE_OPENMP_SUPPORT)
549 assert(source != (ImageView *) NULL);
550 assert(source->signature == MagickSignature);
551 if (get == (GetImageViewMethod) NULL)
553 source_image=source->image;
556 #if defined(MAGICKCORE_OPENMP_SUPPORT)
557 height=source->extent.height-source->extent.y;
558 #pragma omp parallel for schedule(static,4) shared(progress,status) \
559 magick_threads(source_image,source_image,height,1)
561 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
564 id = GetOpenMPThreadId();
566 register const Quantum
569 if (status == MagickFalse)
571 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
572 source->extent.width,1,source->exception);
573 if (pixels == (const Quantum *) NULL)
578 if (get(source,y,id,context) == MagickFalse)
580 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
585 #if defined(MAGICKCORE_OPENMP_SUPPORT)
586 #pragma omp critical (MagickCore_GetImageViewIterator)
588 proceed=SetImageProgress(source_image,source->description,progress++,
589 source->extent.height);
590 if (proceed == MagickFalse)
598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
602 % 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 %
606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
608 % GetImageViewVirtualMetacontent() returns the image view virtual
611 % The format of the GetImageViewVirtualMetacontent method is:
613 % const void *GetImageViewVirtualMetacontent(
614 % const ImageView *image_view)
616 % A description of each parameter follows:
618 % o image_view: the image view.
621 MagickExport const void *GetImageViewVirtualMetacontent(
622 const ImageView *image_view)
624 assert(image_view != (ImageView *) NULL);
625 assert(image_view->signature == MagickSignature);
626 return(GetCacheViewVirtualMetacontent(image_view->view));
630 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
634 % 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 %
638 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640 % GetImageViewVirtualPixels() returns the image view virtual pixels.
642 % The format of the GetImageViewVirtualPixels method is:
644 % const Quantum *GetImageViewVirtualPixels(const ImageView *image_view)
646 % A description of each parameter follows:
648 % o image_view: the image view.
651 MagickExport const Quantum *GetImageViewVirtualPixels(
652 const ImageView *image_view)
654 assert(image_view != (ImageView *) NULL);
655 assert(image_view->signature == MagickSignature);
656 return(GetCacheViewVirtualPixelQueue(image_view->view));
660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
664 % I s I m a g e V i e w %
668 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
670 % IsImageView() returns MagickTrue if the the parameter is verified as a image
673 % The format of the IsImageView method is:
675 % MagickBooleanType IsImageView(const ImageView *image_view)
677 % A description of each parameter follows:
679 % o image_view: the image view.
682 MagickExport MagickBooleanType IsImageView(const ImageView *image_view)
684 if (image_view == (const ImageView *) NULL)
686 if (image_view->signature != MagickSignature)
692 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
696 % N e w I m a g e V i e w %
700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
702 % NewImageView() returns a image view required for all other methods in the
705 % The format of the NewImageView method is:
707 % ImageView *NewImageView(MagickCore *wand,ExceptionInfo *exception)
709 % A description of each parameter follows:
711 % o image: the image.
713 % o exception: return any errors or warnings in this structure.
716 MagickExport ImageView *NewImageView(Image *image,ExceptionInfo *exception)
721 assert(image != (Image *) NULL);
722 assert(image->signature == MagickSignature);
723 image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
724 if (image_view == (ImageView *) NULL)
725 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
726 (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
727 image_view->description=ConstantString("ImageView");
728 image_view->image=image;
729 image_view->view=AcquireVirtualCacheView(image_view->image,exception);
730 image_view->extent.width=image->columns;
731 image_view->extent.height=image->rows;
732 image_view->extent.x=0;
733 image_view->extent.y=0;
734 image_view->exception=AcquireExceptionInfo();
735 image_view->debug=IsEventLogging();
736 image_view->signature=MagickSignature;
741 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
745 % N e w I m a g e V i e w R e g i o n %
749 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
751 % NewImageViewRegion() returns a image view required for all other methods
752 % in the Image View API.
754 % The format of the NewImageViewRegion method is:
756 % ImageView *NewImageViewRegion(MagickCore *wand,const ssize_t x,
757 % const ssize_t y,const size_t width,const size_t height,
758 % ExceptionInfo *exception)
760 % A description of each parameter follows:
762 % o wand: the magick wand.
764 % o x,y,columns,rows: These values define the perimeter of a extent of
767 % o exception: return any errors or warnings in this structure.
770 MagickExport ImageView *NewImageViewRegion(Image *image,const ssize_t x,
771 const ssize_t y,const size_t width,const size_t height,
772 ExceptionInfo *exception)
777 assert(image != (Image *) NULL);
778 assert(image->signature == MagickSignature);
779 image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
780 if (image_view == (ImageView *) NULL)
781 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
782 (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
783 image_view->description=ConstantString("ImageView");
784 image_view->view=AcquireVirtualCacheView(image_view->image,exception);
785 image_view->image=image;
786 image_view->extent.width=width;
787 image_view->extent.height=height;
788 image_view->extent.x=x;
789 image_view->extent.y=y;
790 image_view->exception=AcquireExceptionInfo();
791 image_view->debug=IsEventLogging();
792 image_view->signature=MagickSignature;
797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
801 % S e t I m a g e V i e w D e s c r i p t i o n %
805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
807 % SetImageViewDescription() associates a description with an image view.
809 % The format of the SetImageViewDescription method is:
811 % void SetImageViewDescription(ImageView *image_view,
812 % const char *description)
814 % A description of each parameter follows:
816 % o image_view: the image view.
818 % o description: the image view description.
821 MagickExport void SetImageViewDescription(ImageView *image_view,
822 const char *description)
824 assert(image_view != (ImageView *) NULL);
825 assert(image_view->signature == MagickSignature);
826 image_view->description=ConstantString(description);
830 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
834 % S e t I m a g e V i e w I t e r a t o r %
838 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
840 % SetImageViewIterator() iterates over the image view in parallel and calls
841 % your set method for each scanline of the view. The pixel extent is
842 % confined to the image canvas-- that is no negative offsets or widths or
843 % heights that exceed the image dimension. The pixels are initiallly
844 % undefined and any settings you make in the callback method are automagically
845 % synced back to your image.
847 % The callback signature is:
849 % MagickBooleanType SetImageViewMethod(ImageView *destination,
850 % const ssize_t y,const int thread_id,void *context)
852 % Use this pragma if the view is not single threaded:
854 % #pragma omp critical
856 % to define a section of code in your callback set method that must be
857 % executed by a single thread at a time.
859 % The format of the SetImageViewIterator method is:
861 % MagickBooleanType SetImageViewIterator(ImageView *destination,
862 % SetImageViewMethod set,void *context)
864 % A description of each parameter follows:
866 % o destination: the image view.
868 % o set: the set callback method.
870 % o context: the user defined context.
873 MagickExport MagickBooleanType SetImageViewIterator(ImageView *destination,
874 SetImageViewMethod set,void *context)
885 #if defined(MAGICKCORE_OPENMP_SUPPORT)
893 assert(destination != (ImageView *) NULL);
894 assert(destination->signature == MagickSignature);
895 if (set == (SetImageViewMethod) NULL)
897 destination_image=destination->image;
898 status=SetImageStorageClass(destination_image,DirectClass,
899 destination->exception);
900 if (status == MagickFalse)
904 #if defined(MAGICKCORE_OPENMP_SUPPORT)
905 height=destination->extent.height-destination->extent.y;
906 #pragma omp parallel for schedule(static,4) shared(progress,status) \
907 magick_threads(destination_image,destination_image,height,1)
909 for (y=destination->extent.y; y < (ssize_t) destination->extent.height; y++)
912 id = GetOpenMPThreadId();
920 if (status == MagickFalse)
922 pixels=GetCacheViewAuthenticPixels(destination->view,destination->extent.x,
923 y,destination->extent.width,1,destination->exception);
924 if (pixels == (Quantum *) NULL)
929 if (set(destination,y,id,context) == MagickFalse)
931 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
932 if (sync == MagickFalse)
934 if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
939 #if defined(MAGICKCORE_OPENMP_SUPPORT)
940 #pragma omp critical (MagickCore_SetImageViewIterator)
942 proceed=SetImageProgress(destination_image,destination->description,
943 progress++,destination->extent.height);
944 if (proceed == MagickFalse)
952 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
956 % 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 %
960 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
962 % TransferImageViewIterator() iterates over two image views in parallel and
963 % calls your transfer method for each scanline of the view. The source pixel
964 % extent is not confined to the image canvas-- that is you can include
965 % negative offsets or widths or heights that exceed the image dimension.
966 % However, the destination image view is confined to the image canvas-- that
967 % is no negative offsets or widths or heights that exceed the image dimension
970 % The callback signature is:
972 % MagickBooleanType TransferImageViewMethod(const ImageView *source,
973 % ImageView *destination,const ssize_t y,const int thread_id,
976 % Use this pragma if the view is not single threaded:
978 % #pragma omp critical
980 % to define a section of code in your callback transfer method that must be
981 % executed by a single thread at a time.
983 % The format of the TransferImageViewIterator method is:
985 % MagickBooleanType TransferImageViewIterator(ImageView *source,
986 % ImageView *destination,TransferImageViewMethod transfer,void *context)
988 % A description of each parameter follows:
990 % o source: the source image view.
992 % o destination: the destination image view.
994 % o transfer: the transfer callback method.
996 % o context: the user defined context.
999 MagickExport MagickBooleanType TransferImageViewIterator(ImageView *source,
1000 ImageView *destination,TransferImageViewMethod transfer,void *context)
1012 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1020 assert(source != (ImageView *) NULL);
1021 assert(source->signature == MagickSignature);
1022 if (transfer == (TransferImageViewMethod) NULL)
1023 return(MagickFalse);
1024 source_image=source->image;
1025 destination_image=destination->image;
1026 status=SetImageStorageClass(destination_image,DirectClass,
1027 destination->exception);
1028 if (status == MagickFalse)
1029 return(MagickFalse);
1032 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1033 height=source->extent.height-source->extent.y;
1034 #pragma omp parallel for schedule(static,4) shared(progress,status) \
1035 magick_threads(source_image,destination_image,height,1)
1037 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1040 id = GetOpenMPThreadId();
1045 register const Quantum
1049 *restrict destination_pixels;
1051 if (status == MagickFalse)
1053 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
1054 source->extent.width,1,source->exception);
1055 if (pixels == (const Quantum *) NULL)
1060 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
1061 destination->extent.x,y,destination->extent.width,1,
1062 destination->exception);
1063 if (destination_pixels == (Quantum *) NULL)
1068 if (transfer(source,destination,y,id,context) == MagickFalse)
1070 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
1071 if (sync == MagickFalse)
1073 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1078 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1079 #pragma omp critical (MagickCore_TransferImageViewIterator)
1081 proceed=SetImageProgress(source_image,source->description,progress++,
1082 source->extent.height);
1083 if (proceed == MagickFalse)
1091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1095 % U p d a t e I m a g e V i e w I t e r a t o r %
1099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1101 % UpdateImageViewIterator() iterates over the image view in parallel and calls
1102 % your update method for each scanline of the view. The pixel extent is
1103 % confined to the image canvas-- that is no negative offsets or widths or
1104 % heights that exceed the image dimension are permitted. Updates to pixels
1105 % in your callback are automagically synced back to the image.
1107 % The callback signature is:
1109 % MagickBooleanType UpdateImageViewMethod(ImageView *source,
1110 % const ssize_t y,const int thread_id,void *context)
1112 % Use this pragma if the view is not single threaded:
1114 % #pragma omp critical
1116 % to define a section of code in your callback update method that must be
1117 % executed by a single thread at a time.
1119 % The format of the UpdateImageViewIterator method is:
1121 % MagickBooleanType UpdateImageViewIterator(ImageView *source,
1122 % UpdateImageViewMethod update,void *context)
1124 % A description of each parameter follows:
1126 % o source: the source image view.
1128 % o update: the update callback method.
1130 % o context: the user defined context.
1133 MagickExport MagickBooleanType UpdateImageViewIterator(ImageView *source,
1134 UpdateImageViewMethod update,void *context)
1145 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1153 assert(source != (ImageView *) NULL);
1154 assert(source->signature == MagickSignature);
1155 if (update == (UpdateImageViewMethod) NULL)
1156 return(MagickFalse);
1157 source_image=source->image;
1158 status=SetImageStorageClass(source_image,DirectClass,source->exception);
1159 if (status == MagickFalse)
1160 return(MagickFalse);
1163 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1164 height=source->extent.height-source->extent.y;
1165 #pragma omp parallel for schedule(static,4) shared(progress,status) \
1166 magick_threads(source_image,source_image,height,1)
1168 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1171 id = GetOpenMPThreadId();
1176 if (status == MagickFalse)
1178 pixels=GetCacheViewAuthenticPixels(source->view,source->extent.x,y,
1179 source->extent.width,1,source->exception);
1180 if (pixels == (Quantum *) NULL)
1185 if (update(source,y,id,context) == MagickFalse)
1187 status=SyncCacheViewAuthenticPixels(source->view,source->exception);
1188 if (status == MagickFalse)
1190 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1195 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1196 #pragma omp critical (MagickCore_UpdateImageViewIterator)
1198 proceed=SetImageProgress(source_image,source->description,progress++,
1199 source->extent.height);
1200 if (proceed == MagickFalse)