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