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