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