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