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