blob: 563d48b43349bc0a44911534a53dc9faf766a1de [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*/
49#include "wand/studio.h"
50#include "wand/MagickWand.h"
51#include "wand/magick-wand-private.h"
52#include "wand/pixel-iterator.h"
53#include "wand/pixel-wand.h"
54#include "wand/wand.h"
55
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
75 CacheView
76 *view;
77
78 RectangleInfo
79 region;
80
81 MagickBooleanType
82 active;
83
cristybb503372010-05-27 20:51:26 +000084 ssize_t
cristy3ed852e2009-09-05 21:47:34 +000085 y;
86
87 PixelWand
88 **pixel_wands;
89
90 MagickBooleanType
91 debug;
92
cristybb503372010-05-27 20:51:26 +000093 size_t
cristy3ed852e2009-09-05 21:47:34 +000094 signature;
95};
96
97/*
98%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99% %
100% %
101% %
102% C l e a r P i x e l I t e r a t o r %
103% %
104% %
105% %
106%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
107%
108% ClearPixelIterator() clear resources associated with a PixelIterator.
109%
110% The format of the ClearPixelIterator method is:
111%
112% PixelIterator *ClearPixelIterator(PixelIterator *iterator)
113%
114% A description of each parameter follows:
115%
116% o iterator: the pixel iterator.
117%
118*/
119WandExport void ClearPixelIterator(PixelIterator *iterator)
120{
121 assert(iterator != (const PixelIterator *) NULL);
122 assert(iterator->signature == WandSignature);
123 if (iterator->debug != MagickFalse)
124 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
125 iterator->pixel_wands=DestroyPixelWands(iterator->pixel_wands,
126 iterator->region.width);
127 ClearMagickException(iterator->exception);
128 iterator->pixel_wands=NewPixelWands(iterator->region.width);
129 iterator->active=MagickFalse;
130 iterator->y=0;
131 iterator->debug=IsEventLogging();
132}
133
134/*
135%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136% %
137% %
138% %
139% C l o n e P i x e l I t e r a t o r %
140% %
141% %
142% %
143%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
144%
145% ClonePixelIterator() makes an exact copy of the specified iterator.
146%
147% The format of the ClonePixelIterator method is:
148%
149% PixelIterator *ClonePixelIterator(const PixelIterator *iterator)
150%
151% A description of each parameter follows:
152%
153% o iterator: the magick iterator.
154%
155*/
156WandExport PixelIterator *ClonePixelIterator(const PixelIterator *iterator)
157{
158 PixelIterator
159 *clone_iterator;
160
161 assert(iterator != (PixelIterator *) NULL);
162 assert(iterator->signature == WandSignature);
163 if (iterator->debug != MagickFalse)
164 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
cristy73bd4a52010-10-05 11:24:23 +0000165 clone_iterator=(PixelIterator *) AcquireMagickMemory(
cristyf2faecf2010-05-28 19:19:36 +0000166 sizeof(*clone_iterator));
cristy3ed852e2009-09-05 21:47:34 +0000167 if (clone_iterator == (PixelIterator *) NULL)
168 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
169 iterator->name);
170 (void) ResetMagickMemory(clone_iterator,0,sizeof(*clone_iterator));
171 clone_iterator->id=AcquireWandId();
cristye8c25f92010-06-03 00:53:06 +0000172 (void) FormatMagickString(clone_iterator->name,MaxTextExtent,"%s-%.20g",
173 PixelIteratorId,(double) clone_iterator->id);
cristy3ed852e2009-09-05 21:47:34 +0000174 clone_iterator->exception=AcquireExceptionInfo();
175 InheritException(clone_iterator->exception,iterator->exception);
176 clone_iterator->view=CloneCacheView(iterator->view);
177 clone_iterator->region=iterator->region;
178 clone_iterator->active=iterator->active;
179 clone_iterator->y=iterator->y;
180 clone_iterator->pixel_wands=ClonePixelWands((const PixelWand **)
181 iterator->pixel_wands,iterator->region.width);
182 clone_iterator->debug=iterator->debug;
183 if (clone_iterator->debug != MagickFalse)
184 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",
185 clone_iterator->name);
186 clone_iterator->signature=WandSignature;
187 return(clone_iterator);
188}
189
190/*
191%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
192% %
193% %
194% %
195% D e s t r o y P i x e l I t e r a t o r %
196% %
197% %
198% %
199%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200%
201% DestroyPixelIterator() deallocates resources associated with a PixelIterator.
202%
203% The format of the DestroyPixelIterator method is:
204%
205% PixelIterator *DestroyPixelIterator(PixelIterator *iterator)
206%
207% A description of each parameter follows:
208%
209% o iterator: the pixel iterator.
210%
211*/
212WandExport PixelIterator *DestroyPixelIterator(PixelIterator *iterator)
213{
214 assert(iterator != (const PixelIterator *) NULL);
215 assert(iterator->signature == WandSignature);
216 if (iterator->debug != MagickFalse)
217 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
218 iterator->view=DestroyCacheView(iterator->view);
219 iterator->pixel_wands=DestroyPixelWands(iterator->pixel_wands,
220 iterator->region.width);
221 iterator->exception=DestroyExceptionInfo(iterator->exception);
222 iterator->signature=(~WandSignature);
223 RelinquishWandId(iterator->id);
224 iterator=(PixelIterator *) RelinquishMagickMemory(iterator);
225 return(iterator);
226}
227
228/*
229%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
230% %
231% %
232% %
233% I s P i x e l I t e r a t o r %
234% %
235% %
236% %
237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
238%
239% IsPixelIterator() returns MagickTrue if the iterator is verified as a pixel
240% iterator.
241%
242% The format of the IsPixelIterator method is:
243%
244% MagickBooleanType IsPixelIterator(const PixelIterator *iterator)
245%
246% A description of each parameter follows:
247%
248% o iterator: the magick iterator.
249%
250*/
251WandExport MagickBooleanType IsPixelIterator(const PixelIterator *iterator)
252{
253 size_t
254 length;
255
256 if (iterator == (const PixelIterator *) NULL)
257 return(MagickFalse);
258 if (iterator->signature != WandSignature)
259 return(MagickFalse);
260 length=strlen(PixelIteratorId);
261 if (LocaleNCompare(iterator->name,PixelIteratorId,length) != 0)
262 return(MagickFalse);
263 return(MagickTrue);
264}
265
266/*
267%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
268% %
269% %
270% %
271% N e w P i x e l I t e r a t o r %
272% %
273% %
274% %
275%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
276%
277% NewPixelIterator() returns a new pixel iterator.
278%
279% The format of the NewPixelIterator method is:
280%
cristy197d0572010-07-29 23:26:05 +0000281% PixelIterator *NewPixelIterator(MagickWand *wand)
cristy3ed852e2009-09-05 21:47:34 +0000282%
283% A description of each parameter follows:
284%
285% o wand: the magick wand.
286%
287*/
288WandExport PixelIterator *NewPixelIterator(MagickWand *wand)
289{
290 const char
291 *quantum;
292
293 Image
294 *image;
295
296 PixelIterator
297 *iterator;
298
cristybb503372010-05-27 20:51:26 +0000299 size_t
cristy3ed852e2009-09-05 21:47:34 +0000300 depth;
301
302 CacheView
303 *view;
304
305 depth=MAGICKCORE_QUANTUM_DEPTH;
306 quantum=GetMagickQuantumDepth(&depth);
307 if (depth != MAGICKCORE_QUANTUM_DEPTH)
308 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
309 assert(wand != (MagickWand *) NULL);
310 image=GetImageFromMagickWand(wand);
311 if (image == (Image *) NULL)
312 return((PixelIterator *) NULL);
313 view=AcquireCacheView(image);
314 if (view == (CacheView *) NULL)
315 return((PixelIterator *) NULL);
cristy73bd4a52010-10-05 11:24:23 +0000316 iterator=(PixelIterator *) AcquireMagickMemory(sizeof(*iterator));
cristy3ed852e2009-09-05 21:47:34 +0000317 if (iterator == (PixelIterator *) NULL)
318 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
319 GetExceptionMessage(errno));
320 (void) ResetMagickMemory(iterator,0,sizeof(*iterator));
321 iterator->id=AcquireWandId();
cristye8c25f92010-06-03 00:53:06 +0000322 (void) FormatMagickString(iterator->name,MaxTextExtent,"%s-%.20g",
323 PixelIteratorId,(double) iterator->id);
cristy3ed852e2009-09-05 21:47:34 +0000324 iterator->exception=AcquireExceptionInfo();
325 iterator->view=view;
326 SetGeometry(image,&iterator->region);
327 iterator->region.width=image->columns;
328 iterator->region.height=image->rows;
329 iterator->region.x=0;
330 iterator->region.y=0;
331 iterator->pixel_wands=NewPixelWands(iterator->region.width);
332 iterator->y=0;
333 iterator->debug=IsEventLogging();
334 if (iterator->debug != MagickFalse)
335 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
336 iterator->signature=WandSignature;
337 return(iterator);
338}
339
340/*
341%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
342% %
343% %
344% %
345% 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 %
346% %
347% %
348% %
349%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350%
351% PixelClearIteratorException() clear any exceptions associated with the
352% iterator.
353%
354% The format of the PixelClearIteratorException method is:
355%
356% MagickBooleanType PixelClearIteratorException(PixelIterator *wand)
357%
358% A description of each parameter follows:
359%
360% o wand: the pixel wand.
361%
362*/
363WandExport MagickBooleanType PixelClearIteratorException(
364 PixelIterator *iterator)
365{
366 assert(iterator != (PixelIterator *) NULL);
367 assert(iterator->signature == WandSignature);
368 if (iterator->debug != MagickFalse)
369 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
370 ClearMagickException(iterator->exception);
371 return(MagickTrue);
372}
373
374/*
375%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376% %
377% %
378% %
379% N e w P i x e l R e g i o n I t e r a t o r %
380% %
381% %
382% %
383%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384%
385% NewPixelRegionIterator() returns a new pixel iterator.
386%
387% The format of the NewPixelRegionIterator method is:
388%
cristybb503372010-05-27 20:51:26 +0000389% PixelIterator NewPixelRegionIterator(MagickWand *wand,const ssize_t x,
390% const ssize_t y,const size_t width,const size_t height)
cristy3ed852e2009-09-05 21:47:34 +0000391%
392% A description of each parameter follows:
393%
394% o wand: the magick wand.
395%
396% o x,y,columns,rows: These values define the perimeter of a region of
397% pixels.
398%
399*/
cristy2e8bde02010-06-22 11:03:25 +0000400WandExport PixelIterator *NewPixelRegionIterator(MagickWand *wand,
401 const ssize_t x,const ssize_t y,const size_t width,const size_t height)
cristy3ed852e2009-09-05 21:47:34 +0000402{
cristy2e8bde02010-06-22 11:03:25 +0000403 CacheView
404 *view;
405
cristy3ed852e2009-09-05 21:47:34 +0000406 const char
407 *quantum;
408
409 Image
410 *image;
411
412 PixelIterator
413 *iterator;
414
cristybb503372010-05-27 20:51:26 +0000415 size_t
cristy3ed852e2009-09-05 21:47:34 +0000416 depth;
417
cristy3ed852e2009-09-05 21:47:34 +0000418 assert(wand != (MagickWand *) NULL);
419 depth=MAGICKCORE_QUANTUM_DEPTH;
420 quantum=GetMagickQuantumDepth(&depth);
421 if (depth != MAGICKCORE_QUANTUM_DEPTH)
422 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
423 if ((width == 0) || (width == 0))
424 ThrowWandFatalException(WandError,"ZeroRegionSize",quantum);
425 image=GetImageFromMagickWand(wand);
426 if (image == (Image *) NULL)
427 return((PixelIterator *) NULL);
428 view=AcquireCacheView(image);
429 if (view == (CacheView *) NULL)
430 return((PixelIterator *) NULL);
cristy73bd4a52010-10-05 11:24:23 +0000431 iterator=(PixelIterator *) AcquireMagickMemory(sizeof(*iterator));
cristy3ed852e2009-09-05 21:47:34 +0000432 if (iterator == (PixelIterator *) NULL)
433 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
434 wand->name);
435 (void) ResetMagickMemory(iterator,0,sizeof(*iterator));
436 iterator->id=AcquireWandId();
cristye8c25f92010-06-03 00:53:06 +0000437 (void) FormatMagickString(iterator->name,MaxTextExtent,"%s-%.20g",
438 PixelIteratorId,(double) iterator->id);
cristy3ed852e2009-09-05 21:47:34 +0000439 iterator->exception=AcquireExceptionInfo();
440 iterator->view=view;
441 SetGeometry(image,&iterator->region);
442 iterator->region.width=width;
443 iterator->region.height=height;
444 iterator->region.x=x;
445 iterator->region.y=y;
446 iterator->pixel_wands=NewPixelWands(iterator->region.width);
447 iterator->y=0;
448 iterator->debug=IsEventLogging();
449 if (iterator->debug != MagickFalse)
450 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
451 iterator->signature=WandSignature;
452 return(iterator);
453}
454
455/*
456%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457% %
458% %
459% %
460% 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 %
461% %
462% %
463% %
464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465%
466% PixelGetCurrentIteratorRow() returns the current row as an array of pixel
467% wands from the pixel iterator.
468%
469% The format of the PixelGetCurrentIteratorRow method is:
470%
471% PixelWand **PixelGetCurrentIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000472% size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000473%
474% A description of each parameter follows:
475%
476% o iterator: the pixel iterator.
477%
478% o number_wands: the number of pixel wands.
479%
480*/
481WandExport PixelWand **PixelGetCurrentIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000482 size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000483{
484 register const IndexPacket
485 *indexes;
486
487 register const PixelPacket
488 *pixels;
489
cristybb503372010-05-27 20:51:26 +0000490 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000491 x;
492
493 assert(iterator != (PixelIterator *) NULL);
494 assert(iterator->signature == WandSignature);
495 if (iterator->debug != MagickFalse)
496 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
497 *number_wands=0;
498 iterator->active=MagickTrue;
499 pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
500 iterator->region.y+iterator->y,iterator->region.width,1,
501 iterator->exception);
502 if (pixels == (const PixelPacket *) NULL)
503 {
504 InheritException(iterator->exception,GetCacheViewException(
505 iterator->view));
506 return((PixelWand **) NULL);
507 }
508 indexes=GetCacheViewVirtualIndexQueue(iterator->view);
cristybb503372010-05-27 20:51:26 +0000509 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy3ed852e2009-09-05 21:47:34 +0000510 PixelSetQuantumColor(iterator->pixel_wands[x],pixels+x);
511 if (GetCacheViewColorspace(iterator->view) == CMYKColorspace)
cristybb503372010-05-27 20:51:26 +0000512 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy3ed852e2009-09-05 21:47:34 +0000513 PixelSetBlackQuantum(iterator->pixel_wands[x],indexes[x]);
514 if (GetCacheViewStorageClass(iterator->view) == PseudoClass)
cristybb503372010-05-27 20:51:26 +0000515 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy3ed852e2009-09-05 21:47:34 +0000516 PixelSetIndex(iterator->pixel_wands[x],indexes[x]);
517 *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{
672 register const IndexPacket
673 *indexes;
674
675 register const PixelPacket
676 *pixels;
677
cristybb503372010-05-27 20:51:26 +0000678 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000679 x;
680
681 assert(iterator != (PixelIterator *) NULL);
682 assert(iterator->signature == WandSignature);
683 if (iterator->debug != MagickFalse)
684 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
685 *number_wands=0;
686 if (iterator->active != MagickFalse)
687 iterator->y++;
688 if (PixelSetIteratorRow(iterator,iterator->y) == MagickFalse)
689 return((PixelWand **) NULL);
690 pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
691 iterator->region.y+iterator->y,iterator->region.width,1,
692 iterator->exception);
693 if (pixels == (const PixelPacket *) NULL)
694 {
695 InheritException(iterator->exception,GetCacheViewException(
696 iterator->view));
697 return((PixelWand **) NULL);
698 }
699 indexes=GetCacheViewVirtualIndexQueue(iterator->view);
cristybb503372010-05-27 20:51:26 +0000700 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy3ed852e2009-09-05 21:47:34 +0000701 PixelSetQuantumColor(iterator->pixel_wands[x],pixels+x);
702 if (GetCacheViewColorspace(iterator->view) == CMYKColorspace)
cristybb503372010-05-27 20:51:26 +0000703 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy3ed852e2009-09-05 21:47:34 +0000704 PixelSetBlackQuantum(iterator->pixel_wands[x],indexes[x]);
705 if (GetCacheViewStorageClass(iterator->view) == PseudoClass)
cristybb503372010-05-27 20:51:26 +0000706 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy3ed852e2009-09-05 21:47:34 +0000707 PixelSetIndex(iterator->pixel_wands[x],indexes[x]);
708 *number_wands=iterator->region.width;
709 return(iterator->pixel_wands);
710}
711
712/*
713%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
714% %
715% %
716% %
717% 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 %
718% %
719% %
720% %
721%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
722%
723% PixelGetPreviousIteratorRow() returns the previous row as an array of pixel
724% wands from the pixel iterator.
725%
726% The format of the PixelGetPreviousIteratorRow method is:
727%
728% PixelWand **PixelGetPreviousIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000729% size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000730%
731% A description of each parameter follows:
732%
733% o iterator: the pixel iterator.
734%
735% o number_wands: the number of pixel wands.
736%
737*/
738
739WandExport PixelWand **PixelGetPreviousRow(PixelIterator *iterator)
740{
cristybb503372010-05-27 20:51:26 +0000741 size_t
cristy3ed852e2009-09-05 21:47:34 +0000742 number_wands;
743
744 return(PixelGetPreviousIteratorRow(iterator,&number_wands));
745}
746
747WandExport PixelWand **PixelGetPreviousIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000748 size_t *number_wands)
cristy3ed852e2009-09-05 21:47:34 +0000749{
750 register const IndexPacket
751 *indexes;
752
753 register const PixelPacket
754 *pixels;
755
cristybb503372010-05-27 20:51:26 +0000756 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000757 x;
758
759 assert(iterator != (PixelIterator *) NULL);
760 assert(iterator->signature == WandSignature);
761 if (iterator->debug != MagickFalse)
762 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
763 *number_wands=0;
764 if (iterator->active != MagickFalse)
765 iterator->y--;
766 if (PixelSetIteratorRow(iterator,iterator->y) == MagickFalse)
767 return((PixelWand **) NULL);
768 pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
769 iterator->region.y+iterator->y,iterator->region.width,1,
770 iterator->exception);
771 if (pixels == (const PixelPacket *) NULL)
772 {
773 InheritException(iterator->exception,GetCacheViewException(
774 iterator->view));
775 return((PixelWand **) NULL);
776 }
777 indexes=GetCacheViewVirtualIndexQueue(iterator->view);
cristybb503372010-05-27 20:51:26 +0000778 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy3ed852e2009-09-05 21:47:34 +0000779 PixelSetQuantumColor(iterator->pixel_wands[x],pixels+x);
780 if (GetCacheViewColorspace(iterator->view) == CMYKColorspace)
cristybb503372010-05-27 20:51:26 +0000781 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy3ed852e2009-09-05 21:47:34 +0000782 PixelSetBlackQuantum(iterator->pixel_wands[x],indexes[x]);
783 if (GetCacheViewStorageClass(iterator->view) == PseudoClass)
cristybb503372010-05-27 20:51:26 +0000784 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy3ed852e2009-09-05 21:47:34 +0000785 PixelSetIndex(iterator->pixel_wands[x],indexes[x]);
786 *number_wands=iterator->region.width;
787 return(iterator->pixel_wands);
788}
789
790/*
791%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
792% %
793% %
794% %
795% P i x e l R e s e t I t e r a t o r %
796% %
797% %
798% %
799%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
800%
801% PixelResetIterator() resets the pixel iterator. Use it in conjunction
802% with PixelGetNextIteratorRow() to iterate over all the pixels in a pixel
803% container.
804%
805% The format of the PixelResetIterator method is:
806%
807% void PixelResetIterator(PixelIterator *iterator)
808%
809% A description of each parameter follows:
810%
811% o iterator: the pixel iterator.
812%
813*/
814WandExport void PixelResetIterator(PixelIterator *iterator)
815{
816 assert(iterator != (PixelIterator *) NULL);
817 assert(iterator->signature == WandSignature);
818 if (iterator->debug != MagickFalse)
819 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
820 iterator->active=MagickFalse;
821 iterator->y=0;
822}
823
824/*
825%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
826% %
827% %
828% %
829% P i x e l S e t F i r s t I t e r a t o r R o w %
830% %
831% %
832% %
833%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
834%
835% PixelSetFirstIteratorRow() sets the pixel iterator to the first pixel row.
836%
837% The format of the PixelSetFirstIteratorRow method is:
838%
839% void PixelSetFirstIteratorRow(PixelIterator *iterator)
840%
841% A description of each parameter follows:
842%
843% o iterator: the magick iterator.
844%
845*/
846WandExport void PixelSetFirstIteratorRow(PixelIterator *iterator)
847{
848 assert(iterator != (PixelIterator *) NULL);
849 assert(iterator->signature == WandSignature);
850 if (iterator->debug != MagickFalse)
851 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
852 iterator->active=MagickFalse;
853 iterator->y=iterator->region.y;
854}
855
856/*
857%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
858% %
859% %
860% %
861% P i x e l S e t I t e r a t o r R o w %
862% %
863% %
864% %
865%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
866%
867% PixelSetIteratorRow() set the pixel iterator row.
868%
869% The format of the PixelSetIteratorRow method is:
870%
871% MagickBooleanType PixelSetIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000872% const ssize_t row)
cristy3ed852e2009-09-05 21:47:34 +0000873%
874% A description of each parameter follows:
875%
876% o iterator: the pixel iterator.
877%
878*/
879WandExport MagickBooleanType PixelSetIteratorRow(PixelIterator *iterator,
cristybb503372010-05-27 20:51:26 +0000880 const ssize_t row)
cristy3ed852e2009-09-05 21:47:34 +0000881{
882 assert(iterator != (const PixelIterator *) NULL);
883 assert(iterator->signature == WandSignature);
884 if (iterator->debug != MagickFalse)
885 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
cristybb503372010-05-27 20:51:26 +0000886 if ((row < 0) || (row >= (ssize_t) iterator->region.height))
cristy3ed852e2009-09-05 21:47:34 +0000887 return(MagickFalse);
888 iterator->active=MagickTrue;
889 iterator->y=row;
890 return(MagickTrue);
891}
892
893/*
894%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
895% %
896% %
897% %
898% P i x e l S e t L a s t I t e r a t o r R o w %
899% %
900% %
901% %
902%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
903%
904% PixelSetLastIteratorRow() sets the pixel iterator to the last pixel row.
905%
906% The format of the PixelSetLastIteratorRow method is:
907%
908% void PixelSetLastIteratorRow(PixelIterator *iterator)
909%
910% A description of each parameter follows:
911%
912% o iterator: the magick iterator.
913%
914*/
915WandExport void PixelSetLastIteratorRow(PixelIterator *iterator)
916{
917 assert(iterator != (PixelIterator *) NULL);
918 assert(iterator->signature == WandSignature);
919 if (iterator->debug != MagickFalse)
920 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
921 iterator->active=MagickFalse;
cristybb503372010-05-27 20:51:26 +0000922 iterator->y=(ssize_t) iterator->region.height-1;
cristy3ed852e2009-09-05 21:47:34 +0000923}
924
925/*
926%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
927% %
928% %
929% %
930% P i x e l S y n c I t e r a t o r %
931% %
932% %
933% %
934%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
935%
936% PixelSyncIterator() syncs the pixel iterator.
937%
938% The format of the PixelSyncIterator method is:
939%
940% MagickBooleanType PixelSyncIterator(PixelIterator *iterator)
941%
942% A description of each parameter follows:
943%
944% o iterator: the pixel iterator.
945%
946*/
947WandExport MagickBooleanType PixelSyncIterator(PixelIterator *iterator)
948{
949 ExceptionInfo
950 *exception;
951
952 register IndexPacket
cristyc47d1f82009-11-26 01:44:43 +0000953 *restrict indexes;
cristy3ed852e2009-09-05 21:47:34 +0000954
cristybb503372010-05-27 20:51:26 +0000955 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000956 x;
957
958 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000959 *restrict pixels;
cristy3ed852e2009-09-05 21:47:34 +0000960
961 assert(iterator != (const PixelIterator *) NULL);
962 assert(iterator->signature == WandSignature);
963 if (iterator->debug != MagickFalse)
964 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
965 if (SetCacheViewStorageClass(iterator->view,DirectClass) == MagickFalse)
966 return(MagickFalse);
967 exception=iterator->exception;
968 pixels=GetCacheViewAuthenticPixels(iterator->view,iterator->region.x,
969 iterator->region.y+iterator->y,iterator->region.width,1,exception);
970 if (pixels == (PixelPacket *) NULL)
971 {
972 InheritException(iterator->exception,GetCacheViewException(
973 iterator->view));
974 return(MagickFalse);
975 }
976 indexes=GetCacheViewAuthenticIndexQueue(iterator->view);
cristybb503372010-05-27 20:51:26 +0000977 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy3ed852e2009-09-05 21:47:34 +0000978 PixelGetQuantumColor(iterator->pixel_wands[x],pixels+x);
979 if (GetCacheViewColorspace(iterator->view) == CMYKColorspace)
cristybb503372010-05-27 20:51:26 +0000980 for (x=0; x < (ssize_t) iterator->region.width; x++)
cristy3ed852e2009-09-05 21:47:34 +0000981 indexes[x]=PixelGetBlackQuantum(iterator->pixel_wands[x]);
982 if (SyncCacheViewAuthenticPixels(iterator->view,exception) == MagickFalse)
983 {
984 InheritException(iterator->exception,GetCacheViewException(
985 iterator->view));
986 return(MagickFalse);
987 }
988 return(MagickTrue);
989}