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