MagickCore  7.0.7
Convert, Edit, Or Compose Bitmap Images
image-view.c
Go to the documentation of this file.
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://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 
45 /*
46  Include declarations.
47 */
48 #include "MagickCore/studio.h"
49 #include "MagickCore/MagickCore.h"
54 
55 /*
56  Typedef declarations.
57 */
58 struct _ImageView
59 {
60  char
62 
65 
66  Image
68 
69  CacheView
70  *view;
71 
74 
77 
78  size_t
80 };
81 
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 */
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) ResetMagickMemory(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 
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 */
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 
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 */
210  ImageView *source,ImageView *duplex,ImageView *destination,
211  DuplexTransferImageViewMethod transfer,void *context)
212 {
213  Image
214  *destination_image,
215  *source_image;
216 
218  status;
219 
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,4) 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 
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  {
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 
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 */
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 
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 */
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 
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 */
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);
420  image_view->exception->severity,image_view->exception->description),
422  (void) ConcatenateMagickString(description,")",MagickPathExtent);
423  }
424  return(description);
425 }
426 
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 */
450 {
451  assert(image_view != (ImageView *) NULL);
452  assert(image_view->signature == MagickCoreSignature);
453  return(image_view->extent);
454 }
455 
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 */
479 {
480  assert(image_view != (ImageView *) NULL);
481  assert(image_view->signature == MagickCoreSignature);
482  return(image_view->image);
483 }
484 
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 */
529  GetImageViewMethod get,void *context)
530 {
531  Image
532  *source_image;
533 
535  status;
536 
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,4) 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  {
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 
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 */
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 
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 */
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 
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 */
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 
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 */
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) ResetMagickMemory(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 
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 */
768  const ssize_t y,const size_t width,const size_t height,
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) ResetMagickMemory(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 
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 */
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 
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 */
869  SetImageViewMethod set,void *context)
870 {
871  Image
872  *destination_image;
873 
875  status;
876 
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,4) 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 
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  {
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 
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 */
995  ImageView *destination,TransferImageViewMethod transfer,void *context)
996 {
997  Image
998  *destination_image,
999  *source_image;
1000 
1002  status;
1003 
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,4) 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 
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  {
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 
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 */
1129  UpdateImageViewMethod update,void *context)
1130 {
1131  Image
1132  *source_image;
1133 
1135  status;
1136 
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,4) 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  {
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 }
size_t rows
Definition: image.h:172
#define magick_restrict
Definition: MagickCore.h:41
MagickExport CacheView * DestroyCacheView(CacheView *cache_view)
Definition: cache-view.c:252
static MagickBooleanType SetImageProgress(const Image *image, const char *tag, const MagickOffsetType offset, const MagickSizeType extent)
MagickExport MagickBooleanType TransferImageViewIterator(ImageView *source, ImageView *destination, TransferImageViewMethod transfer, void *context)
Definition: image-view.c:994
RectangleInfo extent
Definition: image-view.c:64
MagickProgressMonitor progress_monitor
Definition: image.h:303
MagickExport const Quantum * GetCacheViewVirtualPixelQueue(const CacheView *cache_view)
Definition: cache-view.c:601
MagickExport ImageView * CloneImageView(const ImageView *image_view)
Definition: image-view.c:104
MagickExport MagickBooleanType GetImageViewIterator(ImageView *source, GetImageViewMethod get, void *context)
Definition: image-view.c:528
#define ThrowFatalException(severity, tag)
MagickExport ImageView * DestroyImageView(ImageView *image_view)
Definition: image-view.c:145
MagickBooleanType(*)(* GetImageViewMethod)(const ImageView *, const ssize_t, const int, void *)
Definition: image-view.h:31
MagickBooleanType debug
Definition: image-view.c:76
MagickExport size_t ConcatenateMagickString(char *destination, const char *source, const size_t length)
Definition: string.c:410
MagickBooleanType(* DuplexTransferImageViewMethod)(const ImageView *, const ImageView *, ImageView *, const ssize_t, const int, void *)
Definition: image-view.h:29
MagickExport const void * GetImageViewVirtualMetacontent(const ImageView *image_view)
Definition: image-view.c:620
MagickExport ExceptionInfo * AcquireExceptionInfo(void)
Definition: exception.c:108
MagickExport const Quantum * GetCacheViewVirtualPixels(const CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
Definition: cache-view.c:651
Image * image
Definition: image-view.c:67
size_t width
Definition: geometry.h:129
ssize_t MagickOffsetType
Definition: magick-type.h:127
Definition: image.h:151
ExceptionType
Definition: exception.h:27
MagickExport Quantum * GetImageViewAuthenticPixels(const ImageView *image_view)
Definition: image-view.c:363
#define MagickCoreSignature
MagickExport Quantum * GetCacheViewAuthenticPixels(CacheView *cache_view, const ssize_t x, const ssize_t y, const size_t columns, const size_t rows, ExceptionInfo *exception)
Definition: cache-view.c:299
MagickExport ImageView * NewImageView(Image *image, ExceptionInfo *exception)
Definition: image-view.c:715
CacheView * view
Definition: image-view.c:70
MagickBooleanType
Definition: magick-type.h:156
MagickBooleanType(*)(*)(* SetImageViewMethod)(ImageView *, const ssize_t, const int, void *)
Definition: image-view.h:32
size_t signature
Definition: image-view.c:79
char * description
Definition: image-view.c:61
ExceptionInfo * exception
Definition: image-view.c:73
char * reason
Definition: exception.h:110
MagickExport char * GetImageViewException(const ImageView *image_view, ExceptionType *severity)
Definition: image-view.c:397
MagickExport void * ResetMagickMemory(void *memory, int byte, const size_t size)
Definition: memory.c:1164
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:529
static int GetOpenMPThreadId(void)
MagickExport void * GetCacheViewAuthenticMetacontent(CacheView *cache_view)
Definition: cache-view.c:342
MagickExport MagickBooleanType UpdateImageViewIterator(ImageView *source, UpdateImageViewMethod update, void *context)
Definition: image-view.c:1128
MagickExport void * GetImageViewAuthenticMetacontent(const ImageView *image_view)
Definition: image-view.c:333
MagickExport const void * GetCacheViewVirtualMetacontent(const CacheView *cache_view)
Definition: cache-view.c:558
MagickExport RectangleInfo GetImageViewExtent(const ImageView *image_view)
Definition: image-view.c:449
#define MagickPathExtent
MagickExport MagickBooleanType IsEventLogging(void)
Definition: log.c:716
MagickExport void SetImageViewDescription(ImageView *image_view, const char *description)
Definition: image-view.c:816
MagickExport MagickBooleanType static void * AcquireCriticalMemory(const size_t size)
MagickExport const Quantum * GetImageViewVirtualPixels(const ImageView *image_view)
Definition: image-view.c:650
size_t signature
Definition: image.h:354
size_t columns
Definition: image.h:172
MagickBooleanType(* MagickProgressMonitor)(const char *, const MagickOffsetType, const MagickSizeType, void *)
Definition: monitor.h:26
ssize_t x
Definition: geometry.h:133
size_t height
Definition: geometry.h:129
MagickExport MagickBooleanType SetImageStorageClass(Image *image, const ClassType storage_class, ExceptionInfo *exception)
Definition: image.c:2508
MagickExport size_t CopyMagickString(char *destination, const char *source, const size_t length)
Definition: string.c:742
MagickExport CacheView * CloneCacheView(const CacheView *cache_view)
Definition: cache-view.c:205
MagickExport MagickBooleanType SetImageViewIterator(ImageView *destination, SetImageViewMethod set, void *context)
Definition: image-view.c:868
MagickBooleanType(*)(*)(*)(* TransferImageViewMethod)(const ImageView *, ImageView *, const ssize_t, const int, void *)
Definition: image-view.h:33
MagickExport CacheView * AcquireVirtualCacheView(const Image *image, ExceptionInfo *exception)
Definition: cache-view.c:149
MagickBooleanType(*)(*)(*)(*)(* UpdateImageViewMethod)(ImageView *, const ssize_t, const int, void *)
Definition: image-view.h:35
unsigned short Quantum
Definition: magick-type.h:82
MagickExport char * DestroyString(char *string)
Definition: string.c:810
MagickExport Quantum * GetCacheViewAuthenticPixelQueue(CacheView *cache_view)
Definition: cache-view.c:379
MagickExport MagickBooleanType IsImageView(const ImageView *image_view)
Definition: image-view.c:681
MagickExport MagickBooleanType DuplexTransferImageViewIterator(ImageView *source, ImageView *duplex, ImageView *destination, DuplexTransferImageViewMethod transfer, void *context)
Definition: image-view.c:209
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1038
MagickExport Image * GetImageViewImage(const ImageView *image_view)
Definition: image-view.c:478
#define MagickExport
MagickExport MagickBooleanType SyncCacheViewAuthenticPixels(CacheView *magick_restrict cache_view, ExceptionInfo *exception)
Definition: cache-view.c:1100
ssize_t y
Definition: geometry.h:133
MagickExport ImageView * NewImageViewRegion(Image *image, const ssize_t x, const ssize_t y, const size_t width, const size_t height, ExceptionInfo *exception)
Definition: image-view.c:767
MagickExport const char * GetLocaleExceptionMessage(const ExceptionType severity, const char *tag)
Definition: exception.c:589
char * description
Definition: exception.h:110
MagickExport char * ConstantString(const char *source)
Definition: string.c:687
MagickExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition: exception.c:417
MagickExport void InheritException(ExceptionInfo *exception, const ExceptionInfo *relative)
Definition: exception.c:633
ExceptionType severity
Definition: exception.h:104