root / ImageMagick / trunk / wand / pixel-iterator.c

Revision 12610, 37.6 kB (checked in by cristy, 5 days ago)
Line 
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%                      PPPP   IIIII  X   X  EEEEE  L                          %
7%                      P   P    I     X X   E      L                          %
8%                      PPPP     I      X    EEE    L                          %
9%                      P        I     X X   E      L                          %
10%                      P      IIIII  X   X  EEEEE  LLLLL                      %
11%                                                                             %
12%            IIIII  TTTTT EEEEE  RRRR    AAA   TTTTT   OOO   RRRR             %
13%              I      T   E      R   R  A   A    T    O   O  R   R            %
14%              I      T   EEE    RRRR   AAAAA    T    O   O  RRRR             %
15%              I      T   E      R R    A   A    T    O   O  R R              %
16%            IIIII    T   EEEEE  R  R   A   A    T     OOO   R  R             %
17%                                                                             %
18%                                                                             %
19%                   ImageMagick Image Pixel Iterator Methods                  %
20%                                                                             %
21%                              Software Design                                %
22%                                John Cristy                                  %
23%                                March 2003                                   %
24%                                                                             %
25%                                                                             %
26%  Copyright 1999-2008 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 "wand/studio.h"
50#include "wand/MagickWand.h"
51#include "wand/magick-wand-private.h"
52#include "wand/pixel-iterator.h"
53#include "wand/pixel-wand.h"
54#include "wand/wand.h"
55
56/*
57  Define declarations.
58*/
59#define PixelIteratorId  "PixelIterator"
60
61/*
62  Typedef declarations.
63*/
64struct _PixelIterator
65{
66  unsigned long
67    id;
68
69  char
70    name[MaxTextExtent];
71
72  ExceptionInfo
73    *exception;
74
75  ViewInfo
76    *view;
77
78  RectangleInfo
79    region;
80
81  MagickBooleanType
82    active;
83
84  long
85    y;
86
87  PixelWand
88    **pixel_wands;
89
90  MagickBooleanType
91    debug;
92
93  unsigned long
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%      PixelIterator *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 == WandSignature);
123  if (iterator->debug != MagickFalse)
124    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
125  iterator->pixel_wands=DestroyPixelWands(iterator->pixel_wands,
126    iterator->region.width);
127  ClearMagickException(iterator->exception);
128  iterator->pixel_wands=NewPixelWands(iterator->region.width);
129  iterator->active=MagickFalse;
130  iterator->y=0;
131  iterator->debug=IsEventLogging();
132}
133
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 == WandSignature);
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) FormatMagickString(clone_iterator->name,MaxTextExtent,"%s-%lu",
172    PixelIteratorId,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=WandSignature;
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 == WandSignature);
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=(~WandSignature);
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 != WandSignature)
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  Image
293    *image;
294
295  PixelIterator
296    *iterator;
297
298  unsigned long
299    depth;
300
301  ViewInfo
302    *view;
303
304  depth=MAGICKCORE_QUANTUM_DEPTH;
305  quantum=GetMagickQuantumDepth(&depth);
306  if (depth != MAGICKCORE_QUANTUM_DEPTH)
307    ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
308  assert(wand != (MagickWand *) NULL);
309  image=GetImageFromMagickWand(wand);
310  if (image == (Image *) NULL)
311    return((PixelIterator *) NULL);
312  view=AcquireCacheView(image);
313  if (view == (ViewInfo *) NULL)
314    return((PixelIterator *) NULL);
315  iterator=(PixelIterator *) AcquireMagickMemory(sizeof(*iterator));
316  if (iterator == (PixelIterator *) NULL)
317    ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
318      strerror(errno));
319  (void) ResetMagickMemory(iterator,0,sizeof(*iterator));
320  iterator->id=AcquireWandId();
321  (void) FormatMagickString(iterator->name,MaxTextExtent,"%s-%lu",
322    PixelIteratorId,iterator->id);
323  iterator->exception=AcquireExceptionInfo();
324  iterator->view=view;
325  SetGeometry(image,&iterator->region);
326  iterator->region.width=image->columns;
327  iterator->region.height=image->rows;
328  iterator->region.x=0;
329  iterator->region.y=0;
330  iterator->pixel_wands=NewPixelWands(iterator->region.width);
331  iterator->y=0;
332  iterator->debug=IsEventLogging();
333  if (iterator->debug != MagickFalse)
334    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
335  iterator->signature=WandSignature;
336  return(iterator);
337}
338
339/*
340%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
341%                                                                             %
342%                                                                             %
343%                                                                             %
344%   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                     %
345%                                                                             %
346%                                                                             %
347%                                                                             %
348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349%
350%  PixelClearIteratorException() clear any exceptions associated with the
351%  iterator.
352%
353%  The format of the PixelClearIteratorException method is:
354%
355%      MagickBooleanType PixelClearIteratorException(PixelIterator *wand)
356%
357%  A description of each parameter follows:
358%
359%    o wand: the pixel wand.
360%
361*/
362WandExport MagickBooleanType PixelClearIteratorException(
363  PixelIterator *iterator)
364{
365  assert(iterator != (PixelIterator *) NULL);
366  assert(iterator->signature == WandSignature);
367  if (iterator->debug != MagickFalse)
368    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
369  ClearMagickException(iterator->exception);
370  return(MagickTrue);
371}
372
373/*
374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375%                                                                             %
376%                                                                             %
377%                                                                             %
378%   N e w P i x e l R e g i o n I t e r a t o r                               %
379%                                                                             %
380%                                                                             %
381%                                                                             %
382%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
383%
384%  NewPixelRegionIterator() returns a new pixel iterator.
385%
386%  The format of the NewPixelRegionIterator method is:
387%
388%      PixelIterator NewPixelRegionIterator(MagickWand *wand,const long x,
389%        const long y,const unsigned long columns,const unsigned long rows,
390%        const MagickBooleanType modify)
391%
392%  A description of each parameter follows:
393%
394%    o wand: the magick wand.
395%
396%    o x,y,columns,rows:  These values define the perimeter of a region of
397%      pixels.
398%
399*/
400WandExport PixelIterator *NewPixelRegionIterator(MagickWand *wand,const long x,
401  const long y,const unsigned long columns,const unsigned long rows)
402{
403  const char
404    *quantum;
405
406  Image
407    *image;
408
409  PixelIterator
410    *iterator;
411
412  unsigned long
413    depth;
414
415  ViewInfo
416    *view;
417
418  assert(wand != (MagickWand *) NULL);
419  depth=MAGICKCORE_QUANTUM_DEPTH;
420  quantum=GetMagickQuantumDepth(&depth);
421  if (depth != MAGICKCORE_QUANTUM_DEPTH)
422    ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
423  if ((columns == 0) || (rows == 0))
424    ThrowWandFatalException(WandError,"ZeroRegionSize",quantum);
425  image=GetImageFromMagickWand(wand);
426  if (image == (Image *) NULL)
427    return((PixelIterator *) NULL);
428  view=AcquireCacheView(image);
429  if (view == (ViewInfo *) NULL)
430    return((PixelIterator *) NULL);
431  iterator=(PixelIterator *) AcquireMagickMemory(sizeof(*iterator));
432  if (iterator == (PixelIterator *) NULL)
433    ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
434      wand->name);
435  (void) ResetMagickMemory(iterator,0,sizeof(*iterator));
436  iterator->id=AcquireWandId();
437  (void) FormatMagickString(iterator->name,MaxTextExtent,"%s-%lu",
438    PixelIteratorId,iterator->id);
439  iterator->exception=AcquireExceptionInfo();
440  iterator->view=view;
441  SetGeometry(image,&iterator->region);
442  iterator->region.width=columns;
443  iterator->region.height=rows;
444  iterator->region.x=x;
445  iterator->region.y=y;
446  iterator->pixel_wands=NewPixelWands(iterator->region.width);
447  iterator->y=0;
448  iterator->debug=IsEventLogging();
449  if (iterator->debug != MagickFalse)
450    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
451  iterator->signature=WandSignature;
452  return(iterator);
453}
454
455/*
456%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
457%                                                                             %
458%                                                                             %
459%                                                                             %
460%   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                       %
461%                                                                             %
462%                                                                             %
463%                                                                             %
464%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465%
466%  PixelGetCurrentIteratorRow() returns the current row as an array of pixel
467%  wands from the pixel iterator.
468%
469%  The format of the PixelGetCurrentIteratorRow method is:
470%
471%      PixelWand **PixelGetCurrentIteratorRow(PixelIterator *iterator,
472%        unsigned long *number_wands)
473%
474%  A description of each parameter follows:
475%
476%    o iterator: the pixel iterator.
477%
478%    o number_wands: the number of pixel wands.
479%
480*/
481WandExport PixelWand **PixelGetCurrentIteratorRow(PixelIterator *iterator,
482  unsigned long *number_wands)
483{
484  register const IndexPacket
485    *indexes;
486
487  register const PixelPacket
488    *p;
489
490  register long
491    x;
492
493  assert(iterator != (PixelIterator *) NULL);
494  assert(iterator->signature == WandSignature);
495  if (iterator->debug != MagickFalse)
496    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
497  *number_wands=0;
498  iterator->active=MagickTrue;
499  p=AcquireCacheViewPixels(iterator->view,iterator->region.x,iterator->region.y+
500    iterator->y,iterator->region.width,1,iterator->exception);
501  if (p == (const PixelPacket *) NULL)
502    return((PixelWand **) NULL);
503  indexes=AcquireCacheViewIndexes(iterator->view);
504  for (x=0; x < (long) iterator->region.width; x++)
505  {
506    PixelSetQuantumColor(iterator->pixel_wands[x],p);
507    if (GetCacheViewColorspace(iterator->view) == CMYKColorspace)
508      PixelSetBlackQuantum(iterator->pixel_wands[x],indexes[x]);
509    else
510      if (GetCacheViewStorageClass(iterator->view) == PseudoClass)
511        PixelSetIndex(iterator->pixel_wands[x],indexes[x]);
512    p++;
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 == WandSignature);
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*MaxTextExtent,
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),MaxTextExtent);
565  if (iterator->exception->description != (char *) NULL)
566    {
567      (void) ConcatenateMagickString(description," (",MaxTextExtent);
568      (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
569        iterator->exception->severity,iterator->exception->description),
570        MaxTextExtent);
571      (void) ConcatenateMagickString(description,")",MaxTextExtent);
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 wand.
588%  If no exception has occurred, UndefinedExceptionType is returned.
589%
590%  The format of the PixelGetIteratorExceptionType method is:
591%
592%      ExceptionType PixelGetIteratorExceptionType(const PixelWand *wand)
593%
594%  A description of each parameter follows:
595%
596%    o wand: the magick wand.
597%
598*/
599WandExport ExceptionType PixelGetIteratorExceptionType(
600  const PixelIterator *wand)
601{
602  assert(wand != (const PixelIterator *) NULL);
603  assert(wand->signature == WandSignature);
604  if (wand->debug != MagickFalse)
605    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
606  return(wand->exception->severity);
607}
608
609/*
610%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611%                                                                             %
612%                                                                             %
613%                                                                             %
614%   P i x e l G e t I t e r a t o r R o w                                     %
615%                                                                             %
616%                                                                             %
617%                                                                             %
618%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
619%
620%  PixelGetIteratorRow() returns the current pixel iterator row.
621%
622%  The format of the PixelGetIteratorRow method is:
623%
624%      MagickBooleanType PixelGetIteratorRow(PixelIterator *iterator)
625%
626%  A description of each parameter follows:
627%
628%    o iterator: the pixel iterator.
629%
630*/
631WandExport long PixelGetIteratorRow(PixelIterator *iterator)
632{
633  assert(iterator != (const PixelIterator *) NULL);
634  assert(iterator->signature == WandSignature);
635  if (iterator->debug != MagickFalse)
636    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
637  return(iterator->y);
638}
639
640/*
641%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
642%                                                                             %
643%                                                                             %
644%                                                                             %
645%   P i x e l G e t N e x t I t e r a t o r R o w                             %
646%                                                                             %
647%                                                                             %
648%                                                                             %
649%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
650%
651%  PixelGetNextIteratorRow() returns the next row as an array of pixel wands
652%  from the pixel iterator.
653%
654%  The format of the PixelGetNextIteratorRow method is:
655%
656%      PixelWand **PixelGetNextIteratorRow(PixelIterator *iterator,
657%        unsigned long *number_wands)
658%
659%  A description of each parameter follows:
660%
661%    o iterator: the pixel iterator.
662%
663%    o number_wands: the number of pixel wands.
664%
665*/
666WandExport PixelWand **PixelGetNextIteratorRow(PixelIterator *iterator,
667  unsigned long *number_wands)
668{
669  register const IndexPacket
670    *indexes;
671
672  register const PixelPacket
673    *p;
674
675  register long
676    x;
677
678  assert(iterator != (PixelIterator *) NULL);
679  assert(iterator->signature == WandSignature);
680  if (iterator->debug != MagickFalse)
681    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
682  *number_wands=0;
683  if (iterator->active != MagickFalse)
684    iterator->y++;
685  if (PixelSetIteratorRow(iterator,iterator->y) == MagickFalse)
686    return((PixelWand **) NULL);
687  p=AcquireCacheViewPixels(iterator->view,iterator->region.x,iterator->region.y+
688    iterator->y,iterator->region.width,1,iterator->exception);
689  if (p == (const PixelPacket *) NULL)
690    return((PixelWand **) NULL);
691  indexes=AcquireCacheViewIndexes(iterator->view);
692  for (x=0; x < (long) iterator->region.width; x++)
693  {
694    PixelSetQuantumColor(iterator->pixel_wands[x],p);
695    if (GetCacheViewColorspace(iterator->view) == CMYKColorspace)
696      PixelSetBlackQuantum(iterator->pixel_wands[x],indexes[x]);
697    else
698      if (GetCacheViewStorageClass(iterator->view) == PseudoClass)
699        PixelSetIndex(iterator->pixel_wands[x],indexes[x]);
700    p++;
701  }
702  *number_wands=iterator->region.width;
703  return(iterator->pixel_wands);
704}
705
706/*
707%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
708%                                                                             %
709%                                                                             %
710%                                                                             %
711%   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                     %
712%                                                                             %
713%                                                                             %
714%                                                                             %
715%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
716%
717%  PixelGetPreviousIteratorRow() returns the previous row as an array of pixel
718%  wands from the pixel iterator.
719%
720%  The format of the PixelGetPreviousIteratorRow method is:
721%
722%      PixelWand **PixelGetPreviousIteratorRow(PixelIterator *iterator,
723%        unsigned long *number_wands)
724%
725%  A description of each parameter follows:
726%
727%    o iterator: the pixel iterator.
728%
729%    o number_wands: the number of pixel wands.
730%
731*/
732
733WandExport PixelWand **PixelGetPreviousRow(PixelIterator *iterator)
734{
735  unsigned long
736    number_wands;
737
738  return(PixelGetPreviousIteratorRow(iterator,&number_wands));
739}
740
741WandExport PixelWand **PixelGetPreviousIteratorRow(PixelIterator *iterator,
742  unsigned long *number_wands)
743{
744  register const IndexPacket
745    *indexes;
746
747  register const PixelPacket
748    *p;
749
750  register long
751    x;
752
753  assert(iterator != (PixelIterator *) NULL);
754  assert(iterator->signature == WandSignature);
755  if (iterator->debug != MagickFalse)
756    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
757  *number_wands=0;
758  if (iterator->active != MagickFalse)
759    iterator->y--;
760  if (PixelSetIteratorRow(iterator,iterator->y) == MagickFalse)
761    return((PixelWand **) NULL);
762  p=AcquireCacheViewPixels(iterator->view,iterator->region.x,iterator->region.y+
763    iterator->y,iterator->region.width,1,iterator->exception);
764  if (p == (const PixelPacket *) NULL)
765    return((PixelWand **) NULL);
766  indexes=AcquireCacheViewIndexes(iterator->view);
767  for (x=0; x < (long) iterator->region.width; x++)
768  {
769    PixelSetQuantumColor(iterator->pixel_wands[x],p);
770    if (GetCacheViewColorspace(iterator->view) == CMYKColorspace)
771      PixelSetBlackQuantum(iterator->pixel_wands[x],indexes[x]);
772    else
773      if (GetCacheViewStorageClass(iterator->view) == PseudoClass)
774        PixelSetIndex(iterator->pixel_wands[x],indexes[x]);
775    p++;
776  }
777  *number_wands=iterator->region.width;
778  return(iterator->pixel_wands);
779}
780
781/*
782%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
783%                                                                             %
784%                                                                             %
785%                                                                             %
786%   P i x e l R e s e t I t e r a t o r                                       %
787%                                                                             %
788%                                                                             %
789%                                                                             %
790%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
791%
792%  PixelResetIterator() resets the pixel iterator.  Use it in conjunction
793%  with PixelGetNextIteratorRow() to iterate over all the pixels in a pixel
794%  container.
795%
796%  The format of the PixelResetIterator method is:
797%
798%      void PixelResetIterator(PixelIterator *iterator)
799%
800%  A description of each parameter follows:
801%
802%    o iterator: the pixel iterator.
803%
804*/
805WandExport void PixelResetIterator(PixelIterator *iterator)
806{
807  assert(iterator != (PixelIterator *) NULL);
808  assert(iterator->signature == WandSignature);
809  if (iterator->debug != MagickFalse)
810    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
811  iterator->active=MagickFalse;
812  iterator->y=0;
813}
814
815/*
816%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
817%                                                                             %
818%                                                                             %
819%                                                                             %
820%   P i x e l S e t F i r s t I t e r a t o r R o w                           %
821%                                                                             %
822%                                                                             %
823%                                                                             %
824%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
825%
826%  PixelSetFirstIteratorRow() sets the pixel iterator to the first pixel row.
827%
828%  The format of the PixelSetFirstIteratorRow method is:
829%
830%      void PixelSetFirstIteratorRow(PixelIterator *iterator)
831%
832%  A description of each parameter follows:
833%
834%    o iterator: the magick iterator.
835%
836*/
837WandExport void PixelSetFirstIteratorRow(PixelIterator *iterator)
838{
839  assert(iterator != (PixelIterator *) NULL);
840  assert(iterator->signature == WandSignature);
841  if (iterator->debug != MagickFalse)
842    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
843  iterator->active=MagickFalse;
844  iterator->y=iterator->region.y;
845}
846
847/*
848%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
849%                                                                             %
850%                                                                             %
851%                                                                             %
852%   P i x e l S e t I t e r a t o r R o w                                     %
853%                                                                             %
854%                                                                             %
855%                                                                             %
856%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
857%
858%  PixelSetIteratorRow() set the pixel iterator row.
859%
860%  The format of the PixelSetIteratorRow method is:
861%
862%      MagickBooleanType PixelSetIteratorRow(PixelIterator *iterator,
863%        const long row)
864%
865%  A description of each parameter follows:
866%
867%    o iterator: the pixel iterator.
868%
869*/
870WandExport MagickBooleanType PixelSetIteratorRow(PixelIterator *iterator,
871  const long row)
872{
873  assert(iterator != (const PixelIterator *) NULL);
874  assert(iterator->signature == WandSignature);
875  if (iterator->debug != MagickFalse)
876    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
877  if ((row < 0) || (row >= (long) iterator->region.height))
878    return(MagickFalse);
879  iterator->active=MagickTrue;
880  iterator->y=row;
881  return(MagickTrue);
882}
883
884/*
885%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
886%                                                                             %
887%                                                                             %
888%                                                                             %
889%   P i x e l S e t L a s t I t e r a t o r R o w                             %
890%                                                                             %
891%                                                                             %
892%                                                                             %
893%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
894%
895%  PixelSetLastIteratorRow() sets the pixel iterator to the last pixel row.
896%
897%  The format of the PixelSetLastIteratorRow method is:
898%
899%      void PixelSetLastIteratorRow(PixelIterator *iterator)
900%
901%  A description of each parameter follows:
902%
903%    o iterator: the magick iterator.
904%
905*/
906WandExport void PixelSetLastIteratorRow(PixelIterator *iterator)
907{
908  assert(iterator != (PixelIterator *) NULL);
909  assert(iterator->signature == WandSignature);
910  if (iterator->debug != MagickFalse)
911    (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
912  iterator->active=MagickFalse;
913  iterator->y=(long) iterator->region.height-1;
914}
915
916/*
917%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
918%            Â