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