MagickWand 6.9.6
Loading...
Searching...
No Matches
pixel-iterator.c
1/*
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% Cristy %
23% March 2003 %
24% %
25% %
26% Copyright 1999 ImageMagick Studio LLC, a non-profit organization %
27% 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% https://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*/
65{
66 size_t
67 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
84 ssize_t
85 y;
86
88 **pixel_wands;
89
90 MagickBooleanType
91 debug;
92
93 size_t
94 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% void 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{
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);
165 clone_iterator=(PixelIterator *) AcquireCriticalMemory(
166 sizeof(*clone_iterator));
167 (void) memset(clone_iterator,0,sizeof(*clone_iterator));
168 clone_iterator->id=AcquireWandId();
169 (void) FormatLocaleString(clone_iterator->name,MaxTextExtent,"%s-%.20g",
170 PixelIteratorId,(double) clone_iterator->id);
171 clone_iterator->exception=AcquireExceptionInfo();
172 InheritException(clone_iterator->exception,iterator->exception);
173 clone_iterator->view=CloneCacheView(iterator->view);
174 clone_iterator->region=iterator->region;
175 clone_iterator->active=iterator->active;
176 clone_iterator->y=iterator->y;
177 clone_iterator->pixel_wands=ClonePixelWands((const PixelWand **)
178 iterator->pixel_wands,iterator->region.width);
179 clone_iterator->debug=iterator->debug;
180 if (clone_iterator->debug != MagickFalse)
181 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",
182 clone_iterator->name);
183 clone_iterator->signature=WandSignature;
184 return(clone_iterator);
185}
186
187/*
188%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189% %
190% %
191% %
192% D e s t r o y P i x e l I t e r a t o r %
193% %
194% %
195% %
196%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197%
198% DestroyPixelIterator() deallocates resources associated with a PixelIterator.
199%
200% The format of the DestroyPixelIterator method is:
201%
202% PixelIterator *DestroyPixelIterator(PixelIterator *iterator)
203%
204% A description of each parameter follows:
205%
206% o iterator: the pixel iterator.
207%
208*/
209WandExport PixelIterator *DestroyPixelIterator(PixelIterator *iterator)
210{
211 assert(iterator != (const PixelIterator *) NULL);
212 assert(iterator->signature == WandSignature);
213 if (iterator->debug != MagickFalse)
214 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
215 iterator->view=DestroyCacheView(iterator->view);
216 iterator->pixel_wands=DestroyPixelWands(iterator->pixel_wands,
217 iterator->region.width);
218 iterator->exception=DestroyExceptionInfo(iterator->exception);
219 iterator->signature=(~WandSignature);
220 RelinquishWandId(iterator->id);
221 iterator=(PixelIterator *) RelinquishMagickMemory(iterator);
222 return(iterator);
223}
224
225/*
226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227% %
228% %
229% %
230% I s P i x e l I t e r a t o r %
231% %
232% %
233% %
234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235%
236% IsPixelIterator() returns MagickTrue if the iterator is verified as a pixel
237% iterator.
238%
239% The format of the IsPixelIterator method is:
240%
241% MagickBooleanType IsPixelIterator(const PixelIterator *iterator)
242%
243% A description of each parameter follows:
244%
245% o iterator: the magick iterator.
246%
247*/
248WandExport MagickBooleanType IsPixelIterator(const PixelIterator *iterator)
249{
250 size_t
251 length;
252
253 if (iterator == (const PixelIterator *) NULL)
254 return(MagickFalse);
255 if (iterator->signature != WandSignature)
256 return(MagickFalse);
257 length=strlen(PixelIteratorId);
258 if (LocaleNCompare(iterator->name,PixelIteratorId,length) != 0)
259 return(MagickFalse);
260 return(MagickTrue);
261}
262
263/*
264%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265% %
266% %
267% %
268% N e w P i x e l I t e r a t o r %
269% %
270% %
271% %
272%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
273%
274% NewPixelIterator() returns a new pixel iterator.
275%
276% The format of the NewPixelIterator method is:
277%
278% PixelIterator *NewPixelIterator(MagickWand *wand)
279%
280% A description of each parameter follows:
281%
282% o wand: the magick wand.
283%
284*/
285WandExport PixelIterator *NewPixelIterator(MagickWand *wand)
286{
287 const char
288 *quantum;
289
290 ExceptionInfo
291 *exception;
292
293 Image
294 *image;
295
297 *iterator;
298
299 size_t
300 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 exception=AcquireExceptionInfo();
314 view=AcquireVirtualCacheView(image,exception);
315 if (view == (CacheView *) NULL)
316 return((PixelIterator *) NULL);
317 iterator=(PixelIterator *) AcquireCriticalMemory(sizeof(*iterator));
318 (void) memset(iterator,0,sizeof(*iterator));
319 iterator->id=AcquireWandId();
320 (void) FormatLocaleString(iterator->name,MaxTextExtent,"%s-%.20g",
321 PixelIteratorId,(double) iterator->id);
322 iterator->exception=exception;
323 iterator->view=view;
324 SetGeometry(image,&iterator->region);
325 iterator->region.width=image->columns;
326 iterator->region.height=image->rows;
327 iterator->region.x=0;
328 iterator->region.y=0;
329 iterator->pixel_wands=NewPixelWands(iterator->region.width);
330 iterator->y=0;
331 iterator->debug=IsEventLogging();
332 if (iterator->debug != MagickFalse)
333 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
334 iterator->signature=WandSignature;
335 return(iterator);
336}
337
338/*
339%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340% %
341% %
342% %
343% 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 %
344% %
345% %
346% %
347%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
348%
349% PixelClearIteratorException() clear any exceptions associated with the
350% iterator.
351%
352% The format of the PixelClearIteratorException method is:
353%
354% MagickBooleanType PixelClearIteratorException(PixelIterator *iterator)
355%
356% A description of each parameter follows:
357%
358% o iterator: the pixel iterator.
359%
360*/
361WandExport MagickBooleanType PixelClearIteratorException(
362 PixelIterator *iterator)
363{
364 assert(iterator != (PixelIterator *) NULL);
365 assert(iterator->signature == WandSignature);
366 if (iterator->debug != MagickFalse)
367 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
368 ClearMagickException(iterator->exception);
369 return(MagickTrue);
370}
371
372/*
373%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374% %
375% %
376% %
377% N e w P i x e l R e g i o n I t e r a t o r %
378% %
379% %
380% %
381%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
382%
383% NewPixelRegionIterator() returns a new pixel iterator.
384%
385% The format of the NewPixelRegionIterator method is:
386%
387% PixelIterator *NewPixelRegionIterator(MagickWand *wand,const ssize_t x,
388% const ssize_t y,const size_t width,const size_t height)
389%
390% A description of each parameter follows:
391%
392% o wand: the magick wand.
393%
394% o x,y,columns,rows: These values define the perimeter of a region of
395% pixels.
396%
397*/
398WandExport PixelIterator *NewPixelRegionIterator(MagickWand *wand,
399 const ssize_t x,const ssize_t y,const size_t width,const size_t height)
400{
401 CacheView
402 *view;
403
404 const char
405 *quantum;
406
407 ExceptionInfo
408 *exception;
409
410 Image
411 *image;
412
414 *iterator;
415
416 size_t
417 depth;
418
419 assert(wand != (MagickWand *) NULL);
420 depth=MAGICKCORE_QUANTUM_DEPTH;
421 quantum=GetMagickQuantumDepth(&depth);
422 if (depth != MAGICKCORE_QUANTUM_DEPTH)
423 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
424 if ((width == 0) || (height == 0))
425 ThrowWandFatalException(WandError,"ZeroRegionSize",quantum);
426 image=GetImageFromMagickWand(wand);
427 if (image == (Image *) NULL)
428 return((PixelIterator *) NULL);
429 exception=AcquireExceptionInfo();
430 view=AcquireVirtualCacheView(image,exception);
431 if (view == (CacheView *) NULL)
432 return((PixelIterator *) NULL);
433 iterator=(PixelIterator *) AcquireCriticalMemory(sizeof(*iterator));
434 (void) memset(iterator,0,sizeof(*iterator));
435 iterator->id=AcquireWandId();
436 (void) FormatLocaleString(iterator->name,MaxTextExtent,"%s-%.20g",
437 PixelIteratorId,(double) iterator->id);
438 iterator->exception=exception;
439 iterator->view=view;
440 SetGeometry(image,&iterator->region);
441 iterator->region.width=width;
442 iterator->region.height=height;
443 iterator->region.x=x;
444 iterator->region.y=y;
445 iterator->pixel_wands=NewPixelWands(iterator->region.width);
446 iterator->y=0;
447 iterator->debug=IsEventLogging();
448 if (iterator->debug != MagickFalse)
449 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
450 iterator->signature=WandSignature;
451 return(iterator);
452}
453
454/*
455%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456% %
457% %
458% %
459% 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 %
460% %
461% %
462% %
463%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
464%
465% PixelGetCurrentIteratorRow() returns the current row as an array of pixel
466% wands from the pixel iterator.
467%
468% The format of the PixelGetCurrentIteratorRow method is:
469%
470% PixelWand **PixelGetCurrentIteratorRow(PixelIterator *iterator,
471% size_t *number_wands)
472%
473% A description of each parameter follows:
474%
475% o iterator: the pixel iterator.
476%
477% o number_wands: the number of pixel wands.
478%
479*/
480WandExport PixelWand **PixelGetCurrentIteratorRow(PixelIterator *iterator,
481 size_t *number_wands)
482{
483 const IndexPacket
484 *indexes;
485
486 const PixelPacket
487 *pixels;
488
489 ssize_t
490 x;
491
492 assert(iterator != (PixelIterator *) NULL);
493 assert(iterator->signature == WandSignature);
494 if (iterator->debug != MagickFalse)
495 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
496 *number_wands=0;
497 iterator->active=MagickTrue;
498 pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
499 iterator->region.y+iterator->y,iterator->region.width,1,
500 iterator->exception);
501 if (pixels == (const PixelPacket *) NULL)
502 {
503 InheritException(iterator->exception,GetCacheViewException(
504 iterator->view));
505 return((PixelWand **) NULL);
506 }
507 indexes=GetCacheViewVirtualIndexQueue(iterator->view);
508 for (x=0; x < (ssize_t) iterator->region.width; x++)
509 PixelSetQuantumColor(iterator->pixel_wands[x],pixels+x);
510 if (GetCacheViewColorspace(iterator->view) == CMYKColorspace)
511 for (x=0; x < (ssize_t) iterator->region.width; x++)
512 PixelSetBlackQuantum(iterator->pixel_wands[x],
513 GetPixelBlack(indexes+x));
514 if (GetCacheViewStorageClass(iterator->view) == PseudoClass)
515 for (x=0; x < (ssize_t) iterator->region.width; x++)
516 PixelSetIndex(iterator->pixel_wands[x],
517 GetPixelBlack(indexes+x));
518 *number_wands=iterator->region.width;
519 return(iterator->pixel_wands);
520}
521
522/*
523%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
524% %
525% %
526% %
527% 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 %
528% %
529% %
530% %
531%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
532%
533% PixelGetIteratorException() returns the severity, reason, and description of
534% any error that occurs when using other methods in this API.
535%
536% The format of the PixelGetIteratorException method is:
537%
538% char *PixelGetIteratorException(const PixelIterator *iterator,
539% ExceptionType *severity)
540%
541% A description of each parameter follows:
542%
543% o iterator: the pixel iterator.
544%
545% o severity: the severity of the error is returned here.
546%
547*/
548WandExport char *PixelGetIteratorException(const PixelIterator *iterator,
549 ExceptionType *severity)
550{
551 char
552 *description;
553
554 assert(iterator != (const PixelIterator *) NULL);
555 assert(iterator->signature == WandSignature);
556 if (iterator->debug != MagickFalse)
557 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
558 assert(severity != (ExceptionType *) NULL);
559 *severity=iterator->exception->severity;
560 description=(char *) AcquireQuantumMemory(2UL*MaxTextExtent,
561 sizeof(*description));
562 if (description == (char *) NULL)
563 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
564 iterator->name);
565 *description='\0';
566 if (iterator->exception->reason != (char *) NULL)
567 (void) CopyMagickString(description,GetLocaleExceptionMessage(
568 iterator->exception->severity,iterator->exception->reason),MaxTextExtent);
569 if (iterator->exception->description != (char *) NULL)
570 {
571 (void) ConcatenateMagickString(description," (",MaxTextExtent);
572 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
573 iterator->exception->severity,iterator->exception->description),
574 MaxTextExtent);
575 (void) ConcatenateMagickString(description,")",MaxTextExtent);
576 }
577 return(description);
578}
579
580/*
581%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582% %
583% %
584% %
585% P i x e l G e t E x c e p t i o n T y p e %
586% %
587% %
588% %
589%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
590%
591% PixelGetIteratorExceptionType() the exception type associated with the
592% iterator. If no exception has occurred, UndefinedExceptionType is returned.
593%
594% The format of the PixelGetIteratorExceptionType method is:
595%
596% ExceptionType PixelGetIteratorExceptionType(
597% const PixelIterator *iterator)
598%
599% A description of each parameter follows:
600%
601% o iterator: the magick iterator.
602%
603*/
604WandExport ExceptionType PixelGetIteratorExceptionType(
605 const PixelIterator *iterator)
606{
607 assert(iterator != (const PixelIterator *) NULL);
608 assert(iterator->signature == WandSignature);
609 if (iterator->debug != MagickFalse)
610 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
611 return(iterator->exception->severity);
612}
613
614/*
615%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
616% %
617% %
618% %
619% P i x e l G e t I t e r a t o r R o w %
620% %
621% %
622% %
623%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
624%
625% PixelGetIteratorRow() returns the current pixel iterator row.
626%
627% The format of the PixelGetIteratorRow method is:
628%
629% MagickBooleanType PixelGetIteratorRow(PixelIterator *iterator)
630%
631% A description of each parameter follows:
632%
633% o iterator: the pixel iterator.
634%
635*/
636WandExport ssize_t PixelGetIteratorRow(PixelIterator *iterator)
637{
638 assert(iterator != (const PixelIterator *) NULL);
639 assert(iterator->signature == WandSignature);
640 if (iterator->debug != MagickFalse)
641 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
642 return(iterator->y);
643}
644
645/*
646%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
647% %
648% %
649% %
650% P i x e l G e t N e x t I t e r a t o r R o w %
651% %
652% %
653% %
654%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
655%
656% PixelGetNextIteratorRow() returns the next row as an array of pixel wands
657% from the pixel iterator.
658%
659% The format of the PixelGetNextIteratorRow method is:
660%
661% PixelWand **PixelGetNextIteratorRow(PixelIterator *iterator,
662% size_t *number_wands)
663%
664% A description of each parameter follows:
665%
666% o iterator: the pixel iterator.
667%
668% o number_wands: the number of pixel wands.
669%
670*/
671WandExport PixelWand **PixelGetNextIteratorRow(PixelIterator *iterator,
672 size_t *number_wands)
673{
674 const IndexPacket
675 *indexes;
676
677 const PixelPacket
678 *pixels;
679
680 ssize_t
681 x;
682
683 assert(iterator != (PixelIterator *) NULL);
684 assert(iterator->signature == WandSignature);
685 if (iterator->debug != MagickFalse)
686 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
687 *number_wands=0;
688 if (iterator->active != MagickFalse)
689 iterator->y++;
690 if (PixelSetIteratorRow(iterator,iterator->y) == MagickFalse)
691 return((PixelWand **) NULL);
692 pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
693 iterator->region.y+iterator->y,iterator->region.width,1,
694 iterator->exception);
695 if (pixels == (const PixelPacket *) NULL)
696 {
697 InheritException(iterator->exception,GetCacheViewException(
698 iterator->view));
699 return((PixelWand **) NULL);
700 }
701 indexes=GetCacheViewVirtualIndexQueue(iterator->view);
702 for (x=0; x < (ssize_t) iterator->region.width; x++)
703 PixelSetQuantumColor(iterator->pixel_wands[x],pixels+x);
704 if (GetCacheViewColorspace(iterator->view) == CMYKColorspace)
705 for (x=0; x < (ssize_t) iterator->region.width; x++)
706 PixelSetBlackQuantum(iterator->pixel_wands[x],
707 GetPixelBlack(indexes+x));
708 if (GetCacheViewStorageClass(iterator->view) == PseudoClass)
709 for (x=0; x < (ssize_t) iterator->region.width; x++)
710 PixelSetIndex(iterator->pixel_wands[x],
711 GetPixelIndex(indexes+x));
712 *number_wands=iterator->region.width;
713 return(iterator->pixel_wands);
714}
715
716/*
717%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
718% %
719% %
720% %
721% 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 %
722% %
723% %
724% %
725%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
726%
727% PixelGetPreviousIteratorRow() returns the previous row as an array of pixel
728% wands from the pixel iterator.
729%
730% The format of the PixelGetPreviousIteratorRow method is:
731%
732% PixelWand **PixelGetPreviousIteratorRow(PixelIterator *iterator,
733% size_t *number_wands)
734%
735% A description of each parameter follows:
736%
737% o iterator: the pixel iterator.
738%
739% o number_wands: the number of pixel wands.
740%
741*/
742
743WandExport PixelWand **PixelGetPreviousRow(PixelIterator *iterator)
744{
745 size_t
746 number_wands;
747
748 return(PixelGetPreviousIteratorRow(iterator,&number_wands));
749}
750
751WandExport PixelWand **PixelGetPreviousIteratorRow(PixelIterator *iterator,
752 size_t *number_wands)
753{
754 const IndexPacket
755 *indexes;
756
757 const PixelPacket
758 *pixels;
759
760 ssize_t
761 x;
762
763 assert(iterator != (PixelIterator *) NULL);
764 assert(iterator->signature == WandSignature);
765 if (iterator->debug != MagickFalse)
766 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
767 *number_wands=0;
768 if (iterator->active != MagickFalse)
769 iterator->y--;
770 if (PixelSetIteratorRow(iterator,iterator->y) == MagickFalse)
771 return((PixelWand **) NULL);
772 pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
773 iterator->region.y+iterator->y,iterator->region.width,1,
774 iterator->exception);
775 if (pixels == (const PixelPacket *) NULL)
776 {
777 InheritException(iterator->exception,GetCacheViewException(
778 iterator->view));
779 return((PixelWand **) NULL);
780 }
781 indexes=GetCacheViewVirtualIndexQueue(iterator->view);
782 for (x=0; x < (ssize_t) iterator->region.width; x++)
783 PixelSetQuantumColor(iterator->pixel_wands[x],pixels+x);
784 if (GetCacheViewColorspace(iterator->view) == CMYKColorspace)
785 for (x=0; x < (ssize_t) iterator->region.width; x++)
786 PixelSetBlackQuantum(iterator->pixel_wands[x],
787 GetPixelBlack(indexes+x));
788 if (GetCacheViewStorageClass(iterator->view) == PseudoClass)
789 for (x=0; x < (ssize_t) iterator->region.width; x++)
790 PixelSetIndex(iterator->pixel_wands[x],
791 GetPixelIndex(indexes+x));
792 *number_wands=iterator->region.width;
793 return(iterator->pixel_wands);
794}
795
796/*
797%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
798% %
799% %
800% %
801% P i x e l R e s e t I t e r a t o r %
802% %
803% %
804% %
805%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
806%
807% PixelResetIterator() resets the pixel iterator. Use it in conjunction
808% with PixelGetNextIteratorRow() to iterate over all the pixels in a pixel
809% container.
810%
811% The format of the PixelResetIterator method is:
812%
813% void PixelResetIterator(PixelIterator *iterator)
814%
815% A description of each parameter follows:
816%
817% o iterator: the pixel iterator.
818%
819*/
820WandExport void PixelResetIterator(PixelIterator *iterator)
821{
822 assert(iterator != (PixelIterator *) NULL);
823 assert(iterator->signature == WandSignature);
824 if (iterator->debug != MagickFalse)
825 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
826 iterator->active=MagickFalse;
827 iterator->y=0;
828}
829
830/*
831%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
832% %
833% %
834% %
835% P i x e l S e t F i r s t I t e r a t o r R o w %
836% %
837% %
838% %
839%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
840%
841% PixelSetFirstIteratorRow() sets the pixel iterator to the first pixel row.
842%
843% The format of the PixelSetFirstIteratorRow method is:
844%
845% void PixelSetFirstIteratorRow(PixelIterator *iterator)
846%
847% A description of each parameter follows:
848%
849% o iterator: the magick iterator.
850%
851*/
852WandExport void PixelSetFirstIteratorRow(PixelIterator *iterator)
853{
854 assert(iterator != (PixelIterator *) NULL);
855 assert(iterator->signature == WandSignature);
856 if (iterator->debug != MagickFalse)
857 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
858 iterator->active=MagickFalse;
859 iterator->y=iterator->region.y;
860}
861
862/*
863%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
864% %
865% %
866% %
867% P i x e l S e t I t e r a t o r R o w %
868% %
869% %
870% %
871%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
872%
873% PixelSetIteratorRow() set the pixel iterator row.
874%
875% The format of the PixelSetIteratorRow method is:
876%
877% MagickBooleanType PixelSetIteratorRow(PixelIterator *iterator,
878% const ssize_t row)
879%
880% A description of each parameter follows:
881%
882% o iterator: the pixel iterator.
883%
884*/
885WandExport MagickBooleanType PixelSetIteratorRow(PixelIterator *iterator,
886 const ssize_t row)
887{
888 assert(iterator != (const PixelIterator *) NULL);
889 assert(iterator->signature == WandSignature);
890 if (iterator->debug != MagickFalse)
891 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
892 if ((row < 0) || (row >= (ssize_t) iterator->region.height))
893 return(MagickFalse);
894 iterator->active=MagickTrue;
895 iterator->y=row;
896 return(MagickTrue);
897}
898
899/*
900%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
901% %
902% %
903% %
904% P i x e l S e t L a s t I t e r a t o r R o w %
905% %
906% %
907% %
908%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
909%
910% PixelSetLastIteratorRow() sets the pixel iterator to the last pixel row.
911%
912% The format of the PixelSetLastIteratorRow method is:
913%
914% void PixelSetLastIteratorRow(PixelIterator *iterator)
915%
916% A description of each parameter follows:
917%
918% o iterator: the magick iterator.
919%
920*/
921WandExport void PixelSetLastIteratorRow(PixelIterator *iterator)
922{
923 assert(iterator != (PixelIterator *) NULL);
924 assert(iterator->signature == WandSignature);
925 if (iterator->debug != MagickFalse)
926 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
927 iterator->active=MagickFalse;
928 iterator->y=(ssize_t) iterator->region.height-1;
929}
930
931/*
932%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
933% %
934% %
935% %
936% P i x e l S y n c I t e r a t o r %
937% %
938% %
939% %
940%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
941%
942% PixelSyncIterator() syncs the pixel iterator.
943%
944% The format of the PixelSyncIterator method is:
945%
946% MagickBooleanType PixelSyncIterator(PixelIterator *iterator)
947%
948% A description of each parameter follows:
949%
950% o iterator: the pixel iterator.
951%
952*/
953WandExport MagickBooleanType PixelSyncIterator(PixelIterator *iterator)
954{
955 ExceptionInfo
956 *exception;
957
958 IndexPacket
959 *magick_restrict indexes;
960
961 ssize_t
962 x;
963
964 PixelPacket
965 *magick_restrict pixels;
966
967 assert(iterator != (const PixelIterator *) NULL);
968 assert(iterator->signature == WandSignature);
969 if (iterator->debug != MagickFalse)
970 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
971 if (SetCacheViewStorageClass(iterator->view,DirectClass) == MagickFalse)
972 return(MagickFalse);
973 exception=iterator->exception;
974 pixels=GetCacheViewAuthenticPixels(iterator->view,iterator->region.x,
975 iterator->region.y+iterator->y,iterator->region.width,1,exception);
976 if (pixels == (PixelPacket *) NULL)
977 {
978 InheritException(iterator->exception,GetCacheViewException(
979 iterator->view));
980 return(MagickFalse);
981 }
982 indexes=GetCacheViewAuthenticIndexQueue(iterator->view);
983 for (x=0; x < (ssize_t) iterator->region.width; x++)
984 PixelGetQuantumColor(iterator->pixel_wands[x],pixels+x);
985 if (GetCacheViewColorspace(iterator->view) == CMYKColorspace)
986 for (x=0; x < (ssize_t) iterator->region.width; x++)
987 SetPixelBlack(indexes+x,PixelGetBlackQuantum(
988 iterator->pixel_wands[x]));
989 if (SyncCacheViewAuthenticPixels(iterator->view,exception) == MagickFalse)
990 {
991 InheritException(iterator->exception,GetCacheViewException(
992 iterator->view));
993 return(MagickFalse);
994 }
995 return(MagickTrue);
996}