blob: 20ce1dbd51e32ab14100d614f815aac1d3b6981e [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% PPPP IIIII X X EEEEE L %
7% P P I X X E L %
8% PPPP I X EEE L %
9% P I X X E L %
10% P IIIII X X EEEEE LLLLL %
11% %
12% IIIII TTTTT EEEEE RRRR AAA TTTTT OOO RRRR %
13% I T E R R A A T O O R R %
14% I T EEE RRRR AAAAA T O O RRRR %
15% I T E R R A A T O O R R %
16% IIIII T EEEEE R R A A T OOO R R %
17% %
18% %
19% ImageMagick Image Pixel Iterator Methods %
20% %
21% Software Design %
22% John Cristy %
23% March 2003 %
24% %
25% %
cristy7e41fe82010-12-04 23:12:08 +000026% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000027% dedicated to making software imaging solutions freely available. %
28% %
29% You may not use this file except in compliance with the License. You may %
30% obtain a copy of the License at %
31% %
32% http://www.imagemagick.org/script/license.php %
33% %
34% Unless required by applicable law or agreed to in writing, software %
35% distributed under the License is distributed on an "AS IS" BASIS, %
36% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37% See the License for the specific language governing permissions and %
38% limitations under the License. %
39% %
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41%
42%
43%
44*/
45
46/*
47 Include declarations.
48*/
cristy4c08aed2011-07-01 19:47:50 +000049#include "MagickWand/studio.h"
50#include "MagickWand/MagickWand.h"
51#include "MagickWand/magick-wand-private.h"
52#include "MagickWand/pixel-iterator.h"
53#include "MagickWand/pixel-wand.h"
54#include "MagickWand/wand.h"
cristy3ed852e2009-09-05 21:47:34 +000055
56/*
57 Define declarations.
58*/
59#define PixelIteratorId "PixelIterator"
60
61/*
62 Typedef declarations.
63*/
64struct _PixelIterator
65{
cristybb503372010-05-27 20:51:26 +000066 size_t
cristy3ed852e2009-09-05 21:47:34 +000067 id;
68
69 char
70 name[MaxTextExtent];
71
72 ExceptionInfo
73 *exception;
74
cristy4c08aed2011-07-01 19:47:50 +000075 Image
76 *image;
77
cristy3ed852e2009-09-05 21:47:34 +000078 CacheView
79 *view;
80
81 RectangleInfo
82 region;
83
84 MagickBooleanType
85 active;
86
cristybb503372010-05-27 20:51:26 +000087 ssize_t
cristy3ed852e2009-09-05 21:47:34 +000088 y;
89
90 PixelWand
91 **pixel_wands;
92
93 MagickBooleanType
94 debug;
95
cristybb503372010-05-27 20:51:26 +000096 size_t
cristy3ed852e2009-09-05 21:47:34 +000097 signature;
98};
99
100/*
101%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102% %
103% %
104% %
105% C l e a r P i x e l I t e r a t o r %
106% %
107% %
108% %
109%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110%
111% ClearPixelIterator() clear resources associated with a PixelIterator.
112%
113% The format of the ClearPixelIterator method is:
114%
115% PixelIterator *ClearPixelIterator(PixelIterator *iterator)
116%
117% A description of each parameter follows:
118%
119% o iterator: the pixel iterator.
120%
121*/
122WandExport void ClearPixelIterator(PixelIterator *iterator)
123{
124 assert(iterator != (const PixelIterator *) NULL);
125 assert(iterator->signature == WandSignature);
126 if (iterator->debug != MagickFalse)
127 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
128 iterator->pixel_wands=DestroyPixelWands(iterator->pixel_wands,
129 iterator->region.width);
130 ClearMagickException(iterator->exception);
131 iterator->pixel_wands=NewPixelWands(iterator->region.width);
132 iterator->active=MagickFalse;
133 iterator->y=0;
134 iterator->debug=IsEventLogging();
135}
136
137/*
138%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139% %
140% %
141% %
142% C l o n e P i x e l I t e r a t o r %
143% %
144% %
145% %
146%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
147%
148% ClonePixelIterator() makes an exact copy of the specified iterator.
149%
150% The format of the ClonePixelIterator method is:
151%
152% PixelIterator *ClonePixelIterator(const PixelIterator *iterator)
153%
154% A description of each parameter follows:
155%
156% o iterator: the magick iterator.
157%
158*/
159WandExport PixelIterator *ClonePixelIterator(const PixelIterator *iterator)
160{
161 PixelIterator
162 *clone_iterator;
163
164 assert(iterator != (PixelIterator *) NULL);
165 assert(iterator->signature == WandSignature);
166 if (iterator->debug != MagickFalse)
167 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
cristy73bd4a52010-10-05 11:24:23 +0000168 clone_iterator=(PixelIterator *) AcquireMagickMemory(
cristyf2faecf2010-05-28 19:19:36 +0000169 sizeof(*clone_iterator));
cristy3ed852e2009-09-05 21:47:34 +0000170 if (clone_iterator == (PixelIterator *) NULL)
171 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
172 iterator->name);
173 (void) ResetMagickMemory(clone_iterator,0,sizeof(*clone_iterator));
174 clone_iterator->id=AcquireWandId();
cristyb51dff52011-05-19 16:55:47 +0000175 (void) FormatLocaleString(clone_iterator->name,MaxTextExtent,"%s-%.20g",
cristye8c25f92010-06-03 00:53:06 +0000176 PixelIteratorId,(double) clone_iterator->id);
cristy3ed852e2009-09-05 21:47:34 +0000177 clone_iterator->exception=AcquireExceptionInfo();
178 InheritException(clone_iterator->exception,iterator->exception);
cristy4c08aed2011-07-01 19:47:50 +0000179 clone_iterator->image=CloneImage(iterator->image,0,0,MagickTrue,
180 iterator->exception);
cristy3ed852e2009-09-05 21:47:34 +0000181 clone_iterator->view=CloneCacheView(iterator->view);
182 clone_iterator->region=iterator->region;
183 clone_iterator->active=iterator->active;
184 clone_iterator->y=iterator->y;
185 clone_iterator->pixel_wands=ClonePixelWands((const PixelWand **)
186 iterator->pixel_wands,iterator->region.width);
187 clone_iterator->debug=iterator->debug;
188 if (clone_iterator->debug != MagickFalse)
189 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",
190 clone_iterator->name);
191 clone_iterator->signature=WandSignature;
192 return(clone_iterator);
193}
194
195/*
196%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197% %
198% %
199% %
200% D e s t r o y P i x e l I t e r a t o r %
201% %
202% %
203% %
204%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
205%
206% DestroyPixelIterator() deallocates resources associated with a PixelIterator.
207%
208% The format of the DestroyPixelIterator method is:
209%
210% PixelIterator *DestroyPixelIterator(PixelIterator *iterator)
211%
212% A description of each parameter follows:
213%
214% o iterator: the pixel iterator.
215%
216*/
217WandExport PixelIterator *DestroyPixelIterator(PixelIterator *iterator)
218{
219 assert(iterator != (const PixelIterator *) NULL);
220 assert(iterator->signature == WandSignature);
221 if (iterator->debug != MagickFalse)
222 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
cristy4c08aed2011-07-01 19:47:50 +0000223 iterator->image=DestroyImage(iterator->image);
cristy3ed852e2009-09-05 21:47:34 +0000224 iterator->view=DestroyCacheView(iterator->view);
225 iterator->pixel_wands=DestroyPixelWands(iterator->pixel_wands,
226 iterator->region.width);
227 iterator->exception=DestroyExceptionInfo(iterator->exception);
228 iterator->signature=(~WandSignature);
229 RelinquishWandId(iterator->id);
230 iterator=(PixelIterator *) RelinquishMagickMemory(iterator);
231 return(iterator);
232}
233
234/*
235%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236% %
237% %
238% %
239% I s P i x e l I t e r a t o r %
240% %
241% %
242% %
243%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
244%
245% IsPixelIterator() returns MagickTrue if the iterator is verified as a pixel
246% iterator.
247%
248% The format of the IsPixelIterator method is:
249%
250% MagickBooleanType IsPixelIterator(const PixelIterator *iterator)
251%
252% A description of each parameter follows:
253%
254% o iterator: the magick iterator.
255%
256*/
257WandExport MagickBooleanType IsPixelIterator(const PixelIterator *iterator)
258{
259 size_t
260 length;
261
262 if (iterator == (const PixelIterator *) NULL)
263 return(MagickFalse);
264 if (iterator->signature != WandSignature)
265 return(MagickFalse);
266 length=strlen(PixelIteratorId);
267 if (LocaleNCompare(iterator->name,PixelIteratorId,length) != 0)
268 return(MagickFalse);
269 return(MagickTrue);
270}
271
272/*
273%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274% %
275% %
276% %
277% N e w P i x e l I t e r a t o r %
278% %
279% %
280% %
281%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282%
283% NewPixelIterator() returns a new pixel iterator.
284%
285% The format of the NewPixelIterator method is:
286%
cristy197d0572010-07-29 23:26:05 +0000287% PixelIterator *NewPixelIterator(MagickWand *wand)
cristy3ed852e2009-09-05 21:47:34 +0000288%
289% A description of each parameter follows:
290%
291% o wand: the magick wand.
292%
293*/
294WandExport PixelIterator *NewPixelIterator(MagickWand *wand)
295{
296 const char
297 *quantum;
298
299 Image
300 *image;
301
302 PixelIterator
303 *iterator;
304
cristybb503372010-05-27 20:51:26 +0000305 size_t
cristy3ed852e2009-09-05 21:47:34 +0000306 depth;
307
308 CacheView
309 *view;
310
311 depth=MAGICKCORE_QUANTUM_DEPTH;
312 quantum=GetMagickQuantumDepth(&depth);
313 if (depth != MAGICKCORE_QUANTUM_DEPTH)
314 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
315 assert(wand != (MagickWand *) NULL);
316 image=GetImageFromMagickWand(wand);
317 if (image == (Image *) NULL)
318 return((PixelIterator *) NULL);
319 view=AcquireCacheView(image);
320 if (view == (CacheView *) NULL)
321 return((PixelIterator *) NULL);
cristy73bd4a52010-10-05 11:24:23 +0000322 iterator=(PixelIterator *) AcquireMagickMemory(sizeof(*iterator));
cristy3ed852e2009-09-05 21:47:34 +0000323 if (iterator == (PixelIterator *) NULL)
324 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
325 GetExceptionMessage(errno));
326 (void) ResetMagickMemory(iterator,0,sizeof(*iterator));
327 iterator->id=AcquireWandId();
cristyb51dff52011-05-19 16:55:47 +0000328 (void) FormatLocaleString(iterator->name,MaxTextExtent,"%s-%.20g",
cristye8c25f92010-06-03 00:53:06 +0000329 PixelIteratorId,(double) iterator->id);
cristy3ed852e2009-09-05 21:47:34 +0000330 iterator->exception=AcquireExceptionInfo();
cristy4c08aed2011-07-01 19:47:50 +0000331 iterator->image=CloneImage(image,0,0,MagickTrue,iterator->exception);
cristy3ed852e2009-09-05 21:47:34 +0000332 iterator->view=view;
333 SetGeometry(image,&iterator->region);
334 iterator->region.width=image->columns;
335 iterator->region.height=image->rows;
336 iterator->region.x=0;
337 iterator->region.y=0;
338 iterator->pixel_wands=NewPixelWands(iterator->region.width);
339 iterator->y=0;
340 iterator->debug=IsEventLogging();
341 if (iterator->debug != MagickFalse)
342 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
343 iterator->signature=WandSignature;
344 return(iterator);
345}
346
347/*
348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349% %
350% %
351% %
352% P i x e l C l e a r I t e r a t o r E x c e p t i o n %
353% %
354% %
355% %
356%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
357%
358% PixelClearIteratorException() clear any exceptions associated with the
359% iterator.
360%
361% The format of the PixelClearIteratorException method is:
362%
363% MagickBooleanType PixelClearIteratorException(PixelIterator *wand)
364%
365% A description of each parameter follows:
366%
367% o wand: the pixel wand.
368%
369*/
370WandExport MagickBooleanType PixelClearIteratorException(
371 PixelIterator *iterator)
372{
373 assert(iterator != (PixelIterator *) NULL);
374 assert(iterator->signature == WandSignature);
375 if (iterator->debug != MagickFalse)
376 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
377 ClearMagickException(iterator->exception);
378 return(MagickTrue);
379}
380
381/*
382%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
383% %
384% %
385% %
386% N e w P i x e l R e g i o n I t e r a t o r %
387% %
388% %
389% %
390%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
391%
392% NewPixelRegionIterator() returns a new pixel iterator.
393%
394% The format of the NewPixelRegionIterator method is:
395%
cristybb503372010-05-27 20:51:26 +0000396% PixelIterator NewPixelRegionIterator(MagickWand *wand,const ssize_t x,
397% const ssize_t y,const size_t width,const size_t height)
cristy3ed852e2009-09-05 21:47:34 +0000398%
399% A description of each parameter follows:
400%
401% o wand: the magick wand.
402%
403% o x,y,columns,rows: These values define the perimeter of a region of
404% pixels.
405%
406*/
cristy2e8bde02010-06-22 11:03:25 +0000407WandExport PixelIterator *NewPixelRegionIterator(MagickWand *wand,
408 const ssize_t x,const ssize_t y,const size_t width,const size_t height)
cristy3ed852e2009-09-05 21:47:34 +0000409{
cristy2e8bde02010-06-22 11:03:25 +0000410 CacheView
411 *view;
412
cristy3ed852e2009-09-05 21:47:34 +0000413 const char
414 *quantum;
415
416 Image
417 *image;
418
419 PixelIterator
420 *iterator;
421
cristybb503372010-05-27 20:51:26 +0000422 size_t
cristy3ed852e2009-09-05 21:47:34 +0000423 depth;
424
cristy3ed852e2009-09-05 21:47:34 +0000425 assert(wand != (MagickWand *) NULL);
426 depth=MAGICKCORE_QUANTUM_DEPTH;
427 quantum=GetMagickQuantumDepth(&depth);
428 if (depth != MAGICKCORE_QUANTUM_DEPTH)
429 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
430 if ((width == 0) || (width == 0))
431 ThrowWandFatalException(WandError,"ZeroRegionSize",quantum);
432 image=GetImageFromMagickWand(wand);
433 if (image == (Image *) NULL)
434 return((PixelIterator *) NULL);
435 view=AcquireCacheView(image);
436 if (view == (CacheView *) NULL)
437 return((PixelIterator *) NULL);
cristy73bd4a52010-10-05 11:24:23 +0000438 iterator=(PixelIterator *) AcquireMagickMemory(sizeof(*iterator));
cristy3ed852e2009-09-05 21:47:34 +0000439 if (iterator == (PixelIterator *) NULL)
440 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
441 wand->name);
442 (void) ResetMagickMemory(iterator,0,sizeof(*iterator));
443 iterator->id=AcquireWandId();
cristyb51dff52011-05-19 16:55:47 +0000444 (void) FormatLocaleString(iterator->name,MaxTextExtent,"%s-%.20g",
cristye8c25f92010-06-03 00:53:06 +0000445 PixelIteratorId,(double) iterator->id);
cristy3ed852e2009-09-05 21:47:34 +0000446 iterator->exception=AcquireExceptionInfo();
447 iterator->view=view;
448 SetGeometry(image,&iterator->region);
449 iterator->region.width=width;
450 iterator->region.height=height;
451 iterator->region.x=x;
452 iterator->region.y=y;
453 iterator->pixel_wands=NewPixelWands(iterator->region.width);
454 iterator->y=0;
455 iterator->debug=IsEventLogging();
456 if (iterator->debug != MagickFalse)
457 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
458 iterator->signature=WandSignature;
459 return(iterator);
460}
461
462/*
463%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
464% %
465% %
466% %
467% P i x e l G e t C u r r e n t I t e r a t o r R o w %
468% %
469% %
470% %
471%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
472%
473% PixelGetCurrentIteratorRow() returns the current row as an array of pixel
474% wands from the pixel iterator.
475%
476% The format of the PixelGetCurrentIteratorRow method is:
477%
478% PixelWand **PixelGetCurrentIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000479% size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000480%
481% A description of each parameter follows:
482%
483% o iterator: the pixel iterator.
484%
485% o number_wands: the number of pixel wands.
486%
487*/
488WandExport PixelWand **PixelGetCurrentIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000489 size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000490{
cristy4c08aed2011-07-01 19:47:50 +0000491 register const Quantum
cristy3ed852e2009-09-05 21:47:34 +0000492 *pixels;
493
cristybb503372010-05-27 20:51:26 +0000494 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000495 x;
496
497 assert(iterator != (PixelIterator *) NULL);
498 assert(iterator->signature == WandSignature);
499 if (iterator->debug != MagickFalse)
500 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
501 *number_wands=0;
502 iterator->active=MagickTrue;
503 pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
504 iterator->region.y+iterator->y,iterator->region.width,1,
505 iterator->exception);
cristy4c08aed2011-07-01 19:47:50 +0000506 if (pixels == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000507 {
508 InheritException(iterator->exception,GetCacheViewException(
509 iterator->view));
510 return((PixelWand **) NULL);
511 }
cristybb503372010-05-27 20:51:26 +0000512 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy4c08aed2011-07-01 19:47:50 +0000513 {
514 PixelSetQuantumPixel(iterator->image,pixels,iterator->pixel_wands[x]);
cristyed231572011-07-14 02:18:59 +0000515 pixels+=GetPixelChannels(iterator->image);
cristy4c08aed2011-07-01 19:47:50 +0000516 }
cristy3ed852e2009-09-05 21:47:34 +0000517 *number_wands=iterator->region.width;
518 return(iterator->pixel_wands);
519}
520
521/*
522%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
523% %
524% %
525% %
526% P i x e l G e t I t e r a t o r E x c e p t i o n %
527% %
528% %
529% %
530%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
531%
532% PixelGetIteratorException() returns the severity, reason, and description of
533% any error that occurs when using other methods in this API.
534%
535% The format of the PixelGetIteratorException method is:
536%
537% char *PixelGetIteratorException(const Pixeliterator *iterator,
538% ExceptionType *severity)
539%
540% A description of each parameter follows:
541%
542% o iterator: the pixel iterator.
543%
544% o severity: the severity of the error is returned here.
545%
546*/
547WandExport char *PixelGetIteratorException(const PixelIterator *iterator,
548 ExceptionType *severity)
549{
550 char
551 *description;
552
553 assert(iterator != (const PixelIterator *) NULL);
554 assert(iterator->signature == WandSignature);
555 if (iterator->debug != MagickFalse)
556 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
557 assert(severity != (ExceptionType *) NULL);
558 *severity=iterator->exception->severity;
559 description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
560 sizeof(*description));
561 if (description == (char *) NULL)
562 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
563 iterator->name);
564 *description='\0';
565 if (iterator->exception->reason != (char *) NULL)
566 (void) CopyMagickString(description,GetLocaleExceptionMessage(
567 iterator->exception->severity,iterator->exception->reason),MaxTextExtent);
568 if (iterator->exception->description != (char *) NULL)
569 {
570 (void) ConcatenateMagickString(description," (",MaxTextExtent);
571 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
572 iterator->exception->severity,iterator->exception->description),
573 MaxTextExtent);
574 (void) ConcatenateMagickString(description,")",MaxTextExtent);
575 }
576 return(description);
577}
578
579/*
580%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
581% %
582% %
583% %
584% P i x e l G e t E x c e p t i o n T y p e %
585% %
586% %
587% %
588%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
589%
590% PixelGetIteratorExceptionType() the exception type associated with the wand.
591% If no exception has occurred, UndefinedExceptionType is returned.
592%
593% The format of the PixelGetIteratorExceptionType method is:
594%
595% ExceptionType PixelGetIteratorExceptionType(const PixelWand *wand)
596%
597% A description of each parameter follows:
598%
599% o wand: the magick wand.
600%
601*/
602WandExport ExceptionType PixelGetIteratorExceptionType(
603 const PixelIterator *wand)
604{
605 assert(wand != (const PixelIterator *) NULL);
606 assert(wand->signature == WandSignature);
607 if (wand->debug != MagickFalse)
608 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
609 return(wand->exception->severity);
610}
611
612/*
613%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
614% %
615% %
616% %
617% P i x e l G e t I t e r a t o r R o w %
618% %
619% %
620% %
621%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
622%
623% PixelGetIteratorRow() returns the current pixel iterator row.
624%
625% The format of the PixelGetIteratorRow method is:
626%
627% MagickBooleanType PixelGetIteratorRow(PixelIterator *iterator)
628%
629% A description of each parameter follows:
630%
631% o iterator: the pixel iterator.
632%
633*/
cristybb503372010-05-27 20:51:26 +0000634WandExport ssize_t PixelGetIteratorRow(PixelIterator *iterator)
cristy3ed852e2009-09-05 21:47:34 +0000635{
636 assert(iterator != (const PixelIterator *) NULL);
637 assert(iterator->signature == WandSignature);
638 if (iterator->debug != MagickFalse)
639 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
640 return(iterator->y);
641}
642
643/*
644%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645% %
646% %
647% %
648% P i x e l G e t N e x t I t e r a t o r R o w %
649% %
650% %
651% %
652%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
653%
654% PixelGetNextIteratorRow() returns the next row as an array of pixel wands
655% from the pixel iterator.
656%
657% The format of the PixelGetNextIteratorRow method is:
658%
659% PixelWand **PixelGetNextIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000660% size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000661%
662% A description of each parameter follows:
663%
664% o iterator: the pixel iterator.
665%
666% o number_wands: the number of pixel wands.
667%
668*/
669WandExport PixelWand **PixelGetNextIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000670 size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000671{
cristy4c08aed2011-07-01 19:47:50 +0000672 register const Quantum
cristy3ed852e2009-09-05 21:47:34 +0000673 *pixels;
674
cristybb503372010-05-27 20:51:26 +0000675 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000676 x;
677
678 assert(iterator != (PixelIterator *) NULL);
679 assert(iterator->signature == WandSignature);
680 if (iterator->debug != MagickFalse)
681 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
682 *number_wands=0;
683 if (iterator->active != MagickFalse)
684 iterator->y++;
685 if (PixelSetIteratorRow(iterator,iterator->y) == MagickFalse)
686 return((PixelWand **) NULL);
687 pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
688 iterator->region.y+iterator->y,iterator->region.width,1,
689 iterator->exception);
cristy4c08aed2011-07-01 19:47:50 +0000690 if (pixels == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000691 {
692 InheritException(iterator->exception,GetCacheViewException(
693 iterator->view));
694 return((PixelWand **) NULL);
695 }
cristybb503372010-05-27 20:51:26 +0000696 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy4c08aed2011-07-01 19:47:50 +0000697 {
698 PixelSetQuantumPixel(iterator->image,pixels,iterator->pixel_wands[x]);
cristyed231572011-07-14 02:18:59 +0000699 pixels+=GetPixelChannels(iterator->image);
cristy4c08aed2011-07-01 19:47:50 +0000700 }
cristy3ed852e2009-09-05 21:47:34 +0000701 *number_wands=iterator->region.width;
702 return(iterator->pixel_wands);
703}
704
705/*
706%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707% %
708% %
709% %
710% P i x e l G e t P r e v i o u s I t e r a t o r R o w %
711% %
712% %
713% %
714%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
715%
716% PixelGetPreviousIteratorRow() returns the previous row as an array of pixel
717% wands from the pixel iterator.
718%
719% The format of the PixelGetPreviousIteratorRow method is:
720%
721% PixelWand **PixelGetPreviousIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000722% size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000723%
724% A description of each parameter follows:
725%
726% o iterator: the pixel iterator.
727%
728% o number_wands: the number of pixel wands.
729%
730*/
731
732WandExport PixelWand **PixelGetPreviousRow(PixelIterator *iterator)
733{
cristybb503372010-05-27 20:51:26 +0000734 size_t
cristy3ed852e2009-09-05 21:47:34 +0000735 number_wands;
736
737 return(PixelGetPreviousIteratorRow(iterator,&number_wands));
738}
739
740WandExport PixelWand **PixelGetPreviousIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000741 size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000742{
cristy4c08aed2011-07-01 19:47:50 +0000743 register const Quantum
cristy3ed852e2009-09-05 21:47:34 +0000744 *pixels;
745
cristybb503372010-05-27 20:51:26 +0000746 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000747 x;
748
749 assert(iterator != (PixelIterator *) NULL);
750 assert(iterator->signature == WandSignature);
751 if (iterator->debug != MagickFalse)
752 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
753 *number_wands=0;
754 if (iterator->active != MagickFalse)
755 iterator->y--;
756 if (PixelSetIteratorRow(iterator,iterator->y) == MagickFalse)
757 return((PixelWand **) NULL);
758 pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
759 iterator->region.y+iterator->y,iterator->region.width,1,
760 iterator->exception);
cristy4c08aed2011-07-01 19:47:50 +0000761 if (pixels == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000762 {
763 InheritException(iterator->exception,GetCacheViewException(
764 iterator->view));
765 return((PixelWand **) NULL);
766 }
cristybb503372010-05-27 20:51:26 +0000767 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy4c08aed2011-07-01 19:47:50 +0000768 {
769 PixelSetQuantumPixel(iterator->image,pixels,iterator->pixel_wands[x]);
cristyed231572011-07-14 02:18:59 +0000770 pixels+=GetPixelChannels(iterator->image);
cristy4c08aed2011-07-01 19:47:50 +0000771 }
cristy3ed852e2009-09-05 21:47:34 +0000772 *number_wands=iterator->region.width;
773 return(iterator->pixel_wands);
774}
775
776/*
777%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
778% %
779% %
780% %
781% P i x e l R e s e t I t e r a t o r %
782% %
783% %
784% %
785%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
786%
787% PixelResetIterator() resets the pixel iterator. Use it in conjunction
788% with PixelGetNextIteratorRow() to iterate over all the pixels in a pixel
789% container.
790%
791% The format of the PixelResetIterator method is:
792%
793% void PixelResetIterator(PixelIterator *iterator)
794%
795% A description of each parameter follows:
796%
797% o iterator: the pixel iterator.
798%
799*/
800WandExport void PixelResetIterator(PixelIterator *iterator)
801{
802 assert(iterator != (PixelIterator *) NULL);
803 assert(iterator->signature == WandSignature);
804 if (iterator->debug != MagickFalse)
805 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
806 iterator->active=MagickFalse;
807 iterator->y=0;
808}
809
810/*
811%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
812% %
813% %
814% %
815% P i x e l S e t F i r s t I t e r a t o r R o w %
816% %
817% %
818% %
819%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
820%
821% PixelSetFirstIteratorRow() sets the pixel iterator to the first pixel row.
822%
823% The format of the PixelSetFirstIteratorRow method is:
824%
825% void PixelSetFirstIteratorRow(PixelIterator *iterator)
826%
827% A description of each parameter follows:
828%
829% o iterator: the magick iterator.
830%
831*/
832WandExport void PixelSetFirstIteratorRow(PixelIterator *iterator)
833{
834 assert(iterator != (PixelIterator *) NULL);
835 assert(iterator->signature == WandSignature);
836 if (iterator->debug != MagickFalse)
837 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
838 iterator->active=MagickFalse;
839 iterator->y=iterator->region.y;
840}
841
842/*
843%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
844% %
845% %
846% %
847% P i x e l S e t I t e r a t o r R o w %
848% %
849% %
850% %
851%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
852%
853% PixelSetIteratorRow() set the pixel iterator row.
854%
855% The format of the PixelSetIteratorRow method is:
856%
857% MagickBooleanType PixelSetIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000858% const ssize_t row)
cristy3ed852e2009-09-05 21:47:34 +0000859%
860% A description of each parameter follows:
861%
862% o iterator: the pixel iterator.
863%
864*/
865WandExport MagickBooleanType PixelSetIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000866 const ssize_t row)
cristy3ed852e2009-09-05 21:47:34 +0000867{
868 assert(iterator != (const PixelIterator *) NULL);
869 assert(iterator->signature == WandSignature);
870 if (iterator->debug != MagickFalse)
871 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
cristybb503372010-05-27 20:51:26 +0000872 if ((row < 0) || (row >= (ssize_t) iterator->region.height))
cristy3ed852e2009-09-05 21:47:34 +0000873 return(MagickFalse);
874 iterator->active=MagickTrue;
875 iterator->y=row;
876 return(MagickTrue);
877}
878
879/*
880%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
881% %
882% %
883% %
884% P i x e l S e t L a s t I t e r a t o r R o w %
885% %
886% %
887% %
888%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
889%
890% PixelSetLastIteratorRow() sets the pixel iterator to the last pixel row.
891%
892% The format of the PixelSetLastIteratorRow method is:
893%
894% void PixelSetLastIteratorRow(PixelIterator *iterator)
895%
896% A description of each parameter follows:
897%
898% o iterator: the magick iterator.
899%
900*/
901WandExport void PixelSetLastIteratorRow(PixelIterator *iterator)
902{
903 assert(iterator != (PixelIterator *) NULL);
904 assert(iterator->signature == WandSignature);
905 if (iterator->debug != MagickFalse)
906 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
907 iterator->active=MagickFalse;
cristybb503372010-05-27 20:51:26 +0000908 iterator->y=(ssize_t) iterator->region.height-1;
cristy3ed852e2009-09-05 21:47:34 +0000909}
910
911/*
912%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
913% %
914% %
915% %
916% P i x e l S y n c I t e r a t o r %
917% %
918% %
919% %
920%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
921%
922% PixelSyncIterator() syncs the pixel iterator.
923%
924% The format of the PixelSyncIterator method is:
925%
926% MagickBooleanType PixelSyncIterator(PixelIterator *iterator)
927%
928% A description of each parameter follows:
929%
930% o iterator: the pixel iterator.
931%
932*/
933WandExport MagickBooleanType PixelSyncIterator(PixelIterator *iterator)
934{
935 ExceptionInfo
936 *exception;
937
cristybb503372010-05-27 20:51:26 +0000938 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000939 x;
940
cristy4c08aed2011-07-01 19:47:50 +0000941 register Quantum
cristyc47d1f82009-11-26 01:44:43 +0000942 *restrict pixels;
cristy3ed852e2009-09-05 21:47:34 +0000943
944 assert(iterator != (const PixelIterator *) NULL);
945 assert(iterator->signature == WandSignature);
946 if (iterator->debug != MagickFalse)
947 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
948 if (SetCacheViewStorageClass(iterator->view,DirectClass) == MagickFalse)
949 return(MagickFalse);
950 exception=iterator->exception;
951 pixels=GetCacheViewAuthenticPixels(iterator->view,iterator->region.x,
952 iterator->region.y+iterator->y,iterator->region.width,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000953 if (pixels == (Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000954 {
955 InheritException(iterator->exception,GetCacheViewException(
956 iterator->view));
957 return(MagickFalse);
958 }
cristybb503372010-05-27 20:51:26 +0000959 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy4c08aed2011-07-01 19:47:50 +0000960 {
961 PixelGetQuantumPixel(iterator->image,iterator->pixel_wands[x],pixels);
cristyed231572011-07-14 02:18:59 +0000962 pixels+=GetPixelChannels(iterator->image);
cristy4c08aed2011-07-01 19:47:50 +0000963 }
cristy3ed852e2009-09-05 21:47:34 +0000964 if (SyncCacheViewAuthenticPixels(iterator->view,exception) == MagickFalse)
965 {
966 InheritException(iterator->exception,GetCacheViewException(
967 iterator->view));
968 return(MagickFalse);
969 }
970 return(MagickTrue);
971}