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