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"
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)
233 assert(source != (ImageView *) NULL);
234 assert(source->signature == MagickSignature);
235 if (transfer == (DuplexTransferImageViewMethod) NULL)
237 source_image=source->image;
238 destination_image=destination->image;
239 status=SetImageStorageClass(destination_image,DirectClass,
240 destination->exception);
241 if (status == MagickFalse)
245 #if defined(MAGICKCORE_OPENMP_SUPPORT)
246 height=source->extent.height-source->extent.y;
247 width=source->extent.width-source->extent.x;
248 #pragma omp parallel for schedule(static) shared(progress,status) \
249 dynamic_number_threads(source_image,width,height,1)
251 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
254 id = GetOpenMPThreadId();
259 register const Quantum
260 *restrict duplex_pixels,
264 *restrict destination_pixels;
266 if (status == MagickFalse)
268 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
269 source->extent.width,1,source->exception);
270 if (pixels == (const Quantum *) NULL)
275 duplex_pixels=GetCacheViewVirtualPixels(duplex->view,duplex->extent.x,y,
276 duplex->extent.width,1,duplex->exception);
277 if (duplex_pixels == (const Quantum *) NULL)
282 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
283 destination->extent.x,y,destination->extent.width,1,
284 destination->exception);
285 if (destination_pixels == (Quantum *) NULL)
290 if (transfer(source,duplex,destination,y,id,context) == MagickFalse)
292 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
293 if (sync == MagickFalse)
295 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
300 #if defined(MAGICKCORE_OPENMP_SUPPORT)
301 #pragma omp critical (MagickCore_DuplexTransferImageViewIterator)
303 proceed=SetImageProgress(source_image,source->description,progress++,
304 source->extent.height);
305 if (proceed == MagickFalse)
313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317 % G e t I m a g e V i e w A u t h e n t i c M e t a c o n t e n t %
321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
323 % GetImageViewAuthenticMetacontent() returns the image view authentic
326 % The format of the GetImageViewAuthenticPixels method is:
328 % void *GetImageViewAuthenticMetacontent(
329 % const ImageView *image_view)
331 % A description of each parameter follows:
333 % o image_view: the image view.
336 MagickExport void *GetImageViewAuthenticMetacontent(
337 const ImageView *image_view)
339 assert(image_view != (ImageView *) NULL);
340 assert(image_view->signature == MagickSignature);
341 return(GetCacheViewAuthenticMetacontent(image_view->view));
345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349 % G e t I m a g e V i e w A u t h e n t i c P i x e l s %
353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
355 % GetImageViewAuthenticPixels() returns the image view authentic pixels.
357 % The format of the GetImageViewAuthenticPixels method is:
359 % Quantum *GetImageViewAuthenticPixels(const ImageView *image_view)
361 % A description of each parameter follows:
363 % o image_view: the image view.
366 MagickExport Quantum *GetImageViewAuthenticPixels(
367 const ImageView *image_view)
369 assert(image_view != (ImageView *) NULL);
370 assert(image_view->signature == MagickSignature);
371 return(GetCacheViewAuthenticPixelQueue(image_view->view));
375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
379 % G e t I m a g e V i e w E x c e p t i o n %
383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
385 % GetImageViewException() returns the severity, reason, and description of any
386 % error that occurs when utilizing a image view.
388 % The format of the GetImageViewException method is:
390 % char *GetImageViewException(const PixelImage *image_view,
391 % ExceptionType *severity)
393 % A description of each parameter follows:
395 % o image_view: the pixel image_view.
397 % o severity: the severity of the error is returned here.
400 MagickExport char *GetImageViewException(const ImageView *image_view,
401 ExceptionType *severity)
406 assert(image_view != (const ImageView *) NULL);
407 assert(image_view->signature == MagickSignature);
408 assert(severity != (ExceptionType *) NULL);
409 *severity=image_view->exception->severity;
410 description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
411 sizeof(*description));
412 if (description == (char *) NULL)
413 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
415 if (image_view->exception->reason != (char *) NULL)
416 (void) CopyMagickString(description,GetLocaleExceptionMessage(
417 image_view->exception->severity,image_view->exception->reason),
419 if (image_view->exception->description != (char *) NULL)
421 (void) ConcatenateMagickString(description," (",MaxTextExtent);
422 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
423 image_view->exception->severity,image_view->exception->description),
425 (void) ConcatenateMagickString(description,")",MaxTextExtent);
431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
435 % G e t I m a g e V i e w E x t e n t %
439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
441 % GetImageViewExtent() returns the image view extent.
443 % The format of the GetImageViewExtent method is:
445 % RectangleInfo GetImageViewExtent(const ImageView *image_view)
447 % A description of each parameter follows:
449 % o image_view: the image view.
452 MagickExport RectangleInfo GetImageViewExtent(const ImageView *image_view)
454 assert(image_view != (ImageView *) NULL);
455 assert(image_view->signature == MagickSignature);
456 return(image_view->extent);
460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
464 % G e t I m a g e V i e w I m a g e %
468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470 % GetImageViewImage() returns the image associated with the image view.
472 % The format of the GetImageViewImage method is:
474 % MagickCore *GetImageViewImage(const ImageView *image_view)
476 % A description of each parameter follows:
478 % o image_view: the image view.
481 MagickExport Image *GetImageViewImage(const ImageView *image_view)
483 assert(image_view != (ImageView *) NULL);
484 assert(image_view->signature == MagickSignature);
485 return(image_view->image);
489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
493 % G e t I m a g e V i e w I t e r a t o r %
497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
499 % GetImageViewIterator() iterates over the image view in parallel and calls
500 % your get method for each scanline of the view. The pixel extent is
501 % not confined to the image canvas-- that is you can include negative offsets
502 % or widths or heights that exceed the image dimension. Any updates to
503 % the pixels in your callback are ignored.
505 % The callback signature is:
507 % MagickBooleanType GetImageViewMethod(const ImageView *source,
508 % const ssize_t y,const int thread_id,void *context)
510 % Use this pragma if the view is not single threaded:
512 % #pragma omp critical
514 % to define a section of code in your callback get method that must be
515 % executed by a single thread at a time.
517 % The format of the GetImageViewIterator method is:
519 % MagickBooleanType GetImageViewIterator(ImageView *source,
520 % GetImageViewMethod get,void *context)
522 % A description of each parameter follows:
524 % o source: the source image view.
526 % o get: the get callback method.
528 % o context: the user defined context.
531 MagickExport MagickBooleanType GetImageViewIterator(ImageView *source,
532 GetImageViewMethod get,void *context)
543 #if defined(MAGICKCORE_OPENMP_SUPPORT)
552 assert(source != (ImageView *) NULL);
553 assert(source->signature == MagickSignature);
554 if (get == (GetImageViewMethod) NULL)
556 source_image=source->image;
559 #if defined(MAGICKCORE_OPENMP_SUPPORT)
560 height=source->extent.height-source->extent.y;
561 width=source->extent.width-source->extent.x;
562 #pragma omp parallel for schedule(static) shared(progress,status) \
563 dynamic_number_threads(source_image,width,height,1)
565 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
568 id = GetOpenMPThreadId();
570 register const Quantum
573 if (status == MagickFalse)
575 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
576 source->extent.width,1,source->exception);
577 if (pixels == (const Quantum *) NULL)
582 if (get(source,y,id,context) == MagickFalse)
584 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
589 #if defined(MAGICKCORE_OPENMP_SUPPORT)
590 #pragma omp critical (MagickCore_GetImageViewIterator)
592 proceed=SetImageProgress(source_image,source->description,progress++,
593 source->extent.height);
594 if (proceed == MagickFalse)
602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
606 % 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 %
610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
612 % GetImageViewVirtualMetacontent() returns the image view virtual
615 % The format of the GetImageViewVirtualMetacontent method is:
617 % const void *GetImageViewVirtualMetacontent(
618 % const ImageView *image_view)
620 % A description of each parameter follows:
622 % o image_view: the image view.
625 MagickExport const void *GetImageViewVirtualMetacontent(
626 const ImageView *image_view)
628 assert(image_view != (ImageView *) NULL);
629 assert(image_view->signature == MagickSignature);
630 return(GetCacheViewVirtualMetacontent(image_view->view));
634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
638 % 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 %
642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
644 % GetImageViewVirtualPixels() returns the image view virtual pixels.
646 % The format of the GetImageViewVirtualPixels method is:
648 % const Quantum *GetImageViewVirtualPixels(const ImageView *image_view)
650 % A description of each parameter follows:
652 % o image_view: the image view.
655 MagickExport const Quantum *GetImageViewVirtualPixels(
656 const ImageView *image_view)
658 assert(image_view != (ImageView *) NULL);
659 assert(image_view->signature == MagickSignature);
660 return(GetCacheViewVirtualPixelQueue(image_view->view));
664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
668 % I s I m a g e V i e w %
672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
674 % IsImageView() returns MagickTrue if the the parameter is verified as a image
677 % The format of the IsImageView method is:
679 % MagickBooleanType IsImageView(const ImageView *image_view)
681 % A description of each parameter follows:
683 % o image_view: the image view.
686 MagickExport MagickBooleanType IsImageView(const ImageView *image_view)
688 if (image_view == (const ImageView *) NULL)
690 if (image_view->signature != MagickSignature)
696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
700 % N e w I m a g e V i e w %
704 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
706 % NewImageView() returns a image view required for all other methods in the
709 % The format of the NewImageView method is:
711 % ImageView *NewImageView(MagickCore *wand,ExceptionInfo *exception)
713 % A description of each parameter follows:
715 % o image: the image.
717 % o exception: return any errors or warnings in this structure.
720 MagickExport ImageView *NewImageView(Image *image,ExceptionInfo *exception)
725 assert(image != (Image *) NULL);
726 assert(image->signature == MagickSignature);
727 image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
728 if (image_view == (ImageView *) NULL)
729 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
730 (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
731 image_view->description=ConstantString("ImageView");
732 image_view->image=image;
733 image_view->view=AcquireVirtualCacheView(image_view->image,exception);
734 image_view->extent.width=image->columns;
735 image_view->extent.height=image->rows;
736 image_view->extent.x=0;
737 image_view->extent.y=0;
738 image_view->exception=AcquireExceptionInfo();
739 image_view->debug=IsEventLogging();
740 image_view->signature=MagickSignature;
745 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
749 % N e w I m a g e V i e w R e g i o n %
753 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
755 % NewImageViewRegion() returns a image view required for all other methods
756 % in the Image View API.
758 % The format of the NewImageViewRegion method is:
760 % ImageView *NewImageViewRegion(MagickCore *wand,const ssize_t x,
761 % const ssize_t y,const size_t width,const size_t height,
762 % ExceptionInfo *exception)
764 % A description of each parameter follows:
766 % o wand: the magick wand.
768 % o x,y,columns,rows: These values define the perimeter of a extent of
771 % o exception: return any errors or warnings in this structure.
774 MagickExport ImageView *NewImageViewRegion(Image *image,const ssize_t x,
775 const ssize_t y,const size_t width,const size_t height,
776 ExceptionInfo *exception)
781 assert(image != (Image *) NULL);
782 assert(image->signature == MagickSignature);
783 image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
784 if (image_view == (ImageView *) NULL)
785 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
786 (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
787 image_view->description=ConstantString("ImageView");
788 image_view->view=AcquireVirtualCacheView(image_view->image,exception);
789 image_view->image=image;
790 image_view->extent.width=width;
791 image_view->extent.height=height;
792 image_view->extent.x=x;
793 image_view->extent.y=y;
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)
889 #if defined(MAGICKCORE_OPENMP_SUPPORT)
898 assert(destination != (ImageView *) NULL);
899 assert(destination->signature == MagickSignature);
900 if (set == (SetImageViewMethod) NULL)
902 destination_image=destination->image;
903 status=SetImageStorageClass(destination_image,DirectClass,
904 destination->exception);
905 if (status == MagickFalse)
909 #if defined(MAGICKCORE_OPENMP_SUPPORT)
910 height=destination->extent.height-destination->extent.y;
911 width=destination->extent.width-destination->extent.x;
912 #pragma omp parallel for schedule(static) shared(progress,status) \
913 dynamic_number_threads(destination_image,width,height,1)
915 for (y=destination->extent.y; y < (ssize_t) destination->extent.height; y++)
918 id = GetOpenMPThreadId();
926 if (status == MagickFalse)
928 pixels=GetCacheViewAuthenticPixels(destination->view,destination->extent.x,
929 y,destination->extent.width,1,destination->exception);
930 if (pixels == (Quantum *) NULL)
935 if (set(destination,y,id,context) == MagickFalse)
937 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
938 if (sync == MagickFalse)
940 if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
945 #if defined(MAGICKCORE_OPENMP_SUPPORT)
946 #pragma omp critical (MagickCore_SetImageViewIterator)
948 proceed=SetImageProgress(destination_image,destination->description,
949 progress++,destination->extent.height);
950 if (proceed == MagickFalse)
958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
962 % 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 %
966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
968 % TransferImageViewIterator() iterates over two image views in parallel and
969 % calls your transfer method for each scanline of the view. The source pixel
970 % extent is not confined to the image canvas-- that is you can include
971 % negative offsets or widths or heights that exceed the image dimension.
972 % However, the destination image view is confined to the image canvas-- that
973 % is no negative offsets or widths or heights that exceed the image dimension
976 % The callback signature is:
978 % MagickBooleanType TransferImageViewMethod(const ImageView *source,
979 % ImageView *destination,const ssize_t y,const int thread_id,
982 % Use this pragma if the view is not single threaded:
984 % #pragma omp critical
986 % to define a section of code in your callback transfer method that must be
987 % executed by a single thread at a time.
989 % The format of the TransferImageViewIterator method is:
991 % MagickBooleanType TransferImageViewIterator(ImageView *source,
992 % ImageView *destination,TransferImageViewMethod transfer,void *context)
994 % A description of each parameter follows:
996 % o source: the source image view.
998 % o destination: the destination image view.
1000 % o transfer: the transfer callback method.
1002 % o context: the user defined context.
1005 MagickExport MagickBooleanType TransferImageViewIterator(ImageView *source,
1006 ImageView *destination,TransferImageViewMethod transfer,void *context)
1018 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1027 assert(source != (ImageView *) NULL);
1028 assert(source->signature == MagickSignature);
1029 if (transfer == (TransferImageViewMethod) NULL)
1030 return(MagickFalse);
1031 source_image=source->image;
1032 destination_image=destination->image;
1033 status=SetImageStorageClass(destination_image,DirectClass,
1034 destination->exception);
1035 if (status == MagickFalse)
1036 return(MagickFalse);
1039 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1040 height=source->extent.height-source->extent.y;
1041 width=source->extent.width-source->extent.x;
1042 #pragma omp parallel for schedule(static) shared(progress,status) \
1043 dynamic_number_threads(source_image,width,height,1)
1045 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1048 id = GetOpenMPThreadId();
1053 register const Quantum
1057 *restrict destination_pixels;
1059 if (status == MagickFalse)
1061 pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
1062 source->extent.width,1,source->exception);
1063 if (pixels == (const Quantum *) NULL)
1068 destination_pixels=GetCacheViewAuthenticPixels(destination->view,
1069 destination->extent.x,y,destination->extent.width,1,
1070 destination->exception);
1071 if (destination_pixels == (Quantum *) NULL)
1076 if (transfer(source,destination,y,id,context) == MagickFalse)
1078 sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
1079 if (sync == MagickFalse)
1081 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1086 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1087 #pragma omp critical (MagickCore_TransferImageViewIterator)
1089 proceed=SetImageProgress(source_image,source->description,progress++,
1090 source->extent.height);
1091 if (proceed == MagickFalse)
1099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1103 % U p d a t e I m a g e V i e w I t e r a t o r %
1107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1109 % UpdateImageViewIterator() iterates over the image view in parallel and calls
1110 % your update method for each scanline of the view. The pixel extent is
1111 % confined to the image canvas-- that is no negative offsets or widths or
1112 % heights that exceed the image dimension are permitted. Updates to pixels
1113 % in your callback are automagically synced back to the image.
1115 % The callback signature is:
1117 % MagickBooleanType UpdateImageViewMethod(ImageView *source,
1118 % const ssize_t y,const int thread_id,void *context)
1120 % Use this pragma if the view is not single threaded:
1122 % #pragma omp critical
1124 % to define a section of code in your callback update method that must be
1125 % executed by a single thread at a time.
1127 % The format of the UpdateImageViewIterator method is:
1129 % MagickBooleanType UpdateImageViewIterator(ImageView *source,
1130 % UpdateImageViewMethod update,void *context)
1132 % A description of each parameter follows:
1134 % o source: the source image view.
1136 % o update: the update callback method.
1138 % o context: the user defined context.
1141 MagickExport MagickBooleanType UpdateImageViewIterator(ImageView *source,
1142 UpdateImageViewMethod update,void *context)
1153 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1162 assert(source != (ImageView *) NULL);
1163 assert(source->signature == MagickSignature);
1164 if (update == (UpdateImageViewMethod) NULL)
1165 return(MagickFalse);
1166 source_image=source->image;
1167 status=SetImageStorageClass(source_image,DirectClass,source->exception);
1168 if (status == MagickFalse)
1169 return(MagickFalse);
1172 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1173 height=source->extent.height-source->extent.y;
1174 width=source->extent.width-source->extent.x;
1175 #pragma omp parallel for schedule(static) shared(progress,status) \
1176 dynamic_number_threads(source_image,width,height,1)
1178 for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1181 id = GetOpenMPThreadId();
1186 if (status == MagickFalse)
1188 pixels=GetCacheViewAuthenticPixels(source->view,source->extent.x,y,
1189 source->extent.width,1,source->exception);
1190 if (pixels == (Quantum *) NULL)
1195 if (update(source,y,id,context) == MagickFalse)
1197 status=SyncCacheViewAuthenticPixels(source->view,source->exception);
1198 if (status == MagickFalse)
1200 if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1205 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1206 #pragma omp critical (MagickCore_UpdateImageViewIterator)
1208 proceed=SetImageProgress(source_image,source->description,progress++,
1209 source->extent.height);
1210 if (proceed == MagickFalse)