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