Home | History | Annotate | Download | only in MagickWand
      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