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