MagickWand  7.1.0
pixel-iterator.c
Go to the documentation of this file.
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 "MagickWand/studio.h"
50 #include "MagickWand/MagickWand.h"
53 #include "MagickWand/pixel-wand.h"
54 #include "MagickWand/wand.h"
55 
56 /*
57  Define declarations.
58 */
59 #define PixelIteratorId "PixelIterator"
60 
61 /*
62  Typedef declarations.
63 */
65 {
66  size_t
67  id;
68 
69  char
71 
72  ExceptionInfo
74 
75  CacheView
76  *view;
77 
78  RectangleInfo
80 
81  MagickBooleanType
82  active; /* user has been given pixel data */
83 
84  ssize_t
85  y;
86 
87  PixelWand
89 
90  MagickBooleanType
92 
93  size_t
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 */
120 {
121  assert(iterator != (const PixelIterator *) NULL);
122  assert(iterator->signature == MagickWandSignature);
123  if (iterator->debug != MagickFalse)
124  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
125  iterator->pixel_wands=DestroyPixelWands(iterator->pixel_wands,
126  iterator->region.width);
127  ClearMagickException(iterator->exception);
128  iterator->pixel_wands=NewPixelWands(iterator->region.width);
129  iterator->active=MagickFalse;
130  iterator->y=0;
131  iterator->debug=IsEventLogging();
132 }
133 
134 /*
135 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136 % %
137 % %
138 % %
139 % C l o n e P i x e l I t e r a t o r %
140 % %
141 % %
142 % %
143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
144 %
145 % ClonePixelIterator() makes an exact copy of the specified iterator.
146 %
147 % The format of the ClonePixelIterator method is:
148 %
149 % PixelIterator *ClonePixelIterator(const PixelIterator *iterator)
150 %
151 % A description of each parameter follows:
152 %
153 % o iterator: the magick iterator.
154 %
155 */
157 {
159  *clone_iterator;
160 
161  assert(iterator != (PixelIterator *) NULL);
162  assert(iterator->signature == MagickWandSignature);
163  if (iterator->debug != MagickFalse)
164  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
165  clone_iterator=(PixelIterator *) 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,MagickPathExtent,"%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=MagickWandSignature;
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 */
210 {
211  assert(iterator != (const PixelIterator *) NULL);
212  assert(iterator->signature == MagickWandSignature);
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=(~MagickWandSignature);
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 != MagickWandSignature)
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 */
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,MagickPathExtent,"%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=MagickWandSignature;
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 */
362  PixelIterator *iterator)
363 {
364  assert(iterator != (PixelIterator *) NULL);
365  assert(iterator->signature == MagickWandSignature);
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 */
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,MagickPathExtent,"%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=MagickWandSignature;
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 */
481  size_t *number_wands)
482 {
483  const Quantum
484  *pixels;
485 
486  ssize_t
487  x;
488 
489  assert(iterator != (PixelIterator *) NULL);
490  assert(iterator->signature == MagickWandSignature);
491  if (iterator->debug != MagickFalse)
492  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
493  *number_wands=0;
494  iterator->active=MagickTrue;
495  pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
496  iterator->region.y+iterator->y,iterator->region.width,1,
497  iterator->exception);
498  if (pixels == (const Quantum *) NULL)
499  return((PixelWand **) NULL);
500  for (x=0; x < (ssize_t) iterator->region.width; x++)
501  {
502  PixelSetQuantumPixel(GetCacheViewImage(iterator->view),pixels,
503  iterator->pixel_wands[x]);
504  pixels+=GetPixelChannels(GetCacheViewImage(iterator->view));
505  }
506  *number_wands=iterator->region.width;
507  return(iterator->pixel_wands);
508 }
509 
510 /*
511 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
512 % %
513 % %
514 % %
515 % 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 %
516 % %
517 % %
518 % %
519 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
520 %
521 % PixelGetIteratorException() returns the severity, reason, and description of
522 % any error that occurs when using other methods in this API.
523 %
524 % The format of the PixelGetIteratorException method is:
525 %
526 % char *PixelGetIteratorException(const PixelIterator *iterator,
527 % ExceptionType *severity)
528 %
529 % A description of each parameter follows:
530 %
531 % o iterator: the pixel iterator.
532 %
533 % o severity: the severity of the error is returned here.
534 %
535 */
537  ExceptionType *severity)
538 {
539  char
540  *description;
541 
542  assert(iterator != (const PixelIterator *) NULL);
543  assert(iterator->signature == MagickWandSignature);
544  if (iterator->debug != MagickFalse)
545  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
546  assert(severity != (ExceptionType *) NULL);
547  *severity=iterator->exception->severity;
548  description=(char *) AcquireQuantumMemory(2UL*MagickPathExtent,
549  sizeof(*description));
550  if (description == (char *) NULL)
551  ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
552  iterator->name);
553  *description='\0';
554  if (iterator->exception->reason != (char *) NULL)
555  (void) CopyMagickString(description,GetLocaleExceptionMessage(
556  iterator->exception->severity,iterator->exception->reason),
558  if (iterator->exception->description != (char *) NULL)
559  {
560  (void) ConcatenateMagickString(description," (",MagickPathExtent);
561  (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
562  iterator->exception->severity,iterator->exception->description),
564  (void) ConcatenateMagickString(description,")",MagickPathExtent);
565  }
566  return(description);
567 }
568 
569 /*
570 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
571 % %
572 % %
573 % %
574 % P i x e l G e t E x c e p t i o n T y p e %
575 % %
576 % %
577 % %
578 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
579 %
580 % PixelGetIteratorExceptionType() the exception type associated with the
581 % iterator. If no exception has occurred, UndefinedExceptionType is returned.
582 %
583 % The format of the PixelGetIteratorExceptionType method is:
584 %
585 % ExceptionType PixelGetIteratorExceptionType(
586 % const PixelIterator *iterator)
587 %
588 % A description of each parameter follows:
589 %
590 % o iterator: the pixel iterator.
591 %
592 */
594  const PixelIterator *iterator)
595 {
596  assert(iterator != (const PixelIterator *) NULL);
597  assert(iterator->signature == MagickWandSignature);
598  if (iterator->debug != MagickFalse)
599  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
600  return(iterator->exception->severity);
601 }
602 
603 /*
604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
605 % %
606 % %
607 % %
608 % P i x e l G e t I t e r a t o r R o w %
609 % %
610 % %
611 % %
612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
613 %
614 % PixelGetIteratorRow() returns the current pixel iterator row.
615 %
616 % The format of the PixelGetIteratorRow method is:
617 %
618 % MagickBooleanType PixelGetIteratorRow(PixelIterator *iterator)
619 %
620 % A description of each parameter follows:
621 %
622 % o iterator: the pixel iterator.
623 %
624 */
626 {
627  assert(iterator != (const PixelIterator *) NULL);
628  assert(iterator->signature == MagickWandSignature);
629  if (iterator->debug != MagickFalse)
630  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
631  return(iterator->y);
632 }
633 
634 /*
635 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
636 % %
637 % %
638 % %
639 % P i x e l G e t N e x t I t e r a t o r R o w %
640 % %
641 % %
642 % %
643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
644 %
645 % PixelGetNextIteratorRow() returns the next row as an array of pixel wands
646 % from the pixel iterator.
647 %
648 % The format of the PixelGetNextIteratorRow method is:
649 %
650 % PixelWand **PixelGetNextIteratorRow(PixelIterator *iterator,
651 % size_t *number_wands)
652 %
653 % A description of each parameter follows:
654 %
655 % o iterator: the pixel iterator.
656 %
657 % o number_wands: the number of pixel wands.
658 %
659 */
661  size_t *number_wands)
662 {
663  const Quantum
664  *pixels;
665 
666  ssize_t
667  x;
668 
669  assert(iterator != (PixelIterator *) NULL);
670  assert(iterator->signature == MagickWandSignature);
671  if (iterator->debug != MagickFalse)
672  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
673  *number_wands=0;
674  if (iterator->active != MagickFalse)
675  iterator->y++;
676  if (PixelSetIteratorRow(iterator,iterator->y) == MagickFalse)
677  return((PixelWand **) NULL);
678  pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
679  iterator->region.y+iterator->y,iterator->region.width,1,
680  iterator->exception);
681  if (pixels == (const Quantum *) NULL)
682  return((PixelWand **) NULL);
683  for (x=0; x < (ssize_t) iterator->region.width; x++)
684  {
685  PixelSetQuantumPixel(GetCacheViewImage(iterator->view),pixels,
686  iterator->pixel_wands[x]);
687  pixels+=GetPixelChannels(GetCacheViewImage(iterator->view));
688  }
689  *number_wands=iterator->region.width;
690  return(iterator->pixel_wands);
691 }
692 
693 /*
694 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
695 % %
696 % %
697 % %
698 % 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 %
699 % %
700 % %
701 % %
702 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
703 %
704 % PixelGetPreviousIteratorRow() returns the previous row as an array of pixel
705 % wands from the pixel iterator.
706 %
707 % The format of the PixelGetPreviousIteratorRow method is:
708 %
709 % PixelWand **PixelGetPreviousIteratorRow(PixelIterator *iterator,
710 % size_t *number_wands)
711 %
712 % A description of each parameter follows:
713 %
714 % o iterator: the pixel iterator.
715 %
716 % o number_wands: the number of pixel wands.
717 %
718 */
720  size_t *number_wands)
721 {
722  const Quantum
723  *pixels;
724 
725  ssize_t
726  x;
727 
728  assert(iterator != (PixelIterator *) NULL);
729  assert(iterator->signature == MagickWandSignature);
730  if (iterator->debug != MagickFalse)
731  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
732  *number_wands=0;
733  if (iterator->active != MagickFalse)
734  iterator->y--;
735  if (PixelSetIteratorRow(iterator,iterator->y) == MagickFalse)
736  return((PixelWand **) NULL);
737  pixels=GetCacheViewVirtualPixels(iterator->view,iterator->region.x,
738  iterator->region.y+iterator->y,iterator->region.width,1,
739  iterator->exception);
740  if (pixels == (const Quantum *) NULL)
741  return((PixelWand **) NULL);
742  for (x=0; x < (ssize_t) iterator->region.width; x++)
743  {
744  PixelSetQuantumPixel(GetCacheViewImage(iterator->view),pixels,
745  iterator->pixel_wands[x]);
746  pixels+=GetPixelChannels(GetCacheViewImage(iterator->view));
747  }
748  *number_wands=iterator->region.width;
749  return(iterator->pixel_wands);
750 }
751 
752 /*
753 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
754 % %
755 % %
756 % %
757 % P i x e l R e s e t I t e r a t o r %
758 % %
759 % %
760 % %
761 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
762 %
763 % PixelResetIterator() resets the pixel iterator. Use it in conjunction
764 % with PixelGetNextIteratorRow() to iterate over all the pixels in a pixel
765 % container.
766 %
767 % The format of the PixelResetIterator method is:
768 %
769 % void PixelResetIterator(PixelIterator *iterator)
770 %
771 % A description of each parameter follows:
772 %
773 % o iterator: the pixel iterator.
774 %
775 */
777 {
778  assert(iterator != (PixelIterator *) NULL);
779  assert(iterator->signature == MagickWandSignature);
780  if (iterator->debug != MagickFalse)
781  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
782  iterator->active=MagickFalse;
783  iterator->y=0;
784 }
785 
786 /*
787 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
788 % %
789 % %
790 % %
791 % P i x e l S e t F i r s t I t e r a t o r R o w %
792 % %
793 % %
794 % %
795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
796 %
797 % PixelSetFirstIteratorRow() sets the pixel iterator to the first pixel row.
798 %
799 % The format of the PixelSetFirstIteratorRow method is:
800 %
801 % void PixelSetFirstIteratorRow(PixelIterator *iterator)
802 %
803 % A description of each parameter follows:
804 %
805 % o iterator: the magick iterator.
806 %
807 */
809 {
810  assert(iterator != (PixelIterator *) NULL);
811  assert(iterator->signature == MagickWandSignature);
812  if (iterator->debug != MagickFalse)
813  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
814  iterator->active=MagickFalse;
815  iterator->y=iterator->region.y;
816 }
817 
818 /*
819 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
820 % %
821 % %
822 % %
823 % P i x e l S e t I t e r a t o r R o w %
824 % %
825 % %
826 % %
827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
828 %
829 % PixelSetIteratorRow() set the pixel iterator row.
830 %
831 % The format of the PixelSetIteratorRow method is:
832 %
833 % MagickBooleanType PixelSetIteratorRow(PixelIterator *iterator,
834 % const ssize_t row)
835 %
836 % A description of each parameter follows:
837 %
838 % o iterator: the pixel iterator.
839 %
840 */
841 WandExport MagickBooleanType PixelSetIteratorRow(PixelIterator *iterator,
842  const ssize_t row)
843 {
844  assert(iterator != (const PixelIterator *) NULL);
845  assert(iterator->signature == MagickWandSignature);
846  if (iterator->debug != MagickFalse)
847  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
848  if ((row < 0) || (row >= (ssize_t) iterator->region.height))
849  return(MagickFalse);
850  iterator->active=MagickTrue;
851  iterator->y=row;
852  return(MagickTrue);
853 }
854 
855 /*
856 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
857 % %
858 % %
859 % %
860 % P i x e l S e t L a s t I t e r a t o r R o w %
861 % %
862 % %
863 % %
864 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
865 %
866 % PixelSetLastIteratorRow() sets the pixel iterator to the last pixel row.
867 %
868 % The format of the PixelSetLastIteratorRow method is:
869 %
870 % void PixelSetLastIteratorRow(PixelIterator *iterator)
871 %
872 % A description of each parameter follows:
873 %
874 % o iterator: the magick iterator.
875 %
876 */
878 {
879  assert(iterator != (PixelIterator *) NULL);
880  assert(iterator->signature == MagickWandSignature);
881  if (iterator->debug != MagickFalse)
882  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
883  iterator->active=MagickFalse;
884  iterator->y=(ssize_t) iterator->region.height-1;
885 }
886 
887 /*
888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
889 % %
890 % %
891 % %
892 % P i x e l S y n c I t e r a t o r %
893 % %
894 % %
895 % %
896 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
897 %
898 % PixelSyncIterator() syncs the pixel iterator.
899 %
900 % The format of the PixelSyncIterator method is:
901 %
902 % MagickBooleanType PixelSyncIterator(PixelIterator *iterator)
903 %
904 % A description of each parameter follows:
905 %
906 % o iterator: the pixel iterator.
907 %
908 */
909 WandExport MagickBooleanType PixelSyncIterator(PixelIterator *iterator)
910 {
911  MagickBooleanType
912  status;
913 
914  Quantum
915  *magick_restrict pixels;
916 
917  ssize_t
918  x;
919 
920  assert(iterator != (const PixelIterator *) NULL);
921  assert(iterator->signature == MagickWandSignature);
922  if (iterator->debug != MagickFalse)
923  (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",iterator->name);
924  status=SetCacheViewStorageClass(iterator->view,DirectClass,
925  iterator->exception);
926  if (status == MagickFalse)
927  return(MagickFalse);
928  pixels=GetCacheViewAuthenticPixels(iterator->view,iterator->region.x,
929  iterator->region.y+iterator->y,iterator->region.width,1,
930  iterator->exception);
931  if (pixels == (Quantum *) NULL)
932  return(MagickFalse);
933  for (x=0; x < (ssize_t) iterator->region.width; x++)
934  {
935  PixelGetQuantumPixel(GetCacheViewImage(iterator->view),
936  iterator->pixel_wands[x],pixels);
937  pixels+=GetPixelChannels(GetCacheViewImage(iterator->view));
938  }
939  if (SyncCacheViewAuthenticPixels(iterator->view,iterator->exception) == MagickFalse)
940  return(MagickFalse);
941  return(MagickTrue);
942 }
WandExport ExceptionType PixelGetIteratorExceptionType(const PixelIterator *iterator)
WandExport ssize_t PixelGetIteratorRow(PixelIterator *iterator)
WandExport void PixelSetLastIteratorRow(PixelIterator *iterator)
#define ThrowWandFatalException(severity, tag, context)
WandExport void PixelSetFirstIteratorRow(PixelIterator *iterator)
WandExport PixelIterator * NewPixelIterator(MagickWand *wand)
WandExport PixelWand ** ClonePixelWands(const PixelWand **wands, const size_t number_wands)
Definition: pixel-wand.c:192
#define PixelIteratorId
#define MagickWandSignature
WandExport size_t AcquireWandId(void)
Definition: wand.c:74
#define WandExport
WandExport void PixelSetQuantumPixel(const Image *image, const Quantum *pixel, PixelWand *wand)
Definition: pixel-wand.c:2131
WandExport void ClearPixelIterator(PixelIterator *iterator)
PixelWand ** pixel_wands
WandExport void PixelResetIterator(PixelIterator *iterator)
WandExport char * PixelGetIteratorException(const PixelIterator *iterator, ExceptionType *severity)
WandExport PixelWand ** PixelGetCurrentIteratorRow(PixelIterator *iterator, size_t *number_wands)
char name[MagickPathExtent]
WandExport PixelWand ** PixelGetPreviousIteratorRow(PixelIterator *iterator, size_t *number_wands)
WandExport void RelinquishWandId(const size_t id)
Definition: wand.c:150
WandExport PixelWand ** NewPixelWands(const size_t number_wands)
Definition: pixel-wand.c:433
WandExport MagickBooleanType PixelSetIteratorRow(PixelIterator *iterator, const ssize_t row)
#define MagickPathExtent
CacheView * view
WandExport PixelWand ** PixelGetNextIteratorRow(PixelIterator *iterator, size_t *number_wands)
WandExport Image * GetImageFromMagickWand(const MagickWand *wand)
Definition: magick-image.c:135
WandExport PixelIterator * NewPixelRegionIterator(MagickWand *wand, const ssize_t x, const ssize_t y, const size_t width, const size_t height)
WandExport PixelIterator * ClonePixelIterator(const PixelIterator *iterator)
RectangleInfo region
WandExport MagickBooleanType PixelSyncIterator(PixelIterator *iterator)
WandExport PixelWand ** DestroyPixelWands(PixelWand **wand, const size_t number_wands)
Definition: pixel-wand.c:269
ExceptionInfo * exception
#define magick_restrict
Definition: MagickWand.h:41
WandExport MagickBooleanType IsPixelIterator(const PixelIterator *iterator)
WandExport MagickBooleanType PixelClearIteratorException(PixelIterator *iterator)
WandExport void PixelGetQuantumPixel(const Image *image, const PixelWand *wand, Quantum *pixel)
Definition: pixel-wand.c:1302
MagickBooleanType debug
MagickBooleanType active
WandExport PixelIterator * DestroyPixelIterator(PixelIterator *iterator)