MagickWand  7.0.7
Convert, Edit, Or Compose Bitmap Images
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-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 "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) ResetMagickMemory(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 
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,4) 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 critical (MagickWand_DuplexTransferWandViewIterator)
377 #endif
378  proceed=SetImageProgress(source_image,source->description,progress++,
379  source->extent.height);
380  if (proceed == MagickFalse)
381  status=MagickFalse;
382  }
383  }
384  return(status);
385 }
386 
387 /*
388 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
389 % %
390 % %
391 % %
392 % G e t W a n d V i e w E x c e p t i o n %
393 % %
394 % %
395 % %
396 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
397 %
398 % GetWandViewException() returns the severity, reason, and description of any
399 % error that occurs when utilizing a wand view.
400 %
401 % The format of the GetWandViewException method is:
402 %
403 % char *GetWandViewException(const WandView *wand_view,
404 % ExceptionType *severity)
405 %
406 % A description of each parameter follows:
407 %
408 % o wand_view: the pixel wand_view.
409 %
410 % o severity: the severity of the error is returned here.
411 %
412 */
413 WandExport char *GetWandViewException(const WandView *wand_view,
414  ExceptionType *severity)
415 {
416  char
417  *description;
418 
419  assert(wand_view != (const WandView *) NULL);
420  assert(wand_view->signature == MagickWandSignature);
421  if (wand_view->debug != MagickFalse)
422  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand_view->name);
423  assert(severity != (ExceptionType *) NULL);
424  *severity=wand_view->exception->severity;
425  description=(char *) AcquireQuantumMemory(2UL*MagickPathExtent,
426  sizeof(*description));
427  if (description == (char *) NULL)
428  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
429  wand_view->name);
430  *description='\0';
431  if (wand_view->exception->reason != (char *) NULL)
432  (void) CopyMagickString(description,GetLocaleExceptionMessage(
433  wand_view->exception->severity,wand_view->exception->reason),
434  MagickPathExtent);
435  if (wand_view->exception->description != (char *) NULL)
436  {
437  (void) ConcatenateMagickString(description," (",MagickPathExtent);
438  (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
439  wand_view->exception->severity,wand_view->exception->description),
441  (void) ConcatenateMagickString(description,")",MagickPathExtent);
442  }
443  return(description);
444 }
445 
446 /*
447 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
448 % %
449 % %
450 % %
451 % G e t W a n d V i e w E x t e n t %
452 % %
453 % %
454 % %
455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456 %
457 % GetWandViewExtent() returns the wand view extent.
458 %
459 % The format of the GetWandViewExtent method is:
460 %
461 % RectangleInfo GetWandViewExtent(const WandView *wand_view)
462 %
463 % A description of each parameter follows:
464 %
465 % o wand_view: the wand view.
466 %
467 */
468 WandExport RectangleInfo GetWandViewExtent(const WandView *wand_view)
469 {
470  assert(wand_view != (WandView *) NULL);
471  assert(wand_view->signature == MagickWandSignature);
472  return(wand_view->extent);
473 }
474 
475 /*
476 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
477 % %
478 % %
479 % %
480 % G e t W a n d V i e w I t e r a t o r %
481 % %
482 % %
483 % %
484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
485 %
486 % GetWandViewIterator() iterates over the wand view in parallel and calls
487 % your get method for each scanline of the view. The pixel extent is
488 % not confined to the image canvas-- that is you can include negative offsets
489 % or widths or heights that exceed the image dimension. Any updates to
490 % the pixels in your callback are ignored.
491 %
492 % The callback signature is:
493 %
494 % MagickBooleanType GetImageViewMethod(const WandView *source,
495 % const ssize_t y,const int thread_id,void *context)
496 %
497 % Use this pragma if the view is not single threaded:
498 %
499 % #pragma omp critical
500 %
501 % to define a section of code in your callback get method that must be
502 % executed by a single thread at a time.
503 %
504 % The format of the GetWandViewIterator method is:
505 %
506 % MagickBooleanType GetWandViewIterator(WandView *source,
507 % GetWandViewMethod get,void *context)
508 %
509 % A description of each parameter follows:
510 %
511 % o source: the source wand view.
512 %
513 % o get: the get callback method.
514 %
515 % o context: the user defined context.
516 %
517 */
518 WandExport MagickBooleanType GetWandViewIterator(WandView *source,
519  GetWandViewMethod get,void *context)
520 {
521  Image
522  *source_image;
523 
524  MagickBooleanType
525  status;
526 
527  MagickOffsetType
528  progress;
529 
530 #if defined(MAGICKCORE_OPENMP_SUPPORT)
531  size_t
532  height;
533 #endif
534 
535  ssize_t
536  y;
537 
538  assert(source != (WandView *) NULL);
539  assert(source->signature == MagickWandSignature);
540  if (get == (GetWandViewMethod) NULL)
541  return(MagickFalse);
542  source_image=source->wand->images;
543  status=MagickTrue;
544  progress=0;
545 #if defined(MAGICKCORE_OPENMP_SUPPORT)
546  height=source->extent.height-source->extent.y;
547  #pragma omp parallel for schedule(static,4) shared(progress,status) \
548  magick_number_threads(source_image,source_image,height,1)
549 #endif
550  for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
551  {
552  const int
553  id = GetOpenMPThreadId();
554 
555  register const Quantum
556  *pixels;
557 
558  register ssize_t
559  x;
560 
561  if (status == MagickFalse)
562  continue;
563  pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
564  source->extent.width,1,source->exception);
565  if (pixels == (const Quantum *) NULL)
566  {
567  status=MagickFalse;
568  continue;
569  }
570  for (x=0; x < (ssize_t) source->extent.width; x++)
571  {
572  PixelSetQuantumPixel(source->image,pixels,source->pixel_wands[id][x]);
573  pixels+=GetPixelChannels(source->image);
574  }
575  if (get(source,y,id,context) == MagickFalse)
576  status=MagickFalse;
577  if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
578  {
579  MagickBooleanType
580  proceed;
581 
582 #if defined(MAGICKCORE_OPENMP_SUPPORT)
583  #pragma omp critical (MagickWand_GetWandViewIterator)
584 #endif
585  proceed=SetImageProgress(source_image,source->description,progress++,
586  source->extent.height);
587  if (proceed == MagickFalse)
588  status=MagickFalse;
589  }
590  }
591  return(status);
592 }
593 
594 /*
595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
596 % %
597 % %
598 % %
599 % G e t W a n d V i e w P i x e l s %
600 % %
601 % %
602 % %
603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604 %
605 % GetWandViewPixels() returns the wand view pixel_wands.
606 %
607 % The format of the GetWandViewPixels method is:
608 %
609 % PixelWand *GetWandViewPixels(const WandView *wand_view)
610 %
611 % A description of each parameter follows:
612 %
613 % o wand_view: the wand view.
614 %
615 */
617 {
618  const int
619  id = GetOpenMPThreadId();
620 
621  assert(wand_view != (WandView *) NULL);
622  assert(wand_view->signature == MagickWandSignature);
623  return(wand_view->pixel_wands[id]);
624 }
625 
626 /*
627 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
628 % %
629 % %
630 % %
631 % G e t W a n d V i e w W a n d %
632 % %
633 % %
634 % %
635 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
636 %
637 % GetWandViewWand() returns the magick wand associated with the wand view.
638 %
639 % The format of the GetWandViewWand method is:
640 %
641 % MagickWand *GetWandViewWand(const WandView *wand_view)
642 %
643 % A description of each parameter follows:
644 %
645 % o wand_view: the wand view.
646 %
647 */
649 {
650  assert(wand_view != (WandView *) NULL);
651  assert(wand_view->signature == MagickWandSignature);
652  return(wand_view->wand);
653 }
654 
655 /*
656 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
657 % %
658 % %
659 % %
660 % I s W a n d V i e w %
661 % %
662 % %
663 % %
664 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
665 %
666 % IsWandView() returns MagickTrue if the the parameter is verified as a wand
667 % view object.
668 %
669 % The format of the IsWandView method is:
670 %
671 % MagickBooleanType IsWandView(const WandView *wand_view)
672 %
673 % A description of each parameter follows:
674 %
675 % o wand_view: the wand view.
676 %
677 */
678 WandExport MagickBooleanType IsWandView(const WandView *wand_view)
679 {
680  size_t
681  length;
682 
683  if (wand_view == (const WandView *) NULL)
684  return(MagickFalse);
685  if (wand_view->signature != MagickWandSignature)
686  return(MagickFalse);
687  length=strlen(WandViewId);
688  if (LocaleNCompare(wand_view->name,WandViewId,length) != 0)
689  return(MagickFalse);
690  return(MagickTrue);
691 }
692 
693 /*
694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
695 % %
696 % %
697 % %
698 % N e w W a n d V i e w %
699 % %
700 % %
701 % %
702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
703 %
704 % NewWandView() returns a wand view required for all other methods in the
705 % Wand View API.
706 %
707 % The format of the NewWandView method is:
708 %
709 % WandView *NewWandView(MagickWand *wand)
710 %
711 % A description of each parameter follows:
712 %
713 % o wand: the wand.
714 %
715 */
716 
717 static PixelWand ***AcquirePixelsThreadSet(const size_t number_wands)
718 {
719  PixelWand
720  ***pixel_wands;
721 
722  register ssize_t
723  i;
724 
725  size_t
726  number_threads;
727 
728  number_threads=GetOpenMPMaximumThreads();
729  pixel_wands=(PixelWand ***) AcquireQuantumMemory(number_threads,
730  sizeof(*pixel_wands));
731  if (pixel_wands == (PixelWand ***) NULL)
732  return((PixelWand ***) NULL);
733  (void) ResetMagickMemory(pixel_wands,0,number_threads*sizeof(*pixel_wands));
734  for (i=0; i < (ssize_t) number_threads; i++)
735  {
736  pixel_wands[i]=NewPixelWands(number_wands);
737  if (pixel_wands[i] == (PixelWand **) NULL)
738  return(DestroyPixelsThreadSet(pixel_wands,number_wands));
739  }
740  return(pixel_wands);
741 }
742 
744 {
745  ExceptionInfo
746  *exception;
747 
748  WandView
749  *wand_view;
750 
751  assert(wand != (MagickWand *) NULL);
752  assert(wand->signature == MagickWandSignature);
753  wand_view=(WandView *) AcquireMagickMemory(sizeof(*wand_view));
754  if (wand_view == (WandView *) NULL)
755  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
756  GetExceptionMessage(errno));
757  (void) ResetMagickMemory(wand_view,0,sizeof(*wand_view));
758  wand_view->id=AcquireWandId();
759  (void) FormatLocaleString(wand_view->name,MagickPathExtent,"%s-%.20g",
760  WandViewId,(double) wand_view->id);
761  wand_view->description=ConstantString("WandView");
762  wand_view->wand=wand;
763  exception=AcquireExceptionInfo();
764  wand_view->view=AcquireVirtualCacheView(wand_view->wand->images,exception);
765  wand_view->extent.width=wand->images->columns;
766  wand_view->extent.height=wand->images->rows;
767  wand_view->pixel_wands=AcquirePixelsThreadSet(wand_view->extent.width);
768  wand_view->exception=exception;
769  if (wand_view->pixel_wands == (PixelWand ***) NULL)
770  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
771  GetExceptionMessage(errno));
772  wand_view->debug=IsEventLogging();
773  wand_view->signature=MagickWandSignature;
774  return(wand_view);
775 }
776 
777 /*
778 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
779 % %
780 % %
781 % %
782 % N e w W a n d V i e w E x t e n t %
783 % %
784 % %
785 % %
786 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
787 %
788 % NewWandViewExtent() returns a wand view required for all other methods
789 % in the Wand View API.
790 %
791 % The format of the NewWandViewExtent method is:
792 %
793 % WandView *NewWandViewExtent(MagickWand *wand,const ssize_t x,
794 % const ssize_t y,const size_t width,const size_t height)
795 %
796 % A description of each parameter follows:
797 %
798 % o wand: the magick wand.
799 %
800 % o x,y,columns,rows: These values define the perimeter of a extent of
801 % pixel_wands view.
802 %
803 */
805  const ssize_t y,const size_t width,const size_t height)
806 {
807  ExceptionInfo
808  *exception;
809 
810  WandView
811  *wand_view;
812 
813  assert(wand != (MagickWand *) NULL);
814  assert(wand->signature == MagickWandSignature);
815  wand_view=(WandView *) AcquireMagickMemory(sizeof(*wand_view));
816  if (wand_view == (WandView *) NULL)
817  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
818  GetExceptionMessage(errno));
819  (void) ResetMagickMemory(wand_view,0,sizeof(*wand_view));
820  wand_view->id=AcquireWandId();
821  (void) FormatLocaleString(wand_view->name,MagickPathExtent,"%s-%.20g",
822  WandViewId,(double) wand_view->id);
823  wand_view->description=ConstantString("WandView");
824  exception=AcquireExceptionInfo();
825  wand_view->view=AcquireVirtualCacheView(wand_view->wand->images,exception);
826  wand_view->wand=wand;
827  wand_view->extent.width=width;
828  wand_view->extent.height=height;
829  wand_view->extent.x=x;
830  wand_view->extent.y=y;
831  wand_view->exception=exception;
832  wand_view->pixel_wands=AcquirePixelsThreadSet(wand_view->extent.width);
833  if (wand_view->pixel_wands == (PixelWand ***) NULL)
834  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
835  GetExceptionMessage(errno));
836  wand_view->debug=IsEventLogging();
837  wand_view->signature=MagickWandSignature;
838  return(wand_view);
839 }
840 
841 /*
842 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
843 % %
844 % %
845 % %
846 % S e t W a n d V i e w D e s c r i p t i o n %
847 % %
848 % %
849 % %
850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
851 %
852 % SetWandViewDescription() associates a description with an image view.
853 %
854 % The format of the SetWandViewDescription method is:
855 %
856 % void SetWandViewDescription(WandView *image_view,const char *description)
857 %
858 % A description of each parameter follows:
859 %
860 % o wand_view: the wand view.
861 %
862 % o description: the wand view description.
863 %
864 */
865 MagickExport void SetWandViewDescription(WandView *wand_view,
866  const char *description)
867 {
868  assert(wand_view != (WandView *) NULL);
869  assert(wand_view->signature == MagickWandSignature);
870  wand_view->description=ConstantString(description);
871 }
872 
873 /*
874 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
875 % %
876 % %
877 % %
878 % S e t W a n d V i e w I t e r a t o r %
879 % %
880 % %
881 % %
882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
883 %
884 % SetWandViewIterator() iterates over the wand view in parallel and calls
885 % your set method for each scanline of the view. The pixel extent is
886 % confined to the image canvas-- that is no negative offsets or widths or
887 % heights that exceed the image dimension. The pixels are initiallly
888 % undefined and any settings you make in the callback method are automagically
889 % synced back to your image.
890 %
891 % The callback signature is:
892 %
893 % MagickBooleanType SetImageViewMethod(ImageView *destination,
894 % const ssize_t y,const int thread_id,void *context)
895 %
896 % Use this pragma if the view is not single threaded:
897 %
898 % #pragma omp critical
899 %
900 % to define a section of code in your callback set method that must be
901 % executed by a single thread at a time.
902 %
903 % The format of the SetWandViewIterator method is:
904 %
905 % MagickBooleanType SetWandViewIterator(WandView *destination,
906 % SetWandViewMethod set,void *context)
907 %
908 % A description of each parameter follows:
909 %
910 % o destination: the wand view.
911 %
912 % o set: the set callback method.
913 %
914 % o context: the user defined context.
915 %
916 */
917 WandExport MagickBooleanType SetWandViewIterator(WandView *destination,
918  SetWandViewMethod set,void *context)
919 {
920  Image
921  *destination_image;
922 
923  MagickBooleanType
924  status;
925 
926  MagickOffsetType
927  progress;
928 
929 #if defined(MAGICKCORE_OPENMP_SUPPORT)
930  size_t
931  height;
932 #endif
933 
934  ssize_t
935  y;
936 
937  assert(destination != (WandView *) NULL);
938  assert(destination->signature == MagickWandSignature);
939  if (set == (SetWandViewMethod) NULL)
940  return(MagickFalse);
941  destination_image=destination->wand->images;
942  status=SetImageStorageClass(destination_image,DirectClass,
943  destination->exception);
944  if (status == MagickFalse)
945  return(MagickFalse);
946  status=MagickTrue;
947  progress=0;
948 #if defined(MAGICKCORE_OPENMP_SUPPORT)
949  height=destination->extent.height-destination->extent.y;
950  #pragma omp parallel for schedule(static,4) shared(progress,status) \
951  magick_number_threads(destination_image,destination_image,height,1)
952 #endif
953  for (y=destination->extent.y; y < (ssize_t) destination->extent.height; y++)
954  {
955  const int
956  id = GetOpenMPThreadId();
957 
958  MagickBooleanType
959  sync;
960 
961  register ssize_t
962  x;
963 
964  register Quantum
965  *magick_restrict pixels;
966 
967  if (status == MagickFalse)
968  continue;
969  pixels=GetCacheViewAuthenticPixels(destination->view,destination->extent.x,
970  y,destination->extent.width,1,destination->exception);
971  if (pixels == (Quantum *) NULL)
972  {
973  status=MagickFalse;
974  continue;
975  }
976  if (set(destination,y,id,context) == MagickFalse)
977  status=MagickFalse;
978  for (x=0; x < (ssize_t) destination->extent.width; x++)
979  {
980  PixelGetQuantumPixel(destination->image,destination->pixel_wands[id][x],
981  pixels);
982  pixels+=GetPixelChannels(destination->image);
983  }
984  sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
985  if (sync == MagickFalse)
986  status=MagickFalse;
987  if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
988  {
989  MagickBooleanType
990  proceed;
991 
992 #if defined(MAGICKCORE_OPENMP_SUPPORT)
993  #pragma omp critical (MagickWand_SetWandViewIterator)
994 #endif
995  proceed=SetImageProgress(destination_image,destination->description,
996  progress++,destination->extent.height);
997  if (proceed == MagickFalse)
998  status=MagickFalse;
999  }
1000  }
1001  return(status);
1002 }
1003 
1004 /*
1005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1006 % %
1007 % %
1008 % %
1009 % T r a n s f e r W a n d V i e w I t e r a t o r %
1010 % %
1011 % %
1012 % %
1013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1014 %
1015 % TransferWandViewIterator() iterates over two wand views in parallel and
1016 % calls your transfer method for each scanline of the view. The source pixel
1017 % extent is not confined to the image canvas-- that is you can include
1018 % negative offsets or widths or heights that exceed the image dimension.
1019 % However, the destination wand view is confined to the image canvas-- that
1020 % is no negative offsets or widths or heights that exceed the image dimension
1021 % are permitted.
1022 %
1023 % The callback signature is:
1024 %
1025 % MagickBooleanType TransferImageViewMethod(const WandView *source,
1026 % WandView *destination,const ssize_t y,const int thread_id,
1027 % void *context)
1028 %
1029 % Use this pragma if the view is not single threaded:
1030 %
1031 % #pragma omp critical
1032 %
1033 % to define a section of code in your callback transfer method that must be
1034 % executed by a single thread at a time.
1035 %
1036 % The format of the TransferWandViewIterator method is:
1037 %
1038 % MagickBooleanType TransferWandViewIterator(WandView *source,
1039 % WandView *destination,TransferWandViewMethod transfer,void *context)
1040 %
1041 % A description of each parameter follows:
1042 %
1043 % o source: the source wand view.
1044 %
1045 % o destination: the destination wand view.
1046 %
1047 % o transfer: the transfer callback method.
1048 %
1049 % o context: the user defined context.
1050 %
1051 */
1053  WandView *destination,TransferWandViewMethod transfer,void *context)
1054 {
1055  Image
1056  *destination_image,
1057  *source_image;
1058 
1059  MagickBooleanType
1060  status;
1061 
1062  MagickOffsetType
1063  progress;
1064 
1065 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1066  size_t
1067  height;
1068 #endif
1069 
1070  ssize_t
1071  y;
1072 
1073  assert(source != (WandView *) NULL);
1074  assert(source->signature == MagickWandSignature);
1075  if (transfer == (TransferWandViewMethod) NULL)
1076  return(MagickFalse);
1077  source_image=source->wand->images;
1078  destination_image=destination->wand->images;
1079  status=SetImageStorageClass(destination_image,DirectClass,
1080  destination->exception);
1081  if (status == MagickFalse)
1082  return(MagickFalse);
1083  status=MagickTrue;
1084  progress=0;
1085 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1086  height=source->extent.height-source->extent.y;
1087  #pragma omp parallel for schedule(static,4) shared(progress,status) \
1088  magick_number_threads(source_image,destination_image,height,1)
1089 #endif
1090  for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1091  {
1092  const int
1093  id = GetOpenMPThreadId();
1094 
1095  MagickBooleanType
1096  sync;
1097 
1098  register const Quantum
1099  *magick_restrict pixels;
1100 
1101  register ssize_t
1102  x;
1103 
1104  register Quantum
1105  *magick_restrict destination_pixels;
1106 
1107  if (status == MagickFalse)
1108  continue;
1109  pixels=GetCacheViewVirtualPixels(source->view,source->extent.x,y,
1110  source->extent.width,1,source->exception);
1111  if (pixels == (const Quantum *) NULL)
1112  {
1113  status=MagickFalse;
1114  continue;
1115  }
1116  for (x=0; x < (ssize_t) source->extent.width; x++)
1117  {
1118  PixelSetQuantumPixel(source->image,pixels,source->pixel_wands[id][x]);
1119  pixels+=GetPixelChannels(source->image);
1120  }
1121  destination_pixels=GetCacheViewAuthenticPixels(destination->view,
1122  destination->extent.x,y,destination->extent.width,1,
1123  destination->exception);
1124  if (destination_pixels == (Quantum *) NULL)
1125  {
1126  status=MagickFalse;
1127  continue;
1128  }
1129  for (x=0; x < (ssize_t) destination->extent.width; x++)
1130  {
1131  PixelSetQuantumPixel(destination->image,destination_pixels,
1132  destination->pixel_wands[id][x]);
1133  destination_pixels+=GetPixelChannels(destination->image);
1134  }
1135  if (transfer(source,destination,y,id,context) == MagickFalse)
1136  status=MagickFalse;
1137  destination_pixels=GetCacheViewAuthenticPixels(destination->view,
1138  destination->extent.x,y,destination->extent.width,1,
1139  destination->exception);
1140  for (x=0; x < (ssize_t) destination->extent.width; x++)
1141  {
1142  PixelGetQuantumPixel(destination->image,destination->pixel_wands[id][x],
1143  destination_pixels);
1144  destination_pixels+=GetPixelChannels(destination->image);
1145  }
1146  sync=SyncCacheViewAuthenticPixels(destination->view,destination->exception);
1147  if (sync == MagickFalse)
1148  status=MagickFalse;
1149  if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1150  {
1151  MagickBooleanType
1152  proceed;
1153 
1154 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1155  #pragma omp critical (MagickWand_TransferWandViewIterator)
1156 #endif
1157  proceed=SetImageProgress(source_image,source->description,progress++,
1158  source->extent.height);
1159  if (proceed == MagickFalse)
1160  status=MagickFalse;
1161  }
1162  }
1163  return(status);
1164 }
1165 
1166 /*
1167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1168 % %
1169 % %
1170 % %
1171 % U p d a t e W a n d V i e w I t e r a t o r %
1172 % %
1173 % %
1174 % %
1175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1176 %
1177 % UpdateWandViewIterator() iterates over the wand view in parallel and calls
1178 % your update method for each scanline of the view. The pixel extent is
1179 % confined to the image canvas-- that is no negative offsets or widths or
1180 % heights that exceed the image dimension are permitted. Updates to pixels
1181 % in your callback are automagically synced back to the image.
1182 %
1183 % The callback signature is:
1184 %
1185 % MagickBooleanType UpdateImageViewMethod(WandView *source,const ssize_t y,
1186 % const int thread_id,void *context)
1187 %
1188 % Use this pragma if the view is not single threaded:
1189 %
1190 % #pragma omp critical
1191 %
1192 % to define a section of code in your callback update method that must be
1193 % executed by a single thread at a time.
1194 %
1195 % The format of the UpdateWandViewIterator method is:
1196 %
1197 % MagickBooleanType UpdateWandViewIterator(WandView *source,
1198 % UpdateWandViewMethod update,void *context)
1199 %
1200 % A description of each parameter follows:
1201 %
1202 % o source: the source wand view.
1203 %
1204 % o update: the update callback method.
1205 %
1206 % o context: the user defined context.
1207 %
1208 */
1209 WandExport MagickBooleanType UpdateWandViewIterator(WandView *source,
1210  UpdateWandViewMethod update,void *context)
1211 {
1212  Image
1213  *source_image;
1214 
1215  MagickBooleanType
1216  status;
1217 
1218  MagickOffsetType
1219  progress;
1220 
1221 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1222  size_t
1223  height;
1224 #endif
1225 
1226  ssize_t
1227  y;
1228 
1229  assert(source != (WandView *) NULL);
1230  assert(source->signature == MagickWandSignature);
1231  if (update == (UpdateWandViewMethod) NULL)
1232  return(MagickFalse);
1233  source_image=source->wand->images;
1234  status=SetImageStorageClass(source_image,DirectClass,source->exception);
1235  if (status == MagickFalse)
1236  return(MagickFalse);
1237  status=MagickTrue;
1238  progress=0;
1239 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1240  height=source->extent.height-source->extent.y;
1241  #pragma omp parallel for schedule(static,4) shared(progress,status) \
1242  magick_number_threads(source_image,source_image,height,1)
1243 #endif
1244  for (y=source->extent.y; y < (ssize_t) source->extent.height; y++)
1245  {
1246  const int
1247  id = GetOpenMPThreadId();
1248 
1249  MagickBooleanType
1250  sync;
1251 
1252  register ssize_t
1253  x;
1254 
1255  register Quantum
1256  *magick_restrict pixels;
1257 
1258  if (status == MagickFalse)
1259  continue;
1260  pixels=GetCacheViewAuthenticPixels(source->view,source->extent.x,y,
1261  source->extent.width,1,source->exception);
1262  if (pixels == (Quantum *) NULL)
1263  {
1264  status=MagickFalse;
1265  continue;
1266  }
1267  for (x=0; x < (ssize_t) source->extent.width; x++)
1268  {
1269  PixelSetQuantumPixel(source->image,pixels,source->pixel_wands[id][x]);
1270  pixels+=GetPixelChannels(source->image);
1271  }
1272  if (update(source,y,id,context) == MagickFalse)
1273  status=MagickFalse;
1274  for (x=0; x < (ssize_t) source->extent.width; x++)
1275  {
1276  PixelGetQuantumPixel(source->image,source->pixel_wands[id][x],pixels);
1277  pixels+=GetPixelChannels(source->image);
1278  }
1279  sync=SyncCacheViewAuthenticPixels(source->view,source->exception);
1280  if (sync == MagickFalse)
1281  status=MagickFalse;
1282  if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
1283  {
1284  MagickBooleanType
1285  proceed;
1286 
1287 #if defined(MAGICKCORE_OPENMP_SUPPORT)
1288  #pragma omp critical (MagickWand_UpdateWandViewIterator)
1289 #endif
1290  proceed=SetImageProgress(source_image,source->description,progress++,
1291  source->extent.height);
1292  if (proceed == MagickFalse)
1293  status=MagickFalse;
1294  }
1295  }
1296  return(status);
1297 }
WandExport MagickBooleanType GetWandViewIterator(WandView *source, GetWandViewMethod get, void *context)
Definition: wand-view.c:518
MagickBooleanType(* DuplexTransferWandViewMethod)(const WandView *, const WandView *, WandView *, const ssize_t, const int, void *)
Definition: wand-view.h:29
#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
MagickBooleanType(*)(*)(*)(* TransferWandViewMethod)(const WandView *, WandView *, const ssize_t, const int, void *)
Definition: wand-view.h:33
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:743
MagickBooleanType(*)(* GetWandViewMethod)(const WandView *, const ssize_t, const int, void *)
Definition: wand-view.h:31
#define WandExport
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
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:1052
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:717
WandExport void RelinquishWandId(const size_t id)
Definition: wand.c:150
MagickBooleanType(*)(*)(*)(*)(* UpdateWandViewMethod)(WandView *, const ssize_t, const int, void *)
Definition: wand-view.h:35
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:865
#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:804
WandExport PixelWand ** GetWandViewPixels(const WandView *wand_view)
Definition: wand-view.c:616
WandExport MagickWand * GetWandViewWand(const WandView *wand_view)
Definition: wand-view.c:648
char name[MagickPathExtent]
Definition: wand-view.c:68
WandExport RectangleInfo GetWandViewExtent(const WandView *wand_view)
Definition: wand-view.c:468
MagickBooleanType(*)(*)(* SetWandViewMethod)(WandView *, const ssize_t, const int, void *)
Definition: wand-view.h:32
WandExport PixelWand ** DestroyPixelWands(PixelWand **wand, const size_t number_wands)
Definition: pixel-wand.c:275
WandExport MagickBooleanType UpdateWandViewIterator(WandView *source, UpdateWandViewMethod update, void *context)
Definition: wand-view.c:1209
MagickWand * wand
Definition: wand-view.c:75
WandExport WandView * CloneWandView(const WandView *wand_view)
Definition: wand-view.c:118
WandExport MagickBooleanType SetWandViewIterator(WandView *destination, SetWandViewMethod set, void *context)
Definition: wand-view.c:917
#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:678
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:413