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-2016 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
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*/
64struct _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*/
119WandExport 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*/
156WandExport 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) ResetMagickMemory(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*/
211WandExport 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*/
250WandExport MagickBooleanType IsPixelIterator(const PixelIterator *iterator)
251{
252  size_t
253    length;
254
255  if (iterator == (const PixelIterator *) NULL)
256    return(MagickFalse);
257  if (iterator->signature != 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*/
287WandExport 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) ResetMagickMemory(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*/
366WandExport 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*/
403WandExport 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) ResetMagickMemory(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*/
488WandExport 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*/
544WandExport 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*/
600WandExport 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*/
632WandExport 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*/
667WandExport 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*/
726WandExport 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*/
783WandExport 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*/
815WandExport 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*/
848WandExport 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*/
884WandExport 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*/
916WandExport 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