]> granicus.if.org Git - imagemagick/blob - MagickCore/image-view.c
Add RobidouxSharp filter depreciate Bessel Filter and Static Gravity
[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-2012 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   size_t
72     number_threads;
73
74   ExceptionInfo
75     *exception;
76
77   MagickBooleanType
78     debug;
79
80   size_t
81     signature;
82 };
83 \f
84 /*
85 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
86 %                                                                             %
87 %                                                                             %
88 %                                                                             %
89 %   C l o n e I m a g e V i e w                                               %
90 %                                                                             %
91 %                                                                             %
92 %                                                                             %
93 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94 %
95 %  CloneImageView() makes a copy of the specified image view.
96 %
97 %  The format of the CloneImageView method is:
98 %
99 %      ImageView *CloneImageView(const ImageView *image_view)
100 %
101 %  A description of each parameter follows:
102 %
103 %    o image_view: the image view.
104 %
105 */
106 MagickExport ImageView *CloneImageView(const ImageView *image_view)
107 {
108   ImageView
109     *clone_view;
110
111   assert(image_view != (ImageView *) NULL);
112   assert(image_view->signature == MagickSignature);
113   clone_view=(ImageView *) AcquireMagickMemory(sizeof(*clone_view));
114   if (clone_view == (ImageView *) NULL)
115     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
116   (void) ResetMagickMemory(clone_view,0,sizeof(*clone_view));
117   clone_view->description=ConstantString(image_view->description);
118   clone_view->extent=image_view->extent;
119   clone_view->view=CloneCacheView(image_view->view);
120   clone_view->number_threads=image_view->number_threads;
121   clone_view->exception=AcquireExceptionInfo();
122   InheritException(clone_view->exception,image_view->exception);
123   clone_view->debug=image_view->debug;
124   clone_view->signature=MagickSignature;
125   return(clone_view);
126 }
127 \f
128 /*
129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130 %                                                                             %
131 %                                                                             %
132 %                                                                             %
133 %   D e s t r o y I m a g e V i e w                                           %
134 %                                                                             %
135 %                                                                             %
136 %                                                                             %
137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138 %
139 %  DestroyImageView() deallocates memory associated with a image view.
140 %
141 %  The format of the DestroyImageView method is:
142 %
143 %      ImageView *DestroyImageView(ImageView *image_view)
144 %
145 %  A description of each parameter follows:
146 %
147 %    o image_view: the image view.
148 %
149 */
150 MagickExport ImageView *DestroyImageView(ImageView *image_view)
151 {
152   assert(image_view != (ImageView *) NULL);
153   assert(image_view->signature == MagickSignature);
154   if (image_view->description != (char *) NULL)
155     image_view->description=DestroyString(image_view->description);
156   image_view->view=DestroyCacheView(image_view->view);
157   image_view->exception=DestroyExceptionInfo(image_view->exception);
158   image_view->signature=(~MagickSignature);
159   image_view=(ImageView *) RelinquishMagickMemory(image_view);
160   return(image_view);
161 }
162 \f
163 /*
164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
165 %                                                                             %
166 %                                                                             %
167 %                                                                             %
168 %   D u p l e x T r a n s f e r I m a g e V i e w I t e r a t o r             %
169 %                                                                             %
170 %                                                                             %
171 %                                                                             %
172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 %
174 %  DuplexTransferImageViewIterator() iterates over three image views in
175 %  parallel and calls your transfer method for each scanline of the view.  The
176 %  source and duplex pixel extent is not confined to the image canvas-- that is
177 %  you can include negative offsets or widths or heights that exceed the image
178 %  dimension.  However, the destination image view is confined to the image
179 %  canvas-- that is no negative offsets or widths or heights that exceed the
180 %  image dimension are permitted.
181 %
182 %  The callback signature is:
183 %
184 %      MagickBooleanType DuplexTransferImageViewMethod(const ImageView *source,
185 %        const ImageView *duplex,ImageView *destination,const ssize_t y,
186 %        const int thread_id,void *context)
187 %
188 %  Use this pragma if the view is not single threaded:
189 %
190 %    #pragma omp critical
191 %
192 %  to define a section of code in your callback transfer method that must be
193 %  executed by a single thread at a time.
194 %
195 %  The format of the DuplexTransferImageViewIterator method is:
196 %
197 %      MagickBooleanType DuplexTransferImageViewIterator(ImageView *source,
198 %        ImageView *duplex,ImageView *destination,
199 %        DuplexTransferImageViewMethod transfer,void *context)
200 %
201 %  A description of each parameter follows:
202 %
203 %    o source: the source image view.
204 %
205 %    o duplex: the duplex image view.
206 %
207 %    o destination: the destination image view.
208 %
209 %    o transfer: the transfer callback method.
210 %
211 %    o context: the user defined context.
212 %
213 */
214 MagickExport MagickBooleanType DuplexTransferImageViewIterator(
215   ImageView *source,ImageView *duplex,ImageView *destination,
216   DuplexTransferImageViewMethod transfer,void *context)
217 {
218   Image
219     *destination_image,
220     *source_image;
221
222   MagickBooleanType
223     status;
224
225   MagickOffsetType
226     progress;
227
228   ssize_t
229     y;
230
231   assert(source != (ImageView *) NULL);
232   assert(source->signature == MagickSignature);
233   if (transfer == (DuplexTransferImageViewMethod) NULL)
234     return(MagickFalse);
235   source_image=source->image;
236   destination_image=destination->image;
237   status=SetImageStorageClass(destination_image,DirectClass,
238     destination->exception);
239   if (status == MagickFalse)
240     return(MagickFalse);
241   status=MagickTrue;
242   progress=0;
243 #if defined(MAGICKCORE_OPENMP_SUPPORT)
244   #pragma omp parallel for schedule(static) shared(progress,status) num_threads(source->number_threads)
245 #endif
246   for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
247   {
248     const int
249       id = GetOpenMPThreadId();
250
251     MagickBooleanType
252       sync;
253
254     register const Quantum
255       *restrict duplex_pixels,
256       *restrict pixels;
257
258     register Quantum
259       *restrict destination_pixels;
260
261     if (status == MagickFalse)
262       continue;
263     pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
264       source->extent.width,1,source->exception);
265     if (pixels == (const Quantum *) NULL)
266       {
267         status=MagickFalse;
268         continue;
269       }
270     duplex_pixels=GetCacheViewVirtualPixels(duplex->view,duplex->extent.x,y,
271       duplex->extent.width,1,duplex->exception);
272     if (duplex_pixels == (const Quantum *) NULL)
273       {
274         status=MagickFalse;
275         continue;
276       }
277     destination_pixels=GetCacheViewAuthenticPixels(destination->view,
278       destination->extent.x,y,destination->extent.width,1,
279       destination->exception);
280     if (destination_pixels == (Quantum *) NULL)
281       {
282         status=MagickFalse;
283         continue;
284       }
285     if (transfer(source,duplex,destination,y,id,context) == MagickFalse)
286       status=MagickFalse;
287     sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
288     if (sync == MagickFalse)
289       status=MagickFalse;
290     if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
291       {
292         MagickBooleanType
293           proceed;
294
295 #if defined(MAGICKCORE_OPENMP_SUPPORT)
296   #pragma omp critical (MagickCore_DuplexTransferImageViewIterator)
297 #endif
298         proceed=SetImageProgress(source_image,source->description,progress++,
299           source->extent.height);
300         if (proceed == MagickFalse)
301           status=MagickFalse;
302       }
303   }
304   return(status);
305 }
306 \f
307 /*
308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
309 %                                                                             %
310 %                                                                             %
311 %                                                                             %
312 %   G e t I m a g e V i e w A u t h e n t i c M e t a c o n t e n t           %
313 %                                                                             %
314 %                                                                             %
315 %                                                                             %
316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317 %
318 %  GetImageViewAuthenticMetacontent() returns the image view authentic
319 %  meta-content.
320 %
321 %  The format of the GetImageViewAuthenticPixels method is:
322 %
323 %      void *GetImageViewAuthenticMetacontent(
324 %        const ImageView *image_view)
325 %
326 %  A description of each parameter follows:
327 %
328 %    o image_view: the image view.
329 %
330 */
331 MagickExport void *GetImageViewAuthenticMetacontent(
332   const ImageView *image_view)
333 {
334   assert(image_view != (ImageView *) NULL);
335   assert(image_view->signature == MagickSignature);
336   return(GetCacheViewAuthenticMetacontent(image_view->view));
337 }
338 \f
339 /*
340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
341 %                                                                             %
342 %                                                                             %
343 %                                                                             %
344 %   G e t I m a g e V i e w A u t h e n t i c P i x e l s                     %
345 %                                                                             %
346 %                                                                             %
347 %                                                                             %
348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349 %
350 %  GetImageViewAuthenticPixels() returns the image view authentic pixels.
351 %
352 %  The format of the GetImageViewAuthenticPixels method is:
353 %
354 %      Quantum *GetImageViewAuthenticPixels(const ImageView *image_view)
355 %
356 %  A description of each parameter follows:
357 %
358 %    o image_view: the image view.
359 %
360 */
361 MagickExport Quantum *GetImageViewAuthenticPixels(
362   const ImageView *image_view)
363 {
364   assert(image_view != (ImageView *) NULL);
365   assert(image_view->signature == MagickSignature);
366   return(GetCacheViewAuthenticPixelQueue(image_view->view));
367 }
368 \f
369 /*
370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
371 %                                                                             %
372 %                                                                             %
373 %                                                                             %
374 %   G e t I m a g e V i e w E x c e p t i o n                                 %
375 %                                                                             %
376 %                                                                             %
377 %                                                                             %
378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
379 %
380 %  GetImageViewException() returns the severity, reason, and description of any
381 %  error that occurs when utilizing a image view.
382 %
383 %  The format of the GetImageViewException method is:
384 %
385 %      char *GetImageViewException(const PixelImage *image_view,
386 %        ExceptionType *severity)
387 %
388 %  A description of each parameter follows:
389 %
390 %    o image_view: the pixel image_view.
391 %
392 %    o severity: the severity of the error is returned here.
393 %
394 */
395 MagickExport char *GetImageViewException(const ImageView *image_view,
396   ExceptionType *severity)
397 {
398   char
399     *description;
400
401   assert(image_view != (const ImageView *) NULL);
402   assert(image_view->signature == MagickSignature);
403   assert(severity != (ExceptionType *) NULL);
404   *severity=image_view->exception->severity;
405   description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
406     sizeof(*description));
407   if (description == (char *) NULL)
408     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
409   *description='\0';
410   if (image_view->exception->reason != (char *) NULL)
411     (void) CopyMagickString(description,GetLocaleExceptionMessage(
412       image_view->exception->severity,image_view->exception->reason),
413         MaxTextExtent);
414   if (image_view->exception->description != (char *) NULL)
415     {
416       (void) ConcatenateMagickString(description," (",MaxTextExtent);
417       (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
418         image_view->exception->severity,image_view->exception->description),
419         MaxTextExtent);
420       (void) ConcatenateMagickString(description,")",MaxTextExtent);
421     }
422   return(description);
423 }
424 \f
425 /*
426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
427 %                                                                             %
428 %                                                                             %
429 %                                                                             %
430 %   G e t I m a g e V i e w E x t e n t                                       %
431 %                                                                             %
432 %                                                                             %
433 %                                                                             %
434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
435 %
436 %  GetImageViewExtent() returns the image view extent.
437 %
438 %  The format of the GetImageViewExtent method is:
439 %
440 %      RectangleInfo GetImageViewExtent(const ImageView *image_view)
441 %
442 %  A description of each parameter follows:
443 %
444 %    o image_view: the image view.
445 %
446 */
447 MagickExport RectangleInfo GetImageViewExtent(const ImageView *image_view)
448 {
449   assert(image_view != (ImageView *) NULL);
450   assert(image_view->signature == MagickSignature);
451   return(image_view->extent);
452 }
453 \f
454 /*
455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456 %                                                                             %
457 %                                                                             %
458 %                                                                             %
459 %   G e t I m a g e V i e w I m a g e                                         %
460 %                                                                             %
461 %                                                                             %
462 %                                                                             %
463 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
464 %
465 %  GetImageViewImage() returns the image associated with the image view.
466 %
467 %  The format of the GetImageViewImage method is:
468 %
469 %      MagickCore *GetImageViewImage(const ImageView *image_view)
470 %
471 %  A description of each parameter follows:
472 %
473 %    o image_view: the image view.
474 %
475 */
476 MagickExport Image *GetImageViewImage(const ImageView *image_view)
477 {
478   assert(image_view != (ImageView *) NULL);
479   assert(image_view->signature == MagickSignature);
480   return(image_view->image);
481 }
482 \f
483 /*
484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485 %                                                                             %
486 %                                                                             %
487 %                                                                             %
488 %   G e t I m a g e V i e w I t e r a t o r                                   %
489 %                                                                             %
490 %                                                                             %
491 %                                                                             %
492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
493 %
494 %  GetImageViewIterator() iterates over the image view in parallel and calls
495 %  your get method for each scanline of the view.  The pixel extent is
496 %  not confined to the image canvas-- that is you can include negative offsets
497 %  or widths or heights that exceed the image dimension.  Any updates to
498 %  the pixels in your callback are ignored.
499 %
500 %  The callback signature is:
501 %
502 %      MagickBooleanType GetImageViewMethod(const ImageView *source,
503 %        const ssize_t y,const int thread_id,void *context)
504 %
505 %  Use this pragma if the view is not single threaded:
506 %
507 %    #pragma omp critical
508 %
509 %  to define a section of code in your callback get method that must be
510 %  executed by a single thread at a time.
511 %
512 %  The format of the GetImageViewIterator method is:
513 %
514 %      MagickBooleanType GetImageViewIterator(ImageView *source,
515 %        GetImageViewMethod get,void *context)
516 %
517 %  A description of each parameter follows:
518 %
519 %    o source: the source image view.
520 %
521 %    o get: the get callback method.
522 %
523 %    o context: the user defined context.
524 %
525 */
526 MagickExport MagickBooleanType GetImageViewIterator(ImageView *source,
527   GetImageViewMethod get,void *context)
528 {
529   Image
530     *source_image;
531
532   MagickBooleanType
533     status;
534
535   MagickOffsetType
536     progress;
537
538   ssize_t
539     y;
540
541   assert(source != (ImageView *) NULL);
542   assert(source->signature == MagickSignature);
543   if (get == (GetImageViewMethod) NULL)
544     return(MagickFalse);
545   source_image=source->image;
546   status=MagickTrue;
547   progress=0;
548 #if defined(MAGICKCORE_OPENMP_SUPPORT)
549   #pragma omp parallel for schedule(static) shared(progress,status) num_threads(source->number_threads)
550 #endif
551   for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
552   {
553     const int
554       id = GetOpenMPThreadId();
555
556     register const Quantum
557       *pixels;
558
559     if (status == MagickFalse)
560       continue;
561     pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
562       source->extent.width,1,source->exception);
563     if (pixels == (const Quantum *) NULL)
564       {
565         status=MagickFalse;
566         continue;
567       }
568     if (get(source,y,id,context) == MagickFalse)
569       status=MagickFalse;
570     if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
571       {
572         MagickBooleanType
573           proceed;
574
575 #if defined(MAGICKCORE_OPENMP_SUPPORT)
576   #pragma omp critical (MagickCore_GetImageViewIterator)
577 #endif
578         proceed=SetImageProgress(source_image,source->description,progress++,
579           source->extent.height);
580         if (proceed == MagickFalse)
581           status=MagickFalse;
582       }
583   }
584   return(status);
585 }
586 \f
587 /*
588 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
589 %                                                                             %
590 %                                                                             %
591 %                                                                             %
592 %   G e t I m a g e V i e w V i r t u a l M e t a c o n t e n t     %
593 %                                                                             %
594 %                                                                             %
595 %                                                                             %
596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
597 %
598 %  GetImageViewVirtualMetacontent() returns the image view virtual
599 %  meta-content.
600 %
601 %  The format of the GetImageViewVirtualMetacontent method is:
602 %
603 %      const void *GetImageViewVirtualMetacontent(
604 %        const ImageView *image_view)
605 %
606 %  A description of each parameter follows:
607 %
608 %    o image_view: the image view.
609 %
610 */
611 MagickExport const void *GetImageViewVirtualMetacontent(
612   const ImageView *image_view)
613 {
614   assert(image_view != (ImageView *) NULL);
615   assert(image_view->signature == MagickSignature);
616   return(GetCacheViewVirtualMetacontent(image_view->view));
617 }
618 \f
619 /*
620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
621 %                                                                             %
622 %                                                                             %
623 %                                                                             %
624 %   G e t I m a g e V i e w V i r t u a l P i x e l s                         %
625 %                                                                             %
626 %                                                                             %
627 %                                                                             %
628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629 %
630 %  GetImageViewVirtualPixels() returns the image view virtual pixels.
631 %
632 %  The format of the GetImageViewVirtualPixels method is:
633 %
634 %      const Quantum *GetImageViewVirtualPixels(const ImageView *image_view)
635 %
636 %  A description of each parameter follows:
637 %
638 %    o image_view: the image view.
639 %
640 */
641 MagickExport const Quantum *GetImageViewVirtualPixels(
642   const ImageView *image_view)
643 {
644   assert(image_view != (ImageView *) NULL);
645   assert(image_view->signature == MagickSignature);
646   return(GetCacheViewVirtualPixelQueue(image_view->view));
647 }
648 \f
649 /*
650 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
651 %                                                                             %
652 %                                                                             %
653 %                                                                             %
654 %   I s I m a g e V i e w                                                     %
655 %                                                                             %
656 %                                                                             %
657 %                                                                             %
658 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
659 %
660 %  IsImageView() returns MagickTrue if the the parameter is verified as a image
661 %  view object.
662 %
663 %  The format of the IsImageView method is:
664 %
665 %      MagickBooleanType IsImageView(const ImageView *image_view)
666 %
667 %  A description of each parameter follows:
668 %
669 %    o image_view: the image view.
670 %
671 */
672 MagickExport MagickBooleanType IsImageView(const ImageView *image_view)
673 {
674   if (image_view == (const ImageView *) NULL)
675     return(MagickFalse);
676   if (image_view->signature != MagickSignature)
677     return(MagickFalse);
678   return(MagickTrue);
679 }
680 \f
681 /*
682 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
683 %                                                                             %
684 %                                                                             %
685 %                                                                             %
686 %   N e w I m a g e V i e w                                                   %
687 %                                                                             %
688 %                                                                             %
689 %                                                                             %
690 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
691 %
692 %  NewImageView() returns a image view required for all other methods in the
693 %  Image View API.
694 %
695 %  The format of the NewImageView method is:
696 %
697 %      ImageView *NewImageView(MagickCore *wand,ExceptionInfo *exception)
698 %
699 %  A description of each parameter follows:
700 %
701 %    o image: the image.
702 %
703 %    o exception: return any errors or warnings in this structure.
704 %
705 */
706 MagickExport ImageView *NewImageView(Image *image,ExceptionInfo *exception)
707 {
708   ImageView
709     *image_view;
710
711   assert(image != (Image *) NULL);
712   assert(image->signature == MagickSignature);
713   image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
714   if (image_view == (ImageView *) NULL)
715     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
716   (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
717   image_view->description=ConstantString("ImageView");
718   image_view->image=image;
719   image_view->view=AcquireVirtualCacheView(image_view->image,exception);
720   image_view->extent.width=image->columns;
721   image_view->extent.height=image->rows;
722   image_view->extent.x=0;
723   image_view->extent.y=0;
724   image_view->number_threads=GetOpenMPMaximumThreads();
725   image_view->exception=AcquireExceptionInfo();
726   image_view->debug=IsEventLogging();
727   image_view->signature=MagickSignature;
728   return(image_view);
729 }
730 \f
731 /*
732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
733 %                                                                             %
734 %                                                                             %
735 %                                                                             %
736 %   N e w I m a g e V i e w R e g i o n                                       %
737 %                                                                             %
738 %                                                                             %
739 %                                                                             %
740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
741 %
742 %  NewImageViewRegion() returns a image view required for all other methods
743 %  in the Image View API.
744 %
745 %  The format of the NewImageViewRegion method is:
746 %
747 %      ImageView *NewImageViewRegion(MagickCore *wand,const ssize_t x,
748 %        const ssize_t y,const size_t width,const size_t height,
749 %        ExceptionInfo *exception)
750 %
751 %  A description of each parameter follows:
752 %
753 %    o wand: the magick wand.
754 %
755 %    o x,y,columns,rows:  These values define the perimeter of a extent of
756 %      pixel_wands view.
757 %
758 %    o exception: return any errors or warnings in this structure.
759 %
760 */
761 MagickExport ImageView *NewImageViewRegion(Image *image,const ssize_t x,
762   const ssize_t y,const size_t width,const size_t height,
763   ExceptionInfo *exception)
764 {
765   ImageView
766     *image_view;
767
768   assert(image != (Image *) NULL);
769   assert(image->signature == MagickSignature);
770   image_view=(ImageView *) AcquireMagickMemory(sizeof(*image_view));
771   if (image_view == (ImageView *) NULL)
772     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
773   (void) ResetMagickMemory(image_view,0,sizeof(*image_view));
774   image_view->description=ConstantString("ImageView");
775   image_view->view=AcquireVirtualCacheView(image_view->image,exception);
776   image_view->image=image;
777   image_view->extent.width=width;
778   image_view->extent.height=height;
779   image_view->extent.x=x;
780   image_view->extent.y=y;
781   image_view->number_threads=GetOpenMPMaximumThreads();
782   image_view->exception=AcquireExceptionInfo();
783   image_view->debug=IsEventLogging();
784   image_view->signature=MagickSignature;
785   return(image_view);
786 }
787 \f
788 /*
789 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
790 %                                                                             %
791 %                                                                             %
792 %                                                                             %
793 %   S e t I m a g e V i e w D e s c r i p t i o n                             %
794 %                                                                             %
795 %                                                                             %
796 %                                                                             %
797 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
798 %
799 %  SetImageViewDescription() associates a description with an image view.
800 %
801 %  The format of the SetImageViewDescription method is:
802 %
803 %      void SetImageViewDescription(ImageView *image_view,
804 %        const char *description)
805 %
806 %  A description of each parameter follows:
807 %
808 %    o image_view: the image view.
809 %
810 %    o description: the image view description.
811 %
812 */
813 MagickExport void SetImageViewDescription(ImageView *image_view,
814   const char *description)
815 {
816   assert(image_view != (ImageView *) NULL);
817   assert(image_view->signature == MagickSignature);
818   image_view->description=ConstantString(description);
819 }
820 \f
821 /*
822 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
823 %                                                                             %
824 %                                                                             %
825 %                                                                             %
826 %   S e t I m a g e V i e w I t e r a t o r                                   %
827 %                                                                             %
828 %                                                                             %
829 %                                                                             %
830 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
831 %
832 %  SetImageViewIterator() iterates over the image view in parallel and calls
833 %  your set method for each scanline of the view.  The pixel extent is
834 %  confined to the image canvas-- that is no negative offsets or widths or
835 %  heights that exceed the image dimension.  The pixels are initiallly
836 %  undefined and any settings you make in the callback method are automagically
837 %  synced back to your image.
838 %
839 %  The callback signature is:
840 %
841 %      MagickBooleanType SetImageViewMethod(ImageView *destination,
842 %        const ssize_t y,const int thread_id,void *context)
843 %
844 %  Use this pragma if the view is not single threaded:
845 %
846 %    #pragma omp critical
847 %
848 %  to define a section of code in your callback set method that must be
849 %  executed by a single thread at a time.
850 %
851 %  The format of the SetImageViewIterator method is:
852 %
853 %      MagickBooleanType SetImageViewIterator(ImageView *destination,
854 %        SetImageViewMethod set,void *context)
855 %
856 %  A description of each parameter follows:
857 %
858 %    o destination: the image view.
859 %
860 %    o set: the set callback method.
861 %
862 %    o context: the user defined context.
863 %
864 */
865 MagickExport MagickBooleanType SetImageViewIterator(ImageView *destination,
866   SetImageViewMethod set,void *context)
867 {
868   Image
869     *destination_image;
870
871   MagickBooleanType
872     status;
873
874   MagickOffsetType
875     progress;
876
877   ssize_t
878     y;
879
880   assert(destination != (ImageView *) NULL);
881   assert(destination->signature == MagickSignature);
882   if (set == (SetImageViewMethod) NULL)
883     return(MagickFalse);
884   destination_image=destination->image;
885   status=SetImageStorageClass(destination_image,DirectClass,
886     destination->exception);
887   if (status == MagickFalse)
888     return(MagickFalse);
889   status=MagickTrue;
890   progress=0;
891 #if defined(MAGICKCORE_OPENMP_SUPPORT)
892   #pragma omp parallel for schedule(static) shared(progress,status) num_threads(destination->number_threads)
893 #endif
894   for (y=destination->extent.y; y < (ssize_t) destination->extent.height; y++)
895   {
896     const int
897       id = GetOpenMPThreadId();
898
899     MagickBooleanType
900       sync;
901
902     register Quantum
903       *restrict pixels;
904
905     if (status == MagickFalse)
906       continue;
907     pixels=GetCacheViewAuthenticPixels(destination->view,destination->extent.x,
908       y,destination->extent.width,1,destination->exception);
909     if (pixels == (Quantum *) NULL)
910       {
911         status=MagickFalse;
912         continue;
913       }
914     if (set(destination,y,id,context) == MagickFalse)
915       status=MagickFalse;
916     sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
917     if (sync == MagickFalse)
918       status=MagickFalse;
919     if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
920       {
921         MagickBooleanType
922           proceed;
923
924 #if defined(MAGICKCORE_OPENMP_SUPPORT)
925   #pragma omp critical (MagickCore_SetImageViewIterator)
926 #endif
927         proceed=SetImageProgress(destination_image,destination->description,
928           progress++,destination->extent.height);
929         if (proceed == MagickFalse)
930           status=MagickFalse;
931       }
932   }
933   return(status);
934 }
935 \f
936 /*
937 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
938 %                                                                             %
939 %                                                                             %
940 %                                                                             %
941 %   S e t I m a g e V i e w T h r e a d s                                     %
942 %                                                                             %
943 %                                                                             %
944 %                                                                             %
945 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
946 %
947 %  SetImageViewThreads() sets the number of threads in a thread team.
948 %
949 %  The format of the SetImageViewDescription method is:
950 %
951 %      void SetImageViewThreads(ImageView *image_view,
952 %        const size_t number_threads)
953 %
954 %  A description of each parameter follows:
955 %
956 %    o image_view: the image view.
957 %
958 %    o number_threads: the number of threads in a thread team.
959 %
960 */
961 MagickExport void SetImageViewThreads(ImageView *image_view,
962   const size_t number_threads)
963 {
964   assert(image_view != (ImageView *) NULL);
965   assert(image_view->signature == MagickSignature);
966   image_view->number_threads=number_threads;
967   if (number_threads > GetOpenMPMaximumThreads())
968     image_view->number_threads=GetOpenMPMaximumThreads();
969 }
970 \f
971 /*
972 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
973 %                                                                             %
974 %                                                                             %
975 %                                                                             %
976 %   T r a n s f e r I m a g e V i e w I t e r a t o r                         %
977 %                                                                             %
978 %                                                                             %
979 %                                                                             %
980 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
981 %
982 %  TransferImageViewIterator() iterates over two image views in parallel and
983 %  calls your transfer method for each scanline of the view.  The source pixel
984 %  extent is not confined to the image canvas-- that is you can include
985 %  negative offsets or widths or heights that exceed the image dimension.
986 %  However, the destination image view is confined to the image canvas-- that
987 %  is no negative offsets or widths or heights that exceed the image dimension
988 %  are permitted.
989 %
990 %  The callback signature is:
991 %
992 %      MagickBooleanType TransferImageViewMethod(const ImageView *source,
993 %        ImageView *destination,const ssize_t y,const int thread_id,
994 %        void *context)
995 %
996 %  Use this pragma if the view is not single threaded:
997 %
998 %    #pragma omp critical
999 %
1000 %  to define a section of code in your callback transfer method that must be
1001 %  executed by a single thread at a time.
1002 %
1003 %  The format of the TransferImageViewIterator method is:
1004 %
1005 %      MagickBooleanType TransferImageViewIterator(ImageView *source,
1006 %        ImageView *destination,TransferImageViewMethod transfer,void *context)
1007 %
1008 %  A description of each parameter follows:
1009 %
1010 %    o source: the source image view.
1011 %
1012 %    o destination: the destination image view.
1013 %
1014 %    o transfer: the transfer callback method.
1015 %
1016 %    o context: the user defined context.
1017 %
1018 */
1019 MagickExport MagickBooleanType TransferImageViewIterator(ImageView *source,
1020   ImageView *destination,TransferImageViewMethod transfer,void *context)
1021 {
1022   Image
1023     *destination_image,
1024     *source_image;
1025
1026   MagickBooleanType
1027     status;
1028
1029   MagickOffsetType
1030     progress;
1031
1032   ssize_t
1033     y;
1034
1035   assert(source != (ImageView *) NULL);
1036   assert(source->signature == MagickSignature);
1037   if (transfer == (TransferImageViewMethod) NULL)
1038     return(MagickFalse);
1039   source_image=source->image;
1040   destination_image=destination->image;
1041   status=SetImageStorageClass(destination_image,DirectClass,
1042     destination->exception);
1043   if (status == MagickFalse)
1044     return(MagickFalse);
1045   status=MagickTrue;
1046   progress=0;
1047 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1048   #pragma omp parallel for schedule(static) shared(progress,status) num_threads(source->number_threads)
1049 #endif
1050   for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1051   {
1052     const int
1053       id = GetOpenMPThreadId();
1054
1055     MagickBooleanType
1056       sync;
1057
1058     register const Quantum
1059       *restrict pixels;
1060
1061     register Quantum
1062       *restrict destination_pixels;
1063
1064     if (status == MagickFalse)
1065       continue;
1066     pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
1067       source->extent.width,1,source->exception);
1068     if (pixels == (const Quantum *) NULL)
1069       {
1070         status=MagickFalse;
1071         continue;
1072       }
1073     destination_pixels=GetCacheViewAuthenticPixels(destination->view,
1074       destination->extent.x,y,destination->extent.width,1,
1075       destination->exception);
1076     if (destination_pixels == (Quantum *) NULL)
1077       {
1078         status=MagickFalse;
1079         continue;
1080       }
1081     if (transfer(source,destination,y,id,context) == MagickFalse)
1082       status=MagickFalse;
1083     sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
1084     if (sync == MagickFalse)
1085       status=MagickFalse;
1086     if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1087       {
1088         MagickBooleanType
1089           proceed;
1090
1091 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1092   #pragma omp critical (MagickCore_TransferImageViewIterator)
1093 #endif
1094         proceed=SetImageProgress(source_image,source->description,progress++,
1095           source->extent.height);
1096         if (proceed == MagickFalse)
1097           status=MagickFalse;
1098       }
1099   }
1100   return(status);
1101 }
1102 \f
1103 /*
1104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1105 %                                                                             %
1106 %                                                                             %
1107 %                                                                             %
1108 %   U p d a t e I m a g e V i e w I t e r a t o r                             %
1109 %                                                                             %
1110 %                                                                             %
1111 %                                                                             %
1112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1113 %
1114 %  UpdateImageViewIterator() iterates over the image view in parallel and calls
1115 %  your update method for each scanline of the view.  The pixel extent is
1116 %  confined to the image canvas-- that is no negative offsets or widths or
1117 %  heights that exceed the image dimension are permitted.  Updates to pixels
1118 %  in your callback are automagically synced back to the image.
1119 %
1120 %  The callback signature is:
1121 %
1122 %      MagickBooleanType UpdateImageViewMethod(ImageView *source,
1123 %        const ssize_t y,const int thread_id,void *context)
1124 %
1125 %  Use this pragma if the view is not single threaded:
1126 %
1127 %    #pragma omp critical
1128 %
1129 %  to define a section of code in your callback update method that must be
1130 %  executed by a single thread at a time.
1131 %
1132 %  The format of the UpdateImageViewIterator method is:
1133 %
1134 %      MagickBooleanType UpdateImageViewIterator(ImageView *source,
1135 %        UpdateImageViewMethod update,void *context)
1136 %
1137 %  A description of each parameter follows:
1138 %
1139 %    o source: the source image view.
1140 %
1141 %    o update: the update callback method.
1142 %
1143 %    o context: the user defined context.
1144 %
1145 */
1146 MagickExport MagickBooleanType UpdateImageViewIterator(ImageView *source,
1147   UpdateImageViewMethod update,void *context)
1148 {
1149   Image
1150     *source_image;
1151
1152   MagickBooleanType
1153     status;
1154
1155   MagickOffsetType
1156     progress;
1157
1158   ssize_t
1159     y;
1160
1161   assert(source != (ImageView *) NULL);
1162   assert(source->signature == MagickSignature);
1163   if (update == (UpdateImageViewMethod) NULL)
1164     return(MagickFalse);
1165   source_image=source->image;
1166   status=SetImageStorageClass(source_image,DirectClass,source->exception);
1167   if (status == MagickFalse)
1168     return(MagickFalse);
1169   status=MagickTrue;
1170   progress=0;
1171 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1172   #pragma omp parallel for schedule(static) shared(progress,status) num_threads(source->number_threads)
1173 #endif
1174   for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1175   {
1176     const int
1177       id = GetOpenMPThreadId();
1178
1179     register Quantum
1180       *restrict pixels;
1181
1182     if (status == MagickFalse)
1183       continue;
1184     pixels=GetCacheViewAuthenticPixels(source->view,source->extent.x,y,
1185       source->extent.width,1,source->exception);
1186     if (pixels == (Quantum *) NULL)
1187       {
1188         status=MagickFalse;
1189         continue;
1190       }
1191     if (update(source,y,id,context) == MagickFalse)
1192       status=MagickFalse;
1193     status=SyncCacheViewAuthenticPixels(source->view,source->exception);
1194     if (status == MagickFalse)
1195       status=MagickFalse;
1196     if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1197       {
1198         MagickBooleanType
1199           proceed;
1200
1201 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1202   #pragma omp critical (MagickCore_UpdateImageViewIterator)
1203 #endif
1204         proceed=SetImageProgress(source_image,source->description,progress++,
1205           source->extent.height);
1206         if (proceed == MagickFalse)
1207           status=MagickFalse;
1208       }
1209   }
1210   return(status);
1211 }