MagickWand  6.9.12-67
Convert, Edit, Or Compose Bitmap Images
 All Data Structures
deprecate.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % DDDD EEEEE PPPP RRRR EEEEE CCCC AAA TTTTT EEEEE %
7 % D D E P P R R E C A A T E %
8 % D D EEE PPPPP RRRR EEE C AAAAA T EEE %
9 % D D E P R R E C A A T E %
10 % DDDD EEEEE P R R EEEEE CCCC A A T EEEEE %
11 % %
12 % %
13 % MagickWand Deprecated Methods %
14 % %
15 % Software Design %
16 % Cristy %
17 % October 2002 %
18 % %
19 % %
20 % Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
22 % %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
25 % %
26 % https://imagemagick.org/script/license.php %
27 % %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
33 % %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 %
38 */
39 
40 /*
41  Include declarations.
42 */
43 #include "wand/studio.h"
44 #include "wand/MagickWand.h"
45 #include "wand/magick-wand-private.h"
46 #include "wand/wand.h"
47 #include "magick/monitor-private.h"
48 #include "magick/thread-private.h"
49 
50 /*
51  Define declarations.
52 */
53 #define PixelViewId "PixelView"
54 
55 /*
56  Typedef declarations.
57 */
58 struct _PixelView
59 {
60  size_t
61  id;
62 
63  char
64  name[MaxTextExtent];
65 
66  ExceptionInfo
67  *exception;
68 
70  *wand;
71 
72  CacheView
73  *view;
74 
75  RectangleInfo
76  region;
77 
78  size_t
79  number_threads;
80 
81  PixelWand
82  ***pixel_wands;
83 
84  MagickBooleanType
85  debug;
86 
87  size_t
88  signature;
89 };
90 
91 #if !defined(MAGICKCORE_EXCLUDE_DEPRECATED)
92 /*
93 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94 % %
95 % %
96 % %
97 + D r a w A l l o c a t e W a n d %
98 % %
99 % %
100 % %
101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102 %
103 % DrawAllocateWand() allocates an initial drawing wand which is an opaque
104 % handle required by the remaining drawing methods.
105 %
106 % The format of the DrawAllocateWand method is:
107 %
108 % DrawingWand DrawAllocateWand(const DrawInfo *draw_info,Image *image)
109 %
110 % A description of each parameter follows:
111 %
112 % o draw_info: Initial drawing defaults. Set to NULL to use defaults.
113 %
114 % o image: the image to draw on.
115 %
116 */
117 WandExport DrawingWand *DrawAllocateWand(const DrawInfo *draw_info,Image *image)
118 {
119  return(AcquireDrawingWand(draw_info,image));
120 }
121 
122 /*
123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
124 % %
125 % %
126 % %
127 % M a g i c k A v e r a g e I m a g e s %
128 % %
129 % %
130 % %
131 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132 %
133 % MagickAverageImages() average a set of images.
134 %
135 % The format of the MagickAverageImages method is:
136 %
137 % MagickWand *MagickAverageImages(MagickWand *wand)
138 %
139 % A description of each parameter follows:
140 %
141 % o wand: the magick wand.
142 %
143 */
144 
145 static MagickWand *CloneMagickWandFromImages(const MagickWand *wand,
146  Image *images)
147 {
148  MagickWand
149  *clone_wand;
150 
151  assert(wand != (MagickWand *) NULL);
152  assert(wand->signature == WandSignature);
153  if (wand->debug != MagickFalse)
154  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
155  clone_wand=(MagickWand *) AcquireMagickMemory(sizeof(*clone_wand));
156  if (clone_wand == (MagickWand *) NULL)
157  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
158  images->filename);
159  (void) memset(clone_wand,0,sizeof(*clone_wand));
160  clone_wand->id=AcquireWandId();
161  (void) FormatLocaleString(clone_wand->name,MaxTextExtent,"%s-%.20g",
162  MagickWandId,(double) clone_wand->id);
163  clone_wand->exception=AcquireExceptionInfo();
164  InheritException(clone_wand->exception,wand->exception);
165  clone_wand->image_info=CloneImageInfo(wand->image_info);
166  clone_wand->quantize_info=CloneQuantizeInfo(wand->quantize_info);
167  clone_wand->images=images;
168  clone_wand->debug=IsEventLogging();
169  if (clone_wand->debug != MagickFalse)
170  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_wand->name);
171  clone_wand->signature=WandSignature;
172  return(clone_wand);
173 }
174 
175 WandExport MagickWand *MagickAverageImages(MagickWand *wand)
176 {
177  Image
178  *average_image;
179 
180  assert(wand != (MagickWand *) NULL);
181  assert(wand->signature == WandSignature);
182  if (wand->debug != MagickFalse)
183  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
184  if (wand->images == (Image *) NULL)
185  return((MagickWand *) NULL);
186  average_image=EvaluateImages(wand->images,MeanEvaluateOperator,
187  wand->exception);
188  if (average_image == (Image *) NULL)
189  return((MagickWand *) NULL);
190  return(CloneMagickWandFromImages(wand,average_image));
191 }
192 
193 /*
194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
195 % %
196 % %
197 % %
198 % C l o n e P i x e l V i e w %
199 % %
200 % %
201 % %
202 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203 %
204 % ClonePixelView() makes a copy of the specified pixel view.
205 %
206 % The format of the ClonePixelView method is:
207 %
208 % PixelView *ClonePixelView(const PixelView *pixel_view)
209 %
210 % A description of each parameter follows:
211 %
212 % o pixel_view: the pixel view.
213 %
214 */
215 WandExport PixelView *ClonePixelView(const PixelView *pixel_view)
216 {
217  PixelView
218  *clone_view;
219 
220  ssize_t
221  i;
222 
223  assert(pixel_view != (PixelView *) NULL);
224  assert(pixel_view->signature == WandSignature);
225  if (pixel_view->debug != MagickFalse)
226  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",pixel_view->name);
227  clone_view=(PixelView *) AcquireMagickMemory(sizeof(*clone_view));
228  if (clone_view == (PixelView *) NULL)
229  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
230  pixel_view->name);
231  (void) memset(clone_view,0,sizeof(*clone_view));
232  clone_view->id=AcquireWandId();
233  (void) FormatLocaleString(clone_view->name,MaxTextExtent,"%s-%.20g",
234  PixelViewId,(double) clone_view->id);
235  clone_view->exception=AcquireExceptionInfo();
236  InheritException(clone_view->exception,pixel_view->exception);
237  clone_view->view=CloneCacheView(pixel_view->view);
238  clone_view->region=pixel_view->region;
239  clone_view->number_threads=pixel_view->number_threads;
240  for (i=0; i < (ssize_t) pixel_view->number_threads; i++)
241  clone_view->pixel_wands[i]=ClonePixelWands((const PixelWand **)
242  pixel_view->pixel_wands[i],pixel_view->region.width);
243  clone_view->debug=pixel_view->debug;
244  if (clone_view->debug != MagickFalse)
245  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_view->name);
246  clone_view->signature=WandSignature;
247  return(clone_view);
248 }
249 
250 /*
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 % %
253 % %
254 % %
255 % D e s t r o y P i x e l V i e w %
256 % %
257 % %
258 % %
259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260 %
261 % DestroyPixelView() deallocates memory associated with a pixel view.
262 %
263 % The format of the DestroyPixelView method is:
264 %
265 % PixelView *DestroyPixelView(PixelView *pixel_view,
266 % const size_t number_wands,const size_t number_threads)
267 %
268 % A description of each parameter follows:
269 %
270 % o pixel_view: the pixel view.
271 %
272 % o number_wand: the number of pixel wands.
273 %
274 % o number_threads: number of threads.
275 %
276 */
277 
278 static PixelWand ***DestroyPixelsTLS(PixelWand ***pixel_wands,
279  const size_t number_wands,const size_t number_threads)
280 {
281  ssize_t
282  i;
283 
284  assert(pixel_wands != (PixelWand ***) NULL);
285  for (i=0; i < (ssize_t) number_threads; i++)
286  if (pixel_wands[i] != (PixelWand **) NULL)
287  pixel_wands[i]=DestroyPixelWands(pixel_wands[i],number_wands);
288  pixel_wands=(PixelWand ***) RelinquishMagickMemory(pixel_wands);
289  return(pixel_wands);
290 }
291 
292 WandExport PixelView *DestroyPixelView(PixelView *pixel_view)
293 {
294  assert(pixel_view != (PixelView *) NULL);
295  assert(pixel_view->signature == WandSignature);
296  pixel_view->pixel_wands=DestroyPixelsTLS(pixel_view->pixel_wands,
297  pixel_view->region.width,pixel_view->number_threads);
298  pixel_view->view=DestroyCacheView(pixel_view->view);
299  pixel_view->exception=DestroyExceptionInfo(pixel_view->exception);
300  pixel_view->signature=(~WandSignature);
301  RelinquishWandId(pixel_view->id);
302  pixel_view=(PixelView *) RelinquishMagickMemory(pixel_view);
303  return(pixel_view);
304 }
305 
306 /*
307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
308 % %
309 % %
310 % %
311 % D u p l e x T r a n s f e r P i x e l V i e w I t e r a t o r %
312 % %
313 % %
314 % %
315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
316 %
317 % DuplexTransferPixelViewIterator() iterates over three pixel views in
318 % parallel and calls your transfer method for each scanline of the view. The
319 % source and duplex pixel region is not confined to the image canvas-- that is
320 % you can include negative offsets or widths or heights that exceed the image
321 % dimension. However, the destination pixel view is confined to the image
322 % canvas-- that is no negative offsets or widths or heights that exceed the
323 % image dimension are permitted.
324 %
325 % Use this pragma:
326 %
327 % #pragma omp critical
328 %
329 % to define a section of code in your callback transfer method that must be
330 % executed by a single thread at a time.
331 %
332 % The format of the DuplexTransferPixelViewIterator method is:
333 %
334 % MagickBooleanType DuplexTransferPixelViewIterator(PixelView *source,
335 % PixelView *duplex,PixelView *destination,
336 % DuplexTransferPixelViewMethod transfer,void *context)
337 %
338 % A description of each parameter follows:
339 %
340 % o source: the source pixel view.
341 %
342 % o duplex: the duplex pixel view.
343 %
344 % o destination: the destination pixel view.
345 %
346 % o transfer: the transfer callback method.
347 %
348 % o context: the user defined context.
349 %
350 */
351 WandExport MagickBooleanType DuplexTransferPixelViewIterator(
352  PixelView *source,PixelView *duplex,PixelView *destination,
353  DuplexTransferPixelViewMethod transfer,void *context)
354 {
355 #define DuplexTransferPixelViewTag "PixelView/DuplexTransfer"
356 
357  ExceptionInfo
358  *exception;
359 
360  Image
361  *destination_image,
362  *duplex_image,
363  *source_image;
364 
365  MagickBooleanType
366  status;
367 
368  MagickOffsetType
369  progress;
370 
371  ssize_t
372  y;
373 
374  assert(source != (PixelView *) NULL);
375  assert(source->signature == WandSignature);
376  if (transfer == (DuplexTransferPixelViewMethod) NULL)
377  return(MagickFalse);
378  source_image=source->wand->images;
379  duplex_image=duplex->wand->images;
380  destination_image=destination->wand->images;
381  if (SetImageStorageClass(destination_image,DirectClass) == MagickFalse)
382  return(MagickFalse);
383  status=MagickTrue;
384  progress=0;
385  exception=destination->exception;
386 #if defined(MAGICKCORE_OPENMP_SUPPORT)
387  #pragma omp parallel for schedule(static) shared(progress,status)
388 #endif
389  for (y=source->region.y; y < (ssize_t) source->region.height; y++)
390  {
391  const int
392  id = GetOpenMPThreadId();
393 
394  MagickBooleanType
395  sync;
396 
397  const IndexPacket
398  *magick_restrict duplex_indexes,
399  *magick_restrict indexes;
400 
401  const PixelPacket
402  *magick_restrict duplex_pixels,
403  *magick_restrict pixels;
404 
405  IndexPacket
406  *magick_restrict destination_indexes;
407 
408  ssize_t
409  x;
410 
411  PixelPacket
412  *magick_restrict destination_pixels;
413 
414  if (status == MagickFalse)
415  continue;
416  pixels=GetCacheViewVirtualPixels(source->view,source->region.x,y,
417  source->region.width,1,source->exception);
418  if (pixels == (const PixelPacket *) NULL)
419  {
420  status=MagickFalse;
421  continue;
422  }
423  indexes=GetCacheViewVirtualIndexQueue(source->view);
424  for (x=0; x < (ssize_t) source->region.width; x++)
425  PixelSetQuantumColor(source->pixel_wands[id][x],pixels+x);
426  if (source_image->colorspace == CMYKColorspace)
427  for (x=0; x < (ssize_t) source->region.width; x++)
428  PixelSetBlackQuantum(source->pixel_wands[id][x],
429  GetPixelIndex(indexes+x));
430  if (source_image->storage_class == PseudoClass)
431  for (x=0; x < (ssize_t) source->region.width; x++)
432  PixelSetIndex(source->pixel_wands[id][x],
433  GetPixelIndex(indexes+x));
434  duplex_pixels=GetCacheViewVirtualPixels(duplex->view,duplex->region.x,y,
435  duplex->region.width,1,duplex->exception);
436  if (duplex_pixels == (const PixelPacket *) NULL)
437  {
438  status=MagickFalse;
439  continue;
440  }
441  duplex_indexes=GetCacheViewVirtualIndexQueue(duplex->view);
442  for (x=0; x < (ssize_t) duplex->region.width; x++)
443  PixelSetQuantumColor(duplex->pixel_wands[id][x],duplex_pixels+x);
444  if (duplex_image->colorspace == CMYKColorspace)
445  for (x=0; x < (ssize_t) duplex->region.width; x++)
446  PixelSetBlackQuantum(duplex->pixel_wands[id][x],
447  GetPixelIndex(duplex_indexes+x));
448  if (duplex_image->storage_class == PseudoClass)
449  for (x=0; x < (ssize_t) duplex->region.width; x++)
450  PixelSetIndex(duplex->pixel_wands[id][x],
451  GetPixelIndex(duplex_indexes+x));
452  destination_pixels=GetCacheViewAuthenticPixels(destination->view,
453  destination->region.x,y,destination->region.width,1,exception);
454  if (destination_pixels == (PixelPacket *) NULL)
455  {
456  status=MagickFalse;
457  continue;
458  }
459  destination_indexes=GetCacheViewAuthenticIndexQueue(destination->view);
460  for (x=0; x < (ssize_t) destination->region.width; x++)
461  PixelSetQuantumColor(destination->pixel_wands[id][x],
462  destination_pixels+x);
463  if (destination_image->colorspace == CMYKColorspace)
464  for (x=0; x < (ssize_t) destination->region.width; x++)
465  PixelSetBlackQuantum(destination->pixel_wands[id][x],
466  GetPixelIndex(destination_indexes+x));
467  if (destination_image->storage_class == PseudoClass)
468  for (x=0; x < (ssize_t) destination->region.width; x++)
469  PixelSetIndex(destination->pixel_wands[id][x],
470  GetPixelIndex(destination_indexes+x));
471  if (transfer(source,duplex,destination,context) == MagickFalse)
472  status=MagickFalse;
473  for (x=0; x < (ssize_t) destination->region.width; x++)
474  PixelGetQuantumColor(destination->pixel_wands[id][x],
475  destination_pixels+x);
476  if (destination_image->colorspace == CMYKColorspace)
477  for (x=0; x < (ssize_t) destination->region.width; x++)
478  SetPixelIndex(destination_indexes+x,PixelGetBlackQuantum(
479  destination->pixel_wands[id][x]));
480  sync=SyncCacheViewAuthenticPixels(destination->view,exception);
481  if (sync == MagickFalse)
482  {
483  InheritException(destination->exception,GetCacheViewException(
484  source->view));
485  status=MagickFalse;
486  }
487  if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
488  {
489  MagickBooleanType
490  proceed;
491 
492 
493 #if defined(MAGICKCORE_OPENMP_SUPPORT)
494  #pragma omp atomic
495 #endif
496  progress++;
497  proceed=SetImageProgress(source_image,DuplexTransferPixelViewTag,
498  progress,source->region.height);
499  if (proceed == MagickFalse)
500  status=MagickFalse;
501  }
502  }
503  return(status);
504 }
505 
506 /*
507 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
508 % %
509 % %
510 % %
511 % G e t P i x e l V i e w E x c e p t i o n %
512 % %
513 % %
514 % %
515 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
516 %
517 % GetPixelViewException() returns the severity, reason, and description of any
518 % error that occurs when utilizing a pixel view.
519 %
520 % The format of the GetPixelViewException method is:
521 %
522 % char *GetPixelViewException(const PixelWand *pixel_view,
523 % ExceptionType *severity)
524 %
525 % A description of each parameter follows:
526 %
527 % o pixel_view: the pixel pixel_view.
528 %
529 % o severity: the severity of the error is returned here.
530 %
531 */
532 WandExport char *GetPixelViewException(const PixelView *pixel_view,
533  ExceptionType *severity)
534 {
535  char
536  *description;
537 
538  assert(pixel_view != (const PixelView *) NULL);
539  assert(pixel_view->signature == WandSignature);
540  if (pixel_view->debug != MagickFalse)
541  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",pixel_view->name);
542  assert(severity != (ExceptionType *) NULL);
543  *severity=pixel_view->exception->severity;
544  description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
545  sizeof(*description));
546  if (description == (char *) NULL)
547  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
548  pixel_view->name);
549  *description='\0';
550  if (pixel_view->exception->reason != (char *) NULL)
551  (void) CopyMagickString(description,GetLocaleExceptionMessage(
552  pixel_view->exception->severity,pixel_view->exception->reason),
553  MaxTextExtent);
554  if (pixel_view->exception->description != (char *) NULL)
555  {
556  (void) ConcatenateMagickString(description," (",MaxTextExtent);
557  (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
558  pixel_view->exception->severity,pixel_view->exception->description),
559  MaxTextExtent);
560  (void) ConcatenateMagickString(description,")",MaxTextExtent);
561  }
562  return(description);
563 }
564 
565 /*
566 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
567 % %
568 % %
569 % %
570 % G e t P i x e l V i e w H e i g h t %
571 % %
572 % %
573 % %
574 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
575 %
576 % GetPixelViewHeight() returns the pixel view height.
577 %
578 % The format of the GetPixelViewHeight method is:
579 %
580 % size_t GetPixelViewHeight(const PixelView *pixel_view)
581 %
582 % A description of each parameter follows:
583 %
584 % o pixel_view: the pixel view.
585 %
586 */
587 WandExport size_t GetPixelViewHeight(const PixelView *pixel_view)
588 {
589  assert(pixel_view != (PixelView *) NULL);
590  assert(pixel_view->signature == WandSignature);
591  return(pixel_view->region.height);
592 }
593 
594 /*
595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
596 % %
597 % %
598 % %
599 % G e t P i x e l V i e w I t e r a t o r %
600 % %
601 % %
602 % %
603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604 %
605 % GetPixelViewIterator() iterates over the pixel view in parallel and calls
606 % your get method for each scanline of the view. The pixel region is
607 % not confined to the image canvas-- that is you can include negative offsets
608 % or widths or heights that exceed the image dimension. Any updates to
609 % the pixels in your callback are ignored.
610 %
611 % Use this pragma:
612 %
613 % #pragma omp critical
614 %
615 % to define a section of code in your callback get method that must be
616 % executed by a single thread at a time.
617 %
618 % The format of the GetPixelViewIterator method is:
619 %
620 % MagickBooleanType GetPixelViewIterator(PixelView *source,
621 % GetPixelViewMethod get,void *context)
622 %
623 % A description of each parameter follows:
624 %
625 % o source: the source pixel view.
626 %
627 % o get: the get callback method.
628 %
629 % o context: the user defined context.
630 %
631 */
632 WandExport MagickBooleanType GetPixelViewIterator(PixelView *source,
633  GetPixelViewMethod get,void *context)
634 {
635 #define GetPixelViewTag "PixelView/Get"
636 
637  Image
638  *source_image;
639 
640  MagickBooleanType
641  status;
642 
643  MagickOffsetType
644  progress;
645 
646  ssize_t
647  y;
648 
649  assert(source != (PixelView *) NULL);
650  assert(source->signature == WandSignature);
651  if (get == (GetPixelViewMethod) NULL)
652  return(MagickFalse);
653  source_image=source->wand->images;
654  status=MagickTrue;
655  progress=0;
656 #if defined(MAGICKCORE_OPENMP_SUPPORT)
657  #pragma omp parallel for schedule(static) shared(progress,status)
658 #endif
659  for (y=source->region.y; y < (ssize_t) source->region.height; y++)
660  {
661  const int
662  id = GetOpenMPThreadId();
663 
664  const IndexPacket
665  *indexes;
666 
667  const PixelPacket
668  *pixels;
669 
670  ssize_t
671  x;
672 
673  if (status == MagickFalse)
674  continue;
675  pixels=GetCacheViewVirtualPixels(source->view,source->region.x,y,
676  source->region.width,1,source->exception);
677  if (pixels == (const PixelPacket *) NULL)
678  {
679  status=MagickFalse;
680  continue;
681  }
682  indexes=GetCacheViewVirtualIndexQueue(source->view);
683  for (x=0; x < (ssize_t) source->region.width; x++)
684  PixelSetQuantumColor(source->pixel_wands[id][x],pixels+x);
685  if (source_image->colorspace == CMYKColorspace)
686  for (x=0; x < (ssize_t) source->region.width; x++)
687  PixelSetBlackQuantum(source->pixel_wands[id][x],
688  GetPixelIndex(indexes+x));
689  if (source_image->storage_class == PseudoClass)
690  for (x=0; x < (ssize_t) source->region.width; x++)
691  PixelSetIndex(source->pixel_wands[id][x],
692  GetPixelIndex(indexes+x));
693  if (get(source,context) == MagickFalse)
694  status=MagickFalse;
695  if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
696  {
697  MagickBooleanType
698  proceed;
699 
700 #if defined(MAGICKCORE_OPENMP_SUPPORT)
701  #pragma omp atomic
702 #endif
703  progress++;
704  proceed=SetImageProgress(source_image,GetPixelViewTag,progress,
705  source->region.height);
706  if (proceed == MagickFalse)
707  status=MagickFalse;
708  }
709  }
710  return(status);
711 }
712 
713 /*
714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
715 % %
716 % %
717 % %
718 % G e t P i x e l V i e w P i x e l s %
719 % %
720 % %
721 % %
722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
723 %
724 % GetPixelViewPixels() returns the pixel view pixel_wands.
725 %
726 % The format of the GetPixelViewPixels method is:
727 %
728 % PixelWand *GetPixelViewPixels(const PixelView *pixel_view)
729 %
730 % A description of each parameter follows:
731 %
732 % o pixel_view: the pixel view.
733 %
734 */
735 WandExport PixelWand **GetPixelViewPixels(const PixelView *pixel_view)
736 {
737  const int
738  id = GetOpenMPThreadId();
739 
740  assert(pixel_view != (PixelView *) NULL);
741  assert(pixel_view->signature == WandSignature);
742  return(pixel_view->pixel_wands[id]);
743 }
744 
745 /*
746 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
747 % %
748 % %
749 % %
750 % G e t P i x e l V i e w W a n d %
751 % %
752 % %
753 % %
754 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
755 %
756 % GetPixelViewWand() returns the magick wand associated with the pixel view.
757 %
758 % The format of the GetPixelViewWand method is:
759 %
760 % MagickWand *GetPixelViewWand(const PixelView *pixel_view)
761 %
762 % A description of each parameter follows:
763 %
764 % o pixel_view: the pixel view.
765 %
766 */
767 WandExport MagickWand *GetPixelViewWand(const PixelView *pixel_view)
768 {
769  assert(pixel_view != (PixelView *) NULL);
770  assert(pixel_view->signature == WandSignature);
771  return(pixel_view->wand);
772 }
773 
774 /*
775 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
776 % %
777 % %
778 % %
779 % G e t P i x e l V i e w W i d t h %
780 % %
781 % %
782 % %
783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
784 %
785 % GetPixelViewWidth() returns the pixel view width.
786 %
787 % The format of the GetPixelViewWidth method is:
788 %
789 % size_t GetPixelViewWidth(const PixelView *pixel_view)
790 %
791 % A description of each parameter follows:
792 %
793 % o pixel_view: the pixel view.
794 %
795 */
796 WandExport size_t GetPixelViewWidth(const PixelView *pixel_view)
797 {
798  assert(pixel_view != (PixelView *) NULL);
799  assert(pixel_view->signature == WandSignature);
800  return(pixel_view->region.width);
801 }
802 
803 /*
804 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
805 % %
806 % %
807 % %
808 % G e t P i x e l V i e w X %
809 % %
810 % %
811 % %
812 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
813 %
814 % GetPixelViewX() returns the pixel view x offset.
815 %
816 % The format of the GetPixelViewX method is:
817 %
818 % ssize_t GetPixelViewX(const PixelView *pixel_view)
819 %
820 % A description of each parameter follows:
821 %
822 % o pixel_view: the pixel view.
823 %
824 */
825 WandExport ssize_t GetPixelViewX(const PixelView *pixel_view)
826 {
827  assert(pixel_view != (PixelView *) NULL);
828  assert(pixel_view->signature == WandSignature);
829  return(pixel_view->region.x);
830 }
831 
832 /*
833 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
834 % %
835 % %
836 % %
837 % G e t P i x e l V i e w Y %
838 % %
839 % %
840 % %
841 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
842 %
843 % GetPixelViewY() returns the pixel view y offset.
844 %
845 % The format of the GetPixelViewY method is:
846 %
847 % ssize_t GetPixelViewY(const PixelView *pixel_view)
848 %
849 % A description of each parameter follows:
850 %
851 % o pixel_view: the pixel view.
852 %
853 */
854 WandExport ssize_t GetPixelViewY(const PixelView *pixel_view)
855 {
856  assert(pixel_view != (PixelView *) NULL);
857  assert(pixel_view->signature == WandSignature);
858  return(pixel_view->region.y);
859 }
860 
861 /*
862 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
863 % %
864 % %
865 % %
866 % I s P i x e l V i e w %
867 % %
868 % %
869 % %
870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
871 %
872 % IsPixelView() returns MagickTrue if the parameter is verified as a pixel
873 % view container.
874 %
875 % The format of the IsPixelView method is:
876 %
877 % MagickBooleanType IsPixelView(const PixelView *pixel_view)
878 %
879 % A description of each parameter follows:
880 %
881 % o pixel_view: the pixel view.
882 %
883 */
884 WandExport MagickBooleanType IsPixelView(const PixelView *pixel_view)
885 {
886  size_t
887  length;
888 
889  if (pixel_view == (const PixelView *) NULL)
890  return(MagickFalse);
891  if (pixel_view->signature != WandSignature)
892  return(MagickFalse);
893  length=strlen(PixelViewId);
894  if (LocaleNCompare(pixel_view->name,PixelViewId,length) != 0)
895  return(MagickFalse);
896  return(MagickTrue);
897 }
898 
899 /*
900 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
901 % %
902 % %
903 % %
904 % M a g i c k C l i p P a t h I m a g e %
905 % %
906 % %
907 % %
908 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
909 %
910 % MagickClipPathImage() clips along the named paths from the 8BIM profile, if
911 % present. Later operations take effect inside the path. Id may be a number
912 % if preceded with #, to work on a numbered path, e.g., "#1" to use the first
913 % path.
914 %
915 % The format of the MagickClipPathImage method is:
916 %
917 % MagickBooleanType MagickClipPathImage(MagickWand *wand,
918 % const char *pathname,const MagickBooleanType inside)
919 %
920 % A description of each parameter follows:
921 %
922 % o wand: the magick wand.
923 %
924 % o pathname: name of clipping path resource. If name is preceded by #, use
925 % clipping path numbered by name.
926 %
927 % o inside: if non-zero, later operations take effect inside clipping path.
928 % Otherwise later operations take effect outside clipping path.
929 %
930 */
931 WandExport MagickBooleanType MagickClipPathImage(MagickWand *wand,
932  const char *pathname,const MagickBooleanType inside)
933 {
934  return(MagickClipImagePath(wand,pathname,inside));
935 }
936 /*
937 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
938 % %
939 % %
940 % %
941 % D r a w G e t F i l l A l p h a %
942 % %
943 % %
944 % %
945 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
946 %
947 % DrawGetFillAlpha() returns the alpha used when drawing using the fill
948 % color or fill texture. Fully opaque is 1.0.
949 %
950 % The format of the DrawGetFillAlpha method is:
951 %
952 % double DrawGetFillAlpha(const DrawingWand *wand)
953 %
954 % A description of each parameter follows:
955 %
956 % o wand: the drawing wand.
957 %
958 */
959 WandExport double DrawGetFillAlpha(const DrawingWand *wand)
960 {
961  return(DrawGetFillOpacity(wand));
962 }
963 
964 /*
965 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
966 % %
967 % %
968 % %
969 % D r a w G e t S t r o k e A l p h a %
970 % %
971 % %
972 % %
973 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
974 %
975 % DrawGetStrokeAlpha() returns the alpha of stroked object outlines.
976 %
977 % The format of the DrawGetStrokeAlpha method is:
978 %
979 % double DrawGetStrokeAlpha(const DrawingWand *wand)
980 %
981 % A description of each parameter follows:
982 %
983 % o wand: the drawing wand.
984 */
985 WandExport double DrawGetStrokeAlpha(const DrawingWand *wand)
986 {
987  return(DrawGetStrokeOpacity(wand));
988 }
989 
990 /*
991 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
992 % %
993 % %
994 % %
995 % D r a w P e e k G r a p h i c W a n d %
996 % %
997 % %
998 % %
999 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1000 %
1001 % DrawPeekGraphicWand() returns the current drawing wand.
1002 %
1003 % The format of the PeekDrawingWand method is:
1004 %
1005 % DrawInfo *DrawPeekGraphicWand(const DrawingWand *wand)
1006 %
1007 % A description of each parameter follows:
1008 %
1009 % o wand: the drawing wand.
1010 %
1011 */
1012 WandExport DrawInfo *DrawPeekGraphicWand(const DrawingWand *wand)
1013 {
1014  return(PeekDrawingWand(wand));
1015 }
1016 
1017 /*
1018 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1019 % %
1020 % %
1021 % %
1022 % D r a w P o p G r a p h i c C o n t e x t %
1023 % %
1024 % %
1025 % %
1026 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1027 %
1028 % DrawPopGraphicContext() destroys the current drawing wand and returns to the
1029 % previously pushed drawing wand. Multiple drawing wands may exist. It is an
1030 % error to attempt to pop more drawing wands than have been pushed, and it is
1031 % proper form to pop all drawing wands which have been pushed.
1032 %
1033 % The format of the DrawPopGraphicContext method is:
1034 %
1035 % MagickBooleanType DrawPopGraphicContext(DrawingWand *wand)
1036 %
1037 % A description of each parameter follows:
1038 %
1039 % o wand: the drawing wand.
1040 %
1041 */
1042 WandExport void DrawPopGraphicContext(DrawingWand *wand)
1043 {
1044  (void) PopDrawingWand(wand);
1045 }
1046 
1047 /*
1048 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1049 % %
1050 % %
1051 % %
1052 % D r a w P u s h G r a p h i c C o n t e x t %
1053 % %
1054 % %
1055 % %
1056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1057 %
1058 % DrawPushGraphicContext() clones the current drawing wand to create a new
1059 % drawing wand. The original drawing wand(s) may be returned to by
1060 % invoking PopDrawingWand(). The drawing wands are stored on a drawing wand
1061 % stack. For every Pop there must have already been an equivalent Push.
1062 %
1063 % The format of the DrawPushGraphicContext method is:
1064 %
1065 % MagickBooleanType DrawPushGraphicContext(DrawingWand *wand)
1066 %
1067 % A description of each parameter follows:
1068 %
1069 % o wand: the drawing wand.
1070 %
1071 */
1072 WandExport void DrawPushGraphicContext(DrawingWand *wand)
1073 {
1074  (void) PushDrawingWand(wand);
1075 }
1076 
1077 /*
1078 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1079 % %
1080 % %
1081 % %
1082 % D r a w S e t F i l l A l p h a %
1083 % %
1084 % %
1085 % %
1086 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1087 %
1088 % DrawSetFillAlpha() sets the alpha to use when drawing using the fill
1089 % color or fill texture. Fully opaque is 1.0.
1090 %
1091 % The format of the DrawSetFillAlpha method is:
1092 %
1093 % void DrawSetFillAlpha(DrawingWand *wand,const double fill_alpha)
1094 %
1095 % A description of each parameter follows:
1096 %
1097 % o wand: the drawing wand.
1098 %
1099 % o fill_alpha: fill alpha
1100 %
1101 */
1102 WandExport void DrawSetFillAlpha(DrawingWand *wand,const double fill_alpha)
1103 {
1104  DrawSetFillOpacity(wand,fill_alpha);
1105 }
1106 
1107 /*
1108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1109 % %
1110 % %
1111 % %
1112 % D r a w S e t S t r o k e A l p h a %
1113 % %
1114 % %
1115 % %
1116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1117 %
1118 % DrawSetStrokeAlpha() specifies the alpha of stroked object outlines.
1119 %
1120 % The format of the DrawSetStrokeAlpha method is:
1121 %
1122 % void DrawSetStrokeAlpha(DrawingWand *wand,const double stroke_alpha)
1123 %
1124 % A description of each parameter follows:
1125 %
1126 % o wand: the drawing wand.
1127 %
1128 % o stroke_alpha: stroke alpha. The value 1.0 is opaque.
1129 %
1130 */
1131 WandExport void DrawSetStrokeAlpha(DrawingWand *wand,const double stroke_alpha)
1132 {
1133  DrawSetStrokeOpacity(wand,stroke_alpha);
1134 }
1135 
1136 /*
1137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1138 % %
1139 % %
1140 % %
1141 % M a g i c k C o l o r F l o o d f i l l I m a g e %
1142 % %
1143 % %
1144 % %
1145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1146 %
1147 % MagickColorFloodfillImage() changes the color value of any pixel that matches
1148 % target and is an immediate neighbor. If the method FillToBorderMethod is
1149 % specified, the color value is changed for any neighbor pixel that does not
1150 % match the bordercolor member of image.
1151 %
1152 % The format of the MagickColorFloodfillImage method is:
1153 %
1154 % MagickBooleanType MagickColorFloodfillImage(MagickWand *wand,
1155 % const PixelWand *fill,const double fuzz,const PixelWand *bordercolor,
1156 % const ssize_t x,const ssize_t y)
1157 %
1158 % A description of each parameter follows:
1159 %
1160 % o wand: the magick wand.
1161 %
1162 % o fill: the floodfill color pixel wand.
1163 %
1164 % o fuzz: By default target must match a particular pixel color
1165 % exactly. However, in many cases two colors may differ by a small amount.
1166 % The fuzz member of image defines how much tolerance is acceptable to
1167 % consider two colors as the same. For example, set fuzz to 10 and the
1168 % color red at intensities of 100 and 102 respectively are now interpreted
1169 % as the same color for the purposes of the floodfill.
1170 %
1171 % o bordercolor: the border color pixel wand.
1172 %
1173 % o x,y: the starting location of the operation.
1174 %
1175 */
1176 WandExport MagickBooleanType MagickColorFloodfillImage(MagickWand *wand,
1177  const PixelWand *fill,const double fuzz,const PixelWand *bordercolor,
1178  const ssize_t x,const ssize_t y)
1179 {
1180  DrawInfo
1181  *draw_info;
1182 
1183  MagickBooleanType
1184  status;
1185 
1186  PixelPacket
1187  target;
1188 
1189  assert(wand != (MagickWand *) NULL);
1190  assert(wand->signature == WandSignature);
1191  if (wand->debug != MagickFalse)
1192  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1193  if (wand->images == (Image *) NULL)
1194  ThrowWandException(WandError,"ContainsNoImages",wand->name);
1195  draw_info=CloneDrawInfo(wand->image_info,(DrawInfo *) NULL);
1196  PixelGetQuantumColor(fill,&draw_info->fill);
1197  (void) GetOneVirtualPixel(wand->images,x % wand->images->columns,
1198  y % wand->images->rows,&target,wand->exception);
1199  if (bordercolor != (PixelWand *) NULL)
1200  PixelGetQuantumColor(bordercolor,&target);
1201  wand->images->fuzz=fuzz;
1202  status=ColorFloodfillImage(wand->images,draw_info,target,x,y,
1203  bordercolor != (PixelWand *) NULL ? FillToBorderMethod : FloodfillMethod);
1204  if (status == MagickFalse)
1205  InheritException(wand->exception,&wand->images->exception);
1206  draw_info=DestroyDrawInfo(draw_info);
1207  return(status);
1208 }
1209 
1210 /*
1211 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1212 % %
1213 % %
1214 % %
1215 % M a g i c k D e s c r i b e I m a g e %
1216 % %
1217 % %
1218 % %
1219 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1220 %
1221 % MagickDescribeImage() identifies an image by printing its attributes to the
1222 % file. Attributes include the image width, height, size, and others.
1223 %
1224 % The format of the MagickDescribeImage method is:
1225 %
1226 % const char *MagickDescribeImage(MagickWand *wand)
1227 %
1228 % A description of each parameter follows:
1229 %
1230 % o wand: the magick wand.
1231 %
1232 */
1233 WandExport char *MagickDescribeImage(MagickWand *wand)
1234 {
1235  return(MagickIdentifyImage(wand));
1236 }
1237 
1238 /*
1239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1240 % %
1241 % %
1242 % %
1243 % M a g i c k F l a t t e n I m a g e s %
1244 % %
1245 % %
1246 % %
1247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1248 %
1249 % MagickFlattenImages() merges a sequence of images. This useful for
1250 % combining Photoshop layers into a single image.
1251 %
1252 % The format of the MagickFlattenImages method is:
1253 %
1254 % MagickWand *MagickFlattenImages(MagickWand *wand)
1255 %
1256 % A description of each parameter follows:
1257 %
1258 % o wand: the magick wand.
1259 %
1260 */
1261 WandExport MagickWand *MagickFlattenImages(MagickWand *wand)
1262 {
1263  Image
1264  *flatten_image;
1265 
1266  assert(wand != (MagickWand *) NULL);
1267  assert(wand->signature == WandSignature);
1268  if (wand->debug != MagickFalse)
1269  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1270  if (wand->images == (Image *) NULL)
1271  return((MagickWand *) NULL);
1272  flatten_image=FlattenImages(wand->images,wand->exception);
1273  if (flatten_image == (Image *) NULL)
1274  return((MagickWand *) NULL);
1275  return(CloneMagickWandFromImages(wand,flatten_image));
1276 }
1277 
1278 /*
1279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1280 % %
1281 % %
1282 % %
1283 % M a g i c k G e t I m a g e A t t r i b u t e %
1284 % %
1285 % %
1286 % %
1287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1288 %
1289 % MagickGetImageAttribute() returns a value associated with the specified
1290 % property. Use MagickRelinquishMemory() to free the value when you are
1291 % finished with it.
1292 %
1293 % The format of the MagickGetImageAttribute method is:
1294 %
1295 % char *MagickGetImageAttribute(MagickWand *wand,const char *property)
1296 %
1297 % A description of each parameter follows:
1298 %
1299 % o wand: the magick wand.
1300 %
1301 % o property: the property.
1302 %
1303 */
1304 WandExport char *MagickGetImageAttribute(MagickWand *wand,const char *property)
1305 {
1306  return(MagickGetImageProperty(wand,property));
1307 }
1308 
1309 /*
1310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1311 % %
1312 % %
1313 % %
1314 + M a g i c k G e t I m a g e I n d e x %
1315 % %
1316 % %
1317 % %
1318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1319 %
1320 % MagickGetImageIndex() returns the index of the current image.
1321 %
1322 % The format of the MagickGetImageIndex method is:
1323 %
1324 % ssize_t MagickGetImageIndex(MagickWand *wand)
1325 %
1326 % A description of each parameter follows:
1327 %
1328 % o wand: the magick wand.
1329 %
1330 */
1331 WandExport ssize_t MagickGetImageIndex(MagickWand *wand)
1332 {
1333  return(MagickGetIteratorIndex(wand));
1334 }
1335 
1336 /*
1337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1338 % %
1339 % %
1340 % %
1341 + M a g i c k G e t I m a g e C h a n n e l E x t r e m a %
1342 % %
1343 % %
1344 % %
1345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1346 %
1347 % MagickGetImageChannelExtrema() gets the extrema for one or more image
1348 % channels.
1349 %
1350 % The format of the MagickGetImageChannelExtrema method is:
1351 %
1352 % MagickBooleanType MagickGetImageChannelExtrema(MagickWand *wand,
1353 % const ChannelType channel,size_t *minima,size_t *maxima)
1354 %
1355 % A description of each parameter follows:
1356 %
1357 % o wand: the magick wand.
1358 %
1359 % o channel: the image channel(s).
1360 %
1361 % o minima: The minimum pixel value for the specified channel(s).
1362 %
1363 % o maxima: The maximum pixel value for the specified channel(s).
1364 %
1365 */
1366 WandExport MagickBooleanType MagickGetImageChannelExtrema(MagickWand *wand,
1367  const ChannelType channel,size_t *minima,size_t *maxima)
1368 {
1369  MagickBooleanType
1370  status;
1371 
1372  assert(wand != (MagickWand *) NULL);
1373  assert(wand->signature == WandSignature);
1374  if (wand->debug != MagickFalse)
1375  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1376  if (wand->images == (Image *) NULL)
1377  ThrowWandException(WandError,"ContainsNoImages",wand->name);
1378  status=GetImageChannelExtrema(wand->images,channel,minima,maxima,
1379  wand->exception);
1380  return(status);
1381 }
1382 
1383 /*
1384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1385 % %
1386 % %
1387 % %
1388 + M a g i c k G e t I m a g e E x t r e m a %
1389 % %
1390 % %
1391 % %
1392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1393 %
1394 % MagickGetImageExtrema() gets the extrema for the image.
1395 %
1396 % The format of the MagickGetImageExtrema method is:
1397 %
1398 % MagickBooleanType MagickGetImageExtrema(MagickWand *wand,
1399 % size_t *minima,size_t *maxima)
1400 %
1401 % A description of each parameter follows:
1402 %
1403 % o wand: the magick wand.
1404 %
1405 % o minima: The minimum pixel value for the specified channel(s).
1406 %
1407 % o maxima: The maximum pixel value for the specified channel(s).
1408 %
1409 */
1410 WandExport MagickBooleanType MagickGetImageExtrema(MagickWand *wand,
1411  size_t *minima,size_t *maxima)
1412 {
1413  MagickBooleanType
1414  status;
1415 
1416  assert(wand != (MagickWand *) NULL);
1417  assert(wand->signature == WandSignature);
1418  if (wand->debug != MagickFalse)
1419  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1420  if (wand->images == (Image *) NULL)
1421  ThrowWandException(WandError,"ContainsNoImages",wand->name);
1422  status=GetImageExtrema(wand->images,minima,maxima,wand->exception);
1423  return(status);
1424 }
1425 
1426 /*
1427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1428 % %
1429 % %
1430 % %
1431 % M a g i c k G e t I m a g e M a t t e %
1432 % %
1433 % %
1434 % %
1435 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1436 %
1437 % MagickGetImageMatte() returns MagickTrue if the image has a matte channel
1438 % otherwise MagickFalse.
1439 %
1440 % The format of the MagickGetImageMatte method is:
1441 %
1442 % size_t MagickGetImageMatte(MagickWand *wand)
1443 %
1444 % A description of each parameter follows:
1445 %
1446 % o wand: the magick wand.
1447 %
1448 */
1449 WandExport MagickBooleanType MagickGetImageMatte(MagickWand *wand)
1450 {
1451  assert(wand != (MagickWand *) NULL);
1452  assert(wand->signature == WandSignature);
1453  if (wand->debug != MagickFalse)
1454  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1455  if (wand->images == (Image *) NULL)
1456  ThrowWandException(WandError,"ContainsNoImages",wand->name);
1457  return(wand->images->matte);
1458 }
1459 
1460 /*
1461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1462 % %
1463 % %
1464 % %
1465 % M a g i c k G e t I m a g e P i x e l s %
1466 % %
1467 % %
1468 % %
1469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1470 %
1471 % MagickGetImagePixels() extracts pixel data from an image and returns it to
1472 % you. The method returns MagickTrue on success otherwise MagickFalse if an
1473 % error is encountered. The data is returned as char, short int, int, ssize_t,
1474 % float, or double in the order specified by map.
1475 %
1476 % Suppose you want to extract the first scanline of a 640x480 image as
1477 % character data in red-green-blue order:
1478 %
1479 % MagickGetImagePixels(wand,0,0,640,1,"RGB",CharPixel,pixels);
1480 %
1481 % The format of the MagickGetImagePixels method is:
1482 %
1483 % MagickBooleanType MagickGetImagePixels(MagickWand *wand,
1484 % const ssize_t x,const ssize_t y,const size_t columns,
1485 % const size_t rows,const char *map,const StorageType storage,
1486 % void *pixels)
1487 %
1488 % A description of each parameter follows:
1489 %
1490 % o wand: the magick wand.
1491 %
1492 % o x, y, columns, rows: These values define the perimeter
1493 % of a region of pixels you want to extract.
1494 %
1495 % o map: This string reflects the expected ordering of the pixel array.
1496 % It can be any combination or order of R = red, G = green, B = blue,
1497 % A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
1498 % Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
1499 % P = pad.
1500 %
1501 % o storage: Define the data type of the pixels. Float and double types are
1502 % expected to be normalized [0..1] otherwise [0..QuantumRange]. Choose from
1503 % these types: CharPixel, DoublePixel, FloatPixel, IntegerPixel,
1504 % LongPixel, QuantumPixel, or ShortPixel.
1505 %
1506 % o pixels: This array of values contain the pixel components as defined by
1507 % map and type. You must preallocate this array where the expected
1508 % length varies depending on the values of width, height, map, and type.
1509 %
1510 */
1511 WandExport MagickBooleanType MagickGetImagePixels(MagickWand *wand,
1512  const ssize_t x,const ssize_t y,const size_t columns,
1513  const size_t rows,const char *map,const StorageType storage,
1514  void *pixels)
1515 {
1516  return(MagickExportImagePixels(wand,x,y,columns,rows,map,storage,pixels));
1517 }
1518 
1519 /*
1520 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1521 % %
1522 % %
1523 % %
1524 % M a g i c k G e t I m a g e S i z e %
1525 % %
1526 % %
1527 % %
1528 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1529 %
1530 % MagickGetImageSize() returns the image length in bytes.
1531 %
1532 % The format of the MagickGetImageSize method is:
1533 %
1534 % MagickBooleanType MagickGetImageSize(MagickWand *wand,
1535 % MagickSizeType *length)
1536 %
1537 % A description of each parameter follows:
1538 %
1539 % o wand: the magick wand.
1540 %
1541 % o length: the image length in bytes.
1542 %
1543 */
1544 WandExport MagickSizeType MagickGetImageSize(MagickWand *wand)
1545 {
1546  assert(wand != (MagickWand *) NULL);
1547  assert(wand->signature == WandSignature);
1548  if (wand->debug != MagickFalse)
1549  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1550  if (wand->images == (Image *) NULL)
1551  ThrowWandException(WandError,"ContainsNoImages",wand->name);
1552  return(GetBlobSize(wand->images));
1553 }
1554 
1555 /*
1556 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1557 % %
1558 % %
1559 % %
1560 % M a g i c k M a p I m a g e %
1561 % %
1562 % %
1563 % %
1564 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1565 %
1566 % MagickMapImage() replaces the colors of an image with the closest color
1567 % from a reference image.
1568 %
1569 % The format of the MagickMapImage method is:
1570 %
1571 % MagickBooleanType MagickMapImage(MagickWand *wand,
1572 % const MagickWand *map_wand,const MagickBooleanType dither)
1573 %
1574 % A description of each parameter follows:
1575 %
1576 % o wand: the magick wand.
1577 %
1578 % o map: the map wand.
1579 %
1580 % o dither: Set this integer value to something other than zero to dither
1581 % the mapped image.
1582 %
1583 */
1584 WandExport MagickBooleanType MagickMapImage(MagickWand *wand,
1585  const MagickWand *map_wand,const MagickBooleanType dither)
1586 {
1587  MagickBooleanType
1588  status;
1589 
1590  assert(wand != (MagickWand *) NULL);
1591  assert(wand->signature == WandSignature);
1592  if (wand->debug != MagickFalse)
1593  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1594  if ((wand->images == (Image *) NULL) || (map_wand->images == (Image *) NULL))
1595  ThrowWandException(WandError,"ContainsNoImages",wand->name);
1596  status=MapImage(wand->images,map_wand->images,dither);
1597  if (status == MagickFalse)
1598  InheritException(wand->exception,&wand->images->exception);
1599  return(status);
1600 }
1601 
1602 /*
1603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1604 % %
1605 % %
1606 % %
1607 % M a g i c k M a t t e F l o o d f i l l I m a g e %
1608 % %
1609 % %
1610 % %
1611 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1612 %
1613 % MagickMatteFloodfillImage() changes the transparency value of any pixel that
1614 % matches target and is an immediate neighbor. If the method
1615 % FillToBorderMethod is specified, the transparency value is changed for any
1616 % neighbor pixel that does not match the bordercolor member of image.
1617 %
1618 % The format of the MagickMatteFloodfillImage method is:
1619 %
1620 % MagickBooleanType MagickMatteFloodfillImage(MagickWand *wand,
1621 % const double alpha,const double fuzz,const PixelWand *bordercolor,
1622 % const ssize_t x,const ssize_t y)
1623 %
1624 % A description of each parameter follows:
1625 %
1626 % o wand: the magick wand.
1627 %
1628 % o alpha: the level of transparency: 1.0 is fully opaque and 0.0 is fully
1629 % transparent.
1630 %
1631 % o fuzz: By default target must match a particular pixel color
1632 % exactly. However, in many cases two colors may differ by a small amount.
1633 % The fuzz member of image defines how much tolerance is acceptable to
1634 % consider two colors as the same. For example, set fuzz to 10 and the
1635 % color red at intensities of 100 and 102 respectively are now interpreted
1636 % as the same color for the purposes of the floodfill.
1637 %
1638 % o bordercolor: the border color pixel wand.
1639 %
1640 % o x,y: the starting location of the operation.
1641 %
1642 */
1643 WandExport MagickBooleanType MagickMatteFloodfillImage(MagickWand *wand,
1644  const double alpha,const double fuzz,const PixelWand *bordercolor,
1645  const ssize_t x,const ssize_t y)
1646 {
1647  DrawInfo
1648  *draw_info;
1649 
1650  MagickBooleanType
1651  status;
1652 
1653  PixelPacket
1654  target;
1655 
1656  assert(wand != (MagickWand *) NULL);
1657  assert(wand->signature == WandSignature);
1658  if (wand->debug != MagickFalse)
1659  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1660  if (wand->images == (Image *) NULL)
1661  ThrowWandException(WandError,"ContainsNoImages",wand->name);
1662  draw_info=CloneDrawInfo(wand->image_info,(DrawInfo *) NULL);
1663  (void) GetOneVirtualPixel(wand->images,x % wand->images->columns,
1664  y % wand->images->rows,&target,wand->exception);
1665  if (bordercolor != (PixelWand *) NULL)
1666  PixelGetQuantumColor(bordercolor,&target);
1667  wand->images->fuzz=fuzz;
1668  status=MatteFloodfillImage(wand->images,target,ClampToQuantum(
1669  (MagickRealType) QuantumRange-QuantumRange*alpha),x,y,bordercolor !=
1670  (PixelWand *) NULL ? FillToBorderMethod : FloodfillMethod);
1671  if (status == MagickFalse)
1672  InheritException(wand->exception,&wand->images->exception);
1673  draw_info=DestroyDrawInfo(draw_info);
1674  return(status);
1675 }
1676 
1677 /*
1678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1679 % %
1680 % %
1681 % %
1682 % M a g i c k M e d i a n F i l t e r I m a g e %
1683 % %
1684 % %
1685 % %
1686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1687 %
1688 % MagickMedianFilterImage() applies a digital filter that improves the quality
1689 % of a noisy image. Each pixel is replaced by the median in a set of
1690 % neighboring pixels as defined by radius.
1691 %
1692 % The format of the MagickMedianFilterImage method is:
1693 %
1694 % MagickBooleanType MagickMedianFilterImage(MagickWand *wand,
1695 % const double radius)
1696 %
1697 % A description of each parameter follows:
1698 %
1699 % o wand: the magick wand.
1700 %
1701 % o radius: the radius of the pixel neighborhood.
1702 %
1703 */
1704 WandExport MagickBooleanType MagickMedianFilterImage(MagickWand *wand,
1705  const double radius)
1706 {
1707  Image
1708  *median_image;
1709 
1710  assert(wand != (MagickWand *) NULL);
1711  assert(wand->signature == WandSignature);
1712  if (wand->debug != MagickFalse)
1713  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1714  if (wand->images == (Image *) NULL)
1715  ThrowWandException(WandError,"ContainsNoImages",wand->name);
1716  median_image=MedianFilterImage(wand->images,radius,wand->exception);
1717  if (median_image == (Image *) NULL)
1718  return(MagickFalse);
1719  ReplaceImageInList(&wand->images,median_image);
1720  return(MagickTrue);
1721 }
1722 
1723 /*
1724 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1725 % %
1726 % %
1727 % %
1728 % M a g i c k M i n i m u m I m a g e s %
1729 % %
1730 % %
1731 % %
1732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1733 %
1734 % MagickMinimumImages() returns the minimum intensity of an image sequence.
1735 %
1736 % The format of the MagickMinimumImages method is:
1737 %
1738 % MagickWand *MagickMinimumImages(MagickWand *wand)
1739 %
1740 % A description of each parameter follows:
1741 %
1742 % o wand: the magick wand.
1743 %
1744 */
1745 WandExport MagickWand *MagickMinimumImages(MagickWand *wand)
1746 {
1747  Image
1748  *minimum_image;
1749 
1750  assert(wand != (MagickWand *) NULL);
1751  assert(wand->signature == WandSignature);
1752  if (wand->debug != MagickFalse)
1753  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1754  if (wand->images == (Image *) NULL)
1755  return((MagickWand *) NULL);
1756  minimum_image=EvaluateImages(wand->images,MinEvaluateOperator,
1757  wand->exception);
1758  if (minimum_image == (Image *) NULL)
1759  return((MagickWand *) NULL);
1760  return(CloneMagickWandFromImages(wand,minimum_image));
1761 }
1762 
1763 /*
1764 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1765 % %
1766 % %
1767 % %
1768 % M a g i c k M o d e I m a g e %
1769 % %
1770 % %
1771 % %
1772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1773 %
1774 % MagickModeImage() makes each pixel the 'predominant color' of the
1775 % neighborhood of the specified radius.
1776 %
1777 % The format of the MagickModeImage method is:
1778 %
1779 % MagickBooleanType MagickModeImage(MagickWand *wand,
1780 % const double radius)
1781 %
1782 % A description of each parameter follows:
1783 %
1784 % o wand: the magick wand.
1785 %
1786 % o radius: the radius of the pixel neighborhood.
1787 %
1788 */
1789 WandExport MagickBooleanType MagickModeImage(MagickWand *wand,
1790  const double radius)
1791 {
1792  Image
1793  *mode_image;
1794 
1795  assert(wand != (MagickWand *) NULL);
1796  assert(wand->signature == WandSignature);
1797  if (wand->debug != MagickFalse)
1798  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1799  if (wand->images == (Image *) NULL)
1800  ThrowWandException(WandError,"ContainsNoImages",wand->name);
1801  mode_image=ModeImage(wand->images,radius,wand->exception);
1802  if (mode_image == (Image *) NULL)
1803  return(MagickFalse);
1804  ReplaceImageInList(&wand->images,mode_image);
1805  return(MagickTrue);
1806 }
1807 
1808 /*
1809 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1810 % %
1811 % %
1812 % %
1813 % M a g i c k M o s a i c I m a g e s %
1814 % %
1815 % %
1816 % %
1817 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1818 %
1819 % MagickMosaicImages() inlays an image sequence to form a single coherent
1820 % picture. It returns a wand with each image in the sequence composited at
1821 % the location defined by the page offset of the image.
1822 %
1823 % The format of the MagickMosaicImages method is:
1824 %
1825 % MagickWand *MagickMosaicImages(MagickWand *wand)
1826 %
1827 % A description of each parameter follows:
1828 %
1829 % o wand: the magick wand.
1830 %
1831 */
1832 WandExport MagickWand *MagickMosaicImages(MagickWand *wand)
1833 {
1834  Image
1835  *mosaic_image;
1836 
1837  assert(wand != (MagickWand *) NULL);
1838  assert(wand->signature == WandSignature);
1839  if (wand->debug != MagickFalse)
1840  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1841  if (wand->images == (Image *) NULL)
1842  return((MagickWand *) NULL);
1843  mosaic_image=MosaicImages(wand->images,wand->exception);
1844  if (mosaic_image == (Image *) NULL)
1845  return((MagickWand *) NULL);
1846  return(CloneMagickWandFromImages(wand,mosaic_image));
1847 }
1848 
1849 /*
1850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1851 % %
1852 % %
1853 % %
1854 % M a g i c k O p a q u e I m a g e %
1855 % %
1856 % %
1857 % %
1858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1859 %
1860 % MagickOpaqueImage() changes any pixel that matches color with the color
1861 % defined by fill.
1862 %
1863 % The format of the MagickOpaqueImage method is:
1864 %
1865 % MagickBooleanType MagickOpaqueImage(MagickWand *wand,
1866 % const PixelWand *target,const PixelWand *fill,const double fuzz)
1867 %
1868 % A description of each parameter follows:
1869 %
1870 % o wand: the magick wand.
1871 %
1872 % o channel: the channel(s).
1873 %
1874 % o target: Change this target color to the fill color within the image.
1875 %
1876 % o fill: the fill pixel wand.
1877 %
1878 % o fuzz: By default target must match a particular pixel color
1879 % exactly. However, in many cases two colors may differ by a small amount.
1880 % The fuzz member of image defines how much tolerance is acceptable to
1881 % consider two colors as the same. For example, set fuzz to 10 and the
1882 % color red at intensities of 100 and 102 respectively are now interpreted
1883 % as the same color for the purposes of the floodfill.
1884 %
1885 */
1886 WandExport MagickBooleanType MagickOpaqueImage(MagickWand *wand,
1887  const PixelWand *target,const PixelWand *fill,const double fuzz)
1888 {
1889  return(MagickPaintOpaqueImage(wand,target,fill,fuzz));
1890 }
1891 
1892 /*
1893 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1894 % %
1895 % %
1896 % %
1897 % M a g i c k P a i n t F l o o d f i l l I m a g e %
1898 % %
1899 % %
1900 % %
1901 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1902 %
1903 % MagickPaintFloodfillImage() changes the color value of any pixel that matches
1904 % target and is an immediate neighbor. If the method FillToBorderMethod is
1905 % specified, the color value is changed for any neighbor pixel that does not
1906 % match the bordercolor member of image.
1907 %
1908 % The format of the MagickPaintFloodfillImage method is:
1909 %
1910 % MagickBooleanType MagickPaintFloodfillImage(MagickWand *wand,
1911 % const ChannelType channel,const PixelWand *fill,const double fuzz,
1912 % const PixelWand *bordercolor,const ssize_t x,const ssize_t y)
1913 %
1914 % A description of each parameter follows:
1915 %
1916 % o wand: the magick wand.
1917 %
1918 % o channel: the channel(s).
1919 %
1920 % o fill: the floodfill color pixel wand.
1921 %
1922 % o fuzz: By default target must match a particular pixel color
1923 % exactly. However, in many cases two colors may differ by a small amount.
1924 % The fuzz member of image defines how much tolerance is acceptable to
1925 % consider two colors as the same. For example, set fuzz to 10 and the
1926 % color red at intensities of 100 and 102 respectively are now interpreted
1927 % as the same color for the purposes of the floodfill.
1928 %
1929 % o bordercolor: the border color pixel wand.
1930 %
1931 % o x,y: the starting location of the operation.
1932 %
1933 */
1934 WandExport MagickBooleanType MagickPaintFloodfillImage(MagickWand *wand,
1935  const ChannelType channel,const PixelWand *fill,const double fuzz,
1936  const PixelWand *bordercolor,const ssize_t x,const ssize_t y)
1937 {
1938  MagickBooleanType
1939  status;
1940 
1941  status=MagickFloodfillPaintImage(wand,channel,fill,fuzz,bordercolor,x,y,
1942  MagickFalse);
1943  return(status);
1944 }
1945 
1946 /*
1947 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1948 % %
1949 % %
1950 % %
1951 % M a g i c k P a i n t O p a q u e I m a g e %
1952 % %
1953 % %
1954 % %
1955 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1956 %
1957 % MagickPaintOpaqueImage() changes any pixel that matches color with the color
1958 % defined by fill.
1959 %
1960 % The format of the MagickPaintOpaqueImage method is:
1961 %
1962 % MagickBooleanType MagickPaintOpaqueImage(MagickWand *wand,
1963 % const PixelWand *target,const PixelWand *fill,const double fuzz)
1964 % MagickBooleanType MagickPaintOpaqueImageChannel(MagickWand *wand,
1965 % const ChannelType channel,const PixelWand *target,
1966 % const PixelWand *fill,const double fuzz)
1967 %
1968 % A description of each parameter follows:
1969 %
1970 % o wand: the magick wand.
1971 %
1972 % o channel: the channel(s).
1973 %
1974 % o target: Change this target color to the fill color within the image.
1975 %
1976 % o fill: the fill pixel wand.
1977 %
1978 % o fuzz: By default target must match a particular pixel color
1979 % exactly. However, in many cases two colors may differ by a small amount.
1980 % The fuzz member of image defines how much tolerance is acceptable to
1981 % consider two colors as the same. For example, set fuzz to 10 and the
1982 % color red at intensities of 100 and 102 respectively are now interpreted
1983 % as the same color for the purposes of the floodfill.
1984 %
1985 */
1986 
1987 WandExport MagickBooleanType MagickPaintOpaqueImage(MagickWand *wand,
1988  const PixelWand *target,const PixelWand *fill,const double fuzz)
1989 {
1990  return(MagickPaintOpaqueImageChannel(wand,DefaultChannels,target,fill,fuzz));
1991 }
1992 
1993 WandExport MagickBooleanType MagickPaintOpaqueImageChannel(MagickWand *wand,
1994  const ChannelType channel,const PixelWand *target,const PixelWand *fill,
1995  const double fuzz)
1996 {
1997  MagickBooleanType
1998  status;
1999 
2000  status=MagickOpaquePaintImageChannel(wand,channel,target,fill,fuzz,
2001  MagickFalse);
2002  return(status);
2003 }
2004 
2005 /*
2006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2007 % %
2008 % %
2009 % %
2010 % M a g i c k P a i n t T r a n s p a r e n t I m a g e %
2011 % %
2012 % %
2013 % %
2014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2015 %
2016 % MagickPaintTransparentImage() changes any pixel that matches color with the
2017 % color defined by fill.
2018 %
2019 % The format of the MagickPaintTransparentImage method is:
2020 %
2021 % MagickBooleanType MagickPaintTransparentImage(MagickWand *wand,
2022 % const PixelWand *target,const double alpha,const double fuzz)
2023 %
2024 % A description of each parameter follows:
2025 %
2026 % o wand: the magick wand.
2027 %
2028 % o target: Change this target color to specified opacity value within
2029 % the image.
2030 %
2031 % o alpha: the level of transparency: 1.0 is fully opaque and 0.0 is fully
2032 % transparent.
2033 %
2034 % o fuzz: By default target must match a particular pixel color
2035 % exactly. However, in many cases two colors may differ by a small amount.
2036 % The fuzz member of image defines how much tolerance is acceptable to
2037 % consider two colors as the same. For example, set fuzz to 10 and the
2038 % color red at intensities of 100 and 102 respectively are now interpreted
2039 % as the same color for the purposes of the floodfill.
2040 %
2041 */
2042 WandExport MagickBooleanType MagickPaintTransparentImage(MagickWand *wand,
2043  const PixelWand *target,const double alpha,const double fuzz)
2044 {
2045  return(MagickTransparentPaintImage(wand,target,alpha,fuzz,MagickFalse));
2046 }
2047 
2048 /*
2049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2050 % %
2051 % %
2052 % %
2053 % M a g i c k R a d i a l B l u r I m a g e %
2054 % %
2055 % %
2056 % %
2057 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2058 %
2059 % MagickRadialBlurImage() radial blurs an image.
2060 %
2061 % The format of the MagickRadialBlurImage method is:
2062 %
2063 % MagickBooleanType MagickRadialBlurImage(MagickWand *wand,
2064 % const double angle)
2065 % MagickBooleanType MagickRadialBlurImageChannel(MagickWand *wand,
2066 % const ChannelType channel,const double angle)
2067 %
2068 % A description of each parameter follows:
2069 %
2070 % o wand: the magick wand.
2071 %
2072 % o channel: the image channel(s).
2073 %
2074 % o angle: the angle of the blur in degrees.
2075 %
2076 */
2077 WandExport MagickBooleanType MagickRadialBlurImage(MagickWand *wand,
2078  const double angle)
2079 {
2080  return(MagickRotationalBlurImage(wand,angle));
2081 }
2082 
2083 WandExport MagickBooleanType MagickRadialBlurImageChannel(MagickWand *wand,
2084  const ChannelType channel,const double angle)
2085 {
2086  return(MagickRotationalBlurImageChannel(wand,channel,angle));
2087 }
2088 
2089 /*
2090 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2091 % %
2092 % %
2093 % %
2094 % M a g i c k R e c o l o r I m a g e %
2095 % %
2096 % %
2097 % %
2098 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2099 %
2100 % MagickRecolorImage() apply color transformation to an image. The method
2101 % permits saturation changes, hue rotation, luminance to alpha, and various
2102 % other effects. Although variable-sized transformation matrices can be used,
2103 % typically one uses a 5x5 matrix for an RGBA image and a 6x6 for CMYKA
2104 % (or RGBA with offsets). The matrix is similar to those used by Adobe Flash
2105 % except offsets are in column 6 rather than 5 (in support of CMYKA images)
2106 % and offsets are normalized (divide Flash offset by 255).
2107 %
2108 % The format of the MagickRecolorImage method is:
2109 %
2110 % MagickBooleanType MagickRecolorImage(MagickWand *wand,
2111 % const size_t order,const double *color_matrix)
2112 %
2113 % A description of each parameter follows:
2114 %
2115 % o wand: the magick wand.
2116 %
2117 % o order: the number of columns and rows in the color matrix.
2118 %
2119 % o color_matrix: An array of doubles representing the color matrix.
2120 %
2121 */
2122 WandExport MagickBooleanType MagickRecolorImage(MagickWand *wand,
2123  const size_t order,const double *color_matrix)
2124 {
2125  Image
2126  *transform_image;
2127 
2128  assert(wand != (MagickWand *) NULL);
2129  assert(wand->signature == WandSignature);
2130  if (wand->debug != MagickFalse)
2131  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2132  if (color_matrix == (const double *) NULL)
2133  return(MagickFalse);
2134  if (wand->images == (Image *) NULL)
2135  ThrowWandException(WandError,"ContainsNoImages",wand->name);
2136  transform_image=RecolorImage(wand->images,order,color_matrix,
2137  wand->exception);
2138  if (transform_image == (Image *) NULL)
2139  return(MagickFalse);
2140  ReplaceImageInList(&wand->images,transform_image);
2141  return(MagickTrue);
2142 }
2143 
2144 /*
2145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2146 % %
2147 % %
2148 % %
2149 % M a g i c k R e d u c e N o i s e I m a g e %
2150 % %
2151 % %
2152 % %
2153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2154 %
2155 % MagickReduceNoiseImage() smooths the contours of an image while still
2156 % preserving edge information. The algorithm works by replacing each pixel
2157 % with its neighbor closest in value. A neighbor is defined by radius. Use
2158 % a radius of 0 and ReduceNoise() selects a suitable radius for you.
2159 %
2160 % The format of the MagickReduceNoiseImage method is:
2161 %
2162 % MagickBooleanType MagickReduceNoiseImage(MagickWand *wand,
2163 % const double radius)
2164 %
2165 % A description of each parameter follows:
2166 %
2167 % o wand: the magick wand.
2168 %
2169 % o radius: the radius of the pixel neighborhood.
2170 %
2171 */
2172 WandExport MagickBooleanType MagickReduceNoiseImage(MagickWand *wand,
2173  const double radius)
2174 {
2175  Image
2176  *noise_image;
2177 
2178  assert(wand != (MagickWand *) NULL);
2179  assert(wand->signature == WandSignature);
2180  if (wand->debug != MagickFalse)
2181  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2182  if (wand->images == (Image *) NULL)
2183  ThrowWandException(WandError,"ContainsNoImages",wand->name);
2184  noise_image=ReduceNoiseImage(wand->images,radius,wand->exception);
2185  if (noise_image == (Image *) NULL)
2186  return(MagickFalse);
2187  ReplaceImageInList(&wand->images,noise_image);
2188  return(MagickTrue);
2189 }
2190 
2191 /*
2192 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2193 % %
2194 % %
2195 % %
2196 % M a g i c k M a x i m u m I m a g e s %
2197 % %
2198 % %
2199 % %
2200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2201 %
2202 % MagickMaximumImages() returns the maximum intensity of an image sequence.
2203 %
2204 % The format of the MagickMaximumImages method is:
2205 %
2206 % MagickWand *MagickMaximumImages(MagickWand *wand)
2207 %
2208 % A description of each parameter follows:
2209 %
2210 % o wand: the magick wand.
2211 %
2212 */
2213 WandExport MagickWand *MagickMaximumImages(MagickWand *wand)
2214 {
2215  Image
2216  *maximum_image;
2217 
2218  assert(wand != (MagickWand *) NULL);
2219  assert(wand->signature == WandSignature);
2220  if (wand->debug != MagickFalse)
2221  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2222  if (wand->images == (Image *) NULL)
2223  return((MagickWand *) NULL);
2224  maximum_image=EvaluateImages(wand->images,MaxEvaluateOperator,
2225  wand->exception);
2226  if (maximum_image == (Image *) NULL)
2227  return((MagickWand *) NULL);
2228  return(CloneMagickWandFromImages(wand,maximum_image));
2229 }
2230 
2231 /*
2232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2233 % %
2234 % %
2235 % %
2236 % M a g i c k S e t I m a g e A t t r i b u t e %
2237 % %
2238 % %
2239 % %
2240 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2241 %
2242 % MagickSetImageAttribute() associates a property with an image.
2243 %
2244 % The format of the MagickSetImageAttribute method is:
2245 %
2246 % MagickBooleanType MagickSetImageAttribute(MagickWand *wand,
2247 % const char *property,const char *value)
2248 %
2249 % A description of each parameter follows:
2250 %
2251 % o wand: the magick wand.
2252 %
2253 % o property: the property.
2254 %
2255 % o value: the value.
2256 %
2257 */
2258 WandExport MagickBooleanType MagickSetImageAttribute(MagickWand *wand,
2259  const char *property,const char *value)
2260 {
2261  return(SetImageProperty(wand->images,property,value));
2262 }
2263 
2264 /*
2265 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2266 % %
2267 % %
2268 % %
2269 % M a g i c k S e t I m a g e I n d e x %
2270 % %
2271 % %
2272 % %
2273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2274 %
2275 % MagickSetImageIndex() set the current image to the position of the list
2276 % specified with the index parameter.
2277 %
2278 % The format of the MagickSetImageIndex method is:
2279 %
2280 % MagickBooleanType MagickSetImageIndex(MagickWand *wand,
2281 % const ssize_t index)
2282 %
2283 % A description of each parameter follows:
2284 %
2285 % o wand: the magick wand.
2286 %
2287 % o index: the scene number.
2288 %
2289 */
2290 WandExport MagickBooleanType MagickSetImageIndex(MagickWand *wand,
2291  const ssize_t index)
2292 {
2293  return(MagickSetIteratorIndex(wand,index));
2294 }
2295 
2296 /*
2297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2298 % %
2299 % %
2300 % %
2301 + M a g i c k S e t I m a g e O p t i o n %
2302 % %
2303 % %
2304 % %
2305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2306 %
2307 % MagickSetImageOption() associates one or options with a particular image
2308 % format (.e.g MagickSetImageOption(wand,"jpeg","perserve","yes").
2309 %
2310 % The format of the MagickSetImageOption method is:
2311 %
2312 % MagickBooleanType MagickSetImageOption(MagickWand *wand,
2313 % const char *format,const char *key,const char *value)
2314 %
2315 % A description of each parameter follows:
2316 %
2317 % o wand: the magick wand.
2318 %
2319 % o format: the image format.
2320 %
2321 % o key: The key.
2322 %
2323 % o value: The value.
2324 %
2325 */
2326 WandExport MagickBooleanType MagickSetImageOption(MagickWand *wand,
2327  const char *format,const char *key,const char *value)
2328 {
2329  char
2330  option[MaxTextExtent];
2331 
2332  assert(wand != (MagickWand *) NULL);
2333  assert(wand->signature == WandSignature);
2334  if (wand->debug != MagickFalse)
2335  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
2336  (void) FormatLocaleString(option,MaxTextExtent,"%s:%s=%s",format,key,value);
2337  return(DefineImageOption(wand->image_info,option));
2338 }
2339 
2340 /*
2341 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2342 % %
2343 % %
2344 % %
2345 % M a g i c k T r a n s p a r e n t I m a g e %
2346 % %
2347 % %
2348 % %
2349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2350 %
2351 % MagickTransparentImage() changes any pixel that matches color with the
2352 % color defined by fill.
2353 %
2354 % The format of the MagickTransparentImage method is:
2355 %
2356 % MagickBooleanType MagickTransparentImage(MagickWand *wand,
2357 % const PixelWand *target,const double alpha,const double fuzz)
2358 %
2359 % A description of each parameter follows:
2360 %
2361 % o wand: the magick wand.
2362 %
2363 % o target: Change this target color to specified opacity value within
2364 % the image.
2365 %
2366 % o alpha: the level of transparency: 1.0 is fully opaque and 0.0 is fully
2367 % transparent.
2368 %
2369 % o fuzz: By default target must match a particular pixel color
2370 % exactly. However, in many cases two colors may differ by a small amount.
2371 % The fuzz member of image defines how much tolerance is acceptable to
2372 % consider two colors as the same. For example, set fuzz to 10 and the
2373 % color red at intensities of 100 and 102 respectively are now interpreted
2374 % as the same color for the purposes of the floodfill.
2375 %
2376 */
2377 WandExport MagickBooleanType MagickTransparentImage(MagickWand *wand,
2378  const PixelWand *target,const double alpha,const double fuzz)
2379 {
2380  return(MagickPaintTransparentImage(wand,target,alpha,fuzz));
2381 }
2382 
2383 /*
2384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2385 % %
2386 % %
2387 % %
2388 % M a g i c k R e g i o n O f I n t e r e s t I m a g e %
2389 % %
2390 % %
2391 % %
2392 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2393 %
2394 % MagickRegionOfInterestImage() extracts a region of the image and returns it
2395 % as a new wand.
2396 %
2397 % The format of the MagickRegionOfInterestImage method is:
2398 %
2399 % MagickWand *MagickRegionOfInterestImage(MagickWand *wand,
2400 % const size_t width,const size_t height,const ssize_t x,
2401 % const ssize_t y)
2402 %
2403 % A description of each parameter follows:
2404 %
2405 % o wand: the magick wand.
2406 %
2407 % o width: the region width.
2408 %
2409 % o height: the region height.
2410 %
2411 % o x: the region x offset.
2412 %
2413 % o y: the region y offset.
2414 %
2415 */
2416 WandExport MagickWand *MagickRegionOfInterestImage(MagickWand *wand,
2417  const size_t width,const size_t height,const ssize_t x,
2418  const ssize_t y)
2419 {
2420  return(MagickGetImageRegion(wand,width,height,x,y));
2421 }
2422 
2423 /*
2424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2425 % %
2426 % %
2427 % %
2428 % M a g i c k S e t I m a g e P i x e l s %
2429 % %
2430 % %
2431 % %
2432 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2433 %
2434 % MagickSetImagePixels() accepts pixel datand stores it in the image at the
2435 % location you specify. The method returns MagickFalse on success otherwise
2436 % MagickTrue if an error is encountered. The pixel data can be either char,
2437 % short int, int, ssize_t, float, or double in the order specified by map.
2438 %
2439 % Suppose your want to upload the first scanline of a 640x480 image from
2440 % character data in red-green-blue order:
2441 %
2442 % MagickSetImagePixels(wand,0,0,640,1,"RGB",CharPixel,pixels);
2443 %
2444 % The format of the MagickSetImagePixels method is:
2445 %
2446 % MagickBooleanType MagickSetImagePixels(MagickWand *wand,
2447 % const ssize_t x,const ssize_t y,const size_t columns,
2448 % const size_t rows,const char *map,const StorageType storage,
2449 % const void *pixels)
2450 %
2451 % A description of each parameter follows:
2452 %
2453 % o wand: the magick wand.
2454 %
2455 % o x, y, columns, rows: These values define the perimeter of a region
2456 % of pixels you want to define.
2457 %
2458 % o map: This string reflects the expected ordering of the pixel array.
2459 % It can be any combination or order of R = red, G = green, B = blue,
2460 % A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
2461 % Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
2462 % P = pad.
2463 %
2464 % o storage: Define the data type of the pixels. Float and double types are
2465 % expected to be normalized [0..1] otherwise [0..QuantumRange]. Choose from
2466 % these types: CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel,
2467 % or DoublePixel.
2468 %
2469 % o pixels: This array of values contain the pixel components as defined by
2470 % map and type. You must preallocate this array where the expected
2471 % length varies depending on the values of width, height, map, and type.
2472 %
2473 */
2474 WandExport MagickBooleanType MagickSetImagePixels(MagickWand *wand,
2475  const ssize_t x,const ssize_t y,const size_t columns,
2476  const size_t rows,const char *map,const StorageType storage,
2477  const void *pixels)
2478 {
2479  return(MagickImportImagePixels(wand,x,y,columns,rows,map,storage,pixels));
2480 }
2481 
2482 /*
2483 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2484 % %
2485 % %
2486 % %
2487 % M a g i c k W r i t e I m a g e B l o b %
2488 % %
2489 % %
2490 % %
2491 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2492 %
2493 % MagickWriteImageBlob() implements direct to memory image formats. It
2494 % returns the image as a blob and its length. Use MagickSetFormat() to
2495 % set the format of the returned blob (GIF, JPEG, PNG, etc.).
2496 %
2497 % Use MagickRelinquishMemory() to free the blob when you are done with it.
2498 %
2499 % The format of the MagickWriteImageBlob method is:
2500 %
2501 % unsigned char *MagickWriteImageBlob(MagickWand *wand,size_t *length)
2502 %
2503 % A description of each parameter follows:
2504 %
2505 % o wand: the magick wand.
2506 %
2507 % o length: the length of the blob.
2508 %
2509 */
2510 WandExport unsigned char *MagickWriteImageBlob(MagickWand *wand,size_t *length)
2511 {
2512  return(MagickGetImageBlob(wand,length));
2513 }
2514 
2515 /*
2516 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2517 % %
2518 % %
2519 % %
2520 % N e w P i x e l V i e w %
2521 % %
2522 % %
2523 % %
2524 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2525 %
2526 % NewPixelView() returns a pixel view required for all other methods in the
2527 % Pixel View API.
2528 %
2529 % The format of the NewPixelView method is:
2530 %
2531 % PixelView *NewPixelView(MagickWand *wand)
2532 %
2533 % A description of each parameter follows:
2534 %
2535 % o wand: the wand.
2536 %
2537 */
2538 
2539 static PixelWand ***AcquirePixelsTLS(const size_t number_wands,
2540  const size_t number_threads)
2541 {
2542  PixelWand
2543  ***pixel_wands;
2544 
2545  ssize_t
2546  i;
2547 
2548  pixel_wands=(PixelWand ***) AcquireQuantumMemory(number_threads,
2549  sizeof(*pixel_wands));
2550  if (pixel_wands == (PixelWand ***) NULL)
2551  return((PixelWand ***) NULL);
2552  (void) memset(pixel_wands,0,number_threads*sizeof(*pixel_wands));
2553  for (i=0; i < (ssize_t) number_threads; i++)
2554  {
2555  pixel_wands[i]=NewPixelWands(number_wands);
2556  if (pixel_wands[i] == (PixelWand **) NULL)
2557  return(DestroyPixelsTLS(pixel_wands,number_wands,number_threads));
2558  }
2559  return(pixel_wands);
2560 }
2561 
2562 WandExport PixelView *NewPixelView(MagickWand *wand)
2563 {
2564  PixelView
2565  *pixel_view;
2566 
2567  assert(wand != (MagickWand *) NULL);
2568  assert(wand->signature == MagickCoreSignature);
2569  pixel_view=(PixelView *) AcquireMagickMemory(sizeof(*pixel_view));
2570  if (pixel_view == (PixelView *) NULL)
2571  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
2572  GetExceptionMessage(errno));
2573  (void) memset(pixel_view,0,sizeof(*pixel_view));
2574  pixel_view->id=AcquireWandId();
2575  (void) FormatLocaleString(pixel_view->name,MaxTextExtent,"%s-%.20g",
2576  PixelViewId,(double) pixel_view->id);
2577  pixel_view->exception=AcquireExceptionInfo();
2578  pixel_view->wand=wand;
2579  pixel_view->view=AcquireVirtualCacheView(pixel_view->wand->images,
2580  pixel_view->exception);
2581  pixel_view->region.width=wand->images->columns;
2582  pixel_view->region.height=wand->images->rows;
2583  pixel_view->number_threads=GetOpenMPMaximumThreads();
2584  pixel_view->pixel_wands=AcquirePixelsTLS(pixel_view->region.width,
2585  pixel_view->number_threads);
2586  if (pixel_view->pixel_wands == (PixelWand ***) NULL)
2587  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
2588  GetExceptionMessage(errno));
2589  pixel_view->debug=IsEventLogging();
2590  pixel_view->signature=WandSignature;
2591  return(pixel_view);
2592 }
2593 
2594 /*
2595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2596 % %
2597 % %
2598 % %
2599 % N e w P i x e l V i e w R e g i o n %
2600 % %
2601 % %
2602 % %
2603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2604 %
2605 % NewPixelViewRegion() returns a pixel view required for all other methods
2606 % in the Pixel View API.
2607 %
2608 % The format of the NewPixelViewRegion method is:
2609 %
2610 % PixelView *NewPixelViewRegion(MagickWand *wand,const ssize_t x,
2611 % const ssize_t y,const size_t width,const size_t height)
2612 %
2613 % A description of each parameter follows:
2614 %
2615 % o wand: the magick wand.
2616 %
2617 % o x,y,columns,rows: These values define the perimeter of a region of
2618 % pixel_wands view.
2619 %
2620 */
2621 WandExport PixelView *NewPixelViewRegion(MagickWand *wand,const ssize_t x,
2622  const ssize_t y,const size_t width,const size_t height)
2623 {
2624  PixelView
2625  *pixel_view;
2626 
2627  assert(wand != (MagickWand *) NULL);
2628  assert(wand->signature == MagickCoreSignature);
2629  pixel_view=(PixelView *) AcquireMagickMemory(sizeof(*pixel_view));
2630  if (pixel_view == (PixelView *) NULL)
2631  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
2632  GetExceptionMessage(errno));
2633  (void) memset(pixel_view,0,sizeof(*pixel_view));
2634  pixel_view->id=AcquireWandId();
2635  (void) FormatLocaleString(pixel_view->name,MaxTextExtent,"%s-%.20g",
2636  PixelViewId,(double) pixel_view->id);
2637  pixel_view->exception=AcquireExceptionInfo();
2638  pixel_view->view=AcquireVirtualCacheView(pixel_view->wand->images,
2639  pixel_view->exception);
2640  pixel_view->wand=wand;
2641  pixel_view->region.width=width;
2642  pixel_view->region.height=height;
2643  pixel_view->region.x=x;
2644  pixel_view->region.y=y;
2645  pixel_view->number_threads=GetOpenMPMaximumThreads();
2646  pixel_view->pixel_wands=AcquirePixelsTLS(pixel_view->region.width,
2647  pixel_view->number_threads);
2648  if (pixel_view->pixel_wands == (PixelWand ***) NULL)
2649  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
2650  GetExceptionMessage(errno));
2651  pixel_view->debug=IsEventLogging();
2652  pixel_view->signature=WandSignature;
2653  return(pixel_view);
2654 }
2655 
2656 /*
2657 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2658 % %
2659 % %
2660 % %
2661 % P i x e l G e t N e x t R o w %
2662 % %
2663 % %
2664 % %
2665 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2666 %
2667 % PixelGetNextRow() returns the next row as an array of pixel wands from the
2668 % pixel iterator.
2669 %
2670 % The format of the PixelGetNextRow method is:
2671 %
2672 % PixelWand **PixelGetNextRow(PixelIterator *iterator,
2673 % size_t *number_wands)
2674 %
2675 % A description of each parameter follows:
2676 %
2677 % o iterator: the pixel iterator.
2678 %
2679 % o number_wands: the number of pixel wands.
2680 %
2681 */
2682 WandExport PixelWand **PixelGetNextRow(PixelIterator *iterator)
2683 {
2684  size_t
2685  number_wands;
2686 
2687  return(PixelGetNextIteratorRow(iterator,&number_wands));
2688 }
2689 
2690 /*
2691 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2692 % %
2693 % %
2694 % %
2695 % P i x e l I t e r a t o r G e t E x c e p t i o n %
2696 % %
2697 % %
2698 % %
2699 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2700 %
2701 % PixelIteratorGetException() returns the severity, reason, and description of
2702 % any error that occurs when using other methods in this API.
2703 %
2704 % The format of the PixelIteratorGetException method is:
2705 %
2706 % char *PixelIteratorGetException(const Pixeliterator *iterator,
2707 % ExceptionType *severity)
2708 %
2709 % A description of each parameter follows:
2710 %
2711 % o iterator: the pixel iterator.
2712 %
2713 % o severity: the severity of the error is returned here.
2714 %
2715 */
2716 WandExport char *PixelIteratorGetException(const PixelIterator *iterator,
2717  ExceptionType *severity)
2718 {
2719  return(PixelGetIteratorException(iterator,severity));
2720 }
2721 
2722 /*
2723 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2724 % %
2725 % %
2726 % %
2727 % S e t P i x e l V i e w I t e r a t o r %
2728 % %
2729 % %
2730 % %
2731 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2732 %
2733 % SetPixelViewIterator() iterates over the pixel view in parallel and calls
2734 % your set method for each scanline of the view. The pixel region is
2735 % confined to the image canvas-- that is no negative offsets or widths or
2736 % heights that exceed the image dimension. The pixels are initiallly
2737 % undefined and any settings you make in the callback method are automagically
2738 % synced back to your image.
2739 %
2740 % Use this pragma:
2741 %
2742 % #pragma omp critical
2743 %
2744 % to define a section of code in your callback set method that must be
2745 % executed by a single thread at a time.
2746 %
2747 % The format of the SetPixelViewIterator method is:
2748 %
2749 % MagickBooleanType SetPixelViewIterator(PixelView *destination,
2750 % SetPixelViewMethod set,void *context)
2751 %
2752 % A description of each parameter follows:
2753 %
2754 % o destination: the pixel view.
2755 %
2756 % o set: the set callback method.
2757 %
2758 % o context: the user defined context.
2759 %
2760 */
2761 WandExport MagickBooleanType SetPixelViewIterator(PixelView *destination,
2762  SetPixelViewMethod set,void *context)
2763 {
2764 #define SetPixelViewTag "PixelView/Set"
2765 
2766  ExceptionInfo
2767  *exception;
2768 
2769  Image
2770  *destination_image;
2771 
2772  MagickBooleanType
2773  status;
2774 
2775  MagickOffsetType
2776  progress;
2777 
2778  ssize_t
2779  y;
2780 
2781  assert(destination != (PixelView *) NULL);
2782  assert(destination->signature == WandSignature);
2783  if (set == (SetPixelViewMethod) NULL)
2784  return(MagickFalse);
2785  destination_image=destination->wand->images;
2786  if (SetImageStorageClass(destination_image,DirectClass) == MagickFalse)
2787  return(MagickFalse);
2788  status=MagickTrue;
2789  progress=0;
2790  exception=destination->exception;
2791 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2792  #pragma omp parallel for schedule(static) shared(progress,status)
2793 #endif
2794  for (y=destination->region.y; y < (ssize_t) destination->region.height; y++)
2795  {
2796  const int
2797  id = GetOpenMPThreadId();
2798 
2799  MagickBooleanType
2800  sync;
2801 
2802  IndexPacket
2803  *magick_restrict indexes;
2804 
2805  ssize_t
2806  x;
2807 
2808  PixelPacket
2809  *magick_restrict pixels;
2810 
2811  if (status == MagickFalse)
2812  continue;
2813  pixels=GetCacheViewAuthenticPixels(destination->view,destination->region.x,
2814  y,destination->region.width,1,exception);
2815  if (pixels == (PixelPacket *) NULL)
2816  {
2817  InheritException(destination->exception,GetCacheViewException(
2818  destination->view));
2819  status=MagickFalse;
2820  continue;
2821  }
2822  indexes=GetCacheViewAuthenticIndexQueue(destination->view);
2823  if (set(destination,context) == MagickFalse)
2824  status=MagickFalse;
2825  for (x=0; x < (ssize_t) destination->region.width; x++)
2826  PixelGetQuantumColor(destination->pixel_wands[id][x],pixels+x);
2827  if (destination_image->colorspace == CMYKColorspace)
2828  for (x=0; x < (ssize_t) destination->region.width; x++)
2829  SetPixelIndex(indexes+x,PixelGetBlackQuantum(
2830  destination->pixel_wands[id][x]));
2831  sync=SyncCacheViewAuthenticPixels(destination->view,exception);
2832  if (sync == MagickFalse)
2833  {
2834  InheritException(destination->exception,GetCacheViewException(
2835  destination->view));
2836  status=MagickFalse;
2837  }
2838  if (destination_image->progress_monitor != (MagickProgressMonitor) NULL)
2839  {
2840  MagickBooleanType
2841  proceed;
2842 
2843 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2844  #pragma omp atomic
2845 #endif
2846  progress++;
2847  proceed=SetImageProgress(destination_image,SetPixelViewTag,progress,
2848  destination->region.height);
2849  if (proceed == MagickFalse)
2850  status=MagickFalse;
2851  }
2852  }
2853  return(status);
2854 }
2855 
2856 /*
2857 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2858 % %
2859 % %
2860 % %
2861 % T r a n s f e r P i x e l V i e w I t e r a t o r %
2862 % %
2863 % %
2864 % %
2865 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2866 %
2867 % TransferPixelViewIterator() iterates over two pixel views in parallel and
2868 % calls your transfer method for each scanline of the view. The source pixel
2869 % region is not confined to the image canvas-- that is you can include
2870 % negative offsets or widths or heights that exceed the image dimension.
2871 % However, the destination pixel view is confined to the image canvas-- that
2872 % is no negative offsets or widths or heights that exceed the image dimension
2873 % are permitted.
2874 %
2875 % Use this pragma:
2876 %
2877 % #pragma omp critical
2878 %
2879 % to define a section of code in your callback transfer method that must be
2880 % executed by a single thread at a time.
2881 %
2882 % The format of the TransferPixelViewIterator method is:
2883 %
2884 % MagickBooleanType TransferPixelViewIterator(PixelView *source,
2885 % PixelView *destination,TransferPixelViewMethod transfer,void *context)
2886 %
2887 % A description of each parameter follows:
2888 %
2889 % o source: the source pixel view.
2890 %
2891 % o destination: the destination pixel view.
2892 %
2893 % o transfer: the transfer callback method.
2894 %
2895 % o context: the user defined context.
2896 %
2897 */
2898 WandExport MagickBooleanType TransferPixelViewIterator(PixelView *source,
2899  PixelView *destination,TransferPixelViewMethod transfer,void *context)
2900 {
2901 #define TransferPixelViewTag "PixelView/Transfer"
2902 
2903  ExceptionInfo
2904  *exception;
2905 
2906  Image
2907  *destination_image,
2908  *source_image;
2909 
2910  MagickBooleanType
2911  status;
2912 
2913  MagickOffsetType
2914  progress;
2915 
2916  ssize_t
2917  y;
2918 
2919  assert(source != (PixelView *) NULL);
2920  assert(source->signature == WandSignature);
2921  if (transfer == (TransferPixelViewMethod) NULL)
2922  return(MagickFalse);
2923  source_image=source->wand->images;
2924  destination_image=destination->wand->images;
2925  if (SetImageStorageClass(destination_image,DirectClass) == MagickFalse)
2926  return(MagickFalse);
2927  status=MagickTrue;
2928  progress=0;
2929  exception=destination->exception;
2930 #if defined(MAGICKCORE_OPENMP_SUPPORT)
2931  #pragma omp parallel for schedule(static) shared(progress,status)
2932 #endif
2933  for (y=source->region.y; y < (ssize_t) source->region.height; y++)
2934  {
2935  const int
2936  id = GetOpenMPThreadId();
2937 
2938  MagickBooleanType
2939  sync;
2940 
2941  const IndexPacket
2942  *magick_restrict indexes;
2943 
2944  const PixelPacket
2945  *magick_restrict pixels;
2946 
2947  IndexPacket
2948  *magick_restrict destination_indexes;
2949 
2950  ssize_t
2951  x;
2952 
2953  PixelPacket
2954  *magick_restrict destination_pixels;
2955 
2956  if (status == MagickFalse)
2957  continue;
2958  pixels=GetCacheViewVirtualPixels(source->view,source->region.x,y,
2959  source->region.width,1,source->exception);
2960  if (pixels == (const PixelPacket *) NULL)
2961  {
2962  status=MagickFalse;
2963  continue;
2964  }
2965  indexes=GetCacheViewVirtualIndexQueue(source->view);
2966  for (x=0; x < (ssize_t) source->region.width; x++)
2967  PixelSetQuantumColor(source->pixel_wands[id][x],pixels+x);
2968  if (source_image->colorspace == CMYKColorspace)
2969  for (x=0; x < (ssize_t) source->region.width; x++)
2970  PixelSetBlackQuantum(source->pixel_wands[id][x],
2971  GetPixelIndex(indexes+x));
2972  if (source_image->storage_class == PseudoClass)
2973  for (x=0; x < (ssize_t) source->region.width; x++)
2974  PixelSetIndex(source->pixel_wands[id][x],
2975  GetPixelIndex(indexes+x));
2976  destination_pixels=GetCacheViewAuthenticPixels(destination->view,
2977  destination->region.x,y,destination->region.width,1,exception);
2978  if (destination_pixels == (PixelPacket *) NULL)
2979  {
2980  status=MagickFalse;
2981  continue;
2982  }
2983  destination_indexes=GetCacheViewAuthenticIndexQueue(destination->view);
2984  for (x=0; x < (ssize_t) destination->region.width; x++)
2985  PixelSetQuantumColor(destination->pixel_wands[id][x],pixels+x);
2986  if (destination_image->colorspace == CMYKColorspace)
2987  for (x=0; x < (ssize_t) destination->region.width; x++)
2988  PixelSetBlackQuantum(destination->pixel_wands[id][x],
2989  GetPixelIndex(indexes+x));
2990  if (destination_image->storage_class == PseudoClass)
2991  for (x=0; x < (ssize_t) destination->region.width; x++)
2992  PixelSetIndex(destination->pixel_wands[id][x],
2993  GetPixelIndex(indexes+x));
2994  if (transfer(source,destination,context) == MagickFalse)
2995  status=MagickFalse;
2996  for (x=0; x < (ssize_t) destination->region.width; x++)
2997  PixelGetQuantumColor(destination->pixel_wands[id][x],
2998  destination_pixels+x);
2999  if (destination_image->colorspace == CMYKColorspace)
3000  for (x=0; x < (ssize_t) destination->region.width; x++)
3001  SetPixelIndex(destination_indexes+x,PixelGetBlackQuantum(
3002  destination->pixel_wands[id][x]));
3003  sync=SyncCacheViewAuthenticPixels(destination->view,exception);
3004  if (sync == MagickFalse)
3005  {
3006  InheritException(destination->exception,GetCacheViewException(
3007  source->view));
3008  status=MagickFalse;
3009  }
3010  if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
3011  {
3012  MagickBooleanType
3013  proceed;
3014 
3015 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3016  #pragma omp atomic
3017 #endif
3018  progress++;
3019  proceed=SetImageProgress(source_image,TransferPixelViewTag,progress,
3020  source->region.height);
3021  if (proceed == MagickFalse)
3022  status=MagickFalse;
3023  }
3024  }
3025  return(status);
3026 }
3027 
3028 /*
3029 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3030 % %
3031 % %
3032 % %
3033 % U p d a t e P i x e l V i e w I t e r a t o r %
3034 % %
3035 % %
3036 % %
3037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3038 %
3039 % UpdatePixelViewIterator() iterates over the pixel view in parallel and calls
3040 % your update method for each scanline of the view. The pixel region is
3041 % confined to the image canvas-- that is no negative offsets or widths or
3042 % heights that exceed the image dimension are permitted. Updates to pixels
3043 % in your callback are automagically synced back to the image.
3044 %
3045 % Use this pragma:
3046 %
3047 % #pragma omp critical
3048 %
3049 % to define a section of code in your callback update method that must be
3050 % executed by a single thread at a time.
3051 %
3052 % The format of the UpdatePixelViewIterator method is:
3053 %
3054 % MagickBooleanType UpdatePixelViewIterator(PixelView *source,
3055 % UpdatePixelViewMethod update,void *context)
3056 %
3057 % A description of each parameter follows:
3058 %
3059 % o source: the source pixel view.
3060 %
3061 % o update: the update callback method.
3062 %
3063 % o context: the user defined context.
3064 %
3065 */
3066 WandExport MagickBooleanType UpdatePixelViewIterator(PixelView *source,
3067  UpdatePixelViewMethod update,void *context)
3068 {
3069 #define UpdatePixelViewTag "PixelView/Update"
3070 
3071  ExceptionInfo
3072  *exception;
3073 
3074  Image
3075  *source_image;
3076 
3077  MagickBooleanType
3078  status;
3079 
3080  MagickOffsetType
3081  progress;
3082 
3083  ssize_t
3084  y;
3085 
3086  assert(source != (PixelView *) NULL);
3087  assert(source->signature == WandSignature);
3088  if (update == (UpdatePixelViewMethod) NULL)
3089  return(MagickFalse);
3090  source_image=source->wand->images;
3091  if (SetImageStorageClass(source_image,DirectClass) == MagickFalse)
3092  return(MagickFalse);
3093  status=MagickTrue;
3094  progress=0;
3095  exception=source->exception;
3096 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3097  #pragma omp parallel for schedule(static) shared(progress,status)
3098 #endif
3099  for (y=source->region.y; y < (ssize_t) source->region.height; y++)
3100  {
3101  const int
3102  id = GetOpenMPThreadId();
3103 
3104  IndexPacket
3105  *magick_restrict indexes;
3106 
3107  ssize_t
3108  x;
3109 
3110  PixelPacket
3111  *magick_restrict pixels;
3112 
3113  if (status == MagickFalse)
3114  continue;
3115  pixels=GetCacheViewAuthenticPixels(source->view,source->region.x,y,
3116  source->region.width,1,exception);
3117  if (pixels == (PixelPacket *) NULL)
3118  {
3119  InheritException(source->exception,GetCacheViewException(
3120  source->view));
3121  status=MagickFalse;
3122  continue;
3123  }
3124  indexes=GetCacheViewAuthenticIndexQueue(source->view);
3125  for (x=0; x < (ssize_t) source->region.width; x++)
3126  PixelSetQuantumColor(source->pixel_wands[id][x],pixels+x);
3127  if (source_image->colorspace == CMYKColorspace)
3128  for (x=0; x < (ssize_t) source->region.width; x++)
3129  PixelSetBlackQuantum(source->pixel_wands[id][x],
3130  GetPixelIndex(indexes+x));
3131  if (update(source,context) == MagickFalse)
3132  status=MagickFalse;
3133  for (x=0; x < (ssize_t) source->region.width; x++)
3134  PixelGetQuantumColor(source->pixel_wands[id][x],pixels+x);
3135  if (source_image->colorspace == CMYKColorspace)
3136  for (x=0; x < (ssize_t) source->region.width; x++)
3137  SetPixelIndex(indexes+x,PixelGetBlackQuantum(
3138  source->pixel_wands[id][x]));
3139  if (SyncCacheViewAuthenticPixels(source->view,exception) == MagickFalse)
3140  {
3141  InheritException(source->exception,GetCacheViewException(source->view));
3142  status=MagickFalse;
3143  }
3144  if (source_image->progress_monitor != (MagickProgressMonitor) NULL)
3145  {
3146  MagickBooleanType
3147  proceed;
3148 
3149 #if defined(MAGICKCORE_OPENMP_SUPPORT)
3150  #pragma omp atomic
3151 #endif
3152  progress++;
3153  proceed=SetImageProgress(source_image,UpdatePixelViewTag,progress,
3154  source->region.height);
3155  if (proceed == MagickFalse)
3156  status=MagickFalse;
3157  }
3158  }
3159  return(status);
3160 }
3161 #endif