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 
69   MagickWand
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 */
DrawAllocateWand(const DrawInfo * draw_info,Image * image)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 
CloneMagickWandFromImages(const MagickWand * wand,Image * images)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 
MagickAverageImages(MagickWand * wand)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 */
ClonePixelView(const PixelView * pixel_view)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 
DestroyPixelsThreadSet(PixelWand *** pixel_wands,const size_t number_wands,const size_t number_threads)278 static PixelWand ***DestroyPixelsThreadSet(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 
DestroyPixelView(PixelView * pixel_view)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=DestroyPixelsThreadSet(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 */
DuplexTransferPixelViewIterator(PixelView * source,PixelView * duplex,PixelView * destination,DuplexTransferPixelViewMethod transfer,void * context)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 */
GetPixelViewException(const PixelView * pixel_view,ExceptionType * severity)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 */
GetPixelViewHeight(const PixelView * pixel_view)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 */
GetPixelViewIterator(PixelView * source,GetPixelViewMethod get,void * context)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 */
GetPixelViewPixels(const PixelView * pixel_view)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 */
GetPixelViewWand(const PixelView * pixel_view)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 */
GetPixelViewWidth(const PixelView * pixel_view)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 */
GetPixelViewX(const PixelView * pixel_view)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 */
GetPixelViewY(const PixelView * pixel_view)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 */
IsPixelView(const PixelView * pixel_view)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 */
MagickClipPathImage(MagickWand * wand,const char * pathname,const MagickBooleanType inside)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 */
DrawGetFillAlpha(const DrawingWand * wand)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 */
DrawGetStrokeAlpha(const DrawingWand * wand)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 */
DrawPeekGraphicWand(const DrawingWand * wand)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 */
DrawPopGraphicContext(DrawingWand * wand)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 */
DrawPushGraphicContext(DrawingWand * wand)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 */
DrawSetFillAlpha(DrawingWand * wand,const double fill_alpha)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 */
DrawSetStrokeAlpha(DrawingWand * wand,const double stroke_alpha)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 */
MagickColorFloodfillImage(MagickWand * wand,const PixelWand * fill,const double fuzz,const PixelWand * bordercolor,const ssize_t x,const ssize_t y)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 */
MagickDescribeImage(MagickWand * wand)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 */
MagickFlattenImages(MagickWand * wand)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 */
MagickGetImageAttribute(MagickWand * wand,const char * property)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 */
MagickGetImageIndex(MagickWand * wand)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 */
MagickGetImageChannelExtrema(MagickWand * wand,const ChannelType channel,size_t * minima,size_t * maxima)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 */
MagickGetImageExtrema(MagickWand * wand,size_t * minima,size_t * maxima)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 */
MagickGetImageMatte(MagickWand * wand)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 */
MagickGetImagePixels(MagickWand * wand,const ssize_t x,const ssize_t y,const size_t columns,const size_t rows,const char * map,const StorageType storage,void * pixels)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 */
MagickGetImageSize(MagickWand * wand)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 */
MagickMapImage(MagickWand * wand,const MagickWand * map_wand,const MagickBooleanType dither)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 */
MagickMatteFloodfillImage(MagickWand * wand,const double alpha,const double fuzz,const PixelWand * bordercolor,const ssize_t x,const ssize_t y)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 */
MagickMedianFilterImage(MagickWand * wand,const double radius)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 */
MagickMinimumImages(MagickWand * wand)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 */
MagickModeImage(MagickWand * wand,const double radius)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 */
MagickMosaicImages(MagickWand * wand)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 */
MagickOpaqueImage(MagickWand * wand,const PixelWand * target,const PixelWand * fill,const double fuzz)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 */
MagickPaintFloodfillImage(MagickWand * wand,const ChannelType channel,const PixelWand * fill,const double fuzz,const PixelWand * bordercolor,const ssize_t x,const ssize_t y)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 
MagickPaintOpaqueImage(MagickWand * wand,const PixelWand * target,const PixelWand * fill,const double fuzz)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 
MagickPaintOpaqueImageChannel(MagickWand * wand,const ChannelType channel,const PixelWand * target,const PixelWand * fill,const double fuzz)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 */
MagickPaintTransparentImage(MagickWand * wand,const PixelWand * target,const double alpha,const double fuzz)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 */
MagickRadialBlurImage(MagickWand * wand,const double angle)2077 WandExport MagickBooleanType MagickRadialBlurImage(MagickWand *wand,
2078   const double angle)
2079 {
2080   return(MagickRotationalBlurImage(wand,angle));
2081 }
2082 
MagickRadialBlurImageChannel(MagickWand * wand,const ChannelType channel,const double angle)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 */
MagickRecolorImage(MagickWand * wand,const size_t order,const double * color_matrix)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 */
MagickReduceNoiseImage(MagickWand * wand,const double radius)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 */
MagickMaximumImages(MagickWand * wand)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 */
MagickSetImageAttribute(MagickWand * wand,const char * property,const char * value)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 */
MagickSetImageIndex(MagickWand * wand,const ssize_t index)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 */
MagickSetImageOption(MagickWand * wand,const char * format,const char * key,const char * value)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 */
MagickTransparentImage(MagickWand * wand,const PixelWand * target,const double alpha,const double fuzz)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 */
MagickRegionOfInterestImage(MagickWand * wand,const size_t width,const size_t height,const ssize_t x,const ssize_t y)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 */
MagickSetImagePixels(MagickWand * wand,const ssize_t x,const ssize_t y,const size_t columns,const size_t rows,const char * map,const StorageType storage,const void * pixels)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 */
MagickWriteImageBlob(MagickWand * wand,size_t * length)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 
AcquirePixelsThreadSet(const size_t number_wands,const size_t number_threads)2539 static PixelWand ***AcquirePixelsThreadSet(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(DestroyPixelsThreadSet(pixel_wands,number_wands,number_threads));
2558   }
2559   return(pixel_wands);
2560 }
2561 
NewPixelView(MagickWand * wand)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=AcquirePixelsThreadSet(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 */
NewPixelViewRegion(MagickWand * wand,const ssize_t x,const ssize_t y,const size_t width,const size_t height)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=AcquirePixelsThreadSet(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 */
PixelGetNextRow(PixelIterator * iterator)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 */
PixelIteratorGetException(const PixelIterator * iterator,ExceptionType * severity)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 */
SetPixelViewIterator(PixelView * destination,SetPixelViewMethod set,void * context)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 */
TransferPixelViewIterator(PixelView * source,PixelView * destination,TransferPixelViewMethod transfer,void * context)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 */
UpdatePixelViewIterator(PixelView * source,UpdatePixelViewMethod update,void * context)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
3162