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