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