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