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