blob: b8a10bffbbc3ac3344cc041a16ae1d0e4749ff95 [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
anthonya89dd172011-10-04 13:29:35 +000085 active; /* user has been given pixel data */
cristy3ed852e2009-09-05 21:47:34 +000086
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)
cristycad4e1b2011-10-16 14:58:39 +0000507 return((PixelWand **) NULL);
cristybb503372010-05-27 20:51:26 +0000508 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy4c08aed2011-07-01 19:47:50 +0000509 {
510 PixelSetQuantumPixel(iterator->image,pixels,iterator->pixel_wands[x]);
cristyed231572011-07-14 02:18:59 +0000511 pixels+=GetPixelChannels(iterator->image);
cristy4c08aed2011-07-01 19:47:50 +0000512 }
cristy3ed852e2009-09-05 21:47:34 +0000513 *number_wands=iterator->region.width;
514 return(iterator->pixel_wands);
515}
516
517/*
518%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
519% %
520% %
521% %
522% 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 %
523% %
524% %
525% %
526%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
527%
528% PixelGetIteratorException() returns the severity, reason, and description of
529% any error that occurs when using other methods in this API.
530%
531% The format of the PixelGetIteratorException method is:
532%
533% char *PixelGetIteratorException(const Pixeliterator *iterator,
534% ExceptionType *severity)
535%
536% A description of each parameter follows:
537%
538% o iterator: the pixel iterator.
539%
540% o severity: the severity of the error is returned here.
541%
542*/
543WandExport char *PixelGetIteratorException(const PixelIterator *iterator,
544 ExceptionType *severity)
545{
546 char
547 *description;
548
549 assert(iterator != (const PixelIterator *) NULL);
550 assert(iterator->signature == WandSignature);
551 if (iterator->debug != MagickFalse)
552 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
553 assert(severity != (ExceptionType *) NULL);
554 *severity=iterator->exception->severity;
555 description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
556 sizeof(*description));
557 if (description == (char *) NULL)
558 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
559 iterator->name);
560 *description='\0';
561 if (iterator->exception->reason != (char *) NULL)
562 (void) CopyMagickString(description,GetLocaleExceptionMessage(
563 iterator->exception->severity,iterator->exception->reason),MaxTextExtent);
564 if (iterator->exception->description != (char *) NULL)
565 {
566 (void) ConcatenateMagickString(description," (",MaxTextExtent);
567 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
568 iterator->exception->severity,iterator->exception->description),
569 MaxTextExtent);
570 (void) ConcatenateMagickString(description,")",MaxTextExtent);
571 }
572 return(description);
573}
574
575/*
576%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
577% %
578% %
579% %
580% P i x e l G e t E x c e p t i o n T y p e %
581% %
582% %
583% %
584%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
585%
586% PixelGetIteratorExceptionType() the exception type associated with the wand.
587% If no exception has occurred, UndefinedExceptionType is returned.
588%
589% The format of the PixelGetIteratorExceptionType method is:
590%
591% ExceptionType PixelGetIteratorExceptionType(const PixelWand *wand)
592%
593% A description of each parameter follows:
594%
595% o wand: the magick wand.
596%
597*/
598WandExport ExceptionType PixelGetIteratorExceptionType(
599 const PixelIterator *wand)
600{
601 assert(wand != (const PixelIterator *) NULL);
602 assert(wand->signature == WandSignature);
603 if (wand->debug != MagickFalse)
604 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
605 return(wand->exception->severity);
606}
607
608/*
609%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
610% %
611% %
612% %
613% P i x e l G e t I t e r a t o r R o w %
614% %
615% %
616% %
617%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
618%
619% PixelGetIteratorRow() returns the current pixel iterator row.
620%
621% The format of the PixelGetIteratorRow method is:
622%
623% MagickBooleanType PixelGetIteratorRow(PixelIterator *iterator)
624%
625% A description of each parameter follows:
626%
627% o iterator: the pixel iterator.
628%
629*/
cristybb503372010-05-27 20:51:26 +0000630WandExport ssize_t PixelGetIteratorRow(PixelIterator *iterator)
cristy3ed852e2009-09-05 21:47:34 +0000631{
632 assert(iterator != (const PixelIterator *) NULL);
633 assert(iterator->signature == WandSignature);
634 if (iterator->debug != MagickFalse)
635 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
636 return(iterator->y);
637}
638
639/*
640%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
641% %
642% %
643% %
644% P i x e l G e t N e x t I t e r a t o r R o w %
645% %
646% %
647% %
648%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
649%
650% PixelGetNextIteratorRow() returns the next row as an array of pixel wands
651% from the pixel iterator.
652%
653% The format of the PixelGetNextIteratorRow method is:
654%
655% PixelWand **PixelGetNextIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000656% size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000657%
658% A description of each parameter follows:
659%
660% o iterator: the pixel iterator.
661%
662% o number_wands: the number of pixel wands.
663%
664*/
665WandExport PixelWand **PixelGetNextIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000666 size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000667{
cristy4c08aed2011-07-01 19:47:50 +0000668 register const Quantum
cristy3ed852e2009-09-05 21:47:34 +0000669 *pixels;
670
cristybb503372010-05-27 20:51:26 +0000671 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000672 x;
673
674 assert(iterator != (PixelIterator *) NULL);
675 assert(iterator->signature == WandSignature);
676 if (iterator->debug != MagickFalse)
677 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
678 *number_wands=0;
679 if (iterator->active != MagickFalse)
680 iterator->y++;
681 if (PixelSetIteratorRow(iterator,iterator->y) == MagickFalse)
682 return((PixelWand **) NULL);
683 pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
684 iterator->region.y+iterator->y,iterator->region.width,1,
685 iterator->exception);
cristy4c08aed2011-07-01 19:47:50 +0000686 if (pixels == (const Quantum *) NULL)
cristycad4e1b2011-10-16 14:58:39 +0000687 return((PixelWand **) NULL);
cristybb503372010-05-27 20:51:26 +0000688 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy4c08aed2011-07-01 19:47:50 +0000689 {
690 PixelSetQuantumPixel(iterator->image,pixels,iterator->pixel_wands[x]);
cristyed231572011-07-14 02:18:59 +0000691 pixels+=GetPixelChannels(iterator->image);
cristy4c08aed2011-07-01 19:47:50 +0000692 }
cristy3ed852e2009-09-05 21:47:34 +0000693 *number_wands=iterator->region.width;
694 return(iterator->pixel_wands);
695}
696
697/*
698%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
699% %
700% %
701% %
702% 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 %
703% %
704% %
705% %
706%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
707%
708% PixelGetPreviousIteratorRow() returns the previous row as an array of pixel
709% wands from the pixel iterator.
710%
711% The format of the PixelGetPreviousIteratorRow method is:
712%
713% PixelWand **PixelGetPreviousIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000714% size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000715%
716% A description of each parameter follows:
717%
718% o iterator: the pixel iterator.
719%
720% o number_wands: the number of pixel wands.
721%
722*/
cristy3ed852e2009-09-05 21:47:34 +0000723WandExport PixelWand **PixelGetPreviousIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000724 size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000725{
cristy4c08aed2011-07-01 19:47:50 +0000726 register const Quantum
cristy3ed852e2009-09-05 21:47:34 +0000727 *pixels;
728
cristybb503372010-05-27 20:51:26 +0000729 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000730 x;
731
732 assert(iterator != (PixelIterator *) NULL);
733 assert(iterator->signature == WandSignature);
734 if (iterator->debug != MagickFalse)
735 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
736 *number_wands=0;
737 if (iterator->active != MagickFalse)
738 iterator->y--;
739 if (PixelSetIteratorRow(iterator,iterator->y) == MagickFalse)
740 return((PixelWand **) NULL);
741 pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
742 iterator->region.y+iterator->y,iterator->region.width,1,
743 iterator->exception);
cristy4c08aed2011-07-01 19:47:50 +0000744 if (pixels == (const Quantum *) NULL)
cristycad4e1b2011-10-16 14:58:39 +0000745 return((PixelWand **) NULL);
cristybb503372010-05-27 20:51:26 +0000746 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy4c08aed2011-07-01 19:47:50 +0000747 {
748 PixelSetQuantumPixel(iterator->image,pixels,iterator->pixel_wands[x]);
cristyed231572011-07-14 02:18:59 +0000749 pixels+=GetPixelChannels(iterator->image);
cristy4c08aed2011-07-01 19:47:50 +0000750 }
cristy3ed852e2009-09-05 21:47:34 +0000751 *number_wands=iterator->region.width;
752 return(iterator->pixel_wands);
753}
754
755/*
756%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
757% %
758% %
759% %
760% P i x e l R e s e t I t e r a t o r %
761% %
762% %
763% %
764%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
765%
766% PixelResetIterator() resets the pixel iterator. Use it in conjunction
767% with PixelGetNextIteratorRow() to iterate over all the pixels in a pixel
768% container.
769%
770% The format of the PixelResetIterator method is:
771%
772% void PixelResetIterator(PixelIterator *iterator)
773%
774% A description of each parameter follows:
775%
776% o iterator: the pixel iterator.
777%
778*/
779WandExport void PixelResetIterator(PixelIterator *iterator)
780{
781 assert(iterator != (PixelIterator *) NULL);
782 assert(iterator->signature == WandSignature);
783 if (iterator->debug != MagickFalse)
784 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
785 iterator->active=MagickFalse;
786 iterator->y=0;
787}
788
789/*
790%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
791% %
792% %
793% %
794% P i x e l S e t F i r s t I t e r a t o r R o w %
795% %
796% %
797% %
798%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
799%
800% PixelSetFirstIteratorRow() sets the pixel iterator to the first pixel row.
801%
802% The format of the PixelSetFirstIteratorRow method is:
803%
804% void PixelSetFirstIteratorRow(PixelIterator *iterator)
805%
806% A description of each parameter follows:
807%
808% o iterator: the magick iterator.
809%
810*/
811WandExport void PixelSetFirstIteratorRow(PixelIterator *iterator)
812{
813 assert(iterator != (PixelIterator *) NULL);
814 assert(iterator->signature == WandSignature);
815 if (iterator->debug != MagickFalse)
816 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
817 iterator->active=MagickFalse;
818 iterator->y=iterator->region.y;
819}
820
821/*
822%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
823% %
824% %
825% %
826% P i x e l S e t I t e r a t o r R o w %
827% %
828% %
829% %
830%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
831%
832% PixelSetIteratorRow() set the pixel iterator row.
833%
834% The format of the PixelSetIteratorRow method is:
835%
836% MagickBooleanType PixelSetIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000837% const ssize_t row)
cristy3ed852e2009-09-05 21:47:34 +0000838%
839% A description of each parameter follows:
840%
841% o iterator: the pixel iterator.
842%
843*/
844WandExport MagickBooleanType PixelSetIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000845 const ssize_t row)
cristy3ed852e2009-09-05 21:47:34 +0000846{
847 assert(iterator != (const PixelIterator *) NULL);
848 assert(iterator->signature == WandSignature);
849 if (iterator->debug != MagickFalse)
850 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
cristybb503372010-05-27 20:51:26 +0000851 if ((row < 0) || (row >= (ssize_t) iterator->region.height))
cristy3ed852e2009-09-05 21:47:34 +0000852 return(MagickFalse);
853 iterator->active=MagickTrue;
854 iterator->y=row;
855 return(MagickTrue);
856}
857
858/*
859%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
860% %
861% %
862% %
863% P i x e l S e t L a s t I t e r a t o r R o w %
864% %
865% %
866% %
867%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
868%
869% PixelSetLastIteratorRow() sets the pixel iterator to the last pixel row.
870%
871% The format of the PixelSetLastIteratorRow method is:
872%
873% void PixelSetLastIteratorRow(PixelIterator *iterator)
874%
875% A description of each parameter follows:
876%
877% o iterator: the magick iterator.
878%
879*/
880WandExport void PixelSetLastIteratorRow(PixelIterator *iterator)
881{
882 assert(iterator != (PixelIterator *) NULL);
883 assert(iterator->signature == WandSignature);
884 if (iterator->debug != MagickFalse)
885 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
886 iterator->active=MagickFalse;
cristybb503372010-05-27 20:51:26 +0000887 iterator->y=(ssize_t) iterator->region.height-1;
cristy3ed852e2009-09-05 21:47:34 +0000888}
889
890/*
891%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
892% %
893% %
894% %
895% P i x e l S y n c I t e r a t o r %
896% %
897% %
898% %
899%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
900%
901% PixelSyncIterator() syncs the pixel iterator.
902%
903% The format of the PixelSyncIterator method is:
904%
905% MagickBooleanType PixelSyncIterator(PixelIterator *iterator)
906%
907% A description of each parameter follows:
908%
909% o iterator: the pixel iterator.
910%
911*/
912WandExport MagickBooleanType PixelSyncIterator(PixelIterator *iterator)
913{
cristyc82a27b2011-10-21 01:07:16 +0000914 MagickBooleanType
915 status;
916
cristybb503372010-05-27 20:51:26 +0000917 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000918 x;
919
cristy4c08aed2011-07-01 19:47:50 +0000920 register Quantum
cristyc47d1f82009-11-26 01:44:43 +0000921 *restrict pixels;
cristy3ed852e2009-09-05 21:47:34 +0000922
923 assert(iterator != (const PixelIterator *) NULL);
924 assert(iterator->signature == WandSignature);
925 if (iterator->debug != MagickFalse)
926 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
cristyc82a27b2011-10-21 01:07:16 +0000927 status=SetCacheViewStorageClass(iterator->view,DirectClass,
928 iterator->exception);
929 if (status == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000930 return(MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +0000931 pixels=GetCacheViewAuthenticPixels(iterator->view,iterator->region.x,
cristycad4e1b2011-10-16 14:58:39 +0000932 iterator->region.y+iterator->y,iterator->region.width,1,
933 iterator->exception);
cristy4c08aed2011-07-01 19:47:50 +0000934 if (pixels == (Quantum *) NULL)
cristycad4e1b2011-10-16 14:58:39 +0000935 return(MagickFalse);
cristybb503372010-05-27 20:51:26 +0000936 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy4c08aed2011-07-01 19:47:50 +0000937 {
938 PixelGetQuantumPixel(iterator->image,iterator->pixel_wands[x],pixels);
cristyed231572011-07-14 02:18:59 +0000939 pixels+=GetPixelChannels(iterator->image);
cristy4c08aed2011-07-01 19:47:50 +0000940 }
cristycad4e1b2011-10-16 14:58:39 +0000941 if (SyncCacheViewAuthenticPixels(iterator->view,iterator->exception) == MagickFalse)
942 return(MagickFalse);
cristy3ed852e2009-09-05 21:47:34 +0000943 return(MagickTrue);
944}