]> granicus.if.org Git - imagemagick/blob - MagickCore/image-view.c
(no commit message)
[imagemagick] / MagickCore / image-view.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                     IIIII  M   M   AAA    GGGG  EEEEE                       %
6 %                       I    MM MM  A   A  G      E                           %
7 %                       I    M M M  AAAAA  G  GG  EEE                         %
8 %                       I    M   M  A   A  G   G  E                           %
9 %                     IIIII  M   M  A   A   GGGG  EEEEE                       %
10 %                                                                             %
11 %                         V   V  IIIII  EEEEE  W   W                          %
12 %                         V   V    I    E      W   W                          %
13 %                         V   V    I    EEE    W W W                          %
14 %                          V V     I    E      WW WW                          %
15 %                           V    IIIII  EEEEE  W   W                          %
16 %                                                                             %
17 %                                                                             %
18 %                       MagickCore Image View Methods                         %
19 %                                                                             %
20 %                              Software Design                                %
21 %                                John Cristy                                  %
22 %                                March 2003                                   %
23 %                                                                             %
24 %                                                                             %
25 %  Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization      %
26 %  dedicated to making software imaging solutions freely available.           %
27 %                                                                             %
28 %  You may not use this file except in compliance with the License.  You may  %
29 %  obtain a copy of the License at                                            %
30 %                                                                             %
31 %    http://www.imagemagick.org/script/license.php                            %
32 %                                                                             %
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.                                             %
38 %                                                                             %
39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
40 %
41 %
42 %
43 */
44 \f
45 /*
46   Include declarations.
47 */
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"
53 \f
54 /*
55   Typedef declarations.
56 */
57 struct _ImageView
58 {
59   char
60     *description;
61
62   RectangleInfo
63     extent;
64
65   Image
66     *image;
67
68   CacheView
69     *view;
70
71   ExceptionInfo
72     *exception;
73
74   MagickBooleanType
75     debug;
76
77   size_t
78     signature;
79 };
80 \f
81 /*
82 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83 %                                                                             %
84 %                                                                             %
85 %                                                                             %
86 %   C l o n e I m a g e V i e w                                               %
87 %                                                                             %
88 %                                                                             %
89 %                                                                             %
90 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
91 %
92 %  CloneImageView() makes a copy of the specified image view.
93 %
94 %  The format of the CloneImageView method is:
95 %
96 %      ImageView *CloneImageView(const ImageView *image_view)
97 %
98 %  A description of each parameter follows:
99 %
100 %    o image_view: the image view.
101 %
102 */
103 MagickExport ImageView *CloneImageView(const ImageView *image_view)
104 {
105   ImageView
106     *clone_view;
107
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;
121   return(clone_view);
122 }
123 \f
124 /*
125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126 %                                                                             %
127 %                                                                             %
128 %                                                                             %
129 %   D e s t r o y I m a g e V i e w                                           %
130 %                                                                             %
131 %                                                                             %
132 %                                                                             %
133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134 %
135 %  DestroyImageView() deallocates memory associated with a image view.
136 %
137 %  The format of the DestroyImageView method is:
138 %
139 %      ImageView *DestroyImageView(ImageView *image_view)
140 %
141 %  A description of each parameter follows:
142 %
143 %    o image_view: the image view.
144 %
145 */
146 MagickExport ImageView *DestroyImageView(ImageView *image_view)
147 {
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);
156   return(image_view);
157 }
158 \f
159 /*
160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161 %                                                                             %
162 %                                                                             %
163 %                                                                             %
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             %
165 %                                                                             %
166 %                                                                             %
167 %                                                                             %
168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169 %
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.
177 %
178 %  The callback signature is:
179 %
180 %      MagickBooleanType DuplexTransferImageViewMethod(const ImageView *source,
181 %        const ImageView *duplex,ImageView *destination,const ssize_t y,
182 %        const int thread_id,void *context)
183 %
184 %  Use this pragma if the view is not single threaded:
185 %
186 %    #pragma omp critical
187 %
188 %  to define a section of code in your callback transfer method that must be
189 %  executed by a single thread at a time.
190 %
191 %  The format of the DuplexTransferImageViewIterator method is:
192 %
193 %      MagickBooleanType DuplexTransferImageViewIterator(ImageView *source,
194 %        ImageView *duplex,ImageView *destination,
195 %        DuplexTransferImageViewMethod transfer,void *context)
196 %
197 %  A description of each parameter follows:
198 %
199 %    o source: the source image view.
200 %
201 %    o duplex: the duplex image view.
202 %
203 %    o destination: the destination image view.
204 %
205 %    o transfer: the transfer callback method.
206 %
207 %    o context: the user defined context.
208 %
209 */
210 MagickExport MagickBooleanType DuplexTransferImageViewIterator(
211   ImageView *source,ImageView *duplex,ImageView *destination,
212   DuplexTransferImageViewMethod transfer,void *context)
213 {
214   Image
215     *destination_image,
216     *source_image;
217
218   MagickBooleanType
219     status;
220
221   MagickOffsetType
222     progress;
223
224 #if defined(MAGICKCORE_OPENMP_SUPPORT)
225   size_t
226     height,
227     width;
228 #endif
229
230   ssize_t
231     y;
232
233   assert(source != (ImageView *) NULL);
234   assert(source->signature == MagickSignature);
235   if (transfer == (DuplexTransferImageViewMethod) NULL)
236     return(MagickFalse);
237   source_image=source->image;
238   destination_image=destination->image;
239   status=SetImageStorageClass(destination_image,DirectClass,
240     destination->exception);
241   if (status == MagickFalse)
242     return(MagickFalse);
243   status=MagickTrue;
244   progress=0;
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,4) shared(progress,status) \
249     dynamic_number_threads(source_image,width,height,1)
250 #endif
251   for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
252   {
253     const int
254       id = GetOpenMPThreadId();
255
256     MagickBooleanType
257       sync;
258
259     register const Quantum
260       *restrict duplex_pixels,
261       *restrict pixels;
262
263     register Quantum
264       *restrict destination_pixels;
265
266     if (status == MagickFalse)
267       continue;
268     pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
269       source->extent.width,1,source->exception);
270     if (pixels == (const Quantum *) NULL)
271       {
272         status=MagickFalse;
273         continue;
274       }
275     duplex_pixels=GetCacheViewVirtualPixels(duplex->view,duplex->extent.x,y,
276       duplex->extent.width,1,duplex->exception);
277     if (duplex_pixels == (const Quantum *) NULL)
278       {
279         status=MagickFalse;
280         continue;
281       }
282     destination_pixels=GetCacheViewAuthenticPixels(destination->view,
283       destination->extent.x,y,destination->extent.width,1,
284       destination->exception);
285     if (destination_pixels == (Quantum *) NULL)
286       {
287         status=MagickFalse;
288         continue;
289       }
290     if (transfer(source,duplex,destination,y,id,context) == MagickFalse)
291       status=MagickFalse;
292     sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
293     if (sync == MagickFalse)
294       status=MagickFalse;
295     if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
296       {
297         MagickBooleanType
298           proceed;
299
300 #if defined(MAGICKCORE_OPENMP_SUPPORT)
301         #pragma omp critical (MagickCore_DuplexTransferImageViewIterator)
302 #endif
303         proceed=SetImageProgress(source_image,source->description,progress++,
304           source->extent.height);
305         if (proceed == MagickFalse)
306           status=MagickFalse;
307       }
308   }
309   return(status);
310 }
311 \f
312 /*
313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
314 %                                                                             %
315 %                                                                             %
316 %                                                                             %
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           %
318 %                                                                             %
319 %                                                                             %
320 %                                                                             %
321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
322 %
323 %  GetImageViewAuthenticMetacontent() returns the image view authentic
324 %  meta-content.
325 %
326 %  The format of the GetImageViewAuthenticPixels method is:
327 %
328 %      void *GetImageViewAuthenticMetacontent(
329 %        const ImageView *image_view)
330 %
331 %  A description of each parameter follows:
332 %
333 %    o image_view: the image view.
334 %
335 */
336 MagickExport void *GetImageViewAuthenticMetacontent(
337   const ImageView *image_view)
338 {
339   assert(image_view != (ImageView *) NULL);
340   assert(image_view->signature == MagickSignature);
341   return(GetCacheViewAuthenticMetacontent(image_view->view));
342 }
343 \f
344 /*
345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
346 %                                                                             %
347 %                                                                             %
348 %                                                                             %
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                     %
350 %                                                                             %
351 %                                                                             %
352 %                                                                             %
353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
354 %
355 %  GetImageViewAuthenticPixels() returns the image view authentic pixels.
356 %
357 %  The format of the GetImageViewAuthenticPixels method is:
358 %
359 %      Quantum *GetImageViewAuthenticPixels(const ImageView *image_view)
360 %
361 %  A description of each parameter follows:
362 %
363 %    o image_view: the image view.
364 %
365 */
366 MagickExport Quantum *GetImageViewAuthenticPixels(
367   const ImageView *image_view)
368 {
369   assert(image_view != (ImageView *) NULL);
370   assert(image_view->signature == MagickSignature);
371   return(GetCacheViewAuthenticPixelQueue(image_view->view));
372 }
373 \f
374 /*
375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376 %                                                                             %
377 %                                                                             %
378 %                                                                             %
379 %   G e t I m a g e V i e w E x c e p t i o n                                 %
380 %                                                                             %
381 %                                                                             %
382 %                                                                             %
383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384 %
385 %  GetImageViewException() returns the severity, reason, and description of any
386 %  error that occurs when utilizing a image view.
387 %
388 %  The format of the GetImageViewException method is:
389 %
390 %      char *GetImageViewException(const PixelImage *image_view,
391 %        ExceptionType *severity)
392 %
393 %  A description of each parameter follows:
394 %
395 %    o image_view: the pixel image_view.
396 %
397 %    o severity: the severity of the error is returned here.
398 %
399 */
400 MagickExport char *GetImageViewException(const ImageView *image_view,
401   ExceptionType *severity)
402 {
403   char
404     *description;
405
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");
414   *description='\0';
415   if (image_view->exception->reason != (char *) NULL)
416     (void) CopyMagickString(description,GetLocaleExceptionMessage(
417       image_view->exception->severity,image_view->exception->reason),
418         MaxTextExtent);
419   if (image_view->exception->description != (char *) NULL)
420     {
421       (void) ConcatenateMagickString(description," (",MaxTextExtent);
422       (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
423         image_view->exception->severity,image_view->exception->description),
424         MaxTextExtent);
425       (void) ConcatenateMagickString(description,")",MaxTextExtent);
426     }
427   return(description);
428 }
429 \f
430 /*
431 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
432 %                                                                             %
433 %                                                                             %
434 %                                                                             %
435 %   G e t I m a g e V i e w E x t e n t                                       %
436 %                                                                             %
437 %                                                                             %
438 %                                                                             %
439 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
440 %
441 %  GetImageViewExtent() returns the image view extent.
442 %
443 %  The format of the GetImageViewExtent method is:
444 %
445 %      RectangleInfo GetImageViewExtent(const ImageView *image_view)
446 %
447 %  A description of each parameter follows:
448 %
449 %    o image_view: the image view.
450 %
451 */
452 MagickExport RectangleInfo GetImageViewExtent(const ImageView *image_view)
453 {
454   assert(image_view != (ImageView *) NULL);
455   assert(image_view->signature == MagickSignature);
456   return(image_view->extent);
457 }
458 \f
459 /*
460 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
461 %                                                                             %
462 %                                                                             %
463 %                                                                             %
464 %   G e t I m a g e V i e w I m a g e                                         %
465 %                                                                             %
466 %                                                                             %
467 %                                                                             %
468 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
469 %
470 %  GetImageViewImage() returns the image associated with the image view.
471 %
472 %  The format of the GetImageViewImage method is:
473 %
474 %      MagickCore *GetImageViewImage(const ImageView *image_view)
475 %
476 %  A description of each parameter follows:
477 %
478 %    o image_view: the image view.
479 %
480 */
481 MagickExport Image *GetImageViewImage(const ImageView *image_view)
482 {
483   assert(image_view != (ImageView *) NULL);
484   assert(image_view->signature == MagickSignature);
485   return(image_view->image);
486 }
487 \f
488 /*
489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
490 %                                                                             %
491 %                                                                             %
492 %                                                                             %
493 %   G e t I m a g e V i e w I t e r a t o r                                   %
494 %                                                                             %
495 %                                                                             %
496 %                                                                             %
497 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
498 %
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.
504 %
505 %  The callback signature is:
506 %
507 %      MagickBooleanType GetImageViewMethod(const ImageView *source,
508 %        const ssize_t y,const int thread_id,void *context)
509 %
510 %  Use this pragma if the view is not single threaded:
511 %
512 %    #pragma omp critical
513 %
514 %  to define a section of code in your callback get method that must be
515 %  executed by a single thread at a time.
516 %
517 %  The format of the GetImageViewIterator method is:
518 %
519 %      MagickBooleanType GetImageViewIterator(ImageView *source,
520 %        GetImageViewMethod get,void *context)
521 %
522 %  A description of each parameter follows:
523 %
524 %    o source: the source image view.
525 %
526 %    o get: the get callback method.
527 %
528 %    o context: the user defined context.
529 %
530 */
531 MagickExport MagickBooleanType GetImageViewIterator(ImageView *source,
532   GetImageViewMethod get,void *context)
533 {
534   Image
535     *source_image;
536
537   MagickBooleanType
538     status;
539
540   MagickOffsetType
541     progress;
542
543 #if defined(MAGICKCORE_OPENMP_SUPPORT)
544   size_t
545     height,
546     width;
547 #endif
548
549   ssize_t
550     y;
551
552   assert(source != (ImageView *) NULL);
553   assert(source->signature == MagickSignature);
554   if (get == (GetImageViewMethod) NULL)
555     return(MagickFalse);
556   source_image=source->image;
557   status=MagickTrue;
558   progress=0;
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,4) shared(progress,status) \
563     dynamic_number_threads(source_image,width,height,1)
564 #endif
565   for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
566   {
567     const int
568       id = GetOpenMPThreadId();
569
570     register const Quantum
571       *pixels;
572
573     if (status == MagickFalse)
574       continue;
575     pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
576       source->extent.width,1,source->exception);
577     if (pixels == (const Quantum *) NULL)
578       {
579         status=MagickFalse;
580         continue;
581       }
582     if (get(source,y,id,context) == MagickFalse)
583       status=MagickFalse;
584     if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
585       {
586         MagickBooleanType
587           proceed;
588
589 #if defined(MAGICKCORE_OPENMP_SUPPORT)
590         #pragma omp critical (MagickCore_GetImageViewIterator)
591 #endif
592         proceed=SetImageProgress(source_image,source->description,progress++,
593           source->extent.height);
594         if (proceed == MagickFalse)
595           status=MagickFalse;
596       }
597   }
598   return(status);
599 }
600 \f
601 /*
602 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
603 %                                                                             %
604 %                                                                             %
605 %                                                                             %
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     %
607 %                                                                             %
608 %                                                                             %
609 %                                                                             %
610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611 %
612 %  GetImageViewVirtualMetacontent() returns the image view virtual
613 %  meta-content.
614 %
615 %  The format of the GetImageViewVirtualMetacontent method is:
616 %
617 %      const void *GetImageViewVirtualMetacontent(
618 %        const ImageView *image_view)
619 %
620 %  A description of each parameter follows:
621 %
622 %    o image_view: the image view.
623 %
624 */
625 MagickExport const void *GetImageViewVirtualMetacontent(
626   const ImageView *image_view)
627 {
628   assert(image_view != (ImageView *) NULL);
629   assert(image_view->signature == MagickSignature);
630   return(GetCacheViewVirtualMetacontent(image_view->view));
631 }
632 \f
633 /*
634 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
635 %                                                                             %
636 %                                                                             %
637 %                                                                             %
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                         %
639 %                                                                             %
640 %                                                                             %
641 %                                                                             %
642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
643 %
644 %  GetImageViewVirtualPixels() returns the image view virtual pixels.
645 %
646 %  The format of the GetImageViewVirtualPixels method is:
647 %
648 %      const Quantum *GetImageViewVirtualPixels(const ImageView *image_view)
649 %
650 %  A description of each parameter follows:
651 %
652 %    o image_view: the image view.
653 %
654 */
655 MagickExport const Quantum *GetImageViewVirtualPixels(
656   const ImageView *image_view)
657 {
658   assert(image_view != (ImageView *) NULL);
659   assert(image_view->signature == MagickSignature);
660   return(GetCacheViewVirtualPixelQueue(image_view->view));
661 }
662 \f
663 /*
664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
665 %                                                                             %
666 %                                                                             %
667 %                                                                             %
668 %   I s I m a g e V i e w                                                     %
669 %                                                                             %
670 %                                                                             %
671 %                                                                             %
672 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
673 %
674 %  IsImageView() returns MagickTrue if the the parameter is verified as a image
675 %  view object.
676 %
677 %  The format of the IsImageView method is:
678 %
679 %      MagickBooleanType IsImageView(const ImageView *image_view)
680 %
681 %  A description of each parameter follows:
682 %
683 %    o image_view: the image view.
684 %
685 */
686 MagickExport MagickBooleanType IsImageView(const ImageView *image_view)
687 {
688   if (image_view == (const ImageView *) NULL)
689     return(MagickFalse);
690   if (image_view->signature != MagickSignature)
691     return(MagickFalse);
692   return(MagickTrue);
693 }
694 \f
695 /*
696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
697 %                                                                             %
698 %                                                                             %
699 %                                                                             %
700 %   N e w I m a g e V i e w                                                   %
701 %                                                                             %
702 %                                                                             %
703 %                                                                             %
704 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
705 %
706 %  NewImageView() returns a image view required for all other methods in the
707 %  Image View API.
708 %
709 %  The format of the NewImageView method is:
710 %
711 %      ImageView *NewImageView(MagickCore *wand,ExceptionInfo *exception)
712 %
713 %  A description of each parameter follows:
714 %
715 %    o image: the image.
716 %
717 %    o exception: return any errors or warnings in this structure.
718 %
719 */
720 MagickExport ImageView *NewImageView(Image *image,ExceptionInfo *exception)
721 {
722   ImageView
723     *image_view;
724
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;
741   return(image_view);
742 }
743 \f
744 /*
745 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
746 %                                                                             %
747 %                                                                             %
748 %                                                                             %
749 %   N e w I m a g e V i e w R e g i o n                                       %
750 %                                                                             %
751 %                                                                             %
752 %                                                                             %
753 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
754 %
755 %  NewImageViewRegion() returns a image view required for all other methods
756 %  in the Image View API.
757 %
758 %  The format of the NewImageViewRegion method is:
759 %
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)
763 %
764 %  A description of each parameter follows:
765 %
766 %    o wand: the magick wand.
767 %
768 %    o x,y,columns,rows:  These values define the perimeter of a extent of
769 %      pixel_wands view.
770 %
771 %    o exception: return any errors or warnings in this structure.
772 %
773 */
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)
777 {
778   ImageView
779     *image_view;
780
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;
797   return(image_view);
798 }
799 \f
800 /*
801 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802 %                                                                             %
803 %                                                                             %
804 %                                                                             %
805 %   S e t I m a g e V i e w D e s c r i p t i o n                             %
806 %                                                                             %
807 %                                                                             %
808 %                                                                             %
809 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
810 %
811 %  SetImageViewDescription() associates a description with an image view.
812 %
813 %  The format of the SetImageViewDescription method is:
814 %
815 %      void SetImageViewDescription(ImageView *image_view,
816 %        const char *description)
817 %
818 %  A description of each parameter follows:
819 %
820 %    o image_view: the image view.
821 %
822 %    o description: the image view description.
823 %
824 */
825 MagickExport void SetImageViewDescription(ImageView *image_view,
826   const char *description)
827 {
828   assert(image_view != (ImageView *) NULL);
829   assert(image_view->signature == MagickSignature);
830   image_view->description=ConstantString(description);
831 }
832 \f
833 /*
834 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
835 %                                                                             %
836 %                                                                             %
837 %                                                                             %
838 %   S e t I m a g e V i e w I t e r a t o r                                   %
839 %                                                                             %
840 %                                                                             %
841 %                                                                             %
842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
843 %
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.
850 %
851 %  The callback signature is:
852 %
853 %      MagickBooleanType SetImageViewMethod(ImageView *destination,
854 %        const ssize_t y,const int thread_id,void *context)
855 %
856 %  Use this pragma if the view is not single threaded:
857 %
858 %    #pragma omp critical
859 %
860 %  to define a section of code in your callback set method that must be
861 %  executed by a single thread at a time.
862 %
863 %  The format of the SetImageViewIterator method is:
864 %
865 %      MagickBooleanType SetImageViewIterator(ImageView *destination,
866 %        SetImageViewMethod set,void *context)
867 %
868 %  A description of each parameter follows:
869 %
870 %    o destination: the image view.
871 %
872 %    o set: the set callback method.
873 %
874 %    o context: the user defined context.
875 %
876 */
877 MagickExport MagickBooleanType SetImageViewIterator(ImageView *destination,
878   SetImageViewMethod set,void *context)
879 {
880   Image
881     *destination_image;
882
883   MagickBooleanType
884     status;
885
886   MagickOffsetType
887     progress;
888
889 #if defined(MAGICKCORE_OPENMP_SUPPORT)
890   size_t
891     height,
892     width;
893 #endif
894
895   ssize_t
896     y;
897
898   assert(destination != (ImageView *) NULL);
899   assert(destination->signature == MagickSignature);
900   if (set == (SetImageViewMethod) NULL)
901     return(MagickFalse);
902   destination_image=destination->image;
903   status=SetImageStorageClass(destination_image,DirectClass,
904     destination->exception);
905   if (status == MagickFalse)
906     return(MagickFalse);
907   status=MagickTrue;
908   progress=0;
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,4) shared(progress,status) \
913     dynamic_number_threads(destination_image,width,height,1)
914 #endif
915   for (y=destination->extent.y; y < (ssize_t) destination->extent.height; y++)
916   {
917     const int
918       id = GetOpenMPThreadId();
919
920     MagickBooleanType
921       sync;
922
923     register Quantum
924       *restrict pixels;
925
926     if (status == MagickFalse)
927       continue;
928     pixels=GetCacheViewAuthenticPixels(destination->view,destination->extent.x,
929       y,destination->extent.width,1,destination->exception);
930     if (pixels == (Quantum *) NULL)
931       {
932         status=MagickFalse;
933         continue;
934       }
935     if (set(destination,y,id,context) == MagickFalse)
936       status=MagickFalse;
937     sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
938     if (sync == MagickFalse)
939       status=MagickFalse;
940     if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
941       {
942         MagickBooleanType
943           proceed;
944
945 #if defined(MAGICKCORE_OPENMP_SUPPORT)
946         #pragma omp critical (MagickCore_SetImageViewIterator)
947 #endif
948         proceed=SetImageProgress(destination_image,destination->description,
949           progress++,destination->extent.height);
950         if (proceed == MagickFalse)
951           status=MagickFalse;
952       }
953   }
954   return(status);
955 }
956 \f
957 /*
958 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
959 %                                                                             %
960 %                                                                             %
961 %                                                                             %
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                         %
963 %                                                                             %
964 %                                                                             %
965 %                                                                             %
966 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
967 %
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
974 %  are permitted.
975 %
976 %  The callback signature is:
977 %
978 %      MagickBooleanType TransferImageViewMethod(const ImageView *source,
979 %        ImageView *destination,const ssize_t y,const int thread_id,
980 %        void *context)
981 %
982 %  Use this pragma if the view is not single threaded:
983 %
984 %    #pragma omp critical
985 %
986 %  to define a section of code in your callback transfer method that must be
987 %  executed by a single thread at a time.
988 %
989 %  The format of the TransferImageViewIterator method is:
990 %
991 %      MagickBooleanType TransferImageViewIterator(ImageView *source,
992 %        ImageView *destination,TransferImageViewMethod transfer,void *context)
993 %
994 %  A description of each parameter follows:
995 %
996 %    o source: the source image view.
997 %
998 %    o destination: the destination image view.
999 %
1000 %    o transfer: the transfer callback method.
1001 %
1002 %    o context: the user defined context.
1003 %
1004 */
1005 MagickExport MagickBooleanType TransferImageViewIterator(ImageView *source,
1006   ImageView *destination,TransferImageViewMethod transfer,void *context)
1007 {
1008   Image
1009     *destination_image,
1010     *source_image;
1011
1012   MagickBooleanType
1013     status;
1014
1015   MagickOffsetType
1016     progress;
1017
1018 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1019   size_t
1020     height,
1021     width;
1022 #endif
1023
1024   ssize_t
1025     y;
1026
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);
1037   status=MagickTrue;
1038   progress=0;
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,4) shared(progress,status) \
1043     dynamic_number_threads(source_image,width,height,1)
1044 #endif
1045   for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1046   {
1047     const int
1048       id = GetOpenMPThreadId();
1049
1050     MagickBooleanType
1051       sync;
1052
1053     register const Quantum
1054       *restrict pixels;
1055
1056     register Quantum
1057       *restrict destination_pixels;
1058
1059     if (status == MagickFalse)
1060       continue;
1061     pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
1062       source->extent.width,1,source->exception);
1063     if (pixels == (const Quantum *) NULL)
1064       {
1065         status=MagickFalse;
1066         continue;
1067       }
1068     destination_pixels=GetCacheViewAuthenticPixels(destination->view,
1069       destination->extent.x,y,destination->extent.width,1,
1070       destination->exception);
1071     if (destination_pixels == (Quantum *) NULL)
1072       {
1073         status=MagickFalse;
1074         continue;
1075       }
1076     if (transfer(source,destination,y,id,context) == MagickFalse)
1077       status=MagickFalse;
1078     sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
1079     if (sync == MagickFalse)
1080       status=MagickFalse;
1081     if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1082       {
1083         MagickBooleanType
1084           proceed;
1085
1086 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1087         #pragma omp critical (MagickCore_TransferImageViewIterator)
1088 #endif
1089         proceed=SetImageProgress(source_image,source->description,progress++,
1090           source->extent.height);
1091         if (proceed == MagickFalse)
1092           status=MagickFalse;
1093       }
1094   }
1095   return(status);
1096 }
1097 \f
1098 /*
1099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1100 %                                                                             %
1101 %                                                                             %
1102 %                                                                             %
1103 %   U p d a t e I m a g e V i e w I t e r a t o r                             %
1104 %                                                                             %
1105 %                                                                             %
1106 %                                                                             %
1107 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1108 %
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.
1114 %
1115 %  The callback signature is:
1116 %
1117 %      MagickBooleanType UpdateImageViewMethod(ImageView *source,
1118 %        const ssize_t y,const int thread_id,void *context)
1119 %
1120 %  Use this pragma if the view is not single threaded:
1121 %
1122 %    #pragma omp critical
1123 %
1124 %  to define a section of code in your callback update method that must be
1125 %  executed by a single thread at a time.
1126 %
1127 %  The format of the UpdateImageViewIterator method is:
1128 %
1129 %      MagickBooleanType UpdateImageViewIterator(ImageView *source,
1130 %        UpdateImageViewMethod update,void *context)
1131 %
1132 %  A description of each parameter follows:
1133 %
1134 %    o source: the source image view.
1135 %
1136 %    o update: the update callback method.
1137 %
1138 %    o context: the user defined context.
1139 %
1140 */
1141 MagickExport MagickBooleanType UpdateImageViewIterator(ImageView *source,
1142   UpdateImageViewMethod update,void *context)
1143 {
1144   Image
1145     *source_image;
1146
1147   MagickBooleanType
1148     status;
1149
1150   MagickOffsetType
1151     progress;
1152
1153 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1154   size_t
1155     height,
1156     width;
1157 #endif
1158
1159   ssize_t
1160     y;
1161
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);
1170   status=MagickTrue;
1171   progress=0;
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,4) shared(progress,status) \
1176     dynamic_number_threads(source_image,width,height,1)
1177 #endif
1178   for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1179   {
1180     const int
1181       id = GetOpenMPThreadId();
1182
1183     register Quantum
1184       *restrict pixels;
1185
1186     if (status == MagickFalse)
1187       continue;
1188     pixels=GetCacheViewAuthenticPixels(source->view,source->extent.x,y,
1189       source->extent.width,1,source->exception);
1190     if (pixels == (Quantum *) NULL)
1191       {
1192         status=MagickFalse;
1193         continue;
1194       }
1195     if (update(source,y,id,context) == MagickFalse)
1196       status=MagickFalse;
1197     status=SyncCacheViewAuthenticPixels(source->view,source->exception);
1198     if (status == MagickFalse)
1199       status=MagickFalse;
1200     if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1201       {
1202         MagickBooleanType
1203           proceed;
1204
1205 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1206         #pragma omp critical (MagickCore_UpdateImageViewIterator)
1207 #endif
1208         proceed=SetImageProgress(source_image,source->description,progress++,
1209           source->extent.height);
1210         if (proceed == MagickFalse)
1211           status=MagickFalse;
1212       }
1213   }
1214   return(status);
1215 }